[
  {
    "path": ".gitignore",
    "content": "# Logs\nlogs\n*.log\n\nwww/*\nplatforms/ios/www/*\n\n# Runtime data\npids\n*.pid\n*.seed\n\n# Directory for instrumented libs generated by jscoverage/JSCover\nlib-cov\n\n# Coverage directory used by tools like istanbul\ncoverage\n\n# Common\n.DS_Store\nbuild\n\n# Node.js\nnode_modules\n\n# Xcode\n*.mode1v3\n*.mode2v3\n*.perspectivev3\n*.pbxuser\n*.hmap\n*.ipa\n*.xcuserstate\n*.xccheckout\n*.moved-aside\n*.perspectivev3\nxcuserdata\nDerivedData\n\n# Android\nbuild.xml\nlocal.properties\ngradlew\ngradlew.bat\ngradle\nant-build\nant-gen\ngen\nout\nsrc/js/stores/secret.json\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2015 Thinkmill\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n"
  },
  {
    "path": "README.md",
    "content": "# ReactEU Mobile App\n\nReactEurope Mobile App, built with [TouchstoneJS](http://touchstonejs.io)\n\nFull Instructions and documentation coming as soon as we can publish them after the conference :)\n\n### Instructions\n\nBuild/run in the browser\n\n``` bash\ngit clone git@github.com:Thinkmill/reacteu-app.git\ncd reacteu-app\nnpm install\nnpm start\n```\n\n\nor, Build/run on Android -- **requires** cordova and the Android SDK to be installed\n\n``` bash\ngit clone git@github.com:Thinkmill/reacteu-app.git\ncd reacteu-app\nnpm install\nnpm run build\ncordova platform add android\ncordova run android\n```\n\n## License\n\nCopyright (c) 2015 Thinkmill. Made available under The MIT License (MIT).\n"
  },
  {
    "path": "config.xml",
    "content": "<?xml version='1.0' encoding='utf-8'?>\n<widget id=\"com.thinkmill.react-europe\" version=\"1.0.2\" xmlns=\"http://www.w3.org/ns/widgets\" xmlns:cdv=\"http://cordova.apache.org/ns/1.0\">\n\t<name>ReactEurope</name>\n\n\t<description>\n\t\tReactEurope Conference app - list the schedule, speakers, and event info.\n\t</description>\n\n\t<author email=\"hello@thinkmill.com.au\" href=\"http://www.thinkmill.com.au\">\n\t\tThinkmill Team\n\t</author>\n\n\t<content src=\"index.html\" />\n\t<access origin=\"*\" />\n\n\t<preference name=\"SplashScreen\" value=\"screen\" />\n\t<preference name=\"SplashScreenDelay\" value=\"10000\" />\n\t<preference name=\"AutoHideSplashScreen\" value=\"false\" />\n\n\t<!-- ANDROID -->\n\t<platform name=\"android\">\n\t\t<icon src=\"resources/icons/android.png\" density=\"ldpi\" />\n\t\t<icon src=\"resources/icons/android.png\" density=\"mdpi\" />\n\t\t<icon src=\"resources/icons/android.png\" density=\"hdpi\" />\n\t\t<icon src=\"resources/icons/android.png\" density=\"xhdpi\" />\n\n\t\t<splash src=\"resources/splash/android.png\" density=\"ldpi\" />\n\t\t<splash src=\"resources/splash/android.png\" density=\"mdpi\" />\n\t\t<splash src=\"resources/splash/android.png\" density=\"hdpi\" />\n\t\t<splash src=\"resources/splash/android.png\" density=\"xhdpi\" />\n\n\t\t<!-- CODEPUSH -->\n\t\t<!-- Production -->\n\t\t<preference name=\"CodePushDeploymentKey\" value=\"3dC4K2JZ2MY2RXkdsdxe8xPTxwLaN1h1Lr9zb\" />\n\t\t<!-- Staging: Un12wp6Bw3_IhrzfyQBhowpA_p_vN1h1Lr9zb -->\n\t</platform>\n\n\t<!-- IOS -->\n\t<platform name=\"ios\">\n\t\t<!-- CODEPUSH -->\n\t\t<!-- Production -->\n\t\t<preference name=\"CodePushDeploymentKey\" value=\"M5thQofU_KiBb2g0lIj2M1RJcx46N1h1Lr9zb\" />\n\t\t<!-- Staging: vnXK_Iq7uZcga27gFHA4TixA06OKN1h1Lr9zb -->\n\t</platform>\n\n\t<!-- PLUGINS -->\n\t<plugin name=\"com.ionic.keyboard\" spec=\"^1.0.4\" />\n\t<plugin name=\"cordova-plugin-appavailability\" spec=\"^0.4.1\" />\n\t<plugin name=\"cordova-plugin-inappbrowser\" spec=\"^1.0.0\" />\n\t<plugin name=\"cordova-plugin-splashscreen\" spec=\"^2.0.0\" />\n\t<plugin name=\"cordova-plugin-statusbar\" spec=\"^1.0.0\" />\n\t<plugin name=\"cordova-plugin-vibration\" spec=\"^1.1.0\" />\n\t<plugin name=\"cordova-plugin-code-push\" version=\"1.7.1-beta\" />\n\t<plugin name=\"cordova-plugin-whitelist\" spec=\"^1.1.0\" />\n\t<plugin name=\"nl.x-services.plugins.socialsharing\" spec=\"^4.3.18\" />\n\t<plugin name=\"phonegap-plugin-barcodescanner\" spec=\"^3.1.0\" />\n</widget>\n"
  },
  {
    "path": "gulpfile.js",
    "content": "/**\n * Gulp tasks are added by the touchstonejs-tasks package\n * See https://github.com/JedWatson/touchstonejs-tasks\n */\n\nrequire('touchstonejs-tasks')(require('gulp'));\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"react-europe\",\n  \"version\": \"1.0.2\",\n  \"description\": \"ReactEurope Conference\",\n  \"private\": true,\n  \"main\": \"src/js/app.js\",\n  \"author\": \"Joss Mackison\",\n  \"dependencies\": {\n    \"async\": \"^1.0.0\",\n    \"blacklist\": \"^1.1.2\",\n    \"capitalize\": \"^1.0.0\",\n    \"classnames\": \"^2.1.1\",\n    \"defaults\": \"^1.0.2\",\n    \"httpify\": \"^1.0.0\",\n    \"moment\": \"^2.10.3\",\n    \"react\": \"^0.13.3\",\n    \"react-blink\": \"^1.0.2\",\n    \"react-container\": \"^0.2.2\",\n    \"react-sentry\": \"^0.4.0\",\n    \"react-tappable\": \"^0.5.1\",\n    \"react-timers\": \"^3.1.0\",\n    \"touchstonejs\": \"git+https://github.com/touchstonejs/touchstonejs.git#3a0d5dbb2a3ee987aefe9d306855a60b0577866b\",\n    \"tween.js\": \"^0.14.0\"\n  },\n  \"devDependencies\": {\n    \"gulp\": \"^3.9.0\",\n    \"happiness\": \"^1.0.6\",\n    \"touchstonejs-tasks\": \"^0.2.5\"\n  },\n  \"scripts\": {\n    \"build\": \"gulp clean && gulp build\",\n    \"build:production\": \"gulp clean && NODE_ENV=production gulp build\",\n    \"lint\": \"happiness\",\n    \"start\": \"gulp clean && gulp dev\",\n    \"watch\": \"gulp clean && gulp watch\"\n  }\n}\n"
  },
  {
    "path": "plugins/android.json",
    "content": "{\n    \"prepare_queue\": {\n        \"installed\": [],\n        \"uninstalled\": []\n    },\n    \"config_munge\": {\n        \"files\": {}\n    },\n    \"installed_plugins\": {\n        \"cordova-plugin-appavailability\": {\n            \"PACKAGE_NAME\": \"com.thinkmill.reactEurope\"\n        },\n        \"cordova-plugin-code-push\": {\n            \"PACKAGE_NAME\": \"com.thinkmill.reactEurope\"\n        },\n        \"cordova-plugin-inappbrowser\": {\n            \"PACKAGE_NAME\": \"com.thinkmill.reactEurope\"\n        },\n        \"cordova-plugin-splashscreen\": {\n            \"PACKAGE_NAME\": \"com.thinkmill.reactEurope\"\n        },\n        \"cordova-plugin-statusbar\": {\n            \"PACKAGE_NAME\": \"com.thinkmill.reactEurope\"\n        },\n        \"cordova-plugin-vibration\": {\n            \"PACKAGE_NAME\": \"com.thinkmill.reactEurope\"\n        },\n        \"cordova-plugin-whitelist\": {\n            \"PACKAGE_NAME\": \"com.thinkmill.reactEurope\"\n        },\n        \"phonegap-plugin-barcodescanner\": {\n            \"PACKAGE_NAME\": \"com.thinkmill.reactEurope\"\n        }\n    },\n    \"dependent_plugins\": {\n        \"code-push\": {\n            \"PACKAGE_NAME\": \"com.thinkmill.reactEurope\"\n        },\n        \"cordova-plugin-compat\": {\n            \"PACKAGE_NAME\": \"com.thinkmill.reactEurope\"\n        },\n        \"cordova-plugin-file\": {\n            \"PACKAGE_NAME\": \"com.thinkmill.reactEurope\"\n        },\n        \"cordova-plugin-file-transfer\": {\n            \"PACKAGE_NAME\": \"com.thinkmill.reactEurope\"\n        },\n        \"cordova-plugin-zip\": {\n            \"PACKAGE_NAME\": \"com.thinkmill.reactEurope\"\n        },\n        \"cordova-plugin-dialogs\": {\n            \"PACKAGE_NAME\": \"com.thinkmill.reactEurope\"\n        },\n        \"cordova-plugin-device\": {\n            \"PACKAGE_NAME\": \"com.thinkmill.reactEurope\"\n        }\n    }\n}"
  },
  {
    "path": "plugins/code-push/README.md",
    "content": "# CodePush Management SDK (Node.js)\n\nA JavaScript library for programmatically managing your CodePush account (e.g. creating apps, promoting releases), which allows authoring Node.js-based build and/or deployment scripts, without needing to shell out to the [CLI](https://github.com/Microsoft/code-push/blob/master/cli/README.md).\n\n\n## Getting Started\n\n1. Create an access key to authenticate with the CodePush server using the following CodePush CLI command:\n\n    ```shell\n    code-push access-key add \"DESCRIPTION_OF_THE_KEY\"\n    ```\n    \n    If you already created a key that you want to use here, then you can retrieve it by running `code-push access-key ls` and using the value of the `Key` column for the key you wish to use.\n    \n2. Install the management SDK by running `npm install code-push --save`\n\n3. Import it using the following statement (using ES6 syntax as applicable):\n\n    ```javascript\n    var CodePush = require(\"code-push\");    \n    ```\n    \n4. Create an instance of the `CodePush` class, passing it the access key you created or retrieved in step #1:\n\n    ```javascript\n    var codePush = new CodePush(\"YOUR_ACCESS_KEY\");\n    ```\n\n5. Begin automating the management of your account! For more details on what you can do with this `codePush` object, refer to the API reference section below.\n\n## API Reference\n\nThe `code-push` module exports a single class (typically referred to as `CodePush`), which represents a proxy to the CodePush account management REST API. This class has a single constructor for authenticating with the CodePush service, and a collection of instance methods that correspond to the commands in the management [CLI](https://github.com/Microsoft/code-push/blob/master/cli/README.md), which allow you to programmatically control every aspect of your CodePush account.\n\n### Constructors\n\n- __CodePush(accessKey: string)__ - Creates a new instance of the CodePush management SDK, using the specified access key to authenticated with the server.\n\n### Methods\n\n- __addAccessKey(description: string): Promise&lt;AccessKey&gt;__ - Creates a new access key with the specified description (e.g. \"VSTS CI\").\n\n- __addApp(appName: string): Promise&lt;App&gt;__ - Creates a new CodePush app with the specified name.\n\n- __addCollaborator(appName: string, email: string): Promise&lt;void&gt;__ - Adds the specified CodePush user as a collaborator to the specified CodePush app.\n\n- __addDeployment(appName: string, deploymentName: string): Promise&lt;Deployment&gt;__ - Creates a new deployment with the specified name, and associated with the specified app.\n\n- __clearDeploymentHistory(appName: string, deploymentName: string): Promise&lt;void&gt;__ - Clears the release history associated with the specified app deployment.\n\n- __getAccessKey(accessKey: string): Promise&lt;AccessKey&gt;__ - Retrieves the metadata about the specific access key.\n\n- __getAccessKeys(): Promise&lt;AccessKey[]&gt;__ - Retrieves the list of access keys associated with your CodePush account.\n\n- __getApp(appName: string): Promise&lt;App&gt;__ - Retrieves the metadata about the specified app.\n\n- __getApps(): Promise&lt;App[]&gt;__ - Retrieves the list of apps associated with your CodePush account.\n\n- __getCollaborators(appName: string): Promise&lt;CollaboratorMap&gt;__ - Retrieves the list of collaborators associated with the specified app.\n\n- __getDeployment(appName: string, deploymentName: string): Promise&lt;Deployment&gt;__ - Retrieves the metadata for the specified app deployment.\n\n- __getDeploymentHistory(appName: string, deploymentName: string): Promise&lt;Package[]&gt;__ - Retrieves the list of releases that have been made to the specified app deployment.\n\n- __getDeploymentMetrics(appName: string, deploymentName): Promise&lt;DeploymentMetrics&gt;__ - Retrieves the installation metrics for the specified app deployment. \n\n- __getDeployments(appName: string): Promose&lt;Deployment[]&gt;__ - Retrieves the list of deployments associated with the specified app.\n\n- __patchRelease(appName: string, deploymentName: string, label: string, updateMetadata: PackageInfo): Promise&lt;void&gt;__ - Updates the specified release's metadata with the given information.\n\n- __promote(appName: string, sourceDeploymentName: string, destinationDeploymentName: string, updateMetadata: PackageInfo): Promise&lt;void&gt;__ - Promotes the latest release from one deployment to another for the specified app and updates the release with the given metadata.\n\n- __release(appName: string, deploymentName: string, updateContentsPath: string, targetBinaryVersion: string, updateMetadata: PackageInfo): Promise&lt;void&gt;__ - Releases a new update to the specified deployment with the given metadata.\n\n- __removeAccessKey(accessKey: string): Promise&lt;void&gt;__ - Removes the specified access key from your CodePush account.\n\n- __removeApp(appName: string): Promise&lt;void&gt;__ - Deletes the specified CodePush app from your account.\n\n- __removeCollaborator(appName: string, email: string): Promise&lt;void&gt;__ - Removes the specified account as a collaborator from the specified app.\n\n- __removeDeployment(appName: string, deploymentName: string): Promise&lt;void&gt;__ - Removes the specified deployment from the specified app.\n\n- __renameApp(oldAppName: string, newAppName: string): Promise&lt;void&gt;__ - Renames an existing app.\n\n- __renameDeployment(appName: string, oldDeploymentName: string, newDeploymentName: string): Promise&lt;void&gt;__ - Renames an existing deployment within the specified app.\n\n- __rollback(appName: string, deploymentName: string, targetRelease?: string): Promise&lt;void&gt;__ - Rolls back the latest release within the specified deployment. Optionally allows you to target a specific release in the deployment's history, as opposed to rolling to the previous release.\n\n- __transferApp(appName: string, email: string): Promise&lt;void&gt;__ - Transfers the ownership of the specified app to the specified account.\n"
  },
  {
    "path": "plugins/code-push/package.json",
    "content": "{\n  \"name\": \"code-push\",\n  \"version\": \"1.9.2-beta\",\n  \"description\": \"Management SDK for the CodePush service\",\n  \"main\": \"script/index.js\",\n  \"scripts\": {\n    \"test\": \"gulp\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/Microsoft/code-push.git\"\n  },\n  \"author\": \"Microsoft Corporation\",\n  \"license\": \"MIT\",\n  \"homepage\": \"https://microsoft.github.io/code-push\",\n  \"dependencies\": {\n    \"base-64\": \"^0.1.0\",\n    \"node-uuid\": \"^1.4.3\",\n    \"q\": \"^1.4.1\",\n    \"superagent\": \"^1.7.2\",\n    \"superagent-proxy\": \"^1.0.0\"\n  }\n}\n"
  },
  {
    "path": "plugins/code-push/plugin.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<plugin xmlns=\"http://apache.org/cordova/ns/plugins/1.0\" id=\"code-push\" version=\"1.9.0-beta\">\n\t<name>CodePushAcquisition</name>\n\t<description>CodePush Acquisition Plugin for Apache Cordova</description>\n\t<license>MIT</license>\n\t<keywords>cordova,code,push,acquisition</keywords>\n\t<repo>https://github.com/Microsoft/code-push.git</repo>\n\t<js-module src=\"script/acquisition-sdk.js\" name=\"AcquisitionManager\">\n\t\t<merges target=\"window\" />\n\t</js-module>\n</plugin>\n"
  },
  {
    "path": "plugins/code-push/script/acquisition-sdk.js",
    "content": "/// <reference path=\"../definitions/harness.d.ts\" />\nvar AcquisitionStatus = (function () {\n    function AcquisitionStatus() {\n    }\n    AcquisitionStatus.DeploymentSucceeded = \"DeploymentSucceeded\";\n    AcquisitionStatus.DeploymentFailed = \"DeploymentFailed\";\n    return AcquisitionStatus;\n})();\nexports.AcquisitionStatus = AcquisitionStatus;\nvar AcquisitionManager = (function () {\n    function AcquisitionManager(httpRequester, configuration) {\n        this._httpRequester = httpRequester;\n        this._serverUrl = configuration.serverUrl;\n        if (this._serverUrl.slice(-1) !== \"/\") {\n            this._serverUrl += \"/\";\n        }\n        this._appVersion = configuration.appVersion;\n        this._clientUniqueId = configuration.clientUniqueId;\n        this._deploymentKey = configuration.deploymentKey;\n        this._ignoreAppVersion = configuration.ignoreAppVersion;\n    }\n    AcquisitionManager.prototype.queryUpdateWithCurrentPackage = function (currentPackage, callback) {\n        var _this = this;\n        if (!currentPackage || !currentPackage.appVersion) {\n            throw new Error(\"Calling common acquisition SDK with incorrect package\"); // Unexpected; indicates error in our implementation\n        }\n        var updateRequest = {\n            deploymentKey: this._deploymentKey,\n            appVersion: currentPackage.appVersion,\n            packageHash: currentPackage.packageHash,\n            isCompanion: this._ignoreAppVersion,\n            label: currentPackage.label,\n            clientUniqueId: this._clientUniqueId\n        };\n        var requestUrl = this._serverUrl + \"updateCheck?\" + queryStringify(updateRequest);\n        this._httpRequester.request(0 /* GET */, requestUrl, function (error, response) {\n            if (error) {\n                callback(error, null);\n                return;\n            }\n            if (response.statusCode !== 200) {\n                callback(new Error(response.statusCode + \": \" + response.body), null);\n                return;\n            }\n            try {\n                var responseObject = JSON.parse(response.body);\n                var updateInfo = responseObject.updateInfo;\n            }\n            catch (error) {\n                callback(error, null);\n                return;\n            }\n            if (!updateInfo) {\n                callback(error, null);\n                return;\n            }\n            else if (updateInfo.updateAppVersion) {\n                callback(null, { updateAppVersion: true, appVersion: updateInfo.appVersion });\n                return;\n            }\n            else if (!updateInfo.isAvailable) {\n                callback(null, null);\n                return;\n            }\n            var remotePackage = {\n                deploymentKey: _this._deploymentKey,\n                description: updateInfo.description,\n                label: updateInfo.label,\n                appVersion: updateInfo.appVersion,\n                isMandatory: updateInfo.isMandatory,\n                packageHash: updateInfo.packageHash,\n                packageSize: updateInfo.packageSize,\n                downloadUrl: updateInfo.downloadURL\n            };\n            callback(null, remotePackage);\n        });\n    };\n    AcquisitionManager.prototype.reportStatusDeploy = function (deployedPackage, status, previousLabelOrAppVersion, previousDeploymentKey, callback) {\n        var url = this._serverUrl + \"reportStatus/deploy\";\n        var body = {\n            appVersion: this._appVersion,\n            deploymentKey: this._deploymentKey\n        };\n        if (this._clientUniqueId) {\n            body.clientUniqueId = this._clientUniqueId;\n        }\n        if (deployedPackage) {\n            body.label = deployedPackage.label;\n            body.appVersion = deployedPackage.appVersion;\n            switch (status) {\n                case AcquisitionStatus.DeploymentSucceeded:\n                case AcquisitionStatus.DeploymentFailed:\n                    body.status = status;\n                    break;\n                default:\n                    if (callback) {\n                        if (!status) {\n                            callback(new Error(\"Missing status argument.\"), null);\n                        }\n                        else {\n                            callback(new Error(\"Unrecognized status \\\"\" + status + \"\\\".\"), null);\n                        }\n                    }\n                    return;\n            }\n        }\n        if (previousLabelOrAppVersion) {\n            body.previousLabelOrAppVersion = previousLabelOrAppVersion;\n        }\n        if (previousDeploymentKey) {\n            body.previousDeploymentKey = previousDeploymentKey;\n        }\n        callback = typeof arguments[arguments.length - 1] === \"function\" && arguments[arguments.length - 1];\n        this._httpRequester.request(2 /* POST */, url, JSON.stringify(body), function (error, response) {\n            if (callback) {\n                if (error) {\n                    callback(error, null);\n                    return;\n                }\n                if (response.statusCode !== 200) {\n                    callback(new Error(response.statusCode + \": \" + response.body), null);\n                    return;\n                }\n                callback(null, null);\n            }\n        });\n    };\n    AcquisitionManager.prototype.reportStatusDownload = function (downloadedPackage, callback) {\n        var url = this._serverUrl + \"reportStatus/download\";\n        var body = {\n            clientUniqueId: this._clientUniqueId,\n            deploymentKey: this._deploymentKey,\n            label: downloadedPackage.label\n        };\n        this._httpRequester.request(2 /* POST */, url, JSON.stringify(body), function (error, response) {\n            if (callback) {\n                if (error) {\n                    callback(error, null);\n                    return;\n                }\n                if (response.statusCode !== 200) {\n                    callback(new Error(response.statusCode + \": \" + response.body), null);\n                    return;\n                }\n                callback(null, null);\n            }\n        });\n    };\n    return AcquisitionManager;\n})();\nexports.AcquisitionManager = AcquisitionManager;\nfunction queryStringify(object) {\n    var queryString = \"\";\n    var isFirst = true;\n    for (var property in object) {\n        if (object.hasOwnProperty(property)) {\n            var value = object[property];\n            if (!isFirst) {\n                queryString += \"&\";\n            }\n            queryString += encodeURIComponent(property) + \"=\";\n            if (value !== null && typeof value !== \"undefined\") {\n                queryString += encodeURIComponent(value);\n            }\n            isFirst = false;\n        }\n    }\n    return queryString;\n}\n"
  },
  {
    "path": "plugins/code-push/script/index.js",
    "content": "var AccountManager = require(\"./management-sdk\");\nmodule.exports = AccountManager;\n"
  },
  {
    "path": "plugins/code-push/script/management-sdk.js",
    "content": "var os = require(\"os\");\nvar Q = require(\"q\");\nvar superagent = require(\"superagent\");\nvar Promise = Q.Promise;\nvar superproxy = require(\"superagent-proxy\");\nsuperproxy(superagent);\nvar packageJson = require(\"../package.json\");\nif (typeof window === \"undefined\") {\n    fs = require(\"fs\");\n}\nelse {\n    fs = {\n        createReadStream: function (fileOrPath) {\n            throw new Error(\"Tried to call a node fs function from the browser.\");\n        }\n    };\n}\n// A template string tag function that URL encodes the substituted values\nfunction urlEncode(strings) {\n    var values = [];\n    for (var _i = 1; _i < arguments.length; _i++) {\n        values[_i - 1] = arguments[_i];\n    }\n    var result = \"\";\n    for (var i = 0; i < strings.length; i++) {\n        result += strings[i];\n        if (i < values.length) {\n            result += encodeURIComponent(values[i]);\n        }\n    }\n    return result;\n}\nvar AccountManager = (function () {\n    function AccountManager(accessKey, customHeaders, serverUrl, proxy) {\n        if (!accessKey)\n            throw new Error(\"An access key must be specified.\");\n        this._accessKey = accessKey;\n        this._customHeaders = customHeaders;\n        this._serverUrl = serverUrl || AccountManager.SERVER_URL;\n        this._proxy = proxy;\n    }\n    Object.defineProperty(AccountManager.prototype, \"accessKey\", {\n        get: function () {\n            return this._accessKey;\n        },\n        enumerable: true,\n        configurable: true\n    });\n    AccountManager.prototype.isAuthenticated = function () {\n        var _this = this;\n        return Promise(function (resolve, reject, notify) {\n            var request = superagent.get(_this._serverUrl + (_a = [\"/authenticated\"], _a.raw = [\"/authenticated\"], urlEncode(_a)));\n            if (_this._proxy)\n                request.proxy(_this._proxy);\n            _this.attachCredentials(request);\n            request.end(function (err, res) {\n                if (err && err.status !== 401) {\n                    reject({ message: _this.getErrorMessage(err, res) });\n                    return;\n                }\n                var status = res ? res.status : err.status;\n                var authenticated = status === 200;\n                resolve(authenticated);\n            });\n            var _a;\n        });\n    };\n    AccountManager.prototype.addAccessKey = function (description) {\n        if (!description) {\n            throw new Error(\"A description must be specified when adding an access key.\");\n        }\n        var hostname = os.hostname();\n        var accessKeyRequest = { createdBy: hostname, description: description };\n        return this.post((_a = [\"/accessKeys/\"], _a.raw = [\"/accessKeys/\"], urlEncode(_a)), JSON.stringify(accessKeyRequest), true)\n            .then(function (response) { return response.body.accessKey; });\n        var _a;\n    };\n    AccountManager.prototype.getAccessKey = function (accessKey) {\n        return this.get((_a = [\"/accessKeys/\", \"\"], _a.raw = [\"/accessKeys/\", \"\"], urlEncode(_a, accessKey)))\n            .then(function (res) { return res.body.accessKey; });\n        var _a;\n    };\n    AccountManager.prototype.getAccessKeys = function () {\n        return this.get((_a = [\"/accessKeys\"], _a.raw = [\"/accessKeys\"], urlEncode(_a)))\n            .then(function (res) { return res.body.accessKeys; });\n        var _a;\n    };\n    AccountManager.prototype.removeAccessKey = function (accessKey) {\n        return this.del((_a = [\"/accessKeys/\", \"\"], _a.raw = [\"/accessKeys/\", \"\"], urlEncode(_a, accessKey)))\n            .then(function () { return null; });\n        var _a;\n    };\n    // Account\n    AccountManager.prototype.getAccountInfo = function () {\n        return this.get((_a = [\"/account\"], _a.raw = [\"/account\"], urlEncode(_a)))\n            .then(function (res) { return res.body.account; });\n        var _a;\n    };\n    // Apps\n    AccountManager.prototype.getApps = function () {\n        return this.get((_a = [\"/apps\"], _a.raw = [\"/apps\"], urlEncode(_a)))\n            .then(function (res) { return res.body.apps; });\n        var _a;\n    };\n    AccountManager.prototype.getApp = function (appName) {\n        return this.get((_a = [\"/apps/\", \"\"], _a.raw = [\"/apps/\", \"\"], urlEncode(_a, appName)))\n            .then(function (res) { return res.body.app; });\n        var _a;\n    };\n    AccountManager.prototype.addApp = function (appName) {\n        var app = { name: appName };\n        return this.post((_a = [\"/apps/\"], _a.raw = [\"/apps/\"], urlEncode(_a)), JSON.stringify(app), false)\n            .then(function () { return app; });\n        var _a;\n    };\n    AccountManager.prototype.removeApp = function (appName) {\n        return this.del((_a = [\"/apps/\", \"\"], _a.raw = [\"/apps/\", \"\"], urlEncode(_a, appName)))\n            .then(function () { return null; });\n        var _a;\n    };\n    AccountManager.prototype.renameApp = function (oldAppName, newAppName) {\n        return this.patch((_a = [\"/apps/\", \"\"], _a.raw = [\"/apps/\", \"\"], urlEncode(_a, oldAppName)), JSON.stringify({ name: newAppName }))\n            .then(function () { return null; });\n        var _a;\n    };\n    AccountManager.prototype.transferApp = function (appName, email) {\n        return this.post((_a = [\"/apps/\", \"/transfer/\", \"\"], _a.raw = [\"/apps/\", \"/transfer/\", \"\"], urlEncode(_a, appName, email)), null, false)\n            .then(function () { return null; });\n        var _a;\n    };\n    // Collaborators\n    AccountManager.prototype.getCollaborators = function (appName) {\n        return this.get((_a = [\"/apps/\", \"/collaborators\"], _a.raw = [\"/apps/\", \"/collaborators\"], urlEncode(_a, appName)))\n            .then(function (res) { return res.body.collaborators; });\n        var _a;\n    };\n    AccountManager.prototype.addCollaborator = function (appName, email) {\n        return this.post((_a = [\"/apps/\", \"/collaborators/\", \"\"], _a.raw = [\"/apps/\", \"/collaborators/\", \"\"], urlEncode(_a, appName, email)), null, false)\n            .then(function () { return null; });\n        var _a;\n    };\n    AccountManager.prototype.removeCollaborator = function (appName, email) {\n        return this.del((_a = [\"/apps/\", \"/collaborators/\", \"\"], _a.raw = [\"/apps/\", \"/collaborators/\", \"\"], urlEncode(_a, appName, email)))\n            .then(function () { return null; });\n        var _a;\n    };\n    // Deployments\n    AccountManager.prototype.addDeployment = function (appName, deploymentName) {\n        var deployment = { name: deploymentName };\n        return this.post((_a = [\"/apps/\", \"/deployments/\"], _a.raw = [\"/apps/\", \"/deployments/\"], urlEncode(_a, appName)), JSON.stringify(deployment), true)\n            .then(function (res) { return res.body.deployment; });\n        var _a;\n    };\n    AccountManager.prototype.clearDeploymentHistory = function (appName, deploymentName) {\n        return this.del((_a = [\"/apps/\", \"/deployments/\", \"/history\"], _a.raw = [\"/apps/\", \"/deployments/\", \"/history\"], urlEncode(_a, appName, deploymentName)))\n            .then(function () { return null; });\n        var _a;\n    };\n    AccountManager.prototype.getDeployments = function (appName) {\n        return this.get((_a = [\"/apps/\", \"/deployments/\"], _a.raw = [\"/apps/\", \"/deployments/\"], urlEncode(_a, appName)))\n            .then(function (res) { return res.body.deployments; });\n        var _a;\n    };\n    AccountManager.prototype.getDeployment = function (appName, deploymentName) {\n        return this.get((_a = [\"/apps/\", \"/deployments/\", \"\"], _a.raw = [\"/apps/\", \"/deployments/\", \"\"], urlEncode(_a, appName, deploymentName)))\n            .then(function (res) { return res.body.deployment; });\n        var _a;\n    };\n    AccountManager.prototype.renameDeployment = function (appName, oldDeploymentName, newDeploymentName) {\n        return this.patch((_a = [\"/apps/\", \"/deployments/\", \"\"], _a.raw = [\"/apps/\", \"/deployments/\", \"\"], urlEncode(_a, appName, oldDeploymentName)), JSON.stringify({ name: newDeploymentName }))\n            .then(function () { return null; });\n        var _a;\n    };\n    AccountManager.prototype.removeDeployment = function (appName, deploymentName) {\n        return this.del((_a = [\"/apps/\", \"/deployments/\", \"\"], _a.raw = [\"/apps/\", \"/deployments/\", \"\"], urlEncode(_a, appName, deploymentName)))\n            .then(function () { return null; });\n        var _a;\n    };\n    AccountManager.prototype.getDeploymentMetrics = function (appName, deploymentName) {\n        return this.get((_a = [\"/apps/\", \"/deployments/\", \"/metrics\"], _a.raw = [\"/apps/\", \"/deployments/\", \"/metrics\"], urlEncode(_a, appName, deploymentName)))\n            .then(function (res) { return res.body.metrics; });\n        var _a;\n    };\n    AccountManager.prototype.getDeploymentHistory = function (appName, deploymentName) {\n        return this.get((_a = [\"/apps/\", \"/deployments/\", \"/history\"], _a.raw = [\"/apps/\", \"/deployments/\", \"/history\"], urlEncode(_a, appName, deploymentName)))\n            .then(function (res) { return res.body.history; });\n        var _a;\n    };\n    AccountManager.prototype.release = function (appName, deploymentName, fileOrPath, targetBinaryVersion, updateMetadata, uploadProgressCallback) {\n        var _this = this;\n        return Promise(function (resolve, reject, notify) {\n            updateMetadata.appVersion = targetBinaryVersion;\n            var request = superagent.post(_this._serverUrl + (_a = [\"/apps/\", \"/deployments/\", \"/release\"], _a.raw = [\"/apps/\", \"/deployments/\", \"/release\"], urlEncode(_a, appName, deploymentName)));\n            if (_this._proxy)\n                request.proxy(_this._proxy);\n            _this.attachCredentials(request);\n            var file;\n            if (typeof fileOrPath === \"string\") {\n                file = fs.createReadStream(fileOrPath);\n            }\n            else {\n                file = fileOrPath;\n            }\n            request.attach(\"package\", file)\n                .field(\"packageInfo\", JSON.stringify(updateMetadata))\n                .on(\"progress\", function (event) {\n                if (uploadProgressCallback && event && event.total > 0) {\n                    var currentProgress = event.loaded / event.total * 100;\n                    uploadProgressCallback(currentProgress);\n                }\n            })\n                .end(function (err, res) {\n                if (err) {\n                    reject({ message: _this.getErrorMessage(err, res) });\n                    return;\n                }\n                if (res.ok) {\n                    resolve(null);\n                }\n                else {\n                    try {\n                        var body = JSON.parse(res.text);\n                    }\n                    catch (err) {\n                    }\n                    if (body) {\n                        reject(body);\n                    }\n                    else {\n                        reject({ message: res.text, statusCode: res.status });\n                    }\n                }\n            });\n            var _a;\n        });\n    };\n    AccountManager.prototype.patchRelease = function (appName, deploymentName, label, updateMetadata) {\n        updateMetadata.label = label;\n        var requestBody = JSON.stringify({ packageInfo: updateMetadata });\n        return this.patch((_a = [\"/apps/\", \"/deployments/\", \"/release\"], _a.raw = [\"/apps/\", \"/deployments/\", \"/release\"], urlEncode(_a, appName, deploymentName)), requestBody, false)\n            .then(function () { return null; });\n        var _a;\n    };\n    AccountManager.prototype.promote = function (appName, sourceDeploymentName, destinationDeploymentName, updateMetadata) {\n        var requestBody = JSON.stringify({ packageInfo: updateMetadata });\n        return this.post((_a = [\"/apps/\", \"/deployments/\", \"/promote/\", \"\"], _a.raw = [\"/apps/\", \"/deployments/\", \"/promote/\", \"\"], urlEncode(_a, appName, sourceDeploymentName, destinationDeploymentName)), requestBody, false)\n            .then(function () { return null; });\n        var _a;\n    };\n    AccountManager.prototype.rollback = function (appName, deploymentName, targetRelease) {\n        return this.post((_a = [\"/apps/\", \"/deployments/\", \"/rollback/\", \"\"], _a.raw = [\"/apps/\", \"/deployments/\", \"/rollback/\", \"\"], urlEncode(_a, appName, deploymentName, targetRelease || \"\")), null, false)\n            .then(function () { return null; });\n        var _a;\n    };\n    AccountManager.prototype.get = function (endpoint, expectResponseBody) {\n        if (expectResponseBody === void 0) { expectResponseBody = true; }\n        return this.makeApiRequest(\"get\", endpoint, null, expectResponseBody, null);\n    };\n    AccountManager.prototype.post = function (endpoint, requestBody, expectResponseBody, contentType) {\n        if (contentType === void 0) { contentType = \"application/json;charset=UTF-8\"; }\n        return this.makeApiRequest(\"post\", endpoint, requestBody, expectResponseBody, contentType);\n    };\n    AccountManager.prototype.patch = function (endpoint, requestBody, expectResponseBody, contentType) {\n        if (expectResponseBody === void 0) { expectResponseBody = false; }\n        if (contentType === void 0) { contentType = \"application/json;charset=UTF-8\"; }\n        return this.makeApiRequest(\"patch\", endpoint, requestBody, expectResponseBody, contentType);\n    };\n    AccountManager.prototype.del = function (endpoint, expectResponseBody) {\n        if (expectResponseBody === void 0) { expectResponseBody = false; }\n        return this.makeApiRequest(\"del\", endpoint, null, expectResponseBody, null);\n    };\n    AccountManager.prototype.makeApiRequest = function (method, endpoint, requestBody, expectResponseBody, contentType) {\n        var _this = this;\n        return Promise(function (resolve, reject, notify) {\n            var request = superagent[method](_this._serverUrl + endpoint);\n            if (_this._proxy)\n                request.proxy(_this._proxy);\n            _this.attachCredentials(request);\n            if (requestBody) {\n                if (contentType) {\n                    request = request.set(\"Content-Type\", contentType);\n                }\n                request = request.send(requestBody);\n            }\n            request.end(function (err, res) {\n                if (err) {\n                    reject({ message: _this.getErrorMessage(err, res) });\n                    return;\n                }\n                try {\n                    var body = JSON.parse(res.text);\n                }\n                catch (err) {\n                }\n                if (res.ok) {\n                    if (expectResponseBody && !body) {\n                        reject({ message: \"Could not parse response: \" + res.text, statusCode: res.status });\n                    }\n                    else {\n                        resolve({\n                            headers: res.header,\n                            body: body\n                        });\n                    }\n                }\n                else {\n                    if (body) {\n                        reject(body);\n                    }\n                    else {\n                        reject({ message: res.text, statusCode: res.status });\n                    }\n                }\n            });\n        });\n    };\n    AccountManager.prototype.getErrorMessage = function (error, response) {\n        return response && response.text ? response.text : error.message;\n    };\n    AccountManager.prototype.attachCredentials = function (request) {\n        if (this._customHeaders) {\n            for (var headerName in this._customHeaders) {\n                request.set(headerName, this._customHeaders[headerName]);\n            }\n        }\n        request.set(\"Accept\", \"application/vnd.code-push.v\" + AccountManager.API_VERSION + \"+json\");\n        request.set(\"Authorization\", \"Bearer \" + this._accessKey);\n        request.set(\"X-CodePush-SDK-Version\", packageJson.version);\n    };\n    AccountManager.AppPermission = {\n        OWNER: \"Owner\",\n        COLLABORATOR: \"Collaborator\"\n    };\n    AccountManager.SERVER_URL = \"https://codepush-management.azurewebsites.net\";\n    AccountManager.API_VERSION = 2;\n    return AccountManager;\n})();\nmodule.exports = AccountManager;\n"
  },
  {
    "path": "plugins/code-push/script/types.js",
    "content": "\n"
  },
  {
    "path": "plugins/code-push/test/acquisition-rest-mock.js",
    "content": "/// <reference path=\"../definitions/harness.d.ts\" />\nvar querystring = require(\"querystring\");\nvar acquisitionSdk = require(\"../script/acquisition-sdk\");\nexports.validDeploymentKey = \"asdfasdfawerqw\";\nexports.latestPackage = {\n    downloadURL: \"http://www.windowsazure.com/blobs/awperoiuqpweru\",\n    description: \"Angry flappy birds\",\n    appVersion: \"1.5.0\",\n    label: \"2.4.0\",\n    isMandatory: false,\n    isAvailable: true,\n    updateAppVersion: false,\n    packageHash: \"hash240\",\n    packageSize: 1024\n};\nexports.serverUrl = \"http://myurl.com\";\nvar reportStatusDeployUrl = exports.serverUrl + \"/reportStatus/deploy\";\nvar reportStatusDownloadUrl = exports.serverUrl + \"/reportStatus/download\";\nvar updateCheckUrl = exports.serverUrl + \"/updateCheck?\";\nvar HttpRequester = (function () {\n    function HttpRequester() {\n    }\n    HttpRequester.prototype.request = function (verb, url, requestBodyOrCallback, callback) {\n        if (!callback && typeof requestBodyOrCallback === \"function\") {\n            callback = requestBodyOrCallback;\n        }\n        if (verb === 0 /* GET */ && url.indexOf(updateCheckUrl) === 0) {\n            var params = querystring.parse(url.substring(updateCheckUrl.length));\n            Server.onUpdateCheck(params, callback);\n        }\n        else if (verb === 2 /* POST */ && url === reportStatusDeployUrl) {\n            Server.onReportStatus(callback);\n        }\n        else if (verb === 2 /* POST */ && url === reportStatusDownloadUrl) {\n            Server.onReportStatus(callback);\n        }\n        else {\n            throw new Error(\"Unexpected call\");\n        }\n    };\n    return HttpRequester;\n})();\nexports.HttpRequester = HttpRequester;\nvar CustomResponseHttpRequester = (function () {\n    function CustomResponseHttpRequester(response) {\n        this.response = response;\n    }\n    CustomResponseHttpRequester.prototype.request = function (verb, url, requestBodyOrCallback, callback) {\n        if (typeof requestBodyOrCallback !== \"function\") {\n            throw new Error(\"Unexpected request body\");\n        }\n        callback = requestBodyOrCallback;\n        callback(null, this.response);\n    };\n    return CustomResponseHttpRequester;\n})();\nexports.CustomResponseHttpRequester = CustomResponseHttpRequester;\nvar Server = (function () {\n    function Server() {\n    }\n    Server.onAcquire = function (params, callback) {\n        if (params.deploymentKey !== exports.validDeploymentKey) {\n            callback(null, {\n                statusCode: 200,\n                body: JSON.stringify({ updateInfo: { isAvailable: false } })\n            });\n        }\n        else {\n            callback(null, {\n                statusCode: 200,\n                body: JSON.stringify({ updateInfo: exports.latestPackage })\n            });\n        }\n    };\n    Server.onUpdateCheck = function (params, callback) {\n        var updateRequest = {\n            deploymentKey: params.deploymentKey,\n            appVersion: params.appVersion,\n            packageHash: params.packageHash,\n            isCompanion: !!(params.isCompanion),\n            label: params.label\n        };\n        if (!updateRequest.deploymentKey || !updateRequest.appVersion) {\n            callback(null, { statusCode: 400 });\n        }\n        else {\n            var updateInfo = { isAvailable: false };\n            if (updateRequest.deploymentKey === exports.validDeploymentKey) {\n                if (updateRequest.isCompanion || updateRequest.appVersion === exports.latestPackage.appVersion) {\n                    if (updateRequest.packageHash !== exports.latestPackage.packageHash) {\n                        updateInfo = exports.latestPackage;\n                    }\n                }\n                else if (updateRequest.appVersion < exports.latestPackage.appVersion) {\n                    updateInfo = { updateAppVersion: true, appVersion: exports.latestPackage.appVersion };\n                }\n            }\n            callback(null, {\n                statusCode: 200,\n                body: JSON.stringify({ updateInfo: updateInfo })\n            });\n        }\n    };\n    Server.onReportStatus = function (callback) {\n        callback(null, { statusCode: 200 });\n    };\n    return Server;\n})();\n"
  },
  {
    "path": "plugins/code-push/test/acquisition-sdk.js",
    "content": "/// <reference path=\"../definitions/harness.d.ts\" />\nvar assert = require(\"assert\");\nvar acquisitionSdk = require(\"../script/acquisition-sdk\");\nvar mockApi = require(\"./acquisition-rest-mock\");\nvar latestPackage = clone(mockApi.latestPackage);\nvar configuration = {\n    appVersion: \"1.5.0\",\n    clientUniqueId: \"My iPhone\",\n    deploymentKey: mockApi.validDeploymentKey,\n    serverUrl: mockApi.serverUrl,\n};\nvar templateCurrentPackage = {\n    deploymentKey: mockApi.validDeploymentKey,\n    description: \"sdfsdf\",\n    label: \"v1\",\n    appVersion: latestPackage.appVersion,\n    packageHash: \"hash001\",\n    isMandatory: false,\n    packageSize: 100\n};\nvar scriptUpdateResult = {\n    deploymentKey: mockApi.validDeploymentKey,\n    description: latestPackage.description,\n    downloadUrl: latestPackage.downloadURL,\n    label: latestPackage.label,\n    appVersion: latestPackage.appVersion,\n    isMandatory: latestPackage.isMandatory,\n    packageHash: latestPackage.packageHash,\n    packageSize: latestPackage.packageSize\n};\nvar nativeUpdateResult = {\n    updateAppVersion: true,\n    appVersion: latestPackage.appVersion\n};\ndescribe(\"Acquisition SDK\", function () {\n    beforeEach(function () {\n        mockApi.latestPackage = clone(latestPackage);\n    });\n    it(\"Package with lower label and different package hash gives update\", function (done) {\n        var acquisition = new acquisitionSdk.AcquisitionManager(new mockApi.HttpRequester(), configuration);\n        acquisition.queryUpdateWithCurrentPackage(templateCurrentPackage, function (error, returnPackage) {\n            assert.equal(null, error);\n            assert.deepEqual(scriptUpdateResult, returnPackage);\n            done();\n        });\n    });\n    it(\"Package with equal package hash gives no update\", function (done) {\n        var equalVersionPackage = clone(templateCurrentPackage);\n        equalVersionPackage.packageHash = latestPackage.packageHash;\n        var acquisition = new acquisitionSdk.AcquisitionManager(new mockApi.HttpRequester(), configuration);\n        acquisition.queryUpdateWithCurrentPackage(equalVersionPackage, function (error, returnPackage) {\n            assert.equal(null, error);\n            assert.equal(null, returnPackage);\n            done();\n        });\n    });\n    it(\"Package with higher different hash and higher label version gives update\", function (done) {\n        var higherVersionPackage = clone(templateCurrentPackage);\n        higherVersionPackage.packageHash = \"hash990\";\n        var acquisition = new acquisitionSdk.AcquisitionManager(new mockApi.HttpRequester(), configuration);\n        acquisition.queryUpdateWithCurrentPackage(higherVersionPackage, function (error, returnPackage) {\n            assert.equal(null, error);\n            assert.deepEqual(scriptUpdateResult, returnPackage);\n            done();\n        });\n    });\n    it(\"Package with lower native version gives update notification\", function (done) {\n        var lowerAppVersionPackage = clone(templateCurrentPackage);\n        lowerAppVersionPackage.appVersion = \"0.0.1\";\n        var acquisition = new acquisitionSdk.AcquisitionManager(new mockApi.HttpRequester(), configuration);\n        acquisition.queryUpdateWithCurrentPackage(lowerAppVersionPackage, function (error, returnPackage) {\n            assert.equal(null, error);\n            assert.deepEqual(nativeUpdateResult, returnPackage);\n            done();\n        });\n    });\n    it(\"Package with higher native version gives no update\", function (done) {\n        var higherAppVersionPackage = clone(templateCurrentPackage);\n        higherAppVersionPackage.appVersion = \"9.9.0\";\n        var acquisition = new acquisitionSdk.AcquisitionManager(new mockApi.HttpRequester(), configuration);\n        acquisition.queryUpdateWithCurrentPackage(higherAppVersionPackage, function (error, returnPackage) {\n            assert.equal(null, error);\n            assert.deepEqual(null, returnPackage);\n            done();\n        });\n    });\n    it(\"An empty response gives no update\", function (done) {\n        var lowerAppVersionPackage = clone(templateCurrentPackage);\n        lowerAppVersionPackage.appVersion = \"0.0.1\";\n        var emptyReponse = {\n            statusCode: 200,\n            body: JSON.stringify({})\n        };\n        var acquisition = new acquisitionSdk.AcquisitionManager(new mockApi.CustomResponseHttpRequester(emptyReponse), configuration);\n        acquisition.queryUpdateWithCurrentPackage(lowerAppVersionPackage, function (error, returnPackage) {\n            assert.equal(null, error);\n            done();\n        });\n    });\n    it(\"An unexpected (but valid) JSON response gives no update\", function (done) {\n        var lowerAppVersionPackage = clone(templateCurrentPackage);\n        lowerAppVersionPackage.appVersion = \"0.0.1\";\n        var unexpectedResponse = {\n            statusCode: 200,\n            body: JSON.stringify({ unexpected: \"response\" })\n        };\n        var acquisition = new acquisitionSdk.AcquisitionManager(new mockApi.CustomResponseHttpRequester(unexpectedResponse), configuration);\n        acquisition.queryUpdateWithCurrentPackage(lowerAppVersionPackage, function (error, returnPackage) {\n            assert.equal(null, error);\n            done();\n        });\n    });\n    it(\"Package for companion app ignores high native version and gives update\", function (done) {\n        var higherAppVersionCompanionPackage = clone(templateCurrentPackage);\n        higherAppVersionCompanionPackage.appVersion = \"9.9.0\";\n        var companionAppConfiguration = clone(configuration);\n        configuration.ignoreAppVersion = true;\n        var acquisition = new acquisitionSdk.AcquisitionManager(new mockApi.HttpRequester(), configuration);\n        acquisition.queryUpdateWithCurrentPackage(higherAppVersionCompanionPackage, function (error, returnPackage) {\n            assert.equal(null, error);\n            assert.deepEqual(scriptUpdateResult, returnPackage);\n            done();\n        });\n    });\n    it(\"If latest package is mandatory, returned package is mandatory\", function (done) {\n        mockApi.latestPackage.isMandatory = true;\n        var acquisition = new acquisitionSdk.AcquisitionManager(new mockApi.HttpRequester(), configuration);\n        acquisition.queryUpdateWithCurrentPackage(templateCurrentPackage, function (error, returnPackage) {\n            assert.equal(null, error);\n            assert.equal(true, returnPackage.isMandatory);\n            done();\n        });\n    });\n    it(\"If invalid arguments are provided, an error is raised\", function (done) {\n        var invalidPackage = clone(templateCurrentPackage);\n        invalidPackage.appVersion = null;\n        var acquisition = new acquisitionSdk.AcquisitionManager(new mockApi.HttpRequester(), configuration);\n        try {\n            acquisition.queryUpdateWithCurrentPackage(invalidPackage, function (error, returnPackage) {\n                assert.fail(\"Should throw an error if the native implementation gave an incorrect package\");\n                done();\n            });\n        }\n        catch (error) {\n            done();\n        }\n    });\n    it(\"If an invalid JSON response is returned by the server, an error is raised\", function (done) {\n        var lowerAppVersionPackage = clone(templateCurrentPackage);\n        lowerAppVersionPackage.appVersion = \"0.0.1\";\n        var invalidJsonReponse = {\n            statusCode: 200,\n            body: \"invalid {{ json\"\n        };\n        var acquisition = new acquisitionSdk.AcquisitionManager(new mockApi.CustomResponseHttpRequester(invalidJsonReponse), configuration);\n        acquisition.queryUpdateWithCurrentPackage(lowerAppVersionPackage, function (error, returnPackage) {\n            assert.notEqual(null, error);\n            done();\n        });\n    });\n    it(\"If deploymentKey is not valid...\", function (done) {\n        // TODO: behaviour is not defined\n        done();\n    });\n    it(\"reportStatusDeploy(...) signals completion\", function (done) {\n        var acquisition = new acquisitionSdk.AcquisitionManager(new mockApi.HttpRequester(), configuration);\n        acquisition.reportStatusDeploy(templateCurrentPackage, acquisitionSdk.AcquisitionStatus.DeploymentFailed, \"1.5.0\", mockApi.validDeploymentKey, (function (error, parameter) {\n            if (error) {\n                throw error;\n            }\n            assert.equal(parameter, null);\n            done();\n        }));\n    });\n    it(\"reportStatusDownload(...) signals completion\", function (done) {\n        var acquisition = new acquisitionSdk.AcquisitionManager(new mockApi.HttpRequester(), configuration);\n        acquisition.reportStatusDownload(templateCurrentPackage, (function (error, parameter) {\n            if (error) {\n                throw error;\n            }\n            assert.equal(parameter, null);\n            done();\n        }));\n    });\n});\nfunction clone(initialObject) {\n    return JSON.parse(JSON.stringify(initialObject));\n}\n"
  },
  {
    "path": "plugins/code-push/test/management-sdk.js",
    "content": "/// <reference path=\"../definitions/harness.d.ts\" />\nvar assert = require(\"assert\");\nvar Q = require(\"q\");\nvar AccountManager = require(\"../script/management-sdk\");\nvar request = require(\"superagent\");\nvar manager;\ndescribe(\"Management SDK\", function () {\n    beforeEach(function () {\n        manager = new AccountManager(\"dummyAccessKey\", null, \"http://localhost\");\n    });\n    after(function () {\n        // Prevent an exception that occurs due to how superagent-mock overwrites methods\n        request.Request.prototype._callback = function () { };\n    });\n    it(\"methods reject the promise with status code info when an error occurs\", function (done) {\n        mockReturn(\"Text\", 404);\n        var methodsWithErrorHandling = [\n            manager.addApp.bind(manager, \"appName\"),\n            manager.getApp.bind(manager, \"appName\"),\n            manager.renameApp.bind(manager, \"appName\", {}),\n            manager.removeApp.bind(manager, \"appName\"),\n            manager.transferApp.bind(manager, \"appName\", \"email1\"),\n            manager.addDeployment.bind(manager, \"appName\", \"deploymentName\"),\n            manager.getDeployment.bind(manager, \"appName\", \"deploymentName\"),\n            manager.getDeployments.bind(manager, \"appName\"),\n            manager.renameDeployment.bind(manager, \"appName\", \"deploymentName\", { name: \"newDeploymentName\" }),\n            manager.removeDeployment.bind(manager, \"appName\", \"deploymentName\"),\n            manager.addCollaborator.bind(manager, \"appName\", \"email1\"),\n            manager.getCollaborators.bind(manager, \"appName\"),\n            manager.removeCollaborator.bind(manager, \"appName\", \"email1\"),\n            manager.patchRelease.bind(manager, \"appName\", \"deploymentName\", \"label\", { description: \"newDescription\" }),\n            manager.promote.bind(manager, \"appName\", \"deploymentName\", \"newDeploymentName\", { description: \"newDescription\" }),\n            manager.rollback.bind(manager, \"appName\", \"deploymentName\", \"targetReleaseLabel\")\n        ];\n        var result = Q(null);\n        methodsWithErrorHandling.forEach(function (f) {\n            result = result.then(function () {\n                return testErrors(f);\n            });\n        });\n        result.done(function () {\n            done();\n        });\n        // Test that the proper error code and text is passed through on a server error\n        function testErrors(method) {\n            return Q.Promise(function (resolve, reject, notify) {\n                method().done(function () {\n                    assert.fail(\"Should have thrown an error\");\n                    reject();\n                }, function (error) {\n                    assert.equal(error.message, \"Text\");\n                    resolve();\n                });\n            });\n        }\n    });\n    it(\"isAuthenticated handles successful auth\", function (done) {\n        mockReturn(JSON.stringify({ authenticated: true }), 200, {});\n        manager.isAuthenticated()\n            .done(function (authenticated) {\n            assert(authenticated, \"Should be authenticated\");\n            done();\n        });\n    });\n    it(\"isAuthenticated handles unsuccessful auth\", function (done) {\n        mockReturn(\"Unauthorized\", 401, {});\n        manager.isAuthenticated()\n            .done(function (authenticated) {\n            assert(!authenticated, \"Should not be authenticated\");\n            done();\n        });\n    });\n    it(\"isAuthenticated handles unexpected status codes\", function (done) {\n        mockReturn(\"Not Found\", 404, {});\n        manager.isAuthenticated()\n            .done(function (authenticated) {\n            assert.fail(\"isAuthenticated should have rejected the promise\");\n            done();\n        }, function (err) {\n            assert.equal(err.message, \"Not Found\", \"Error message should be 'Not Found'\");\n            done();\n        });\n    });\n    it(\"addApp handles successful response\", function (done) {\n        mockReturn(JSON.stringify({ success: true }), 201, { location: \"/appName\" });\n        manager.addApp(\"appName\")\n            .done(function (obj) {\n            assert.ok(obj);\n            done();\n        }, rejectHandler);\n    });\n    it(\"addApp handles error response\", function (done) {\n        mockReturn(JSON.stringify({ success: false }), 404, {});\n        manager.addApp(\"appName\")\n            .done(function (obj) {\n            throw new Error(\"Call should not complete successfully\");\n        }, function (error) { return done(); });\n    });\n    it(\"getApp handles JSON response\", function (done) {\n        mockReturn(JSON.stringify({ app: {} }), 200, {});\n        manager.getApp(\"appName\")\n            .done(function (obj) {\n            assert.ok(obj);\n            done();\n        }, rejectHandler);\n    });\n    it(\"updateApp handles success response\", function (done) {\n        mockReturn(JSON.stringify({ apps: [] }), 200, {});\n        manager.renameApp(\"appName\", \"newAppName\")\n            .done(function (obj) {\n            assert.ok(!obj);\n            done();\n        }, rejectHandler);\n    });\n    it(\"removeApp handles success response\", function (done) {\n        mockReturn(\"\", 200, {});\n        manager.removeApp(\"appName\")\n            .done(function (obj) {\n            assert.ok(!obj);\n            done();\n        }, rejectHandler);\n    });\n    it(\"transferApp handles successful response\", function (done) {\n        mockReturn(\"\", 201);\n        manager.transferApp(\"appName\", \"email1\")\n            .done(function (obj) {\n            assert.ok(!obj);\n            done();\n        }, rejectHandler);\n    });\n    it(\"addDeployment handles success response\", function (done) {\n        mockReturn(JSON.stringify({ deployment: { name: \"name\", key: \"key\" } }), 201, { location: \"/deploymentName\" });\n        manager.addDeployment(\"appName\", \"deploymentName\")\n            .done(function (obj) {\n            assert.ok(obj);\n            done();\n        }, rejectHandler);\n    });\n    it(\"getDeployment handles JSON response\", function (done) {\n        mockReturn(JSON.stringify({ deployment: {} }), 200, {});\n        manager.getDeployment(\"appName\", \"deploymentName\")\n            .done(function (obj) {\n            assert.ok(obj);\n            done();\n        }, rejectHandler);\n    });\n    it(\"getDeployments handles JSON response\", function (done) {\n        mockReturn(JSON.stringify({ deployments: [] }), 200, {});\n        manager.getDeployments(\"appName\")\n            .done(function (obj) {\n            assert.ok(obj);\n            done();\n        }, rejectHandler);\n    });\n    it(\"renameDeployment handles success response\", function (done) {\n        mockReturn(JSON.stringify({ apps: [] }), 200, {});\n        manager.renameDeployment(\"appName\", \"deploymentName\", \"newDeploymentName\")\n            .done(function (obj) {\n            assert.ok(!obj);\n            done();\n        }, rejectHandler);\n    });\n    it(\"removeDeployment handles success response\", function (done) {\n        mockReturn(\"\", 200, {});\n        manager.removeDeployment(\"appName\", \"deploymentName\")\n            .done(function (obj) {\n            assert.ok(!obj);\n            done();\n        }, rejectHandler);\n    });\n    it(\"getDeploymentHistory handles success response with no packages\", function (done) {\n        mockReturn(JSON.stringify({ history: [] }), 200);\n        manager.getDeploymentHistory(\"appName\", \"deploymentName\")\n            .done(function (obj) {\n            assert.ok(obj);\n            assert.equal(obj.length, 0);\n            done();\n        }, rejectHandler);\n    });\n    it(\"getDeploymentHistory handles success response with two packages\", function (done) {\n        mockReturn(JSON.stringify({ history: [{ label: \"v1\" }, { label: \"v2\" }] }), 200);\n        manager.getDeploymentHistory(\"appName\", \"deploymentName\")\n            .done(function (obj) {\n            assert.ok(obj);\n            assert.equal(obj.length, 2);\n            assert.equal(obj[0].label, \"v1\");\n            assert.equal(obj[1].label, \"v2\");\n            done();\n        }, rejectHandler);\n    });\n    it(\"getDeploymentHistory handles error response\", function (done) {\n        mockReturn(\"\", 404);\n        manager.getDeploymentHistory(\"appName\", \"deploymentName\")\n            .done(function (obj) {\n            throw new Error(\"Call should not complete successfully\");\n        }, function (error) { return done(); });\n    });\n    it(\"clearDeploymentHistory handles success response\", function (done) {\n        mockReturn(\"\", 204);\n        manager.clearDeploymentHistory(\"appName\", \"deploymentName\")\n            .done(function (obj) {\n            assert.ok(!obj);\n            done();\n        }, rejectHandler);\n    });\n    it(\"clearDeploymentHistory handles error response\", function (done) {\n        mockReturn(\"\", 404);\n        manager.clearDeploymentHistory(\"appName\", \"deploymentName\")\n            .done(function (obj) {\n            throw new Error(\"Call should not complete successfully\");\n        }, function (error) { return done(); });\n    });\n    it(\"addCollaborator handles successful response\", function (done) {\n        mockReturn(\"\", 201, { location: \"/collaborators\" });\n        manager.addCollaborator(\"appName\", \"email1\")\n            .done(function (obj) {\n            assert.ok(!obj);\n            done();\n        }, rejectHandler);\n    });\n    it(\"addCollaborator handles error response\", function (done) {\n        mockReturn(\"\", 404, {});\n        manager.addCollaborator(\"appName\", \"email1\")\n            .done(function (obj) {\n            throw new Error(\"Call should not complete successfully\");\n        }, function (error) { return done(); });\n    });\n    it(\"getCollaborators handles success response with no collaborators\", function (done) {\n        mockReturn(JSON.stringify({ collaborators: {} }), 200);\n        manager.getCollaborators(\"appName\")\n            .done(function (obj) {\n            assert.ok(obj);\n            assert.equal(Object.keys(obj).length, 0);\n            done();\n        }, rejectHandler);\n    });\n    it(\"getCollaborators handles success response with multiple collaborators\", function (done) {\n        mockReturn(JSON.stringify({\n            collaborators: {\n                \"email1\": { permission: \"Owner\", isCurrentAccount: true },\n                \"email2\": { permission: \"Collaborator\", isCurrentAccount: false }\n            }\n        }), 200);\n        manager.getCollaborators(\"appName\")\n            .done(function (obj) {\n            assert.ok(obj);\n            assert.equal(obj[\"email1\"].permission, \"Owner\");\n            assert.equal(obj[\"email2\"].permission, \"Collaborator\");\n            done();\n        }, rejectHandler);\n    });\n    it(\"removeCollaborator handles success response\", function (done) {\n        mockReturn(\"\", 200, {});\n        manager.removeCollaborator(\"appName\", \"email1\")\n            .done(function (obj) {\n            assert.ok(!obj);\n            done();\n        }, rejectHandler);\n    });\n    it(\"patchRelease handles success response\", function (done) {\n        mockReturn(JSON.stringify({ package: { description: \"newDescription\" } }), 200);\n        manager.patchRelease(\"appName\", \"deploymentName\", \"label\", { description: \"newDescription\" })\n            .done(function (obj) {\n            assert.ok(!obj);\n            done();\n        }, rejectHandler);\n    });\n    it(\"patchRelease handles error response\", function (done) {\n        mockReturn(\"\", 400);\n        manager.patchRelease(\"appName\", \"deploymentName\", \"label\", {})\n            .done(function (obj) {\n            throw new Error(\"Call should not complete successfully\");\n        }, function (error) { return done(); });\n    });\n    it(\"promote handles success response\", function (done) {\n        mockReturn(JSON.stringify({ package: { description: \"newDescription\" } }), 200);\n        manager.promote(\"appName\", \"deploymentName\", \"newDeploymentName\", { description: \"newDescription\" })\n            .done(function (obj) {\n            assert.ok(!obj);\n            done();\n        }, rejectHandler);\n    });\n    it(\"promote handles error response\", function (done) {\n        mockReturn(\"\", 400);\n        manager.promote(\"appName\", \"deploymentName\", \"newDeploymentName\", { rollout: 123 })\n            .done(function (obj) {\n            throw new Error(\"Call should not complete successfully\");\n        }, function (error) { return done(); });\n    });\n    it(\"rollback handles success response\", function (done) {\n        mockReturn(JSON.stringify({ package: { label: \"v1\" } }), 200);\n        manager.rollback(\"appName\", \"deploymentName\", \"v1\")\n            .done(function (obj) {\n            assert.ok(!obj);\n            done();\n        }, rejectHandler);\n    });\n    it(\"rollback handles error response\", function (done) {\n        mockReturn(\"\", 400);\n        manager.rollback(\"appName\", \"deploymentName\", \"v1\")\n            .done(function (obj) {\n            throw new Error(\"Call should not complete successfully\");\n        }, function (error) { return done(); });\n    });\n});\n// Helper method that is used everywhere that an assert.fail() is needed in a promise handler\nfunction rejectHandler(val) {\n    assert.fail();\n}\n// Wrapper for superagent-mock that abstracts away information not needed for SDK tests\nfunction mockReturn(bodyText, statusCode, header) {\n    if (header === void 0) { header = {}; }\n    require(\"superagent-mock\")(request, [{\n            pattern: \"http://localhost/(\\\\w+)/?\",\n            fixtures: function (match, params) {\n                var isOk = statusCode >= 200 && statusCode < 300;\n                if (!isOk) {\n                    var err = new Error(bodyText);\n                    err.status = statusCode;\n                    throw err;\n                }\n                return { text: bodyText, status: statusCode, ok: isOk, header: header, headers: {} };\n            },\n            callback: function (match, data) { return data; }\n        }]);\n}\n"
  },
  {
    "path": "plugins/code-push/test/superagent-mock-config.js",
    "content": "// ./superagent-mock-config.js file\nmodule.exports = [\n  {\n      pattern: 'http://localhost/(\\\\w+)/',\n\n      /**\n       * returns the data\n       *\n       * @param match array Result of the resolution of the regular expression\n       * @param params object sent by 'send' function\n       */\n      fixtures: function (match, params) {\n          return {text: \"Error\", status: 403, ok: false};\n\n          /**\n           * example: \n           *   request.get('https://error.example/404').end(function(err, res){\n           *     console.log(err); // 404\n           *   }) \n           */ \n          if (match[1] === '404') {\n              throw new Error(404);\n          }\n\n          /**\n           * example: \n           *   request.get('https://error.example/200').end(function(err, res){\n           *     console.log(res.body); // \"Data fixtures\"\n           *   })\n           */\n\n          /**\n           * example: \n           *   request.get('https://domain.send.example/').send({superhero: \"me\"}).end(function(err, res){\n           *     console.log(res.body); // \"Data fixtures - superhero:me\"\n           *   }) \n           */\n          if(params[\"superhero\"]) {\n              return 'Data fixtures - superhero:' + params[\"superhero\"];\n          } else {\n              return 'Data fixtures';\n          }\n      },\n\n      /**\n       * returns the result of the request\n       *\n       * @param match array Result of the resolution of the regular expression\n       * @param data  mixed Data returns by `fixtures` attribute\n       */\n      callback: function (match, data) {\n          return data;\n      }\n  },\n];"
  },
  {
    "path": "plugins/cordova-plugin-appavailability/README.md",
    "content": "# AppAvailability for iOS and Android\n\n`Version 0.4.2`\n\nA Plugin for Apache Cordova and Adobe PhoneGap by [ohh2ahh](http://ohh2ahh.com).\n\n1. [Description](https://github.com/ohh2ahh/AppAvailability#1-description)\n2. [Installation](https://github.com/ohh2ahh/AppAvailability#2-installation)\n\t2. [Automatically (Command-line Interface)](https://github.com/ohh2ahh/AppAvailability#automatically-command-line-interface)\n\t2. [PhoneGap Build](https://github.com/ohh2ahh/AppAvailability#phonegap-build)\n3. [Usage](https://github.com/ohh2ahh/AppAvailability#3-usage)\n\t3. [iOS](https://github.com/ohh2ahh/AppAvailability#ios)\n\t3. [Android](https://github.com/ohh2ahh/AppAvailability#android)\n\t3. [Full Example](https://github.com/ohh2ahh/AppAvailability#full-example)\n\t3. [Old Approach (AppAvailability < 0.3.0)](https://github.com/ohh2ahh/AppAvailability#old-approach-appavailability--030)\n4. [Some URI Schemes / Package Names](https://github.com/ohh2ahh/AppAvailability#4-some-uri-schemes--package-names)\n5. [License](https://github.com/ohh2ahh/AppAvailability#5-license)\n\n## Important: iOS 9 URL Scheme Whitelist\nApple changed the `canOpenURL` method on iOS 9. Apps which are checking for URL Schemes have to declare these Schemes as it is submitted to Apple. The article [Quick Take on iOS 9 URL Scheme Changes](http://awkwardhare.com/post/121196006730/quick-take-on-ios-9-url-scheme-changes) expains the changes in detail.\n\n### Add URL Schemes to the Whitelist\nSimply open your app's .plist (usually `platforms/ios/<appname>/<appname>-Info.plist)` with an editor and add the following code with your needed Schemes.\n\n```xml\n<key>LSApplicationQueriesSchemes</key>\n<array>\n    <string>twitter</string>\n    <string>whatsapp</string>\n</array>\n```\n\n## 1. Description\n\nThis plugin allows you to check if an app is installed on the user's device.\nIt requires an URI Scheme (e.g. twitter://) on iOS or a Package Name (e.g com.twitter.android) on Android.\n\n* Ready for the Command-line Interface of Cordova / PhoneGap 3.0 and later\n* Works with PhoneGap Build ([more information](https://build.phonegap.com/plugins/17))\n\n### Supported Platforms\n\n* iOS\n* Android\n\n## 2. Installation\n\nThe Cordova CLI is the recommended way to install AppAvailability, see [The Command-line Interface](http://cordova.apache.org/docs/en/4.0.0/guide_cli_index.md.html#The%20Command-Line%20Interface). You can find the plugin on these registries:\n* [GitHub](https://github.com/ohh2ahh/AppAvailability)\n* [npm](https://www.npmjs.com/package/cordova-plugin-appavailability)\n* [Cordova Plugin Registry](http://plugins.cordova.io/#/package/com.ohh2ahh.plugins.appavailability) (deprecated [in favor of npm](http://cordova.apache.org/announcements/2015/04/21/plugins-release-and-move-to-npm.html))\n* [PhoneGap Plugin Registry](https://build.phonegap.com/plugins/1054) (deprecated because updating a plugin on PhoneGap Build requires a paid plan now)\n\n### Automatically (Command-line Interface)\n\nSimply run this command to add the latest version of AppAvailability from [npm](https://www.npmjs.com/package/cordova-plugin-appavailability) to your project:\n```\n$ cordova plugin add cordova-plugin-appavailability\n```\n\nDon't forget to prepare and compile your project:\n```\n$ cordova build\n```\n\nYou don't have to reference the JavaScript in your `index.html`.\n\nAlternatively you can install AppAvailability from [GitHub](https://github.com/ohh2ahh/AppAvailability):\n```\n$ cordova plugin add https://github.com/ohh2ahh/AppAvailability.git\n```\n\n### PhoneGap Build\n\nAppAvailability works with PhoneGap build too. **Unfortunately PhoneGap Build requires now a paid plan to update a plugin. Therefore the version on PhoneGap Build is deprecated.**\n\nYou can implement version `0.3.1` of the plugin by adding the following xml to your `config.xml`:\n```xml\n<gap:plugin name=\"com.ohh2ahh.plugins.appavailability\" />\n```\nOr if you want to use the exact version of AppAvailability:\n```xml\n<gap:plugin name=\"com.ohh2ahh.plugins.appavailability\" version=\"0.3.1\" />\n```\n\nThere is no need to reference the JavaScript in your `index.html`.\n\nYou can find a PhoneGap Build project which demonstrates AppAvailability in the repository [ohh2ahh/AppAvailability-Demo-PhoneGap-Build](https://github.com/ohh2ahh/AppAvailability-Demo-PhoneGap-Build).\n\n## 3. Usage\n\n:exclamation: The code changed in version 0.3.0 and supports now success and error callbacks! But you can still use the old approach, which is [described below](https://github.com/ohh2ahh/AppAvailability#old-approach-appavailability--030).\n\n### iOS\n\n```javascript\nappAvailability.check(\n    'twitter://', // URI Scheme\n    function() {  // Success callback\n        console.log('Twitter is available');\n    },\n    function() {  // Error callback\n        console.log('Twitter is not available');\n    }\n);\n```\n\n### Android\n\n```javascript\nappAvailability.check(\n    'com.twitter.android', // Package Name\n    function() {           // Success callback\n        console.log('Twitter is available');\n    },\n    function() {           // Error callback\n        console.log('Twitter is not available');\n    }\n);\n```\n\n### Full Example\n\n```javascript\nvar scheme;\n\n// Don't forget to add the org.apache.cordova.device plugin!\nif(device.platform === 'iOS') {\n    scheme = 'twitter://';\n}\nelse if(device.platform === 'Android') {\n    scheme = 'com.twitter.android';\n}\n\nappAvailability.check(\n    scheme,       // URI Scheme or Package Name\n    function() {  // Success callback\n        console.log(scheme + ' is available :)');\n    },\n    function() {  // Error callback\n        console.log(scheme + ' is not available :(');\n    }\n);\n```\n\n### Old Approach (AppAvailability < 0.3.0)\n\nThe only thing you have to do is replacing `appAvailability.check` with `appAvailability.checkBool`:\n\n```javascript\nappAvailability.checkBool('twitter://', function(availability) {\n    // availability is either true or false\n    if(availability) { console.log('Twitter is available'); }\n});\n```\n\n## 4. Some URI Schemes / Package Names\n\n[How do I get the URI Scheme / Package Name?](https://github.com/ohh2ahh/AppAvailability/issues/2#issuecomment-22203591)\n\nTwitter:\n* iOS: `twitter://` ([more Schemes](http://wiki.akosma.com/IPhone_URL_Schemes#Twitter))\n* Android: `com.twitter.android`\n\nFacebook:\n* iOS: `fb://` (and [many more](http://wiki.akosma.com/IPhone_URL_Schemes#Facebook) as `fb://profile`)\n* Android: `com.facebook.katana`\n\nWhatsApp:\n* iOS: `whatsapp://` (only since v. 2.10.1, [more information](http://www.whatsapp.com/faq/en/iphone/23559013))\n* Android: `com.whatsapp`\n\n## 5. License\n\n[The MIT License (MIT)](http://www.opensource.org/licenses/mit-license.html)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE."
  },
  {
    "path": "plugins/cordova-plugin-appavailability/package.json",
    "content": "{\n  \"name\": \"cordova-plugin-appavailability\",\n  \"version\": \"0.4.2\",\n  \"description\": \"This plugin for Cordova and PhoneGap allows you to check if an app is installed. It requires an URI Scheme (iOS) or a Package Name (Android).\",\n  \"cordova\": {\n    \"id\": \"cordova-plugin-appavailability\",\n    \"platforms\": [\n      \"ios\",\n      \"android\"\n    ]\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/ohh2ahh/AppAvailability.git\"\n  },\n  \"keywords\": [\n    \"Cordova\",\n    \"PhoneGap\",\n    \"plugin\",\n    \"app\",\n    \"availability\",\n    \"installed\",\n    \"URIScheme\",\n    \"URI\",\n    \"Scheme\",\n    \"PackageName\",\n    \"Package\",\n    \"Name\",\n    \"iOS\",\n    \"Android\",\n    \"ecosystem:cordova\",\n    \"cordova-ios\",\n    \"cordova-android\"\n  ],\n  \"engines\": [\n    {\n      \"name\": \"cordova\",\n      \"version\": \">=3.0.0\"\n    }\n  ],\n  \"author\": \"ohh2ahh\",\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/ohh2ahh/AppAvailability/issues\"\n  },\n  \"homepage\": \"https://github.com/ohh2ahh/AppAvailability#readme\"\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-appavailability/plugin.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<plugin xmlns=\"http://apache.org/cordova/ns/plugins/1.0\"\n        xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        id=\"cordova-plugin-appavailability\"\n        version=\"0.4.2\">\n    \n    <name>AppAvailability</name>\n    \n    <description>This plugin for Cordova and PhoneGap allows you to check if an app is installed. It requires an URI Scheme (iOS) or a Package Name (Android).</description>\n    \n    <keywords>Cordova,PhoneGap,plugin,app,availability,installed, URIScheme,URI,Scheme,PackageName,Package,Name,iOS,Android</keywords>\n    \n    <repo>https://github.com/ohh2ahh/AppAvailability.git</repo>\n    <issue>https://github.com/ohh2ahh/AppAvailability/issues</issue>\n    \n    <license>MIT</license>\n    \n    <engines>\n        <engine name=\"cordova\" version=\">=3.0.0\" />\n    </engines>\n    \n    <js-module src=\"www/AppAvailability.js\" name=\"AppAvailability\">\n        <clobbers target=\"appAvailability\" />\n    </js-module>\n    \n    <!-- iOS -->\n    <platform name=\"ios\">\n        <config-file target=\"config.xml\" parent=\"/*\">\n            <feature name=\"AppAvailability\">\n                <param name=\"ios-package\" value=\"AppAvailability\" />\n            </feature>\n        </config-file>\n        \n        <header-file src=\"src/ios/AppAvailability.h\" />\n        <source-file src=\"src/ios/AppAvailability.m\" />\n    </platform>\n    \n    <!-- Android -->\n    <platform name=\"android\">\n        <config-file target=\"res/xml/config.xml\" parent=\"/*\">\n            <feature name=\"AppAvailability\">\n                <param name=\"android-package\" value=\"com.ohh2ahh.appavailability.AppAvailability\" />\n            </feature>\n        </config-file>\n        \n        <source-file src=\"src/android/AppAvailability.java\" target-dir=\"src/com/ohh2ahh/appavailability/\" />\n    </platform>\n    \n</plugin>"
  },
  {
    "path": "plugins/cordova-plugin-appavailability/src/android/AppAvailability.java",
    "content": "package com.ohh2ahh.appavailability;\n\nimport org.apache.cordova.CallbackContext;\nimport org.apache.cordova.CordovaPlugin;\nimport org.json.JSONArray;\nimport org.json.JSONException;\n\nimport android.content.Context;\nimport android.content.pm.PackageManager;\n\npublic class AppAvailability extends CordovaPlugin {\n    @Override\n    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {\n        if(action.equals(\"checkAvailability\")) {\n            String uri = args.getString(0);\n            this.checkAvailability(uri, callbackContext);\n            return true;\n        }\n        return false;\n    }\n    \n    // Thanks to http://floresosvaldo.com/android-cordova-plugin-checking-if-an-app-exists\n    public boolean appInstalled(String uri) {\n        Context ctx = this.cordova.getActivity().getApplicationContext();\n        final PackageManager pm = ctx.getPackageManager();\n        boolean app_installed = false;\n        try {\n            pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES);\n            app_installed = true;\n        }\n        catch(PackageManager.NameNotFoundException e) {\n            app_installed = false;\n        }\n        return app_installed;\n    }\n    \n    private void checkAvailability(String uri, CallbackContext callbackContext) {\n        if(appInstalled(uri)) {\n            callbackContext.success();\n        }\n        else {\n            callbackContext.error(\"\");\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-appavailability/src/ios/AppAvailability.h",
    "content": "#import <Cordova/CDV.h>\n\n@interface AppAvailability : CDVPlugin\n\n- (void)checkAvailability:(CDVInvokedUrlCommand*)command;\n\n@end"
  },
  {
    "path": "plugins/cordova-plugin-appavailability/src/ios/AppAvailability.m",
    "content": "#import \"AppAvailability.h\"\n#import <Cordova/CDV.h>\n\n@implementation AppAvailability\n\n- (void)checkAvailability:(CDVInvokedUrlCommand*)command {\n    \n    CDVPluginResult* pluginResult = nil;\n    \n    NSString* scheme = [command.arguments objectAtIndex:0];\n    \n    if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:scheme]]) {\n        pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:(true)];\n    }\n    else {\n        pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsBool:(false)];\n    }\n    \n    [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];\n    \n}\n\n@end"
  },
  {
    "path": "plugins/cordova-plugin-appavailability/www/AppAvailability.js",
    "content": "var appAvailability = {\n    \n    check: function(urlScheme, successCallback, errorCallback) {\n        cordova.exec(\n            successCallback,\n            errorCallback,\n            \"AppAvailability\",\n            \"checkAvailability\",\n            [urlScheme]\n        );\n    },\n    \n    checkBool: function(urlScheme, callback) {\n        cordova.exec(\n            function(success) { callback(success); },\n            function(error) { callback(error); },\n            \"AppAvailability\",\n            \"checkAvailability\",\n            [urlScheme]\n        );\n    }\n    \n};\n\nmodule.exports = appAvailability;"
  },
  {
    "path": "plugins/cordova-plugin-code-push/CONTRIBUTING.md",
    "content": "# Contributing\n\n## TypeScript\n\nAll the JS code in this plugin is compiled from TypeScript sources. Please do not submit pull requests with direct changes to the JS files in ```bin``` directory.\nInstead, modify the sources in the ```www``` folder and compile a new version of the plugin. Read on for more details.\n\n## Building the plugin\n\n### Environment setup\n\n```node.js``` and ```npm``` are needed for building this project. ```npm``` comes bundled with the ```node.js``` installer. You can download the ```node.js``` installer here: https://nodejs.org/download/. \n\n### Compile\n\nFollow these steps to build a new version of the plugin:\n- clone this repository\n- install the dependencies\n\n\tNavigate to the root folder from your command line console and run:\n\t```\n\tnpm install\n\t```\n- compile\n\n\tFrom the same root folder location, run:\n\t```\n\tgulp\n\t```\n\tThis will compile the sources and place them in the ```bin``` folder. Any compilation errors will be displayed in the console.\n\n## Test\n\n### Environment setup\n\nMake sure you can build the plugin by following the steps above.\n\nTo run Android tests, make sure you have ```sdk\\tools``` and  ```sdk\\platform-tools``` in your PATH.\n\n### Supported platforms\n\nThe plugin has end to end tests for Android and iOS. Depending on your development machine OS, you can run some or all the tests.\n\nOS            | Supported tests\n------------- | -------------\nOS X          | Android, iOS\nWindows       | Android\n\n### Test descriptions\n\nThe tests first build the app.\n\nThey then check if the required emulators are currently running.\n\nIf an Android emulator is not running, it attempts to boot an Android emulator named ```emulator```. You can specify an emulator by adding ```--androidemu yourEmulatorNameHere``` as a command line option to the gulp task.\n\nIf an iOS simulator is not running, it attempts to boot the latest iOS iPhone simulator. You can specify a simulator by adding ```--iosemu yourSimulatorNameHere``` as a command line option to the gulp task.\n\nIf all the required emulators are not running and the tests fail to boot them, the tests will fail.\n\nIf you would like the tests to always restart the necessary emulators (killing them if they are currently running), add a ```--clean``` flag to the command.\n\nThe desired unit tests are then run.\n\nIf you would like to skip building, add a ```-fast``` to the end of the command you'd like to run. For example, ```gulp test-ios``` becomes ```gulp test-ios-fast```.\n\nThere is a both a full unit test suite and a \"core\" set of unit tests that you may run. If you would like to run only the core tests, add a ```--core``` flag to the command.\n\nIf you would like to pull the plugin from NPM rather than running the tests on the local version, add a ```--npm``` flag to the command.\n\n#### Default\n\nTo run all of the unit tests on Android and iOS with both UIWebView and WkWebView:\n```\ngulp test\n```\n\n#### iOS\n\nTo run all of the unit tests on iOS with both the UIWebView and WkWebView:\n```\ngulp test-ios\n```\n\nTo run all of the unit tests on iOS with the UIWebView:\n```\ngulp test-ios-ui\n```\n\nTo run all of the unit tests on iOS with the WkWebView:\n```\ngulp test-ios-wk\n```\n\n#### Android\n\nTo run all of the unit tests on Android:\n```\ngulp test-android\n```\n\n#### More examples\n\nAll possible testing configurations have tasks!\n\nThe platforms are ordered as follows, and ran in that order:\nandroid, ios-ui, ios-wk\n\nTo run the core unit tests on Android:\n```\ngulp test-android --core\n```\n\nTo run all of the unit tests on iOS with the UIWebView and pull the plugin from NPM:\n```\ngulp test-ios-ui --npm\n```\n\nTo run all of the unit tests on Android and iOS with the UIWebView without building first:\n```\ngulp test-android-ios-ui-fast\n```\n\nTo run all of the unit tests on iOS with the WkWebView and restart the emulators:\n```\ngulp test-ios-wk --clean\n```\n\nTo run the core unit tests on Android and pull the plugin from NPM:\n```\ngulp test-android --core --npm\n```\n\n...and so on!"
  },
  {
    "path": "plugins/cordova-plugin-code-push/LICENSE.md",
    "content": "Microsoft CodePush Plugin for Apache Cordova \n\nCopyright (c) Microsoft Corporation\n\nAll rights reserved. \n\nMIT License\n\nPermission 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:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE 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.\n"
  },
  {
    "path": "plugins/cordova-plugin-code-push/bin/www/codePush.js",
    "content": "\n /******************************************************************************************** \n \t THIS FILE HAS BEEN COMPILED FROM TYPESCRIPT SOURCES. \n \t PLEASE DO NOT MODIFY THIS FILE AS YOU WILL LOSE YOUR CHANGES WHEN RECOMPILING. \n \t ALSO, PLEASE DO NOT SUBMIT PULL REQUESTS WITH CHANGES TO THIS FILE. \n \t INSTEAD, EDIT THE TYPESCRIPT SOURCES UNDER THE WWW FOLDER. \n \t FOR MORE INFORMATION, PLEASE SEE CONTRIBUTING.md. \n *********************************************************************************************/ \n\n\n\"use strict\";\nvar LocalPackage = require(\"./localPackage\");\nvar RemotePackage = require(\"./remotePackage\");\nvar CodePushUtil = require(\"./codePushUtil\");\nvar NativeAppInfo = require(\"./nativeAppInfo\");\nvar Sdk = require(\"./sdk\");\nvar SyncStatus = require(\"./syncStatus\");\nvar CodePush = (function () {\n    function CodePush() {\n    }\n    CodePush.prototype.notifyApplicationReady = function (notifySucceeded, notifyFailed) {\n        cordova.exec(notifySucceeded, notifyFailed, \"CodePush\", \"updateSuccess\", []);\n    };\n    CodePush.prototype.restartApplication = function (installSuccess, errorCallback) {\n        cordova.exec(installSuccess, errorCallback, \"CodePush\", \"restartApplication\", []);\n    };\n    CodePush.prototype.reportStatus = function (status, label, appVersion, currentDeploymentKey, previousLabelOrAppVersion, previousDeploymentKey) {\n        try {\n            var createPackageForReporting = function (label, appVersion) {\n                return {\n                    label: label, appVersion: appVersion,\n                    deploymentKey: currentDeploymentKey, description: null,\n                    isMandatory: false, packageHash: null,\n                    packageSize: null, failedInstall: false\n                };\n            };\n            switch (status) {\n                case ReportStatus.STORE_VERSION:\n                    Sdk.reportStatusDeploy(null, AcquisitionStatus.DeploymentSucceeded, currentDeploymentKey, previousLabelOrAppVersion, previousDeploymentKey);\n                    break;\n                case ReportStatus.UPDATE_CONFIRMED:\n                    Sdk.reportStatusDeploy(createPackageForReporting(label, appVersion), AcquisitionStatus.DeploymentSucceeded, currentDeploymentKey, previousLabelOrAppVersion, previousDeploymentKey);\n                    break;\n                case ReportStatus.UPDATE_ROLLED_BACK:\n                    Sdk.reportStatusDeploy(createPackageForReporting(label, appVersion), AcquisitionStatus.DeploymentFailed, currentDeploymentKey, previousLabelOrAppVersion, previousDeploymentKey);\n                    break;\n            }\n        }\n        catch (e) {\n            CodePushUtil.logError(\"An error occurred while reporting.\" + CodePushUtil.getErrorMessage(e));\n        }\n    };\n    CodePush.prototype.getCurrentPackage = function (packageSuccess, packageError) {\n        NativeAppInfo.isPendingUpdate(function (pendingUpdate) {\n            var packageInfoFile = pendingUpdate ? LocalPackage.OldPackageInfoFile : LocalPackage.PackageInfoFile;\n            LocalPackage.getPackageInfoOrNull(packageInfoFile, packageSuccess, packageError);\n        });\n    };\n    CodePush.prototype.getPendingPackage = function (packageSuccess, packageError) {\n        NativeAppInfo.isPendingUpdate(function (pendingUpdate) {\n            if (pendingUpdate) {\n                LocalPackage.getPackageInfoOrNull(LocalPackage.PackageInfoFile, packageSuccess, packageError);\n            }\n            else {\n                packageSuccess(null);\n            }\n        });\n    };\n    CodePush.prototype.checkForUpdate = function (querySuccess, queryError, deploymentKey) {\n        try {\n            var callback = function (error, remotePackageOrUpdateNotification) {\n                if (error) {\n                    CodePushUtil.invokeErrorCallback(error, queryError);\n                }\n                else {\n                    var appUpToDate = function () {\n                        CodePushUtil.logMessage(\"App is up to date.\");\n                        querySuccess && querySuccess(null);\n                    };\n                    if (remotePackageOrUpdateNotification) {\n                        if (remotePackageOrUpdateNotification.updateAppVersion) {\n                            CodePushUtil.logMessage(\"An update is available, but it is targeting a newer binary version than you are currently running.\");\n                            appUpToDate();\n                        }\n                        else {\n                            var remotePackage = remotePackageOrUpdateNotification;\n                            NativeAppInfo.isFailedUpdate(remotePackage.packageHash, function (installFailed) {\n                                var result = new RemotePackage();\n                                result.appVersion = remotePackage.appVersion;\n                                result.deploymentKey = deploymentKey;\n                                result.description = remotePackage.description;\n                                result.downloadUrl = remotePackage.downloadUrl;\n                                result.isMandatory = remotePackage.isMandatory;\n                                result.label = remotePackage.label;\n                                result.packageHash = remotePackage.packageHash;\n                                result.packageSize = remotePackage.packageSize;\n                                result.failedInstall = installFailed;\n                                CodePushUtil.logMessage(\"An update is available. \" + JSON.stringify(result));\n                                querySuccess && querySuccess(result);\n                            });\n                        }\n                    }\n                    else {\n                        appUpToDate();\n                    }\n                }\n            };\n            var queryUpdate = function () {\n                Sdk.getAcquisitionManager(function (initError, acquisitionManager) {\n                    if (initError) {\n                        CodePushUtil.invokeErrorCallback(initError, queryError);\n                    }\n                    else {\n                        LocalPackage.getCurrentOrDefaultPackage(function (localPackage) {\n                            CodePushUtil.logMessage(\"Checking for update.\");\n                            acquisitionManager.queryUpdateWithCurrentPackage(localPackage, callback);\n                        }, function (error) {\n                            CodePushUtil.invokeErrorCallback(error, queryError);\n                        });\n                    }\n                }, deploymentKey);\n            };\n            if (deploymentKey) {\n                queryUpdate();\n            }\n            else {\n                NativeAppInfo.getDeploymentKey(function (deploymentKeyError, defaultDeploymentKey) {\n                    if (deploymentKeyError) {\n                        CodePushUtil.invokeErrorCallback(deploymentKeyError, queryError);\n                    }\n                    else {\n                        deploymentKey = defaultDeploymentKey;\n                        queryUpdate();\n                    }\n                });\n            }\n        }\n        catch (e) {\n            CodePushUtil.invokeErrorCallback(new Error(\"An error occurred while querying for updates.\" + CodePushUtil.getErrorMessage(e)), queryError);\n        }\n    };\n    CodePush.prototype.sync = function (syncCallback, syncOptions, downloadProgress) {\n        if (CodePush.SyncInProgress) {\n            CodePushUtil.logMessage(\"Sync already in progress.\");\n            syncCallback && syncCallback(SyncStatus.IN_PROGRESS);\n        }\n        else {\n            var syncCallbackAndUpdateSyncInProgress = function (result) {\n                switch (result) {\n                    case SyncStatus.ERROR:\n                    case SyncStatus.IN_PROGRESS:\n                    case SyncStatus.UP_TO_DATE:\n                    case SyncStatus.UPDATE_IGNORED:\n                    case SyncStatus.UPDATE_INSTALLED:\n                        CodePush.SyncInProgress = false;\n                    default:\n                        break;\n                }\n                syncCallback && syncCallback(result);\n            };\n            CodePush.SyncInProgress = true;\n            this.syncInternal(syncCallbackAndUpdateSyncInProgress, syncOptions, downloadProgress);\n        }\n    };\n    CodePush.prototype.syncInternal = function (syncCallback, syncOptions, downloadProgress) {\n        if (!syncOptions) {\n            syncOptions = this.getDefaultSyncOptions();\n        }\n        else {\n            var defaultDialogOptions = this.getDefaultUpdateDialogOptions();\n            if (syncOptions.updateDialog) {\n                if (typeof syncOptions.updateDialog !== typeof ({})) {\n                    syncOptions.updateDialog = defaultDialogOptions;\n                }\n                else {\n                    CodePushUtil.copyUnassignedMembers(defaultDialogOptions, syncOptions.updateDialog);\n                }\n            }\n            var defaultOptions = this.getDefaultSyncOptions();\n            CodePushUtil.copyUnassignedMembers(defaultOptions, syncOptions);\n        }\n        window.codePush.notifyApplicationReady();\n        var onError = function (error) {\n            CodePushUtil.logError(\"An error occurred during sync.\", error);\n            syncCallback && syncCallback(SyncStatus.ERROR);\n        };\n        var onInstallSuccess = function (appliedWhen) {\n            switch (appliedWhen) {\n                case InstallMode.ON_NEXT_RESTART:\n                    CodePushUtil.logMessage(\"Update is installed and will be run on the next app restart.\");\n                    break;\n                case InstallMode.ON_NEXT_RESUME:\n                    if (syncOptions.minimumBackgroundDuration > 0) {\n                        CodePushUtil.logMessage(\"Update is installed and will be run after the app has been in the background for at least \" + syncOptions.minimumBackgroundDuration + \" seconds.\");\n                    }\n                    else {\n                        CodePushUtil.logMessage(\"Update is installed and will be run when the app next resumes.\");\n                    }\n                    break;\n            }\n            syncCallback && syncCallback(SyncStatus.UPDATE_INSTALLED);\n        };\n        var onDownloadSuccess = function (localPackage) {\n            syncCallback && syncCallback(SyncStatus.INSTALLING_UPDATE);\n            localPackage.install(onInstallSuccess, onError, syncOptions);\n        };\n        var downloadAndInstallUpdate = function (remotePackage) {\n            syncCallback && syncCallback(SyncStatus.DOWNLOADING_PACKAGE);\n            remotePackage.download(onDownloadSuccess, onError, downloadProgress);\n        };\n        var onUpdate = function (remotePackage) {\n            var updateShouldBeIgnored = remotePackage && (remotePackage.failedInstall && syncOptions.ignoreFailedUpdates);\n            if (!remotePackage || updateShouldBeIgnored) {\n                if (updateShouldBeIgnored) {\n                    CodePushUtil.logMessage(\"An update is available, but it is being ignored due to have been previously rolled back.\");\n                }\n                syncCallback && syncCallback(SyncStatus.UP_TO_DATE);\n            }\n            else {\n                var dlgOpts = syncOptions.updateDialog;\n                if (dlgOpts) {\n                    CodePushUtil.logMessage(\"Awaiting user action.\");\n                    syncCallback && syncCallback(SyncStatus.AWAITING_USER_ACTION);\n                }\n                if (remotePackage.isMandatory && syncOptions.updateDialog) {\n                    var message = dlgOpts.appendReleaseDescription ?\n                        dlgOpts.mandatoryUpdateMessage + dlgOpts.descriptionPrefix + remotePackage.description\n                        : dlgOpts.mandatoryUpdateMessage;\n                    navigator.notification.alert(message, function () { downloadAndInstallUpdate(remotePackage); }, dlgOpts.updateTitle, dlgOpts.mandatoryContinueButtonLabel);\n                }\n                else if (!remotePackage.isMandatory && syncOptions.updateDialog) {\n                    var optionalUpdateCallback = function (buttonIndex) {\n                        switch (buttonIndex) {\n                            case 1:\n                                downloadAndInstallUpdate(remotePackage);\n                                break;\n                            case 2:\n                            default:\n                                CodePushUtil.logMessage(\"User cancelled the update.\");\n                                syncCallback && syncCallback(SyncStatus.UPDATE_IGNORED);\n                                break;\n                        }\n                    };\n                    var message = dlgOpts.appendReleaseDescription ?\n                        dlgOpts.optionalUpdateMessage + dlgOpts.descriptionPrefix + remotePackage.description\n                        : dlgOpts.optionalUpdateMessage;\n                    navigator.notification.confirm(message, optionalUpdateCallback, dlgOpts.updateTitle, [dlgOpts.optionalInstallButtonLabel, dlgOpts.optionalIgnoreButtonLabel]);\n                }\n                else {\n                    downloadAndInstallUpdate(remotePackage);\n                }\n            }\n        };\n        syncCallback && syncCallback(SyncStatus.CHECKING_FOR_UPDATE);\n        window.codePush.checkForUpdate(onUpdate, onError, syncOptions.deploymentKey);\n    };\n    CodePush.prototype.getDefaultSyncOptions = function () {\n        if (!CodePush.DefaultSyncOptions) {\n            CodePush.DefaultSyncOptions = {\n                ignoreFailedUpdates: true,\n                installMode: InstallMode.ON_NEXT_RESTART,\n                minimumBackgroundDuration: 0,\n                mandatoryInstallMode: InstallMode.IMMEDIATE,\n                updateDialog: false,\n                deploymentKey: undefined\n            };\n        }\n        return CodePush.DefaultSyncOptions;\n    };\n    CodePush.prototype.getDefaultUpdateDialogOptions = function () {\n        if (!CodePush.DefaultUpdateDialogOptions) {\n            CodePush.DefaultUpdateDialogOptions = {\n                updateTitle: \"Update available\",\n                mandatoryUpdateMessage: \"An update is available that must be installed.\",\n                mandatoryContinueButtonLabel: \"Continue\",\n                optionalUpdateMessage: \"An update is available. Would you like to install it?\",\n                optionalInstallButtonLabel: \"Install\",\n                optionalIgnoreButtonLabel: \"Ignore\",\n                appendReleaseDescription: false,\n                descriptionPrefix: \" Description: \"\n            };\n        }\n        return CodePush.DefaultUpdateDialogOptions;\n    };\n    return CodePush;\n}());\nvar ReportStatus;\n(function (ReportStatus) {\n    ReportStatus[ReportStatus[\"STORE_VERSION\"] = 0] = \"STORE_VERSION\";\n    ReportStatus[ReportStatus[\"UPDATE_CONFIRMED\"] = 1] = \"UPDATE_CONFIRMED\";\n    ReportStatus[ReportStatus[\"UPDATE_ROLLED_BACK\"] = 2] = \"UPDATE_ROLLED_BACK\";\n})(ReportStatus || (ReportStatus = {}));\nvar instance = new CodePush();\nmodule.exports = instance;\n"
  },
  {
    "path": "plugins/cordova-plugin-code-push/bin/www/codePushUtil.js",
    "content": "\n /******************************************************************************************** \n \t THIS FILE HAS BEEN COMPILED FROM TYPESCRIPT SOURCES. \n \t PLEASE DO NOT MODIFY THIS FILE AS YOU WILL LOSE YOUR CHANGES WHEN RECOMPILING. \n \t ALSO, PLEASE DO NOT SUBMIT PULL REQUESTS WITH CHANGES TO THIS FILE. \n \t INSTEAD, EDIT THE TYPESCRIPT SOURCES UNDER THE WWW FOLDER. \n \t FOR MORE INFORMATION, PLEASE SEE CONTRIBUTING.md. \n *********************************************************************************************/ \n\n\n\"use strict\";\nvar CodePushUtil = (function () {\n    function CodePushUtil() {\n    }\n    CodePushUtil.copyUnassignedMembers = function (fromParameter, toParameter) {\n        for (var key in fromParameter) {\n            if (toParameter[key] === undefined || toParameter[key] === null) {\n                toParameter[key] = fromParameter[key];\n            }\n        }\n    };\n    CodePushUtil.getNodeStyleCallbackFor = function (successCallback, errorCallback) {\n        return function (error, result) {\n            if (error) {\n                errorCallback && errorCallback(error);\n            }\n            else {\n                successCallback && successCallback(result);\n            }\n        };\n    };\n    CodePushUtil.getErrorMessage = function (e) {\n        return e && e.message || e && e.toString() || \"\";\n    };\n    CodePushUtil.logMessage = function (msg) {\n        console.log(CodePushUtil.TAG + \" \" + msg);\n    };\n    CodePushUtil.logError = function (message, error) {\n        var errorMessage = message || \"\" + \" \" + CodePushUtil.getErrorMessage(error);\n        console.error(CodePushUtil.TAG + \" \" + errorMessage);\n    };\n    CodePushUtil.TAG = \"[CodePush]\";\n    CodePushUtil.invokeErrorCallback = function (error, errorCallback) {\n        CodePushUtil.logError(null, error);\n        errorCallback && errorCallback(error);\n    };\n    return CodePushUtil;\n}());\nmodule.exports = CodePushUtil;\n"
  },
  {
    "path": "plugins/cordova-plugin-code-push/bin/www/fileUtil.js",
    "content": "\n /******************************************************************************************** \n \t THIS FILE HAS BEEN COMPILED FROM TYPESCRIPT SOURCES. \n \t PLEASE DO NOT MODIFY THIS FILE AS YOU WILL LOSE YOUR CHANGES WHEN RECOMPILING. \n \t ALSO, PLEASE DO NOT SUBMIT PULL REQUESTS WITH CHANGES TO THIS FILE. \n \t INSTEAD, EDIT THE TYPESCRIPT SOURCES UNDER THE WWW FOLDER. \n \t FOR MORE INFORMATION, PLEASE SEE CONTRIBUTING.md. \n *********************************************************************************************/ \n\n\n\"use strict\";\nvar FileUtil = (function () {\n    function FileUtil() {\n    }\n    FileUtil.directoryExists = function (rootUri, path, callback) {\n        FileUtil.getDirectory(rootUri, path, false, function (error, dirEntry) {\n            var dirExists = !error && !!dirEntry;\n            callback(null, dirExists);\n        });\n    };\n    FileUtil.fileErrorToError = function (fileError, message) {\n        return new Error((message ? message : \"An error has occurred while performing the operation. \") + \" Error code: \" + fileError.code);\n    };\n    FileUtil.getDataDirectory = function (path, createIfNotExists, callback) {\n        FileUtil.getDirectory(cordova.file.dataDirectory, path, createIfNotExists, callback);\n    };\n    FileUtil.writeStringToDataFile = function (content, path, fileName, createIfNotExists, callback) {\n        FileUtil.writeStringToFile(content, cordova.file.dataDirectory, path, fileName, createIfNotExists, callback);\n    };\n    FileUtil.getApplicationDirectory = function (path, callback) {\n        FileUtil.getApplicationEntry(path, callback);\n    };\n    FileUtil.getApplicationFile = function (path, callback) {\n        FileUtil.getApplicationEntry(path, callback);\n    };\n    FileUtil.getOrCreateFile = function (parent, path, createIfNotExists, success, fail) {\n        var failFirst = function (error) {\n            if (!createIfNotExists) {\n                fail(error);\n            }\n            else {\n                parent.getFile(path, { create: true, exclusive: false }, success, fail);\n            }\n        };\n        parent.getFile(path, { create: false, exclusive: false }, success, failFirst);\n    };\n    FileUtil.getFile = function (rootUri, path, fileName, createIfNotExists, callback) {\n        FileUtil.getDirectory(rootUri, path, createIfNotExists, function (error, directoryEntry) {\n            if (error) {\n                callback(error, null);\n            }\n            else {\n                FileUtil.getOrCreateFile(directoryEntry, fileName, createIfNotExists, function (entry) { callback(null, entry); }, function (error) { callback(FileUtil.fileErrorToError(error), null); });\n            }\n        });\n    };\n    FileUtil.getDataFile = function (path, fileName, createIfNotExists, callback) {\n        FileUtil.getFile(cordova.file.dataDirectory, path, fileName, createIfNotExists, callback);\n    };\n    FileUtil.fileExists = function (rootUri, path, fileName, callback) {\n        FileUtil.getFile(rootUri, path, fileName, false, function (error, fileEntry) {\n            var exists = !error && !!fileEntry;\n            callback(null, exists);\n        });\n    };\n    FileUtil.getDirectory = function (rootUri, path, createIfNotExists, callback) {\n        var pathArray = path.split(\"/\");\n        var currentDir;\n        var currentIndex = 0;\n        var appDirError = function (error) {\n            callback(new Error(\"Could not get application subdirectory. Error code: \" + error.code), null);\n        };\n        var rootDirSuccess = function (appDir) {\n            if (!createIfNotExists) {\n                appDir.getDirectory(path, { create: false, exclusive: false }, function (directoryEntry) { callback(null, directoryEntry); }, appDirError);\n            }\n            else {\n                currentDir = appDir;\n                if (currentIndex >= pathArray.length) {\n                    callback(null, appDir);\n                }\n                else {\n                    var currentPath = pathArray[currentIndex];\n                    currentIndex++;\n                    if (currentPath) {\n                        FileUtil.getOrCreateSubDirectory(appDir, currentPath, createIfNotExists, rootDirSuccess, appDirError);\n                    }\n                    else {\n                        rootDirSuccess(appDir);\n                    }\n                }\n            }\n        };\n        window.resolveLocalFileSystemURL(rootUri, rootDirSuccess, appDirError);\n    };\n    FileUtil.dataDirectoryExists = function (path, callback) {\n        FileUtil.directoryExists(cordova.file.dataDirectory, path, callback);\n    };\n    FileUtil.copyDirectoryEntriesTo = function (sourceDir, destinationDir, callback) {\n        var fail = function (error) {\n            callback(FileUtil.fileErrorToError(error), null);\n        };\n        var success = function (entries) {\n            var i = 0;\n            var copyOne = function () {\n                if (i < entries.length) {\n                    var nextEntry = entries[i++];\n                    var entryAlreadyInDestination = function (destinationEntry) {\n                        var replaceError = function (fileError) {\n                            callback(new Error(\"Error during entry replacement. Error code: \" + fileError.code), null);\n                        };\n                        if (destinationEntry.isDirectory) {\n                            FileUtil.copyDirectoryEntriesTo(nextEntry, destinationEntry, function (error) {\n                                if (error) {\n                                    callback(error, null);\n                                }\n                                else {\n                                    copyOne();\n                                }\n                            });\n                        }\n                        else {\n                            var fileEntry = destinationEntry;\n                            fileEntry.remove(function () {\n                                nextEntry.copyTo(destinationDir, nextEntry.name, copyOne, fail);\n                            }, replaceError);\n                        }\n                    };\n                    var entryNotInDestination = function (error) {\n                        nextEntry.copyTo(destinationDir, nextEntry.name, copyOne, fail);\n                    };\n                    FileUtil.entryExistsInDirectory(nextEntry, destinationDir, entryAlreadyInDestination, entryNotInDestination);\n                }\n                else {\n                    callback(null, null);\n                }\n            };\n            copyOne();\n        };\n        var directoryReader = sourceDir.createReader();\n        directoryReader.readEntries(success, fail);\n    };\n    FileUtil.entryExistsInDirectory = function (entry, destinationDir, exists, doesNotExist) {\n        var options = { create: false, exclusive: false };\n        if (entry.isDirectory) {\n            destinationDir.getDirectory(entry.name, options, exists, doesNotExist);\n        }\n        else {\n            destinationDir.getFile(entry.name, options, exists, doesNotExist);\n        }\n    };\n    FileUtil.deleteDirectory = function (dirLocation, deleteDirCallback) {\n        FileUtil.getDataDirectory(dirLocation, false, function (oldDirError, dirToDelete) {\n            if (oldDirError) {\n                deleteDirCallback(oldDirError, null);\n            }\n            else {\n                var win = function () { deleteDirCallback(null, null); };\n                var fail = function (e) { deleteDirCallback(FileUtil.fileErrorToError(e), null); };\n                dirToDelete.removeRecursively(win, fail);\n            }\n        });\n    };\n    FileUtil.deleteEntriesFromDataDirectory = function (dirPath, filesToDelete, callback) {\n        FileUtil.getDataDirectory(dirPath, false, function (error, rootDir) {\n            if (error) {\n                callback(error, null);\n            }\n            else {\n                var i = 0;\n                var deleteOne = function () {\n                    if (i < filesToDelete.length) {\n                        var continueDeleting = function () {\n                            i++;\n                            deleteOne();\n                        };\n                        var fail = function (error) {\n                            console.log(\"Could not delete file: \" + filesToDelete[i]);\n                            continueDeleting();\n                        };\n                        var success = function (entry) {\n                            entry.remove(continueDeleting, fail);\n                        };\n                        rootDir.getFile(filesToDelete[i], { create: false, exclusive: false }, success, fail);\n                    }\n                    else {\n                        callback(null, null);\n                    }\n                };\n                deleteOne();\n            }\n        });\n    };\n    FileUtil.writeStringToFile = function (content, rootUri, path, fileName, createIfNotExists, callback) {\n        var gotFile = function (fileEntry) {\n            fileEntry.createWriter(function (writer) {\n                writer.onwriteend = function (ev) {\n                    callback(null, null);\n                };\n                writer.onerror = function (ev) {\n                    callback(writer.error, null);\n                };\n                writer.write(content);\n            }, function (error) {\n                callback(new Error(\"Could write the current package information file. Error code: \" + error.code), null);\n            });\n        };\n        FileUtil.getFile(rootUri, path, fileName, createIfNotExists, function (error, fileEntry) {\n            if (error) {\n                callback(error, null);\n            }\n            else {\n                gotFile(fileEntry);\n            }\n        });\n    };\n    FileUtil.readFileEntry = function (fileEntry, callback) {\n        fileEntry.file(function (file) {\n            var fileReader = new FileReader();\n            fileReader.onloadend = function (ev) {\n                callback(null, ev.target.result);\n            };\n            fileReader.onerror = function (ev) {\n                callback(new Error(\"Could not get file. Error: \" + ev.error), null);\n            };\n            fileReader.readAsText(file);\n        }, function (error) {\n            callback(new Error(\"Could not get file. Error code: \" + error.code), null);\n        });\n    };\n    FileUtil.readFile = function (rootUri, path, fileName, callback) {\n        FileUtil.getFile(rootUri, path, fileName, false, function (error, fileEntry) {\n            if (error) {\n                callback(error, null);\n            }\n            else {\n                FileUtil.readFileEntry(fileEntry, callback);\n            }\n        });\n    };\n    FileUtil.readDataFile = function (path, fileName, callback) {\n        FileUtil.readFile(cordova.file.dataDirectory, path, fileName, callback);\n    };\n    FileUtil.getApplicationEntry = function (path, callback) {\n        var success = function (entry) {\n            callback(null, entry);\n        };\n        var fail = function (error) {\n            callback(FileUtil.fileErrorToError(error), null);\n        };\n        window.resolveLocalFileSystemURL(cordova.file.applicationDirectory + path, success, fail);\n    };\n    FileUtil.getOrCreateSubDirectory = function (parent, path, createIfNotExists, success, fail) {\n        var failFirst = function (error) {\n            if (!createIfNotExists) {\n                fail(error);\n            }\n            else {\n                parent.getDirectory(path, { create: true, exclusive: false }, success, fail);\n            }\n        };\n        parent.getDirectory(path, { create: false, exclusive: false }, success, failFirst);\n    };\n    return FileUtil;\n}());\nmodule.exports = FileUtil;\n"
  },
  {
    "path": "plugins/cordova-plugin-code-push/bin/www/httpRequester.js",
    "content": "\n /******************************************************************************************** \n \t THIS FILE HAS BEEN COMPILED FROM TYPESCRIPT SOURCES. \n \t PLEASE DO NOT MODIFY THIS FILE AS YOU WILL LOSE YOUR CHANGES WHEN RECOMPILING. \n \t ALSO, PLEASE DO NOT SUBMIT PULL REQUESTS WITH CHANGES TO THIS FILE. \n \t INSTEAD, EDIT THE TYPESCRIPT SOURCES UNDER THE WWW FOLDER. \n \t FOR MORE INFORMATION, PLEASE SEE CONTRIBUTING.md. \n *********************************************************************************************/ \n\n\n\"use strict\";\nvar HttpRequester = (function () {\n    function HttpRequester(contentType) {\n        this.contentType = contentType;\n    }\n    HttpRequester.prototype.request = function (verb, url, callbackOrRequestBody, callback) {\n        var requestBody;\n        var requestCallback = callback;\n        if (!requestCallback && typeof callbackOrRequestBody === \"function\") {\n            requestCallback = callbackOrRequestBody;\n        }\n        if (typeof callbackOrRequestBody === \"string\") {\n            requestBody = callbackOrRequestBody;\n        }\n        var xhr = new XMLHttpRequest();\n        var methodName = this.getHttpMethodName(verb);\n        xhr.onreadystatechange = function () {\n            if (xhr.readyState === 4) {\n                var response = { statusCode: xhr.status, body: xhr.responseText };\n                requestCallback && requestCallback(null, response);\n            }\n        };\n        xhr.open(methodName, url, true);\n        if (this.contentType) {\n            xhr.setRequestHeader(\"Content-Type\", this.contentType);\n        }\n        xhr.setRequestHeader(\"X-CodePush-SDK-Version\", cordova.require(\"cordova/plugin_list\").metadata[\"code-push\"]);\n        xhr.send(requestBody);\n    };\n    HttpRequester.prototype.getHttpMethodName = function (verb) {\n        switch (verb) {\n            case 0:\n                return \"GET\";\n            case 7:\n                return \"CONNECT\";\n            case 4:\n                return \"DELETE\";\n            case 1:\n                return \"HEAD\";\n            case 6:\n                return \"OPTIONS\";\n            case 8:\n                return \"PATCH\";\n            case 2:\n                return \"POST\";\n            case 3:\n                return \"PUT\";\n            case 5:\n                return \"TRACE\";\n            default:\n                return null;\n        }\n    };\n    return HttpRequester;\n}());\nmodule.exports = HttpRequester;\n"
  },
  {
    "path": "plugins/cordova-plugin-code-push/bin/www/installMode.js",
    "content": "\n /******************************************************************************************** \n \t THIS FILE HAS BEEN COMPILED FROM TYPESCRIPT SOURCES. \n \t PLEASE DO NOT MODIFY THIS FILE AS YOU WILL LOSE YOUR CHANGES WHEN RECOMPILING. \n \t ALSO, PLEASE DO NOT SUBMIT PULL REQUESTS WITH CHANGES TO THIS FILE. \n \t INSTEAD, EDIT THE TYPESCRIPT SOURCES UNDER THE WWW FOLDER. \n \t FOR MORE INFORMATION, PLEASE SEE CONTRIBUTING.md. \n *********************************************************************************************/ \n\n\n\"use strict\";\nvar InstallMode;\n(function (InstallMode) {\n    InstallMode[InstallMode[\"IMMEDIATE\"] = 0] = \"IMMEDIATE\";\n    InstallMode[InstallMode[\"ON_NEXT_RESTART\"] = 1] = \"ON_NEXT_RESTART\";\n    InstallMode[InstallMode[\"ON_NEXT_RESUME\"] = 2] = \"ON_NEXT_RESUME\";\n})(InstallMode || (InstallMode = {}));\nmodule.exports = InstallMode;\n"
  },
  {
    "path": "plugins/cordova-plugin-code-push/bin/www/localPackage.js",
    "content": "\n /******************************************************************************************** \n \t THIS FILE HAS BEEN COMPILED FROM TYPESCRIPT SOURCES. \n \t PLEASE DO NOT MODIFY THIS FILE AS YOU WILL LOSE YOUR CHANGES WHEN RECOMPILING. \n \t ALSO, PLEASE DO NOT SUBMIT PULL REQUESTS WITH CHANGES TO THIS FILE. \n \t INSTEAD, EDIT THE TYPESCRIPT SOURCES UNDER THE WWW FOLDER. \n \t FOR MORE INFORMATION, PLEASE SEE CONTRIBUTING.md. \n *********************************************************************************************/ \n\n\n\"use strict\";\nvar __extends = (this && this.__extends) || function (d, b) {\n    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];\n    function __() { this.constructor = d; }\n    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n};\nvar Package = require(\"./package\");\nvar NativeAppInfo = require(\"./nativeAppInfo\");\nvar FileUtil = require(\"./fileUtil\");\nvar CodePushUtil = require(\"./codePushUtil\");\nvar Sdk = require(\"./sdk\");\nvar LocalPackage = (function (_super) {\n    __extends(LocalPackage, _super);\n    function LocalPackage() {\n        _super.apply(this, arguments);\n    }\n    LocalPackage.prototype.install = function (installSuccess, errorCallback, installOptions) {\n        var _this = this;\n        try {\n            CodePushUtil.logMessage(\"Installing update\");\n            if (!installOptions) {\n                installOptions = LocalPackage.getDefaultInstallOptions();\n            }\n            else {\n                CodePushUtil.copyUnassignedMembers(LocalPackage.getDefaultInstallOptions(), installOptions);\n            }\n            var installError = function (error) {\n                CodePushUtil.invokeErrorCallback(error, errorCallback);\n                Sdk.reportStatusDeploy(_this, AcquisitionStatus.DeploymentFailed, _this.deploymentKey);\n            };\n            var newPackageLocation = LocalPackage.VersionsDir + \"/\" + this.packageHash;\n            var donePackageFileCopy = function (deployDir) {\n                _this.localPath = deployDir.fullPath;\n                _this.finishInstall(deployDir, installOptions, installSuccess, installError);\n            };\n            var newPackageUnzipped = function (unzipError) {\n                if (unzipError) {\n                    installError && installError(new Error(\"Could not unzip package. \" + CodePushUtil.getErrorMessage(unzipError)));\n                }\n                else {\n                    LocalPackage.handleDeployment(newPackageLocation, CodePushUtil.getNodeStyleCallbackFor(donePackageFileCopy, installError));\n                }\n            };\n            FileUtil.getDataDirectory(LocalPackage.DownloadUnzipDir, false, function (error, directoryEntry) {\n                var unzipPackage = function () {\n                    FileUtil.getDataDirectory(LocalPackage.DownloadUnzipDir, true, function (innerError, unzipDir) {\n                        if (innerError) {\n                            installError && installError(innerError);\n                        }\n                        else {\n                            zip.unzip(_this.localPath, unzipDir.toInternalURL(), newPackageUnzipped);\n                        }\n                    });\n                };\n                if (!error && !!directoryEntry) {\n                    directoryEntry.removeRecursively(function () {\n                        unzipPackage();\n                    }, function (cleanupError) {\n                        installError && installError(FileUtil.fileErrorToError(cleanupError));\n                    });\n                }\n                else {\n                    unzipPackage();\n                }\n            });\n        }\n        catch (e) {\n            installError && installError(new Error(\"An error occured while installing the package. \" + CodePushUtil.getErrorMessage(e)));\n        }\n    };\n    LocalPackage.prototype.finishInstall = function (deployDir, installOptions, installSuccess, installError) {\n        var _this = this;\n        LocalPackage.getCurrentOrDefaultPackage(function (oldPackage) {\n            LocalPackage.backupPackageInformationFile(function (backupError) {\n                _this.writeNewPackageMetadata(deployDir, function (writeMetadataError) {\n                    if (writeMetadataError) {\n                        installError && installError(writeMetadataError);\n                    }\n                    else {\n                        var invokeSuccessAndInstall = function () {\n                            CodePushUtil.logMessage(\"Install succeeded.\");\n                            var installModeToUse = _this.isMandatory ? installOptions.mandatoryInstallMode : installOptions.installMode;\n                            if (installModeToUse === InstallMode.IMMEDIATE) {\n                                installSuccess && installSuccess(installModeToUse);\n                                cordova.exec(function () { }, function () { }, \"CodePush\", \"install\", [deployDir.fullPath,\n                                    installModeToUse.toString(), installOptions.minimumBackgroundDuration.toString()]);\n                            }\n                            else {\n                                cordova.exec(function () { installSuccess && installSuccess(installModeToUse); }, function () { installError && installError(); }, \"CodePush\", \"install\", [deployDir.fullPath,\n                                    installModeToUse.toString(), installOptions.minimumBackgroundDuration.toString()]);\n                            }\n                        };\n                        var preInstallSuccess = function () {\n                            invokeSuccessAndInstall();\n                        };\n                        var preInstallFailure = function (preInstallError) {\n                            CodePushUtil.logError(\"Preinstall failure.\", preInstallError);\n                            var error = new Error(\"An error has occured while installing the package. \" + CodePushUtil.getErrorMessage(preInstallError));\n                            installError && installError(error);\n                        };\n                        cordova.exec(preInstallSuccess, preInstallFailure, \"CodePush\", \"preInstall\", [deployDir.fullPath]);\n                    }\n                });\n            });\n        }, installError);\n    };\n    LocalPackage.handleDeployment = function (newPackageLocation, deployCallback) {\n        FileUtil.getDataDirectory(newPackageLocation, true, function (deployDirError, deployDir) {\n            FileUtil.getDataFile(LocalPackage.DownloadUnzipDir, LocalPackage.DiffManifestFile, false, function (manifestError, diffManifest) {\n                if (!manifestError && !!diffManifest) {\n                    LocalPackage.handleDiffDeployment(newPackageLocation, diffManifest, deployCallback);\n                }\n                else {\n                    LocalPackage.handleCleanDeployment(newPackageLocation, function (error) {\n                        deployCallback(error, deployDir);\n                    });\n                }\n            });\n        });\n    };\n    LocalPackage.prototype.writeNewPackageMetadata = function (deployDir, writeMetadataCallback) {\n        var _this = this;\n        NativeAppInfo.getApplicationBuildTime(function (buildTimeError, timestamp) {\n            NativeAppInfo.getApplicationVersion(function (appVersionError, appVersion) {\n                buildTimeError && CodePushUtil.logError(\"Could not get application build time. \" + buildTimeError);\n                appVersionError && CodePushUtil.logError(\"Could not get application version.\" + appVersionError);\n                var currentPackageMetadata = {\n                    nativeBuildTime: timestamp,\n                    localPath: _this.localPath,\n                    appVersion: appVersion,\n                    deploymentKey: _this.deploymentKey,\n                    description: _this.description,\n                    isMandatory: _this.isMandatory,\n                    packageSize: _this.packageSize,\n                    label: _this.label,\n                    packageHash: _this.packageHash,\n                    isFirstRun: false,\n                    failedInstall: false,\n                    install: undefined\n                };\n                LocalPackage.writeCurrentPackageInformation(currentPackageMetadata, writeMetadataCallback);\n            });\n        });\n    };\n    LocalPackage.handleCleanDeployment = function (newPackageLocation, cleanDeployCallback) {\n        FileUtil.getDataDirectory(newPackageLocation, true, function (deployDirError, deployDir) {\n            FileUtil.getDataDirectory(LocalPackage.DownloadUnzipDir, false, function (unzipDirErr, unzipDir) {\n                if (unzipDirErr || deployDirError) {\n                    cleanDeployCallback(new Error(\"Could not copy new package.\"), null);\n                }\n                else {\n                    FileUtil.copyDirectoryEntriesTo(unzipDir, deployDir, function (copyError) {\n                        if (copyError) {\n                            cleanDeployCallback(copyError, null);\n                        }\n                        else {\n                            cleanDeployCallback(null, deployDir);\n                        }\n                    });\n                }\n            });\n        });\n    };\n    LocalPackage.copyCurrentPackage = function (newPackageLocation, copyCallback) {\n        var handleError = function (e) {\n            copyCallback && copyCallback(e, null);\n        };\n        var doCopy = function (currentPackagePath) {\n            var getCurrentPackageDirectory;\n            if (currentPackagePath) {\n                getCurrentPackageDirectory = function (getCurrentPackageDirectoryCallback) {\n                    FileUtil.getDataDirectory(currentPackagePath, false, getCurrentPackageDirectoryCallback);\n                };\n            }\n            else {\n                newPackageLocation = newPackageLocation + \"/www\";\n                getCurrentPackageDirectory = function (getCurrentPackageDirectoryCallback) {\n                    FileUtil.getApplicationDirectory(\"www\", getCurrentPackageDirectoryCallback);\n                };\n            }\n            FileUtil.getDataDirectory(newPackageLocation, true, function (deployDirError, deployDir) {\n                if (deployDirError) {\n                    handleError(new Error(\"Could not acquire the source/destination folders. \"));\n                }\n                else {\n                    var success = function (currentPackageDirectory) {\n                        FileUtil.copyDirectoryEntriesTo(currentPackageDirectory, deployDir, copyCallback);\n                    };\n                    var fail = function (fileSystemError) {\n                        copyCallback && copyCallback(FileUtil.fileErrorToError(fileSystemError), null);\n                    };\n                    getCurrentPackageDirectory(CodePushUtil.getNodeStyleCallbackFor(success, fail));\n                }\n            });\n        };\n        var packageFailure = function (error) {\n            doCopy();\n        };\n        var packageSuccess = function (currentPackage) {\n            doCopy(currentPackage.localPath);\n        };\n        LocalPackage.getPackage(LocalPackage.PackageInfoFile, packageSuccess, packageFailure);\n    };\n    LocalPackage.handleDiffDeployment = function (newPackageLocation, diffManifest, diffCallback) {\n        var handleError = function (e) {\n            diffCallback(e, null);\n        };\n        LocalPackage.copyCurrentPackage(newPackageLocation, function (currentPackageError) {\n            LocalPackage.handleCleanDeployment(newPackageLocation, function (cleanDeployError) {\n                FileUtil.readFileEntry(diffManifest, function (error, content) {\n                    if (error || currentPackageError || cleanDeployError) {\n                        handleError(new Error(\"Cannot perform diff-update.\"));\n                    }\n                    else {\n                        var manifest = JSON.parse(content);\n                        FileUtil.deleteEntriesFromDataDirectory(newPackageLocation, manifest.deletedFiles, function (deleteError) {\n                            FileUtil.getDataDirectory(newPackageLocation, true, function (deployDirError, deployDir) {\n                                if (deleteError || deployDirError) {\n                                    handleError(new Error(\"Cannot clean up deleted manifest files.\"));\n                                }\n                                else {\n                                    diffCallback(null, deployDir);\n                                }\n                            });\n                        });\n                    }\n                });\n            });\n        });\n    };\n    LocalPackage.writeCurrentPackageInformation = function (packageInfoMetadata, callback) {\n        var content = JSON.stringify(packageInfoMetadata);\n        FileUtil.writeStringToDataFile(content, LocalPackage.RootDir, LocalPackage.PackageInfoFile, true, callback);\n    };\n    LocalPackage.backupPackageInformationFile = function (callback) {\n        var reportFileError = function (error) {\n            callback(FileUtil.fileErrorToError(error), null);\n        };\n        var copyFile = function (fileToCopy) {\n            fileToCopy.getParent(function (parent) {\n                fileToCopy.copyTo(parent, LocalPackage.OldPackageInfoFile, function () {\n                    callback(null, null);\n                }, reportFileError);\n            }, reportFileError);\n        };\n        var gotFile = function (error, currentPackageFile) {\n            if (error) {\n                callback(error, null);\n            }\n            else {\n                FileUtil.getDataFile(LocalPackage.RootDir, LocalPackage.OldPackageInfoFile, false, function (error, oldPackageFile) {\n                    if (!error && !!oldPackageFile) {\n                        oldPackageFile.remove(function () {\n                            copyFile(currentPackageFile);\n                        }, reportFileError);\n                    }\n                    else {\n                        copyFile(currentPackageFile);\n                    }\n                });\n            }\n        };\n        FileUtil.getDataFile(LocalPackage.RootDir, LocalPackage.PackageInfoFile, false, gotFile);\n    };\n    LocalPackage.getOldPackage = function (packageSuccess, packageError) {\n        return LocalPackage.getPackage(LocalPackage.OldPackageInfoFile, packageSuccess, packageError);\n    };\n    LocalPackage.getPackage = function (packageFile, packageSuccess, packageError) {\n        var handleError = function (e) {\n            packageError && packageError(new Error(\"Cannot read package information. \" + CodePushUtil.getErrorMessage(e)));\n        };\n        try {\n            FileUtil.readDataFile(LocalPackage.RootDir, packageFile, function (error, content) {\n                if (error) {\n                    handleError(error);\n                }\n                else {\n                    try {\n                        var packageInfo = JSON.parse(content);\n                        LocalPackage.getLocalPackageFromMetadata(packageInfo, packageSuccess, packageError);\n                    }\n                    catch (e) {\n                        handleError(e);\n                    }\n                }\n            });\n        }\n        catch (e) {\n            handleError(e);\n        }\n    };\n    LocalPackage.getLocalPackageFromMetadata = function (metadata, packageSuccess, packageError) {\n        if (!metadata) {\n            packageError && packageError(new Error(\"Invalid package metadata.\"));\n        }\n        else {\n            NativeAppInfo.isFailedUpdate(metadata.packageHash, function (installFailed) {\n                NativeAppInfo.isFirstRun(metadata.packageHash, function (isFirstRun) {\n                    var localPackage = new LocalPackage();\n                    localPackage.appVersion = metadata.appVersion;\n                    localPackage.deploymentKey = metadata.deploymentKey;\n                    localPackage.description = metadata.description;\n                    localPackage.failedInstall = installFailed;\n                    localPackage.isFirstRun = isFirstRun;\n                    localPackage.label = metadata.label;\n                    localPackage.localPath = metadata.localPath;\n                    localPackage.packageHash = metadata.packageHash;\n                    localPackage.packageSize = metadata.packageSize;\n                    packageSuccess && packageSuccess(localPackage);\n                });\n            });\n        }\n    };\n    LocalPackage.getCurrentOrDefaultPackage = function (packageSuccess, packageError) {\n        LocalPackage.getPackageInfoOrDefault(LocalPackage.PackageInfoFile, packageSuccess, packageError);\n    };\n    LocalPackage.getOldOrDefaultPackage = function (packageSuccess, packageError) {\n        LocalPackage.getPackageInfoOrDefault(LocalPackage.OldPackageInfoFile, packageSuccess, packageError);\n    };\n    LocalPackage.getPackageInfoOrDefault = function (packageFile, packageSuccess, packageError) {\n        var packageFailure = function (error) {\n            NativeAppInfo.getApplicationVersion(function (appVersionError, appVersion) {\n                if (appVersionError) {\n                    CodePushUtil.logError(\"Could not get application version.\" + appVersionError);\n                    packageError(appVersionError);\n                    return;\n                }\n                NativeAppInfo.getBinaryHash(function (binaryHashError, binaryHash) {\n                    var defaultPackage = new LocalPackage();\n                    defaultPackage.appVersion = appVersion;\n                    if (binaryHashError) {\n                        CodePushUtil.logError(\"Could not get binary hash.\" + binaryHashError);\n                    }\n                    else {\n                        defaultPackage.packageHash = binaryHash;\n                    }\n                    packageSuccess(defaultPackage);\n                });\n            });\n        };\n        LocalPackage.getPackage(packageFile, packageSuccess, packageFailure);\n    };\n    LocalPackage.getPackageInfoOrNull = function (packageFile, packageSuccess, packageError) {\n        LocalPackage.getPackage(packageFile, packageSuccess, packageSuccess.bind(null, null));\n    };\n    LocalPackage.getDefaultInstallOptions = function () {\n        if (!LocalPackage.DefaultInstallOptions) {\n            LocalPackage.DefaultInstallOptions = {\n                installMode: InstallMode.ON_NEXT_RESTART,\n                minimumBackgroundDuration: 0,\n                mandatoryInstallMode: InstallMode.IMMEDIATE\n            };\n        }\n        return LocalPackage.DefaultInstallOptions;\n    };\n    LocalPackage.RootDir = \"codepush\";\n    LocalPackage.DownloadDir = LocalPackage.RootDir + \"/download\";\n    LocalPackage.DownloadUnzipDir = LocalPackage.DownloadDir + \"/unzipped\";\n    LocalPackage.DeployDir = LocalPackage.RootDir + \"/deploy\";\n    LocalPackage.VersionsDir = LocalPackage.DeployDir + \"/versions\";\n    LocalPackage.PackageUpdateFileName = \"update.zip\";\n    LocalPackage.PackageInfoFile = \"currentPackage.json\";\n    LocalPackage.OldPackageInfoFile = \"oldPackage.json\";\n    LocalPackage.DiffManifestFile = \"hotcodepush.json\";\n    return LocalPackage;\n}(Package));\nmodule.exports = LocalPackage;\n"
  },
  {
    "path": "plugins/cordova-plugin-code-push/bin/www/nativeAppInfo.js",
    "content": "\n /******************************************************************************************** \n \t THIS FILE HAS BEEN COMPILED FROM TYPESCRIPT SOURCES. \n \t PLEASE DO NOT MODIFY THIS FILE AS YOU WILL LOSE YOUR CHANGES WHEN RECOMPILING. \n \t ALSO, PLEASE DO NOT SUBMIT PULL REQUESTS WITH CHANGES TO THIS FILE. \n \t INSTEAD, EDIT THE TYPESCRIPT SOURCES UNDER THE WWW FOLDER. \n \t FOR MORE INFORMATION, PLEASE SEE CONTRIBUTING.md. \n *********************************************************************************************/ \n\n\n\"use strict\";\nvar DefaultServerUrl = \"https://codepush.azurewebsites.net/\";\nvar NativeAppInfo = (function () {\n    function NativeAppInfo() {\n    }\n    NativeAppInfo.getApplicationBuildTime = function (callback) {\n        var timestampSuccess = function (timestamp) { callback(null, timestamp); };\n        var timestampError = function () { callback(new Error(\"Could not get application timestamp.\"), null); };\n        cordova.exec(timestampSuccess, timestampError, \"CodePush\", \"getNativeBuildTime\", []);\n    };\n    NativeAppInfo.getApplicationVersion = function (callback) {\n        var versionSuccess = function (version) { callback(null, version); };\n        var versionError = function () { callback(new Error(\"Could not get application version.\"), null); };\n        cordova.exec(versionSuccess, versionError, \"CodePush\", \"getAppVersion\", []);\n    };\n    NativeAppInfo.getBinaryHash = function (callback) {\n        var binaryHashSuccess = function (binaryHash) { callback(null, binaryHash); };\n        var binaryHashError = function () { callback(new Error(\"Could not get binary hash.\"), null); };\n        cordova.exec(binaryHashSuccess, binaryHashError, \"CodePush\", \"getBinaryHash\", []);\n    };\n    NativeAppInfo.getServerURL = function (serverCallback) {\n        var serverSuccess = function (serverURL) { serverCallback(null, serverURL); };\n        var serverError = function () { serverCallback(null, DefaultServerUrl); };\n        cordova.exec(serverSuccess, serverError, \"CodePush\", \"getServerURL\", []);\n    };\n    NativeAppInfo.getDeploymentKey = function (deploymentKeyCallback) {\n        var deploymentSuccess = function (deploymentKey) { deploymentKeyCallback(null, deploymentKey); };\n        var deploymentError = function () { deploymentKeyCallback(new Error(\"Deployment key not found.\"), null); };\n        cordova.exec(deploymentSuccess, deploymentError, \"CodePush\", \"getDeploymentKey\", []);\n    };\n    NativeAppInfo.isFailedUpdate = function (packageHash, checkCallback) {\n        var win = function (failed) {\n            checkCallback && checkCallback(!!failed);\n        };\n        var fail = function (e) {\n            win(0);\n        };\n        cordova.exec(win, fail, \"CodePush\", \"isFailedUpdate\", [packageHash]);\n    };\n    NativeAppInfo.isFirstRun = function (packageHash, firstRunCallback) {\n        var win = function (firstRun) {\n            firstRunCallback(!!firstRun);\n        };\n        var fail = function () {\n            firstRunCallback(false);\n        };\n        cordova.exec(win, fail, \"CodePush\", \"isFirstRun\", [packageHash]);\n    };\n    NativeAppInfo.isPendingUpdate = function (callback) {\n        var win = function (firstRun) {\n            callback(!!firstRun);\n        };\n        var fail = function () {\n            callback(false);\n        };\n        cordova.exec(win, fail, \"CodePush\", \"isPendingUpdate\", []);\n    };\n    return NativeAppInfo;\n}());\nmodule.exports = NativeAppInfo;\n"
  },
  {
    "path": "plugins/cordova-plugin-code-push/bin/www/package.js",
    "content": "\n /******************************************************************************************** \n \t THIS FILE HAS BEEN COMPILED FROM TYPESCRIPT SOURCES. \n \t PLEASE DO NOT MODIFY THIS FILE AS YOU WILL LOSE YOUR CHANGES WHEN RECOMPILING. \n \t ALSO, PLEASE DO NOT SUBMIT PULL REQUESTS WITH CHANGES TO THIS FILE. \n \t INSTEAD, EDIT THE TYPESCRIPT SOURCES UNDER THE WWW FOLDER. \n \t FOR MORE INFORMATION, PLEASE SEE CONTRIBUTING.md. \n *********************************************************************************************/ \n\n\n\"use strict\";\nvar Package = (function () {\n    function Package() {\n    }\n    return Package;\n}());\nmodule.exports = Package;\n"
  },
  {
    "path": "plugins/cordova-plugin-code-push/bin/www/remotePackage.js",
    "content": "\n /******************************************************************************************** \n \t THIS FILE HAS BEEN COMPILED FROM TYPESCRIPT SOURCES. \n \t PLEASE DO NOT MODIFY THIS FILE AS YOU WILL LOSE YOUR CHANGES WHEN RECOMPILING. \n \t ALSO, PLEASE DO NOT SUBMIT PULL REQUESTS WITH CHANGES TO THIS FILE. \n \t INSTEAD, EDIT THE TYPESCRIPT SOURCES UNDER THE WWW FOLDER. \n \t FOR MORE INFORMATION, PLEASE SEE CONTRIBUTING.md. \n *********************************************************************************************/ \n\n\n\"use strict\";\nvar __extends = (this && this.__extends) || function (d, b) {\n    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];\n    function __() { this.constructor = d; }\n    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n};\nvar LocalPackage = require(\"./localPackage\");\nvar Package = require(\"./package\");\nvar NativeAppInfo = require(\"./nativeAppInfo\");\nvar CodePushUtil = require(\"./codePushUtil\");\nvar Sdk = require(\"./sdk\");\nvar RemotePackage = (function (_super) {\n    __extends(RemotePackage, _super);\n    function RemotePackage() {\n        _super.apply(this, arguments);\n    }\n    RemotePackage.prototype.download = function (successCallback, errorCallback, downloadProgress) {\n        var _this = this;\n        try {\n            CodePushUtil.logMessage(\"Downloading update\");\n            if (!this.downloadUrl) {\n                CodePushUtil.invokeErrorCallback(new Error(\"The remote package does not contain a download URL.\"), errorCallback);\n            }\n            else {\n                this.currentFileTransfer = new FileTransfer();\n                var downloadSuccess = function (fileEntry) {\n                    _this.currentFileTransfer = null;\n                    fileEntry.file(function (file) {\n                        NativeAppInfo.isFailedUpdate(_this.packageHash, function (installFailed) {\n                            var localPackage = new LocalPackage();\n                            localPackage.deploymentKey = _this.deploymentKey;\n                            localPackage.description = _this.description;\n                            localPackage.label = _this.label;\n                            localPackage.appVersion = _this.appVersion;\n                            localPackage.isMandatory = _this.isMandatory;\n                            localPackage.packageHash = _this.packageHash;\n                            localPackage.isFirstRun = false;\n                            localPackage.failedInstall = installFailed;\n                            localPackage.localPath = fileEntry.toInternalURL();\n                            CodePushUtil.logMessage(\"Package download success: \" + JSON.stringify(localPackage));\n                            successCallback && successCallback(localPackage);\n                            Sdk.reportStatusDownload(localPackage, localPackage.deploymentKey);\n                        });\n                    }, function (fileError) {\n                        CodePushUtil.invokeErrorCallback(new Error(\"Could not access local package. Error code: \" + fileError.code), errorCallback);\n                    });\n                };\n                var downloadError = function (error) {\n                    _this.currentFileTransfer = null;\n                    CodePushUtil.invokeErrorCallback(new Error(error.body), errorCallback);\n                };\n                this.currentFileTransfer.onprogress = function (progressEvent) {\n                    if (downloadProgress) {\n                        var dp = { receivedBytes: progressEvent.loaded, totalBytes: progressEvent.total };\n                        downloadProgress(dp);\n                    }\n                };\n                this.currentFileTransfer.download(this.downloadUrl, cordova.file.dataDirectory + LocalPackage.DownloadDir + \"/\" + LocalPackage.PackageUpdateFileName, downloadSuccess, downloadError, true);\n            }\n        }\n        catch (e) {\n            CodePushUtil.invokeErrorCallback(new Error(\"An error occured while downloading the package. \" + (e && e.message) ? e.message : \"\"), errorCallback);\n        }\n    };\n    RemotePackage.prototype.abortDownload = function (abortSuccess, abortError) {\n        try {\n            if (this.currentFileTransfer) {\n                this.currentFileTransfer.abort();\n                abortSuccess && abortSuccess();\n            }\n        }\n        catch (e) {\n            abortError && abortError(e);\n        }\n    };\n    return RemotePackage;\n}(Package));\nmodule.exports = RemotePackage;\n"
  },
  {
    "path": "plugins/cordova-plugin-code-push/bin/www/sdk.js",
    "content": "\n /******************************************************************************************** \n \t THIS FILE HAS BEEN COMPILED FROM TYPESCRIPT SOURCES. \n \t PLEASE DO NOT MODIFY THIS FILE AS YOU WILL LOSE YOUR CHANGES WHEN RECOMPILING. \n \t ALSO, PLEASE DO NOT SUBMIT PULL REQUESTS WITH CHANGES TO THIS FILE. \n \t INSTEAD, EDIT THE TYPESCRIPT SOURCES UNDER THE WWW FOLDER. \n \t FOR MORE INFORMATION, PLEASE SEE CONTRIBUTING.md. \n *********************************************************************************************/ \n\n\n\"use strict\";\nvar NativeAppInfo = require(\"./nativeAppInfo\");\nvar HttpRequester = require(\"./httpRequester\");\nvar Sdk = (function () {\n    function Sdk() {\n    }\n    Sdk.getAcquisitionManager = function (callback, userDeploymentKey, contentType) {\n        var resolveManager = function () {\n            if (userDeploymentKey !== Sdk.DefaultConfiguration.deploymentKey || contentType) {\n                var customConfiguration = {\n                    deploymentKey: userDeploymentKey || Sdk.DefaultConfiguration.deploymentKey,\n                    serverUrl: Sdk.DefaultConfiguration.serverUrl,\n                    ignoreAppVersion: Sdk.DefaultConfiguration.ignoreAppVersion,\n                    appVersion: Sdk.DefaultConfiguration.appVersion,\n                    clientUniqueId: Sdk.DefaultConfiguration.clientUniqueId\n                };\n                var requester = new HttpRequester(contentType);\n                var customAcquisitionManager = new AcquisitionManager(requester, customConfiguration);\n                callback(null, customAcquisitionManager);\n            }\n            else if (Sdk.DefaultConfiguration.deploymentKey) {\n                callback(null, Sdk.DefaultAcquisitionManager);\n            }\n            else {\n                callback(new Error(\"No deployment key provided, please provide a default one in your config.xml or specify one in the call to checkForUpdate() or sync().\"), null);\n            }\n        };\n        if (Sdk.DefaultAcquisitionManager) {\n            resolveManager();\n        }\n        else {\n            NativeAppInfo.getServerURL(function (serverError, serverURL) {\n                NativeAppInfo.getDeploymentKey(function (depolymentKeyError, deploymentKey) {\n                    NativeAppInfo.getApplicationVersion(function (appVersionError, appVersion) {\n                        if (!serverURL || !appVersion) {\n                            callback(new Error(\"Could not get the CodePush configuration. Please check your config.xml file.\"), null);\n                        }\n                        else {\n                            Sdk.DefaultConfiguration = {\n                                deploymentKey: deploymentKey,\n                                serverUrl: serverURL,\n                                ignoreAppVersion: false,\n                                appVersion: appVersion,\n                                clientUniqueId: device.uuid\n                            };\n                            if (deploymentKey) {\n                                Sdk.DefaultAcquisitionManager = new AcquisitionManager(new HttpRequester(), Sdk.DefaultConfiguration);\n                            }\n                            resolveManager();\n                        }\n                    });\n                });\n            });\n        }\n    };\n    Sdk.reportStatusDeploy = function (pkg, status, currentDeploymentKey, previousLabelOrAppVersion, previousDeploymentKey, callback) {\n        try {\n            Sdk.getAcquisitionManager(function (error, acquisitionManager) {\n                if (error) {\n                    callback && callback(error, null);\n                }\n                else {\n                    console.log(\"Reporting status: \" + status + \" label: \" + (pkg && pkg.label) + \" appVersion: \" + Sdk.DefaultConfiguration.appVersion + \" previousLabelOrAppVersion: \" + previousLabelOrAppVersion + \" previousDeploymentKey:\" + previousDeploymentKey);\n                    acquisitionManager.reportStatusDeploy(pkg, status, previousLabelOrAppVersion, previousDeploymentKey, callback);\n                }\n            }, currentDeploymentKey, \"application/json\");\n        }\n        catch (e) {\n            callback && callback(new Error(\"An error occured while reporting the deployment status. \" + e), null);\n        }\n    };\n    Sdk.reportStatusDownload = function (pkg, deploymentKey, callback) {\n        try {\n            Sdk.getAcquisitionManager(function (error, acquisitionManager) {\n                if (error) {\n                    callback && callback(error, null);\n                }\n                else {\n                    acquisitionManager.reportStatusDownload(pkg, callback);\n                }\n            }, deploymentKey, \"application/json\");\n        }\n        catch (e) {\n            callback && callback(new Error(\"An error occured while reporting the download status. \" + e), null);\n        }\n    };\n    return Sdk;\n}());\nmodule.exports = Sdk;\n"
  },
  {
    "path": "plugins/cordova-plugin-code-push/bin/www/syncStatus.js",
    "content": "\n /******************************************************************************************** \n \t THIS FILE HAS BEEN COMPILED FROM TYPESCRIPT SOURCES. \n \t PLEASE DO NOT MODIFY THIS FILE AS YOU WILL LOSE YOUR CHANGES WHEN RECOMPILING. \n \t ALSO, PLEASE DO NOT SUBMIT PULL REQUESTS WITH CHANGES TO THIS FILE. \n \t INSTEAD, EDIT THE TYPESCRIPT SOURCES UNDER THE WWW FOLDER. \n \t FOR MORE INFORMATION, PLEASE SEE CONTRIBUTING.md. \n *********************************************************************************************/ \n\n\n\"use strict\";\nvar SyncStatus;\n(function (SyncStatus) {\n    SyncStatus[SyncStatus[\"UP_TO_DATE\"] = 0] = \"UP_TO_DATE\";\n    SyncStatus[SyncStatus[\"UPDATE_INSTALLED\"] = 1] = \"UPDATE_INSTALLED\";\n    SyncStatus[SyncStatus[\"UPDATE_IGNORED\"] = 2] = \"UPDATE_IGNORED\";\n    SyncStatus[SyncStatus[\"ERROR\"] = 3] = \"ERROR\";\n    SyncStatus[SyncStatus[\"IN_PROGRESS\"] = 4] = \"IN_PROGRESS\";\n    SyncStatus[SyncStatus[\"CHECKING_FOR_UPDATE\"] = 5] = \"CHECKING_FOR_UPDATE\";\n    SyncStatus[SyncStatus[\"AWAITING_USER_ACTION\"] = 6] = \"AWAITING_USER_ACTION\";\n    SyncStatus[SyncStatus[\"DOWNLOADING_PACKAGE\"] = 7] = \"DOWNLOADING_PACKAGE\";\n    SyncStatus[SyncStatus[\"INSTALLING_UPDATE\"] = 8] = \"INSTALLING_UPDATE\";\n})(SyncStatus || (SyncStatus = {}));\nmodule.exports = SyncStatus;\n"
  },
  {
    "path": "plugins/cordova-plugin-code-push/package.json",
    "content": "{\n  \"name\": \"cordova-plugin-code-push\",\n  \"version\": \"1.7.1-beta\",\n  \"description\": \"CodePush Plugin for Apache Cordova\",\n  \"cordova\": {\n    \"id\": \"cordova-plugin-code-push\",\n    \"platforms\": [\n      \"android\",\n      \"ios\"\n    ]\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/Microsoft/cordova-plugin-code-push\"\n  },\n  \"keywords\": [\n    \"cordova\",\n    \"code\",\n    \"push\",\n    \"ecosystem:cordova\",\n    \"cordova-android\",\n    \"cordova-ios\"\n  ],\n  \"peerDependencies\": {\n    \"code-push\": \">=1.8.0-beta\",\n    \"cordova-plugin-file-transfer\": \">=1.3.0\",\n    \"cordova-plugin-file\": \">=3.0.0\",\n    \"cordova-plugin-zip\": \">=3.0.0\",\n    \"cordova-plugin-dialogs\": \">=1.1.1\",\n    \"cordova-plugin-device\": \">=1.1.0\"\n  },\n  \"author\": \"Microsoft Corporation\",\n  \"license\": \"MIT\",\n  \"devDependencies\": {\n    \"gulp\": \"latest\",\n    \"gulp-typescript\": \"latest\",\n    \"gulp-insert\": \"latest\",\n    \"gulp-tslint\": \"latest\",\n    \"tslint\": \"latest\",\n    \"del\": \"latest\",\n    \"run-sequence\": \"latest\",\n    \"q\": \"latest\",\n    \"replace\": \"latest\",\n    \"mkdirp\": \"latest\",\n    \"express\": \"latest\",\n    \"body-parser\": \"latest\",\n    \"archiver\": \"latest\"\n  }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-code-push/plugin.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n    <plugin xmlns=\"http://apache.org/cordova/ns/plugins/1.0\" id=\"cordova-plugin-code-push\" version=\"1.7.1-beta\">\n        <name>CodePush</name>\n        <description>This plugin allows you to push code updates to your apps instantly using the CodePush service</description>\n        <license>MIT</license>\n        <keywords>cordova,code,push</keywords>\n        <repo>https://github.com/Microsoft/cordova-plugin-code-push.git</repo>\n\n        <dependency id=\"code-push\" version=\">=1.8.0-beta\" />\n        <dependency id=\"cordova-plugin-file\" version=\">=3.0.0\" /> \n        <dependency id=\"cordova-plugin-file-transfer\" version=\">=1.3.0\" /> \n        <dependency id=\"cordova-plugin-zip\" version=\">=3.0.0\" />\n        <dependency id=\"cordova-plugin-dialogs\" version=\">=1.1.1\" />\n        <dependency id=\"cordova-plugin-device\" version=\">=1.1.0\" />\n\n        <js-module src=\"bin/www/codePush.js\" name=\"codePush\">\n            <clobbers target=\"codePush\" />\n        </js-module>\n\n        <js-module src=\"bin/www/localPackage.js\" name=\"localPackage\">\n            <clobbers target=\"LocalPackage\" />\n        </js-module>\n\n        <js-module src=\"bin/www/remotePackage.js\" name=\"remotePackage\">\n            <clobbers target=\"RemotePackage\" />\n        </js-module>\n\n        <js-module src=\"bin/www/syncStatus.js\" name=\"syncStatus\">\n            <clobbers target=\"SyncStatus\" />\n        </js-module>\n\n        <js-module src=\"bin/www/installMode.js\" name=\"installMode\">\n            <clobbers target=\"InstallMode\" />\n        </js-module>\n\n        <js-module src=\"bin/www/codePushUtil.js\" name=\"codePushUtil\">\n            <runs/>\n        </js-module>\n\n        <js-module src=\"bin/www/fileUtil.js\" name=\"fileUtil\">\n            <runs/>\n        </js-module>\n\n        <js-module src=\"bin/www/httpRequester.js\" name=\"httpRequester\">\n            <runs/>\n        </js-module>\n\n        <js-module src=\"bin/www/nativeAppInfo.js\" name=\"nativeAppInfo\">\n            <runs/>\n        </js-module>\n\n        <js-module src=\"bin/www/package.js\" name=\"package\">\n            <runs/>\n        </js-module>\n\n        <js-module src=\"bin/www/sdk.js\" name=\"sdk\">\n            <runs/>\n        </js-module>\n\n        <platform name=\"android\">\n            <framework src=\"src/android/build-extras.gradle\" custom=\"true\" type=\"gradleReference\" />\n            <source-file src=\"src/android/CodePush.java\" target-dir=\"src/com/microsoft/cordova\" />\n            <source-file src=\"src/android/CodePushPackageManager.java\" target-dir=\"src/com/microsoft/cordova\" />\n            <source-file src=\"src/android/CodePushPackageMetadata.java\" target-dir=\"src/com/microsoft/cordova\" />\n            <source-file src=\"src/android/CodePushPreferences.java\" target-dir=\"src/com/microsoft/cordova\" />\n            <source-file src=\"src/android/CodePushReportingManager.java\" target-dir=\"src/com/microsoft/cordova\" />\n            <source-file src=\"src/android/InstallMode.java\" target-dir=\"src/com/microsoft/cordova\" />\n            <source-file src=\"src/android/InstallOptions.java\" target-dir=\"src/com/microsoft/cordova\" />\n            <source-file src=\"src/android/Utilities.java\" target-dir=\"src/com/microsoft/cordova\" />\n            <source-file src=\"src/android/UpdateHashUtils.java\" target-dir=\"src/com/microsoft/cordova\" />\n            <config-file target=\"config.xml\" parent=\"/*\">\n                <feature name=\"CodePush\">\n                    <param name=\"android-package\" value=\"com.microsoft.cordova.CodePush\" />\n                    <param name=\"onload\" value=\"true\" />\n                </feature>\n            </config-file>\n        </platform>\n\n        <platform name=\"ios\">\n            <header-file src=\"src/ios/CodePush.h\" />\n            <source-file src=\"src/ios/CodePush.m\" />\n            <header-file src=\"src/ios/CodePushPackageMetadata.h\" />\n            <source-file src=\"src/ios/CodePushPackageMetadata.m\" />\n            <header-file src=\"src/ios/CodePushPackageManager.h\" />\n            <source-file src=\"src/ios/CodePushPackageManager.m\" />\n            <source-file src=\"src/ios/CodePushReportingManager.m\" />\n            <header-file src=\"src/ios/CodePushReportingManager.h\" />\n            <header-file src=\"src/ios/Utilities.h\" />\n            <source-file src=\"src/ios/Utilities.m\" />\n            <header-file src=\"src/ios/InstallOptions.h\" />\n            <source-file src=\"src/ios/InstallOptions.m\" />\n            <header-file src=\"src/ios/InstallMode.h\" />\n            <source-file src=\"src/ios/UpdateHashUtils.m\" />\n            <header-file src=\"src/ios/UpdateHashUtils.h\" />\n            <config-file target=\"config.xml\" parent=\"/*\">\n                <feature name=\"CodePush\">\n                    <param name=\"ios-package\" value=\"CodePush\" />\n                    <param name=\"onload\" value=\"true\" />\n                </feature>\n            </config-file>\n        </platform>\n    </plugin>\n"
  },
  {
    "path": "plugins/cordova-plugin-code-push/samples/advanced/README.md",
    "content": "# Cordova CodePush Sample App - Advanced\n\nThis is a sample application demonstrating a more advanced way you could integrate CodePush in your Cordova application. All the CodePush specific code is found in [index.js](/samples/advanced/www/js/index.js). The CodePush configuration is found in [config.xml](/samples/advanced/config.xml).\n\nWhen the application loads, on the `deviceready` event, we poll the CodePush server for an update. If an update is available, we prompt the user to install it. If the user approves it, the update is installed and the application is reloaded.\n\nFor more information on how to get started see our [Getting Started](/README.md#getting-started) section.\n"
  },
  {
    "path": "plugins/cordova-plugin-code-push/samples/advanced/config.xml",
    "content": "<?xml version='1.0' encoding='utf-8'?>\n    <widget id=\"io.cordova.hellocodepush.advanced\" version=\"1.5.0-beta\" xmlns=\"http://www.w3.org/ns/widgets\" xmlns:cdv=\"http://cordova.apache.org/ns/1.0\">\n        <name>CodePushAdvanced</name>\n        <description>\n            A sample Apache Cordova application that uses the CodePush service.\n        </description>\n\n        <!-- The contents of the main page can change between Code-Push updates, but not the name. -->\n        <content src=\"index.html\" />\n\n        <plugin name=\"cordova-plugin-whitelist\" version=\"1\" />\n        <plugin name=\"cordova-plugin-code-push\" version=\"1.5.0-beta\" />\n\n        <!-- This sample application can communicate with any external domain.\n         If you want to restrict this, don't forget to enable communication with the Code-Push server URL as well. -->\n        <access origin=\"*\" />\n\n        <allow-intent href=\"http://*/*\" />\n        <allow-intent href=\"https://*/*\" />\n        <allow-intent href=\"tel:*\" />\n        <allow-intent href=\"sms:*\" />\n        <allow-intent href=\"mailto:*\" />\n        <allow-intent href=\"geo:*\" />\n\n        <platform name=\"android\">\n            <allow-intent href=\"market:*\" />\n            <!-- CodePush deployment key for the Android platform. -->\n            <preference name=\"CodePushDeploymentKey\" value=\"TODO_ADD_ANDROID_DEPLOYMENT_KEY\" />\n        </platform>\n\n        <platform name=\"ios\">\n            <allow-intent href=\"itms:*\" />\n            <allow-intent href=\"itms-apps:*\" />\n            <!-- CodePush deployment key for the iOS platform. -->\n            <preference name=\"CodePushDeploymentKey\" value=\"TODO_ADD_IOS_DEPLOYMENT_KEY\" />\n        </platform>\n    </widget>"
  },
  {
    "path": "plugins/cordova-plugin-code-push/samples/advanced/www/css/index.css",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n* {\n    -webkit-tap-highlight-color: rgba(0,0,0,0); /* make transparent link selection, adjust last value opacity 0 to 1.0 */\n}\n\nbody {\n    -webkit-touch-callout: none;                /* prevent callout to copy image, etc when tap to hold */\n    -webkit-text-size-adjust: none;             /* prevent webkit from resizing text to fit */\n    -webkit-user-select: none;                  /* prevent copy paste, to allow, change 'none' to 'text' */\n    background-color:#E4E4E4;\n    background-image:linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);\n    background-image:-webkit-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);\n    background-image:-ms-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);\n    background-image:-webkit-gradient(\n        linear,\n        left top,\n        left bottom,\n        color-stop(0, #A7A7A7),\n        color-stop(0.51, #E4E4E4)\n    );\n    background-attachment:fixed;\n    font-family:'HelveticaNeue-Light', 'HelveticaNeue', Helvetica, Arial, sans-serif;\n    font-size:12px;\n    height:100%;\n    margin:0px;\n    padding:0px;\n    text-transform:uppercase;\n    width:100%;\n}\n\n/* Portrait layout (default) */\n.app {\n    background:url(../img/logo.png) no-repeat center top; /* 170px x 200px */\n    position:absolute;             /* position in the center of the screen */\n    left:50%;\n    top:50%;\n    height:50px;                   /* text area height */\n    width:225px;                   /* text area width */\n    text-align:center;\n    padding:180px 0px 0px 0px;     /* image height is 200px (bottom 20px are overlapped with text) */\n    margin:-115px 0px 0px -112px;  /* offset vertical: half of image height and text area height */\n                                   /* offset horizontal: half of text area width */\n}\n\n/* Landscape layout (with min-width) */\n@media screen and (min-aspect-ratio: 1/1) and (min-width:400px) {\n    .app {\n        background-position:left center;\n        padding:75px 0px 75px 170px;  /* padding-top + padding-bottom + text area = image height */\n        margin:-90px 0px 0px -198px;  /* offset vertical: half of image height */\n                                      /* offset horizontal: half of image width and text area width */\n    }\n}\n\nh1 {\n    font-size:24px;\n    font-weight:normal;\n    margin:0px;\n    overflow:visible;\n    padding:0px;\n    text-align:center;\n}\n\n.event {\n    border-radius:4px;\n    -webkit-border-radius:4px;\n    color:#FFFFFF;\n    font-size:12px;\n    margin:0px 30px;\n    padding:2px 0px;\n}\n\n.event.listening {\n    background-color:#333333;\n    display:block;\n}\n\n.event.received {\n    background-color:#4B946A;\n    display:none;\n}\n\n@keyframes fade {\n    from { opacity: 1.0; }\n    50% { opacity: 0.4; }\n    to { opacity: 1.0; }\n}\n \n@-webkit-keyframes fade {\n    from { opacity: 1.0; }\n    50% { opacity: 0.4; }\n    to { opacity: 1.0; }\n}\n \n.blink {\n    animation:fade 3000ms infinite;\n    -webkit-animation:fade 3000ms infinite;\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-code-push/samples/advanced/www/index.html",
    "content": "<!DOCTYPE html>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n     KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<html>\n    <head>\n        <!--\n        Customize this policy to fit your own app's needs. For more guidance, see:\n            https://github.com/apache/cordova-plugin-whitelist/blob/master/README.md#content-security-policy\n        Some notes:\n            * gap: is required only on iOS (when using UIWebView) and is needed for JS->native communication\n            * https://ssl.gstatic.com is required only on Android and is needed for TalkBack to function properly\n            * Disables use of inline scripts in order to mitigate risk of XSS vulnerabilities. To change this:\n                * Enable inline JS: add 'unsafe-inline' to default-src\n            * CodePush users, you need to add the CodePush server URL to the CSP's default-src\n        -->\n        <meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self' https://codepush.azurewebsites.net/ data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *\">\n        <meta name=\"format-detection\" content=\"telephone=no\">\n        <meta name=\"msapplication-tap-highlight\" content=\"no\">\n        <meta name=\"viewport\" content=\"user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width\">\n        <link rel=\"stylesheet\" type=\"text/css\" href=\"css/index.css\">\n        <title>Hello World</title>\n    </head>\n    <body>\n        <div class=\"app\">\n            <h1>Hello, CodePush (Version 1)</h1>\n            <div id=\"deviceready\" class=\"blink\">\n                <p class=\"event listening\">Connecting to Device</p>\n                <p class=\"event received\">Device is Ready</p>\n            </div>\n        </div>\n        <script type=\"text/javascript\" src=\"cordova.js\"></script>\n        <script type=\"text/javascript\" src=\"js/index.js\"></script>\n    </body>\n</html>\n"
  },
  {
    "path": "plugins/cordova-plugin-code-push/samples/advanced/www/js/index.js",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\nvar app = {\n    // Application Constructor\n    initialize: function () {\n        this.bindEvents();\n    },\n    // Bind Event Listeners\n    //\n    // Bind any events that are required on startup. Common events are:\n    // 'load', 'deviceready', 'offline', and 'online'.\n    bindEvents: function () {\n        document.addEventListener('deviceready', this.onDeviceReady, false);\n    },\n    // deviceready Event Handler\n    //\n    // The scope of 'this' is the event. In order to call the 'receivedEvent'\n    // function, we must explicitly call 'app.receivedEvent(...);'\n    onDeviceReady: function () {\n        // Migrate data from older versions\n        window.codePush.getCurrentPackage(function (currentPackage) {\n            // getCurrentPackage returns null if no update was installed (app store version)\n            if (currentPackage && currentPackage.isFirstRun) {\n                // First run after an update, migrate data\n                if (currentPackage.appVersion === \"1.0.0\") {\n                    // migrate data from store version to version 1.0.0\n                } else if (currentPackage.appVersion === \"2.0.0\") {\n                    // migrate data to version 2.0.0\n                }\n            }\n            \n            // continue application initialization\n            app.receivedEvent('deviceready');\n            \n            // Wait for 5s after the application started and check for updates.\n            setTimeout(app.checkAndInstallUpdates, 5000);\n            \n            // Notify the plugin that update succeeded.\n            window.codePush.notifyApplicationReady();\n\n        }, app.getErrorHandler(\"Error while retrieving the current package.\"));\n    },\n    // Update DOM on a Received Event\n    receivedEvent: function (id) {\n        var parentElement = document.getElementById(id);\n        var listeningElement = parentElement.querySelector('.listening');\n        var receivedElement = parentElement.querySelector('.received');\n\n        listeningElement.setAttribute('style', 'display:none;');\n        receivedElement.setAttribute('style', 'display:block;');\n\n        console.log('Received Event: ' + id);\n    },\n    // Uses the CodePush service configured in config.xml to check for updates, prompt the user and install them.\n    checkAndInstallUpdates: function () {\n        \n        // Check the CodePush server for updates.\n        console.log(\"Checking for updates...\");\n        window.codePush.checkForUpdate(app.checkSuccess, app.getErrorHandler(\"Checking for update failed.\"));\n    },\n    // Called after the CodePush server responded the checkForUpdate call\n    checkSuccess: function (remotePackage) {\n        if (!remotePackage) {\n            // A null remotePackage means that the server successfully responded, but there is no update available.\n            console.log(\"The application is up to date.\");\n        }\n        else {\n            console.log(\"There is an update available. Remote package:\" + JSON.stringify(remotePackage));\n                \n            // Called after the user confirmed or canceled the update \n            function onConfirm(buttonIndex) {\n                switch (buttonIndex) {\n                    case 1:\n                        /* Install */\n                        console.log(\"Downloading package...\");\n                        remotePackage.download(app.onDownloadSuccess, app.getErrorHandler(\"Downloading the update package failed.\"));\n                        break;\n                    case 2:\n                        /* Cancel */\n                        /* nothing to do */\n                        break;\n                }\n            }\n\n            // Ask the user if they want to download and install the update\n            navigator.notification.confirm(\n                'An update is available. Would you like to download and install it?',\n                onConfirm,\n                'Update'\n                ['Install', 'Cancel']);\n        }\n    },\n    // Called after an update package was downloaded sucessfully.\n    onDownloadSuccess: function (localPackage) {\n        console.log(\"Local package downloaded. Local package: \" + localPackage.localPath);\n\n        var installCallback = function () {\n            console.log(\"Install succeeded\");\n        };\n\n        console.log(\"Installing package...\");\n        localPackage.install(installCallback, app.getErrorHandler(\"Installation failed.\"), { installMode: InstallMode.IMMEDIATE });\n    },\n    // Returns an error handler that logs the error to the console and displays a notification containing the error message.\n    getErrorHandler: function (message) {\n        // Displays a dialog containing a message.\n        var displayErrorMessage = function (message) {\n            navigator.notification.alert(\n                message,\n                null,\n                'CodePush',\n                'OK');\n        };\n\n        return function (error) {\n            console.log(message + \":\" + error.message);\n            displayErrorMessage(message + \":\" + error.message);\n        }\n    }\n};\n\napp.initialize();"
  },
  {
    "path": "plugins/cordova-plugin-code-push/samples/basic/README.md",
    "content": "# Cordova CodePush Sample App - Basic\n\nThis is a sample application demonstrating the CodePush sync operation. This operation offers a very easy way of integrating CodePush in your application, by invoking only one function. All the CodePush specific code is found in [index.js](/samples/basic/www/js/index.js). The CodePush configuration is found in [config.xml](/samples/basic/config.xml).\n\nWhen the application loads, on the `deviceready` event, we invoke sync. This checks for an update, and if one is available, the user will be prompted to install it. Once the user accepts it, the update is installed and the application reloaded. See [SyncOptions](/README.md#syncoptions) in our documentation for customizing the sync behavior. \n\nFor more information on how to get started see our [Getting Started](/README.md#getting-started) section.\n"
  },
  {
    "path": "plugins/cordova-plugin-code-push/samples/basic/config.xml",
    "content": "<?xml version='1.0' encoding='utf-8'?>\n    <widget id=\"io.cordova.hellocodepush.basic\" version=\"1.5.0-beta\" xmlns=\"http://www.w3.org/ns/widgets\" xmlns:cdv=\"http://cordova.apache.org/ns/1.0\">\n        <name>CodePushBasic</name>\n        <description>\n            A sample Apache Cordova application that uses the CodePush service.\n        </description>\n\n        <!-- The contents of the main page can change between Code-Push updates, but not the name. -->\n        <content src=\"index.html\" />\n\n        <plugin name=\"cordova-plugin-whitelist\" version=\"1\" />\n        <plugin name=\"cordova-plugin-code-push\" version=\"1.5.0-beta\" />\n\n        <!-- This sample application can communicate with any external domain.\n         If you want to restrict this, don't forget to enable communication with the Code-Push server URL as well. -->\n        <access origin=\"*\" />\n\n        <allow-intent href=\"http://*/*\" />\n        <allow-intent href=\"https://*/*\" />\n        <allow-intent href=\"tel:*\" />\n        <allow-intent href=\"sms:*\" />\n        <allow-intent href=\"mailto:*\" />\n        <allow-intent href=\"geo:*\" />\n\n        <platform name=\"android\">\n            <allow-intent href=\"market:*\" />\n            <!-- CodePush deployment key for the Android platform. -->\n            <preference name=\"CodePushDeploymentKey\" value=\"TODO_ADD_ANDROID_DEPLOYMENT_KEY\" />\n        </platform>\n\n        <platform name=\"ios\">\n            <allow-intent href=\"itms:*\" />\n            <allow-intent href=\"itms-apps:*\" />\n            <!-- CodePush deployment key for the iOS platform. -->\n            <preference name=\"CodePushDeploymentKey\" value=\"TODO_ADD_IOS_DEPLOYMENT_KEY\" />\n        </platform>\n    </widget>"
  },
  {
    "path": "plugins/cordova-plugin-code-push/samples/basic/www/css/index.css",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n* {\n    -webkit-tap-highlight-color: rgba(0,0,0,0); /* make transparent link selection, adjust last value opacity 0 to 1.0 */\n}\n\nbody {\n    -webkit-touch-callout: none;                /* prevent callout to copy image, etc when tap to hold */\n    -webkit-text-size-adjust: none;             /* prevent webkit from resizing text to fit */\n    -webkit-user-select: none;                  /* prevent copy paste, to allow, change 'none' to 'text' */\n    background-color:#E4E4E4;\n    background-image:linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);\n    background-image:-webkit-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);\n    background-image:-ms-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);\n    background-image:-webkit-gradient(\n        linear,\n        left top,\n        left bottom,\n        color-stop(0, #A7A7A7),\n        color-stop(0.51, #E4E4E4)\n    );\n    background-attachment:fixed;\n    font-family:'HelveticaNeue-Light', 'HelveticaNeue', Helvetica, Arial, sans-serif;\n    font-size:12px;\n    height:100%;\n    margin:0px;\n    padding:0px;\n    text-transform:uppercase;\n    width:100%;\n}\n\n/* Portrait layout (default) */\n.app {\n    background:url(../img/logo.png) no-repeat center top; /* 170px x 200px */\n    position:absolute;             /* position in the center of the screen */\n    left:50%;\n    top:50%;\n    height:50px;                   /* text area height */\n    width:225px;                   /* text area width */\n    text-align:center;\n    padding:180px 0px 0px 0px;     /* image height is 200px (bottom 20px are overlapped with text) */\n    margin:-115px 0px 0px -112px;  /* offset vertical: half of image height and text area height */\n                                   /* offset horizontal: half of text area width */\n}\n\n/* Landscape layout (with min-width) */\n@media screen and (min-aspect-ratio: 1/1) and (min-width:400px) {\n    .app {\n        background-position:left center;\n        padding:75px 0px 75px 170px;  /* padding-top + padding-bottom + text area = image height */\n        margin:-90px 0px 0px -198px;  /* offset vertical: half of image height */\n                                      /* offset horizontal: half of image width and text area width */\n    }\n}\n\nh1 {\n    font-size:24px;\n    font-weight:normal;\n    margin:0px;\n    overflow:visible;\n    padding:0px;\n    text-align:center;\n}\n\n.event {\n    border-radius:4px;\n    -webkit-border-radius:4px;\n    color:#FFFFFF;\n    font-size:12px;\n    margin:0px 30px;\n    padding:2px 0px;\n}\n\n.event.listening {\n    background-color:#333333;\n    display:block;\n}\n\n.event.received {\n    background-color:#4B946A;\n    display:none;\n}\n\n@keyframes fade {\n    from { opacity: 1.0; }\n    50% { opacity: 0.4; }\n    to { opacity: 1.0; }\n}\n \n@-webkit-keyframes fade {\n    from { opacity: 1.0; }\n    50% { opacity: 0.4; }\n    to { opacity: 1.0; }\n}\n \n.blink {\n    animation:fade 3000ms infinite;\n    -webkit-animation:fade 3000ms infinite;\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-code-push/samples/basic/www/index.html",
    "content": "<!DOCTYPE html>\n<!--\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n     KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n<html>\n    <head>\n        <!--\n        Customize this policy to fit your own app's needs. For more guidance, see:\n            https://github.com/apache/cordova-plugin-whitelist/blob/master/README.md#content-security-policy\n        Some notes:\n            * gap: is required only on iOS (when using UIWebView) and is needed for JS->native communication\n            * https://ssl.gstatic.com is required only on Android and is needed for TalkBack to function properly\n            * Disables use of inline scripts in order to mitigate risk of XSS vulnerabilities. To change this:\n                * Enable inline JS: add 'unsafe-inline' to default-src\n            * CodePush users, you need to add the CodePush server URL to the CSP's default-src\n        -->\n        <meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self' https://codepush.azurewebsites.net/ data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *\">\n        <meta name=\"format-detection\" content=\"telephone=no\">\n        <meta name=\"msapplication-tap-highlight\" content=\"no\">\n        <meta name=\"viewport\" content=\"user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width\">\n        <link rel=\"stylesheet\" type=\"text/css\" href=\"css/index.css\">\n        <title>Hello World</title>\n    </head>\n    <body>\n        <div class=\"app\">\n            <h1>Hello, CodePush (Version 1)</h1>\n            <div id=\"deviceready\" class=\"blink\">\n                <p class=\"event listening\">Connecting to Device</p>\n                <p class=\"event received\">Device is Ready</p>\n            </div>\n        </div>\n        <script type=\"text/javascript\" src=\"cordova.js\"></script>\n        <script type=\"text/javascript\" src=\"js/index.js\"></script>\n    </body>\n</html>\n"
  },
  {
    "path": "plugins/cordova-plugin-code-push/samples/basic/www/js/index.js",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\nvar app = {\n    // Application Constructor\n    initialize: function () {\n        this.bindEvents();\n    },\n    // Bind Event Listeners\n    //\n    // Bind any events that are required on startup. Common events are:\n    // 'load', 'deviceready', 'offline', and 'online'.\n    bindEvents: function () {\n        document.addEventListener('deviceready', this.onDeviceReady, false);\n    },\n    // deviceready Event Handler\n    //\n    // The scope of 'this' is the event. In order to call the 'receivedEvent'\n    // function, we must explicitly call 'app.receivedEvent(...);'\n    onDeviceReady: function () {\n        \n        /* Invoke sync with the custom options, which enables user interaction.\n           For customizing the sync behavior, see SyncOptions in the CodePush documentation. */\n        window.codePush.sync(\n            function (syncStatus) {\n                switch (syncStatus) {\n                    // Result (final) statuses\n                    case SyncStatus.UPDATE_INSTALLED:\n                        app.displayMessage(\"The update was installed successfully. For InstallMode.ON_NEXT_RESTART, the changes will be visible after application restart. \");\n                        break;\n                    case SyncStatus.UP_TO_DATE:\n                        app.displayMessage(\"The application is up to date.\");\n                        break;\n                    case SyncStatus.UPDATE_IGNORED:\n                        app.displayMessage(\"The user decided not to install the optional update.\");\n                        break;\n                    case SyncStatus.ERROR:\n                        app.displayMessage(\"An error occured while checking for updates\");\n                        break;\n                    \n                    // Intermediate (non final) statuses\n                    case SyncStatus.CHECKING_FOR_UPDATE:\n                        console.log(\"Checking for update.\");\n                        break;\n                    case SyncStatus.AWAITING_USER_ACTION:\n                        console.log(\"Alerting user.\");\n                        break;\n                    case SyncStatus.DOWNLOADING_PACKAGE:\n                        console.log(\"Downloading package.\");\n                        break;\n                    case SyncStatus.INSTALLING_UPDATE:\n                        console.log(\"Installing update\");\n                        break;\n                }\n            },\n            {\n                installMode: InstallMode.ON_NEXT_RESTART, updateDialog: true\n            },\n            function (downloadProgress) {\n                console.log(\"Downloading \" + downloadProgress.receivedBytes + \" of \" + downloadProgress.totalBytes + \" bytes.\");\n            });\n            \n        // continue application initialization\n        app.receivedEvent('deviceready');\n    },\n    // Update DOM on a Received Event\n    receivedEvent: function (id) {\n        var parentElement = document.getElementById(id);\n        var listeningElement = parentElement.querySelector('.listening');\n        var receivedElement = parentElement.querySelector('.received');\n\n        listeningElement.setAttribute('style', 'display:none;');\n        receivedElement.setAttribute('style', 'display:block;');\n\n        console.log('Received Event: ' + id);\n    },\n    // Displays an alert dialog containing a message.\n    displayMessage: function (message) {\n        navigator.notification.alert(\n            message,\n            null,\n            'CodePush',\n            'OK');\n    }\n};\n\napp.initialize();"
  },
  {
    "path": "plugins/cordova-plugin-code-push/src/android/CodePush.java",
    "content": "package com.microsoft.cordova;\n\nimport android.content.pm.PackageManager;\nimport android.os.AsyncTask;\n\nimport org.apache.cordova.CallbackContext;\nimport org.apache.cordova.ConfigXmlParser;\nimport org.apache.cordova.CordovaArgs;\nimport org.apache.cordova.CordovaInterface;\nimport org.apache.cordova.CordovaPlugin;\nimport org.apache.cordova.CordovaWebView;\nimport org.json.JSONException;\n\nimport java.io.File;\nimport java.io.IOException;\nimport java.net.MalformedURLException;\nimport java.security.NoSuchAlgorithmException;\n\nimport java.util.Date;\n\n/**\n * Native Android CodePush Cordova Plugin.\n */\npublic class CodePush extends CordovaPlugin {\n\n    public static final String RESOURCES_BUNDLE = \"resources.arsc\";\n    private static final String DEPLOYMENT_KEY_PREFERENCE = \"codepushdeploymentkey\";\n    private static final String WWW_ASSET_PATH_PREFIX = \"file:///android_asset/www/\";\n    private static boolean ShouldClearHistoryOnLoad = false;\n    private CordovaWebView mainWebView;\n    private CodePushPackageManager codePushPackageManager;\n    private CodePushReportingManager codePushReportingManager;\n    private boolean pluginDestroyed = false;\n    private boolean didUpdate = false;\n    private boolean didStartApp = false;\n    private long lastPausedTimeMs = 0;\n\n    @Override\n    public void initialize(CordovaInterface cordova, CordovaWebView webView) {\n        super.initialize(cordova, webView);\n        CodePushPreferences codePushPreferences = new CodePushPreferences(cordova.getActivity());\n        codePushPackageManager = new CodePushPackageManager(cordova.getActivity(), codePushPreferences);\n        codePushReportingManager = new CodePushReportingManager(cordova.getActivity(), codePushPreferences);\n        mainWebView = webView;\n    }\n\n    @Override\n    public boolean execute(String action, CordovaArgs args, final CallbackContext callbackContext) {\n        if (\"getServerURL\".equals(action)) {\n            this.returnStringPreference(\"codepushserverurl\", callbackContext);\n            return true;\n        } else if (\"getDeploymentKey\".equals(action)) {\n            this.returnStringPreference(DEPLOYMENT_KEY_PREFERENCE, callbackContext);\n            return true;\n        } else if (\"getNativeBuildTime\".equals(action)) {\n            return execGetNativeBuildTime(callbackContext);\n        } else if (\"getAppVersion\".equals(action)) {\n            return execGetAppVersion(callbackContext);\n        } else if (\"getBinaryHash\".equals(action)) {\n            return execGetBinaryHash(callbackContext);\n        } else if (\"preInstall\".equals(action)) {\n            return execPreInstall(args, callbackContext);\n        } else if (\"install\".equals(action)) {\n            return execInstall(args, callbackContext);\n        } else if (\"updateSuccess\".equals(action)) {\n            return execUpdateSuccess(callbackContext);\n        } else if (\"restartApplication\".equals(action)) {\n            return execRestartApplication(args, callbackContext);\n        } else if (\"isPendingUpdate\".equals(action)) {\n            return execIsPendingUpdate(args, callbackContext);\n        } else if (\"isFailedUpdate\".equals(action)) {\n            return execIsFailedUpdate(args, callbackContext);\n        } else if (\"isFirstRun\".equals(action)) {\n            return execIsFirstRun(args, callbackContext);\n        } else {\n            return false;\n        }\n    }\n\n    private boolean execGetBinaryHash(final CallbackContext callbackContext) {\n        String cachedBinaryHash = codePushPackageManager.getCachedBinaryHash();\n        if (cachedBinaryHash == null) {\n            new AsyncTask<Void, Void, Void>() {\n                @Override\n                protected Void doInBackground(Void... params) {\n                    try {\n                        String binaryHash = UpdateHashUtils.getBinaryHash(cordova.getActivity());\n                        codePushPackageManager.saveBinaryHash(binaryHash);\n                        callbackContext.success(binaryHash);\n                    } catch (IOException e) {\n                        callbackContext.error(\"An error occurred when trying to get the hash of the binary contents. \" + e.getMessage());\n                    } catch (NoSuchAlgorithmException e) {\n                        callbackContext.error(\"An error occurred when trying to get the hash of the binary contents. \" + e.getMessage());\n                    }\n\n                    return null;\n                }\n            }.execute();\n        } else {\n            callbackContext.success(cachedBinaryHash);\n        }\n\n        return true;\n    }\n\n    private boolean execUpdateSuccess(CallbackContext callbackContext) {\n        if (this.codePushPackageManager.isFirstRun()) {\n            this.codePushPackageManager.saveFirstRunFlag();\n            /* save reporting status for first install */\n            try {\n                String appVersion = Utilities.getAppVersionName(cordova.getActivity());\n                codePushReportingManager.reportStatus(CodePushReportingManager.Status.STORE_VERSION, null, appVersion, mainWebView.getPreferences().getString(DEPLOYMENT_KEY_PREFERENCE, null), this.mainWebView);\n            } catch (PackageManager.NameNotFoundException e) {\n                // Should not happen unless the appVersion is not specified, in which case we can't report anything anyway.\n                e.printStackTrace();\n            }\n        }\n\n        if (this.codePushPackageManager.installNeedsConfirmation()) {\n            /* save reporting status */\n            CodePushPackageMetadata currentMetadata = this.codePushPackageManager.getCurrentPackageMetadata();\n            codePushReportingManager.reportStatus(CodePushReportingManager.Status.UPDATE_CONFIRMED, currentMetadata.label, currentMetadata.appVersion, currentMetadata.deploymentKey, this.mainWebView);\n        }\n\n        this.codePushPackageManager.clearInstallNeedsConfirmation();\n        this.cleanOldPackageSilently();\n        callbackContext.success();\n\n        return true;\n    }\n\n    private boolean execIsFirstRun(CordovaArgs args, CallbackContext callbackContext) {\n        try {\n            boolean isFirstRun = false;\n            String packageHash = args.getString(0);\n            CodePushPackageMetadata currentPackageMetadata = codePushPackageManager.getCurrentPackageMetadata();\n            if (null != currentPackageMetadata) {\n                /* This is the first run for a package if we just updated, and the current package hash matches the one provided. */\n                isFirstRun = (null != packageHash\n                        && !packageHash.isEmpty()\n                        && packageHash.equals(currentPackageMetadata.packageHash)\n                        && didUpdate);\n            }\n            callbackContext.success(isFirstRun ? 1 : 0);\n        } catch (JSONException e) {\n            callbackContext.error(\"Invalid package hash. \" + e.getMessage());\n        }\n        return true;\n    }\n\n    private boolean execIsPendingUpdate(CordovaArgs args, CallbackContext callbackContext) {\n        try {\n            InstallOptions pendingInstall = this.codePushPackageManager.getPendingInstall();\n            callbackContext.success((pendingInstall != null) ? 1 : 0);\n        } catch (Exception e) {\n            callbackContext.error(\"An error occurred. \" + e.getMessage());\n        }\n        return true;\n    }\n\n    private boolean execIsFailedUpdate(CordovaArgs args, CallbackContext callbackContext) {\n        try {\n            final String packageHash = args.getString(0);\n            boolean isFailedUpdate = this.codePushPackageManager.isFailedUpdate(packageHash);\n            callbackContext.success(isFailedUpdate ? 1 : 0);\n        } catch (JSONException e) {\n            callbackContext.error(\"Could not read the package hash: \" + e.getMessage());\n        }\n        return true;\n    }\n\n    private boolean execInstall(CordovaArgs args, CallbackContext callbackContext) {\n        try {\n            final String startLocation = args.getString(0);\n            final InstallMode installMode = InstallMode.fromValue(args.optInt(1));\n            final int minimumBackgroundDuration = args.optInt(2);\n\n            File startPage = this.getStartPageForPackage(startLocation);\n            if (startPage != null) {\n                /* start page file exists */\n                /* navigate to the start page */\n                if (InstallMode.IMMEDIATE.equals(installMode)) {\n                    this.navigateToFile(startPage);\n                    markUpdate();\n                } else {\n                    InstallOptions pendingInstall = new InstallOptions(installMode, minimumBackgroundDuration);\n                    this.codePushPackageManager.savePendingInstall(pendingInstall);\n                }\n\n                callbackContext.success();\n            } else {\n                callbackContext.error(\"Could not find the package start page.\");\n            }\n        } catch (Exception e) {\n            callbackContext.error(\"Cound not read webview URL: \" + e.getMessage());\n        }\n        return true;\n    }\n\n    private boolean execRestartApplication(CordovaArgs args, CallbackContext callbackContext) {\n        try {\n            /* check if we have a deployed package already */\n            CodePushPackageMetadata deployedPackageMetadata = this.codePushPackageManager.getCurrentPackageMetadata();\n            if (deployedPackageMetadata != null) {\n                callbackContext.success();\n                didStartApp = false;\n                onStart();\n            } else {\n                final String configLaunchUrl = this.getConfigLaunchUrl();\n                if (!this.pluginDestroyed) {\n                    callbackContext.success();\n                    this.cordova.getActivity().runOnUiThread(new Runnable() {\n                        @Override\n                        public void run() {\n                            navigateToURL(configLaunchUrl);\n                        }\n                    });\n                }\n            }\n        } catch (Exception e) {\n            callbackContext.error(\"An error occurred while restarting the application.\" + e.getMessage());\n        }\n        return true;\n    }\n\n    private void markUpdate() {\n    /* this flag will clear when reloading the plugin */\n        this.didUpdate = true;\n        this.codePushPackageManager.markInstallNeedsConfirmation();\n    }\n\n    private void cleanOldPackageSilently() {\n        try {\n            this.codePushPackageManager.cleanOldPackage();\n        } catch (Exception e) {\n            /* silently fail if there was an error during cleanup */\n            Utilities.logException(e);\n        }\n    }\n\n    private boolean execPreInstall(CordovaArgs args, CallbackContext callbackContext) {\n    /* check if package is valid */\n        try {\n            final String startLocation = args.getString(0);\n            File startPage = this.getStartPageForPackage(startLocation);\n            if (startPage != null) {\n                /* start page exists */\n                callbackContext.success();\n            } else {\n                callbackContext.error(\"Could not get the package start page\");\n            }\n        } catch (Exception e) {\n            callbackContext.error(\"Could not get the package start page\");\n        }\n        return true;\n    }\n\n    private boolean execGetAppVersion(CallbackContext callbackContext) {\n        try {\n            String appVersionName = Utilities.getAppVersionName(this.cordova.getActivity());\n            callbackContext.success(appVersionName);\n        } catch (PackageManager.NameNotFoundException e) {\n            callbackContext.error(\"Cannot get application version.\");\n        }\n        return true;\n    }\n\n    private boolean execGetNativeBuildTime(CallbackContext callbackContext) {\n        long millis = Utilities.getApkEntryBuildTime(RESOURCES_BUNDLE, this.cordova.getActivity());\n        if (millis == -1) {\n            callbackContext.error(\"Could not get the application buildstamp.\");\n        } else {\n            String result = String.valueOf(millis);\n            callbackContext.success(result);\n        }\n        return true;\n    }\n\n    private void returnStringPreference(String preferenceName, CallbackContext callbackContext) {\n        String result = mainWebView.getPreferences().getString(preferenceName, null);\n        if (result != null) {\n            callbackContext.success(result);\n        } else {\n            callbackContext.error(\"Could not get preference: \" + preferenceName);\n        }\n    }\n\n    private void handleAppStart() {\n        try {\n            /* check if we have a deployed package already */\n            CodePushPackageMetadata deployedPackageMetadata = this.codePushPackageManager.getCurrentPackageMetadata();\n            if (deployedPackageMetadata != null) {\n                String deployedPackageTimeStamp = deployedPackageMetadata.nativeBuildTime;\n                long nativeBuildTime = Utilities.getApkEntryBuildTime(RESOURCES_BUNDLE, this.cordova.getActivity());\n                if (nativeBuildTime != -1) {\n                    String currentAppTimeStamp = String.valueOf(nativeBuildTime);\n                    if ((deployedPackageTimeStamp != null) && (currentAppTimeStamp != null)) {\n                        if (deployedPackageTimeStamp.equals(currentAppTimeStamp)) {\n                            /* same native version, safe to launch from local storage */\n                            if (deployedPackageMetadata.localPath != null) {\n                                File startPage = this.getStartPageForPackage(deployedPackageMetadata.localPath);\n                                if (startPage != null) {\n                                    /* file exists */\n                                    navigateToFile(startPage);\n                                }\n                            }\n                        } else {\n                            /* application updated in the store or via local deployment */\n                            this.codePushPackageManager.cleanDeployments();\n                            this.codePushPackageManager.clearFailedUpdates();\n                            this.codePushPackageManager.clearPendingInstall();\n                            this.codePushPackageManager.clearInstallNeedsConfirmation();\n                            try {\n                                String appVersion = Utilities.getAppVersionName(cordova.getActivity());\n                                codePushReportingManager.reportStatus(CodePushReportingManager.Status.STORE_VERSION, null, appVersion, mainWebView.getPreferences().getString(DEPLOYMENT_KEY_PREFERENCE, null), this.mainWebView);\n                            } catch (PackageManager.NameNotFoundException e) {\n                                // Should not happen unless the appVersion is not specified, in which case we can't report anything anyway.\n                                e.printStackTrace();\n                            }\n                        }\n                    }\n                }\n            }\n        } catch (Exception e) {\n            /* empty - if there is an exception, the app will launch with the bundled content */\n        }\n    }\n\n    private void handleUnconfirmedInstall(boolean navigate) {\n        if (this.codePushPackageManager.installNeedsConfirmation()) {\n            /* save status for later reporting */\n            CodePushPackageMetadata currentMetadata = this.codePushPackageManager.getCurrentPackageMetadata();\n            codePushReportingManager.reportStatus(CodePushReportingManager.Status.UPDATE_ROLLED_BACK, currentMetadata.label, currentMetadata.appVersion, currentMetadata.deploymentKey, this.mainWebView);\n\n            /* revert application to the previous version */\n            this.codePushPackageManager.clearInstallNeedsConfirmation();\n            this.codePushPackageManager.revertToPreviousVersion();\n\n            /* reload the previous version */\n            if (navigate) {\n                String url;\n                try {\n                    CodePushPackageMetadata currentPackageMetadata = this.codePushPackageManager.getCurrentPackageMetadata();\n                    url = this.getStartPageURLForPackage(currentPackageMetadata.localPath);\n                } catch (Exception e) {\n                    url = this.getConfigLaunchUrl();\n                }\n\n                final String finalURL = url;\n\n                if (!this.pluginDestroyed) {\n                    this.cordova.getActivity().runOnUiThread(new Runnable() {\n                        @Override\n                        public void run() {\n                            navigateToURL(finalURL);\n                        }\n                    });\n                }\n            }\n        }\n    }\n\n    private void navigateToFile(File startPageFile) throws MalformedURLException {\n        if (startPageFile != null) {\n            String url = startPageFile.toURI().toURL().toString();\n            this.navigateToURL(url);\n        }\n    }\n\n    private void navigateToURL(String url) {\n        if (url != null) {\n            CodePush.ShouldClearHistoryOnLoad = true;\n            this.mainWebView.loadUrlIntoView(url, false);\n        }\n    }\n\n    private File getStartPageForPackage(String packageLocation) {\n        if (packageLocation != null) {\n            File startPage = new File(this.cordova.getActivity().getFilesDir() + packageLocation, \"www/\" + getConfigStartPageName());\n            if (startPage.exists()) {\n                return startPage;\n            }\n        }\n\n        return null;\n    }\n\n    private String getStartPageURLForPackage(String packageLocation) throws MalformedURLException {\n        String result = null;\n        File startPageFile = getStartPageForPackage(packageLocation);\n        if (startPageFile != null) {\n            result = startPageFile.toURI().toURL().toString();\n        }\n\n        return result;\n    }\n\n    private String getConfigStartPageName() {\n        String launchUrl = this.getConfigLaunchUrl();\n        int launchUrlLength = launchUrl.length();\n        if (launchUrl.startsWith(CodePush.WWW_ASSET_PATH_PREFIX)) {\n            launchUrl = launchUrl.substring(CodePush.WWW_ASSET_PATH_PREFIX.length(), launchUrlLength);\n        }\n\n        return launchUrl;\n    }\n\n    private String getConfigLaunchUrl() {\n        ConfigXmlParser parser = new ConfigXmlParser();\n        parser.parse(this.cordova.getActivity());\n        return parser.getLaunchUrl();\n    }\n\n    /**\n     * Called when the system is about to start resuming a previous activity.\n     *\n     * @param multitasking Flag indicating if multitasking is turned on for app\n     */\n    @Override\n    public void onPause(boolean multitasking) {\n        lastPausedTimeMs = new Date().getTime();\n    }\n\n    /**\n     * Called when the activity will start interacting with the user.\n     *\n     * @param multitasking Flag indicating if multitasking is turned on for app\n     */\n    @Override\n    public void onResume(boolean multitasking) {\n        this.pluginDestroyed = false;\n    }\n\n    /**\n     * Called when the activity is becoming visible to the user.\n     */\n    @Override\n    public void onStart() {\n        if (!didStartApp) {\n            /* The application was just started. */\n            didStartApp = true;\n            InstallOptions pendingInstall = this.codePushPackageManager.getPendingInstall();\n\n            /* Revert to the previous version if the install is not confirmed and no update is pending. */\n            if (pendingInstall == null) {\n                handleUnconfirmedInstall(false);\n            }\n\n            handleAppStart();\n            /* Handle ON_NEXT_RESUME and ON_NEXT_RESTART pending installations */\n            if (pendingInstall != null && (InstallMode.ON_NEXT_RESUME.equals(pendingInstall.installMode) || InstallMode.ON_NEXT_RESTART.equals(pendingInstall.installMode))) {\n                this.markUpdate();\n                this.codePushPackageManager.clearPendingInstall();\n            }\n        } else {\n            /* The application was resumed from the background. */\n            /* Handle ON_NEXT_RESUME pending installations. */\n            InstallOptions pendingInstall = this.codePushPackageManager.getPendingInstall();\n            long durationInBackground = (new Date().getTime() - lastPausedTimeMs) / 1000;\n            if (pendingInstall != null && InstallMode.ON_NEXT_RESUME.equals(pendingInstall.installMode) && durationInBackground >= pendingInstall.minimumBackgroundDuration) {\n                handleAppStart();\n                this.markUpdate();\n                this.codePushPackageManager.clearPendingInstall();\n            }\n        }\n    }\n\n    /**\n     * The final call you receive before your activity is destroyed.\n     */\n    @Override\n    public void onDestroy() {\n        this.pluginDestroyed = true;\n    }\n\n    @Override\n    public Object onMessage(String id, Object data) {\n        if (\"onPageFinished\".equals(id)) {\n            if (CodePush.ShouldClearHistoryOnLoad) {\n                CodePush.ShouldClearHistoryOnLoad = false;\n                if (this.mainWebView != null) {\n                    this.mainWebView.clearHistory();\n                }\n            }\n        }\n\n        return null;\n    }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-code-push/src/android/CodePushPackageManager.java",
    "content": "package com.microsoft.cordova;\n\nimport android.content.Context;\n\nimport org.json.JSONException;\n\nimport java.io.File;\nimport java.io.IOException;\n\n/**\n * Handles update package management.\n */\npublic class CodePushPackageManager {\n\n    public static final String CODEPUSH_OLD_PACKAGE_PATH = \"/codepush/oldPackage.json\";\n    public static final String CODEPUSH_CURRENT_PACKAGE_PATH = \"/codepush/currentPackage.json\";\n\n    private Context context;\n    private CodePushPreferences codePushPreferences;\n\n    public CodePushPackageManager(Context context, CodePushPreferences codePushPreferences) {\n        this.context = context;\n        this.codePushPreferences = codePushPreferences;\n    }\n\n    public void revertToPreviousVersion() {\n        /* delete the failed update package */\n        CodePushPackageMetadata failedUpdateMetadata = this.getCurrentPackageMetadata();\n        if (failedUpdateMetadata != null) {\n            if (failedUpdateMetadata.packageHash != null) {\n                this.codePushPreferences.saveFailedUpdate(failedUpdateMetadata.packageHash);\n            }\n            File failedUpdateDir = new File(this.context.getFilesDir() + failedUpdateMetadata.localPath);\n            if (failedUpdateDir.exists()) {\n                Utilities.deleteEntryRecursively(failedUpdateDir);\n            }\n        }\n\n        /* replace the current file with the old one */\n        File currentFile = new File(this.context.getFilesDir() + CodePushPackageManager.CODEPUSH_CURRENT_PACKAGE_PATH);\n        File oldFile = new File(this.context.getFilesDir() + CodePushPackageManager.CODEPUSH_OLD_PACKAGE_PATH);\n\n        if (currentFile.exists()) {\n            currentFile.delete();\n        }\n\n        if (oldFile.exists()) {\n            oldFile.renameTo(currentFile);\n        }\n    }\n\n    public void cleanDeployments() {\n        File file = new File(this.context.getFilesDir() + \"/codepush\");\n        if (file.exists()) {\n            Utilities.deleteEntryRecursively(file);\n        }\n    }\n\n    public void cleanOldPackage() throws IOException, JSONException {\n        CodePushPackageMetadata oldPackageMetadata = this.getOldPackageMetadata();\n        if (oldPackageMetadata != null) {\n            File file = new File(this.context.getFilesDir() + oldPackageMetadata.localPath);\n            if (file.exists()) {\n                Utilities.deleteEntryRecursively(file);\n            }\n        }\n    }\n\n    public CodePushPackageMetadata getOldPackageMetadata() {\n        String currentPackageFilePath = this.context.getFilesDir() + CODEPUSH_OLD_PACKAGE_PATH;\n        return CodePushPackageMetadata.getPackageMetadata(currentPackageFilePath);\n    }\n\n    public CodePushPackageMetadata getCurrentPackageMetadata() {\n        String currentPackageFilePath = this.context.getFilesDir() + CODEPUSH_CURRENT_PACKAGE_PATH;\n        return CodePushPackageMetadata.getPackageMetadata(currentPackageFilePath);\n    }\n\n    public String getCachedBinaryHash() {\n        return this.codePushPreferences.getCachedBinaryHash();\n    }\n\n    public void saveBinaryHash(String binaryHash) {\n        this.codePushPreferences.saveBinaryHash(binaryHash);\n    }\n\n    public boolean isFailedUpdate(String packageHash) {\n        return this.codePushPreferences.isFailedUpdate(packageHash);\n    }\n\n    public void clearFailedUpdates() {\n        this.codePushPreferences.clearFailedUpdates();\n    }\n\n    public void savePendingInstall(InstallOptions options) {\n        this.codePushPreferences.savePendingInstall(options);\n    }\n\n    public InstallOptions getPendingInstall() {\n        return this.codePushPreferences.getPendingInstall();\n    }\n\n    public void clearPendingInstall() {\n        this.codePushPreferences.clearPendingInstall();\n    }\n\n    public void markInstallNeedsConfirmation() {\n        this.codePushPreferences.markInstallNeedsConfirmation();\n    }\n\n    public void clearInstallNeedsConfirmation() {\n        this.codePushPreferences.clearInstallNeedsConfirmation();\n    }\n\n    public boolean installNeedsConfirmation() {\n        return this.codePushPreferences.installNeedsConfirmation();\n    }\n\n    public boolean isFirstRun() {\n        return this.codePushPreferences.isFirstRun();\n    }\n\n    public void saveFirstRunFlag() {\n        this.codePushPreferences.saveFirstRunFlag();\n    }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-code-push/src/android/CodePushPackageMetadata.java",
    "content": "package com.microsoft.cordova;\n\nimport org.json.JSONObject;\n\nimport java.io.File;\n\n/**\n * Model class for the CodePush metadata stored alongside a package deployment.\n */\npublic class CodePushPackageMetadata {\n    public String deploymentKey;\n    public String packageDescription;\n    public String label;\n    public String appVersion;\n    public boolean isMandatory;\n    public String packageHash;\n    public long packageSize;\n    public String nativeBuildTime;\n    public String localPath;\n\n    final static class JsonField {\n        public static final String DeploymentKey = \"deploymentKey\";\n        public static final String Description = \"description\";\n        public static final String Label = \"label\";\n        public static final String AppVersion = \"appVersion\";\n        public static final String IsMandatory = \"isMandatory\";\n        public static final String PackageHash = \"packageHash\";\n        public static final String PackageSize = \"packageSize\";\n        public static final String NativeBuildTime = \"nativeBuildTime\";\n        public static final String LocalPath = \"localPath\";\n    }\n\n    public static CodePushPackageMetadata getPackageMetadata(String filePath) {\n        CodePushPackageMetadata result = null;\n\n        try {\n            File file = new File(filePath);\n            if (file.exists()) {\n                String content = Utilities.readFileContents(file);\n                result = new CodePushPackageMetadata();\n                JSONObject jsonObject = new JSONObject(content);\n\n                if (jsonObject.has(CodePushPackageMetadata.JsonField.DeploymentKey)) {\n                    result.deploymentKey = jsonObject.getString(CodePushPackageMetadata.JsonField.DeploymentKey);\n                }\n\n                if (jsonObject.has(CodePushPackageMetadata.JsonField.Description)) {\n                    result.packageDescription = jsonObject.getString(CodePushPackageMetadata.JsonField.Description);\n                }\n\n                if (jsonObject.has(CodePushPackageMetadata.JsonField.Label)) {\n                    result.label = jsonObject.getString(CodePushPackageMetadata.JsonField.Label);\n                }\n\n                if (jsonObject.has(CodePushPackageMetadata.JsonField.AppVersion)) {\n                    result.appVersion = jsonObject.getString(CodePushPackageMetadata.JsonField.AppVersion);\n                }\n\n                if (jsonObject.has(CodePushPackageMetadata.JsonField.IsMandatory)) {\n                    result.isMandatory = jsonObject.getBoolean(CodePushPackageMetadata.JsonField.IsMandatory);\n                }\n\n                if (jsonObject.has(CodePushPackageMetadata.JsonField.PackageHash)) {\n                    result.packageHash = jsonObject.getString(CodePushPackageMetadata.JsonField.PackageHash);\n                }\n\n                if (jsonObject.has(CodePushPackageMetadata.JsonField.PackageSize)) {\n                    result.packageSize = jsonObject.getLong(CodePushPackageMetadata.JsonField.PackageSize);\n                }\n\n                if (jsonObject.has(CodePushPackageMetadata.JsonField.NativeBuildTime)) {\n                    result.nativeBuildTime = jsonObject.getString(CodePushPackageMetadata.JsonField.NativeBuildTime);\n                }\n\n                if (jsonObject.has(CodePushPackageMetadata.JsonField.LocalPath)) {\n                    result.localPath = jsonObject.getString(CodePushPackageMetadata.JsonField.LocalPath);\n                }\n            }\n        } catch (Exception e) {\n            Utilities.logException(e);\n        }\n\n        return result;\n    }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-code-push/src/android/CodePushPreferences.java",
    "content": "package com.microsoft.cordova;\n\nimport android.content.Context;\nimport android.content.SharedPreferences;\n\nimport java.util.HashSet;\nimport java.util.Set;\n\n/**\n * Manages interaction with the Android preferences system.\n */\npublic class CodePushPreferences {\n\n    private static final String BINARY_HASH_PREFERENCE = \"BINARY_HASH\";\n    private static final String BINARY_HASH_PREFERENCE_KEY = \"BINARY_HASH_KEY\";\n    private static final String FAILED_UPDATES_PREFERENCE = \"FAILED_UPDATES\";\n    private static final String FAILED_UPDATES_KEY = \"FAILED_UPDATES_KEY\";\n    private static final String PENDING_INSTALL_PREFERENCE = \"PENDING_INSTALL\";\n    private static final String INSTALL_MODE_KEY = \"INSTALL_MODE_KEY\";\n    private static final String INSTALL_MIN_BACKGROUND_DURATION = \"INSTALL_MINIMUM_BACKGROUND_DURATION\";\n    private static final String INSTALL_NEEDS_CONFIRMATION = \"INSTALL_NEEDS_CONFIRMATION\";\n    private static final String INSTALL_NEEDS_CONFIRMATION_KEY = \"INSTALL_NEEDS_CONFIRMATION_KEY\";\n    private static final String FIRST_RUN_PREFERENCE = \"CODE_PUSH_FIRST_RUN\";\n    private static final String FIRST_RUN_PREFERENCE_KEY = \"CODE_PUSH_FIRST_RUN_KEY\";\n    private static final String LAST_VERSION_PREFERENCE = \"CODE_PUSH_LAST_VERSION\";\n    private static final String LAST_VERSION_DEPLOYMENT_KEY_KEY = \"LAST_VERSION_DEPLOYMENT_KEY_KEY\";\n    private static final String LAST_VERSION_LABEL_OR_APP_VERSION_KEY = \"LAST_VERSION_LABEL_OR_APP_VERSION_KEY\";\n\n    private Context context;\n\n    public CodePushPreferences(Context context) {\n        this.context = context;\n    }\n\n    public String getCachedBinaryHash() {\n        SharedPreferences preferences = context.getSharedPreferences(CodePushPreferences.BINARY_HASH_PREFERENCE, Context.MODE_PRIVATE);\n        return preferences.getString(CodePushPreferences.BINARY_HASH_PREFERENCE_KEY, null);\n    }\n\n    public void saveBinaryHash(String binaryHash) {\n        SharedPreferences preferences = context.getSharedPreferences(CodePushPreferences.BINARY_HASH_PREFERENCE, Context.MODE_PRIVATE);\n        SharedPreferences.Editor editor = preferences.edit();\n        editor.putString(CodePushPreferences.BINARY_HASH_PREFERENCE_KEY, binaryHash);\n        editor.commit();\n    }\n\n    public void saveFailedUpdate(String hashCode) {\n        SharedPreferences preferences = context.getSharedPreferences(CodePushPreferences.FAILED_UPDATES_PREFERENCE, Context.MODE_PRIVATE);\n        Set<String> failedUpdatesSet = preferences.getStringSet(CodePushPreferences.FAILED_UPDATES_KEY, null);\n        if (failedUpdatesSet == null) {\n            failedUpdatesSet = new HashSet<String>();\n        }\n\n        failedUpdatesSet.add(hashCode);\n        SharedPreferences.Editor editor = preferences.edit();\n        editor.putStringSet(CodePushPreferences.FAILED_UPDATES_KEY, failedUpdatesSet);\n        editor.commit();\n    }\n\n    public boolean isFailedUpdate(String hashCode) {\n        if (hashCode == null) {\n            return false;\n        }\n\n        SharedPreferences preferences = context.getSharedPreferences(CodePushPreferences.FAILED_UPDATES_PREFERENCE, Context.MODE_PRIVATE);\n        Set<String> failedUpdatesSet = preferences.getStringSet(CodePushPreferences.FAILED_UPDATES_KEY, null);\n        return (failedUpdatesSet != null && failedUpdatesSet.contains(hashCode));\n    }\n\n    public void clearFailedUpdates() {\n        this.clearPreferences(CodePushPreferences.FAILED_UPDATES_PREFERENCE);\n    }\n\n    public void savePendingInstall(InstallOptions installOptions) {\n        SharedPreferences preferences = context.getSharedPreferences(CodePushPreferences.PENDING_INSTALL_PREFERENCE, Context.MODE_PRIVATE);\n        SharedPreferences.Editor editor = preferences.edit();\n        editor.putInt(CodePushPreferences.INSTALL_MODE_KEY, installOptions.installMode.getValue());\n        editor.putInt(CodePushPreferences.INSTALL_MIN_BACKGROUND_DURATION, installOptions.minimumBackgroundDuration);\n        editor.commit();\n    }\n\n    public void clearPendingInstall() {\n        this.clearPreferences(CodePushPreferences.PENDING_INSTALL_PREFERENCE);\n    }\n\n    public InstallOptions getPendingInstall() {\n        InstallOptions pendingInstall = null;\n\n        SharedPreferences preferences = context.getSharedPreferences(CodePushPreferences.PENDING_INSTALL_PREFERENCE, Context.MODE_PRIVATE);\n        int installMode = preferences.getInt(CodePushPreferences.INSTALL_MODE_KEY, -1);\n        int minimumBackgroundDuration = preferences.getInt(CodePushPreferences.INSTALL_MIN_BACKGROUND_DURATION, -1);\n\n        if (installMode != -1 && minimumBackgroundDuration != -1) {\n            pendingInstall = new InstallOptions(InstallMode.fromValue(installMode), minimumBackgroundDuration);\n        }\n\n        return pendingInstall;\n    }\n\n    public void markInstallNeedsConfirmation() {\n        SharedPreferences preferences = context.getSharedPreferences(CodePushPreferences.INSTALL_NEEDS_CONFIRMATION, Context.MODE_PRIVATE);\n        SharedPreferences.Editor editor = preferences.edit();\n        editor.putBoolean(CodePushPreferences.INSTALL_NEEDS_CONFIRMATION_KEY, true);\n        editor.commit();\n    }\n\n    public void clearInstallNeedsConfirmation() {\n        this.clearPreferences(CodePushPreferences.INSTALL_NEEDS_CONFIRMATION);\n    }\n\n    public boolean installNeedsConfirmation() {\n        SharedPreferences preferences = context.getSharedPreferences(CodePushPreferences.INSTALL_NEEDS_CONFIRMATION, Context.MODE_PRIVATE);\n        boolean notConfirmedInstall = preferences.getBoolean(CodePushPreferences.INSTALL_NEEDS_CONFIRMATION_KEY, false);\n        return notConfirmedInstall;\n    }\n\n    public void saveFirstRunFlag() {\n        SharedPreferences preferences = context.getSharedPreferences(CodePushPreferences.FIRST_RUN_PREFERENCE, Context.MODE_PRIVATE);\n        SharedPreferences.Editor editor = preferences.edit();\n        editor.putBoolean(CodePushPreferences.FIRST_RUN_PREFERENCE_KEY, false);\n        editor.commit();\n    }\n\n    public boolean isFirstRun() {\n        SharedPreferences preferences = context.getSharedPreferences(CodePushPreferences.FIRST_RUN_PREFERENCE, Context.MODE_PRIVATE);\n        boolean isFirstRun = preferences.getBoolean(CodePushPreferences.FIRST_RUN_PREFERENCE_KEY, true);\n        return isFirstRun;\n    }\n\n    public void clearPreferences(String preferencesId) {\n        SharedPreferences preferences = context.getSharedPreferences(preferencesId, Context.MODE_PRIVATE);\n        SharedPreferences.Editor editor = preferences.edit();\n        editor.clear();\n        editor.commit();\n    }\n\n    public void saveLastVersion(String labelOrAppVersion, String deploymentKey) {\n        SharedPreferences preferences = context.getSharedPreferences(CodePushPreferences.LAST_VERSION_PREFERENCE, Context.MODE_PRIVATE);\n        SharedPreferences.Editor editor = preferences.edit();\n        editor.putString(CodePushPreferences.LAST_VERSION_LABEL_OR_APP_VERSION_KEY, labelOrAppVersion);\n        editor.putString(CodePushPreferences.LAST_VERSION_DEPLOYMENT_KEY_KEY, deploymentKey);\n        editor.commit();\n    }\n\n    public String getLastVersionDeploymentKey() {\n        SharedPreferences preferences = context.getSharedPreferences(CodePushPreferences.LAST_VERSION_PREFERENCE, Context.MODE_PRIVATE);\n        return preferences.getString(CodePushPreferences.LAST_VERSION_DEPLOYMENT_KEY_KEY, null);\n    }\n\n    public String getLastVersionLabelOrAppVersion() {\n        SharedPreferences preferences = context.getSharedPreferences(CodePushPreferences.LAST_VERSION_PREFERENCE, Context.MODE_PRIVATE);\n        return preferences.getString(CodePushPreferences.LAST_VERSION_LABEL_OR_APP_VERSION_KEY, null);\n    }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-code-push/src/android/CodePushReportingManager.java",
    "content": "package com.microsoft.cordova;\n\nimport org.apache.cordova.CordovaWebView;\n\nimport java.util.ArrayList;\nimport java.util.Locale;\nimport android.app.Activity;\n\n/**\n * Handles the native -> JS reporting mechanism.\n */\npublic class CodePushReportingManager {\n\n    private Activity cordovaActivity;\n    private CodePushPreferences codePushPreferences;\n\n    /**\n     * Defines application statuses we use in reporting events from the native to the JS layer.\n     */\n    public static enum Status {\n        STORE_VERSION(0),\n        UPDATE_CONFIRMED(1),\n        UPDATE_ROLLED_BACK(2);\n\n        private int value;\n\n        Status(int i) {\n            this.value = i;\n        }\n\n        /**\n         * Returns the value associated with this enum.\n         */\n        public int getValue() {\n            return this.value;\n        }\n    }\n\n    public CodePushReportingManager(Activity cordovaActivity, CodePushPreferences codePushPreferences) {\n        this.cordovaActivity = cordovaActivity;\n        this.codePushPreferences = codePushPreferences;\n    }\n\n    /**\n     * Invokes the window.codePush.reportStatus JS function for the given webView.\n     */\n    public void reportStatus(Status status, String label, String appVersion, String deploymentKey, final CordovaWebView webView) {\n        /* JS function to call: window.codePush.reportStatus(status: number, label: String, appVersion: String, currentDeploymentKey: String, previousLabelOrAppVersion?: string, previousDeploymentKey?: string) */\n        if (deploymentKey == null || deploymentKey.isEmpty()) {\n            return;\n        }\n\n        final String script = String.format(\n            Locale.US,\n            \"javascript:document.addEventListener(\\\"deviceready\\\", function () { window.codePush.reportStatus(%d, %s, %s, %s, %s, %s); });\",\n            status.getValue(),\n            convertStringParameter(label),\n            convertStringParameter(appVersion),\n            convertStringParameter(deploymentKey),\n            convertStringParameter(codePushPreferences.getLastVersionLabelOrAppVersion()),\n            convertStringParameter(codePushPreferences.getLastVersionDeploymentKey())\n            );\n\n        if (status == Status.STORE_VERSION || status == Status.UPDATE_CONFIRMED) {\n            codePushPreferences.saveLastVersion(label == null ? appVersion : label, deploymentKey);\n        }\n\n        cordovaActivity.runOnUiThread(new Runnable() {\n            public void run() {\n                webView.loadUrl(script);\n            }\n        });\n    }\n\n    private String convertStringParameter(String input) {\n        if (null == input) {\n            return \"undefined\";\n        } else {\n            return \"'\" + input + \"'\";\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-code-push/src/android/InstallMode.java",
    "content": "package com.microsoft.cordova;\n\n/**\n * Defines the available InstallModes.\n */\npublic enum InstallMode {\n    IMMEDIATE(0),\n    ON_NEXT_RESTART(1),\n    ON_NEXT_RESUME(2);\n\n    private int value;\n\n    InstallMode(int i) {\n        this.value = i;\n    }\n\n    /**\n     * Returns the InstallMode associated with a given value.\n     * If no InstallMode is associated with the provided value, null is returned.\n     */\n    public static InstallMode fromValue(int i) {\n        for (InstallMode mode : InstallMode.values()) {\n            if (i == mode.value) {\n                return mode;\n            }\n        }\n\n        return null;\n    }\n\n    /**\n     * Returns the value associated with this enum.\n     */\n    public int getValue() {\n        return this.value;\n    }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-code-push/src/android/InstallOptions.java",
    "content": "package com.microsoft.cordova;\n\n/**\n * Defines the update installation options.\n */\npublic class InstallOptions {\n    public InstallMode installMode;\n    public int minimumBackgroundDuration;\n\n    public InstallOptions(InstallMode installMode, int minimumBackgroundDuration) {\n        this.installMode = installMode;\n        this.minimumBackgroundDuration = minimumBackgroundDuration;\n    }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-code-push/src/android/UpdateHashUtils.java",
    "content": "package com.microsoft.cordova;\n\nimport android.app.Activity;\nimport android.content.res.AssetManager;\n\nimport org.json.JSONArray;\n\nimport java.io.ByteArrayInputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.security.DigestInputStream;\nimport java.security.MessageDigest;\nimport java.security.NoSuchAlgorithmException;\nimport java.util.ArrayList;\nimport java.util.Collections;\n\n/**\n * Utilities class used for native operations related to calculating hashes of update contents.\n */\npublic class UpdateHashUtils {\n\n    public static String getBinaryHash(Activity activity) throws IOException, NoSuchAlgorithmException {\n        ArrayList<String> manifestEntries = new ArrayList<String>();\n        addFolderEntriesToManifest(manifestEntries, \"www\", activity.getAssets());\n        Collections.sort(manifestEntries);\n        JSONArray manifestJSONArray = new JSONArray();\n        for (String manifestEntry : manifestEntries) {\n            manifestJSONArray.put(manifestEntry);\n        }\n\n        // The JSON serialization turns path separators into \"\\/\", e.g. \"www\\/images\\/image.png\"\n        String manifestString = manifestJSONArray.toString().replace(\"\\\\/\", \"/\");\n        return computeHash(new ByteArrayInputStream(manifestString.getBytes()));\n    }\n\n    private static void addFolderEntriesToManifest(ArrayList<String> manifestEntries, String path, AssetManager assetManager) throws IOException, NoSuchAlgorithmException {\n        String[] fileList = assetManager.list(path);\n        if (fileList.length > 0) {\n            // This is a folder, recursively add folder entries to the manifest.\n            for (String pathInFolder : fileList) {\n                addFolderEntriesToManifest(manifestEntries, path + \"/\" + pathInFolder, assetManager);\n            }\n        } else {\n            // This is a file, compute a hash and create a manifest entry for it.\n            manifestEntries.add(path + \":\" + computeHash(assetManager.open(path)));\n        }\n    }\n\n    private static String computeHash(InputStream dataStream) throws IOException, NoSuchAlgorithmException {\n        MessageDigest messageDigest = null;\n        DigestInputStream digestInputStream = null;\n        try {\n            messageDigest = MessageDigest.getInstance(\"SHA-256\");\n            digestInputStream = new DigestInputStream(dataStream, messageDigest);\n            byte[] byteBuffer = new byte[1024 * 8];\n            while (digestInputStream.read(byteBuffer) != -1);\n        } finally {\n            try {\n                if (digestInputStream != null) digestInputStream.close();\n                if (dataStream != null) dataStream.close();\n            } catch (IOException e) {\n                e.printStackTrace();\n            }\n        }\n\n        byte[] hash = messageDigest.digest();\n        return String.format(\"%064x\", new java.math.BigInteger(1, hash));\n    }\n\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-code-push/src/android/Utilities.java",
    "content": "package com.microsoft.cordova;\n\nimport android.content.Context;\nimport android.content.pm.ApplicationInfo;\nimport android.content.pm.PackageInfo;\nimport android.content.pm.PackageManager;\nimport android.util.Log;\n\nimport java.io.BufferedReader;\nimport java.io.File;\nimport java.io.FileReader;\nimport java.io.IOException;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipFile;\n\n/**\n * Utilities class used for file and other common native operations.\n */\npublic class Utilities {\n    public static String readFileContents(File file) throws IOException {\n        StringBuilder sb = new StringBuilder();\n        BufferedReader br = null;\n        try {\n            br = new BufferedReader(new FileReader(file));\n            String currentLine;\n\n            while ((currentLine = br.readLine()) != null) {\n                sb.append(currentLine);\n                sb.append('\\n');\n            }\n        } finally {\n            if (br != null) {\n                br.close();\n            }\n        }\n\n        return sb.toString();\n    }\n\n    public static void deleteEntryRecursively(File entry) {\n        if (entry.isDirectory()) {\n            /* delete contents first */\n            for (File child : entry.listFiles()) {\n                Utilities.deleteEntryRecursively(child);\n            }\n        }\n\n        entry.delete();\n    }\n\n    public static String getAppVersionName(Context context) throws PackageManager.NameNotFoundException {\n        String currentPackageName = context.getPackageName();\n        PackageInfo packageInfo = context.getPackageManager().getPackageInfo(currentPackageName, 0);\n        return packageInfo.versionName;\n    }\n\n    public static long getApkEntryBuildTime(String entryName, Context context) {\n        ZipFile applicationFile;\n        long result = -1;\n\n        try {\n            ApplicationInfo ai = context.getPackageManager().getApplicationInfo(context.getPackageName(), 0);\n            applicationFile = new ZipFile(ai.sourceDir);\n            ZipEntry classesDexEntry = applicationFile.getEntry(entryName);\n            result = classesDexEntry.getTime();\n            applicationFile.close();\n        } catch (Exception e) {\n            /* empty, will return -1 */\n        }\n\n        return result;\n    }\n\n    public static void logException(Throwable e) {\n        Log.e(CodePush.class.getName(), \"An error occured. \" + e.getMessage(), e);\n    }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-code-push/src/android/build-extras.gradle",
    "content": "// Needed to speed up asset listing: refer to https://github.com/apache/cordova-plugin-file/blob/76c8fd5e43598ea660c2db64eb08e2659b45a575/src/android/AssetFilesystem.java#L41\n// Taken from https://raw.githubusercontent.com/apache/cordova-plugin-file/ed4cb4b999373eaa80b2fe1f38e3fc24db1b00ae/src/android/build-extras.gradle\n\n/*\n       Licensed to the Apache Software Foundation (ASF) under one\n       or more contributor license agreements.  See the NOTICE file\n       distributed with this work for additional information\n       regarding copyright ownership.  The ASF licenses this file\n       to you under the Apache License, Version 2.0 (the\n       \"License\"); you may not use this file except in compliance\n       with the License.  You may obtain a copy of the License at\n\n         http://www.apache.org/licenses/LICENSE-2.0\n\n       Unless required by applicable law or agreed to in writing,\n       software distributed under the License is distributed on an\n       \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n       KIND, either express or implied.  See the License for the\n       specific language governing permissions and limitations\n       under the License.\n */\next.postBuildExtras = {\n    def inAssetsDir = file(\"assets\")\n    def outAssetsDir = inAssetsDir\n    def outFile = new File(outAssetsDir, \"cdvasset.manifest\")\n\n    def newTask = task(\"cdvCreateAssetManifest\") << {\n        def contents = new HashMap()\n        def sizes = new HashMap()\n        contents[\"\"] = inAssetsDir.list()\n        def tree = fileTree(dir: inAssetsDir)\n        tree.visit { fileDetails ->\n            if (fileDetails.isDirectory()) {\n                contents[fileDetails.relativePath.toString()] = fileDetails.file.list()\n            } else {\n                sizes[fileDetails.relativePath.toString()] = fileDetails.file.length()\n            }\n        }\n\n        outAssetsDir.mkdirs()\n        outFile.withObjectOutputStream { oos ->\n            oos.writeObject(contents)\n            oos.writeObject(sizes)\n        }\n    }\n    newTask.inputs.dir inAssetsDir\n    newTask.outputs.file outFile\n    def preBuildTask = tasks[\"preBuild\"]\n    preBuildTask.dependsOn(newTask)\n}"
  },
  {
    "path": "plugins/cordova-plugin-code-push/src/ios/CodePush.h",
    "content": "#import <Cordova/CDV.h>\n\n@interface CodePush : CDVPlugin\n\n- (void)getServerURL:(CDVInvokedUrlCommand*)command;\n- (void)getDeploymentKey:(CDVInvokedUrlCommand*)command;\n- (void)getNativeBuildTime:(CDVInvokedUrlCommand*)command;\n- (void)getAppVersion:(CDVInvokedUrlCommand*)command;\n- (void)install:(CDVInvokedUrlCommand *)command;\n- (void)preInstall:(CDVInvokedUrlCommand *)command;\n- (void)isFailedUpdate:(CDVInvokedUrlCommand *)command;\n- (void)isFirstRun:(CDVInvokedUrlCommand *)command;\n- (void)isPendingUpdate:(CDVInvokedUrlCommand *)command;\n- (void)updateSuccess:(CDVInvokedUrlCommand *)command;\n- (void)restartApplication:(CDVInvokedUrlCommand *)command;\n- (void)pluginInitialize;\n\n@end\n\n"
  },
  {
    "path": "plugins/cordova-plugin-code-push/src/ios/CodePush.m",
    "content": "#import <Cordova/CDV.h>\n#import <Cordova/CDVConfigParser.h>\n#import \"CodePush.h\"\n#import \"CodePushPackageMetadata.h\"\n#import \"CodePushPackageManager.h\"\n#import \"Utilities.h\"\n#import \"InstallOptions.h\"\n#import \"InstallMode.h\"\n#import \"CodePushReportingManager.h\"\n#import \"UpdateHashUtils.h\"\n\n@implementation CodePush\n\nbool didUpdate = false;\nbool pendingInstall = false;\nNSDate* lastResignedDate;\nconst NSString* DeploymentKeyPreference = @\"codepushdeploymentkey\";\n\n- (void)getBinaryHash:(CDVInvokedUrlCommand *)command {\n    CDVPluginResult* pluginResult = nil;\n    NSString* binaryHash = [CodePushPackageManager getCachedBinaryHash];\n    if (binaryHash) {\n        pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK\n                                         messageAsString:binaryHash];\n    } else {\n        NSError* error;\n        binaryHash = [UpdateHashUtils getBinaryHash:&error];\n        if (error) {\n            pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR\n                                             messageAsString:[@\"An error occurred when trying to get the hash of the binary contents. \" stringByAppendingString:error.description]];\n        } else {\n            [CodePushPackageManager saveBinaryHash:binaryHash];\n            pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK\n                                             messageAsString:binaryHash];\n        }\n    }\n\n    [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];\n}\n\n- (void)handleUnconfirmedInstall:(BOOL)navigate {\n    if ([CodePushPackageManager installNeedsConfirmation]) {\n        /* save reporting status */\n        CodePushPackageMetadata* currentMetadata = [CodePushPackageManager getCurrentPackageMetadata];\n        [CodePushReportingManager reportStatus:UPDATE_ROLLED_BACK withLabel:currentMetadata.label version:currentMetadata.appVersion deploymentKey:currentMetadata.deploymentKey webView:self.webView];\n\n        [CodePushPackageManager clearInstallNeedsConfirmation];\n        [CodePushPackageManager revertToPreviousVersion];\n        if (navigate) {\n            CodePushPackageMetadata* currentMetadata = [CodePushPackageManager getCurrentPackageMetadata];\n            bool revertSuccess = (nil != currentMetadata && [self loadPackage:currentMetadata.localPath]);\n            if (!revertSuccess) {\n                /* first update failed, go back to store version */\n                [self loadStoreVersion];\n            }\n        }\n    }\n}\n\n- (void)updateSuccess:(CDVInvokedUrlCommand *)command {\n    if ([CodePushPackageManager isFirstRun]) {\n        [CodePushPackageManager markFirstRunFlag];\n        NSString *appVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:@\"CFBundleShortVersionString\"];\n        NSString *deploymentKey = ((CDVViewController *)self.viewController).settings[DeploymentKeyPreference];\n        [CodePushReportingManager reportStatus:STORE_VERSION withLabel:nil version:appVersion deploymentKey:deploymentKey webView:self.webView];\n    }\n\n    if ([CodePushPackageManager installNeedsConfirmation]) {\n        /* save reporting status */\n        CodePushPackageMetadata* currentMetadata = [CodePushPackageManager getCurrentPackageMetadata];\n        [CodePushReportingManager reportStatus:UPDATE_CONFIRMED withLabel:currentMetadata.label version:currentMetadata.appVersion deploymentKey:currentMetadata.deploymentKey webView:self.webView];\n    }\n\n    [CodePushPackageManager clearInstallNeedsConfirmation];\n    [CodePushPackageManager cleanOldPackage];\n    CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];\n    [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];\n}\n\n- (void)install:(CDVInvokedUrlCommand *)command {\n    CDVPluginResult* pluginResult = nil;\n\n    NSString* location = [command argumentAtIndex:0 withDefault:nil andClass:[NSString class]];\n    NSString* installModeString = [command argumentAtIndex:1 withDefault:IMMEDIATE andClass:[NSString class]];\n    NSString* minimumBackgroundDurationString = [command argumentAtIndex:2 withDefault:0 andClass:[NSString class]];\n\n    InstallOptions* options = [[InstallOptions alloc] init];\n    [options setInstallMode:[installModeString intValue]];\n    [options setMinimumBackgroundDuration:[minimumBackgroundDurationString intValue]];\n\n    if ([options installMode] == IMMEDIATE) {\n        if (nil == location) {\n            pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@\"Cannot read the start URL.\"];\n        }\n        else {\n            bool applied = [self loadPackage: location];\n            if (applied) {\n                [self markUpdate];\n                pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];\n            }\n            else {\n                pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@\"An error happened during package install.\"];\n            }\n        }\n    }\n    else {\n        /* install on restart or on resume */\n        [CodePushPackageManager savePendingInstall:options];\n        pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];\n    }\n\n    [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];\n}\n\n- (void)restartApplication:(CDVInvokedUrlCommand *)command {\n    /* Callback before navigating */\n    CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];\n    [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];\n\n    CodePushPackageMetadata* deployedPackageMetadata = [CodePushPackageManager getCurrentPackageMetadata];\n    if (deployedPackageMetadata && deployedPackageMetadata.localPath && [self getStartPageURLForLocalPackage:deployedPackageMetadata.localPath]) {\n        [self loadPackage: deployedPackageMetadata.localPath];\n        InstallOptions* pendingInstall = [CodePushPackageManager getPendingInstall];\n        if (pendingInstall) {\n            [self markUpdate];\n            [CodePushPackageManager clearPendingInstall];\n        }\n    }\n    else {\n        [self loadStoreVersion];\n    }\n}\n\n- (void) markUpdate {\n    didUpdate = YES;\n    [CodePushPackageManager markInstallNeedsConfirmation];\n}\n\n- (void)preInstall:(CDVInvokedUrlCommand *)command {\n    CDVPluginResult* pluginResult = nil;\n\n    NSString* location = [command argumentAtIndex:0 withDefault:nil andClass:[NSString class]];\n    if (nil == location) {\n        pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@\"Cannot read the start URL.\"];\n    }\n    else {\n        NSURL* URL = [self getStartPageURLForLocalPackage:location];\n        if (URL) {\n            pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];\n        }\n        else {\n            pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@\"Could not find start page in package.\"];\n        }\n    }\n\n    [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];\n}\n\n- (void)getServerURL:(CDVInvokedUrlCommand *)command {\n    [self sendResultForPreference:@\"codepushserverurl\" command:command];\n}\n\n- (void)getDeploymentKey:(CDVInvokedUrlCommand *)command {\n    [self sendResultForPreference:DeploymentKeyPreference command:command];\n}\n\n\n- (void)getNativeBuildTime:(CDVInvokedUrlCommand *)command {\n    NSString* timeStamp = [Utilities getApplicationTimestamp];\n    CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:timeStamp];\n    [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];\n}\n\n- (void)sendResultForPreference:(NSString*)preferenceName command:(CDVInvokedUrlCommand*)command {\n    NSString* preferenceValue = ((CDVViewController *)self.viewController).settings[preferenceName];\n    // length of NIL is zero\n    CDVPluginResult* pluginResult;\n    if ([preferenceValue length] > 0) {\n        pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:preferenceValue];\n    } else {\n        pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:[NSString stringWithFormat:@\"Could not find preference %@\", preferenceName]];\n    }\n\n    [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];\n}\n\n- (void)dealloc {\n    [[NSNotificationCenter defaultCenter] removeObserver:self];\n}\n\n- (void)handleAppStart {\n    // check if we have a deployed package\n    CodePushPackageMetadata* deployedPackageMetadata = [CodePushPackageManager getCurrentPackageMetadata];\n    if (deployedPackageMetadata) {\n        NSString* deployedPackageNativeBuildTime = deployedPackageMetadata.nativeBuildTime;\n        NSString* applicationBuildTime = [Utilities getApplicationTimestamp];\n\n        if (deployedPackageNativeBuildTime != nil && applicationBuildTime != nil) {\n            if ([deployedPackageNativeBuildTime isEqualToString: applicationBuildTime] ) {\n                // same version, safe to launch from local storage\n                if (deployedPackageMetadata.localPath) {\n                    [self redirectStartPageToURL: deployedPackageMetadata.localPath];\n                }\n            }\n            else {\n                // installed native version is different from package version => clean up deployed package and do not modify start page\n                [CodePushPackageManager cleanDeployments];\n                [CodePushPackageManager clearFailedUpdates];\n                [CodePushPackageManager clearPendingInstall];\n                [CodePushPackageManager clearInstallNeedsConfirmation];\n                NSString *appVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:@\"CFBundleShortVersionString\"];\n                NSString *deploymentKey = ((CDVViewController *)self.viewController).settings[DeploymentKeyPreference];\n                [CodePushReportingManager reportStatus:STORE_VERSION withLabel:nil version:appVersion deploymentKey:deploymentKey webView:self.webView];\n            }\n        }\n    }\n}\n\n- (void)pluginInitialize {\n    // register for \"on resume\", \"on pause\" notifications\n    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillEnterForeground) name:UIApplicationWillEnterForegroundNotification object:nil];\n    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillResignActive) name:UIApplicationWillResignActiveNotification object:nil];\n    InstallOptions* pendingInstall = [CodePushPackageManager getPendingInstall];\n    if (!pendingInstall) {\n        [self handleUnconfirmedInstall:NO];\n    }\n    [self handleAppStart];\n\n    // handle both ON_NEXT_RESUME and ON_NEXT_RESTART - the application might have been killed after transitioning to the background\n    if (pendingInstall && (pendingInstall.installMode == ON_NEXT_RESTART || pendingInstall.installMode == ON_NEXT_RESUME)) {\n        [self markUpdate];\n        [CodePushPackageManager clearPendingInstall];\n    }\n}\n\n- (void)applicationWillEnterForeground {\n    InstallOptions* pendingInstall = [CodePushPackageManager getPendingInstall];\n    // calculate the duration that the app was in the background\n    long durationInBackground = lastResignedDate ? [[NSDate date] timeIntervalSinceDate:lastResignedDate] : 0;\n    if (pendingInstall && pendingInstall.installMode == ON_NEXT_RESUME && durationInBackground >= pendingInstall.minimumBackgroundDuration) {\n        CodePushPackageMetadata* deployedPackageMetadata = [CodePushPackageManager getCurrentPackageMetadata];\n        if (deployedPackageMetadata && deployedPackageMetadata.localPath) {\n            bool applied = [self loadPackage: deployedPackageMetadata.localPath];\n            if (applied) {\n                [self markUpdate];\n                [CodePushPackageManager clearPendingInstall];\n            }\n        }\n    }\n}\n\n- (void)applicationWillResignActive {\n    // Save the current time so that when the app is later resumed, we can detect how long it was in the background\n    lastResignedDate = [NSDate date];\n}\n\n- (BOOL)loadPackage:(NSString*)packageLocation {\n    NSURL* URL = [self getStartPageURLForLocalPackage:packageLocation];\n    if (URL) {\n        [self loadURL:URL];\n        return YES;\n    }\n\n    return NO;\n}\n\n- (void)loadURL:(NSURL*)url {\n    // Cast to a UIWebView here to enable call to loadRequest.\n    // Both UIWebView and WKWebview share this call, so regardless of which type the returned webview is, this will work.\n    [(UIWebView*)self.webView loadRequest:[NSURLRequest requestWithURL:url]];\n}\n\n- (void)loadStoreVersion {\n    NSString* mainBundlePath = [[NSBundle mainBundle] bundlePath];\n    NSString* configStartPage = [self getConfigLaunchUrl];\n    NSArray* realLocationArray = @[mainBundlePath, @\"www\", configStartPage];\n    NSString* mainPageLocation = [NSString pathWithComponents:realLocationArray];\n    if ([[NSFileManager defaultManager] fileExistsAtPath:mainPageLocation]) {\n        NSURL* mainPagePath = [NSURL fileURLWithPath:mainPageLocation];\n        [self loadURL:mainPagePath];\n    }\n}\n\n- (NSString*)getConfigLaunchUrl\n{\n    CDVConfigParser* delegate = [[CDVConfigParser alloc] init];\n    NSString* configPath = [[NSBundle mainBundle] pathForResource:@\"config\" ofType:@\"xml\"];\n    NSURL* configUrl = [NSURL fileURLWithPath:configPath];\n\n    NSXMLParser* configParser = [[NSXMLParser alloc] initWithContentsOfURL:configUrl];\n    [configParser setDelegate:((id < NSXMLParserDelegate >)delegate)];\n    [configParser parse];\n\n    return delegate.startPage;\n}\n\n- (NSURL *)getStartPageURLForLocalPackage:(NSString*)packageLocation {\n    if (packageLocation) {\n        NSString* startPage = [self getConfigLaunchUrl];\n        NSString* libraryLocation = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0];\n        NSArray* realLocationArray = @[libraryLocation, @\"NoCloud\", packageLocation, @\"www\", startPage];\n        NSString* realStartPageLocation = [NSString pathWithComponents:realLocationArray];\n        if ([[NSFileManager defaultManager] fileExistsAtPath:realStartPageLocation]) {\n            return [NSURL fileURLWithPath:realStartPageLocation];\n        }\n    }\n\n    return nil;\n}\n\n- (void)redirectStartPageToURL:(NSString*)packageLocation{\n    NSURL* URL = [self getStartPageURLForLocalPackage:packageLocation];\n    if (URL) {\n        ((CDVViewController *)self.viewController).startPage = [URL absoluteString];\n    }\n}\n\n- (void)isFailedUpdate:(CDVInvokedUrlCommand *)command {\n    CDVPluginResult* result;\n    NSString* packageHash = [command argumentAtIndex:0 withDefault:nil andClass:[NSString class]];\n    if (nil == packageHash) {\n        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@\"Invalid package hash parameter.\"];\n    }\n    else {\n        BOOL failedHash = [CodePushPackageManager isFailedHash:packageHash];\n        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:failedHash ? 1 : 0];\n    }\n\n    [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n}\n\n- (void)isFirstRun:(CDVInvokedUrlCommand *)command {\n    CDVPluginResult* result;\n    BOOL isFirstRun = NO;\n\n    NSString* packageHash = [command argumentAtIndex:0 withDefault:nil andClass:[NSString class]];\n    CodePushPackageMetadata* currentPackageMetadata = [CodePushPackageManager getCurrentPackageMetadata];\n    if (currentPackageMetadata) {\n        isFirstRun = (nil != packageHash\n                      && [packageHash length] > 0\n                      && [packageHash isEqualToString:currentPackageMetadata.packageHash]\n                      && didUpdate);\n    }\n\n    result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:isFirstRun ? 1 : 0];\n    [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n}\n\n- (void)isPendingUpdate:(CDVInvokedUrlCommand *)command {\n    CDVPluginResult* result;\n\n    InstallOptions* pendingInstall = [CodePushPackageManager getPendingInstall];\n    result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:pendingInstall ? 1 : 0];\n    [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n}\n\n- (void)getAppVersion:(CDVInvokedUrlCommand *)command {\n    NSString* version = [[NSBundle mainBundle] objectForInfoDictionaryKey:@\"CFBundleShortVersionString\"];\n    CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:version];\n    [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];\n}\n\n@end\n\n"
  },
  {
    "path": "plugins/cordova-plugin-code-push/src/ios/CodePushPackageManager.h",
    "content": "#import \"CodePushPackageMetadata.h\"\n#import \"InstallOptions.h\"\n\n@interface CodePushPackageManager : NSObject\n\n+ (void)cleanOldPackage;\n+ (void)revertToPreviousVersion;\n+ (CodePushPackageMetadata*)getCurrentPackageMetadata;\n+ (void)clearFailedUpdates;\n+ (void)cleanDeployments;\n+ (NSString*)getCachedBinaryHash;\n+ (void)saveBinaryHash:(NSString*)binaryHash;\n+ (BOOL)isFailedHash:(NSString*)packageHash;\n+ (void)savePendingInstall:(InstallOptions *)installOptions;\n+ (InstallOptions*)getPendingInstall;\n+ (void)clearPendingInstall;\n+ (void)markInstallNeedsConfirmation;\n+ (BOOL)installNeedsConfirmation;\n+ (void)clearInstallNeedsConfirmation;\n+ (void)markFirstRunFlag;\n+ (BOOL)isFirstRun;\n\n@end\n"
  },
  {
    "path": "plugins/cordova-plugin-code-push/src/ios/CodePushPackageManager.m",
    "content": "#import \"CodePushPackageManager.h\"\n#import \"CodePushPackageMetadata.h\"\n#import \"InstallOptions.h\"\n\n@implementation CodePushPackageManager\n\nNSString* const BinaryHashKey = @\"BINARY_HASH\";\nNSString* const FailedUpdatesKey = @\"FAILED_UPDATES\";\nNSString* const PendingInstallKey = @\"PENDING_INSTALL\";\nNSString* const NotConfirmedInstallKey = @\"NOT_CONFIRMED_INSTALL\";\nNSString* const IsFirstRunKey = @\"FIRST_RUN\";\nNSString* const OldPackageManifestName = @\"oldPackage.json\";\nNSString* const CurrentPackageManifestName = @\"currentPackage.json\";\n\n+(void)cleanOldPackage {\n    CodePushPackageMetadata* oldMetadata = [self getOldPackageMetadata];\n    \n    // delete the package folder\n    [self cleanPackageDirectory:oldMetadata];\n    \n    // delete the downloads folder\n    [self cleanDownloads];\n}\n\n+(void)cleanDownloads {\n    NSString* libraryLocation = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0];\n    NSArray* downloadFolderArray = @[libraryLocation, @\"NoCloud\", @\"codepush\", @\"download\"];\n    NSString* downloadFolderLocation = [NSString pathWithComponents:downloadFolderArray];\n    if ([[NSFileManager defaultManager] fileExistsAtPath: downloadFolderLocation]) {\n        [[NSFileManager defaultManager] removeItemAtPath:downloadFolderLocation error:nil];\n    }\n}\n\n+(void)cleanPackageDirectory:(CodePushPackageMetadata*)packageMetadata {\n    NSString* libraryLocation = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0];\n    \n    if (nil != packageMetadata && nil != packageMetadata.localPath) {\n        // delete the package folder\n        NSArray* oldPackageDir = @[libraryLocation, @\"NoCloud\", packageMetadata.localPath];\n        NSString* oldPackageDirPath = [NSString pathWithComponents:oldPackageDir];\n        if ([[NSFileManager defaultManager] fileExistsAtPath: oldPackageDirPath]) {\n            [[NSFileManager defaultManager] removeItemAtPath:oldPackageDirPath error:nil];\n        }\n    }\n}\n\n+(void)cleanDeployments {\n    // check if the file exists\n    NSString* libraryLocation = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0];\n    NSArray* codePushDirectoryArray = @[libraryLocation, @\"NoCloud\", @\"codepush\" ];\n    NSString* codePushDirPath = [NSString pathWithComponents:codePushDirectoryArray];\n    if ([[NSFileManager defaultManager] fileExistsAtPath:codePushDirPath]) {\n        [[NSFileManager defaultManager] removeItemAtPath:codePushDirPath error:nil];\n    }\n}\n\n+ (NSString*)getCachedBinaryHash {\n    NSUserDefaults* preferences = [NSUserDefaults standardUserDefaults];\n    NSString* cachedBinaryHash = [preferences objectForKey:BinaryHashKey];\n    return cachedBinaryHash;\n}\n\n+ (void)saveBinaryHash:(NSString*)binaryHash {\n    NSUserDefaults* preferences = [NSUserDefaults standardUserDefaults];\n    [preferences setObject:binaryHash forKey:BinaryHashKey];\n    [preferences synchronize];\n}\n\n+ (CodePushPackageMetadata*)getOldPackageMetadata {\n    return [self readPackageManifest:OldPackageManifestName];\n}\n\n+ (CodePushPackageMetadata*)getCurrentPackageMetadata {\n    return [self readPackageManifest:CurrentPackageManifestName];\n}\n\n+ (BOOL)isFailedHash:(NSString*)packageHash {\n    NSUserDefaults* preferences = [NSUserDefaults standardUserDefaults];\n    NSMutableArray* failedUpdates = [preferences objectForKey:FailedUpdatesKey];\n    return (nil != failedUpdates && [failedUpdates containsObject:packageHash]);\n}\n\n+ (void)saveFailedUpdate:(NSString *)packageHash {\n    NSUserDefaults* preferences = [NSUserDefaults standardUserDefaults];\n    NSMutableArray* failedUpdates = [[preferences objectForKey:FailedUpdatesKey] mutableCopy];\n    if (nil == failedUpdates) {\n        failedUpdates = [[NSMutableArray alloc] init];\n    }\n    \n    [failedUpdates addObject:packageHash];\n    [preferences setObject:failedUpdates forKey:FailedUpdatesKey];\n    [preferences synchronize];\n}\n\n+ (void)clearFailedUpdates {\n    NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults];\n    [preferences removeObjectForKey:FailedUpdatesKey];\n}\n\n+ (void)savePendingInstall:(InstallOptions *)installOptions {\n    NSUserDefaults* preferences = [NSUserDefaults standardUserDefaults];\n    NSData* serializedPendingInstall = [NSKeyedArchiver archivedDataWithRootObject:installOptions];\n    [preferences setObject:serializedPendingInstall forKey:PendingInstallKey];\n    [preferences synchronize];\n}\n\n+ (InstallOptions*)getPendingInstall{\n    NSUserDefaults* preferences = [NSUserDefaults standardUserDefaults];\n    NSData* serializedPendingInstall = [[preferences objectForKey:PendingInstallKey] mutableCopy];\n    if (serializedPendingInstall) {\n        InstallOptions* pendingInstall = [NSKeyedUnarchiver unarchiveObjectWithData:serializedPendingInstall];\n        return pendingInstall;\n    }\n    \n    return nil;\n}\n\n+ (void)clearPendingInstall {\n    NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults];\n    [preferences removeObjectForKey:PendingInstallKey];\n}\n\n+ (void)markFirstRunFlag {\n    NSUserDefaults* preferences = [NSUserDefaults standardUserDefaults];\n    [preferences setBool:YES forKey:IsFirstRunKey];\n    [preferences synchronize];\n}\n\n+ (BOOL)isFirstRun {\n    NSUserDefaults* preferences = [NSUserDefaults standardUserDefaults];\n    BOOL firstRunFlagSet = [preferences boolForKey:IsFirstRunKey];\n    return !firstRunFlagSet;\n}\n\n+ (void)markInstallNeedsConfirmation {\n    NSUserDefaults* preferences = [NSUserDefaults standardUserDefaults];\n    [preferences setBool:YES forKey:NotConfirmedInstallKey];\n    [preferences synchronize];\n}\n\n+ (BOOL)installNeedsConfirmation {\n    NSUserDefaults* preferences = [NSUserDefaults standardUserDefaults];\n    BOOL notConfirmedInstall = [preferences boolForKey:NotConfirmedInstallKey];\n    return notConfirmedInstall;\n}\n\n+ (void)clearInstallNeedsConfirmation {\n    NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults];\n    [preferences removeObjectForKey:NotConfirmedInstallKey];\n}\n\n+ (CodePushPackageMetadata*)readPackageManifest:(NSString*)manifestName {\n    // check if the file exists\n    NSString* libraryLocation = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0];\n    NSArray* manifestLocationArray = @[libraryLocation, @\"NoCloud\", @\"codepush\", manifestName];\n    NSString* manifestLocation = [NSString pathWithComponents:manifestLocationArray];\n    if ([[NSFileManager defaultManager] fileExistsAtPath:manifestLocation]) {\n        // read the package manifest\n        NSString* content = [NSString stringWithContentsOfFile:manifestLocation encoding:NSUTF8StringEncoding  error:NULL];\n        if (content != nil) {\n            // parse the content\n            return [CodePushPackageMetadata parsePackageManifest:content];\n        }\n    }\n    \n    return nil;\n    \n}\n\n+ (void)revertToPreviousVersion {\n    /* clean the current package */\n    CodePushPackageMetadata* failedMetadata = [self getCurrentPackageMetadata];\n    if (nil != failedMetadata.packageHash) {\n        [self saveFailedUpdate:failedMetadata.packageHash];\n    }\n    [self cleanPackageDirectory:failedMetadata];\n    \n    /* replace the current metadata file with the old one */\n    NSString* libraryLocation = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0];\n    NSArray* oldManifestArray = @[libraryLocation, @\"NoCloud\", @\"codepush\", OldPackageManifestName];\n    NSArray* currentManifestArray = @[libraryLocation, @\"NoCloud\", @\"codepush\", CurrentPackageManifestName];\n    \n    NSString* oldManifestLocation = [NSString pathWithComponents:oldManifestArray];\n    NSString* currentManifestLocation = [NSString pathWithComponents:currentManifestArray];\n    \n    if ([[NSFileManager defaultManager] fileExistsAtPath:currentManifestLocation]) {\n        [[NSFileManager defaultManager] removeItemAtPath:currentManifestLocation error:nil];\n    }\n    \n    /* move the old manifest to the curent location */\n    if ([[NSFileManager defaultManager] fileExistsAtPath:oldManifestLocation]) {\n        [[NSFileManager defaultManager] moveItemAtPath:oldManifestLocation toPath:currentManifestLocation error:nil];\n    }\n    \n    [self cleanDownloads];\n}\n\n@end"
  },
  {
    "path": "plugins/cordova-plugin-code-push/src/ios/CodePushPackageMetadata.h",
    "content": "@interface CodePushPackageMetadata : NSObject\n\n@property NSString* deploymentKey;\n@property NSString* packageDescription;\n@property NSString* label;\n@property NSString* appVersion;\n@property bool isMandatory;\n@property NSString* packageHash;\n@property NSNumber* packageSize;\n@property NSString* localPath;\n@property NSString* nativeBuildTime;\n\n+ (CodePushPackageMetadata*)parsePackageManifest:(NSString*)content;\n\n@end"
  },
  {
    "path": "plugins/cordova-plugin-code-push/src/ios/CodePushPackageMetadata.m",
    "content": "#import \"CodePushPackageMetadata.h\"\n\n@implementation CodePushPackageMetadata\n\n+ (CodePushPackageMetadata*)parsePackageManifest:(NSString*)content {\n    if (content) {\n        NSData* manifestData = [content dataUsingEncoding:NSUTF8StringEncoding];\n        NSMutableDictionary *manifest = [NSJSONSerialization JSONObjectWithData:manifestData options:NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves error:NULL];\n        \n        if (manifestData) {\n            CodePushPackageMetadata* packageMetadata = [[CodePushPackageMetadata alloc] init];\n            packageMetadata.deploymentKey = manifest[@\"deploymentKey\"];\n            packageMetadata.packageDescription = manifest[@\"description\"];\n            packageMetadata.label = manifest[@\"label\"];\n            packageMetadata.appVersion = manifest[@\"appVersion\"];\n            packageMetadata.isMandatory = manifest[@\"isMandatory\"];\n            packageMetadata.packageHash = manifest[@\"packageHash\"];\n            packageMetadata.packageSize = manifest[@\"packageSize\"];\n            packageMetadata.nativeBuildTime = manifest[@\"nativeBuildTime\"];\n            packageMetadata.localPath = manifest[@\"localPath\"];\n            return packageMetadata;\n        }\n    }\n    \n    return nil;\n}\n\n@end"
  },
  {
    "path": "plugins/cordova-plugin-code-push/src/ios/CodePushReportingManager.h",
    "content": "enum {\n    STORE_VERSION = 0,\n    UPDATE_CONFIRMED = 1,\n    UPDATE_ROLLED_BACK = 2\n};\ntypedef NSInteger ReportingStatus;\n\n@interface CodePushReportingManager : NSObject\n+ (void)reportStatus:(ReportingStatus)status withLabel:(NSString*)label version:(NSString*)version deploymentKey:(NSString*)deploymentKey webView:(UIView*)webView;\n@end\n\n"
  },
  {
    "path": "plugins/cordova-plugin-code-push/src/ios/CodePushReportingManager.m",
    "content": "#import \"CodePushReportingManager.h\"\n\n@implementation CodePushReportingManager\n\nconst NSString* LastVersionPreference = @\"CODE_PUSH_LAST_VERSION\";\nconst NSString* LastVersionDeploymentKeyKey = @\"LAST_VERSION_DEPLOYMENT_KEY_KEY\";\nconst NSString* LastVersionLabelOrAppVersionKey = @\"LAST_VERSION_LABEL_OR_APP_VERSION_KEY\";\n\n+ (void)reportStatus:(ReportingStatus)status withLabel:(NSString*)label version:(NSString*)version deploymentKey:(NSString*)deploymentKey webView:(UIView*)webView {\n    @synchronized(self) {\n        if (!deploymentKey) {\n            return;\n        }\n\n        NSString* labelParameter = [CodePushReportingManager convertStringParameter:label];\n        NSString* appVersionParameter = [CodePushReportingManager convertStringParameter:version];\n        NSString* deploymentKeyParameter = [CodePushReportingManager convertStringParameter:deploymentKey];\n        NSString* lastVersionLabelOrAppVersionParameter = nil;\n        NSString* lastVersionDeploymentKeyParameter = nil;\n\n        NSUserDefaults* preferences = [NSUserDefaults standardUserDefaults];\n        NSDictionary* lastVersion = [preferences objectForKey:LastVersionPreference];\n        if (lastVersion) {\n            lastVersionLabelOrAppVersionParameter = [CodePushReportingManager convertStringParameter:[lastVersion objectForKey:LastVersionLabelOrAppVersionKey]];\n            lastVersionDeploymentKeyParameter = [CodePushReportingManager convertStringParameter:[lastVersion objectForKey:LastVersionDeploymentKeyKey]];\n        }\n\n        /* JS function to call: window.codePush.reportStatus(status: number, label: String, appVersion: String, deploymentKey: String) */\n        NSString* script = [NSString stringWithFormat:@\"document.addEventListener(\\\"deviceready\\\", function () { window.codePush.reportStatus(%i, %@, %@, %@, %@, %@); });\", (int)status, labelParameter, appVersionParameter, deploymentKeyParameter, lastVersionLabelOrAppVersionParameter, lastVersionDeploymentKeyParameter];\n        if ([webView respondsToSelector:@selector(evaluateJavaScript:completionHandler:)]) {\n            [webView performSelector:@selector(evaluateJavaScript:completionHandler:) withObject:script withObject: NULL];\n        } else if ([webView isKindOfClass:[UIWebView class]]) {\n            [(UIWebView*)webView stringByEvaluatingJavaScriptFromString:script];\n        }\n\n        if (status == STORE_VERSION || status == UPDATE_CONFIRMED) {\n            NSDictionary* newLastVersion = @{LastVersionLabelOrAppVersionKey:(label ? label : version), LastVersionDeploymentKeyKey:deploymentKey};\n            [preferences setObject:newLastVersion forKey:LastVersionPreference];\n            [preferences synchronize];\n        }\n    }\n}\n\n+ (NSString*)convertStringParameter:(NSString*)input {\n    if (!input) {\n        return @\"undefined\";\n    } else {\n        return [NSString stringWithFormat:@\"'%@'\", input];\n    }\n}\n\n@end\n\n\n"
  },
  {
    "path": "plugins/cordova-plugin-code-push/src/ios/InstallMode.h",
    "content": "enum {\n    IMMEDIATE = 0,\n    ON_NEXT_RESTART = 1,\n    ON_NEXT_RESUME = 2\n};\ntypedef NSInteger InstallMode;\n\n"
  },
  {
    "path": "plugins/cordova-plugin-code-push/src/ios/InstallOptions.h",
    "content": "#include \"InstallMode.h\"\n\n@interface InstallOptions : NSObject\n\n@property InstallMode installMode;\n@property int minimumBackgroundDuration;\n\n-(void)encodeWithCoder:(NSCoder*)encoder;\n-(id)initWithCoder:(NSCoder*)decoder;\n\n@end"
  },
  {
    "path": "plugins/cordova-plugin-code-push/src/ios/InstallOptions.m",
    "content": "#include \"InstallOptions.h\"\n\n@implementation InstallOptions\n\nNSString* const InstallModeKey = @\"installMode\";\nNSString* const MinimumBackgroundDurationKey = @\"minimumBackgroundDuration\";\n\n-(void)encodeWithCoder:(NSCoder*)encoder {\n    [encoder encodeInteger:self.installMode forKey:InstallModeKey];\n    [encoder encodeInteger:self.minimumBackgroundDuration forKey:MinimumBackgroundDurationKey];\n}\n\n-(id)initWithCoder:(NSCoder*)decoder {    \n    self.installMode = [decoder decodeIntegerForKey:InstallModeKey];\n    self.minimumBackgroundDuration = [decoder decodeIntegerForKey:MinimumBackgroundDurationKey];\n    return self;\n}\n\n@end"
  },
  {
    "path": "plugins/cordova-plugin-code-push/src/ios/UpdateHashUtils.h",
    "content": "@interface UpdateHashUtils : NSObject\n\n+ (NSString*)getBinaryHash:(NSError**)error;\n\n@end"
  },
  {
    "path": "plugins/cordova-plugin-code-push/src/ios/UpdateHashUtils.m",
    "content": "#import <CommonCrypto/CommonDigest.h>\n#import \"UpdateHashUtils.h\"\n\n@implementation UpdateHashUtils : NSObject\n\n+ (NSString*)binaryAssetsPath\n{\n    return [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@\"www\"];\n}\n\n+ (void)addFolderEntriesToManifest:(NSString*)folderPath\n                        pathPrefix:(NSString*)pathPrefix\n                   manifestEntries:(NSMutableArray*)manifestEntries\n                             error:(NSError**)error\n{\n    NSArray* folderFiles = [[NSFileManager defaultManager]\n                            contentsOfDirectoryAtPath:folderPath\n                            error:error];\n    if (*error) {\n        return;\n    }\n    \n    for (NSString* fileName in folderFiles) {\n        NSString* fullFilePath = [folderPath stringByAppendingPathComponent:fileName];\n        NSString* relativePath = [pathPrefix stringByAppendingPathComponent:fileName];\n        BOOL isDir = NO;\n        if ([[NSFileManager defaultManager] fileExistsAtPath:fullFilePath\n                                                 isDirectory:&isDir] && isDir) {\n            [self addFolderEntriesToManifest:fullFilePath\n                                  pathPrefix:relativePath\n                             manifestEntries:manifestEntries\n                                       error:error];\n            if (*error) {\n                return;\n            }\n        } else {\n            NSData* fileContents = [NSData dataWithContentsOfFile:fullFilePath];\n            NSString* fileContentsHash = [self computeHashForData:fileContents];\n            [manifestEntries addObject:[[relativePath stringByAppendingString:@\":\"] stringByAppendingString:fileContentsHash]];\n        }\n    }\n}\n\n+ (NSString*)computeFinalHashFromManifestEntries:(NSMutableArray*)manifest\n                                           error:(NSError**)error\n{\n    NSArray* sortedManifest = [manifest sortedArrayUsingSelector:@selector(compare:)];\n    NSData* manifestData = [NSJSONSerialization dataWithJSONObject:sortedManifest\n                                                           options:kNilOptions\n                                                             error:error];\n    if (*error) {\n        return nil;\n    }\n    \n    NSString* manifestString = [[NSString alloc] initWithData:manifestData\n                                                     encoding:NSUTF8StringEncoding];\n    // The JSON serialization turns path separators into \"\\/\", e.g. \"www\\/images\\/image.png\"\n    manifestString = [manifestString stringByReplacingOccurrencesOfString:@\"\\\\/\"\n                                                               withString:@\"/\"];\n    return [self computeHashForData:[NSData dataWithBytes:manifestString.UTF8String length:manifestString.length]];\n}\n\n+ (NSString*)computeHashForData:(NSData*)inputData\n{\n    uint8_t digest[CC_SHA256_DIGEST_LENGTH];\n    CC_SHA256(inputData.bytes, inputData.length, digest);\n    NSMutableString* inputHash = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH * 2];\n    for (int i = 0; i < CC_SHA256_DIGEST_LENGTH; i++) {\n        [inputHash appendFormat:@\"%02x\", digest[i]];\n    }\n    \n    return inputHash;\n}\n\n+ (NSString*)getBinaryHash:(NSError**)error\n{\n    NSMutableArray* manifestEntries = [NSMutableArray array];\n    [self addFolderEntriesToManifest:[self binaryAssetsPath]\n                          pathPrefix:@\"www\"\n                     manifestEntries:manifestEntries\n                               error:error];\n    return [self computeFinalHashFromManifestEntries:manifestEntries error:error];\n}\n\n@end"
  },
  {
    "path": "plugins/cordova-plugin-code-push/src/ios/Utilities.h",
    "content": "@interface Utilities : NSObject\n\n+ (NSString*)getApplicationTimestamp;\n+ (NSDate*)getApplicationBuildTime;\n\n@end"
  },
  {
    "path": "plugins/cordova-plugin-code-push/src/ios/Utilities.m",
    "content": "#import \"Utilities.h\"\n\n@implementation Utilities\n\n+ (NSString*)getApplicationTimestamp{\n    NSDate* applicationBuildTime = [self getApplicationBuildTime];\n    if (applicationBuildTime){\n        NSNumber* timestamp = [[NSNumber alloc] initWithDouble: floor([applicationBuildTime timeIntervalSince1970] * 1000)];\n        return [timestamp stringValue];\n    }\n    \n    return nil;\n}\n\n+ (NSDate*)getApplicationBuildTime{\n    NSString *appPath = [[NSBundle mainBundle] bundlePath];\n    NSDictionary *executableAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:appPath error:nil];\n    return [executableAttributes objectForKey:@\"NSFileModificationDate\"];\n}\n\n@end"
  },
  {
    "path": "plugins/cordova-plugin-compat/README.md",
    "content": "<!--\n#\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#  KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n#\n-->\n\ncordova-plugin-compat\n------------------------\n\nThis repo is for remaining backwards compatible with previous versions of Cordova.\n"
  },
  {
    "path": "plugins/cordova-plugin-compat/package.json",
    "content": "{\n    \"name\": \"cordova-plugin-compat\",\n    \"description\": \"This repo is for remaining backwards compatible with previous versions of Cordova.\",\n    \"version\": \"1.0.0\",\n    \"homepage\": \"http://github.com/apache/cordova-plugin-compat#readme\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"git://github.com/apache/cordova-plugin-compat.git\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/apache/cordova-plugin-compat/issues\"\n    },\n    \"cordova\": {\n        \"id\": \"cordova-plugin-compat\",\n        \"platforms\": [\n            \"android\"\n        ]\n    },\n    \"keywords\": [\n        \"ecosystem:cordova\",\n        \"ecosystem:phonegap\",\n        \"cordova-android\"\n    ],\n    \"engines\": [\n        {\n            \"name\": \"cordova\",\n            \"version\": \">=5.0.0\"\n        }\n    ],\n    \"author\": \"Apache Software Foundation\",\n    \"license\": \"Apache-2.0\"\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-compat/plugin.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<!--\n  Licensed to the Apache Software Foundation (ASF) under one\n  or more contributor license agreements.  See the NOTICE file\n  distributed with this work for additional information\n  regarding copyright ownership.  The ASF licenses this file\n  to you under the Apache License, Version 2.0 (the\n  \"License\"); you may not use this file except in compliance\n  with the License.  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing,\n  software distributed under the License is distributed on an\n  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n  KIND, either express or implied.  See the License for the\n  specific language governing permissions and limitations\n  under the License.\n-->\n\n<plugin xmlns=\"http://cordova.apache.org/ns/plugins/1.0\"\n           id=\"cordova-plugin-compat\"\n      version=\"1.0.0\">\n    <name>Compat</name>\n    <description>Cordova Compatibility Plugin</description>\n    <license>Apache 2.0</license>\n    <keywords>cordova,compat</keywords>\n    <repo>https://git-wip-us.apache.org/repos/asf/cordova-plugin-compat.git</repo>\n\n    <!-- android -->\n    <platform name=\"android\">\n        <source-file src=\"src/android/PermissionHelper.java\" target-dir=\"src/org/apache/cordova\" />\n    </platform>\n\n</plugin>\n"
  },
  {
    "path": "plugins/cordova-plugin-compat/src/android/PermissionHelper.java",
    "content": "/*\n       Licensed to the Apache Software Foundation (ASF) under one\n       or more contributor license agreements.  See the NOTICE file\n       distributed with this work for additional information\n       regarding copyright ownership.  The ASF licenses this file\n       to you under the Apache License, Version 2.0 (the\n       \"License\"); you may not use this file except in compliance\n       with the License.  You may obtain a copy of the License at\n\n         http://www.apache.org/licenses/LICENSE-2.0\n\n       Unless required by applicable law or agreed to in writing,\n       software distributed under the License is distributed on an\n       \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n       KIND, either express or implied.  See the License for the\n       specific language governing permissions and limitations\n       under the License.\n*/\npackage org.apache.cordova;\n\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\nimport java.util.Arrays;\n\nimport org.apache.cordova.CordovaInterface;\nimport org.apache.cordova.CordovaPlugin;\nimport org.apache.cordova.LOG;\n\nimport android.content.pm.PackageManager;\n\n/**\n * This class provides reflective methods for permission requesting and checking so that plugins\n * written for cordova-android 5.0.0+ can still compile with earlier cordova-android versions.\n */\npublic class PermissionHelper {\n    private static final String LOG_TAG = \"CordovaPermissionHelper\";\n\n    /**\n     * Requests a \"dangerous\" permission for the application at runtime. This is a helper method\n     * alternative to cordovaInterface.requestPermission() that does not require the project to be\n     * built with cordova-android 5.0.0+\n     *\n     * @param plugin        The plugin the permission is being requested for\n     * @param requestCode   A requestCode to be passed to the plugin's onRequestPermissionResult()\n     *                      along with the result of the permission request\n     * @param permission    The permission to be requested\n     */\n    public static void requestPermission(CordovaPlugin plugin, int requestCode, String permission) {\n        PermissionHelper.requestPermissions(plugin, requestCode, new String[] {permission});\n    }\n\n    /**\n     * Requests \"dangerous\" permissions for the application at runtime. This is a helper method\n     * alternative to cordovaInterface.requestPermissions() that does not require the project to be\n     * built with cordova-android 5.0.0+\n     *\n     * @param plugin        The plugin the permissions are being requested for\n     * @param requestCode   A requestCode to be passed to the plugin's onRequestPermissionResult()\n     *                      along with the result of the permissions request\n     * @param permissions   The permissions to be requested\n     */\n    public static void requestPermissions(CordovaPlugin plugin, int requestCode, String[] permissions) {\n        try {\n            Method requestPermission = CordovaInterface.class.getDeclaredMethod(\n                    \"requestPermissions\", CordovaPlugin.class, int.class, String[].class);\n\n            // If there is no exception, then this is cordova-android 5.0.0+\n            requestPermission.invoke(plugin.cordova, plugin, requestCode, permissions);\n        } catch (NoSuchMethodException noSuchMethodException) {\n            // cordova-android version is less than 5.0.0, so permission is implicitly granted\n            LOG.d(LOG_TAG, \"No need to request permissions \" + Arrays.toString(permissions));\n\n            // Notify the plugin that all were granted by using more reflection\n            deliverPermissionResult(plugin, requestCode, permissions);\n        } catch (IllegalAccessException illegalAccessException) {\n            // Should never be caught; this is a public method\n            LOG.e(LOG_TAG, \"IllegalAccessException when requesting permissions \" + Arrays.toString(permissions), illegalAccessException);\n        } catch(InvocationTargetException invocationTargetException) {\n            // This method does not throw any exceptions, so this should never be caught\n            LOG.e(LOG_TAG, \"invocationTargetException when requesting permissions \" + Arrays.toString(permissions), invocationTargetException);\n        }\n    }\n\n    /**\n     * Checks at runtime to see if the application has been granted a permission. This is a helper\n     * method alternative to cordovaInterface.hasPermission() that does not require the project to\n     * be built with cordova-android 5.0.0+\n     *\n     * @param plugin        The plugin the permission is being checked against\n     * @param permission    The permission to be checked\n     *\n     * @return              True if the permission has already been granted and false otherwise\n     */\n    public static boolean hasPermission(CordovaPlugin plugin, String permission) {\n        try {\n            Method hasPermission = CordovaInterface.class.getDeclaredMethod(\"hasPermission\", String.class);\n\n            // If there is no exception, then this is cordova-android 5.0.0+\n            return (Boolean) hasPermission.invoke(plugin.cordova, permission);\n        } catch (NoSuchMethodException noSuchMethodException) {\n            // cordova-android version is less than 5.0.0, so permission is implicitly granted\n            LOG.d(LOG_TAG, \"No need to check for permission \" + permission);\n            return true;\n        } catch (IllegalAccessException illegalAccessException) {\n            // Should never be caught; this is a public method\n            LOG.e(LOG_TAG, \"IllegalAccessException when checking permission \" + permission, illegalAccessException);\n        } catch(InvocationTargetException invocationTargetException) {\n            // This method does not throw any exceptions, so this should never be caught\n            LOG.e(LOG_TAG, \"invocationTargetException when checking permission \" + permission, invocationTargetException);\n        }\n        return false;\n    }\n\n    private static void deliverPermissionResult(CordovaPlugin plugin, int requestCode, String[] permissions) {\n        // Generate the request results\n        int[] requestResults = new int[permissions.length];\n        Arrays.fill(requestResults, PackageManager.PERMISSION_GRANTED);\n\n        try {\n            Method onRequestPermissionResult = CordovaPlugin.class.getDeclaredMethod(\n                    \"onRequestPermissionResult\", int.class, String[].class, int[].class);\n\n            onRequestPermissionResult.invoke(plugin, requestCode, permissions, requestResults);\n        } catch (NoSuchMethodException noSuchMethodException) {\n            // Should never be caught since the plugin must be written for cordova-android 5.0.0+ if it\n            // made it to this point\n            LOG.e(LOG_TAG, \"NoSuchMethodException when delivering permissions results\", noSuchMethodException);\n        } catch (IllegalAccessException illegalAccessException) {\n            // Should never be caught; this is a public method\n            LOG.e(LOG_TAG, \"IllegalAccessException when delivering permissions results\", illegalAccessException);\n        } catch(InvocationTargetException invocationTargetException) {\n            // This method may throw a JSONException. We are just duplicating cordova-android's\n            // exception handling behavior here; all it does is log the exception in CordovaActivity,\n            // print the stacktrace, and ignore it\n            LOG.e(LOG_TAG, \"InvocationTargetException when delivering permissions results\", invocationTargetException);\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-device/CONTRIBUTING.md",
    "content": "<!--\n#\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#  KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n#\n-->\n\n# Contributing to Apache Cordova\n\nAnyone can contribute to Cordova. And we need your contributions.\n\nThere are multiple ways to contribute: report bugs, improve the docs, and\ncontribute code.\n\nFor instructions on this, start with the \n[contribution overview](http://cordova.apache.org/contribute/).\n\nThe details are explained there, but the important items are:\n - Sign and submit an Apache ICLA (Contributor License Agreement).\n - Have a Jira issue open that corresponds to your contribution.\n - Run the tests so your patch doesn't break existing functionality.\n\nWe look forward to your contributions!\n"
  },
  {
    "path": "plugins/cordova-plugin-device/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License."
  },
  {
    "path": "plugins/cordova-plugin-device/NOTICE",
    "content": "Apache Cordova\nCopyright 2012 The Apache Software Foundation\n\nThis product includes software developed at\nThe Apache Software Foundation (http://www.apache.org/).\n"
  },
  {
    "path": "plugins/cordova-plugin-device/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-device.svg?branch=master)](https://travis-ci.org/apache/cordova-plugin-device)\n\n# cordova-plugin-device\n\nThis plugin defines a global `device` object, which describes the device's hardware and software.\nAlthough the object is in the global scope, it is not available until after the `deviceready` event.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(device.cordova);\n    }\n\nReport issues with this plugin on the [Apache Cordova issue tracker](https://issues.apache.org/jira/issues/?jql=project%20%3D%20CB%20AND%20status%20in%20%28Open%2C%20%22In%20Progress%22%2C%20Reopened%29%20AND%20resolution%20%3D%20Unresolved%20AND%20component%20%3D%20%22Plugin%20Device%22%20ORDER%20BY%20priority%20DESC%2C%20summary%20ASC%2C%20updatedDate%20DESC)\n\n\n## Installation\n\n    cordova plugin add cordova-plugin-device\n\n## Properties\n\n- device.cordova\n- device.model\n- device.platform\n- device.uuid\n- device.version\n- device.manufacturer\n- device.isVirtual\n- device.serial\n\n## device.cordova\n\nGet the version of Cordova running on the device.\n\n### Supported Platforms\n\n- Amazon Fire OS\n- Android\n- BlackBerry 10\n- Browser\n- Firefox OS\n- iOS\n- Tizen\n- Windows Phone 7 and 8\n- Windows\n- OSX\n\n## device.model\n\nThe `device.model` returns the name of the device's model or\nproduct. The value is set by the device manufacturer and may be\ndifferent across versions of the same product.\n\n### Supported Platforms\n\n- Android\n- BlackBerry 10\n- Browser\n- iOS\n- Tizen\n- Windows Phone 7 and 8\n- Windows\n- OSX\n\n### Quick Example\n\n    // Android:    Nexus One       returns \"Passion\" (Nexus One code name)\n    //             Motorola Droid  returns \"voles\"\n    // BlackBerry: Torch 9800      returns \"9800\"\n    // Browser:    Google Chrome   returns \"Chrome\"\n    //             Safari          returns \"Safari\"\n    // iOS:     for the iPad Mini, returns iPad2,5; iPhone 5 is iPhone 5,1. See http://theiphonewiki.com/wiki/index.php?title=Models\n    // OSX:                        returns \"x86_64\"\n    // \n    var model = device.model;\n\n### Android Quirks\n\n- Gets the [product name](http://developer.android.com/reference/android/os/Build.html#PRODUCT) instead of the [model name](http://developer.android.com/reference/android/os/Build.html#MODEL), which is often the production code name. For example, the Nexus One returns `Passion`, and Motorola Droid returns `voles`.\n\n### Tizen Quirks\n\n- Returns the device model assigned by the vendor, for example, `TIZEN`\n\n### Windows Phone 7 and 8 Quirks\n\n- Returns the device model specified by the manufacturer. For example, the Samsung Focus returns `SGH-i917`.\n\n## device.platform\n\nGet the device's operating system name.\n\n    var string = device.platform;\n\n### Supported Platforms\n\n- Android\n- BlackBerry 10\n- Browser\n- Firefox OS\n- iOS\n- Tizen\n- Windows Phone 7 and 8\n- Windows\n- OSX\n\n### Quick Example\n\n    // Depending on the device, a few examples are:\n    //   - \"Android\"\n    //   - \"BlackBerry 10\"\n    //   - \"browser\"\n    //   - \"iOS\"\n    //   - \"WinCE\"\n    //   - \"Tizen\"\n    //   - \"Mac OS X\"\n    var devicePlatform = device.platform;\n\n### Windows Phone 7 Quirks\n\nWindows Phone 7 devices report the platform as `WinCE`.\n\n### Windows Phone 8 Quirks\n\nWindows Phone 8 devices report the platform as `Win32NT`.\n\n## device.uuid\n\nGet the device's Universally Unique Identifier ([UUID](http://en.wikipedia.org/wiki/Universally_Unique_Identifier)).\n\n    var string = device.uuid;\n\n### Description\n\nThe details of how a UUID is generated are determined by the device manufacturer and are specific to the device's platform or model.\n\n### Supported Platforms\n\n- Android\n- BlackBerry 10\n- iOS\n- Tizen\n- Windows Phone 7 and 8\n- Windows\n- OSX\n\n### Quick Example\n\n    // Android: Returns a random 64-bit integer (as a string, again!)\n    //          The integer is generated on the device's first boot\n    //\n    // BlackBerry: Returns the PIN number of the device\n    //             This is a nine-digit unique integer (as a string, though!)\n    //\n    // iPhone: (Paraphrased from the UIDevice Class documentation)\n    //         Returns the [UIDevice identifierForVendor] UUID which is unique and the same for all apps installed by the same vendor. However the UUID can be different if the user deletes all apps from the vendor and then reinstalls it.\n    // Windows Phone 7 : Returns a hash of device+current user,\n    // if the user is not defined, a guid is generated and will persist until the app is uninstalled\n    // Tizen: returns the device IMEI (International Mobile Equipment Identity or IMEI is a number\n    // unique to every GSM and UMTS mobile phone.\n    var deviceID = device.uuid;\n\n### iOS Quirk\n\nThe `uuid` on iOS uses the identifierForVendor property. It is unique to the device across the same vendor, but will be different for different vendors and will change if all apps from the vendor are deleted and then reinstalled.\nRefer [here](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIDevice_Class/#//apple_ref/occ/instp/UIDevice/identifierForVendor) for details.\nThe UUID will be the same if app is restored from a backup or iCloud as it is saved in preferences. Users using older versions of this plugin will still receive the same previous UUID generated by another means as it will be retrieved from preferences.\n\n### OSX Quirk\n\nThe `uuid` on OSX is generated automatically if it does not exist yet and is stored in the `standardUserDefaults` in the `CDVUUID` property. \n\n### Windows Phone 7 and 8 Quirks\n\nThe `uuid` for Windows Phone 7 requires the permission\n`ID_CAP_IDENTITY_DEVICE`.  Microsoft will likely deprecate this\nproperty soon.  If the capability is not available, the application\ngenerates a persistent guid that is maintained for the duration of the\napplication's installation on the device.\n\n## device.version\n\nGet the operating system version.\n\n    var string = device.version;\n\n### Supported Platforms\n\n- Android 2.1+\n- BlackBerry 10\n- Browser\n- iOS\n- Tizen\n- Windows Phone 7 and 8\n- Windows\n- OSX\n\n### Quick Example\n\n    // Android:    Froyo OS would return \"2.2\"\n    //             Eclair OS would return \"2.1\", \"2.0.1\", or \"2.0\"\n    //             Version can also return update level \"2.1-update1\"\n    //\n    // BlackBerry: Torch 9800 using OS 6.0 would return \"6.0.0.600\"\n    //\n    // Browser:    Returns version number for the browser\n    //\n    // iPhone:     iOS 3.2 returns \"3.2\"\n    //\n    // Windows Phone 7: returns current OS version number, ex. on Mango returns 7.10.7720\n    // Windows 8: return the current OS version, ex on Windows 8.1 returns 6.3.9600.16384\n    // Tizen: returns \"TIZEN_20120425_2\"\n    // OSX:        El Capitan would return \"10.11.2\"\n    //\n    var deviceVersion = device.version;\n\n## device.manufacturer\n\nGet the device's manufacturer.\n\n    var string = device.manufacturer;\n\n### Supported Platforms\n\n- Android \n- BlackBerry 10\n- iOS\n- Windows Phone 7 and 8\n- Windows\n\n### Quick Example\n\n    // Android:    Motorola XT1032 would return \"motorola\"\n    // BlackBerry: returns \"BlackBerry\"\n    // iPhone:     returns \"Apple\"\n    //\n    var deviceManufacturer = device.manufacturer;\n\n## device.isVirtual\n\nwhether the device is running on a simulator.\n\n    var isSim = device.isVirtual;\n\n### Supported Platforms\n\n- Android 2.1+\n- iOS\n- Windows Phone 8\n- Windows\n- OSX \n\n### OSX Quirk\n\nThe `isVirtual` property on OS X always returns false.\n\n## device.serial\n\nGet the device hardware serial number ([SERIAL](http://developer.android.com/reference/android/os/Build.html#SERIAL)).\n\n    var string = device.serial;\n\n### Supported Platforms\n\n- Android\n- OSX\n\n"
  },
  {
    "path": "plugins/cordova-plugin-device/RELEASENOTES.md",
    "content": "<!--\n#\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n# \n# http://www.apache.org/licenses/LICENSE-2.0\n# \n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#  KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n#\n-->\n# Release Notes\n\n### 1.1.2 (Apr 15, 2016)\n* Use passed device, follow create policy forf `CFUUIDCreate`\n* CB-10631 Fix for `device.uuid` in **iOS 5.1.1**\n* Updating the comment to exclude URL\n* CB-10636 Add `JSHint` for plugins\n* Refactored `deviceInfo` on **iOS** for better readability.\n\n### 1.1.1 (Jan 15, 2016)\n* CB-10238 **OSX** Move `device-plugin` out from `cordovalib` to the plugin repository\n* CB-9923 Update `device.platform` documentation for **Browser** platform\n\n### 1.1.0 (Nov 18, 2015)\n* [CB-10035](https://issues.apache.org/jira/browse/CB-10035) Updated `RELEASENOTES` to be newest to oldest\n* Add `isVirtual` for **Windows Phone 8.x**\n* Added basic **Android** support for hardware serial number\n* [CB-9865](https://issues.apache.org/jira/browse/CB-9865) Better simulator detection for **iOS**\n* Fixing contribute link.\n* Added **WP8** implementation\n* update to use `TARGET_OS_SIMULATOR` as `TARGET_IPHONE_SIMULATOR` is deprecated.\n* update code to use 'isVirtual'\n* create test to verify existence and type of new property 'isVirtual'\n* add `isSimulator` for **iOS** & **Android** device\n* Updated documentation to mention backwards compatibility\n* Updated **README** to reflect new behaviour and quirks on **iOS**\n* Check user defaults first to maintain backwards compatibility\n* Changed `UUID` to use `[UIDevice identifierForVendor]`\n\n### 1.0.1 (Jun 17, 2015)\n* [CB-9128](https://issues.apache.org/jira/browse/CB-9128) cordova-plugin-device documentation translation: cordova-plugin-device\n* Attempts to corrent npm markdown issue\n\n### 1.0.0 (Apr 15, 2015)\n* [CB-8746](https://issues.apache.org/jira/browse/CB-8746) gave plugin major version bump\n* [CB-8683](https://issues.apache.org/jira/browse/CB-8683) changed plugin-id to pacakge-name\n* [CB-8653](https://issues.apache.org/jira/browse/CB-8653) properly updated translated docs to use new id\n* [CB-8653](https://issues.apache.org/jira/browse/CB-8653) updated translated docs to use new id\n* Use TRAVIS_BUILD_DIR, install paramedic by npm\n* [CB-8653](https://issues.apache.org/jira/browse/CB-8653) Updated Readme\n* remove defunct windows8 version\n* add travis badge\n* Add cross-plugin ios paramedic test running for TravisCI\n* [CB-8538](https://issues.apache.org/jira/browse/CB-8538) Added package.json file\n\n### 0.3.0 (Feb 04, 2015)\n* Added device.manufacturer property for Android, iOS, Blackberry, WP8\n* Support for Windows Phone 8 ANID2 ANID is only supported up to Windows Phone 7.5\n* [CB-8351](https://issues.apache.org/jira/browse/CB-8351) Use a local copy of uniqueAppInstanceIdentifier rather than CordovaLib's version\n* browser: Fixed a bug that caused an \"cannot call method of undefined\" error if the browser's user agent wasn't recognized\n\n### 0.2.13 (Dec 02, 2014)\n* Changing `device.platform` to always report the platform as \"browser\".\n* [CB-5892](https://issues.apache.org/jira/browse/CB-5892) - Remove deprecated `window.Settings`\n* [CB-7700](https://issues.apache.org/jira/browse/CB-7700) cordova-plugin-device documentation translation: cordova-plugin-device\n* [CB-7571](https://issues.apache.org/jira/browse/CB-7571) Bump version of nested plugin to match parent plugin\n\n### 0.2.12 (Sep 17, 2014)\n* [CB-7471](https://issues.apache.org/jira/browse/CB-7471) cordova-plugin-device documentation translation\n* [CB-7552](https://issues.apache.org/jira/browse/CB-7552) device.name docs have not been removed\n* [fxos] Fix cordova version\n* added status box and documentation to manual tests\n* [fxos] Fix cordova version\n* added status box and documentation to manual tests\n* Added plugin support for the browser\n* [CB-7262](https://issues.apache.org/jira/browse/CB-7262) Adds support for universal windows apps.\n\n### 0.2.11 (Aug 06, 2014)\n* [FFOS] update DeviceProxy.js\n* [CB-6127](https://issues.apache.org/jira/browse/CB-6127) Updated translations for docs\n* Use Windows system calls to get better info\n\n### 0.2.10 (Jun 05, 2014)\n* [CB-6127](https://issues.apache.org/jira/browse/CB-6127) Spanish and French Translations added. Github close #12\n* Changing 1.5 to 2.0\n* added firefoxos version - conversion\n* added firefoxos version\n* [CB-6800](https://issues.apache.org/jira/browse/CB-6800) Add license\n* [CB-6491](https://issues.apache.org/jira/browse/CB-6491) add CONTRIBUTING.md\n\n### 0.2.9 (Apr 17, 2014)\n* [CB-5105](https://issues.apache.org/jira/browse/CB-5105): [Android, windows8, WP, BlackBerry10] Removed dead code for device.version\n* [CB-6422](https://issues.apache.org/jira/browse/CB-6422): [windows8] use cordova/exec/proxy\n* [CB-6460](https://issues.apache.org/jira/browse/CB-6460): Update license headers\n* Add NOTICE file\n\n### 0.2.8 (Feb 05, 2014)\n* Tizen support added\n\n### 0.2.7 (Jan 07, 2014)\n* [CB-5737](https://issues.apache.org/jira/browse/CB-5737) Fix exception on close caused by left over telephony code from [CB-5504](https://issues.apache.org/jira/browse/CB-5504)\n\n### 0.2.6 (Jan 02, 2014)\n* [CB-5658](https://issues.apache.org/jira/browse/CB-5658) Add doc/index.md for Device plugin\n* [CB-5504](https://issues.apache.org/jira/browse/CB-5504) Moving Telephony Logic out of Device\n\n### 0.2.5 (Dec 4, 2013)\n* [CB-5316](https://issues.apache.org/jira/browse/CB-5316) Spell Cordova as a brand unless it's a command or script\n* [ubuntu] use cordova/exec/proxy\n* add ubuntu platform\n* Modify Device.platform logic to use amazon-fireos as the platform for Amazon Devices\n* 1. Added amazon-fireos platform. 2. Change to use cordova-amazon-fireos as the platform if user agent contains 'cordova-amazon-fireos'\n\n### 0.2.4 (Oct 28, 2013)\n* [CB-5128](https://issues.apache.org/jira/browse/CB-5128): added repo + issue tag in plugin.xml for device plugin\n* [CB-5085](https://issues.apache.org/jira/browse/CB-5085) device.cordova returning wrong value\n* [CB-4915](https://issues.apache.org/jira/browse/CB-4915) Incremented plugin version on dev branch.\n\n### 0.2.3 (Sept 25, 2013)\n* [CB-4889](https://issues.apache.org/jira/browse/CB-4889) bumping&resetting version\n* [windows8] commandProxy has moved\n* [BlackBerry10] removed uneeded permission tags in plugin.xml\n* [CB-4889](https://issues.apache.org/jira/browse/CB-4889) renaming org.apache.cordova.core.device to org.apache.cordova.device\n* Rename CHANGELOG.md -> RELEASENOTES.md\n* updated to use commandProxy for ffos\n* add firefoxos support\n* [CB-4752](https://issues.apache.org/jira/browse/CB-4752) Incremented plugin version on dev branch. \n\n### 0.2.1 (Sept 5, 2013)\n* removed extraneous print statement\n* [CB-4432](https://issues.apache.org/jira/browse/CB-4432) copyright notice change\n"
  },
  {
    "path": "plugins/cordova-plugin-device/doc/de/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-device\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-device.svg?branch=master)](https://travis-ci.org/apache/cordova-plugin-device)\n\nDieses Plugin definiert eine globale `device` -Objekt, das des Geräts Hard- und Software beschreibt. Das Objekt im globalen Gültigkeitsbereich ist es zwar nicht verfügbar bis nach dem `deviceready` Ereignis.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(device.cordova);\n    }\n    \n\n## Installation\n\n    cordova plugin add cordova-plugin-device\n    \n\n## Eigenschaften\n\n  * device.cordova\n  * device.model\n  * device.platform\n  * device.uuid\n  * device.version\n\n## device.cordova\n\nRufen Sie die Version von Cordova, die auf dem Gerät ausgeführt.\n\n### Unterstützte Plattformen\n\n  * Amazon Fire OS\n  * Android\n  * BlackBerry 10\n  * Browser\n  * Firefox OS\n  * iOS\n  * Tizen\n  * Windows Phone 7 und 8\n  * Windows 8\n\n## device.model\n\nDie `device.model` gibt den Namen der Modell- oder des Geräts zurück. Der Wert wird vom Gerätehersteller festgelegt und kann zwischen den Versionen des gleichen Produkts unterschiedlich sein.\n\n### Unterstützte Plattformen\n\n  * Android\n  * BlackBerry 10\n  * Browser\n  * iOS\n  * Tizen\n  * Windows Phone 7 und 8\n  * Windows 8\n\n### Kurzes Beispiel\n\n    // Android:    Nexus One       returns \"Passion\" (Nexus One code name)\n    //             Motorola Droid  returns \"voles\"\n    // BlackBerry: Torch 9800      returns \"9800\"\n    // Browser:    Google Chrome   returns \"Chrome\"\n    //             Safari          returns \"Safari\"\n    // iOS:     for the iPad Mini, returns iPad2,5; iPhone 5 is iPhone 5,1. Finden Sie unter http://theiphonewiki.com/wiki/index.php?title=Models / / Var-Modell = device.model;\n    \n\n### Android Eigenarten\n\n  * Ruft den [Produktname](http://developer.android.com/reference/android/os/Build.html#PRODUCT) anstelle des [Modellnamens](http://developer.android.com/reference/android/os/Build.html#MODEL), das ist oft der Codename für die Produktion. Beispielsweise das Nexus One gibt `Passion` , und Motorola Droid gibt`voles`.\n\n### Tizen Macken\n\n  * Gibt z. B. das Gerätemodell von dem Kreditor zugeordnet,`TIZEN`\n\n### Windows Phone 7 und 8 Eigenarten\n\n  * Gibt das vom Hersteller angegebenen Gerätemodell zurück. Beispielsweise gibt der Samsung-Fokus`SGH-i917`.\n\n## device.platform\n\nName des Betriebssystems des Geräts zu erhalten.\n\n    var string = device.platform;\n    \n\n### Unterstützte Plattformen\n\n  * Android\n  * BlackBerry 10\n  * Browser4\n  * Firefox OS\n  * iOS\n  * Tizen\n  * Windows Phone 7 und 8\n  * Windows 8\n\n### Kurzes Beispiel\n\n    // Depending on the device, a few examples are:\n    //   - \"Android\"\n    //   - \"BlackBerry 10\"\n    //   - Browser:         returns \"MacIntel\" on Mac\n    //                      returns \"Win32\" on Windows\n    //   - \"iOS\"\n    //   - \"WinCE\"\n    //   - \"Tizen\"\n    var devicePlatform = device.platform;\n    \n\n### Windows Phone 7 Macken\n\nWindows Phone 7 Geräte melden die Plattform als`WinCE`.\n\n### Windows Phone 8 Macken\n\nWindows Phone 8 Geräte melden die Plattform als`Win32NT`.\n\n## device.uuid\n\nDes Geräts Universally Unique Identifier ([UUID](http://en.wikipedia.org/wiki/Universally_Unique_Identifier) zu erhalten).\n\n    var string = device.uuid;\n    \n\n### Beschreibung\n\nDie Details wie eine UUID generiert wird werden vom Gerätehersteller und beziehen sich auf die Plattform oder das Modell des Geräts.\n\n### Unterstützte Plattformen\n\n  * Android\n  * BlackBerry 10\n  * iOS\n  * Tizen\n  * Windows Phone 7 und 8\n  * Windows 8\n\n### Kurzes Beispiel\n\n    / / Android: wird eine zufällige 64-Bit-Ganzzahl (als Zeichenfolge, wieder!) / / die ganze Zahl wird beim ersten Start des Geräts erzeugt / / / / BlackBerry: gibt die PIN-Nummer des Gerätes / / Dies ist eine neunstellige eindeutige Ganzzahl (als String, obwohl!) / / / / iPhone: (paraphrasiert aus der Dokumentation zur UIDevice-Klasse) / / liefert eine Reihe von Hash-Werte, die aus mehreren Hardware erstellt identifiziert.\n    / / Es ist gewährleistet, dass für jedes Gerät eindeutig sein und kann nicht gebunden werden / / an den Benutzer weitergeleitet.\n    / / Windows Phone 7: gibt einen Hash des Gerät + aktueller Benutzer, / / wenn der Benutzer nicht definiert ist, eine Guid generiert und wird weiter bestehen, bis die app deinstalliert wird / / Tizen: gibt das Gerät IMEI (International Mobile Equipment Identity oder IMEI ist eine Zahl / / einzigartig für jedes GSM- und UMTS-Handy.\n    var deviceID = device.uuid;\n    \n\n### iOS Quirk\n\nDie `uuid` auf iOS ist nicht eindeutig zu einem Gerät, aber für jede Anwendung, für jede Installation variiert. Es ändert sich, wenn Sie löschen und neu die app installieren, und möglicherweise auch beim iOS zu aktualisieren, oder auch ein Upgrade möglich die app pro Version (scheinbaren in iOS 5.1). Die `uuid` ist kein zuverlässiger Wert.\n\n### Windows Phone 7 und 8 Eigenarten\n\nDie `uuid` für Windows Phone 7 die Berechtigung erfordert `ID_CAP_IDENTITY_DEVICE` . Microsoft wird diese Eigenschaft wahrscheinlich bald abzuschaffen. Wenn die Funktion nicht verfügbar ist, generiert die Anwendung eine persistente Guid, die für die Dauer der Installation der Anwendung auf dem Gerät gewährleistet ist.\n\n## device.version\n\nVersion des Betriebssystems zu erhalten.\n\n    var string = device.version;\n    \n\n### Unterstützte Plattformen\n\n  * Android 2.1 +\n  * BlackBerry 10\n  * Browser\n  * iOS\n  * Tizen\n  * Windows Phone 7 und 8\n  * Windows 8\n\n### Kurzes Beispiel\n\n    // Android:    Froyo OS would return \"2.2\"\n    //             Eclair OS would return \"2.1\", \"2.0.1\", or \"2.0\"\n    //             Version can also return update level \"2.1-update1\"\n    //\n    // BlackBerry: Torch 9800 using OS 6.0 would return \"6.0.0.600\"\n    //\n    // Browser:    Returns version number for the browser\n    //\n    // iPhone:     iOS 3.2 returns \"3.2\"\n    //\n    // Windows Phone 7: returns current OS version number, ex. on Mango returns 7.10.7720\n    // Tizen: returns \"TIZEN_20120425_2\"\n    var deviceVersion = device.version;"
  },
  {
    "path": "plugins/cordova-plugin-device/doc/de/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-device\n\nDieses Plugin definiert eine globale `device` -Objekt, das des Geräts Hard- und Software beschreibt. Das Objekt im globalen Gültigkeitsbereich ist es zwar nicht verfügbar bis nach dem `deviceready` Ereignis.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(device.cordova);\n    }\n    \n\n## Installation\n\n    cordova plugin add cordova-plugin-device\n    \n\n## Eigenschaften\n\n*   device.cordova\n*   device.model\n*   device.platform\n*   device.uuid\n*   device.version\n\n## device.cordova\n\nRufen Sie die Version von Cordova, die auf dem Gerät ausgeführt.\n\n### Unterstützte Plattformen\n\n*   Amazon Fire OS\n*   Android\n*   BlackBerry 10\n*   Browser\n*   Firefox OS\n*   iOS\n*   Tizen\n*   Windows Phone 7 und 8\n*   Windows 8\n\n## device.model\n\nDie `device.model` gibt den Namen der Modell- oder des Geräts zurück. Der Wert wird vom Gerätehersteller festgelegt und kann zwischen den Versionen des gleichen Produkts unterschiedlich sein.\n\n### Unterstützte Plattformen\n\n*   Android\n*   BlackBerry 10\n*   Browser\n*   iOS\n*   Tizen\n*   Windows Phone 7 und 8\n*   Windows 8\n\n### Kurzes Beispiel\n\n    // Android:    Nexus One       returns \"Passion\" (Nexus One code name)\n    //             Motorola Droid  returns \"voles\"\n    // BlackBerry: Torch 9800      returns \"9800\"\n    // Browser:    Google Chrome   returns \"Chrome\"\n    //             Safari          returns \"Safari\"\n    // iOS:     for the iPad Mini, returns iPad2,5; iPhone 5 is iPhone 5,1. Finden Sie unter http://theiphonewiki.com/wiki/index.php?title=Models / / Var-Modell = device.model;\n    \n\n### Android Eigenarten\n\n*   Ruft den [Produktname][1] anstelle des [Modellnamens][2], das ist oft der Codename für die Produktion. Beispielsweise das Nexus One gibt `Passion` , und Motorola Droid gibt`voles`.\n\n [1]: http://developer.android.com/reference/android/os/Build.html#PRODUCT\n [2]: http://developer.android.com/reference/android/os/Build.html#MODEL\n\n### Tizen Macken\n\n*   Gibt z. B. das Gerätemodell von dem Kreditor zugeordnet,`TIZEN`\n\n### Windows Phone 7 und 8 Eigenarten\n\n*   Gibt das vom Hersteller angegebenen Gerätemodell zurück. Beispielsweise gibt der Samsung-Fokus`SGH-i917`.\n\n## device.platform\n\nName des Betriebssystems des Geräts zu erhalten.\n\n    var string = device.platform;\n    \n\n### Unterstützte Plattformen\n\n*   Android\n*   BlackBerry 10\n*   Browser4\n*   Firefox OS\n*   iOS\n*   Tizen\n*   Windows Phone 7 und 8\n*   Windows 8\n\n### Kurzes Beispiel\n\n    // Depending on the device, a few examples are:\n    //   - \"Android\"\n    //   - \"BlackBerry 10\"\n    //   - Browser:         returns \"MacIntel\" on Mac\n    //                      returns \"Win32\" on Windows\n    //   - \"iOS\"\n    //   - \"WinCE\"\n    //   - \"Tizen\"\n    var devicePlatform = device.platform;\n    \n\n### Windows Phone 7 Macken\n\nWindows Phone 7 Geräte melden die Plattform als`WinCE`.\n\n### Windows Phone 8 Macken\n\nWindows Phone 8 Geräte melden die Plattform als`Win32NT`.\n\n## device.uuid\n\nDes Geräts Universally Unique Identifier ([UUID][3] zu erhalten).\n\n [3]: http://en.wikipedia.org/wiki/Universally_Unique_Identifier\n\n    var string = device.uuid;\n    \n\n### Beschreibung\n\nDie Details wie eine UUID generiert wird werden vom Gerätehersteller und beziehen sich auf die Plattform oder das Modell des Geräts.\n\n### Unterstützte Plattformen\n\n*   Android\n*   BlackBerry 10\n*   iOS\n*   Tizen\n*   Windows Phone 7 und 8\n*   Windows 8\n\n### Kurzes Beispiel\n\n    / / Android: wird eine zufällige 64-Bit-Ganzzahl (als Zeichenfolge, wieder!) / / die ganze Zahl wird beim ersten Start des Geräts erzeugt / / / / BlackBerry: gibt die PIN-Nummer des Gerätes / / Dies ist eine neunstellige eindeutige Ganzzahl (als String, obwohl!) / / / / iPhone: (paraphrasiert aus der Dokumentation zur UIDevice-Klasse) / / liefert eine Reihe von Hash-Werte, die aus mehreren Hardware erstellt identifiziert.\n    / / Es ist gewährleistet, dass für jedes Gerät eindeutig sein und kann nicht gebunden werden / / an den Benutzer weitergeleitet.\n    / / Windows Phone 7: gibt einen Hash des Gerät + aktueller Benutzer, / / wenn der Benutzer nicht definiert ist, eine Guid generiert und wird weiter bestehen, bis die app deinstalliert wird / / Tizen: gibt das Gerät IMEI (International Mobile Equipment Identity oder IMEI ist eine Zahl / / einzigartig für jedes GSM- und UMTS-Handy.\n    var deviceID = device.uuid;\n    \n\n### iOS Quirk\n\nDie `uuid` auf iOS ist nicht eindeutig zu einem Gerät, aber für jede Anwendung, für jede Installation variiert. Es ändert sich, wenn Sie löschen und neu die app installieren, und möglicherweise auch beim iOS zu aktualisieren, oder auch ein Upgrade möglich die app pro Version (scheinbaren in iOS 5.1). Die `uuid` ist kein zuverlässiger Wert.\n\n### Windows Phone 7 und 8 Eigenarten\n\nDie `uuid` für Windows Phone 7 die Berechtigung erfordert `ID_CAP_IDENTITY_DEVICE` . Microsoft wird diese Eigenschaft wahrscheinlich bald abzuschaffen. Wenn die Funktion nicht verfügbar ist, generiert die Anwendung eine persistente Guid, die für die Dauer der Installation der Anwendung auf dem Gerät gewährleistet ist.\n\n## device.version\n\nVersion des Betriebssystems zu erhalten.\n\n    var string = device.version;\n    \n\n### Unterstützte Plattformen\n\n*   Android 2.1 +\n*   BlackBerry 10\n*   Browser\n*   iOS\n*   Tizen\n*   Windows Phone 7 und 8\n*   Windows 8\n\n### Kurzes Beispiel\n\n    // Android:    Froyo OS would return \"2.2\"\n    //             Eclair OS would return \"2.1\", \"2.0.1\", or \"2.0\"\n    //             Version can also return update level \"2.1-update1\"\n    //\n    // BlackBerry: Torch 9800 using OS 6.0 would return \"6.0.0.600\"\n    //\n    // Browser:    Returns version number for the browser\n    //\n    // iPhone:     iOS 3.2 returns \"3.2\"\n    //\n    // Windows Phone 7: returns current OS version number, ex. on Mango returns 7.10.7720\n    // Tizen: returns \"TIZEN_20120425_2\"\n    var deviceVersion = device.version;\n"
  },
  {
    "path": "plugins/cordova-plugin-device/doc/es/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-device\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-device.svg?branch=master)](https://travis-ci.org/apache/cordova-plugin-device)\n\nEste plugin define un global `device` objeto que describe del dispositivo hardware y software. Aunque el objeto está en el ámbito global, no está disponible hasta después de la `deviceready` evento.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(device.cordova);\n    }\n    \n\n## Instalación\n\n    cordova plugin add cordova-plugin-device\n    \n\n## Propiedades\n\n  * device.cordova\n  * device.model\n  * device.platform\n  * device.uuid\n  * device.version\n\n## device.cordova\n\nObtener la versión de Cordova que se ejecuta en el dispositivo.\n\n### Plataformas soportadas\n\n  * Amazon fire OS\n  * Android\n  * BlackBerry 10\n  * Explorador\n  * Firefox OS\n  * iOS\n  * Tizen\n  * Windows Phone 7 y 8\n  * Windows 8\n\n## device.model\n\nEl `device.model` devuelve el nombre de modelo del dispositivo o producto. El valor es fijado por el fabricante del dispositivo y puede ser diferente a través de versiones del mismo producto.\n\n### Plataformas soportadas\n\n  * Android\n  * BlackBerry 10\n  * Explorador\n  * iOS\n  * Tizen\n  * Windows Phone 7 y 8\n  * Windows 8\n\n### Ejemplo rápido\n\n    // Android:    Nexus One       returns \"Passion\" (Nexus One code name)\n    //             Motorola Droid  returns \"voles\"\n    // BlackBerry: Torch 9800      returns \"9800\"\n    // Browser:    Google Chrome   returns \"Chrome\"\n    //             Safari          returns \"Safari\"\n    // iOS:     for the iPad Mini, returns iPad2,5; iPhone 5 is iPhone 5,1. See http://theiphonewiki.com/wiki/index.php?title=Models\n    //\n    var model = device.model;\n    \n\n### Rarezas Android\n\n  * Obtiene el [nombre del producto](http://developer.android.com/reference/android/os/Build.html#PRODUCT) en lugar del [nombre de la modelo](http://developer.android.com/reference/android/os/Build.html#MODEL), que es a menudo el nombre de código de producción. Por ejemplo, el Nexus One devuelve `Passion` y Motorola Droid devuelve `voles`.\n\n### Rarezas Tizen\n\n  * Devuelve que el modelo de dispositivo asignado por el proveedor, por ejemplo, `TIZEN`\n\n### Windows Phone 7 y 8 rarezas\n\n  * Devuelve el modelo de dispositivo especificado por el fabricante. Por ejemplo, el Samsung Focus devuelve `SGH-i917`.\n\n## device.platform\n\nObtener el nombre del sistema operativo del dispositivo.\n\n    var string = device.platform;\n    \n\n### Plataformas soportadas\n\n  * Android\n  * BlackBerry 10\n  * Browser4\n  * Firefox OS\n  * iOS\n  * Tizen\n  * Windows Phone 7 y 8\n  * Windows 8\n\n### Ejemplo rápido\n\n    // Depending on the device, a few examples are:\n    //   - \"Android\"\n    //   - \"BlackBerry 10\"\n    //   - Browser:         returns \"MacIntel\" on Mac\n    //                      returns \"Win32\" on Windows\n    //   - \"iOS\"\n    //   - \"WinCE\"\n    //   - \"Tizen\"\n    var devicePlatform = device.platform;\n    \n\n### Windows Phone 7 rarezas\n\nDispositivos Windows Phone 7 informe de la plataforma como `WinCE`.\n\n### Windows Phone 8 rarezas\n\nDispositivos Windows Phone 8 Informe la plataforma como `Win32NT`.\n\n## device.uuid\n\nObtener identificador universalmente única del dispositivo ([UUID](http://en.wikipedia.org/wiki/Universally_Unique_Identifier)).\n\n    var string = device.uuid;\n    \n\n### Descripción\n\nLos detalles de cómo se genera un UUID son determinados por el fabricante del dispositivo y son específicos a la plataforma del dispositivo o modelo.\n\n### Plataformas soportadas\n\n  * Android\n  * BlackBerry 10\n  * iOS\n  * Tizen\n  * Windows Phone 7 y 8\n  * Windows 8\n\n### Ejemplo rápido\n\n    // Android: Returns a random 64-bit integer (as a string, again!)\n    //          The integer is generated on the device's first boot\n    //\n    // BlackBerry: Returns the PIN number of the device\n    //             This is a nine-digit unique integer (as a string, though!)\n    //\n    // iPhone: (Paraphrased from the UIDevice Class documentation)\n    //         Returns a string of hash values created from multiple hardware identifies.\n    //         It is guaranteed to be unique for every device and can't be tied\n    //         to the user account.\n    // Windows Phone 7 : Returns a hash of device+current user,\n    // if the user is not defined, a guid is generated and will persist until the app is uninstalled\n    // Tizen: returns the device IMEI (International Mobile Equipment Identity or IMEI is a number\n    // unique to every GSM and UMTS mobile phone.\n    var deviceID = device.uuid;\n    \n\n### Rarezas de iOS\n\nEl `uuid` en iOS no es exclusiva de un dispositivo, pero varía para cada aplicación, para cada instalación. Cambia si puedes borrar y volver a instalar la aplicación, y posiblemente también cuándo actualizar iOS, o incluso mejorar la aplicación por la versión (evidente en iOS 5.1). El `uuid` no es un valor confiable.\n\n### Windows Phone 7 y 8 rarezas\n\nEl `uuid` para Windows Phone 7 requiere el permiso `ID_CAP_IDENTITY_DEVICE`. Microsoft pronto probablemente desaprueban esta propiedad. Si la capacidad no está disponible, la aplicación genera un guid persistente que se mantiene durante la duración de la instalación de la aplicación en el dispositivo.\n\n## device.version\n\nObtener la versión del sistema operativo.\n\n    var string = device.version;\n    \n\n### Plataformas soportadas\n\n  * Android 2.1 +\n  * BlackBerry 10\n  * Explorador\n  * iOS\n  * Tizen\n  * Windows Phone 7 y 8\n  * Windows 8\n\n### Ejemplo rápido\n\n    // Android:    Froyo OS would return \"2.2\"\n    //             Eclair OS would return \"2.1\", \"2.0.1\", or \"2.0\"\n    //             Version can also return update level \"2.1-update1\"\n    //\n    // BlackBerry: Torch 9800 using OS 6.0 would return \"6.0.0.600\"\n    //\n    // Browser:    Returns version number for the browser\n    //\n    // iPhone:     iOS 3.2 returns \"3.2\"\n    //\n    // Windows Phone 7: returns current OS version number, ex. on Mango returns 7.10.7720\n    // Tizen: returns \"TIZEN_20120425_2\"\n    var deviceVersion = device.version;"
  },
  {
    "path": "plugins/cordova-plugin-device/doc/es/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-device\n\nEste plugin define un global `device` objeto que describe del dispositivo hardware y software. Aunque el objeto está en el ámbito global, no está disponible hasta después de la `deviceready` evento.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(device.cordova);\n    }\n    \n\n## Instalación\n\n    cordova plugin add cordova-plugin-device\n    \n\n## Propiedades\n\n*   device.cordova\n*   device.model\n*   device.platform\n*   device.uuid\n*   device.version\n\n## device.cordova\n\nObtener la versión de Cordova que se ejecuta en el dispositivo.\n\n### Plataformas soportadas\n\n*   Amazon fire OS\n*   Android\n*   BlackBerry 10\n*   Explorador\n*   Firefox OS\n*   iOS\n*   Tizen\n*   Windows Phone 7 y 8\n*   Windows 8\n\n## device.model\n\nEl `device.model` devuelve el nombre de modelo del dispositivo o producto. El valor es fijado por el fabricante del dispositivo y puede ser diferente a través de versiones del mismo producto.\n\n### Plataformas soportadas\n\n*   Android\n*   BlackBerry 10\n*   Explorador\n*   iOS\n*   Tizen\n*   Windows Phone 7 y 8\n*   Windows 8\n\n### Ejemplo rápido\n\n    // Android:    Nexus One       returns \"Passion\" (Nexus One code name)\n    //             Motorola Droid  returns \"voles\"\n    // BlackBerry: Torch 9800      returns \"9800\"\n    // Browser:    Google Chrome   returns \"Chrome\"\n    //             Safari          returns \"Safari\"\n    // iOS:     for the iPad Mini, returns iPad2,5; iPhone 5 is iPhone 5,1. See http://theiphonewiki.com/wiki/index.php?title=Models\n    //\n    var model = device.model;\n    \n\n### Rarezas Android\n\n*   Obtiene el [nombre del producto][1] en lugar del [nombre de la modelo][2], que es a menudo el nombre de código de producción. Por ejemplo, el Nexus One devuelve `Passion` y Motorola Droid devuelve `voles`.\n\n [1]: http://developer.android.com/reference/android/os/Build.html#PRODUCT\n [2]: http://developer.android.com/reference/android/os/Build.html#MODEL\n\n### Rarezas Tizen\n\n*   Devuelve que el modelo de dispositivo asignado por el proveedor, por ejemplo, `TIZEN`\n\n### Windows Phone 7 y 8 rarezas\n\n*   Devuelve el modelo de dispositivo especificado por el fabricante. Por ejemplo, el Samsung Focus devuelve `SGH-i917`.\n\n## device.platform\n\nObtener el nombre del sistema operativo del dispositivo.\n\n    var string = device.platform;\n    \n\n### Plataformas soportadas\n\n*   Android\n*   BlackBerry 10\n*   Browser4\n*   Firefox OS\n*   iOS\n*   Tizen\n*   Windows Phone 7 y 8\n*   Windows 8\n\n### Ejemplo rápido\n\n    // Depending on the device, a few examples are:\n    //   - \"Android\"\n    //   - \"BlackBerry 10\"\n    //   - Browser:         returns \"MacIntel\" on Mac\n    //                      returns \"Win32\" on Windows\n    //   - \"iOS\"\n    //   - \"WinCE\"\n    //   - \"Tizen\"\n    var devicePlatform = device.platform;\n    \n\n### Windows Phone 7 rarezas\n\nDispositivos Windows Phone 7 informe de la plataforma como `WinCE`.\n\n### Windows Phone 8 rarezas\n\nDispositivos Windows Phone 8 Informe la plataforma como `Win32NT`.\n\n## device.uuid\n\nObtener identificador universalmente única del dispositivo ([UUID][3]).\n\n [3]: http://en.wikipedia.org/wiki/Universally_Unique_Identifier\n\n    var string = device.uuid;\n    \n\n### Descripción\n\nLos detalles de cómo se genera un UUID son determinados por el fabricante del dispositivo y son específicos a la plataforma del dispositivo o modelo.\n\n### Plataformas soportadas\n\n*   Android\n*   BlackBerry 10\n*   iOS\n*   Tizen\n*   Windows Phone 7 y 8\n*   Windows 8\n\n### Ejemplo rápido\n\n    // Android: devuelve un entero de 64 bits al azar (como una cadena, otra vez!) \n    // el entero es generado en el primer arranque del dispositivo \n    // \n    // BlackBerry: devuelve el número PIN del dispositivo \n    // este es un entero único de nueve dígitos (como una cadena, aunque!) \n    // \n    // iPhone: (parafraseado de la documentación de la clase UIDevice) \n    // devuelve una cadena de valores hash creado a partir \n    //  de múltiples hardware identifica.\n    / / Está garantizado para ser único para cada dispositivo y no puede ser atado / / a la cuenta de usuario.\n    // Windows Phone 7: devuelve un hash de dispositivo + usuario actual, \n    // si el usuario no está definido, un guid generado y persistirá hasta que se desinstala la aplicación \n    // \n    // Tizen: devuelve el dispositivo IMEI (identidad de equipo móvil internacional o IMEI es un número \n    // único para cada teléfono móvil GSM y UMTS.\n    var deviceID = device.uuid;\n    \n\n### iOS chanfle\n\nEl `uuid` en iOS no es exclusiva de un dispositivo, pero varía para cada aplicación, para cada instalación. Cambia si puedes borrar y volver a instalar la aplicación, y posiblemente también cuándo actualizar iOS, o incluso mejorar la aplicación por la versión (evidente en iOS 5.1). El `uuid` no es un valor confiable.\n\n### Windows Phone 7 y 8 rarezas\n\nEl `uuid` para Windows Phone 7 requiere el permiso `ID_CAP_IDENTITY_DEVICE`. Microsoft pronto probablemente desaprueban esta propiedad. Si la capacidad no está disponible, la aplicación genera un guid persistente que se mantiene durante la duración de la instalación de la aplicación en el dispositivo.\n\n## device.version\n\nObtener la versión del sistema operativo.\n\n    var string = device.version;\n    \n\n### Plataformas soportadas\n\n*   Android 2.1 +\n*   BlackBerry 10\n*   Explorador\n*   iOS\n*   Tizen\n*   Windows Phone 7 y 8\n*   Windows 8\n\n### Ejemplo rápido\n\n    // Android:    Froyo OS would return \"2.2\"\n    //             Eclair OS would return \"2.1\", \"2.0.1\", or \"2.0\"\n    //             Version can also return update level \"2.1-update1\"\n    //\n    // BlackBerry: Torch 9800 using OS 6.0 would return \"6.0.0.600\"\n    //\n    // Browser:    Returns version number for the browser\n    //\n    // iPhone:     iOS 3.2 returns \"3.2\"\n    //\n    // Windows Phone 7: returns current OS version number, ex. el Mango se vuelve 7.10.7720 \n    // Tizen: devuelve \"TIZEN_20120425_2\" \n    var deviceVersion = device.version;\n"
  },
  {
    "path": "plugins/cordova-plugin-device/doc/fr/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-device\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-device.svg?branch=master)](https://travis-ci.org/apache/cordova-plugin-device)\n\nCe plugin définit un global `device` objet qui décrit le matériel et les logiciels de l'appareil. Bien que l'objet est dans la portée globale, il n'est pas disponible jusqu'après la `deviceready` événement.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(device.cordova);\n    }\n    \n\n## Installation\n\n    cordova plugin add cordova-plugin-device\n    \n\n## Propriétés\n\n  * device.cordova\n  * device.model\n  * device.platform\n  * device.uuid\n  * device.version\n\n## device.cordova\n\nRetourne la version de Cordova en cours d'exécution sur l'appareil.\n\n### Plates-formes supportées\n\n  * Amazon Fire OS\n  * Android\n  * BlackBerry 10\n  * Navigateur\n  * Firefox OS\n  * iOS\n  * Paciarelli\n  * Windows Phone 7 et 8\n  * Windows 8\n\n## device.model\n\nL'objet `device.model` retourne le nom du modèle de l'appareil/produit. Cette valeur est définie par le fabricant du périphérique et peut varier entre les différentes versions d'un même produit.\n\n### Plates-formes supportées\n\n  * Android\n  * BlackBerry 10\n  * Navigateur\n  * iOS\n  * Paciarelli\n  * Windows Phone 7 et 8\n  * Windows 8\n\n### Exemple court\n\n    // Android:    Nexus One       returns \"Passion\" (Nexus One code name)\n    //             Motorola Droid  returns \"voles\"\n    // BlackBerry: Torch 9800      returns \"9800\"\n    // Browser:    Google Chrome   returns \"Chrome\"\n    //             Safari          returns \"Safari\"\n    // iOS:     for the iPad Mini, returns iPad2,5; iPhone 5 is iPhone 5,1. Voir http://theiphonewiki.com/wiki/index.php?title=Models\n    //\n    var model = device.model;\n    \n\n### Quirks Android\n\n  * Retourne le [nom du produit](http://developer.android.com/reference/android/os/Build.html#PRODUCT) au lieu du [nom du modèle](http://developer.android.com/reference/android/os/Build.html#MODEL), ce qui équivaut souvent au nom de code de production. Par exemple, `Passion` pour le Nexus One et `voles` pour le Motorola Droid.\n\n### Bizarreries de paciarelli\n\n  * Retourne le modèle du dispositif, assigné par le vendeur, par exemple `TIZEN`\n\n### Notes au sujet de Windows Phone 7 et 8\n\n  * Retourne le modèle de l'appareil spécifié par le fabricant. Par exemple `SGH-i917` pour le Samsung Focus.\n\n## device.platform\n\nObtenir le nom de système d'exploitation de l'appareil.\n\n    var string = device.platform;\n    \n\n### Plates-formes supportées\n\n  * Android\n  * BlackBerry 10\n  * Browser4\n  * Firefox OS\n  * iOS\n  * Paciarelli\n  * Windows Phone 7 et 8\n  * Windows 8\n\n### Exemple court\n\n    // Depending on the device, a few examples are:\n    //   - \"Android\"\n    //   - \"BlackBerry 10\"\n    //   - Browser:         returns \"MacIntel\" on Mac\n    //                      returns \"Win32\" on Windows\n    //   - \"iOS\"\n    //   - \"WinCE\"\n    //   - \"Tizen\"\n    var devicePlatform = device.platform;\n    \n\n### Windows Phone 7 Quirks\n\nAppareils Windows Phone 7 rapport de la plate-forme comme`WinCE`.\n\n### Notes au sujet de Windows Phone 8\n\nAppareils Windows Phone 8 rapport de la plate-forme comme`Win32NT`.\n\n## device.uuid\n\nObtenir Universally Unique Identifier de l'appareil ([UUID](http://en.wikipedia.org/wiki/Universally_Unique_Identifier)).\n\n    var string = device.uuid;\n    \n\n### Description\n\nLes détails de comment un UUID généré sont déterminées par le fabricant du périphérique et sont spécifiques à la plate-forme ou le modèle de l'appareil.\n\n### Plates-formes supportées\n\n  * Android\n  * BlackBerry 10\n  * iOS\n  * Paciarelli\n  * Windows Phone 7 et 8\n  * Windows 8\n\n### Exemple court\n\n    // Android : retourne un nombre entier 64-bit aléatoire (sous la forme d'une chaîne de caractères, encore !)\n    // Ce nombre entier est généré lors du premier démarrage de l'appareil\n    //\n    // BlackBerry : retourne le numéro PIN de l'appareil\n    // Il s'agit d'un nombre entier unique à neuf chiffres (sous la forme d'une chaîne de caractères cependant !)\n    //\n    // iPhone : (copié depuis la documentation de la classe UIDevice)\n    // Retourne une chaîne de caractères générée à partir de plusieurs caractéristiques matérielles.\n    / / Il est garanti pour être unique pour chaque appareil et ne peut pas être lié / / pour le compte d'utilisateur.\n    // Windows Phone 7 : retourne un hashage généré à partir de appareil+utilisateur actuel,\n    // si aucun utilisateur n'est défini, un guid est généré persistera jusqu'à ce que l'application soit désinstallée\n    // Tizen : retourne le numéro IMEI (International Mobile Equipment Identity) de l'appareil, ce numéro est\n    // unique pour chaque téléphone GSM et UMTS.\n    var deviceID = device.uuid;\n    \n\n### Spécificités iOS\n\nLe `uuid` sur iOS n'est pas propre à un périphérique, mais varie pour chaque application, pour chaque installation. Elle change si vous supprimez, puis réinstallez l'application, et éventuellement aussi quand vous mettre à jour d'iOS, ou même mettre à jour le soft par version (apparent dans iOS 5.1). Le `uuid` n'est pas une valeur fiable.\n\n### Notes au sujet de Windows Phone 7 et 8\n\nLe `uuid` pour Windows Phone 7 requiert l'autorisation `ID_CAP_IDENTITY_DEVICE` . Microsoft va probablement bientôt obsolète de cette propriété. Si la capacité n'est pas disponible, l'application génère un guid persistant qui est maintenu pendant toute la durée de l'installation de l'application sur le périphérique.\n\n## device.version\n\nTéléchargez la version de système d'exploitation.\n\n    var string = device.version;\n    \n\n### Plates-formes supportées\n\n  * Android 2.1+\n  * BlackBerry 10\n  * Navigateur\n  * iOS\n  * Paciarelli\n  * Windows Phone 7 et 8\n  * Windows 8\n\n### Exemple court\n\n    // Android:    Froyo OS would return \"2.2\"\n    //             Eclair OS would return \"2.1\", \"2.0.1\", or \"2.0\"\n    //             Version can also return update level \"2.1-update1\"\n    //\n    // BlackBerry: Torch 9800 using OS 6.0 would return \"6.0.0.600\"\n    //\n    // Browser:    Returns version number for the browser\n    //\n    // iPhone:     iOS 3.2 returns \"3.2\"\n    //\n    // Windows Phone 7: returns current OS version number, ex. on Mango returns 7.10.7720\n    // Tizen: returns \"TIZEN_20120425_2\"\n    var deviceVersion = device.version;"
  },
  {
    "path": "plugins/cordova-plugin-device/doc/fr/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-device\n\nCe plugin définit un global `device` objet qui décrit le matériel et les logiciels de l'appareil. Bien que l'objet est dans la portée globale, il n'est pas disponible jusqu'après la `deviceready` événement.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(device.cordova);\n    }\n    \n\n## Installation\n\n    cordova plugin add cordova-plugin-device\n    \n\n## Propriétés\n\n*   device.cordova\n*   device.model\n*   device.platform\n*   device.uuid\n*   device.version\n\n## device.cordova\n\nRetourne la version de Cordova en cours d'exécution sur l'appareil.\n\n### Plates-formes prises en charge\n\n*   Amazon Fire OS\n*   Android\n*   BlackBerry 10\n*   Navigateur\n*   Firefox OS\n*   iOS\n*   Paciarelli\n*   Windows Phone 7 et 8\n*   Windows 8\n\n## device.model\n\nL'objet `device.model` retourne le nom du modèle de l'appareil/produit. Cette valeur est définie par le fabricant du périphérique et peut varier entre les différentes versions d'un même produit.\n\n### Plates-formes prises en charge\n\n*   Android\n*   BlackBerry 10\n*   Navigateur\n*   iOS\n*   Paciarelli\n*   Windows Phone 7 et 8\n*   Windows 8\n\n### Petit exemple\n\n    // Android:    Nexus One       returns \"Passion\" (Nexus One code name)\n    //             Motorola Droid  returns \"voles\"\n    // BlackBerry: Torch 9800      returns \"9800\"\n    // Browser:    Google Chrome   returns \"Chrome\"\n    //             Safari          returns \"Safari\"\n    // iOS:     for the iPad Mini, returns iPad2,5; iPhone 5 is iPhone 5,1. Voir http://theiphonewiki.com/wiki/index.php?title=Models\n    //\n    var model = device.model;\n    \n\n### Quirks Android\n\n*   Retourne le [nom du produit][1] au lieu du [nom du modèle][2], ce qui équivaut souvent au nom de code de production. Par exemple, `Passion` pour le Nexus One et `voles` pour le Motorola Droid.\n\n [1]: http://developer.android.com/reference/android/os/Build.html#PRODUCT\n [2]: http://developer.android.com/reference/android/os/Build.html#MODEL\n\n### Bizarreries de paciarelli\n\n*   Retourne le modèle du dispositif, assigné par le vendeur, par exemple `TIZEN`\n\n### Windows Phone 7 et 8 Quirks\n\n*   Retourne le modèle de l'appareil spécifié par le fabricant. Par exemple `SGH-i917` pour le Samsung Focus.\n\n## device.platform\n\nObtenir le nom de système d'exploitation de l'appareil.\n\n    var string = device.platform;\n    \n\n### Plates-formes prises en charge\n\n*   Android\n*   BlackBerry 10\n*   Browser4\n*   Firefox OS\n*   iOS\n*   Paciarelli\n*   Windows Phone 7 et 8\n*   Windows 8\n\n### Petit exemple\n\n    // Depending on the device, a few examples are:\n    //   - \"Android\"\n    //   - \"BlackBerry 10\"\n    //   - Browser:         returns \"MacIntel\" on Mac\n    //                      returns \"Win32\" on Windows\n    //   - \"iOS\"\n    //   - \"WinCE\"\n    //   - \"Tizen\"\n    var devicePlatform = device.platform;\n    \n\n### Windows Phone 7 Quirks\n\nAppareils Windows Phone 7 rapport de la plate-forme comme`WinCE`.\n\n### Notes au sujet de Windows Phone 8\n\nAppareils Windows Phone 8 rapport de la plate-forme comme`Win32NT`.\n\n## device.uuid\n\nObtenir Universally Unique Identifier de l'appareil ([UUID][3]).\n\n [3]: http://en.wikipedia.org/wiki/Universally_Unique_Identifier\n\n    var string = device.uuid;\n    \n\n### Description\n\nLes détails de comment un UUID généré sont déterminées par le fabricant du périphérique et sont spécifiques à la plate-forme ou le modèle de l'appareil.\n\n### Plates-formes prises en charge\n\n*   Android\n*   BlackBerry 10\n*   iOS\n*   Paciarelli\n*   Windows Phone 7 et 8\n*   Windows 8\n\n### Petit exemple\n\n    // Android : retourne un nombre entier 64-bit aléatoire (sous la forme d'une chaîne de caractères, encore !)\n    // Ce nombre entier est généré lors du premier démarrage de l'appareil\n    //\n    // BlackBerry : retourne le numéro PIN de l'appareil\n    // Il s'agit d'un nombre entier unique à neuf chiffres (sous la forme d'une chaîne de caractères cependant !)\n    //\n    // iPhone : (copié depuis la documentation de la classe UIDevice)\n    // Retourne une chaîne de caractères générée à partir de plusieurs caractéristiques matérielles.\n    / / Il est garanti pour être unique pour chaque appareil et ne peut pas être lié / / pour le compte d'utilisateur.\n    // Windows Phone 7 : retourne un hashage généré à partir de appareil+utilisateur actuel,\n    // si aucun utilisateur n'est défini, un guid est généré persistera jusqu'à ce que l'application soit désinstallée\n    // Tizen : retourne le numéro IMEI (International Mobile Equipment Identity) de l'appareil, ce numéro est\n    // unique pour chaque téléphone GSM et UMTS.\n    var deviceID = device.uuid;\n    \n\n### Spécificités iOS\n\nLe `uuid` sur iOS n'est pas propre à un périphérique, mais varie pour chaque application, pour chaque installation. Elle change si vous supprimez, puis réinstallez l'application, et éventuellement aussi quand vous mettre à jour d'iOS, ou même mettre à jour le soft par version (apparent dans iOS 5.1). Le `uuid` n'est pas une valeur fiable.\n\n### Windows Phone 7 et 8 Quirks\n\nLe `uuid` pour Windows Phone 7 requiert l'autorisation `ID_CAP_IDENTITY_DEVICE` . Microsoft va probablement bientôt obsolète de cette propriété. Si la capacité n'est pas disponible, l'application génère un guid persistant qui est maintenu pendant toute la durée de l'installation de l'application sur le périphérique.\n\n## device.version\n\nTéléchargez la version de système d'exploitation.\n\n    var string = device.version;\n    \n\n### Plates-formes prises en charge\n\n*   Android 2.1+\n*   BlackBerry 10\n*   Navigateur\n*   iOS\n*   Paciarelli\n*   Windows Phone 7 et 8\n*   Windows 8\n\n### Petit exemple\n\n    // Android:    Froyo OS would return \"2.2\"\n    //             Eclair OS would return \"2.1\", \"2.0.1\", or \"2.0\"\n    //             Version can also return update level \"2.1-update1\"\n    //\n    // BlackBerry: Torch 9800 using OS 6.0 would return \"6.0.0.600\"\n    //\n    // Browser:    Returns version number for the browser\n    //\n    // iPhone:     iOS 3.2 returns \"3.2\"\n    //\n    // Windows Phone 7: returns current OS version number, ex. on Mango returns 7.10.7720\n    // Tizen: returns \"TIZEN_20120425_2\"\n    var deviceVersion = device.version;\n"
  },
  {
    "path": "plugins/cordova-plugin-device/doc/it/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-device\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-device.svg?branch=master)](https://travis-ci.org/apache/cordova-plugin-device)\n\nQuesto plugin definisce un global `device` oggetto che descrive il dispositivo hardware e software. Sebbene l'oggetto sia in ambito globale, non è disponibile fino a dopo il `deviceready` evento.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(device.cordova);\n    }\n    \n\n## Installazione\n\n    cordova plugin add cordova-plugin-device\n    \n\n## Proprietà\n\n  * device.cordova\n  * device.model\n  * device.platform\n  * device.uuid\n  * device.version\n\n## device.cordova\n\nOttenere la versione di Cordova in esecuzione nel dispositivo.\n\n### Piattaforme supportate\n\n  * Amazon fuoco OS\n  * Android\n  * BlackBerry 10\n  * Browser\n  * Firefox OS\n  * iOS\n  * Tizen\n  * Windows Phone 7 e 8\n  * Windows 8\n\n## device.model\n\nIl `device.model` restituisce il nome del modello del dispositivo o del prodotto. Il valore viene impostato dal produttore del dispositivo e può essere differente tra le versioni dello stesso prodotto.\n\n### Piattaforme supportate\n\n  * Android\n  * BlackBerry 10\n  * Browser\n  * iOS\n  * Tizen\n  * Windows Phone 7 e 8\n  * Windows 8\n\n### Esempio rapido\n\n    // Android:    Nexus One       returns \"Passion\" (Nexus One code name)\n    //             Motorola Droid  returns \"voles\"\n    // BlackBerry: Torch 9800      returns \"9800\"\n    // Browser:    Google Chrome   returns \"Chrome\"\n    //             Safari          returns \"Safari\"\n    // iOS:     for the iPad Mini, returns iPad2,5; iPhone 5 is iPhone 5,1. Vedi http://theiphonewiki.com/wiki/index.php?title=Models / / modello var = device.model;\n    \n\n### Stranezze Android\n\n  * Ottiene il [nome del prodotto](http://developer.android.com/reference/android/os/Build.html#PRODUCT) anziché il [nome del modello](http://developer.android.com/reference/android/os/Build.html#MODEL), che è spesso il nome di codice di produzione. Ad esempio, restituisce il Nexus One `Passion` , e Motorola Droid restituisce`voles`.\n\n### Tizen stranezze\n\n  * Restituisce il modello di dispositivo assegnato dal fornitore, ad esempio,`TIZEN`\n\n### Windows Phone 7 e 8 stranezze\n\n  * Restituisce il modello di dispositivo specificato dal produttore. Ad esempio, restituisce il Samsung Focus`SGH-i917`.\n\n## device.platform\n\nOttenere il nome del sistema operativo del dispositivo.\n\n    var string = device.platform;\n    \n\n### Piattaforme supportate\n\n  * Android\n  * BlackBerry 10\n  * Browser4\n  * Firefox OS\n  * iOS\n  * Tizen\n  * Windows Phone 7 e 8\n  * Windows 8\n\n### Esempio rapido\n\n    // Depending on the device, a few examples are:\n    //   - \"Android\"\n    //   - \"BlackBerry 10\"\n    //   - Browser:         returns \"MacIntel\" on Mac\n    //                      returns \"Win32\" on Windows\n    //   - \"iOS\"\n    //   - \"WinCE\"\n    //   - \"Tizen\"\n    var devicePlatform = device.platform;\n    \n\n### Windows Phone 7 capricci\n\nWindows Phone 7 dispositivi segnalano la piattaforma come`WinCE`.\n\n### Windows Phone 8 stranezze\n\nDispositivi Windows Phone 8 segnalano la piattaforma come`Win32NT`.\n\n## device.uuid\n\nOttenere identificatore del dispositivo univoco universale ([UUID](http://en.wikipedia.org/wiki/Universally_Unique_Identifier)).\n\n    var string = device.uuid;\n    \n\n### Descrizione\n\nI dettagli di come viene generato un UUID sono determinati dal produttore del dispositivo e sono specifici per la piattaforma o il modello del dispositivo.\n\n### Piattaforme supportate\n\n  * Android\n  * BlackBerry 10\n  * iOS\n  * Tizen\n  * Windows Phone 7 e 8\n  * Windows 8\n\n### Esempio rapido\n\n    / / Android: restituisce un intero casuale di 64 bit (come stringa, ancora una volta!) / / il numero intero è generato al primo avvio del dispositivo / / / / BlackBerry: restituisce il numero PIN del dispositivo / / questo è un valore integer univoco a nove cifre (come stringa, benchè!) / / / / iPhone: (parafrasato dalla documentazione della classe UIDevice) / / restituisce una stringa di valori hash creata dall'hardware più identifica.\n    / / È garantito per essere unica per ogni dispositivo e non può essere legato / / per l'account utente.\n    / / Windows Phone 7: restituisce un hash dell'utente corrente, + dispositivo / / se l'utente non è definito, un guid generato e persisterà fino a quando l'applicazione viene disinstallata / / Tizen: restituisce il dispositivo IMEI (International Mobile Equipment Identity o IMEI è un numero / / unico per ogni cellulare GSM e UMTS.\n    var deviceID = device.uuid;\n    \n\n### iOS Quirk\n\nIl `uuid` su iOS non è univoco per un dispositivo, ma varia per ogni applicazione, per ogni installazione. Cambia se si elimina e re-installare l'app, e possibilmente anche quando aggiornare iOS o anche aggiornare l'app per ogni versione (apparente in iOS 5.1). Il `uuid` non è un valore affidabile.\n\n### Windows Phone 7 e 8 stranezze\n\nIl `uuid` per Windows Phone 7 richiede l'autorizzazione `ID_CAP_IDENTITY_DEVICE` . Microsoft probabilmente sarà presto deprecare questa proprietà. Se la funzionalità non è disponibile, l'applicazione genera un guid persistente che viene mantenuto per la durata dell'installazione dell'applicazione sul dispositivo.\n\n## device.version\n\nOttenere la versione del sistema operativo.\n\n    var string = device.version;\n    \n\n### Piattaforme supportate\n\n  * Android 2.1 +\n  * BlackBerry 10\n  * Browser\n  * iOS\n  * Tizen\n  * Windows Phone 7 e 8\n  * Windows 8\n\n### Esempio rapido\n\n    // Android:    Froyo OS would return \"2.2\"\n    //             Eclair OS would return \"2.1\", \"2.0.1\", or \"2.0\"\n    //             Version can also return update level \"2.1-update1\"\n    //\n    // BlackBerry: Torch 9800 using OS 6.0 would return \"6.0.0.600\"\n    //\n    // Browser:    Returns version number for the browser\n    //\n    // iPhone:     iOS 3.2 returns \"3.2\"\n    //\n    // Windows Phone 7: returns current OS version number, ex. on Mango returns 7.10.7720\n    // Tizen: returns \"TIZEN_20120425_2\"\n    var deviceVersion = device.version;"
  },
  {
    "path": "plugins/cordova-plugin-device/doc/it/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-device\n\nQuesto plugin definisce un global `device` oggetto che descrive il dispositivo hardware e software. Sebbene l'oggetto sia in ambito globale, non è disponibile fino a dopo il `deviceready` evento.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(device.cordova);\n    }\n    \n\n## Installazione\n\n    cordova plugin add cordova-plugin-device\n    \n\n## Proprietà\n\n*   device.cordova\n*   device.model\n*   device.platform\n*   device.uuid\n*   device.version\n\n## device.cordova\n\nOttenere la versione di Cordova in esecuzione nel dispositivo.\n\n### Piattaforme supportate\n\n*   Amazon fuoco OS\n*   Android\n*   BlackBerry 10\n*   Browser\n*   Firefox OS\n*   iOS\n*   Tizen\n*   Windows Phone 7 e 8\n*   Windows 8\n\n## device.model\n\nIl `device.model` restituisce il nome del modello del dispositivo o del prodotto. Il valore viene impostato dal produttore del dispositivo e può essere differente tra le versioni dello stesso prodotto.\n\n### Piattaforme supportate\n\n*   Android\n*   BlackBerry 10\n*   Browser\n*   iOS\n*   Tizen\n*   Windows Phone 7 e 8\n*   Windows 8\n\n### Esempio rapido\n\n    // Android:    Nexus One       returns \"Passion\" (Nexus One code name)\n    //             Motorola Droid  returns \"voles\"\n    // BlackBerry: Torch 9800      returns \"9800\"\n    // Browser:    Google Chrome   returns \"Chrome\"\n    //             Safari          returns \"Safari\"\n    // iOS:     for the iPad Mini, returns iPad2,5; iPhone 5 is iPhone 5,1. Vedi http://theiphonewiki.com/wiki/index.php?title=Models / / modello var = device.model;\n    \n\n### Stranezze Android\n\n*   Ottiene il [nome del prodotto][1] anziché il [nome del modello][2], che è spesso il nome di codice di produzione. Ad esempio, restituisce il Nexus One `Passion` , e Motorola Droid restituisce`voles`.\n\n [1]: http://developer.android.com/reference/android/os/Build.html#PRODUCT\n [2]: http://developer.android.com/reference/android/os/Build.html#MODEL\n\n### Tizen stranezze\n\n*   Restituisce il modello di dispositivo assegnato dal fornitore, ad esempio,`TIZEN`\n\n### Windows Phone 7 e 8 stranezze\n\n*   Restituisce il modello di dispositivo specificato dal produttore. Ad esempio, restituisce il Samsung Focus`SGH-i917`.\n\n## device.platform\n\nOttenere il nome del sistema operativo del dispositivo.\n\n    var string = device.platform;\n    \n\n### Piattaforme supportate\n\n*   Android\n*   BlackBerry 10\n*   Browser4\n*   Firefox OS\n*   iOS\n*   Tizen\n*   Windows Phone 7 e 8\n*   Windows 8\n\n### Esempio rapido\n\n    // Depending on the device, a few examples are:\n    //   - \"Android\"\n    //   - \"BlackBerry 10\"\n    //   - Browser:         returns \"MacIntel\" on Mac\n    //                      returns \"Win32\" on Windows\n    //   - \"iOS\"\n    //   - \"WinCE\"\n    //   - \"Tizen\"\n    var devicePlatform = device.platform;\n    \n\n### Windows Phone 7 capricci\n\nWindows Phone 7 dispositivi segnalano la piattaforma come`WinCE`.\n\n### Windows Phone 8 stranezze\n\nDispositivi Windows Phone 8 segnalano la piattaforma come`Win32NT`.\n\n## device.uuid\n\nOttenere identificatore del dispositivo univoco universale ([UUID][3]).\n\n [3]: http://en.wikipedia.org/wiki/Universally_Unique_Identifier\n\n    var string = device.uuid;\n    \n\n### Descrizione\n\nI dettagli di come viene generato un UUID sono determinati dal produttore del dispositivo e sono specifici per la piattaforma o il modello del dispositivo.\n\n### Piattaforme supportate\n\n*   Android\n*   BlackBerry 10\n*   iOS\n*   Tizen\n*   Windows Phone 7 e 8\n*   Windows 8\n\n### Esempio rapido\n\n    / / Android: restituisce un intero casuale di 64 bit (come stringa, ancora una volta!) / / il numero intero è generato al primo avvio del dispositivo / / / / BlackBerry: restituisce il numero PIN del dispositivo / / questo è un valore integer univoco a nove cifre (come stringa, benchè!) / / / / iPhone: (parafrasato dalla documentazione della classe UIDevice) / / restituisce una stringa di valori hash creata dall'hardware più identifica.\n    / / È garantito per essere unica per ogni dispositivo e non può essere legato / / per l'account utente.\n    / / Windows Phone 7: restituisce un hash dell'utente corrente, + dispositivo / / se l'utente non è definito, un guid generato e persisterà fino a quando l'applicazione viene disinstallata / / Tizen: restituisce il dispositivo IMEI (International Mobile Equipment Identity o IMEI è un numero / / unico per ogni cellulare GSM e UMTS.\n    var deviceID = device.uuid;\n    \n\n### iOS Quirk\n\nIl `uuid` su iOS non è univoco per un dispositivo, ma varia per ogni applicazione, per ogni installazione. Cambia se si elimina e re-installare l'app, e possibilmente anche quando aggiornare iOS o anche aggiornare l'app per ogni versione (apparente in iOS 5.1). Il `uuid` non è un valore affidabile.\n\n### Windows Phone 7 e 8 stranezze\n\nIl `uuid` per Windows Phone 7 richiede l'autorizzazione `ID_CAP_IDENTITY_DEVICE` . Microsoft probabilmente sarà presto deprecare questa proprietà. Se la funzionalità non è disponibile, l'applicazione genera un guid persistente che viene mantenuto per la durata dell'installazione dell'applicazione sul dispositivo.\n\n## device.version\n\nOttenere la versione del sistema operativo.\n\n    var string = device.version;\n    \n\n### Piattaforme supportate\n\n*   Android 2.1 +\n*   BlackBerry 10\n*   Browser\n*   iOS\n*   Tizen\n*   Windows Phone 7 e 8\n*   Windows 8\n\n### Esempio rapido\n\n    // Android:    Froyo OS would return \"2.2\"\n    //             Eclair OS would return \"2.1\", \"2.0.1\", or \"2.0\"\n    //             Version can also return update level \"2.1-update1\"\n    //\n    // BlackBerry: Torch 9800 using OS 6.0 would return \"6.0.0.600\"\n    //\n    // Browser:    Returns version number for the browser\n    //\n    // iPhone:     iOS 3.2 returns \"3.2\"\n    //\n    // Windows Phone 7: returns current OS version number, ex. on Mango returns 7.10.7720\n    // Tizen: returns \"TIZEN_20120425_2\"\n    var deviceVersion = device.version;\n"
  },
  {
    "path": "plugins/cordova-plugin-device/doc/ja/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-device\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-device.svg?branch=master)](https://travis-ci.org/apache/cordova-plugin-device)\n\nこのプラグインをグローバル定義します `device` オブジェクトは、デバイスのハードウェアとソフトウェアについて説明します。 それは後まで利用可能なオブジェクトがグローバル スコープでは、 `deviceready` イベント。\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(device.cordova);\n    }\n    \n\n## インストール\n\n    cordova plugin add cordova-plugin-device\n    \n\n## プロパティ\n\n  * device.cordova\n  * device.model\n  * device.platform\n  * device.uuid\n  * device.version\n\n## device.cordova\n\nデバイスで実行されているコルドバのバージョンを取得します。\n\n### サポートされているプラットフォーム\n\n  * アマゾン火 OS\n  * アンドロイド\n  * ブラックベリー 10\n  * ブラウザー\n  * Firefox の OS\n  * iOS\n  * Tizen\n  * Windows Phone 7 と 8\n  * Windows 8\n\n## device.model\n\n`device.model`、デバイスのモデルまたは製品の名前を返します。値は、デバイスの製造元によって設定され、同じ製品のバージョン間で異なる可能性があります。\n\n### サポートされているプラットフォーム\n\n  * アンドロイド\n  * ブラックベリー 10\n  * ブラウザー\n  * iOS\n  * Tizen\n  * Windows Phone 7 と 8\n  * Windows 8\n\n### 簡単な例\n\n    // Android:    Nexus One       returns \"Passion\" (Nexus One code name)\n    //             Motorola Droid  returns \"voles\"\n    // BlackBerry: Torch 9800      returns \"9800\"\n    // Browser:    Google Chrome   returns \"Chrome\"\n    //             Safari          returns \"Safari\"\n    // iOS:     for the iPad Mini, returns iPad2,5; iPhone 5 is iPhone 5,1. Http://theiphonewiki.com/wiki/index.php?title=Models を参照してください//var モデル = device.model;\n    \n\n### Android の癖\n\n  * 生産コード名は[モデル名](http://developer.android.com/reference/android/os/Build.html#MODEL)の代わりに[製品名](http://developer.android.com/reference/android/os/Build.html#PRODUCT)を取得します。 たとえば、ネクサス 1 つを返します `Passion` 、Motorola のドロイドを返します`voles`.\n\n### Tizen の癖\n\n  * たとえば、ベンダーによって割り当てられているデバイスのモデルを返します`TIZEN`\n\n### Windows Phone 7 と 8 癖\n\n  * 製造元によって指定されたデバイスのモデルを返します。たとえば、三星フォーカスを返します`SGH-i917`.\n\n## device.platform\n\nデバイスのオペレーティング システム名を取得します。\n\n    var string = device.platform;\n    \n\n### サポートされているプラットフォーム\n\n  * アンドロイド\n  * ブラックベリー 10\n  * Browser4\n  * Firefox の OS\n  * iOS\n  * Tizen\n  * Windows Phone 7 と 8\n  * Windows 8\n\n### 簡単な例\n\n    // Depending on the device, a few examples are:\n    //   - \"Android\"\n    //   - \"BlackBerry 10\"\n    //   - Browser:         returns \"MacIntel\" on Mac\n    //                      returns \"Win32\" on Windows\n    //   - \"iOS\"\n    //   - \"WinCE\"\n    //   - \"Tizen\"\n    var devicePlatform = device.platform;\n    \n\n### Windows Phone 7 の癖\n\nWindows Phone 7 デバイスとプラットフォームを報告します。`WinCE`.\n\n### Windows Phone 8 癖\n\nWindows Phone 8 デバイスとプラットフォームを報告します。`Win32NT`.\n\n## device.uuid\n\nデバイスのユニバーサル ・ ユニーク識別子 ([UUID](http://en.wikipedia.org/wiki/Universally_Unique_Identifier)を取得します。).\n\n    var string = device.uuid;\n    \n\n### 解説\n\nUUID を生成する方法の詳細は、デバイスの製造元によって決定され、デバイスのプラットフォームやモデルに固有です。\n\n### サポートされているプラットフォーム\n\n  * アンドロイド\n  * ブラックベリー 10\n  * iOS\n  * Tizen\n  * Windows Phone 7 と 8\n  * Windows 8\n\n### 簡単な例\n\n    //アンドロイド: ランダムな 64 ビットの整数 (を文字列として返します、再び ！）/デバイスの最初の起動時に生成される整数/////ブラックベリー: デバイスのピン番号を返します//これは 9 桁の一意な整数 (を文字列としても ！)////iPhone: (UIDevice クラスのドキュメントから言い換え）//識別複数のハードウェアから作成されたハッシュ値の文字列を返します。。\n    //それはすべてのデバイスに対して一意であることが保証され、接続することはできません//ユーザー アカウント。\n    //Windows Phone 7: デバイス + 現在のユーザーのハッシュを返します//ユーザーが定義されていない場合 guid が生成され、アプリがアンインストールされるまで保持されます//Tizen: デバイスの IMEI を返します （国際モバイル機器アイデンティティまたは IMEI は番号です//すべての GSM および UMTS の携帯電話に固有です。\n    var deviceID = device.uuid;\n    \n\n### iOS の気まぐれ\n\n`uuid`IOS で、デバイスに固有ではないインストールごと、アプリケーションごとに異なります。 削除、アプリを再インストールした場合に変更と多分またときアップグレード iOS の, またはもアップグレードするアプリ (iOS の 5.1 で明らかに） バージョンごと。 `uuid`は信頼性の高い値ではありません。\n\n### Windows Phone 7 と 8 癖\n\n`uuid`のために Windows Phone 7 には、権限が必要です `ID_CAP_IDENTITY_DEVICE` 。 Microsoft はすぐにこのプロパティを廃止して可能性があります。 機能が利用できない場合、アプリケーションはデバイスへのアプリケーションのインストールの持続期間のために保持されている永続的な guid を生成します。\n\n## device.version\n\nオペレーティング システムのバージョンを取得します。\n\n    var string = device.version;\n    \n\n### サポートされているプラットフォーム\n\n  * アンドロイド 2.1 +\n  * ブラックベリー 10\n  * ブラウザー\n  * iOS\n  * Tizen\n  * Windows Phone 7 と 8\n  * Windows 8\n\n### 簡単な例\n\n    // Android:    Froyo OS would return \"2.2\"\n    //             Eclair OS would return \"2.1\", \"2.0.1\", or \"2.0\"\n    //             Version can also return update level \"2.1-update1\"\n    //\n    // BlackBerry: Torch 9800 using OS 6.0 would return \"6.0.0.600\"\n    //\n    // Browser:    Returns version number for the browser\n    //\n    // iPhone:     iOS 3.2 returns \"3.2\"\n    //\n    // Windows Phone 7: returns current OS version number, ex. on Mango returns 7.10.7720\n    // Tizen: returns \"TIZEN_20120425_2\"\n    var deviceVersion = device.version;"
  },
  {
    "path": "plugins/cordova-plugin-device/doc/ja/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-device\n\nこのプラグインをグローバル定義します `device` オブジェクトは、デバイスのハードウェアとソフトウェアについて説明します。 それは後まで利用可能なオブジェクトがグローバル スコープでは、 `deviceready` イベント。\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(device.cordova);\n    }\n    \n\n## インストール\n\n    cordova plugin add cordova-plugin-device\n    \n\n## プロパティ\n\n*   device.cordova\n*   device.model\n*   device.platform\n*   device.uuid\n*   device.version\n\n## device.cordova\n\nデバイスで実行されているコルドバのバージョンを取得します。\n\n### サポートされているプラットフォーム\n\n*   アマゾン火 OS\n*   アンドロイド\n*   ブラックベリー 10\n*   ブラウザー\n*   Firefox の OS\n*   iOS\n*   Tizen\n*   Windows Phone 7 と 8\n*   Windows 8\n\n## device.model\n\n`device.model`、デバイスのモデルまたは製品の名前を返します。値は、デバイスの製造元によって設定され、同じ製品のバージョン間で異なる可能性があります。\n\n### サポートされているプラットフォーム\n\n*   アンドロイド\n*   ブラックベリー 10\n*   ブラウザー\n*   iOS\n*   Tizen\n*   Windows Phone 7 と 8\n*   Windows 8\n\n### 簡単な例\n\n    // Android:    Nexus One       returns \"Passion\" (Nexus One code name)\n    //             Motorola Droid  returns \"voles\"\n    // BlackBerry: Torch 9800      returns \"9800\"\n    // Browser:    Google Chrome   returns \"Chrome\"\n    //             Safari          returns \"Safari\"\n    // iOS:     for the iPad Mini, returns iPad2,5; iPhone 5 is iPhone 5,1. Http://theiphonewiki.com/wiki/index.php?title=Models を参照してください//var モデル = device.model;\n    \n\n### Android の癖\n\n*   生産コード名は[モデル名][1]の代わりに[製品名][2]を取得します。 たとえば、ネクサス 1 つを返します `Passion` 、Motorola のドロイドを返します`voles`.\n\n [1]: http://developer.android.com/reference/android/os/Build.html#MODEL\n [2]: http://developer.android.com/reference/android/os/Build.html#PRODUCT\n\n### Tizen の癖\n\n*   たとえば、ベンダーによって割り当てられているデバイスのモデルを返します`TIZEN`\n\n### Windows Phone 7 と 8 癖\n\n*   製造元によって指定されたデバイスのモデルを返します。たとえば、三星フォーカスを返します`SGH-i917`.\n\n## device.platform\n\nデバイスのオペレーティング システム名を取得します。\n\n    var string = device.platform;\n    \n\n### サポートされているプラットフォーム\n\n*   アンドロイド\n*   ブラックベリー 10\n*   Browser4\n*   Firefox の OS\n*   iOS\n*   Tizen\n*   Windows Phone 7 と 8\n*   Windows 8\n\n### 簡単な例\n\n    // Depending on the device, a few examples are:\n    //   - \"Android\"\n    //   - \"BlackBerry 10\"\n    //   - Browser:         returns \"MacIntel\" on Mac\n    //                      returns \"Win32\" on Windows\n    //   - \"iOS\"\n    //   - \"WinCE\"\n    //   - \"Tizen\"\n    var devicePlatform = device.platform;\n    \n\n### Windows Phone 7 の癖\n\nWindows Phone 7 デバイスとプラットフォームを報告します。`WinCE`.\n\n### Windows Phone 8 癖\n\nWindows Phone 8 デバイスとプラットフォームを報告します。`Win32NT`.\n\n## device.uuid\n\nデバイスのユニバーサル ・ ユニーク識別子 ([UUID][3]を取得します。).\n\n [3]: http://en.wikipedia.org/wiki/Universally_Unique_Identifier\n\n    var string = device.uuid;\n    \n\n### 説明\n\nUUID を生成する方法の詳細は、デバイスの製造元によって決定され、デバイスのプラットフォームやモデルに固有です。\n\n### サポートされているプラットフォーム\n\n*   アンドロイド\n*   ブラックベリー 10\n*   iOS\n*   Tizen\n*   Windows Phone 7 と 8\n*   Windows 8\n\n### 簡単な例\n\n    //アンドロイド: ランダムな 64 ビットの整数 (を文字列として返します、再び ！）/デバイスの最初の起動時に生成される整数/////ブラックベリー: デバイスのピン番号を返します//これは 9 桁の一意な整数 (を文字列としても ！)////iPhone: (UIDevice クラスのドキュメントから言い換え）//識別複数のハードウェアから作成されたハッシュ値の文字列を返します。。\n    //それはすべてのデバイスに対して一意であることが保証され、接続することはできません//ユーザー アカウント。\n    //Windows Phone 7: デバイス + 現在のユーザーのハッシュを返します//ユーザーが定義されていない場合 guid が生成され、アプリがアンインストールされるまで保持されます//Tizen: デバイスの IMEI を返します （国際モバイル機器アイデンティティまたは IMEI は番号です//すべての GSM および UMTS の携帯電話に固有です。\n    var deviceID = device.uuid;\n    \n\n### iOS の気まぐれ\n\n`uuid`IOS で、デバイスに固有ではないインストールごと、アプリケーションごとに異なります。 削除、アプリを再インストールした場合に変更と多分またときアップグレード iOS の, またはもアップグレードするアプリ (iOS の 5.1 で明らかに） バージョンごと。 `uuid`は信頼性の高い値ではありません。\n\n### Windows Phone 7 と 8 癖\n\n`uuid`のために Windows Phone 7 には、権限が必要です `ID_CAP_IDENTITY_DEVICE` 。 Microsoft はすぐにこのプロパティを廃止して可能性があります。 機能が利用できない場合、アプリケーションはデバイスへのアプリケーションのインストールの持続期間のために保持されている永続的な guid を生成します。\n\n## device.version\n\nオペレーティング システムのバージョンを取得します。\n\n    var string = device.version;\n    \n\n### サポートされているプラットフォーム\n\n*   アンドロイド 2.1 +\n*   ブラックベリー 10\n*   ブラウザー\n*   iOS\n*   Tizen\n*   Windows Phone 7 と 8\n*   Windows 8\n\n### 簡単な例\n\n    // Android:    Froyo OS would return \"2.2\"\n    //             Eclair OS would return \"2.1\", \"2.0.1\", or \"2.0\"\n    //             Version can also return update level \"2.1-update1\"\n    //\n    // BlackBerry: Torch 9800 using OS 6.0 would return \"6.0.0.600\"\n    //\n    // Browser:    Returns version number for the browser\n    //\n    // iPhone:     iOS 3.2 returns \"3.2\"\n    //\n    // Windows Phone 7: returns current OS version number, ex. on Mango returns 7.10.7720\n    // Tizen: returns \"TIZEN_20120425_2\"\n    var deviceVersion = device.version;\n"
  },
  {
    "path": "plugins/cordova-plugin-device/doc/ko/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-device\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-device.svg?branch=master)](https://travis-ci.org/apache/cordova-plugin-device)\n\n이 플러그인 정의 전역 `device` 개체, 디바이스의 하드웨어 및 소프트웨어에 설명 합니다. 개체는 전역 범위에서 비록 그것은 후까지 사용할 수 있는 `deviceready` 이벤트.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(device.cordova);\n    }\n    \n\n## 설치\n\n    cordova plugin add cordova-plugin-device\n    \n\n## 속성\n\n  * device.cordova\n  * device.model\n  * device.platform\n  * device.uuid\n  * device.version\n\n## device.cordova\n\n코르도바는 장치에서 실행 중인 버전을 얻을.\n\n### 지원 되는 플랫폼\n\n  * 아마존 화재 운영 체제\n  * 안 드 로이드\n  * 블랙베리 10\n  * 브라우저\n  * Firefox 운영 체제\n  * iOS\n  * Tizen\n  * Windows Phone 7과 8\n  * 윈도우 8\n\n## device.model\n\n`device.model`소자의 모델 또는 제품의 이름을 반환 합니다. 값 장치 제조업체에서 설정 되 고 동일 제품의 버전 간에 다를 수 있습니다.\n\n### 지원 되는 플랫폼\n\n  * 안 드 로이드\n  * 블랙베리 10\n  * 브라우저\n  * iOS\n  * Tizen\n  * Windows Phone 7과 8\n  * 윈도우 8\n\n### 빠른 예제\n\n    // Android:    Nexus One       returns \"Passion\" (Nexus One code name)\n    //             Motorola Droid  returns \"voles\"\n    // BlackBerry: Torch 9800      returns \"9800\"\n    // Browser:    Google Chrome   returns \"Chrome\"\n    //             Safari          returns \"Safari\"\n    // iOS:     for the iPad Mini, returns iPad2,5; iPhone 5 is iPhone 5,1. Http://theiphonewiki.com/wiki/index.php?title=Models 참조 / / var 모델 = device.model;\n    \n\n### 안 드 로이드 단점\n\n  * 어떤은 종종 프로덕션 코드 이름 대신 [제품 모델 이름](http://developer.android.com/reference/android/os/Build.html#MODEL), [제품 이름](http://developer.android.com/reference/android/os/Build.html#PRODUCT) 을 가져옵니다. 예를 들어 넥서스 하나 반환 합니다 `Passion` , 모토로라 Droid를 반환 합니다`voles`.\n\n### Tizen 특수\n\n  * 예를 들어, 공급 업체에 의해 할당 된 디바이스 모델을 반환 합니다.`TIZEN`\n\n### Windows Phone 7, 8 특수\n\n  * 제조업체에서 지정 하는 장치 모델을 반환 합니다. 예를 들어 삼성 포커스를 반환 합니다.`SGH-i917`.\n\n## device.platform\n\n장치의 운영 체제 이름을 얻을.\n\n    var string = device.platform;\n    \n\n### 지원 되는 플랫폼\n\n  * 안 드 로이드\n  * 블랙베리 10\n  * Browser4\n  * Firefox 운영 체제\n  * iOS\n  * Tizen\n  * Windows Phone 7과 8\n  * 윈도우 8\n\n### 빠른 예제\n\n    // Depending on the device, a few examples are:\n    //   - \"Android\"\n    //   - \"BlackBerry 10\"\n    //   - Browser:         returns \"MacIntel\" on Mac\n    //                      returns \"Win32\" on Windows\n    //   - \"iOS\"\n    //   - \"WinCE\"\n    //   - \"Tizen\"\n    var devicePlatform = device.platform;\n    \n\n### Windows Phone 7 단점\n\nWindows Phone 7 장치 보고 플랫폼으로`WinCE`.\n\n### Windows Phone 8 단점\n\nWindows Phone 8 장치 보고 플랫폼으로`Win32NT`.\n\n## device.uuid\n\n소자의 보편적으로 고유 식별자 ([UUID](http://en.wikipedia.org/wiki/Universally_Unique_Identifier) 를 얻을합니다).\n\n    var string = device.uuid;\n    \n\n### 설명\n\nUUID 생성 방법의 자세한 내용은 장치 제조업체에 의해 결정 됩니다 및 소자의 플랫폼 이나 모델.\n\n### 지원 되는 플랫폼\n\n  * 안 드 로이드\n  * 블랙베리 10\n  * iOS\n  * Tizen\n  * Windows Phone 7과 8\n  * 윈도우 8\n\n### 빠른 예제\n\n    / / 안 드 로이드: (문자열로 다시!) 임의의 64 비트 정수를 반환 합니다 / / 정수 장치의 첫 번째 부팅에서 생성 / / / / 블랙베리: 디바이스의 핀 번호를 반환 합니다 / / 이것은 9 자리 고유 정수 (문자열로 비록!) / / / / 아이폰: (UIDevice 클래스 설명서에서 읊 었) / / 문자열 여러 하드웨어에서 생성 하는 해시 값을 식별 하는 반환 합니다.\n    / 그것은 모든 장치에 대 한 고유 해야 보장 되 고 묶일 수 없습니다 / / / 사용자 계정에.\n    / / Windows Phone 7: 장치 + 현재 사용자의 해시를 반환 합니다 / / 사용자 정의 되지 않은 경우 guid 생성 되 고 응용 프로그램을 제거할 때까지 유지 됩니다 / / Tizen: 반환 장치 IMEI (국제 모바일 기기 식별 또는 IMEI 숫자입니다 / / 모든 GSM와 UMTS 휴대 전화 고유.\n    var deviceID = device.uuid;\n    \n\n### iOS 특질\n\n`uuid`ios 장치에 고유 하지 않습니다 하지만 각 설치에 대 한 응용 프로그램 마다 다릅니다. 삭제 하 고 다시 애플 리 케이 션을 설치 하는 경우 변경 가능 하 게 또한 iOS를 업그레이드 하거나 때 버전 (iOS 5.1에에서 명백한) 당 응용 프로그램 업그레이드도 하 고. `uuid`은 신뢰할 수 있는 값이 아닙니다.\n\n### Windows Phone 7, 8 특수\n\n`uuid`Windows Phone 7 필요 허가 `ID_CAP_IDENTITY_DEVICE` . Microsoft는 곧이 속성을 세웁니다 가능성이 것입니다. 기능을 사용할 수 없는 경우 응용 프로그램 장치에 응용 프로그램의 설치 하는 동안 유지 하는 영구 guid를 생성 합니다.\n\n## device.version\n\n운영 체제 버전을 얻을.\n\n    var string = device.version;\n    \n\n### 지원 되는 플랫폼\n\n  * 안 드 로이드 2.1 +\n  * 블랙베리 10\n  * 브라우저\n  * iOS\n  * Tizen\n  * Windows Phone 7과 8\n  * 윈도우 8\n\n### 빠른 예제\n\n    // Android:    Froyo OS would return \"2.2\"\n    //             Eclair OS would return \"2.1\", \"2.0.1\", or \"2.0\"\n    //             Version can also return update level \"2.1-update1\"\n    //\n    // BlackBerry: Torch 9800 using OS 6.0 would return \"6.0.0.600\"\n    //\n    // Browser:    Returns version number for the browser\n    //\n    // iPhone:     iOS 3.2 returns \"3.2\"\n    //\n    // Windows Phone 7: returns current OS version number, ex. on Mango returns 7.10.7720\n    // Tizen: returns \"TIZEN_20120425_2\"\n    var deviceVersion = device.version;"
  },
  {
    "path": "plugins/cordova-plugin-device/doc/ko/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-device\n\n이 플러그인 정의 전역 `device` 개체, 디바이스의 하드웨어 및 소프트웨어에 설명 합니다. 개체는 전역 범위에서 비록 그것은 후까지 사용할 수 있는 `deviceready` 이벤트.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(device.cordova);\n    }\n    \n\n## 설치\n\n    cordova plugin add cordova-plugin-device\n    \n\n## 속성\n\n*   device.cordova\n*   device.model\n*   device.platform\n*   device.uuid\n*   device.version\n\n## device.cordova\n\n코르도바는 장치에서 실행 중인 버전을 얻을.\n\n### 지원 되는 플랫폼\n\n*   아마존 화재 운영 체제\n*   안 드 로이드\n*   블랙베리 10\n*   브라우저\n*   Firefox 운영 체제\n*   iOS\n*   Tizen\n*   Windows Phone 7과 8\n*   윈도우 8\n\n## device.model\n\n`device.model`소자의 모델 또는 제품의 이름을 반환 합니다. 값 장치 제조업체에서 설정 되 고 동일 제품의 버전 간에 다를 수 있습니다.\n\n### 지원 되는 플랫폼\n\n*   안 드 로이드\n*   블랙베리 10\n*   브라우저\n*   iOS\n*   Tizen\n*   Windows Phone 7과 8\n*   윈도우 8\n\n### 빠른 예제\n\n    // Android:    Nexus One       returns \"Passion\" (Nexus One code name)\n    //             Motorola Droid  returns \"voles\"\n    // BlackBerry: Torch 9800      returns \"9800\"\n    // Browser:    Google Chrome   returns \"Chrome\"\n    //             Safari          returns \"Safari\"\n    // iOS:     for the iPad Mini, returns iPad2,5; iPhone 5 is iPhone 5,1. Http://theiphonewiki.com/wiki/index.php?title=Models 참조 / / var 모델 = device.model;\n    \n\n### 안 드 로이드 단점\n\n*   어떤은 종종 프로덕션 코드 이름 대신 [제품 모델 이름][1], [제품 이름][2] 을 가져옵니다. 예를 들어 넥서스 하나 반환 합니다 `Passion` , 모토로라 Droid를 반환 합니다`voles`.\n\n [1]: http://developer.android.com/reference/android/os/Build.html#MODEL\n [2]: http://developer.android.com/reference/android/os/Build.html#PRODUCT\n\n### Tizen 특수\n\n*   예를 들어, 공급 업체에 의해 할당 된 디바이스 모델을 반환 합니다.`TIZEN`\n\n### Windows Phone 7, 8 특수\n\n*   제조업체에서 지정 하는 장치 모델을 반환 합니다. 예를 들어 삼성 포커스를 반환 합니다.`SGH-i917`.\n\n## device.platform\n\n장치의 운영 체제 이름을 얻을.\n\n    var string = device.platform;\n    \n\n### 지원 되는 플랫폼\n\n*   안 드 로이드\n*   블랙베리 10\n*   Browser4\n*   Firefox 운영 체제\n*   iOS\n*   Tizen\n*   Windows Phone 7과 8\n*   윈도우 8\n\n### 빠른 예제\n\n    // Depending on the device, a few examples are:\n    //   - \"Android\"\n    //   - \"BlackBerry 10\"\n    //   - Browser:         returns \"MacIntel\" on Mac\n    //                      returns \"Win32\" on Windows\n    //   - \"iOS\"\n    //   - \"WinCE\"\n    //   - \"Tizen\"\n    var devicePlatform = device.platform;\n    \n\n### Windows Phone 7 단점\n\nWindows Phone 7 장치 보고 플랫폼으로`WinCE`.\n\n### Windows Phone 8 단점\n\nWindows Phone 8 장치 보고 플랫폼으로`Win32NT`.\n\n## device.uuid\n\n소자의 보편적으로 고유 식별자 ([UUID][3] 를 얻을합니다).\n\n [3]: http://en.wikipedia.org/wiki/Universally_Unique_Identifier\n\n    var string = device.uuid;\n    \n\n### 설명\n\nUUID 생성 방법의 자세한 내용은 장치 제조업체에 의해 결정 됩니다 및 소자의 플랫폼 이나 모델.\n\n### 지원 되는 플랫폼\n\n*   안 드 로이드\n*   블랙베리 10\n*   iOS\n*   Tizen\n*   Windows Phone 7과 8\n*   윈도우 8\n\n### 빠른 예제\n\n    / / 안 드 로이드: (문자열로 다시!) 임의의 64 비트 정수를 반환 합니다 / / 정수 장치의 첫 번째 부팅에서 생성 / / / / 블랙베리: 디바이스의 핀 번호를 반환 합니다 / / 이것은 9 자리 고유 정수 (문자열로 비록!) / / / / 아이폰: (UIDevice 클래스 설명서에서 읊 었) / / 문자열 여러 하드웨어에서 생성 하는 해시 값을 식별 하는 반환 합니다.\n    / 그것은 모든 장치에 대 한 고유 해야 보장 되 고 묶일 수 없습니다 / / / 사용자 계정에.\n    / / Windows Phone 7: 장치 + 현재 사용자의 해시를 반환 합니다 / / 사용자 정의 되지 않은 경우 guid 생성 되 고 응용 프로그램을 제거할 때까지 유지 됩니다 / / Tizen: 반환 장치 IMEI (국제 모바일 기기 식별 또는 IMEI 숫자입니다 / / 모든 GSM와 UMTS 휴대 전화 고유.\n    var deviceID = device.uuid;\n    \n\n### iOS 특질\n\n`uuid`ios 장치에 고유 하지 않습니다 하지만 각 설치에 대 한 응용 프로그램 마다 다릅니다. 삭제 하 고 다시 애플 리 케이 션을 설치 하는 경우 변경 가능 하 게 또한 iOS를 업그레이드 하거나 때 버전 (iOS 5.1에에서 명백한) 당 응용 프로그램 업그레이드도 하 고. `uuid`은 신뢰할 수 있는 값이 아닙니다.\n\n### Windows Phone 7, 8 특수\n\n`uuid`Windows Phone 7 필요 허가 `ID_CAP_IDENTITY_DEVICE` . Microsoft는 곧이 속성을 세웁니다 가능성이 것입니다. 기능을 사용할 수 없는 경우 응용 프로그램 장치에 응용 프로그램의 설치 하는 동안 유지 하는 영구 guid를 생성 합니다.\n\n## device.version\n\n운영 체제 버전을 얻을.\n\n    var string = device.version;\n    \n\n### 지원 되는 플랫폼\n\n*   안 드 로이드 2.1 +\n*   블랙베리 10\n*   브라우저\n*   iOS\n*   Tizen\n*   Windows Phone 7과 8\n*   윈도우 8\n\n### 빠른 예제\n\n    // Android:    Froyo OS would return \"2.2\"\n    //             Eclair OS would return \"2.1\", \"2.0.1\", or \"2.0\"\n    //             Version can also return update level \"2.1-update1\"\n    //\n    // BlackBerry: Torch 9800 using OS 6.0 would return \"6.0.0.600\"\n    //\n    // Browser:    Returns version number for the browser\n    //\n    // iPhone:     iOS 3.2 returns \"3.2\"\n    //\n    // Windows Phone 7: returns current OS version number, ex. on Mango returns 7.10.7720\n    // Tizen: returns \"TIZEN_20120425_2\"\n    var deviceVersion = device.version;\n"
  },
  {
    "path": "plugins/cordova-plugin-device/doc/pl/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-device\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-device.svg?branch=master)](https://travis-ci.org/apache/cordova-plugin-device)\n\nTen plugin określa globalne `device` obiekt, który opisuje urządzenia sprzętowe i programowe. Mimo, że obiekt jest w globalnym zasięgu, nie jest dostępne dopiero po `deviceready` zdarzenie.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(device.cordova);\n    }\n    \n\n## Instalacja\n\n    cordova plugin add cordova-plugin-device\n    \n\n## Właściwości\n\n  * device.cordova\n  * device.model\n  * device.platform\n  * device.uuid\n  * device.version\n\n## device.cordova\n\nPobierz wersję Cordova działa na urządzeniu.\n\n### Obsługiwane platformy\n\n  * Amazon Fire OS\n  * Android\n  * BlackBerry 10\n  * Przeglądarka\n  * Firefox OS\n  * iOS\n  * Tizen\n  * Windows Phone 7 i 8\n  * Windows 8\n\n## device.model\n\n`device.model`Zwraca nazwę modelu lub produktu. Wartość jest zestaw przez producenta urządzenia i mogą się różnić między wersjami tego samego produktu.\n\n### Obsługiwane platformy\n\n  * Android\n  * BlackBerry 10\n  * Przeglądarka\n  * iOS\n  * Tizen\n  * Windows Phone 7 i 8\n  * Windows 8\n\n### Szybki przykład\n\n    // Android:    Nexus One       returns \"Passion\" (Nexus One code name)\n    //             Motorola Droid  returns \"voles\"\n    // BlackBerry: Torch 9800      returns \"9800\"\n    // Browser:    Google Chrome   returns \"Chrome\"\n    //             Safari          returns \"Safari\"\n    // iOS:     for the iPad Mini, returns iPad2,5; iPhone 5 is iPhone 5,1. Zobacz http://theiphonewiki.com/wiki/index.php?title=Models / / modelu var = device.model;\n    \n\n### Dziwactwa Androida\n\n  * Pobiera [nazwę produktu](http://developer.android.com/reference/android/os/Build.html#PRODUCT) zamiast [nazwy modelu](http://developer.android.com/reference/android/os/Build.html#MODEL), który często jest nazwą kod produkcji. Na przykład, Nexus One zwraca `Passion` , i zwraca Motorola Droid`voles`.\n\n### Dziwactwa Tizen\n\n  * Zwraca modelu urządzenia przypisane przez dostawcę, na przykład,`TIZEN`\n\n### Windows Phone 7 i 8 dziwactwa\n\n  * Zwraca modelu urządzenia, określonej przez producenta. Na przykład Samsung ostrości zwraca`SGH-i917`.\n\n## device.platform\n\nUzyskać nazwę systemu operacyjnego urządzenia.\n\n    var string = device.platform;\n    \n\n### Obsługiwane platformy\n\n  * Android\n  * BlackBerry 10\n  * Browser4\n  * Firefox OS\n  * iOS\n  * Tizen\n  * Windows Phone 7 i 8\n  * Windows 8\n\n### Szybki przykład\n\n    // Depending on the device, a few examples are:\n    //   - \"Android\"\n    //   - \"BlackBerry 10\"\n    //   - Browser:         returns \"MacIntel\" on Mac\n    //                      returns \"Win32\" on Windows\n    //   - \"iOS\"\n    //   - \"WinCE\"\n    //   - \"Tizen\"\n    var devicePlatform = device.platform;\n    \n\n### Dziwactwa Windows Phone 7\n\nUrządzenia Windows Phone 7 raport platformy jako`WinCE`.\n\n### Windows Phone 8 dziwactwa\n\nUrządzenia Windows Phone 8 raport platformy jako`Win32NT`.\n\n## device.uuid\n\nSię urządzenia uniwersalnie unikatowy identyfikator ([UUID](http://en.wikipedia.org/wiki/Universally_Unique_Identifier)).\n\n    var string = device.uuid;\n    \n\n### Opis\n\nSzczegóły jak UUID jest generowane są określane przez producenta urządzenia i są specyficzne dla platformy lub modelu urządzenia.\n\n### Obsługiwane platformy\n\n  * Android\n  * BlackBerry 10\n  * iOS\n  * Tizen\n  * Windows Phone 7 i 8\n  * Windows 8\n\n### Szybki przykład\n\n    // Android: Returns a random 64-bit integer (as a string, again!)\n    //          The integer is generated on the device's first boot\n    //\n    // BlackBerry: Returns the PIN number of the device\n    //             This is a nine-digit unique integer (as a string, though!)\n    //\n    // iPhone: (Paraphrased from the UIDevice Class documentation)\n    //         Returns a string of hash values created from multiple hardware identifies.\n    //         It is guaranteed to be unique for every device and can't be tied\n    //         to the user account.\n    // Windows Phone 7 : Returns a hash of device+current user,\n    // if the user is not defined, a guid is generated and will persist until the app is uninstalled\n    // Tizen: returns the device IMEI (International Mobile Equipment Identity or IMEI is a number\n    // unique to every GSM and UMTS mobile phone.\n    var deviceID = device.uuid;\n    \n\n### iOS dziwactwo\n\n`uuid`Na iOS nie jest przypisany do urządzenia, ale różni się dla każdej aplikacji, dla każdej instalacji. Zmienia się jeśli możesz usunąć i ponownie zainstalować aplikację, a ewentualnie także po aktualizacji iOS czy nawet uaktualnienia aplikacji dla wersji (widoczny w iOS 5.1). `uuid`Jest nie wiarygodne wartości.\n\n### Windows Phone 7 i 8 dziwactwa\n\n`uuid`Dla Windows Phone 7 wymaga uprawnień `ID_CAP_IDENTITY_DEVICE` . Microsoft będzie prawdopodobnie potępiać ten wkrótce. Jeśli funkcja nie jest dostępna, aplikacja generuje trwałe identyfikator guid, który jest utrzymywany przez czas trwania instalacji aplikacji na urządzeniu.\n\n## device.version\n\nPobierz wersję systemu operacyjnego.\n\n    var string = device.version;\n    \n\n### Obsługiwane platformy\n\n  * Android 2.1 +\n  * BlackBerry 10\n  * Przeglądarka\n  * iOS\n  * Tizen\n  * Windows Phone 7 i 8\n  * Windows 8\n\n### Szybki przykład\n\n    // Android:    Froyo OS would return \"2.2\"\n    //             Eclair OS would return \"2.1\", \"2.0.1\", or \"2.0\"\n    //             Version can also return update level \"2.1-update1\"\n    //\n    // BlackBerry: Torch 9800 using OS 6.0 would return \"6.0.0.600\"\n    //\n    // Browser:    Returns version number for the browser\n    //\n    // iPhone:     iOS 3.2 returns \"3.2\"\n    //\n    // Windows Phone 7: returns current OS version number, ex. on Mango returns 7.10.7720\n    // Tizen: returns \"TIZEN_20120425_2\"\n    var deviceVersion = device.version;"
  },
  {
    "path": "plugins/cordova-plugin-device/doc/pl/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-device\n\nTen plugin określa globalne `device` obiekt, który opisuje urządzenia sprzętowe i programowe. Mimo, że obiekt jest w globalnym zasięgu, nie jest dostępne dopiero po `deviceready` zdarzenie.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(device.cordova);\n    }\n    \n\n## Instalacja\n\n    cordova plugin add cordova-plugin-device\n    \n\n## Właściwości\n\n*   device.cordova\n*   device.model\n*   device.platform\n*   device.uuid\n*   device.version\n\n## device.cordova\n\nPobierz wersję Cordova działa na urządzeniu.\n\n### Obsługiwane platformy\n\n*   Amazon Fire OS\n*   Android\n*   BlackBerry 10\n*   Przeglądarka\n*   Firefox OS\n*   iOS\n*   Tizen\n*   Windows Phone 7 i 8\n*   Windows 8\n\n## device.model\n\n`device.model`Zwraca nazwę modelu lub produktu. Wartość jest zestaw przez producenta urządzenia i mogą się różnić między wersjami tego samego produktu.\n\n### Obsługiwane platformy\n\n*   Android\n*   BlackBerry 10\n*   Przeglądarka\n*   iOS\n*   Tizen\n*   Windows Phone 7 i 8\n*   Windows 8\n\n### Szybki przykład\n\n    // Android:    Nexus One       returns \"Passion\" (Nexus One code name)\n    //             Motorola Droid  returns \"voles\"\n    // BlackBerry: Torch 9800      returns \"9800\"\n    // Browser:    Google Chrome   returns \"Chrome\"\n    //             Safari          returns \"Safari\"\n    // iOS:     for the iPad Mini, returns iPad2,5; iPhone 5 is iPhone 5,1. Zobacz http://theiphonewiki.com/wiki/index.php?title=Models / / modelu var = device.model;\n    \n\n### Dziwactwa Androida\n\n*   Pobiera [nazwę produktu][1] zamiast [nazwy modelu][2], który często jest nazwą kod produkcji. Na przykład, Nexus One zwraca `Passion` , i zwraca Motorola Droid`voles`.\n\n [1]: http://developer.android.com/reference/android/os/Build.html#PRODUCT\n [2]: http://developer.android.com/reference/android/os/Build.html#MODEL\n\n### Dziwactwa Tizen\n\n*   Zwraca modelu urządzenia przypisane przez dostawcę, na przykład,`TIZEN`\n\n### Windows Phone 7 i 8 dziwactwa\n\n*   Zwraca modelu urządzenia, określonej przez producenta. Na przykład Samsung ostrości zwraca`SGH-i917`.\n\n## device.platform\n\nUzyskać nazwę systemu operacyjnego urządzenia.\n\n    var string = device.platform;\n    \n\n### Obsługiwane platformy\n\n*   Android\n*   BlackBerry 10\n*   Browser4\n*   Firefox OS\n*   iOS\n*   Tizen\n*   Windows Phone 7 i 8\n*   Windows 8\n\n### Szybki przykład\n\n    // Depending on the device, a few examples are:\n    //   - \"Android\"\n    //   - \"BlackBerry 10\"\n    //   - Browser:         returns \"MacIntel\" on Mac\n    //                      returns \"Win32\" on Windows\n    //   - \"iOS\"\n    //   - \"WinCE\"\n    //   - \"Tizen\"\n    var devicePlatform = device.platform;\n    \n\n### Dziwactwa Windows Phone 7\n\nUrządzenia Windows Phone 7 raport platformy jako`WinCE`.\n\n### Windows Phone 8 dziwactwa\n\nUrządzenia Windows Phone 8 raport platformy jako`Win32NT`.\n\n## device.uuid\n\nSię urządzenia uniwersalnie unikatowy identyfikator ([UUID][3]).\n\n [3]: http://en.wikipedia.org/wiki/Universally_Unique_Identifier\n\n    var string = device.uuid;\n    \n\n### Opis\n\nSzczegóły jak UUID jest generowane są określane przez producenta urządzenia i są specyficzne dla platformy lub modelu urządzenia.\n\n### Obsługiwane platformy\n\n*   Android\n*   BlackBerry 10\n*   iOS\n*   Tizen\n*   Windows Phone 7 i 8\n*   Windows 8\n\n### Szybki przykład\n\n    / / Android: zwraca losowe 64-bitowa liczba całkowita (jako ciąg, znowu!) / / liczba całkowita jest generowany na pierwszego uruchomienia urządzenia / / / / BlackBerry: zwraca numer PIN urządzenia / / to jest unikatową liczbą całkowitą dziewięciu cyfr (jako ciąg, choć!) / / / / iPhone: (zacytowana w dokumentacji klasy UIDevice) / / zwraca ciąg wartości mieszania utworzone z wielu sprzętu identyfikuje.\n    Zapewniona jest unikatowy dla każdego urządzenia i nie może być związane z / do konta użytkownika.\n    / / Windows Phone 7: zwraca wartość mieszania urządzenia + bieżący użytkownik, / / jeśli nie zdefiniowane przez użytkownika, identyfikator guid jest generowany i będzie trwać do czasu odinstalowania aplikacji / / Tizen: zwraca urządzenia IMEI (International Mobile Equipment Identity lub IMEI jest liczbą / / unikatowe dla każdego telefonu komórkowego GSM i UMTS.\n    var deviceID = device.uuid;\n    \n\n### iOS dziwactwo\n\n`uuid`Na iOS nie jest przypisany do urządzenia, ale różni się dla każdej aplikacji, dla każdej instalacji. Zmienia się jeśli możesz usunąć i ponownie zainstalować aplikację, a ewentualnie także po aktualizacji iOS czy nawet uaktualnienia aplikacji dla wersji (widoczny w iOS 5.1). `uuid`Jest nie wiarygodne wartości.\n\n### Windows Phone 7 i 8 dziwactwa\n\n`uuid`Dla Windows Phone 7 wymaga uprawnień `ID_CAP_IDENTITY_DEVICE` . Microsoft będzie prawdopodobnie potępiać ten wkrótce. Jeśli funkcja nie jest dostępna, aplikacja generuje trwałe identyfikator guid, który jest utrzymywany przez czas trwania instalacji aplikacji na urządzeniu.\n\n## device.version\n\nPobierz wersję systemu operacyjnego.\n\n    var string = device.version;\n    \n\n### Obsługiwane platformy\n\n*   Android 2.1 +\n*   BlackBerry 10\n*   Przeglądarka\n*   iOS\n*   Tizen\n*   Windows Phone 7 i 8\n*   Windows 8\n\n### Szybki przykład\n\n    // Android:    Froyo OS would return \"2.2\"\n    //             Eclair OS would return \"2.1\", \"2.0.1\", or \"2.0\"\n    //             Version can also return update level \"2.1-update1\"\n    //\n    // BlackBerry: Torch 9800 using OS 6.0 would return \"6.0.0.600\"\n    //\n    // Browser:    Returns version number for the browser\n    //\n    // iPhone:     iOS 3.2 returns \"3.2\"\n    //\n    // Windows Phone 7: returns current OS version number, ex. on Mango returns 7.10.7720\n    // Tizen: returns \"TIZEN_20120425_2\"\n    var deviceVersion = device.version;\n"
  },
  {
    "path": "plugins/cordova-plugin-device/doc/ru/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-device\n\nЭтот плагин определяет глобальный объект `device`, который описывает оборудование и программное обеспечение устройства. Несмотря на то что объект в глобальной области видимости, он не доступен до того момента пока не произойдет событие `deviceready`.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(device.cordova);\n    }\n    \n\n## Установка\n\n    cordova plugin add cordova-plugin-device\n    \n\n## Параметры\n\n*   device.cordova\n*   device.model\n*   device.platform\n*   device.uuid\n*   device.version\n\n## device.cordova\n\nВозвращает версию Cordova, работающую на устройстве.\n\n### Поддерживаемые платформы\n\n*   Amazon Fire OS\n*   Android\n*   BlackBerry 10\n*   Обозреватель\n*   Firefox OS\n*   iOS\n*   Tizen\n*   Windows Phone 7 и 8\n*   Windows 8\n\n## device.model\n\nСвойство `device.model` возвращает имя устройства модели или продукта. Значение устанавливается производителем устройства и могут отличаться в разных версиях одного и того же продукта.\n\n### Поддерживаемые платформы\n\n*   Android\n*   BlackBerry 10\n*   Обозреватель\n*   iOS\n*   Tizen\n*   Windows Phone 7 и 8\n*   Windows 8\n\n### Краткий пример\n\n    // Android:    Nexus One       returns \"Passion\" (Nexus One code name)\n    //             Motorola Droid  returns \"voles\"\n    // BlackBerry: Torch 9800      returns \"9800\"\n    // Browser:    Google Chrome   returns \"Chrome\"\n    //             Safari          returns \"Safari\"\n    // iOS:     for the iPad Mini, returns iPad2,5; iPhone 5 is iPhone 5,1. See http://theiphonewiki.com/wiki/index.php?title=Models\n    //\n    var model = device.model;\n    \n\n### Особенности Android\n\n*   Возвращает [имя продукта][1] , а не [имя модели][2], которое часто является производственным кодом. Например, Nexus One из них возвращает `Passion` , и Motorola Droid возвращает `voles`.\n\n [1]: http://developer.android.com/reference/android/os/Build.html#PRODUCT\n [2]: http://developer.android.com/reference/android/os/Build.html#MODEL\n\n### Особенности Tizen\n\n*   Возвращает модель устройства, назначенного вендором, например,`TIZEN`\n\n### Особенности Windows Phone 7 и 8\n\n*   Возвращает модель устройства, указанной заводом-изготовителем. Например Samsung Focus возвращает `SGH-i917`.\n\n## device.platform\n\nПолучите имя операционной системы устройства.\n\n    var string = device.platform;\n    \n\n### Поддерживаемые платформы\n\n*   Android\n*   BlackBerry 10\n*   Браузером4\n*   Firefox OS\n*   iOS\n*   Tizen\n*   Windows Phone 7 и 8\n*   Windows 8\n\n### Краткий пример\n\n    // Depending on the device, a few examples are:\n    //   - \"Android\"\n    //   - \"BlackBerry 10\"\n    //   - Browser:         returns \"MacIntel\" on Mac\n    //                      returns \"Win32\" on Windows\n    //   - \"iOS\"\n    //   - \"WinCE\"\n    //   - \"Tizen\"\n    var devicePlatform = device.platform;\n    \n\n### Особенности Windows Phone 7\n\nWindows Phone 7 устройства сообщают платформу как `WinCE`.\n\n### Особенности Windows Phone 8\n\nУстройства Windows Phone 8 сообщают платформу как `Win32NT`.\n\n## device.uuid\n\nВозвращает универсальный уникального идентификатора ([UUID][3] устройства).\n\n [3]: http://en.wikipedia.org/wiki/Universally_Unique_Identifier\n\n    var string = device.uuid;\n    \n\n### Описание\n\nПодробная информация о том как UUID генерируется, определяются изготовителем устройства и являются специфическими для платформы или модели устройства.\n\n### Поддерживаемые платформы\n\n*   Android\n*   BlackBerry 10\n*   iOS\n*   Tizen\n*   Windows Phone 7 и 8\n*   Windows 8\n\n### Краткий пример\n\n    // Android: Возвращает случайное 64-разрядное целое число (в виде строки, опять!) \n    // целое число генерируется при первой загрузке устройства \n    //\n    // BlackBerry: Возвращает номер PIN устройства \n    // это 9 значный уникальный целочисленный (как строка, хотя!) \n    // \n    // iPhone: (Перефразировано из документации класса UIDevice) \n    // возвращает строку хэш-значения, созданные из нескольких аппаратных определяет.\n    // Это значение гарантированно является уникальным для каждого устройства и не может быть привязано \n    // к учетной записи пользователя.\n    // Windows Phone 7: Возвращает хэш устройство + текущего пользователя, \n    // если пользователь не определен, формируется guid который и будет сохраняться до тех пор, пока приложение не удалиться \n    // Tizen: возвращает IMEI устройства (Международный идентификатор мобильного оборудования или IMEI это число \n    // уникальное для каждого мобильного телефона GSM и UMTS.\n    var deviceID = device.uuid;\n    \n\n### Особенности iOS\n\nНа iOS `uuid` не является уникальным для устройства, но варьируется для каждого приложения, и для каждой установки. Значение меняется, если удалить и повторно установить приложение, и возможно также когда вы обновите iOS, или даже обновить приложение до следующей версии (очевидно в iOS 5.1). Значение `uuid` не является надежным.\n\n### Особенности Windows Phone 7 и 8\n\nДля Windows Phone 7 `uuid` требует разрешения `ID_CAP_IDENTITY_DEVICE` . Microsoft скорее всего скоро сделает это свойство устаревшим. Если возможность недоступна, приложение создает постоянные guid, который сохраняется на все время установки приложения на устройстве.\n\n## device.version\n\nВозвращает версию операционной системы.\n\n    var string = device.version;\n    \n\n### Поддерживаемые платформы\n\n*   Android 2.1 +\n*   BlackBerry 10\n*   Обозреватель\n*   iOS\n*   Tizen\n*   Windows Phone 7 и 8\n*   Windows 8\n\n### Краткий пример\n\n    // Android:    Froyo OS would return \"2.2\"\n    //             Eclair OS would return \"2.1\", \"2.0.1\", or \"2.0\"\n    //             Version can also return update level \"2.1-update1\"\n    //\n    // BlackBerry: Torch 9800 using OS 6.0 would return \"6.0.0.600\"\n    //\n    // Browser:    Returns version number for the browser\n    //\n    // iPhone:     iOS 3.2 returns \"3.2\"\n    //\n    // Windows Phone 7: returns current OS version number, ex. on Mango returns 7.10.7720\n    // Tizen: returns \"TIZEN_20120425_2\"\n    var deviceVersion = device.version;\n"
  },
  {
    "path": "plugins/cordova-plugin-device/doc/zh/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-device\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-device.svg?branch=master)](https://travis-ci.org/apache/cordova-plugin-device)\n\n這個外掛程式定義全球 `device` 物件，描述該設備的硬體和軟體。 雖然物件是在全球範圍內，但不是可用，直到後 `deviceready` 事件。\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(device.cordova);\n    }\n    \n\n## 安裝\n\n    cordova plugin add cordova-plugin-device\n    \n\n## 屬性\n\n  * device.cordova\n  * device.model\n  * device.platform\n  * device.uuid\n  * device.version\n\n## device.cordova\n\n獲取科爾多瓦在設備上運行的版本。\n\n### 支援的平臺\n\n  * 亞馬遜火 OS\n  * Android 系統\n  * 黑莓 10\n  * 瀏覽器\n  * 火狐瀏覽器作業系統\n  * iOS\n  * Tizen\n  * Windows Phone 7 和 8\n  * Windows 8\n\n## device.model\n\n`device.model`返回設備的模型或產品的名稱。值由設備製造商設置和同一產品的不同版本可能不同。\n\n### 支援的平臺\n\n  * Android 系統\n  * 黑莓 10\n  * 瀏覽器\n  * iOS\n  * Tizen\n  * Windows Phone 7 和 8\n  * Windows 8\n\n### 快速的示例\n\n    // Android:    Nexus One       returns \"Passion\" (Nexus One code name)\n    //             Motorola Droid  returns \"voles\"\n    // BlackBerry: Torch 9800      returns \"9800\"\n    // Browser:    Google Chrome   returns \"Chrome\"\n    //             Safari          returns \"Safari\"\n    // iOS:     for the iPad Mini, returns iPad2,5; iPhone 5 is iPhone 5,1. 請參閱 HTTP://theiphonewiki.com/wiki/index.php?title=Models / / var 模型 = device.model ；\n    \n\n### Android 的怪癖\n\n  * 獲取[產品名稱](http://developer.android.com/reference/android/os/Build.html#PRODUCT)而不是[產品型號名稱](http://developer.android.com/reference/android/os/Build.html#MODEL)，這往往是生產代碼名稱。 例如，Nexus One 返回 `Passion` ，和摩托羅拉 Droid 返回`voles`.\n\n### Tizen 怪癖\n\n  * 例如，返回與供應商指派的設備模型`TIZEN`\n\n### Windows Phone 7 和 8 怪癖\n\n  * 返回由製造商指定的設備模型。例如，三星焦點返回`SGH-i917`.\n\n## device.platform\n\n獲取設備的作業系統名稱。\n\n    var string = device.platform;\n    \n\n### 支援的平臺\n\n  * Android 系統\n  * 黑莓 10\n  * Browser4\n  * 火狐瀏覽器作業系統\n  * iOS\n  * Tizen\n  * Windows Phone 7 和 8\n  * Windows 8\n\n### 快速的示例\n\n    // Depending on the device, a few examples are:\n    //   - \"Android\"\n    //   - \"BlackBerry 10\"\n    //   - Browser:         returns \"MacIntel\" on Mac\n    //                      returns \"Win32\" on Windows\n    //   - \"iOS\"\n    //   - \"WinCE\"\n    //   - \"Tizen\"\n    var devicePlatform = device.platform;\n    \n\n### Windows Phone 7 的怪癖\n\nWindows Phone 7 設備報告作為平臺`WinCE`.\n\n### Windows Phone 8 怪癖\n\nWindows Phone 8 設備報告作為平臺`Win32NT`.\n\n## device.uuid\n\n獲取設備的通用唯一識別碼 ([UUID](http://en.wikipedia.org/wiki/Universally_Unique_Identifier)).\n\n    var string = device.uuid;\n    \n\n### 說明\n\n如何生成一個 UUID 的細節由設備製造商和特定于設備的平臺或模型。\n\n### 支援的平臺\n\n  * Android 系統\n  * 黑莓 10\n  * iOS\n  * Tizen\n  * Windows Phone 7 和 8\n  * Windows 8\n\n### 快速的示例\n\n    / / Android： 一個隨機的 64 位整數 （作為字串返回，再次!) / / 上設備的第一次啟動生成的整數 / / / / 黑莓手機： 返回設備的 PIN 號碼 / / 這是九個數字的唯一整數 （作為字串，雖然!) / / / / iPhone： （從 UIDevice 類文檔解釋） / / 返回一個字串的雜湊值創建的多個硬體標識。\n    / / 它保證是唯一的每個設備並不能綁 / / 到使用者帳戶。\n    / / Windows Phone 7： 返回的雜湊代碼的設備 + 當前使用者，/ / 如果未定義使用者，則一個 guid 生成的並且將會保留直到卸載該應用程式 / / Tizen： 返回設備 IMEI （國際行動裝置身份或 IMEI 是一個數位 / / 獨有的每一個 UMTS 和 GSM 行動電話。\n    var deviceID = device.uuid;\n    \n\n### iOS 怪癖\n\n`uuid`在 iOS 不是唯一的一種裝置，但對於每個應用程式，為每個安裝而異。 如果您刪除並重新安裝該應用程式，它更改和可能還當你升級 iOS，或甚至升級每個版本 （iOS 5.1 中存在明顯的） 的應用程式。 `uuid`不是一個可靠的值。\n\n### Windows Phone 7 和 8 怪癖\n\n`uuid`為 Windows Phone 7 須經許可 `ID_CAP_IDENTITY_DEVICE` 。 Microsoft 可能會很快棄用此屬性。 如果沒有可用的能力，應用程式將生成設備上應用程式的安裝過程中保持持續的 guid。\n\n## device.version\n\n獲取作業系統版本。\n\n    var string = device.version;\n    \n\n### 支援的平臺\n\n  * Android 2.1 +\n  * 黑莓 10\n  * 瀏覽器\n  * iOS\n  * Tizen\n  * Windows Phone 7 和 8\n  * Windows 8\n\n### 快速的示例\n\n    // Android:    Froyo OS would return \"2.2\"\n    //             Eclair OS would return \"2.1\", \"2.0.1\", or \"2.0\"\n    //             Version can also return update level \"2.1-update1\"\n    //\n    // BlackBerry: Torch 9800 using OS 6.0 would return \"6.0.0.600\"\n    //\n    // Browser:    Returns version number for the browser\n    //\n    // iPhone:     iOS 3.2 returns \"3.2\"\n    //\n    // Windows Phone 7: returns current OS version number, ex. on Mango returns 7.10.7720\n    // Tizen: returns \"TIZEN_20120425_2\"\n    var deviceVersion = device.version;"
  },
  {
    "path": "plugins/cordova-plugin-device/doc/zh/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-device\n\n這個外掛程式定義全球 `device` 物件，描述該設備的硬體和軟體。 雖然物件是在全球範圍內，但不是可用，直到後 `deviceready` 事件。\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(device.cordova);\n    }\n    \n\n## 安裝\n\n    cordova plugin add cordova-plugin-device\n    \n\n## 屬性\n\n*   device.cordova\n*   device.model\n*   device.platform\n*   device.uuid\n*   device.version\n\n## device.cordova\n\n獲取科爾多瓦在設備上運行的版本。\n\n### 支援的平臺\n\n*   亞馬遜火 OS\n*   Android 系統\n*   黑莓 10\n*   瀏覽器\n*   火狐瀏覽器的作業系統\n*   iOS\n*   泰\n*   Windows Phone 7 和 8\n*   Windows 8\n\n## device.model\n\n`device.model`返回設備的模型或產品的名稱。值由設備製造商設置和同一產品的不同版本可能不同。\n\n### 支援的平臺\n\n*   Android 系統\n*   黑莓 10\n*   瀏覽器\n*   iOS\n*   泰\n*   Windows Phone 7 和 8\n*   Windows 8\n\n### 快速的示例\n\n    // Android:    Nexus One       returns \"Passion\" (Nexus One code name)\n    //             Motorola Droid  returns \"voles\"\n    // BlackBerry: Torch 9800      returns \"9800\"\n    // Browser:    Google Chrome   returns \"Chrome\"\n    //             Safari          returns \"Safari\"\n    // iOS:     for the iPad Mini, returns iPad2,5; iPhone 5 is iPhone 5,1. 請參閱 HTTP://theiphonewiki.com/wiki/index.php?title=Models / / var 模型 = device.model ；\n    \n\n### Android 的怪癖\n\n*   獲取[產品名稱][1]而不是[產品型號名稱][2]，這往往是生產代碼名稱。 例如，Nexus One 返回 `Passion` ，和摩托羅拉 Droid 返回`voles`.\n\n [1]: http://developer.android.com/reference/android/os/Build.html#PRODUCT\n [2]: http://developer.android.com/reference/android/os/Build.html#MODEL\n\n### Tizen 怪癖\n\n*   例如，返回與供應商指派的設備模型`TIZEN`\n\n### Windows Phone 7 和 8 怪癖\n\n*   返回由製造商指定的設備模型。例如，三星焦點返回`SGH-i917`.\n\n## device.platform\n\n獲取設備的作業系統名稱。\n\n    var string = device.platform;\n    \n\n### 支援的平臺\n\n*   Android 系統\n*   黑莓 10\n*   Browser4\n*   火狐瀏覽器的作業系統\n*   iOS\n*   泰\n*   Windows Phone 7 和 8\n*   Windows 8\n\n### 快速的示例\n\n    // Depending on the device, a few examples are:\n    //   - \"Android\"\n    //   - \"BlackBerry 10\"\n    //   - Browser:         returns \"MacIntel\" on Mac\n    //                      returns \"Win32\" on Windows\n    //   - \"iOS\"\n    //   - \"WinCE\"\n    //   - \"Tizen\"\n    var devicePlatform = device.platform;\n    \n\n### Windows Phone 7 的怪癖\n\nWindows Phone 7 設備報告作為平臺`WinCE`.\n\n### Windows Phone 8 怪癖\n\nWindows Phone 8 設備報告作為平臺`Win32NT`.\n\n## device.uuid\n\n獲取設備的通用唯一識別碼 ([UUID][3]).\n\n [3]: http://en.wikipedia.org/wiki/Universally_Unique_Identifier\n\n    var string = device.uuid;\n    \n\n### 說明\n\n如何生成一個 UUID 的細節由設備製造商和特定于設備的平臺或模型。\n\n### 支援的平臺\n\n*   Android 系統\n*   黑莓 10\n*   iOS\n*   Tizen\n*   Windows Phone 7 和 8\n*   Windows 8\n\n### 快速的示例\n\n    / / Android： 一個隨機的 64 位整數 （作為字串返回，再次!) / / 上設備的第一次啟動生成的整數 / / / / 黑莓手機： 返回設備的 PIN 號碼 / / 這是九個數字的唯一整數 （作為字串，雖然!) / / / / iPhone： （從 UIDevice 類文檔解釋） / / 返回一個字串的雜湊值創建的多個硬體標識。\n    / / 它保證是唯一的每個設備並不能綁 / / 到使用者帳戶。\n    / / Windows Phone 7： 返回的雜湊代碼的設備 + 當前使用者，/ / 如果未定義使用者，則一個 guid 生成的並且將會保留直到卸載該應用程式 / / Tizen： 返回設備 IMEI （國際行動裝置身份或 IMEI 是一個數位 / / 獨有的每一個 UMTS 和 GSM 行動電話。\n    var deviceID = device.uuid;\n    \n\n### iOS 怪癖\n\n`uuid`在 iOS 不是唯一的一種裝置，但對於每個應用程式，為每個安裝而異。 如果您刪除並重新安裝該應用程式，它更改和可能還當你升級 iOS，或甚至升級每個版本 （iOS 5.1 中存在明顯的） 的應用程式。 `uuid`不是一個可靠的值。\n\n### Windows Phone 7 和 8 怪癖\n\n`uuid`為 Windows Phone 7 須經許可 `ID_CAP_IDENTITY_DEVICE` 。 Microsoft 可能會很快棄用此屬性。 如果沒有可用的能力，應用程式將生成設備上應用程式的安裝過程中保持持續的 guid。\n\n## device.version\n\n獲取作業系統版本。\n\n    var string = device.version;\n    \n\n### 支援的平臺\n\n*   Android 2.1 +\n*   黑莓 10\n*   瀏覽器\n*   iOS\n*   泰\n*   Windows Phone 7 和 8\n*   Windows 8\n\n### 快速的示例\n\n    // Android:    Froyo OS would return \"2.2\"\n    //             Eclair OS would return \"2.1\", \"2.0.1\", or \"2.0\"\n    //             Version can also return update level \"2.1-update1\"\n    //\n    // BlackBerry: Torch 9800 using OS 6.0 would return \"6.0.0.600\"\n    //\n    // Browser:    Returns version number for the browser\n    //\n    // iPhone:     iOS 3.2 returns \"3.2\"\n    //\n    // Windows Phone 7: returns current OS version number, ex. on Mango returns 7.10.7720\n    // Tizen: returns \"TIZEN_20120425_2\"\n    var deviceVersion = device.version;\n"
  },
  {
    "path": "plugins/cordova-plugin-device/package.json",
    "content": "{\n  \"name\": \"cordova-plugin-device\",\n  \"version\": \"1.1.2\",\n  \"description\": \"Cordova Device Plugin\",\n  \"cordova\": {\n    \"id\": \"cordova-plugin-device\",\n    \"platforms\": [\n      \"firefoxos\",\n      \"tizen\",\n      \"android\",\n      \"amazon-fireos\",\n      \"ubuntu\",\n      \"ios\",\n      \"blackberry10\",\n      \"wp7\",\n      \"wp8\",\n      \"windows8\",\n      \"windows\",\n      \"browser\",\n      \"osx\"\n    ]\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/apache/cordova-plugin-device\"\n  },\n  \"keywords\": [\n    \"cordova\",\n    \"device\",\n    \"ecosystem:cordova\",\n    \"cordova-firefoxos\",\n    \"cordova-tizen\",\n    \"cordova-android\",\n    \"cordova-amazon-fireos\",\n    \"cordova-ubuntu\",\n    \"cordova-ios\",\n    \"cordova-blackberry10\",\n    \"cordova-wp7\",\n    \"cordova-wp8\",\n    \"cordova-windows8\",\n    \"cordova-windows\",\n    \"cordova-browser\",\n    \"cordova-osx\"\n  ],\n  \"scripts\": {\n    \"test\": \"npm run jshint\",\n    \"jshint\": \"node node_modules/jshint/bin/jshint www && node node_modules/jshint/bin/jshint src && node node_modules/jshint/bin/jshint tests\"\n  },\n  \"author\": \"Apache Software Foundation\",\n  \"license\": \"Apache-2.0\",\n  \"devDependencies\": {\n    \"jshint\": \"^2.6.0\"\n  }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-device/plugin.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  Licensed to the Apache Software Foundation (ASF) under one\n  or more contributor license agreements.  See the NOTICE file\n  distributed with this work for additional information\n  regarding copyright ownership.  The ASF licenses this file\n  to you under the Apache License, Version 2.0 (the\n  \"License\"); you may not use this file except in compliance\n  with the License.  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing,\n  software distributed under the License is distributed on an\n  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n  KIND, either express or implied.  See the License for the\n  specific language governing permissions and limitations\n  under the License.\n-->\n\n<plugin xmlns=\"http://apache.org/cordova/ns/plugins/1.0\"\n    xmlns:rim=\"http://www.blackberry.com/ns/widgets\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    id=\"cordova-plugin-device\"\n    version=\"1.1.2\">\n    <name>Device</name>\n    <description>Cordova Device Plugin</description>\n    <license>Apache 2.0</license>\n    <keywords>cordova,device</keywords>\n    <repo>https://git-wip-us.apache.org/repos/asf/cordova-plugin-device.git</repo>\n    <issue>https://issues.apache.org/jira/browse/CB/component/12320648</issue>\n\n    <js-module src=\"www/device.js\" name=\"device\">\n        <clobbers target=\"device\" />\n    </js-module>\n\n    <!-- firefoxos -->\n    <platform name=\"firefoxos\">\n        <config-file target=\"config.xml\" parent=\"/*\">\n            <feature name=\"Device\">\n                <param name=\"firefoxos-package\" value=\"Device\" />\n            </feature>\n        </config-file>\n\n        <js-module src=\"src/firefoxos/DeviceProxy.js\" name=\"DeviceProxy\">\n            <runs />\n        </js-module>\n    </platform>\n\n    <!-- tizen -->\n    <platform name=\"tizen\">\n        <js-module src=\"src/tizen/DeviceProxy.js\" name=\"DeviceProxy\">\n            <runs />\n        </js-module>\n    </platform>\n\n    <!-- android -->\n    <platform name=\"android\">\n        <config-file target=\"res/xml/config.xml\" parent=\"/*\">\n            <feature name=\"Device\" >\n                <param name=\"android-package\" value=\"org.apache.cordova.device.Device\"/>\n            </feature>\n        </config-file>\n\n        <source-file src=\"src/android/Device.java\" target-dir=\"src/org/apache/cordova/device\" />\n    </platform>\n\n    <!-- amazon-fireos -->\n    <platform name=\"amazon-fireos\">\n        <config-file target=\"res/xml/config.xml\" parent=\"/*\">\n            <feature name=\"Device\" >\n                <param name=\"android-package\" value=\"org.apache.cordova.device.Device\"/>\n            </feature>\n        </config-file>\n\n        <source-file src=\"src/android/Device.java\" target-dir=\"src/org/apache/cordova/device\" />\n    </platform>\n    \n    <!-- ubuntu -->\n    <platform name=\"ubuntu\">\n        <header-file src=\"src/ubuntu/device.h\" />\n        <source-file src=\"src/ubuntu/device.cpp\" />\n        <js-module src=\"src/ubuntu/device.js\" name=\"DeviceProxy\">\n            <merges target=\"device\" />\n        </js-module>\n    </platform>\n\n    <!-- ios -->\n    <platform name=\"ios\">\n        <config-file target=\"config.xml\" parent=\"/*\">\n            <feature name=\"Device\">\n                <param name=\"ios-package\" value=\"CDVDevice\"/>\n            </feature>\n        </config-file>\n\n        <header-file src=\"src/ios/CDVDevice.h\" />\n        <source-file src=\"src/ios/CDVDevice.m\" />\n    </platform>\n\n    <!-- blackberry10 -->\n    <platform name=\"blackberry10\">\n        <source-file src=\"src/blackberry10/index.js\" target-dir=\"Device\" />\n        <config-file target=\"www/config.xml\" parent=\"/widget\">\n            <feature name=\"Device\" value=\"Device\"/>\n        </config-file>\n        <config-file target=\"www/config.xml\" parent=\"/widget/rim:permissions\">\n            <rim:permit>read_device_identifying_information</rim:permit>\n        </config-file>\n    </platform>\n\n    <!-- wp7 -->\n    <platform name=\"wp7\">\n        <config-file target=\"config.xml\" parent=\"/*\">\n            <feature name=\"Device\">\n                <param name=\"wp-package\" value=\"Device\"/>\n            </feature>\n        </config-file>\n\n        <config-file target=\"Properties/WMAppManifest.xml\" parent=\"/Deployment/App/Capabilities\">\n            <Capability Name=\"ID_CAP_IDENTITY_DEVICE\" />\n        </config-file>\n\n        <source-file src=\"src/wp/Device.cs\" />\n    </platform>\n\n    <!-- wp8 -->\n    <platform name=\"wp8\">\n        <config-file target=\"config.xml\" parent=\"/*\">\n            <feature name=\"Device\">\n                <param name=\"wp-package\" value=\"Device\"/>\n            </feature>\n        </config-file>\n\n        <config-file target=\"Properties/WMAppManifest.xml\" parent=\"/Deployment/App/Capabilities\">\n            <Capability Name=\"ID_CAP_IDENTITY_DEVICE\" />\n        </config-file>\n\n        <source-file src=\"src/wp/Device.cs\" />\n    </platform>\n\n    <!-- windows -->\n    <platform name=\"windows\">\n        <js-module src=\"src/windows/DeviceProxy.js\" name=\"DeviceProxy\">\n            <merges target=\"\" />\n        </js-module>\n    </platform>\n\n    <!-- browser -->\n    <platform name=\"browser\">\n        <config-file target=\"config.xml\" parent=\"/*\">\n            <feature name=\"Device\">\n                <param name=\"browser-package\" value=\"Device\" />\n            </feature>\n        </config-file>\n\n        <js-module src=\"src/browser/DeviceProxy.js\" name=\"DeviceProxy\">\n            <runs />\n        </js-module>\n    </platform>\n\n    <!-- osx -->\n    <platform name=\"osx\">\n        <config-file target=\"config.xml\" parent=\"/*\">\n            <feature name=\"Device\">\n                <param name=\"ios-package\" value=\"CDVDevice\"/>\n            </feature>\n        </config-file>\n\n        <header-file src=\"src/osx/CDVDevice.h\" />\n        <source-file src=\"src/osx/CDVDevice.m\" />\n    </platform>\n\n\n</plugin>\n"
  },
  {
    "path": "plugins/cordova-plugin-device/src/android/Device.java",
    "content": "/*\n       Licensed to the Apache Software Foundation (ASF) under one\n       or more contributor license agreements.  See the NOTICE file\n       distributed with this work for additional information\n       regarding copyright ownership.  The ASF licenses this file\n       to you under the Apache License, Version 2.0 (the\n       \"License\"); you may not use this file except in compliance\n       with the License.  You may obtain a copy of the License at\n\n         http://www.apache.org/licenses/LICENSE-2.0\n\n       Unless required by applicable law or agreed to in writing,\n       software distributed under the License is distributed on an\n       \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n       KIND, either express or implied.  See the License for the\n       specific language governing permissions and limitations\n       under the License.\n*/\npackage org.apache.cordova.device;\n\nimport java.util.TimeZone;\n\nimport org.apache.cordova.CordovaWebView;\nimport org.apache.cordova.CallbackContext;\nimport org.apache.cordova.CordovaPlugin;\nimport org.apache.cordova.CordovaInterface;\nimport org.json.JSONArray;\nimport org.json.JSONException;\nimport org.json.JSONObject;\n\nimport android.provider.Settings;\n\npublic class Device extends CordovaPlugin {\n    public static final String TAG = \"Device\";\n\n    public static String platform;                            // Device OS\n    public static String uuid;                                // Device UUID\n\n    private static final String ANDROID_PLATFORM = \"Android\";\n    private static final String AMAZON_PLATFORM = \"amazon-fireos\";\n    private static final String AMAZON_DEVICE = \"Amazon\";\n\n    /**\n     * Constructor.\n     */\n    public Device() {\n    }\n\n    /**\n     * Sets the context of the Command. This can then be used to do things like\n     * get file paths associated with the Activity.\n     *\n     * @param cordova The context of the main Activity.\n     * @param webView The CordovaWebView Cordova is running in.\n     */\n    public void initialize(CordovaInterface cordova, CordovaWebView webView) {\n        super.initialize(cordova, webView);\n        Device.uuid = getUuid();\n    }\n\n    /**\n     * Executes the request and returns PluginResult.\n     *\n     * @param action            The action to execute.\n     * @param args              JSONArry of arguments for the plugin.\n     * @param callbackContext   The callback id used when calling back into JavaScript.\n     * @return                  True if the action was valid, false if not.\n     */\n    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {\n        if (\"getDeviceInfo\".equals(action)) {\n            JSONObject r = new JSONObject();\n            r.put(\"uuid\", Device.uuid);\n            r.put(\"version\", this.getOSVersion());\n            r.put(\"platform\", this.getPlatform());\n            r.put(\"model\", this.getModel());\n            r.put(\"manufacturer\", this.getManufacturer());\n\t        r.put(\"isVirtual\", this.isVirtual());\n            r.put(\"serial\", this.getSerialNumber());\n            callbackContext.success(r);\n        }\n        else {\n            return false;\n        }\n        return true;\n    }\n\n    //--------------------------------------------------------------------------\n    // LOCAL METHODS\n    //--------------------------------------------------------------------------\n\n    /**\n     * Get the OS name.\n     *\n     * @return\n     */\n    public String getPlatform() {\n        String platform;\n        if (isAmazonDevice()) {\n            platform = AMAZON_PLATFORM;\n        } else {\n            platform = ANDROID_PLATFORM;\n        }\n        return platform;\n    }\n\n    /**\n     * Get the device's Universally Unique Identifier (UUID).\n     *\n     * @return\n     */\n    public String getUuid() {\n        String uuid = Settings.Secure.getString(this.cordova.getActivity().getContentResolver(), android.provider.Settings.Secure.ANDROID_ID);\n        return uuid;\n    }\n\n    public String getModel() {\n        String model = android.os.Build.MODEL;\n        return model;\n    }\n\n    public String getProductName() {\n        String productname = android.os.Build.PRODUCT;\n        return productname;\n    }\n\n    public String getManufacturer() {\n        String manufacturer = android.os.Build.MANUFACTURER;\n        return manufacturer;\n    }\n\n    public String getSerialNumber() {\n        String serial = android.os.Build.SERIAL;\n        return serial;\n    }\n\n    /**\n     * Get the OS version.\n     *\n     * @return\n     */\n    public String getOSVersion() {\n        String osversion = android.os.Build.VERSION.RELEASE;\n        return osversion;\n    }\n\n    public String getSDKVersion() {\n        @SuppressWarnings(\"deprecation\")\n        String sdkversion = android.os.Build.VERSION.SDK;\n        return sdkversion;\n    }\n\n    public String getTimeZoneID() {\n        TimeZone tz = TimeZone.getDefault();\n        return (tz.getID());\n    }\n\n    /**\n     * Function to check if the device is manufactured by Amazon\n     *\n     * @return\n     */\n    public boolean isAmazonDevice() {\n        if (android.os.Build.MANUFACTURER.equals(AMAZON_DEVICE)) {\n            return true;\n        }\n        return false;\n    }\n\n    public boolean isVirtual() {\n\treturn android.os.Build.FINGERPRINT.contains(\"generic\") ||\n\t    android.os.Build.PRODUCT.contains(\"sdk\");\n    }\n\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-device/src/blackberry10/index.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/* global PluginResult */\n\nfunction getModelName () {\n    var modelName = window.qnx.webplatform.device.modelName;\n    //Pre 10.2 (meaning Z10 or Q10)\n    if (typeof modelName === \"undefined\") {\n        if (window.screen.height === 720 && window.screen.width === 720) {\n            if ( window.matchMedia(\"(-blackberry-display-technology: -blackberry-display-oled)\").matches) {\n                modelName = \"Q10\";\n            } else {\n                modelName = \"Q5\";\n            }\n        } else if ((window.screen.height === 1280 && window.screen.width === 768) ||\n                   (window.screen.height === 768 && window.screen.width === 1280)) {\n            modelName = \"Z10\";\n        } else {\n            modelName = window.qnx.webplatform.deviceName;\n        }\n    }\n\n    return modelName;\n}\n\nfunction getUUID () {\n    var uuid = \"\";\n    try {\n        //Must surround by try catch because this will throw if the app is missing permissions\n        uuid = window.qnx.webplatform.device.devicePin;\n    } catch (e) {\n        //DO Nothing\n    }\n    return uuid;\n}\n\nmodule.exports = {\n    getDeviceInfo: function (success, fail, args, env) {\n        var result = new PluginResult(args, env),\n            modelName = getModelName(),\n            uuid = getUUID(),\n            info = {\n                manufacturer: 'BlackBerry',\n                platform: \"blackberry10\",\n                version: window.qnx.webplatform.device.scmBundle,\n                model: modelName,\n                uuid: uuid\n            };\n\n        result.ok(info);\n    }\n};\n"
  },
  {
    "path": "plugins/cordova-plugin-device/src/browser/DeviceProxy.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n */\nvar browser = require('cordova/platform');\n\nfunction getPlatform() {\n    return \"browser\";\n}\n\nfunction getModel() {\n    return getBrowserInfo(true);\n}\n\nfunction getVersion() {\n    return getBrowserInfo(false);\n}\n\nfunction getBrowserInfo(getModel) {\n    var userAgent = navigator.userAgent;\n    var returnVal = '';\n    var offset;\n\n    if ((offset = userAgent.indexOf('Chrome')) !== -1) {\n        returnVal = (getModel) ? 'Chrome' : userAgent.substring(offset + 7);\n    } else if ((offset = userAgent.indexOf('Safari')) !== -1) {\n        if (getModel) {\n            returnVal = 'Safari';\n        } else {\n            returnVal = userAgent.substring(offset + 7);\n\n            if ((offset = userAgent.indexOf('Version')) !== -1) {\n                returnVal = userAgent.substring(offset + 8);\n            }\n        }\n    } else if ((offset = userAgent.indexOf('Firefox')) !== -1) {\n        returnVal = (getModel) ? 'Firefox' : userAgent.substring(offset + 8);\n    } else if ((offset = userAgent.indexOf('MSIE')) !== -1) {\n        returnVal = (getModel) ? 'MSIE' : userAgent.substring(offset + 5);\n    } else if ((offset = userAgent.indexOf('Trident')) !== -1) {\n        returnVal = (getModel) ? 'MSIE' : '11';\n    }\n\n    if ((offset = returnVal.indexOf(';')) !== -1 || (offset = returnVal.indexOf(' ')) !== -1) {\n        returnVal = returnVal.substring(0, offset);\n    }\n\n    return returnVal;\n}\n\n\nmodule.exports = {\n    getDeviceInfo: function (success, error) {\n        setTimeout(function () {\n            success({\n                cordova: browser.cordovaVersion,\n                platform: getPlatform(),\n                model: getModel(),\n                version: getVersion(),\n                uuid: null\n            });\n        }, 0);\n    }\n};\n\nrequire(\"cordova/exec/proxy\").add(\"Device\", module.exports);\n"
  },
  {
    "path": "plugins/cordova-plugin-device/src/firefoxos/DeviceProxy.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n */\n//example UA String for Firefox OS \n//Mozilla/5.0 (Mobile; rv:26.0) Gecko/26.0 Firefox/26.0\n\n//UA parsing not recommended but currently this is the only way to get the Firefox OS version\n//https://developer.mozilla.org/en-US/docs/Gecko_user_agent_string_reference\n\n//Should be replaced when better conversion to Firefox OS Version is available\nfunction convertVersionNumber(ver) {\n    var hashVersion = {\n        '18.0': '1.0.1',\n        '18.1': '1.1',\n        '26.0': '1.2',\n        '28.0': '1.3',\n        '30.0': '1.4',\n        '32.0': '2.0'\n    };\n    var rver = ver;\n    var sStr = ver.substring(0, 4);\n    if (hashVersion[sStr]) {\n        rver = hashVersion[sStr];\n    }\n    return (rver);\n\n}\nfunction getVersion() {\n    if (navigator.userAgent.match(/(mobile|tablet)/i)) {\n        var ffVersionArray = (navigator.userAgent.match(/Firefox\\/([\\d]+\\.[\\w]?\\.?[\\w]+)/));\n        if (ffVersionArray.length === 2) {\n            return (convertVersionNumber(ffVersionArray[1]));\n        }\n    }\n    return (null);\n}\n\nfunction getModel() {\n    var uaArray = navigator.userAgent.split(/\\s*[;)(]\\s*/);\n    if (navigator.userAgent.match(/(mobile|tablet)/i)) {\n        if (uaArray.length === 5) {\n            return (uaArray[2]);\n        }\n    }\n    return (null);\n}\nmodule.exports = {\n    getDeviceInfo: function (success, error) {\n        setTimeout(function () {\n            success({\n                platform: 'firefoxos',\n                model: getModel(),\n                version: getVersion(),\n                uuid: null\n            });\n        }, 0);\n    }\n};\n\nrequire(\"cordova/exec/proxy\").add(\"Device\", module.exports);\n"
  },
  {
    "path": "plugins/cordova-plugin-device/src/ios/CDVDevice.h",
    "content": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements.  See the NOTICE file\n distributed with this work for additional information\n regarding copyright ownership.  The ASF licenses this file\n to you under the Apache License, Version 2.0 (the\n \"License\"); you may not use this file except in compliance\n with the License.  You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an\n \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n KIND, either express or implied.  See the License for the\n specific language governing permissions and limitations\n under the License.\n */\n\n#import <UIKit/UIKit.h>\n#import <Cordova/CDVPlugin.h>\n\n@interface CDVDevice : CDVPlugin\n{}\n\n+ (NSString*)cordovaVersion;\n\n- (void)getDeviceInfo:(CDVInvokedUrlCommand*)command;\n\n@end\n"
  },
  {
    "path": "plugins/cordova-plugin-device/src/ios/CDVDevice.m",
    "content": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements.  See the NOTICE file\n distributed with this work for additional information\n regarding copyright ownership.  The ASF licenses this file\n to you under the Apache License, Version 2.0 (the\n \"License\"); you may not use this file except in compliance\n with the License.  You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an\n \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n KIND, either express or implied.  See the License for the\n specific language governing permissions and limitations\n under the License.\n */\n\n#include <sys/types.h>\n#include <sys/sysctl.h>\n#include \"TargetConditionals.h\"\n\n#import <Cordova/CDV.h>\n#import \"CDVDevice.h\"\n\n@implementation UIDevice (ModelVersion)\n\n- (NSString*)modelVersion\n{\n    size_t size;\n\n    sysctlbyname(\"hw.machine\", NULL, &size, NULL, 0);\n    char* machine = malloc(size);\n    sysctlbyname(\"hw.machine\", machine, &size, NULL, 0);\n    NSString* platform = [NSString stringWithUTF8String:machine];\n    free(machine);\n\n    return platform;\n}\n\n@end\n\n@interface CDVDevice () {}\n@end\n\n@implementation CDVDevice\n\n- (NSString*)uniqueAppInstanceIdentifier:(UIDevice*)device\n{\n    NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];\n    static NSString* UUID_KEY = @\"CDVUUID\";\n    \n    // Check user defaults first to maintain backwards compaitibility with previous versions\n    // which didn't user identifierForVendor\n    NSString* app_uuid = [userDefaults stringForKey:UUID_KEY];\n    if (app_uuid == nil) {\n        if ([device respondsToSelector:@selector(identifierForVendor)]) {\n            app_uuid = [[device identifierForVendor] UUIDString];\n        } else {\n            CFUUIDRef uuid = CFUUIDCreate(NULL);\n            app_uuid = (__bridge_transfer NSString *)CFUUIDCreateString(NULL, uuid);\n            CFRelease(uuid);\n        }\n\n        [userDefaults setObject:app_uuid forKey:UUID_KEY];\n        [userDefaults synchronize];\n    }\n    \n    return app_uuid;\n}\n\n- (void)getDeviceInfo:(CDVInvokedUrlCommand*)command\n{\n    NSDictionary* deviceProperties = [self deviceProperties];\n    CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:deviceProperties];\n\n    [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];\n}\n\n- (NSDictionary*)deviceProperties\n{\n    UIDevice* device = [UIDevice currentDevice];\n\n    return @{\n             @\"manufacturer\": @\"Apple\",\n             @\"model\": [device modelVersion],\n             @\"platform\": @\"iOS\",\n             @\"version\": [device systemVersion],\n             @\"uuid\": [self uniqueAppInstanceIdentifier:device],\n             @\"cordova\": [[self class] cordovaVersion],\n             @\"isVirtual\": @([self isVirtual])\n             };\n}\n\n+ (NSString*)cordovaVersion\n{\n    return CDV_VERSION;\n}\n\n- (BOOL)isVirtual\n{\n    #if TARGET_OS_SIMULATOR\n        return true;\n    #elif TARGET_IPHONE_SIMULATOR\n        return true;\n    #else\n        return false;\n    #endif\n}\n\n@end\n"
  },
  {
    "path": "plugins/cordova-plugin-device/src/osx/CDVDevice.h",
    "content": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements.  See the NOTICE file\n distributed with this work for additional information\n regarding copyright ownership.  The ASF licenses this file\n to you under the Apache License, Version 2.0 (the\n \"License\"); you may not use this file except in compliance\n with the License.  You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an\n \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n KIND, either express or implied.  See the License for the\n specific language governing permissions and limitations\n under the License.\n */\n\n#import <Cordova/CDVPlugin.h>\n\n@interface CDVDevice : CDVPlugin\n\n+ (NSString*) cordovaVersion;\n\n- (void) getDeviceInfo:(CDVInvokedUrlCommand*)command;\n\n@end\n"
  },
  {
    "path": "plugins/cordova-plugin-device/src/osx/CDVDevice.m",
    "content": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements.  See the NOTICE file\n distributed with this work for additional information\n regarding copyright ownership.  The ASF licenses this file\n to you under the Apache License, Version 2.0 (the\n \"License\"); you may not use this file except in compliance\n with the License.  You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an\n \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n KIND, either express or implied.  See the License for the\n specific language governing permissions and limitations\n under the License.\n */\n\n#include <sys/sysctl.h>\n\n#import \"CDVDevice.h\"\n\n#define SYSTEM_VERSION_PLIST    @\"/System/Library/CoreServices/SystemVersion.plist\"\n\n@implementation CDVDevice\n\n- (NSString*) modelVersion {\n    size_t size;\n\n    sysctlbyname(\"hw.machine\", NULL, &size, NULL, 0);\n    char* machine = malloc(size);\n    sysctlbyname(\"hw.machine\", machine, &size, NULL, 0);\n    NSString* modelVersion = [NSString stringWithUTF8String:machine];\n    free(machine);\n\n    return modelVersion;\n}\n\n\n- (NSString*) getSerialNr {\n    NSString* serialNr;\n    io_service_t platformExpert = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching(\"IOPlatformExpertDevice\"));\n    if (platformExpert) {\n        CFTypeRef serialNumberAsCFString =\n                IORegistryEntryCreateCFProperty(platformExpert,\n                        CFSTR(kIOPlatformSerialNumberKey),\n                        kCFAllocatorDefault, 0);\n        if (serialNumberAsCFString) {\n            serialNr = (__bridge NSString*) serialNumberAsCFString;\n        }\n        IOObjectRelease(platformExpert);\n    }\n    return serialNr;\n}\n\n- (NSString*) uniqueAppInstanceIdentifier {\n    NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];\n    static NSString* UUID_KEY = @\"CDVUUID\";\n\n    NSString* app_uuid = [userDefaults stringForKey:UUID_KEY];\n\n    if (app_uuid == nil) {\n        CFUUIDRef uuidRef = CFUUIDCreate(kCFAllocatorDefault);\n        CFStringRef uuidString = CFUUIDCreateString(kCFAllocatorDefault, uuidRef);\n\n        app_uuid = [NSString stringWithString:(__bridge NSString*) uuidString];\n        [userDefaults setObject:app_uuid forKey:UUID_KEY];\n        [userDefaults synchronize];\n\n        CFRelease(uuidString);\n        CFRelease(uuidRef);\n    }\n\n    return app_uuid;\n}\n\n- (NSString*) platform {\n    return [NSDictionary dictionaryWithContentsOfFile:SYSTEM_VERSION_PLIST][@\"ProductName\"];\n}\n\n- (NSString*) systemVersion {\n    return [NSDictionary dictionaryWithContentsOfFile:SYSTEM_VERSION_PLIST][@\"ProductVersion\"];\n}\n\n- (void) getDeviceInfo:(CDVInvokedUrlCommand*) command {\n    NSDictionary* deviceProperties = [self deviceProperties];\n    CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:deviceProperties];\n\n    [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];\n}\n\n- (NSDictionary*) deviceProperties {\n    NSMutableDictionary* devProps = [NSMutableDictionary dictionaryWithCapacity:4];\n\n    devProps[@\"manufacturer\"] = @\"Apple\";\n    devProps[@\"model\"] = [self modelVersion];\n    devProps[@\"platform\"] = [self platform];\n    devProps[@\"version\"] = [self systemVersion];\n    devProps[@\"uuid\"] = [self uniqueAppInstanceIdentifier];\n    devProps[@\"cordova\"] = [[self class] cordovaVersion];\n    devProps[@\"serial\"] = [self getSerialNr];\n    devProps[@\"isVirtual\"] = @NO;\n\n    NSDictionary* devReturn = [NSDictionary dictionaryWithDictionary:devProps];\n    return devReturn;\n}\n\n+ (NSString*) cordovaVersion {\n    return CDV_VERSION;\n}\n\n@end\n"
  },
  {
    "path": "plugins/cordova-plugin-device/src/tizen/DeviceProxy.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\nvar tizen = require('cordova/platform');\n\nmodule.exports = {\n    getDeviceInfo: function(success, error) {\n        setTimeout(function () {\n            success({\n                cordova: tizen.cordovaVersion,\n                platform: 'tizen',\n                model: null,\n                version: null,\n                uuid: null\n            });\n        }, 0);\n    }\n};\n\nrequire(\"cordova/tizen/commandProxy\").add(\"Device\", module.exports);\n"
  },
  {
    "path": "plugins/cordova-plugin-device/src/ubuntu/device.cpp",
    "content": "/*\n *  Copyright 2011 Wolfgang Koller - http://www.gofg.at/\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n */\n\n#include <QDeviceInfo>\n#include <QtSystemInfo>\n\n#include\"device.h\"\n\n#define CORDOVA \"3.0.0\"\n\nDevice::Device(Cordova *cordova) : CPlugin(cordova) {\n}\n\nstatic QString getOSName() {\n#ifdef Q_OS_SYMBIAN\n    QString platform = \"Symbian\";\n#endif\n#ifdef Q_OS_WIN\n    QString platform = \"Windows\";\n#endif\n#ifdef Q_OS_WINCE\n    QString platform = \"Windows CE\";\n#endif\n#ifdef Q_OS_LINUX\n    QString platform = \"Linux\";\n#endif\n    return platform;\n}\n\nvoid Device::getInfo(int scId, int ecId) {\n    Q_UNUSED(ecId)\n\n    QDeviceInfo systemDeviceInfo;\n    QDeviceInfo systemInfo;\n\n    QString platform = getOSName();\n\n    QString uuid = systemDeviceInfo.uniqueDeviceID();\n    if (uuid.isEmpty()) {\n        QString deviceDescription = systemInfo.imei(0) + \";\" + systemInfo.manufacturer() + \";\" + systemInfo.model() + \";\" + systemInfo.productName() + \";\" + platform;\n        QString user = qgetenv(\"USER\");\n        if (user.isEmpty()) {\n            user = qgetenv(\"USERNAME\");\n            if (user.isEmpty())\n                user = QDir::homePath();\n        }\n        uuid = QString(QCryptographicHash::hash((deviceDescription + \";\" + user).toUtf8(), QCryptographicHash::Md5).toHex());\n    }\n\n    this->cb(scId, systemDeviceInfo.model(), CORDOVA, platform, uuid, systemInfo.version(QDeviceInfo::Os));\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-device/src/ubuntu/device.h",
    "content": "/*\n *  Copyright 2011 Wolfgang Koller - http://www.gofg.at/\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n */\n\n#ifndef DEVICE_H_FDSAFAS\n#define DEVICE_H_FDSAFAS\n\n#include <QtCore>\n\n#include <cplugin.h>\n\nclass Device: public CPlugin {\n    Q_OBJECT\npublic:\n    explicit Device(Cordova *cordova);\n\n    virtual const QString fullName() override {\n        return Device::fullID();\n    }\n\n    virtual const QString shortName() override {\n        return \"Device\";\n    }\n\n    static const QString fullID() {\n        return \"com.cordova.Device\";\n    }\n\nsignals:\n\npublic slots:\n    void getInfo(int scId, int ecId);\n};\n\n#endif\n"
  },
  {
    "path": "plugins/cordova-plugin-device/src/ubuntu/device.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/* global Cordova */\n\nmodule.exports = {\n    getInfo:function(win,fail,args) {\n        Cordova.exec(function (model, cordova, platform, uuid, version) {\n            win({name: name, model: model, cordova: cordova,\n                 platform: platform, uuid: uuid, version: version});\n        }, null, \"com.cordova.Device\", \"getInfo\", []);\n    }\n};\n\nrequire(\"cordova/exec/proxy\").add(\"Device\", module.exports);\n"
  },
  {
    "path": "plugins/cordova-plugin-device/src/windows/DeviceProxy.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/* global Windows, createUUID */\n\nvar ROOT_CONTAINER = \"{00000000-0000-0000-FFFF-FFFFFFFFFFFF}\";\nvar DEVICE_CLASS_KEY = \"{A45C254E-DF1C-4EFD-8020-67D146A850E0},10\";\nvar DEVICE_CLASS_KEY_NO_SEMICOLON = \"{A45C254E-DF1C-4EFD-8020-67D146A850E0}10\";\nvar ROOT_CONTAINER_QUERY = \"System.Devices.ContainerId:=\\\"\" + ROOT_CONTAINER + \"\\\"\";\nvar HAL_DEVICE_CLASS = \"4d36e966-e325-11ce-bfc1-08002be10318\";\nvar DEVICE_DRIVER_VERSION_KEY = \"{A8B865DD-2E3D-4094-AD97-E593A70C75D6},3\";\n\nmodule.exports = {\n\n    getDeviceInfo:function(win, fail, args) {\n\n        // deviceId aka uuid, stored in Windows.Storage.ApplicationData.current.localSettings.values.deviceId\n        var deviceId;\n        // get deviceId, or create and store one\n        var localSettings = Windows.Storage.ApplicationData.current.localSettings;\n        if (localSettings.values.deviceId) {\n            deviceId = localSettings.values.deviceId;\n        }\n        else {\n            // App-specific hardware id could be used as uuid, but it changes if the hardware changes...\n            try {\n                var ASHWID = Windows.System.Profile.HardwareIdentification.getPackageSpecificToken(null).id;\n                deviceId = Windows.Storage.Streams.DataReader.fromBuffer(ASHWID).readGuid();\n            } catch (e) {\n                // Couldn't get the hardware UUID\n                deviceId = createUUID();\n            }\n            //...so cache it per-install\n            localSettings.values.deviceId = deviceId;\n        }\n\n\n        var userAgent = window.clientInformation.userAgent;\n        // this will report \"windows\" in windows8.1 and windows phone 8.1 apps\n        // and \"windows8\" in windows 8.0 apps similar to cordova.js\n        // See https://github.com/apache/cordova-js/blob/master/src/windows/platform.js#L25\n        var devicePlatform = userAgent.indexOf(\"MSAppHost/1.0\") == -1 ? \"windows\" : \"windows8\";\n        var versionString = userAgent.match(/Windows (?:Phone |NT )?([0-9.]+)/)[1];\n\n        var deviceInfo = new Windows.Security.ExchangeActiveSyncProvisioning.EasClientDeviceInformation();\n        // Running in the Windows Simulator is a remote session.\n        // Running in the Windows Phone Emulator has the systemProductName set to \"Virtual\"\n        var isVirtual = Windows.System.RemoteDesktop.InteractiveSession.isRemote || deviceInfo.systemProductName == \"Virtual\";\n        var manufacturer = deviceInfo.systemManufacturer;\n        var model = deviceInfo.systemProductName;\n\n        var Pnp = Windows.Devices.Enumeration.Pnp;\n\n        Pnp.PnpObject.findAllAsync(Pnp.PnpObjectType.device,\n                                [DEVICE_DRIVER_VERSION_KEY, DEVICE_CLASS_KEY],\n                                ROOT_CONTAINER_QUERY)\n        .then(function (rootDevices) {\n                for (var i = 0; i < rootDevices.length; i++) {\n                    var rootDevice = rootDevices[i];\n                    if (!rootDevice.properties) continue;\n                    if (rootDevice.properties[DEVICE_CLASS_KEY_NO_SEMICOLON] == HAL_DEVICE_CLASS) {\n                        versionString = rootDevice.properties[DEVICE_DRIVER_VERSION_KEY];\n                        break;\n                    }\n                }\n\n                setTimeout(function () {\n                    win({ platform: devicePlatform,\n                          version: versionString,\n                          uuid: deviceId,\n                          isVirtual: isVirtual,\n                          model: model,\n                          manufacturer:manufacturer});\n                }, 0);\n        });\n    }\n\n}; // exports\n\nrequire(\"cordova/exec/proxy\").add(\"Device\", module.exports);\n"
  },
  {
    "path": "plugins/cordova-plugin-device/src/wp/Device.cs",
    "content": "﻿/*  \n    Licensed under the Apache License, Version 2.0 (the \"License\");\n    you may not use this file except in compliance with the License.\n    You may obtain a copy of the License at\n    \n    http://www.apache.org/licenses/LICENSE-2.0\n    \n    Unless required by applicable law or agreed to in writing, software\n    distributed under the License is distributed on an \"AS IS\" BASIS,\n    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n    See the License for the specific language governing permissions and\n    limitations under the License.\n*/\n\nusing Microsoft.Phone.Info;\nusing System;\nusing System.IO;\nusing System.IO.IsolatedStorage;\n\nnamespace WPCordovaClassLib.Cordova.Commands\n{\n    public class Device : BaseCommand\n    {\n        public void getDeviceInfo(string notused)\n        {\n            string res = String.Format(\"\\\"name\\\":\\\"{0}\\\",\\\"platform\\\":\\\"{1}\\\",\\\"uuid\\\":\\\"{2}\\\",\\\"version\\\":\\\"{3}\\\",\\\"model\\\":\\\"{4}\\\",\\\"manufacturer\\\":\\\"{5}\\\",\\\"isVirtual\\\":{6}\",\n                                        DeviceStatus.DeviceName,\n                                        Environment.OSVersion.Platform.ToString(),\n                                        UUID,\n                                        Environment.OSVersion.Version.ToString(),\n                                        DeviceStatus.DeviceName,\n                                        DeviceStatus.DeviceManufacturer,\n                                        IsVirtual ? \"true\" : \"false\");\n            DispatchCommandResult(new PluginResult(PluginResult.Status.OK, \"{\" + res + \"}\"));\n        }\n\n\n        public bool IsVirtual\n        {\n            get \n            {\n                return (Microsoft.Devices.Environment.DeviceType == Microsoft.Devices.DeviceType.Emulator);\n            }\n        }\n\n        public string UUID\n        {\n            get\n            {\n                object id;\n\n                UserExtendedProperties.TryGetValue(\"ANID\", out id);\n                if (id != null)\n                {\n                    return id.ToString().Substring(2, 32);\n                }\n\n                UserExtendedProperties.TryGetValue(\"ANID2\", out id);\n                if (id != null)\n                {\n                    return id.ToString();\n                }\n\n                string returnVal = \"???unknown???\";\n\n                using (IsolatedStorageFile appStorage = IsolatedStorageFile.GetUserStoreForApplication())\n                {\n                    try\n                    {\n                        IsolatedStorageFileStream fileStream = new IsolatedStorageFileStream(\"DeviceID.txt\", FileMode.Open, FileAccess.Read, appStorage);\n\n                        using (StreamReader reader = new StreamReader(fileStream))\n                        {\n                            returnVal = reader.ReadLine();\n                        }\n                    }\n                    catch (Exception /*ex*/)\n                    {\n\n                    }\n                }\n\n                return returnVal;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-device/tests/plugin.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  Licensed to the Apache Software Foundation (ASF) under one\n  or more contributor license agreements.  See the NOTICE file\n  distributed with this work for additional information\n  regarding copyright ownership.  The ASF licenses this file\n  to you under the Apache License, Version 2.0 (the\n  \"License\"); you may not use this file except in compliance\n  with the License.  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing,\n  software distributed under the License is distributed on an\n  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n  KIND, either express or implied.  See the License for the\n  specific language governing permissions and limitations\n  under the License.\n-->\n\n<plugin xmlns=\"http://apache.org/cordova/ns/plugins/1.0\"\n    xmlns:rim=\"http://www.blackberry.com/ns/widgets\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    id=\"cordova-plugin-device-tests\"\n    version=\"1.1.2\">\n    <name>Cordova Device Plugin Tests</name>\n    <license>Apache 2.0</license>\n\n    <js-module src=\"tests.js\" name=\"tests\">\n    </js-module>\n</plugin>\n"
  },
  {
    "path": "plugins/cordova-plugin-device/tests/tests.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/* jshint jasmine: true */\n\nexports.defineAutoTests = function() {\n  describe('Device Information (window.device)', function () {\n    it(\"should exist\", function() {\n      expect(window.device).toBeDefined();\n    });\n\n    it(\"should contain a platform specification that is a string\", function() {\n      expect(window.device.platform).toBeDefined();\n      expect((String(window.device.platform)).length > 0).toBe(true);\n    });\n\n    it(\"should contain a version specification that is a string\", function() {\n      expect(window.device.version).toBeDefined();\n      expect((String(window.device.version)).length > 0).toBe(true);\n    });\n\n    it(\"should contain a UUID specification that is a string or a number\", function() {\n      expect(window.device.uuid).toBeDefined();\n      if (typeof window.device.uuid == 'string' || typeof window.device.uuid == 'object') {\n        expect((String(window.device.uuid)).length > 0).toBe(true);\n      } else {\n        expect(window.device.uuid > 0).toBe(true);\n      }\n    });\n\n    it(\"should contain a cordova specification that is a string\", function() {\n      expect(window.device.cordova).toBeDefined();\n      expect((String(window.device.cordova)).length > 0).toBe(true);\n    });\n\n    it(\"should depend on the presence of cordova.version string\", function() {\n      expect(window.cordova.version).toBeDefined();\n      expect((String(window.cordova.version)).length > 0).toBe(true);\n    });\n\n    it(\"should contain device.cordova equal to cordova.version\", function() {\n      expect(window.device.cordova).toBe(window.cordova.version);\n    });\n\n    it(\"should contain a model specification that is a string\", function() {\n      expect(window.device.model).toBeDefined();\n      expect((String(window.device.model)).length > 0).toBe(true);\n    });\n\n    it(\"should contain a manufacturer property that is a string\", function() {\n      expect(window.device.manufacturer).toBeDefined();\n      expect((String(window.device.manufacturer)).length > 0).toBe(true);\n    });\n\n    it(\"should contain an isVirtual property that is a boolean\", function() {\n      expect(window.device.isVirtual).toBeDefined();\n      expect(typeof window.device.isVirtual).toBe(\"boolean\");\n    });\n\n    it(\"should contain a serial number specification that is a string\", function() {\n      expect(window.device.serial).toBeDefined();\n      expect((String(window.device.serial)).length > 0).toBe(true);\n\n    });\n\n  });\n};\n\nexports.defineManualTests = function(contentEl, createActionButton) {\n    var logMessage = function (message, color) {\n        var log = document.getElementById('info');\n        var logLine = document.createElement('div');\n        if (color) {\n            logLine.style.color = color;\n        }\n        logLine.innerHTML = message;\n        log.appendChild(logLine);\n    };\n\n    var clearLog = function () {\n        var log = document.getElementById('info');\n        log.innerHTML = '';\n    };\n\n    var device_tests = '<h3>Press Dump Device button to get device information</h3>' +\n        '<div id=\"dump_device\"></div>' +\n        'Expected result: Status box will get updated with device info. (i.e. platform, version, uuid, model, etc)';\n\n    contentEl.innerHTML = '<div id=\"info\"></div>' + device_tests;\n\n    createActionButton('Dump device', function() {\n      clearLog();\n      logMessage(JSON.stringify(window.device, null, '\\t'));\n    }, \"dump_device\");\n};\n"
  },
  {
    "path": "plugins/cordova-plugin-device/www/device.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\nvar argscheck = require('cordova/argscheck'),\n    channel = require('cordova/channel'),\n    utils = require('cordova/utils'),\n    exec = require('cordova/exec'),\n    cordova = require('cordova');\n\nchannel.createSticky('onCordovaInfoReady');\n// Tell cordova channel to wait on the CordovaInfoReady event\nchannel.waitForInitialization('onCordovaInfoReady');\n\n/**\n * This represents the mobile device, and provides properties for inspecting the model, version, UUID of the\n * phone, etc.\n * @constructor\n */\nfunction Device() {\n    this.available = false;\n    this.platform = null;\n    this.version = null;\n    this.uuid = null;\n    this.cordova = null;\n    this.model = null;\n    this.manufacturer = null;\n    this.isVirtual = null;\n    this.serial = null;\n\n    var me = this;\n\n    channel.onCordovaReady.subscribe(function() {\n        me.getInfo(function(info) {\n            //ignoring info.cordova returning from native, we should use value from cordova.version defined in cordova.js\n            //TODO: CB-5105 native implementations should not return info.cordova\n            var buildLabel = cordova.version;\n            me.available = true;\n            me.platform = info.platform;\n            me.version = info.version;\n            me.uuid = info.uuid;\n            me.cordova = buildLabel;\n            me.model = info.model;\n            me.isVirtual = info.isVirtual;\n            me.manufacturer = info.manufacturer || 'unknown';\n            me.serial = info.serial || 'unknown';\n            channel.onCordovaInfoReady.fire();\n        },function(e) {\n            me.available = false;\n            utils.alert(\"[ERROR] Error initializing Cordova: \" + e);\n        });\n    });\n}\n\n/**\n * Get device info\n *\n * @param {Function} successCallback The function to call when the heading data is available\n * @param {Function} errorCallback The function to call when there is an error getting the heading data. (OPTIONAL)\n */\nDevice.prototype.getInfo = function(successCallback, errorCallback) {\n    argscheck.checkArgs('fF', 'Device.getInfo', arguments);\n    exec(successCallback, errorCallback, \"Device\", \"getDeviceInfo\", []);\n};\n\nmodule.exports = new Device();\n"
  },
  {
    "path": "plugins/cordova-plugin-dialogs/CONTRIBUTING.md",
    "content": "<!--\n#\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#  KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n#\n-->\n\n# Contributing to Apache Cordova\n\nAnyone can contribute to Cordova. And we need your contributions.\n\nThere are multiple ways to contribute: report bugs, improve the docs, and\ncontribute code.\n\nFor instructions on this, start with the \n[contribution overview](http://cordova.apache.org/contribute/).\n\nThe details are explained there, but the important items are:\n - Sign and submit an Apache ICLA (Contributor License Agreement).\n - Have a Jira issue open that corresponds to your contribution.\n - Run the tests so your patch doesn't break existing functionality.\n\nWe look forward to your contributions!\n"
  },
  {
    "path": "plugins/cordova-plugin-dialogs/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License."
  },
  {
    "path": "plugins/cordova-plugin-dialogs/NOTICE",
    "content": "Apache Cordova\nCopyright 2012 The Apache Software Foundation\n\nThis product includes software developed at\nThe Apache Software Foundation (http://www.apache.org/).\n"
  },
  {
    "path": "plugins/cordova-plugin-dialogs/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-dialogs.svg?branch=master)](https://travis-ci.org/apache/cordova-plugin-dialogs)\n\n# cordova-plugin-dialogs\n\nThis plugin provides access to some native dialog UI elements\nvia a global `navigator.notification` object.\n\nAlthough the object is attached to the global scoped `navigator`, it is not available until after the `deviceready` event.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(navigator.notification);\n    }\n\nReport issues on the [Apache Cordova issue tracker](https://issues.apache.org/jira/issues/?jql=project%20%3D%20CB%20AND%20status%20in%20%28Open%2C%20%22In%20Progress%22%2C%20Reopened%29%20AND%20resolution%20%3D%20Unresolved%20AND%20component%20%3D%20%22Plugin%20Dialogs%22%20ORDER%20BY%20priority%20DESC%2C%20summary%20ASC%2C%20updatedDate%20DESC)\n\n## Installation\n\n    cordova plugin add cordova-plugin-dialogs\n\n## Methods\n\n- `navigator.notification.alert`\n- `navigator.notification.confirm`\n- `navigator.notification.prompt`\n- `navigator.notification.beep`\n\n## navigator.notification.alert\n\nShows a custom alert or dialog box.  Most Cordova implementations use a native\ndialog box for this feature, but some platforms use the browser's `alert`\nfunction, which is typically less customizable.\n\n    navigator.notification.alert(message, alertCallback, [title], [buttonName])\n\n- __message__: Dialog message. _(String)_\n\n- __alertCallback__: Callback to invoke when alert dialog is dismissed. _(Function)_\n\n- __title__: Dialog title. _(String)_ (Optional, defaults to `Alert`)\n\n- __buttonName__: Button name. _(String)_ (Optional, defaults to `OK`)\n\n\n### Example\n\n    function alertDismissed() {\n        // do something\n    }\n\n    navigator.notification.alert(\n        'You are the winner!',  // message\n        alertDismissed,         // callback\n        'Game Over',            // title\n        'Done'                  // buttonName\n    );\n\n### Supported Platforms\n\n- Amazon Fire OS\n- Android\n- BlackBerry 10\n- Firefox OS\n- iOS\n- Tizen\n- Windows Phone 7 and 8\n- Windows 8\n- Windows\n\n### Windows Phone 7 and 8 Quirks\n\n- There is no built-in browser alert, but you can bind one as follows to call `alert()` in the global scope:\n\n        window.alert = navigator.notification.alert;\n\n- Both `alert` and `confirm` are non-blocking calls, results of which are only available asynchronously.\n\n### Firefox OS Quirks:\n\nBoth native-blocking `window.alert()` and non-blocking `navigator.notification.alert()` are available.\n\n### BlackBerry 10 Quirks\n`navigator.notification.alert('text', callback, 'title', 'text')` callback parameter is passed the number 1.\n\n## navigator.notification.confirm\n\nDisplays a customizable confirmation dialog box.\n\n    navigator.notification.confirm(message, confirmCallback, [title], [buttonLabels])\n\n- __message__: Dialog message. _(String)_\n\n- __confirmCallback__: Callback to invoke with index of button pressed (1, 2, or 3) or when the dialog is dismissed without a button press (0). _(Function)_\n\n- __title__: Dialog title. _(String)_ (Optional, defaults to `Confirm`)\n\n- __buttonLabels__: Array of strings specifying button labels. _(Array)_  (Optional, defaults to [`OK,Cancel`])\n\n\n### confirmCallback\n\nThe `confirmCallback` executes when the user presses one of the\nbuttons in the confirmation dialog box.\n\nThe callback takes the argument `buttonIndex` _(Number)_, which is the\nindex of the pressed button. Note that the index uses one-based\nindexing, so the value is `1`, `2`, `3`, etc.\n\n### Example\n\n    function onConfirm(buttonIndex) {\n        alert('You selected button ' + buttonIndex);\n    }\n\n    navigator.notification.confirm(\n        'You are the winner!', // message\n         onConfirm,            // callback to invoke with index of button pressed\n        'Game Over',           // title\n        ['Restart','Exit']     // buttonLabels\n    );\n\n### Supported Platforms\n\n- Amazon Fire OS\n- Android\n- BlackBerry 10\n- Firefox OS\n- iOS\n- Tizen\n- Windows Phone 7 and 8\n- Windows 8\n- Windows\n\n### Windows Phone 7 and 8 Quirks\n\n- There is no built-in browser function for `window.confirm`, but you can bind it by assigning:\n\n        window.confirm = navigator.notification.confirm;\n\n- Calls to `alert` and `confirm` are non-blocking, so the result is only available asynchronously.\n\n### Windows Quirks\n\n- On Windows8/8.1 it is not possible to add more than three buttons to MessageDialog instance.\n\n- On Windows Phone 8.1 it's not possible to show dialog with more than two buttons.\n\n### Firefox OS Quirks:\n\nBoth native-blocking `window.confirm()` and non-blocking `navigator.notification.confirm()` are available.\n\n## navigator.notification.prompt\n\nDisplays a native dialog box that is more customizable than the browser's `prompt` function.\n\n    navigator.notification.prompt(message, promptCallback, [title], [buttonLabels], [defaultText])\n\n- __message__: Dialog message. _(String)_\n\n- __promptCallback__: Callback to invoke with index of button pressed (1, 2, or 3) or when the dialog is dismissed without a button press (0). _(Function)_\n\n- __title__: Dialog title _(String)_ (Optional, defaults to `Prompt`)\n\n- __buttonLabels__: Array of strings specifying button labels _(Array)_ (Optional, defaults to `[\"OK\",\"Cancel\"]`)\n\n- __defaultText__: Default textbox input value (`String`) (Optional, Default: empty string)\n\n### promptCallback\n\nThe `promptCallback` executes when the user presses one of the buttons\nin the prompt dialog box. The `results` object passed to the callback\ncontains the following properties:\n\n- __buttonIndex__: The index of the pressed button. _(Number)_ Note that the index uses one-based indexing, so the value is `1`, `2`, `3`, etc.\n\n\n\n- __input1__: The text entered in the prompt dialog box. _(String)_\n\n### Example\n\n    function onPrompt(results) {\n        alert(\"You selected button number \" + results.buttonIndex + \" and entered \" + results.input1);\n    }\n\n    navigator.notification.prompt(\n        'Please enter your name',  // message\n        onPrompt,                  // callback to invoke\n        'Registration',            // title\n        ['Ok','Exit'],             // buttonLabels\n        'Jane Doe'                 // defaultText\n    );\n\n### Supported Platforms\n\n- Amazon Fire OS\n- Android\n- Firefox OS\n- iOS\n- Windows Phone 7 and 8\n- Windows 8\n- Windows\n\n### Android Quirks\n\n- Android supports a maximum of three buttons, and ignores any more than that.\n\n- On Android 3.0 and later, buttons are displayed in reverse order for devices that use the Holo theme.\n\n### Windows Quirks\n\n- On Windows prompt dialog is html-based due to lack of such native api.\n\n### Firefox OS Quirks:\n\nBoth native-blocking `window.prompt()` and non-blocking `navigator.notification.prompt()` are available.\n\n## navigator.notification.beep\n\nThe device plays a beep sound.\n\n    navigator.notification.beep(times);\n\n- __times__: The number of times to repeat the beep. _(Number)_\n\n### Example\n\n    // Beep twice!\n    navigator.notification.beep(2);\n\n### Supported Platforms\n\n- Amazon Fire OS\n- Android\n- BlackBerry 10\n- iOS\n- Tizen\n- Windows Phone 7 and 8\n- Windows 8\n\n### Amazon Fire OS Quirks\n\n- Amazon Fire OS plays the default __Notification Sound__ specified under the __Settings/Display & Sound__ panel.\n\n### Android Quirks\n\n- Android plays the default __Notification ringtone__ specified under the __Settings/Sound & Display__ panel.\n\n### Windows Phone 7 and 8 Quirks\n\n- Relies on a generic beep file from the Cordova distribution.\n\n### Tizen Quirks\n\n- Tizen implements beeps by playing an audio file via the media API.\n\n- The beep file must be short, must be located in a `sounds` subdirectory of the application's root directory, and must be named `beep.wav`.\n"
  },
  {
    "path": "plugins/cordova-plugin-dialogs/RELEASENOTES.md",
    "content": "<!--\n#\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n# \n# http://www.apache.org/licenses/LICENSE-2.0\n# \n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#  KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n#\n-->\n# Release Notes\n\n### 1.2.1 (Apr 15, 2016)\n* CB-10097 dialog doesn't show on **iOS** when called from a select list `onChange` event\n* Remove `warning` emoji, as it doesn't correctly display in the docs website: http://cordova.apache.org/docs/en/dev/cordova-plugin-dialogs/index.html\n* CB-10727 Dialogs plugin has warnings on **iOS**\n* CB-10636 Add `JSHint` for plugins\n\n### 1.2.0 (Nov 18, 2015)\n* [CB-10035](https://issues.apache.org/jira/browse/CB-10035) Updated `RELEASENOTES` to be newest to oldest\n* [CB-8549](https://issues.apache.org/jira/browse/CB-8549) Updated source to pass `Fortify` scan.\n* Fixing contribute link.\n* add `CSS class` to prompt `div` for **Windows** platform\n* [CB-9347](https://issues.apache.org/jira/browse/CB-9347) - fix to allow to stack multiple `UIAlertControllers`\n\n### 1.1.1 (Jun 17, 2015)\n* [CB-9128](https://issues.apache.org/jira/browse/CB-9128) cordova-plugin-dialogs documentation translation: cordova-plugin-dialogs\n* fix npm md\n\n### 1.1.0 (May 06, 2015)\n* [CB-8928](https://issues.apache.org/jira/browse/CB-8928): Removed direct call to `toStaticHTML`, only call it if we are sure it's present. This closes #52\n* [CB-7734](https://issues.apache.org/jira/browse/CB-7734) - `navigator.notification.alert` or `navigator.notification.confirm` seem have a \"many words\" issue. (closes #39)\n \n### 1.0.0 (Apr 15, 2015)\n* [CB-8746](https://issues.apache.org/jira/browse/CB-8746) gave plugin major version bump\n* [CB-8683](https://issues.apache.org/jira/browse/CB-8683) updated wp and bb specific references of old id to new id\n* [CB-8683](https://issues.apache.org/jira/browse/CB-8683) changed plugin-id to pacakge-name\n* [CB-8653](https://issues.apache.org/jira/browse/CB-8653) properly updated translated docs to use new id\n* [CB-8653](https://issues.apache.org/jira/browse/CB-8653) updated translated docs to use new id\n* Use TRAVIS_BUILD_DIR, install paramedic by npm\n* [CB-8653](https://issues.apache.org/jira/browse/CB-8653) Updated Readme\n* [CB-8659](https://issues.apache.org/jira/browse/CB-8659): ios: 4.0.x Compatibility: Remove use of deprecated headers\n* [CB-8565](https://issues.apache.org/jira/browse/CB-8565) Integrate TravisCI\n* [CB-8438](https://issues.apache.org/jira/browse/CB-8438) cordova-plugin-dialogs documentation translation: cordova-plugin-dialogs\n* [CB-8538](https://issues.apache.org/jira/browse/CB-8538) Added package.json file\n* [CB-8367](https://issues.apache.org/jira/browse/CB-8367) [org.apache.cordova.dialogs] Add Prompt support on Windows\n\n### 0.3.0 (Feb 04, 2015)\n* Correct way to specify Windows platform in config.xml\n* [CB-8351](https://issues.apache.org/jira/browse/CB-8351) ios: Use argumentForIndex rather than NSArray extension\n* [CB-7955](https://issues.apache.org/jira/browse/CB-7955) Add support \"browser\" platform\n\n### 0.2.11 (Dec 02, 2014)\n* [CB-7737](https://issues.apache.org/jira/browse/CB-7737) lower min height for alert\n* [CB-8038](https://issues.apache.org/jira/browse/CB-8038) backslash getting escaped twice in **BB10**\n* [CB-8029](https://issues.apache.org/jira/browse/CB-8029) test 1-based indexing for confirm\n* [CB-7639](https://issues.apache.org/jira/browse/CB-7639) Update docs + manual tests\n* [CB-7639](https://issues.apache.org/jira/browse/CB-7639) Revert back `isAlertShowing` flag in case of exception to prevent queuing of future dialogs.\n* [CB-7639](https://issues.apache.org/jira/browse/CB-7639) Handle button labels as array on windows\n* [CB-7977](https://issues.apache.org/jira/browse/CB-7977) Mention `deviceready` in plugin docs\n* Check for `setTextDirection` API level\n* **Android** Make spinner dialog to use `THEME_DEVICE_DEFAULT_LIGHT` (same as the other dialogs)\n* **Android** Unbreak `API` level < `14`\n* [CB-7414](https://issues.apache.org/jira/browse/CB-7414) **BB10** Document callback parameter for `navigator.notification.alert`\n* [CB-7700](https://issues.apache.org/jira/browse/CB-7700) cordova-plugin-dialogs documentation translation: cordova-plugin-dialogs\n* [CB-7571](https://issues.apache.org/jira/browse/CB-7571) Bump version of nested plugin to match parent plugin\n\n### 0.2.10 (Sep 17, 2014)\n* [CB-7538](https://issues.apache.org/jira/browse/CB-7538) Android beep thread fix Beep now executes in it's own thread. It was previously executing in the main UI thread which was causing the application to lock up will the beep was occurring.  Closing pull request\n* Set dialog text dir to locale\n* Renamed test dir, added nested plugin.xml\n* added documentation for manual tests\n* [CB-6965](https://issues.apache.org/jira/browse/CB-6965) Added manual tests\n* [CB-6965](https://issues.apache.org/jira/browse/CB-6965) Port notification tests to test-framework\n\n### 0.2.9 (Aug 06, 2014)\n* ubuntu: pass proper arguments to prompt callback\n* ubuntu: use TextField instead of TextInput\n* ubuntu: proper message escaping before passing to qml\n* **FFOS** update notification.js\n* [CB-6127](https://issues.apache.org/jira/browse/CB-6127) Updated translations for docs\n* android: Explicitly apply default theme to dialogs\n* Fix Beep exception on Android when no argument passed\n\n### 0.2.8 (Jun 05, 2014)\n* [CB-6801](https://issues.apache.org/jira/browse/CB-6801) Add license\n* running original windows.open, inAppBrowser is overriding it no need to place CSS in every page anymore\n* [CB-5945](https://issues.apache.org/jira/browse/CB-5945) [Windows8] do not call success callbacks until dialog is dismissed\n* [CB-4616](https://issues.apache.org/jira/browse/CB-4616) Returned index 0 was not documented for notification.prompt\n* update docs to state that prompt is supported on windowsphone\n* [CB-6528](https://issues.apache.org/jira/browse/CB-6528) allow scroll on alert message content\n* [CB-6628][amazon-fireos]dialogs plugin's confirm and prompt methods dont work confirm() method was missing amazon-fireos platform check. added that. prompt() method had bug. It is executed in a worker thread that does not have a message queue(or Looper object) associated with it and hence \"can't create a handler\" exception is thrown. To fix this issue, we need to create the EditText widget from within the UI thread. This was fixed sometime ago when we added fireos platform but commit got lost somewhere. So fixing it again now.\n* [CB-6491](https://issues.apache.org/jira/browse/CB-6491) add CONTRIBUTING.md\n* Added check for isFinishing() on the parent activity to prevent crashes when trying to display dialogs when activity is in this phase of it's lifecycle\n* [CB-4966](https://issues.apache.org/jira/browse/CB-4966) Dialogs are in window now No need to add anything to manifest or index.html\n* Removing FirefoxOS Quirks * no need to add special permission (it's different API with the same name) * notification.css is added automatically\n\n### 0.2.7 (Apr 17, 2014)\n* [CB-6212](https://issues.apache.org/jira/browse/CB-6212): [iOS] fix warnings compiled under arm64 64-bit\n* [CB-6411](https://issues.apache.org/jira/browse/CB-6411): [BlackBerry10] Work around Audio playback issue\n* [CB-6411](https://issues.apache.org/jira/browse/CB-6411): [BlackBerry10] Updates to beep\n* [CB-6422](https://issues.apache.org/jira/browse/CB-6422): [windows8] use cordova/exec/proxy\n* [CB-6460](https://issues.apache.org/jira/browse/CB-6460): Update license headers\n* Add NOTICE file\n\n### 0.2.6 (Feb 05, 2014)\n* no need to recreate the manifest.webapp file after each `cordova prepare` for FFOS\n* FFOS description added\n\n### 0.2.5 (Jan 02, 2014)\n* [CB-4696](https://issues.apache.org/jira/browse/CB-4696) Fix compile error for Xcode 4.5.\n* [CB-5658](https://issues.apache.org/jira/browse/CB-5658) Add doc/index.md for Dialogs plugin\n* [CB-3762](https://issues.apache.org/jira/browse/CB-3762) Change prompt default to empty string\n* Move images from css to img\n\n### 0.2.4 (Dec 4, 2013)\n* add ubuntu platform\n* 1. Added amazon-fireos platform. 2. Change to use amazon-fireos as a platform if user agent string contains 'cordova-amazon-fireos'.\n* added beep funtionality using ms-winsoundevent:Notfication.Default\n\n### 0.2.3 (Oct 28, 2013)\n* [CB-5128](https://issues.apache.org/jira/browse/CB-5128): added repo + issue tag to plugin.xml for dialogs plugin\n* new plugin execute arguments supported\n* new plugin style\n* smaller fonts styling input\n* img files copied inside plugin\n* style added\n* prompt added\n* styling from James\n* fixed \"exec\" calls addedd css, but not working yet\n* first (blind) try\n* [CB-4915](https://issues.apache.org/jira/browse/CB-4915) Incremented plugin version on dev branch.\n\n### 0.2.2 (Sept 25, 2013)\n* [CB-4889](https://issues.apache.org/jira/browse/CB-4889) bumping&resetting version\n* [windows8] commandProxy was moved\n* [CB-4889](https://issues.apache.org/jira/browse/CB-4889) renaming reference in Notification.cs\n* [CB-4889](https://issues.apache.org/jira/browse/CB-4889) renaming org.apache.cordova.core.dialogs to org.apache.cordova.dialogs\n* Rename CHANGELOG.md -> RELEASENOTES.md\n* [CB-4592](https://issues.apache.org/jira/browse/CB-4592) [Blackberry10] Added beep support\n* [CB-4752](https://issues.apache.org/jira/browse/CB-4752) Incremented plugin version on dev branch.\n"
  },
  {
    "path": "plugins/cordova-plugin-dialogs/doc/de/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-dialogs\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-dialogs.svg)](https://travis-ci.org/apache/cordova-plugin-dialogs)\n\nDieses Plugin ermöglicht den Zugriff auf einige native Dialog-UI-Elemente über eine globale `navigator.notification`-Objekt.\n\nObwohl das Objekt mit der globalen Gültigkeitsbereich `navigator` verbunden ist, steht es nicht bis nach dem `Deviceready`-Ereignis.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(navigator.notification);\n    }\n    \n\n## Installation\n\n    cordova plugin add cordova-plugin-dialogs\n    \n\n## Methoden\n\n  * `navigator.notification.alert`\n  * `navigator.notification.confirm`\n  * `navigator.notification.prompt`\n  * `navigator.notification.beep`\n\n## navigator.notification.alert\n\nZeigt eine benutzerdefinierte Warnung oder Dialogfeld Feld. Die meisten Implementierungen von Cordova ein native Dialogfeld für dieses Feature verwenden, jedoch einige Plattformen des Browsers-`alert`-Funktion, die in der Regel weniger anpassbar ist.\n\n    navigator.notification.alert(message, alertCallback, [title], [buttonName])\n    \n\n  * **Nachricht**: Dialogfeld Nachricht. *(String)*\n\n  * **AlertCallback**: Callback aufgerufen wird, wenn Warnungs-Dialogfeld geschlossen wird. *(Funktion)*\n\n  * **Titel**: Dialog \"Titel\". *(String)* (Optional, Standard ist`Alert`)\n\n  * **ButtonName**: Name der Schaltfläche. *(String)* (Optional, Standard ist`OK`)\n\n### Beispiel\n\n    function alertDismissed() {\n        // do something\n    }\n    \n    navigator.notification.alert(\n        'You are the winner!',  // message\n        alertDismissed,         // callback\n        'Game Over',            // title\n        'Done'                  // buttonName\n    );\n    \n\n### Unterstützte Plattformen\n\n  * Amazon Fire OS\n  * Android\n  * BlackBerry 10\n  * Firefox OS\n  * iOS\n  * Tizen\n  * Windows Phone 7 und 8\n  * Windows 8\n  * Windows\n\n### Windows Phone 7 und 8 Eigenarten\n\n  * Es gibt keine eingebaute Datenbanksuchroutine-Warnung, aber Sie können binden, wie folgt zu nennen `alert()` im globalen Gültigkeitsbereich:\n    \n        window.alert = navigator.notification.alert;\n        \n\n  * Beide `alert` und `confirm` sind nicht blockierende Aufrufe, die Ergebnisse davon nur asynchron sind.\n\n### Firefox OS Macken:\n\nNative blockierenden `window.alert()` und nicht-blockierende `navigator.notification.alert()` zur Verfügung.\n\n### BlackBerry 10 Macken\n\n`navigator.notification.alert ('Text', Rückruf, 'Titel', 'Text')` Callback-Parameter wird die Zahl 1 übergeben.\n\n## navigator.notification.confirm\n\nZeigt das Dialogfeld anpassbare Bestätigung.\n\n    navigator.notification.confirm(message, confirmCallback, [title], [buttonLabels])\n    \n\n  * **Nachricht**: Dialogfeld Nachricht. *(String)*\n\n  * **ConfirmCallback**: Callback aufgerufen wird, mit Index gedrückt (1, 2 oder 3) oder wenn das Dialogfeld geschlossen wird, ohne einen Tastendruck (0). *(Funktion)*\n\n  * **Titel**: Dialog \"Titel\". *(String)* (Optional, Standard ist`Confirm`)\n\n  * **ButtonLabels**: Array von Zeichenfolgen, die Schaltflächenbezeichnungen angeben. *(Array)* (Optional, Standard ist [ `OK,Cancel` ])\n\n### confirmCallback\n\nDie `confirmCallback` wird ausgeführt, wenn der Benutzer eine der Schaltflächen im Dialogfeld zur Bestätigung drückt.\n\nDer Rückruf dauert das Argument `buttonIndex` *(Anzahl)*, die der Index der Schaltfläche gedrückt ist. Beachten Sie, dass der Index 1-basierte Indizierung, sodass der Wert `1`, `2`, `3` usw. ist.\n\n### Beispiel\n\n    function onConfirm(buttonIndex) {\n        alert('You selected button ' + buttonIndex);\n    }\n    \n    navigator.notification.confirm(\n        'You are the winner!', // message\n         onConfirm,            // callback to invoke with index of button pressed\n        'Game Over',           // title\n        ['Restart','Exit']     // buttonLabels\n    );\n    \n\n### Unterstützte Plattformen\n\n  * Amazon Fire OS\n  * Android\n  * BlackBerry 10\n  * Firefox OS\n  * iOS\n  * Tizen\n  * Windows Phone 7 und 8\n  * Windows 8\n  * Windows\n\n### Windows Phone 7 und 8 Eigenarten\n\n  * Es gibt keine integrierte Browser-Funktion für `window.confirm` , aber Sie können es binden, indem Sie zuweisen:\n    \n        window.confirm = navigator.notification.confirm;\n        \n\n  * Aufrufe von `alert` und `confirm` sind nicht blockierend, so dass das Ergebnis nur asynchron zur Verfügung steht.\n\n### Windows-Eigenheiten\n\n  * Auf Windows8/8.1 kann nicht mehr als drei Schaltflächen MessageDialog-Instanz hinzu.\n\n  * Auf Windows Phone 8.1 ist es nicht möglich, Dialog mit mehr als zwei Knöpfen zeigen.\n\n### Firefox OS Macken:\n\nNative blockierenden `window.confirm()` und nicht-blockierende `navigator.notification.confirm()` zur Verfügung.\n\n## navigator.notification.prompt\n\nZeigt eine native Dialogfeld, das mehr als `Prompt`-Funktion des Browsers anpassbar ist.\n\n    navigator.notification.prompt(message, promptCallback, [title], [buttonLabels], [defaultText])\n    \n\n  * **Nachricht**: Dialogfeld Nachricht. *(String)*\n\n  * **promptCallback**: Callback aufgerufen wird, mit Index gedrückt (1, 2 oder 3) oder wenn das Dialogfeld geschlossen wird, ohne einen Tastendruck (0). *(Funktion)*\n\n  * **title**: Dialog Title *(String)* (Optional, Standard ist `Prompt`)\n\n  * **buttonLabels**: Array von Zeichenfolgen angeben Schaltfläche Etiketten *(Array)* (Optional, Standard ist `[\"OK\", \"Abbrechen\"]`)\n\n  * **defaultText**: Standard-Textbox Eingabewert (`String`) (Optional, Standard: leere Zeichenfolge)\n\n### promptCallback\n\nDie `promptCallback` wird ausgeführt, wenn der Benutzer eine der Schaltflächen im Eingabedialogfeld drückt. `Des Objekts an den Rückruf übergeben` enthält die folgenden Eigenschaften:\n\n  * **buttonIndex**: der Index der Schaltfläche gedrückt. *(Anzahl)* Beachten Sie, dass der Index 1-basierte Indizierung, sodass der Wert `1`, `2`, `3` usw. ist.\n\n  * **input1**: in Eingabedialogfeld eingegebenen Text. *(String)*\n\n### Beispiel\n\n    function onPrompt(results) {\n        alert(\"You selected button number \" + results.buttonIndex + \" and entered \" + results.input1);\n    }\n    \n    navigator.notification.prompt(\n        'Please enter your name',  // message\n        onPrompt,                  // callback to invoke\n        'Registration',            // title\n        ['Ok','Exit'],             // buttonLabels\n        'Jane Doe'                 // defaultText\n    );\n    \n\n### Unterstützte Plattformen\n\n  * Amazon Fire OS\n  * Android\n  * Firefox OS\n  * iOS\n  * Windows Phone 7 und 8\n  * Windows 8\n  * Windows\n\n### Android Eigenarten\n\n  * Android unterstützt maximal drei Schaltflächen und mehr als das ignoriert.\n\n  * Auf Android 3.0 und höher, werden die Schaltflächen in umgekehrter Reihenfolge für Geräte angezeigt, die das Holo-Design verwenden.\n\n### Windows-Eigenheiten\n\n  * Unter Windows ist Prompt Dialogfeld html-basierten mangels solcher native api.\n\n### Firefox OS Macken:\n\nNative blockierenden `window.prompt()` und nicht-blockierende `navigator.notification.prompt()` zur Verfügung.\n\n## navigator.notification.beep\n\nDas Gerät spielt einen Signalton sound.\n\n    navigator.notification.beep(times);\n    \n\n  * **times**: die Anzahl der Wiederholungen des Signaltons. *(Anzahl)*\n\n### Beispiel\n\n    // Beep twice!\n    navigator.notification.beep(2);\n    \n\n### Unterstützte Plattformen\n\n  * Amazon Fire OS\n  * Android\n  * BlackBerry 10\n  * iOS\n  * Tizen\n  * Windows Phone 7 und 8\n  * Windows 8\n\n### Amazon Fire OS Macken\n\n  * Amazon Fire OS spielt die Standardeinstellung **Akustische Benachrichtigung** unter **Einstellungen/Display & Sound** Bereich angegeben.\n\n### Android Eigenarten\n\n  * Android spielt die Standardeinstellung **Benachrichtigung Klingelton** unter **Einstellungen/Sound & Display**-Panel angegeben.\n\n### Windows Phone 7 und 8 Eigenarten\n\n  * Stützt sich auf eine generische Piepton-Datei aus der Cordova-Distribution.\n\n### Tizen Macken\n\n  * Tizen implementiert Signaltöne durch Abspielen einer Audiodatei über die Medien API.\n\n  * Die Beep-Datei muss kurz sein, in einem `sounds`-Unterverzeichnis des Stammverzeichnisses der Anwendung befinden muss und muss den Namen `beep.wav`."
  },
  {
    "path": "plugins/cordova-plugin-dialogs/doc/de/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-dialogs\n\nDieses Plugin ermöglicht den Zugriff auf einige native Dialog-UI-Elemente über eine globale `navigator.notification`-Objekt.\n\nObwohl das Objekt mit der globalen Gültigkeitsbereich `navigator` verbunden ist, steht es nicht bis nach dem `Deviceready`-Ereignis.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(navigator.notification);\n    }\n    \n\n## Installation\n\n    cordova plugin add cordova-plugin-dialogs\n    \n\n## Methoden\n\n*   `navigator.notification.alert`\n*   `navigator.notification.confirm`\n*   `navigator.notification.prompt`\n*   `navigator.notification.beep`\n\n## navigator.notification.alert\n\nZeigt eine benutzerdefinierte Warnung oder Dialogfeld Feld. Die meisten Implementierungen von Cordova ein native Dialogfeld für dieses Feature verwenden, jedoch einige Plattformen des Browsers-`alert`-Funktion, die in der Regel weniger anpassbar ist.\n\n    navigator.notification.alert(message, alertCallback, [title], [buttonName])\n    \n\n*   **Nachricht**: Dialogfeld Nachricht. *(String)*\n\n*   **AlertCallback**: Callback aufgerufen wird, wenn Warnungs-Dialogfeld geschlossen wird. *(Funktion)*\n\n*   **Titel**: Dialog \"Titel\". *(String)* (Optional, Standard ist`Alert`)\n\n*   **ButtonName**: Name der Schaltfläche. *(String)* (Optional, Standard ist`OK`)\n\n### Beispiel\n\n    function alertDismissed() {\n        // do something\n    }\n    \n    navigator.notification.alert(\n        'You are the winner!',  // message\n        alertDismissed,         // callback\n        'Game Over',            // title\n        'Done'                  // buttonName\n    );\n    \n\n### Unterstützte Plattformen\n\n*   Amazon Fire OS\n*   Android\n*   BlackBerry 10\n*   Firefox OS\n*   iOS\n*   Tizen\n*   Windows Phone 7 und 8\n*   Windows 8\n*   Windows\n\n### Windows Phone 7 und 8 Eigenarten\n\n*   Es gibt keine eingebaute Datenbanksuchroutine-Warnung, aber Sie können binden, wie folgt zu nennen `alert()` im globalen Gültigkeitsbereich:\n    \n        window.alert = navigator.notification.alert;\n        \n\n*   Beide `alert` und `confirm` sind nicht blockierende Aufrufe, die Ergebnisse davon nur asynchron sind.\n\n### Firefox OS Macken:\n\nNative blockierenden `window.alert()` und nicht-blockierende `navigator.notification.alert()` zur Verfügung.\n\n### BlackBerry 10 Macken\n\n`navigator.notification.alert ('Text', Rückruf, 'Titel', 'Text')` Callback-Parameter wird die Zahl 1 übergeben.\n\n## navigator.notification.confirm\n\nZeigt das Dialogfeld anpassbare Bestätigung.\n\n    navigator.notification.confirm(message, confirmCallback, [title], [buttonLabels])\n    \n\n*   **Nachricht**: Dialogfeld Nachricht. *(String)*\n\n*   **ConfirmCallback**: Callback aufgerufen wird, mit Index gedrückt (1, 2 oder 3) oder wenn das Dialogfeld geschlossen wird, ohne einen Tastendruck (0). *(Funktion)*\n\n*   **Titel**: Dialog \"Titel\". *(String)* (Optional, Standard ist`Confirm`)\n\n*   **ButtonLabels**: Array von Zeichenfolgen, die Schaltflächenbezeichnungen angeben. *(Array)* (Optional, Standard ist [ `OK,Cancel` ])\n\n### confirmCallback\n\nDie `confirmCallback` wird ausgeführt, wenn der Benutzer eine der Schaltflächen im Dialogfeld zur Bestätigung drückt.\n\nDer Rückruf dauert das Argument `buttonIndex` *(Anzahl)*, die der Index der Schaltfläche gedrückt ist. Beachten Sie, dass der Index 1-basierte Indizierung, sodass der Wert `1`, `2`, `3` usw. ist.\n\n### Beispiel\n\n    function onConfirm(buttonIndex) {\n        alert('You selected button ' + buttonIndex);\n    }\n    \n    navigator.notification.confirm(\n        'You are the winner!', // message\n         onConfirm,            // callback to invoke with index of button pressed\n        'Game Over',           // title\n        ['Restart','Exit']     // buttonLabels\n    );\n    \n\n### Unterstützte Plattformen\n\n*   Amazon Fire OS\n*   Android\n*   BlackBerry 10\n*   Firefox OS\n*   iOS\n*   Tizen\n*   Windows Phone 7 und 8\n*   Windows 8\n*   Windows\n\n### Windows Phone 7 und 8 Eigenarten\n\n*   Es gibt keine integrierte Browser-Funktion für `window.confirm` , aber Sie können es binden, indem Sie zuweisen:\n    \n        window.confirm = navigator.notification.confirm;\n        \n\n*   Aufrufe von `alert` und `confirm` sind nicht blockierend, so dass das Ergebnis nur asynchron zur Verfügung steht.\n\n### Windows-Eigenheiten\n\n*   Auf Windows8/8.1 kann nicht mehr als drei Schaltflächen MessageDialog-Instanz hinzu.\n\n*   Auf Windows Phone 8.1 ist es nicht möglich, Dialog mit mehr als zwei Knöpfen zeigen.\n\n### Firefox OS Macken:\n\nNative blockierenden `window.confirm()` und nicht-blockierende `navigator.notification.confirm()` zur Verfügung.\n\n## navigator.notification.prompt\n\nZeigt eine native Dialogfeld, das mehr als `Prompt`-Funktion des Browsers anpassbar ist.\n\n    navigator.notification.prompt(message, promptCallback, [title], [buttonLabels], [defaultText])\n    \n\n*   **Nachricht**: Dialogfeld Nachricht. *(String)*\n\n*   **promptCallback**: Callback aufgerufen wird, mit Index gedrückt (1, 2 oder 3) oder wenn das Dialogfeld geschlossen wird, ohne einen Tastendruck (0). *(Funktion)*\n\n*   **title**: Dialog Title *(String)* (Optional, Standard ist `Prompt`)\n\n*   **buttonLabels**: Array von Zeichenfolgen angeben Schaltfläche Etiketten *(Array)* (Optional, Standard ist `[\"OK\", \"Abbrechen\"]`)\n\n*   **defaultText**: Standard-Textbox Eingabewert (`String`) (Optional, Standard: leere Zeichenfolge)\n\n### promptCallback\n\nDie `promptCallback` wird ausgeführt, wenn der Benutzer eine der Schaltflächen im Eingabedialogfeld drückt. `Des Objekts an den Rückruf übergeben` enthält die folgenden Eigenschaften:\n\n*   **buttonIndex**: der Index der Schaltfläche gedrückt. *(Anzahl)* Beachten Sie, dass der Index 1-basierte Indizierung, sodass der Wert `1`, `2`, `3` usw. ist.\n\n*   **input1**: in Eingabedialogfeld eingegebenen Text. *(String)*\n\n### Beispiel\n\n    function onPrompt(results) {\n        alert(\"You selected button number \" + results.buttonIndex + \" and entered \" + results.input1);\n    }\n    \n    navigator.notification.prompt(\n        'Please enter your name',  // message\n        onPrompt,                  // callback to invoke\n        'Registration',            // title\n        ['Ok','Exit'],             // buttonLabels\n        'Jane Doe'                 // defaultText\n    );\n    \n\n### Unterstützte Plattformen\n\n*   Amazon Fire OS\n*   Android\n*   Firefox OS\n*   iOS\n*   Windows Phone 7 und 8\n*   Windows 8\n*   Windows\n\n### Android Eigenarten\n\n*   Android unterstützt maximal drei Schaltflächen und mehr als das ignoriert.\n\n*   Auf Android 3.0 und höher, werden die Schaltflächen in umgekehrter Reihenfolge für Geräte angezeigt, die das Holo-Design verwenden.\n\n### Windows-Eigenheiten\n\n*   Unter Windows ist Prompt Dialogfeld html-basierten mangels solcher native api.\n\n### Firefox OS Macken:\n\nNative blockierenden `window.prompt()` und nicht-blockierende `navigator.notification.prompt()` zur Verfügung.\n\n## navigator.notification.beep\n\nDas Gerät spielt einen Signalton sound.\n\n    navigator.notification.beep(times);\n    \n\n*   **times**: die Anzahl der Wiederholungen des Signaltons. *(Anzahl)*\n\n### Beispiel\n\n    // Beep twice!\n    navigator.notification.beep(2);\n    \n\n### Unterstützte Plattformen\n\n*   Amazon Fire OS\n*   Android\n*   BlackBerry 10\n*   iOS\n*   Tizen\n*   Windows Phone 7 und 8\n*   Windows 8\n\n### Amazon Fire OS Macken\n\n*   Amazon Fire OS spielt die Standardeinstellung **Akustische Benachrichtigung** unter **Einstellungen/Display & Sound** Bereich angegeben.\n\n### Android Eigenarten\n\n*   Android spielt die Standardeinstellung **Benachrichtigung Klingelton** unter **Einstellungen/Sound & Display**-Panel angegeben.\n\n### Windows Phone 7 und 8 Eigenarten\n\n*   Stützt sich auf eine generische Piepton-Datei aus der Cordova-Distribution.\n\n### Tizen Macken\n\n*   Tizen implementiert Signaltöne durch Abspielen einer Audiodatei über die Medien API.\n\n*   Die Beep-Datei muss kurz sein, in einem `sounds`-Unterverzeichnis des Stammverzeichnisses der Anwendung befinden muss und muss den Namen `beep.wav`.\n"
  },
  {
    "path": "plugins/cordova-plugin-dialogs/doc/es/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-dialogs\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-dialogs.svg)](https://travis-ci.org/apache/cordova-plugin-dialogs)\n\nEste plugin permite acceder a algunos elementos de interfaz de usuario nativa diálogo vía global `navigator.notification` objeto.\n\nAunque el objeto está unido al ámbito global `navigator` , no estará disponible hasta después de la `deviceready` evento.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(navigator.notification);\n    }\n    \n\n## Instalación\n\n    cordova plugin add cordova-plugin-dialogs\n    \n\n## Métodos\n\n  * `navigator.notification.alert`\n  * `navigator.notification.confirm`\n  * `navigator.notification.prompt`\n  * `navigator.notification.beep`\n\n## navigator.notification.alert\n\nMuestra un cuadro de alerta o cuadro de diálogo personalizado. La mayoría de las implementaciones de Cordova utilizan un cuadro de diálogo nativa para esta característica, pero algunas plataformas utilizan el navegador `alert` la función, que es típicamente menos personalizable.\n\n    navigator.notification.alert(message, alertCallback, [title], [buttonName])\n    \n\n  * **message**: mensaje de diálogo. *(String)*\n\n  * **alertCallback**: Callback para invocar al diálogo de alerta es desestimada. *(Función)*\n\n  * **title**: título de diálogo. *(String)* (Opcional, el valor predeterminado de `Alert`)\n\n  * **buttonName**: nombre del botón. *(String)* (Opcional, por defecto `Aceptar`)\n\n### Ejemplo\n\n    function alertDismissed() {\n        // do something\n    }\n    \n    navigator.notification.alert(\n        'You are the winner!',  // message\n        alertDismissed,         // callback\n        'Game Over',            // title\n        'Done'                  // buttonName\n    );\n    \n\n### Plataformas soportadas\n\n  * Amazon fire OS\n  * Android\n  * BlackBerry 10\n  * Firefox OS\n  * iOS\n  * Tizen\n  * Windows Phone 7 y 8\n  * Windows 8\n  * Windows\n\n### Windows Phone 7 y 8 rarezas\n\n  * No hay ninguna alerta del navegador integrado, pero puede enlazar uno proceda a llamar `alert()` en el ámbito global:\n    \n        window.alert = navigator.notification.alert;\n        \n\n  * `alert` y `confirm` son non-blocking llamadas, cuyos resultados sólo están disponibles de forma asincrónica.\n\n### Firefox OS rarezas:\n\nDos nativos de bloqueo `window.alert()` y no-bloqueo `navigator.notification.alert()` están disponibles.\n\n### BlackBerry 10 rarezas\n\n`navigator.notification.alert('text', callback, 'title', 'text')`parámetro de devolución de llamada se pasa el número 1.\n\n## navigator.notification.confirm\n\nMuestra un cuadro de diálogo de confirmación personalizables.\n\n    navigator.notification.confirm(message, confirmCallback, [title], [buttonLabels])\n    \n\n  * **message**: mensaje de diálogo. *(String)*\n\n  * **confirmCallback**: Callback para invocar con índice de botón pulsado (1, 2 o 3) o cuando el diálogo es despedido sin la presión del botón (0). *(Función)*\n\n  * **title**: título de diálogo. *(String)* (Opcional, por defecto a `confirmar`)\n\n  * **buttonLabels**: matriz de cadenas especificando las etiquetas de botón. *(Matriz)* (Opcional, por defecto [`OK, cancelar`])\n\n### confirmCallback\n\nEl `confirmCallback` se ejecuta cuando el usuario presiona uno de los botones en el cuadro de diálogo de confirmación.\n\nLa devolución de llamada toma el argumento `buttonIndex` *(número)*, que es el índice del botón presionado. Observe que el índice utiliza indexación basada en uno, entonces el valor es `1` , `2` , `3` , etc..\n\n### Ejemplo\n\n    function onConfirm(buttonIndex) {\n        alert('You selected button ' + buttonIndex);\n    }\n    \n    navigator.notification.confirm(\n        'You are the winner!', // message\n         onConfirm,            // callback to invoke with index of button pressed\n        'Game Over',           // title\n        ['Restart','Exit']     // buttonLabels\n    );\n    \n\n### Plataformas soportadas\n\n  * Amazon fire OS\n  * Android\n  * BlackBerry 10\n  * Firefox OS\n  * iOS\n  * Tizen\n  * Windows Phone 7 y 8\n  * Windows 8\n  * Windows\n\n### Windows Phone 7 y 8 rarezas\n\n  * No hay ninguna función de navegador incorporado para `window.confirm`, pero lo puede enlazar mediante la asignación:\n    \n        window.confirm = navigator.notification.confirm;\n        \n\n  * Llamadas de `alert` y `confirm` son non-blocking, así que el resultado sólo está disponible de forma asincrónica.\n\n### Windows rarezas\n\n  * Sobre Windows8/8.1 no es posible agregar más de tres botones a instancia de MessageDialog.\n\n  * En Windows Phone 8.1 no es posible Mostrar cuadro de diálogo con más de dos botones.\n\n### Firefox OS rarezas:\n\nDos nativos de bloqueo `window.confirm()` y no-bloqueo `navigator.notification.confirm()` están disponibles.\n\n## navigator.notification.prompt\n\nMuestra un cuadro de diálogo nativa que es más personalizable que del navegador `prompt` función.\n\n    navigator.notification.prompt(message, promptCallback, [title], [buttonLabels], [defaultText])\n    \n\n  * **message**: mensaje de diálogo. *(String)*\n\n  * **promptCallback**: Callback para invocar con índice del botón pulsado (1, 2 ó 3) o cuando el cuadro de diálogo es despedido sin la presión del botón (0). *(Función)*\n\n  * **título**: título *(String)* (opcional, por defecto de diálogo`Prompt`)\n\n  * **buttonLabels**: matriz de cadenas especificando botón etiquetas *(Array)* (opcional, por defecto`[\"OK\",\"Cancel\"]`)\n\n  * **defaultText**: valor de la entrada predeterminada textbox ( `String` ) (opcional, por defecto: cadena vacía)\n\n### promptCallback\n\nEl `promptCallback` se ejecuta cuando el usuario presiona uno de los botones del cuadro de diálogo pronto. El `results` objeto que se pasa a la devolución de llamada contiene las siguientes propiedades:\n\n  * **buttonIndex**: el índice del botón presionado. *(Número)* Observe que el índice utiliza indexación basada en uno, entonces el valor es `1` , `2` , `3` , etc..\n\n  * **INPUT1**: el texto introducido en el cuadro de diálogo pronto. *(String)*\n\n### Ejemplo\n\n    function onPrompt(results) {\n        alert(\"You selected button number \" + results.buttonIndex + \" and entered \" + results.input1);\n    }\n    \n    navigator.notification.prompt(\n        'Please enter your name',  // message\n        onPrompt,                  // callback to invoke\n        'Registration',            // title\n        ['Ok','Exit'],             // buttonLabels\n        'Jane Doe'                 // defaultText\n    );\n    \n\n### Plataformas soportadas\n\n  * Amazon fire OS\n  * Android\n  * Firefox OS\n  * iOS\n  * Windows Phone 7 y 8\n  * Windows 8\n  * Windows\n\n### Rarezas Android\n\n  * Android soporta un máximo de tres botones e ignora nada más.\n\n  * En Android 3.0 y posteriores, los botones aparecen en orden inverso para dispositivos que utilizan el tema Holo.\n\n### Windows rarezas\n\n  * En Windows pronto diálogo está basado en html debido a falta de tal api nativa.\n\n### Firefox OS rarezas:\n\nDos nativos de bloqueo `window.prompt()` y no-bloqueo `navigator.notification.prompt()` están disponibles.\n\n## navigator.notification.beep\n\nEl aparato reproduce un sonido sonido.\n\n    navigator.notification.beep(times);\n    \n\n  * **tiempos**: el número de veces a repetir la señal. *(Número)*\n\n### Ejemplo\n\n    // Beep twice!\n    navigator.notification.beep(2);\n    \n\n### Plataformas soportadas\n\n  * Amazon fire OS\n  * Android\n  * BlackBerry 10\n  * iOS\n  * Tizen\n  * Windows Phone 7 y 8\n  * Windows 8\n\n### Amazon fuego OS rarezas\n\n  * Amazon fuego OS reproduce el **Sonido de notificación** especificados en el panel de **configuración/pantalla y sonido** por defecto.\n\n### Rarezas Android\n\n  * Androide reproduce el **tono de notificación** especificados en el panel **ajustes de sonido y visualización** por defecto.\n\n### Windows Phone 7 y 8 rarezas\n\n  * Se basa en un archivo de sonido genérico de la distribución de Córdoba.\n\n### Rarezas Tizen\n\n  * Tizen implementa pitidos por reproducir un archivo de audio a través de los medios de comunicación API.\n\n  * El archivo de sonido debe ser corto, debe estar ubicado en un `sounds` subdirectorio del directorio raíz de la aplicación y deben ser nombrados`beep.wav`."
  },
  {
    "path": "plugins/cordova-plugin-dialogs/doc/es/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-dialogs\n\nEste plugin permite acceder a algunos elementos de interfaz de usuario nativa diálogo vía global `navigator.notification` objeto.\n\nAunque el objeto está unido al ámbito global `navigator` , no estará disponible hasta después de la `deviceready` evento.\n\n    document.addEventListener (\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {console.log(navigator.notification)};\n    \n\n## Instalación\n\n    Cordova plugin agregar cordova-plugin-dialogs\n    \n\n## Métodos\n\n*   `navigator.notification.alert`\n*   `navigator.notification.confirm`\n*   `navigator.notification.prompt`\n*   `navigator.notification.beep`\n\n## navigator.notification.alert\n\nMuestra un cuadro de alerta o cuadro de diálogo personalizado. La mayoría de las implementaciones de Cordova utilizan un cuadro de diálogo nativa para esta característica, pero algunas plataformas utilizan el navegador `alert` la función, que es típicamente menos personalizable.\n\n    Navigator.Notification.alert (mensaje, alertCallback, [title], [buttonName])\n    \n\n*   **message**: mensaje de diálogo. *(String)*\n\n*   **alertCallback**: Callback para invocar al diálogo de alerta es desestimada. *(Función)*\n\n*   **title**: título de diálogo. *(String)* (Opcional, el valor predeterminado de `Alert`)\n\n*   **buttonName**: nombre del botón. *(String)* (Opcional, por defecto `Aceptar`)\n\n### Ejemplo\n\n    function alertDismissed() {/ / hacer algo} navigator.notification.alert ('Tú eres el ganador!', / / mensaje alertDismissed, / / callback 'Game Over', / / título 'hecho' / / buttonName);\n    \n\n### Plataformas soportadas\n\n*   Amazon fire OS\n*   Android\n*   BlackBerry 10\n*   Firefox OS\n*   iOS\n*   Tizen\n*   Windows Phone 7 y 8\n*   Windows 8\n*   Windows\n\n### Windows Phone 7 y 8 rarezas\n\n*   No hay ninguna alerta del navegador integrado, pero puede enlazar uno proceda a llamar `alert()` en el ámbito global:\n    \n        window.alert = navigator.notification.alert;\n        \n\n*   `alert` y `confirm` son non-blocking llamadas, cuyos resultados sólo están disponibles de forma asincrónica.\n\n### Firefox OS rarezas:\n\nDos nativos de bloqueo `window.alert()` y no-bloqueo `navigator.notification.alert()` están disponibles.\n\n### BlackBerry 10 rarezas\n\n`navigator.notification.alert('text', callback, 'title', 'text')`parámetro de devolución de llamada se pasa el número 1.\n\n## navigator.notification.confirm\n\nMuestra un cuadro de diálogo de confirmación personalizables.\n\n    Navigator.Notification.CONFIRM (mensaje, confirmCallback, [title], [buttonLabels])\n    \n\n*   **message**: mensaje de diálogo. *(String)*\n\n*   **confirmCallback**: Callback para invocar con índice de botón pulsado (1, 2 o 3) o cuando el diálogo es despedido sin la presión del botón (0). *(Función)*\n\n*   **title**: título de diálogo. *(String)* (Opcional, por defecto a `confirmar`)\n\n*   **buttonLabels**: matriz de cadenas especificando las etiquetas de botón. *(Matriz)* (Opcional, por defecto [`OK, cancelar`])\n\n### confirmCallback\n\nEl `confirmCallback` se ejecuta cuando el usuario presiona uno de los botones en el cuadro de diálogo de confirmación.\n\nLa devolución de llamada toma el argumento `buttonIndex` *(número)*, que es el índice del botón presionado. Observe que el índice utiliza indexación basada en uno, entonces el valor es `1` , `2` , `3` , etc..\n\n### Ejemplo\n\n    function onConfirm(buttonIndex) {alert ('Tu botón seleccionado' + buttonIndex);}\n    \n    Navigator.Notification.CONFIRM ('Tú eres el ganador!', / / mensaje onConfirm, / callback para invocar con índice del botón pulsado 'Game Over', / / / título ['reiniciar', 'Exit'] / / buttonLabels);\n    \n\n### Plataformas soportadas\n\n*   Amazon fire OS\n*   Android\n*   BlackBerry 10\n*   Firefox OS\n*   iOS\n*   Tizen\n*   Windows Phone 7 y 8\n*   Windows 8\n*   Windows\n\n### Windows Phone 7 y 8 rarezas\n\n*   No hay ninguna función de navegador incorporado para `window.confirm`, pero lo puede enlazar mediante la asignación:\n    \n        window.confirm = navigator.notification.confirm;\n        \n\n*   Llamadas de `alert` y `confirm` son non-blocking, así que el resultado sólo está disponible de forma asincrónica.\n\n### Windows rarezas\n\n*   Sobre Windows8/8.1 no es posible agregar más de tres botones a instancia de MessageDialog.\n\n*   En Windows Phone 8.1 no es posible Mostrar cuadro de diálogo con más de dos botones.\n\n### Firefox OS rarezas:\n\nDos nativos de bloqueo `window.confirm()` y no-bloqueo `navigator.notification.confirm()` están disponibles.\n\n## navigator.notification.prompt\n\nMuestra un cuadro de diálogo nativa que es más personalizable que del navegador `prompt` función.\n\n    Navigator.Notification.prompt (mensaje, promptCallback, [title], [buttonLabels], [defaultText])\n    \n\n*   **mensaje**: mensaje de diálogo. *(String)*\n\n*   **promptCallback**: Callback para invocar con índice del botón pulsado (1, 2 ó 3) o cuando el cuadro de diálogo es despedido sin la presión del botón (0). *(Función)*\n\n*   **título**: título *(String)* (opcional, por defecto de diálogo`Prompt`)\n\n*   **buttonLabels**: matriz de cadenas especificando botón etiquetas *(Array)* (opcional, por defecto`[\"OK\",\"Cancel\"]`)\n\n*   **defaultText**: valor de la entrada predeterminada textbox ( `String` ) (opcional, por defecto: cadena vacía)\n\n### promptCallback\n\nEl `promptCallback` se ejecuta cuando el usuario presiona uno de los botones del cuadro de diálogo pronto. El `results` objeto que se pasa a la devolución de llamada contiene las siguientes propiedades:\n\n*   **buttonIndex**: el índice del botón presionado. *(Número)* Observe que el índice utiliza indexación basada en uno, entonces el valor es `1` , `2` , `3` , etc..\n\n*   **INPUT1**: el texto introducido en el cuadro de diálogo pronto. *(String)*\n\n### Ejemplo\n\n    function onPrompt(results) {alert (\"seleccionaron botón número\" + results.buttonIndex + \"y entró en\" + results.input1);}\n    \n    Navigator.Notification.prompt ('Por favor introduce tu nombre', / / mensaje onPrompt, / / callback para invocar 'Registro', / / título ['Ok', 'Exit'], / / buttonLabels 'Jane Doe' / / defaultText);\n    \n\n### Plataformas soportadas\n\n*   Amazon fuego OS\n*   Android\n*   Firefox OS\n*   iOS\n*   Windows Phone 7 y 8\n*   Windows 8\n*   Windows\n\n### Rarezas Android\n\n*   Android soporta un máximo de tres botones e ignora nada más.\n\n*   En Android 3.0 y posteriores, los botones aparecen en orden inverso para dispositivos que utilizan el tema Holo.\n\n### Windows rarezas\n\n*   En Windows pronto diálogo está basado en html debido a falta de tal api nativa.\n\n### Firefox OS rarezas:\n\nDos nativos de bloqueo `window.prompt()` y no-bloqueo `navigator.notification.prompt()` están disponibles.\n\n## navigator.notification.beep\n\nEl aparato reproduce un sonido sonido.\n\n    Navigator.Notification.Beep(Times);\n    \n\n*   **tiempos**: el número de veces a repetir la señal. *(Número)*\n\n### Ejemplo\n\n    Dos pitidos.\n    Navigator.Notification.Beep(2);\n    \n\n### Plataformas soportadas\n\n*   Amazon fuego OS\n*   Android\n*   BlackBerry 10\n*   iOS\n*   Tizen\n*   Windows Phone 7 y 8\n*   Windows 8\n\n### Amazon fuego OS rarezas\n\n*   Amazon fuego OS reproduce el **Sonido de notificación** especificados en el panel de **configuración/pantalla y sonido** por defecto.\n\n### Rarezas Android\n\n*   Androide reproduce el **tono de notificación** especificados en el panel **ajustes de sonido y visualización** por defecto.\n\n### Windows Phone 7 y 8 rarezas\n\n*   Se basa en un archivo de sonido genérico de la distribución de Córdoba.\n\n### Rarezas Tizen\n\n*   Tizen implementa pitidos por reproducir un archivo de audio a través de los medios de comunicación API.\n\n*   El archivo de sonido debe ser corto, debe estar ubicado en un `sounds` subdirectorio del directorio raíz de la aplicación y deben ser nombrados`beep.wav`.\n"
  },
  {
    "path": "plugins/cordova-plugin-dialogs/doc/fr/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-dialogs\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-dialogs.svg)](https://travis-ci.org/apache/cordova-plugin-dialogs)\n\nCe plugin permet d'accéder à certains éléments d'interface utilisateur native de dialogue via un global `navigator.notification` objet.\n\nBien que l'objet est attaché à la portée globale `navigator` , il n'est pas disponible jusqu'après la `deviceready` événement.\n\n    document.addEventListener (« deviceready », onDeviceReady, false) ;\n    function onDeviceReady() {console.log(navigator.notification);}\n    \n\n## Installation\n\n    cordova plugin add cordova-plugin-dialogs\n    \n\n## Méthodes\n\n  * `navigator.notification.alert`\n  * `navigator.notification.confirm`\n  * `navigator.notification.prompt`\n  * `navigator.notification.beep`\n\n## navigator.notification.alert\n\nAffiche une boîte de dialogue ou d'alerte personnalisé. La plupart des implémentations de Cordova utilisent une boîte de dialogue natives pour cette fonctionnalité, mais certaines plates-formes du navigateur `alert` fonction, qui est généralement moins personnalisable.\n\n    Navigator.notification.Alert (message, alertCallback, [title], [buttonName])\n    \n\n  * **message**: message de la boîte de dialogue. *(String)*\n\n  * **alertCallback**: callback à appeler lorsque la boîte de dialogue d'alerte est rejetée. *(Fonction)*\n\n  * **titre**: titre de la boîte de dialogue. *(String)* (Facultatif, par défaut`Alert`)\n\n  * **buttonName**: nom du bouton. *(String)* (Facultatif, par défaut`OK`)\n\n### Exemple\n\n    function alertDismissed() {/ / faire quelque chose} navigator.notification.alert ('Vous êtes le gagnant!', / / message alertDismissed, / / rappel « Game Over », / / titre « Done » / / buttonName) ;\n    \n\n### Plates-formes supportées\n\n  * Amazon Fire OS\n  * Android\n  * BlackBerry 10\n  * Firefox OS\n  * iOS\n  * Paciarelli\n  * Windows Phone 7 et 8\n  * Windows 8\n  * Windows\n\n### Notes au sujet de Windows Phone 7 et 8\n\n  * Il n'y a aucune boîte de dialogue d'alerte intégrée au navigateur, mais vous pouvez en lier une pour appeler `alert()` dans le scope global:\n    \n        window.alert = navigator.notification.alert;\n        \n\n  * Les deux appels `alert` et `confirm` sont non-blocants, leurs résultats ne sont disponibles que de façon asynchrone.\n\n### Firefox OS Quirks :\n\nLes deux indigènes bloquant `window.alert()` et non-bloquante `navigator.notification.alert()` sont disponibles.\n\n### BlackBerry 10 Quirks\n\n`navigator.notification.alert('text', callback, 'title', 'text')`paramètre callback est passé numéro 1.\n\n## navigator.notification.confirm\n\nAffiche une boîte de dialogue de confirmation personnalisable.\n\n    Navigator.notification.Confirm (message, confirmCallback, [title], [buttonLabels])\n    \n\n  * **message**: message de la boîte de dialogue. *(String)*\n\n  * **confirmCallback**: callback à appeler avec l'index du bouton pressé (1, 2 ou 3) ou lorsque la boîte de dialogue est fermée sans qu'un bouton ne soit pressé (0). *(Fonction)*\n\n  * **titre**: titre de dialogue. *(String)* (Facultatif, par défaut`Confirm`)\n\n  * **buttonLabels**: tableau de chaînes spécifiant les étiquettes des boutons. *(Array)* (Optionnel, par défaut, [ `OK,Cancel` ])\n\n### confirmCallback\n\nLe `confirmCallback` s'exécute lorsque l'utilisateur appuie sur un bouton dans la boîte de dialogue de confirmation.\n\nLe rappel prend l'argument `buttonIndex` *(nombre)*, qui est l'index du bouton activé. Notez que l'index utilise base d'indexation, la valeur est `1` , `2` , `3` , etc..\n\n### Exemple\n\n    function onConfirm(buttonIndex) {alert (« Vous bouton sélectionné » + buttonIndex);}\n    \n    Navigator.notification.Confirm ('Vous êtes le gagnant!', / / message onConfirm, / / rappel d'invoquer avec l'index du bouton enfoncé « Game Over », / / title ['redémarrer', « Exit »] / / buttonLabels) ;\n    \n\n### Plates-formes supportées\n\n  * Amazon Fire OS\n  * Android\n  * BlackBerry 10\n  * Firefox OS\n  * iOS\n  * Paciarelli\n  * Windows Phone 7 et 8\n  * Windows 8\n  * Windows\n\n### Notes au sujet de Windows Phone 7 et 8\n\n  * Il n'y a aucune fonction intégrée au navigateur pour `window.confirm`, mais vous pouvez en lier une en affectant:\n    \n        window.confirm = navigator.notification.confirm ;\n        \n\n  * Les appels à `alert` et `confirm` sont non-bloquants, donc le résultat est seulement disponible de façon asynchrone.\n\n### Bizarreries de Windows\n\n  * Sur Windows8/8.1, il n'est pas possible d'ajouter plus de trois boutons à MessageDialog instance.\n\n  * Sur Windows Phone 8.1, il n'est pas possible d'établir le dialogue avec plus de deux boutons.\n\n### Firefox OS Quirks :\n\nLes deux indigènes bloquant `window.confirm()` et non-bloquante `navigator.notification.confirm()` sont disponibles.\n\n## navigator.notification.prompt\n\nAffiche une boîte de dialogue natif qui est plus personnalisable que le navigateur `prompt` fonction.\n\n    Navigator.notification.prompt (message, promptCallback, [title], [buttonLabels], [defaultText])\n    \n\n  * **message**: message de la boîte de dialogue. *(String)*\n\n  * **promptCallback**: rappel d'invoquer avec l'index du bouton pressé (1, 2 ou 3) ou lorsque la boîte de dialogue est fermée sans une presse de bouton (0). *(Fonction)*\n\n  * **titre**: titre *(String)* (facultatif, la valeur par défaut de dialogue`Prompt`)\n\n  * **buttonLabels**: tableau de chaînes spécifiant les bouton *(Array)* (facultatif, par défaut, les étiquettes`[\"OK\",\"Cancel\"]`)\n\n  * **defaultText**: zone de texte par défaut entrée valeur ( `String` ) (en option, par défaut : chaîne vide)\n\n### promptCallback\n\nLe `promptCallback` s'exécute lorsque l'utilisateur appuie sur un bouton dans la boîte de dialogue d'invite. Le `results` objet passé au rappel contient les propriétés suivantes :\n\n  * **buttonIndex**: l'index du bouton activé. *(Nombre)* Notez que l'index utilise base d'indexation, la valeur est `1` , `2` , `3` , etc..\n\n  * **entrée 1**: le texte entré dans la boîte de dialogue d'invite. *(String)*\n\n### Exemple\n\n    function onPrompt(results) {alert (« Vous avez sélectionné le numéro du bouton » + results.buttonIndex + « et saisi » + results.input1);}\n    \n    Navigator.notification.prompt ('Veuillez saisir votre nom', / / message onPrompt, / / rappel à appeler « Registration », / / title ['Ok', 'Exit'], / / buttonLabels « Jane Doe » / / defaultText) ;\n    \n\n### Plates-formes supportées\n\n  * Amazon Fire OS\n  * Android\n  * Firefox OS\n  * iOS\n  * Windows Phone 7 et 8\n  * Windows 8\n  * Windows\n\n### Quirks Android\n\n  * Android prend en charge un maximum de trois boutons et ignore plus que cela.\n\n  * Sur Android 3.0 et versions ultérieures, les boutons sont affichés dans l'ordre inverse pour les appareils qui utilisent le thème Holo.\n\n### Bizarreries de Windows\n\n  * Sous Windows, dialogue d'invite est basé sur html en raison de l'absence de ces api native.\n\n### Firefox OS Quirks :\n\nLes deux indigènes bloquant `window.prompt()` et non-bloquante `navigator.notification.prompt()` sont disponibles.\n\n## navigator.notification.beep\n\nLe dispositif joue un bip sonore.\n\n    Navigator.notification.Beep(Times) ;\n    \n\n  * **temps**: le nombre de fois répéter le bip. *(Nombre)*\n\n### Exemple\n\n    Deux bips !\n    Navigator.notification.Beep(2) ;\n    \n\n### Plates-formes supportées\n\n  * Amazon Fire OS\n  * Android\n  * BlackBerry 10\n  * iOS\n  * Paciarelli\n  * Windows Phone 7 et 8\n  * Windows 8\n\n### Amazon Fire OS Quirks\n\n  * Amazon Fire OS joue la valeur par défaut le **Son de Notification** spécifié sous le panneau **d'affichage des réglages/& Sound** .\n\n### Quirks Android\n\n  * Android joue la **sonnerie de Notification** spécifié sous le panneau des **réglages/son et affichage** de valeur par défaut.\n\n### Notes au sujet de Windows Phone 7 et 8\n\n  * S'appuie sur un fichier générique bip de la distribution de Cordova.\n\n### Bizarreries de paciarelli\n\n  * Paciarelli implémente les bips en lisant un fichier audio via les médias API.\n\n  * Le fichier sonore doit être court, doit se trouver dans un `sounds` sous-répertoire du répertoire racine de l'application et doit être nommé`beep.wav`."
  },
  {
    "path": "plugins/cordova-plugin-dialogs/doc/fr/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-dialogs\n\nCe plugin permet d'accéder à certains éléments d'interface utilisateur native de dialogue via un global `navigator.notification` objet.\n\nBien que l'objet est attaché à la portée globale `navigator` , il n'est pas disponible jusqu'après la `deviceready` événement.\n\n    document.addEventListener (« deviceready », onDeviceReady, false) ;\n    function onDeviceReady() {console.log(navigator.notification);}\n    \n\n## Installation\n\n    Cordova plugin ajouter cordova-plugin-dialogs\n    \n\n## Méthodes\n\n*   `navigator.notification.alert`\n*   `navigator.notification.confirm`\n*   `navigator.notification.prompt`\n*   `navigator.notification.beep`\n\n## navigator.notification.alert\n\nAffiche une boîte de dialogue ou d'alerte personnalisé. La plupart des implémentations de Cordova utilisent une boîte de dialogue natives pour cette fonctionnalité, mais certaines plates-formes du navigateur `alert` fonction, qui est généralement moins personnalisable.\n\n    Navigator.notification.Alert (message, alertCallback, [title], [buttonName])\n    \n\n*   **message**: message de la boîte de dialogue. *(String)*\n\n*   **alertCallback**: callback à appeler lorsque la boîte de dialogue d'alerte est rejetée. *(Fonction)*\n\n*   **titre**: titre de la boîte de dialogue. *(String)* (Facultatif, par défaut`Alert`)\n\n*   **buttonName**: nom du bouton. *(String)* (Facultatif, par défaut`OK`)\n\n### Exemple\n\n    function alertDismissed() {/ / faire quelque chose} navigator.notification.alert ('Vous êtes le gagnant!', / / message alertDismissed, / / rappel « Game Over », / / titre « Done » / / buttonName) ;\n    \n\n### Plates-formes prises en charge\n\n*   Amazon Fire OS\n*   Android\n*   BlackBerry 10\n*   Firefox OS\n*   iOS\n*   Tizen\n*   Windows Phone 7 et 8\n*   Windows 8\n*   Windows\n\n### Windows Phone 7 et 8 Quirks\n\n*   Il n'y a aucune boîte de dialogue d'alerte intégrée au navigateur, mais vous pouvez en lier une pour appeler `alert()` dans le scope global:\n    \n        window.alert = navigator.notification.alert;\n        \n\n*   Les deux appels `alert` et `confirm` sont non-blocants, leurs résultats ne sont disponibles que de façon asynchrone.\n\n### Firefox OS Quirks :\n\nLes deux indigènes bloquant `window.alert()` et non-bloquante `navigator.notification.alert()` sont disponibles.\n\n### BlackBerry 10 Quirks\n\n`navigator.notification.alert('text', callback, 'title', 'text')`paramètre callback est passé numéro 1.\n\n## navigator.notification.confirm\n\nAffiche une boîte de dialogue de confirmation personnalisable.\n\n    Navigator.notification.Confirm (message, confirmCallback, [title], [buttonLabels])\n    \n\n*   **message**: message de la boîte de dialogue. *(String)*\n\n*   **confirmCallback**: callback à appeler avec l'index du bouton pressé (1, 2 ou 3) ou lorsque la boîte de dialogue est fermée sans qu'un bouton ne soit pressé (0). *(Fonction)*\n\n*   **titre**: titre de dialogue. *(String)* (Facultatif, par défaut`Confirm`)\n\n*   **buttonLabels**: tableau de chaînes spécifiant les étiquettes des boutons. *(Array)* (Optionnel, par défaut, [ `OK,Cancel` ])\n\n### confirmCallback\n\nLe `confirmCallback` s'exécute lorsque l'utilisateur appuie sur un bouton dans la boîte de dialogue de confirmation.\n\nLe rappel prend l'argument `buttonIndex` *(nombre)*, qui est l'index du bouton activé. Notez que l'index utilise base d'indexation, la valeur est `1` , `2` , `3` , etc..\n\n### Exemple\n\n    function onConfirm(buttonIndex) {alert (« Vous bouton sélectionné » + buttonIndex);}\n    \n    Navigator.notification.Confirm ('Vous êtes le gagnant!', / / message onConfirm, / / rappel d'invoquer avec l'index du bouton enfoncé « Game Over », / / title ['redémarrer', « Exit »] / / buttonLabels) ;\n    \n\n### Plates-formes prises en charge\n\n*   Amazon Fire OS\n*   Android\n*   BlackBerry 10\n*   Firefox OS\n*   iOS\n*   Paciarelli\n*   Windows Phone 7 et 8\n*   Windows 8\n*   Windows\n\n### Windows Phone 7 et 8 Quirks\n\n*   Il n'y a aucune fonction intégrée au navigateur pour `window.confirm`, mais vous pouvez en lier une en affectant:\n    \n        window.confirm = navigator.notification.confirm ;\n        \n\n*   Les appels à `alert` et `confirm` sont non-bloquants, donc le résultat est seulement disponible de façon asynchrone.\n\n### Bizarreries de Windows\n\n*   Sur Windows8/8.1, il n'est pas possible d'ajouter plus de trois boutons à MessageDialog instance.\n\n*   Sur Windows Phone 8.1, il n'est pas possible d'établir le dialogue avec plus de deux boutons.\n\n### Firefox OS Quirks :\n\nLes deux indigènes bloquant `window.confirm()` et non-bloquante `navigator.notification.confirm()` sont disponibles.\n\n## navigator.notification.prompt\n\nAffiche une boîte de dialogue natif qui est plus personnalisable que le navigateur `prompt` fonction.\n\n    Navigator.notification.prompt (message, promptCallback, [title], [buttonLabels], [defaultText])\n    \n\n*   **message**: message de la boîte de dialogue. *(String)*\n\n*   **promptCallback**: rappel d'invoquer avec l'index du bouton pressé (1, 2 ou 3) ou lorsque la boîte de dialogue est fermée sans une presse de bouton (0). *(Fonction)*\n\n*   **titre**: titre *(String)* (facultatif, la valeur par défaut de dialogue`Prompt`)\n\n*   **buttonLabels**: tableau de chaînes spécifiant les bouton *(Array)* (facultatif, par défaut, les étiquettes`[\"OK\",\"Cancel\"]`)\n\n*   **defaultText**: zone de texte par défaut entrée valeur ( `String` ) (en option, par défaut : chaîne vide)\n\n### promptCallback\n\nLe `promptCallback` s'exécute lorsque l'utilisateur appuie sur un bouton dans la boîte de dialogue d'invite. Le `results` objet passé au rappel contient les propriétés suivantes :\n\n*   **buttonIndex**: l'index du bouton activé. *(Nombre)* Notez que l'index utilise base d'indexation, la valeur est `1` , `2` , `3` , etc..\n\n*   **entrée 1**: le texte entré dans la boîte de dialogue d'invite. *(String)*\n\n### Exemple\n\n    function onPrompt(results) {alert (« Vous avez sélectionné le numéro du bouton » + results.buttonIndex + « et saisi » + results.input1);}\n    \n    Navigator.notification.prompt ('Veuillez saisir votre nom', / / message onPrompt, / / rappel à appeler « Registration », / / title ['Ok', 'Exit'], / / buttonLabels « Jane Doe » / / defaultText) ;\n    \n\n### Plates-formes prises en charge\n\n*   Amazon Fire OS\n*   Android\n*   Firefox OS\n*   iOS\n*   Windows Phone 7 et 8\n*   Windows 8\n*   Windows\n\n### Quirks Android\n\n*   Android prend en charge un maximum de trois boutons et ignore plus que cela.\n\n*   Sur Android 3.0 et versions ultérieures, les boutons sont affichés dans l'ordre inverse pour les appareils qui utilisent le thème Holo.\n\n### Bizarreries de Windows\n\n*   Sous Windows, dialogue d'invite est basé sur html en raison de l'absence de ces api native.\n\n### Firefox OS Quirks :\n\nLes deux indigènes bloquant `window.prompt()` et non-bloquante `navigator.notification.prompt()` sont disponibles.\n\n## navigator.notification.beep\n\nLe dispositif joue un bip sonore.\n\n    Navigator.notification.Beep(Times) ;\n    \n\n*   **temps**: le nombre de fois répéter le bip. *(Nombre)*\n\n### Exemple\n\n    Deux bips !\n    Navigator.notification.Beep(2) ;\n    \n\n### Plates-formes prises en charge\n\n*   Amazon Fire OS\n*   Android\n*   BlackBerry 10\n*   iOS\n*   Paciarelli\n*   Windows Phone 7 et 8\n*   Windows 8\n\n### Amazon Fire OS Quirks\n\n*   Amazon Fire OS joue la valeur par défaut le **Son de Notification** spécifié sous le panneau **d'affichage des réglages/& Sound** .\n\n### Quirks Android\n\n*   Android joue la **sonnerie de Notification** spécifié sous le panneau des **réglages/son et affichage** de valeur par défaut.\n\n### Windows Phone 7 et 8 Quirks\n\n*   S'appuie sur un fichier générique bip de la distribution de Cordova.\n\n### Bizarreries de paciarelli\n\n*   Paciarelli implémente les bips en lisant un fichier audio via les médias API.\n\n*   Le fichier sonore doit être court, doit se trouver dans un `sounds` sous-répertoire du répertoire racine de l'application et doit être nommé`beep.wav`.\n"
  },
  {
    "path": "plugins/cordova-plugin-dialogs/doc/it/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-dialogs\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-dialogs.svg)](https://travis-ci.org/apache/cordova-plugin-dialogs)\n\nQuesto plugin consente di accedere ad alcuni elementi di interfaccia utente nativa dialogo tramite un oggetto globale `navigator.notification`.\n\nAnche se l'oggetto è associato con ambito globale del `navigator`, non è disponibile fino a dopo l'evento `deviceready`.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(navigator.notification);\n    }\n    \n\n## Installazione\n\n    cordova plugin add cordova-plugin-dialogs\n    \n\n## Metodi\n\n  * `navigator.notification.alert`\n  * `navigator.notification.confirm`\n  * `navigator.notification.prompt`\n  * `navigator.notification.beep`\n\n## navigator.notification.alert\n\nMostra una finestra di avviso o la finestra di dialogo personalizzata. La maggior parte delle implementazioni di Cordova utilizzano una finestra di dialogo nativa per questa caratteristica, ma alcune piattaforme utilizzano la funzione di `alert` del browser, che è in genere meno personalizzabile.\n\n    navigator.notification.alert(message, alertCallback, [title], [buttonName])\n    \n\n  * **message**: messaggio finestra di dialogo. *(String)*\n\n  * **alertCallback**: Callback da richiamare quando viene chiusa la finestra di avviso. *(Funzione)*\n\n  * **title**: titolo di dialogo. *(String)* (Opzionale, default è `Alert`)\n\n  * **buttonName**: nome del pulsante. *(String)* (Opzionale, default è `OK`)\n\n### Esempio\n\n    function alertDismissed() {\n        // do something\n    }\n    \n    navigator.notification.alert(\n        'You are the winner!',  // message\n        alertDismissed,         // callback\n        'Game Over',            // title\n        'Done'                  // buttonName\n    );\n    \n\n### Piattaforme supportate\n\n  * Amazon fuoco OS\n  * Android\n  * BlackBerry 10\n  * Firefox OS\n  * iOS\n  * Tizen\n  * Windows Phone 7 e 8\n  * Windows 8\n  * Windows\n\n### Windows Phone 7 e 8 stranezze\n\n  * Non non c'è nessun avviso del browser integrato, ma è possibile associare uno come segue per chiamare `alert()` in ambito globale:\n    \n        window.alert = navigator.notification.alert;\n        \n\n  * Entrambi `alert` e `confirm` sono non di blocco chiamate, risultati di cui sono disponibili solo in modo asincrono.\n\n### Firefox OS Stranezze:\n\nNativo di blocco `window.alert()` blocco `navigator.notification.alert()` sono disponibili sia.\n\n### BlackBerry 10 capricci\n\nparametro di callback `navigator.notification.alert ('text' callback, 'title' 'text')` viene passato il numero 1.\n\n## navigator.notification.confirm\n\nVisualizza una finestra di dialogo conferma personalizzabile.\n\n    navigator.notification.confirm(message, confirmCallback, [title], [buttonLabels])\n    \n\n  * **message**: messaggio finestra di dialogo. *(String)*\n\n  * **confirmCallback**: Callback da richiamare con l'indice del pulsante premuto (1, 2 o 3) o quando la finestra di dialogo viene chiusa senza una pressione del pulsante (0). *(Funzione)*\n\n  * **titolo**: titolo di dialogo. *(String)* (Opzionale, default è`Confirm`)\n\n  * **buttonLabels**: matrice di stringhe che specificano le etichette dei pulsanti. *(Matrice)* (Opzionale, default è [ `OK,Cancel` ])\n\n### confirmCallback\n\nIl `confirmCallback` viene eseguito quando l'utente preme uno dei pulsanti nella finestra di dialogo conferma.\n\nIl callback accetta l'argomento `buttonIndex` *(numero)*, che è l'indice del pulsante premuto. Si noti che l'indice utilizza l'indicizzazione base uno, quindi il valore è `1`, `2`, `3`, ecc.\n\n### Esempio\n\n    function onConfirm(buttonIndex) {\n        alert('You selected button ' + buttonIndex);\n    }\n    \n    navigator.notification.confirm(\n        'You are the winner!', // message\n         onConfirm,            // callback to invoke with index of button pressed\n        'Game Over',           // title\n        ['Restart','Exit']     // buttonLabels\n    );\n    \n\n### Piattaforme supportate\n\n  * Amazon fuoco OS\n  * Android\n  * BlackBerry 10\n  * Firefox OS\n  * iOS\n  * Tizen\n  * Windows Phone 7 e 8\n  * Windows 8\n  * Windows\n\n### Windows Phone 7 e 8 stranezze\n\n  * Non non c'è nessuna funzione browser incorporato per `window.confirm` , ma è possibile associare assegnando:\n    \n        window.confirm = navigator.notification.confirm;\n        \n\n  * Chiama al `alert` e `confirm` sono non bloccante, quindi il risultato è disponibile solo in modo asincrono.\n\n### Stranezze di Windows\n\n  * Su Windows8/8.1 non è possibile aggiungere più di tre pulsanti a MessageDialog istanza.\n\n  * Su Windows Phone 8.1 non è possibile mostrare la finestra di dialogo con più di due pulsanti.\n\n### Firefox OS Stranezze:\n\nNativo di blocco `window.confirm()` blocco `navigator.notification.confirm()` sono disponibili sia.\n\n## navigator.notification.prompt\n\nVisualizza una finestra di dialogo nativa che è più personalizzabile di funzione `prompt` del browser.\n\n    navigator.notification.prompt(message, promptCallback, [title], [buttonLabels], [defaultText])\n    \n\n  * **message**: messaggio finestra di dialogo. *(String)*\n\n  * **promptCallback**: Callback da richiamare con l'indice del pulsante premuto (1, 2 o 3) o quando la finestra di dialogo viene chiusa senza una pressione del pulsante (0). *(Funzione)*\n\n  * **title**: dialogo titolo *(String)* (opzionale, default è `Prompt`)\n\n  * **buttonLabels**: matrice di stringhe specificando il pulsante etichette *(Array)* (opzionale, default è `[\"OK\", \"Cancel\"]`)\n\n  * **defaultText**: valore (`String`) di input predefinito textbox (opzionale, Default: empty string)\n\n### promptCallback\n\nIl `promptCallback` viene eseguito quando l'utente preme uno dei pulsanti nella finestra di dialogo richiesta. `results` oggetto passato al metodo di callback contiene le seguenti proprietà:\n\n  * **buttonIndex**: l'indice del pulsante premuto. *(Numero)* Si noti che l'indice utilizza l'indicizzazione base uno, quindi il valore è `1`, `2`, `3`, ecc.\n\n  * **input1**: il testo immesso nella finestra di dialogo richiesta. *(String)*\n\n### Esempio\n\n    function onPrompt(results) {\n        alert(\"You selected button number \" + results.buttonIndex + \" and entered \" + results.input1);\n    }\n    \n    navigator.notification.prompt(\n        'Please enter your name',  // message\n        onPrompt,                  // callback to invoke\n        'Registration',            // title\n        ['Ok','Exit'],             // buttonLabels\n        'Jane Doe'                 // defaultText\n    );\n    \n\n### Piattaforme supportate\n\n  * Amazon fuoco OS\n  * Android\n  * Firefox OS\n  * iOS\n  * Windows Phone 7 e 8\n  * Windows 8\n  * Windows\n\n### Stranezze Android\n\n  * Android supporta un massimo di tre pulsanti e ignora di più di quello.\n\n  * Su Android 3.0 e versioni successive, i pulsanti vengono visualizzati in ordine inverso per dispositivi che utilizzano il tema Holo.\n\n### Stranezze di Windows\n\n  * Su Windows finestra di dialogo richiesta è a causa di mancanza di tali api nativa basata su html.\n\n### Firefox OS Stranezze:\n\nNativo di blocco `window.prompt()` blocco `navigator.notification.prompt()` sono disponibili sia.\n\n## navigator.notification.beep\n\nIl dispositivo riproduce un bip sonoro.\n\n    navigator.notification.beep(times);\n    \n\n  * **times**: il numero di volte per ripetere il segnale acustico. *(Numero)*\n\n### Esempio\n\n    // Beep twice!\n    navigator.notification.beep(2);\n    \n\n### Piattaforme supportate\n\n  * Amazon fuoco OS\n  * Android\n  * BlackBerry 10\n  * iOS\n  * Tizen\n  * Windows Phone 7 e 8\n  * Windows 8\n\n### Amazon fuoco OS stranezze\n\n  * Amazon fuoco OS riproduce il **Suono di notifica** specificato sotto il pannello **Impostazioni/Display e il suono** predefinito.\n\n### Stranezze Android\n\n  * Android giochi default **Notification ringtone** specificato sotto il pannello **impostazioni/audio e Display**.\n\n### Windows Phone 7 e 8 stranezze\n\n  * Si basa su un file generico bip dalla distribuzione di Cordova.\n\n### Tizen stranezze\n\n  * Tizen implementa bip di riproduzione di un file audio tramite i media API.\n\n  * Il file beep deve essere breve, deve trovarsi in una sottodirectory di `sounds` della directory principale dell'applicazione e deve essere denominato `beep.wav`."
  },
  {
    "path": "plugins/cordova-plugin-dialogs/doc/it/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-dialogs\n\nQuesto plugin consente di accedere ad alcuni elementi di interfaccia utente nativa dialogo tramite un oggetto globale `navigator.notification`.\n\nAnche se l'oggetto è associato con ambito globale del `navigator`, non è disponibile fino a dopo l'evento `deviceready`.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(navigator.notification);\n    }\n    \n\n## Installazione\n\n    cordova plugin add cordova-plugin-dialogs\n    \n\n## Metodi\n\n*   `navigator.notification.alert`\n*   `navigator.notification.confirm`\n*   `navigator.notification.prompt`\n*   `navigator.notification.beep`\n\n## navigator.notification.alert\n\nMostra una finestra di avviso o la finestra di dialogo personalizzata. La maggior parte delle implementazioni di Cordova utilizzano una finestra di dialogo nativa per questa caratteristica, ma alcune piattaforme utilizzano la funzione di `alert` del browser, che è in genere meno personalizzabile.\n\n    navigator.notification.alert(message, alertCallback, [title], [buttonName])\n    \n\n*   **message**: messaggio finestra di dialogo. *(String)*\n\n*   **alertCallback**: Callback da richiamare quando viene chiusa la finestra di avviso. *(Funzione)*\n\n*   **title**: titolo di dialogo. *(String)* (Opzionale, default è `Alert`)\n\n*   **buttonName**: nome del pulsante. *(String)* (Opzionale, default è `OK`)\n\n### Esempio\n\n    function alertDismissed() {\n        // do something\n    }\n    \n    navigator.notification.alert(\n        'You are the winner!',  // message\n        alertDismissed,         // callback\n        'Game Over',            // title\n        'Done'                  // buttonName\n    );\n    \n\n### Piattaforme supportate\n\n*   Amazon fuoco OS\n*   Android\n*   BlackBerry 10\n*   Firefox OS\n*   iOS\n*   Tizen\n*   Windows Phone 7 e 8\n*   Windows 8\n*   Windows\n\n### Windows Phone 7 e 8 stranezze\n\n*   Non non c'è nessun avviso del browser integrato, ma è possibile associare uno come segue per chiamare `alert()` in ambito globale:\n    \n        window.alert = navigator.notification.alert;\n        \n\n*   Entrambi `alert` e `confirm` sono non di blocco chiamate, risultati di cui sono disponibili solo in modo asincrono.\n\n### Firefox OS Stranezze:\n\nNativo di blocco `window.alert()` blocco `navigator.notification.alert()` sono disponibili sia.\n\n### BlackBerry 10 capricci\n\nparametro di callback `navigator.notification.alert ('text' callback, 'title' 'text')` viene passato il numero 1.\n\n## navigator.notification.confirm\n\nVisualizza una finestra di dialogo conferma personalizzabile.\n\n    navigator.notification.confirm(message, confirmCallback, [title], [buttonLabels])\n    \n\n*   **messaggio**: messaggio finestra di dialogo. *(String)*\n\n*   **confirmCallback**: Callback da richiamare con l'indice del pulsante premuto (1, 2 o 3) o quando la finestra di dialogo viene chiusa senza una pressione del pulsante (0). *(Funzione)*\n\n*   **titolo**: titolo di dialogo. *(String)* (Opzionale, default è`Confirm`)\n\n*   **buttonLabels**: matrice di stringhe che specificano le etichette dei pulsanti. *(Matrice)* (Opzionale, default è [ `OK,Cancel` ])\n\n### confirmCallback\n\nIl `confirmCallback` viene eseguito quando l'utente preme uno dei pulsanti nella finestra di dialogo conferma.\n\nIl callback accetta l'argomento `buttonIndex` *(numero)*, che è l'indice del pulsante premuto. Si noti che l'indice utilizza l'indicizzazione base uno, quindi il valore è `1`, `2`, `3`, ecc.\n\n### Esempio\n\n    function onConfirm(buttonIndex) {\n        alert('You selected button ' + buttonIndex);\n    }\n    \n    navigator.notification.confirm(\n        'You are the winner!', // message\n         onConfirm,            // callback to invoke with index of button pressed\n        'Game Over',           // title\n        ['Restart','Exit']     // buttonLabels\n    );\n    \n\n### Piattaforme supportate\n\n*   Amazon fuoco OS\n*   Android\n*   BlackBerry 10\n*   Firefox OS\n*   iOS\n*   Tizen\n*   Windows Phone 7 e 8\n*   Windows 8\n*   Windows\n\n### Windows Phone 7 e 8 stranezze\n\n*   Non non c'è nessuna funzione browser incorporato per `window.confirm` , ma è possibile associare assegnando:\n    \n        window.confirm = navigator.notification.confirm;\n        \n\n*   Chiama al `alert` e `confirm` sono non bloccante, quindi il risultato è disponibile solo in modo asincrono.\n\n### Stranezze di Windows\n\n*   Su Windows8/8.1 non è possibile aggiungere più di tre pulsanti a MessageDialog istanza.\n\n*   Su Windows Phone 8.1 non è possibile mostrare la finestra di dialogo con più di due pulsanti.\n\n### Firefox OS Stranezze:\n\nNativo di blocco `window.confirm()` blocco `navigator.notification.confirm()` sono disponibili sia.\n\n## navigator.notification.prompt\n\nVisualizza una finestra di dialogo nativa che è più personalizzabile di funzione `prompt` del browser.\n\n    navigator.notification.prompt(message, promptCallback, [title], [buttonLabels], [defaultText])\n    \n\n*   **message**: messaggio finestra di dialogo. *(String)*\n\n*   **promptCallback**: Callback da richiamare con l'indice del pulsante premuto (1, 2 o 3) o quando la finestra di dialogo viene chiusa senza una pressione del pulsante (0). *(Funzione)*\n\n*   **title**: dialogo titolo *(String)* (opzionale, default è `Prompt`)\n\n*   **buttonLabels**: matrice di stringhe specificando il pulsante etichette *(Array)* (opzionale, default è `[\"OK\", \"Cancel\"]`)\n\n*   **defaultText**: valore (`String`) di input predefinito textbox (opzionale, Default: empty string)\n\n### promptCallback\n\nIl `promptCallback` viene eseguito quando l'utente preme uno dei pulsanti nella finestra di dialogo richiesta. `results` oggetto passato al metodo di callback contiene le seguenti proprietà:\n\n*   **buttonIndex**: l'indice del pulsante premuto. *(Numero)* Si noti che l'indice utilizza l'indicizzazione base uno, quindi il valore è `1`, `2`, `3`, ecc.\n\n*   **input1**: il testo immesso nella finestra di dialogo richiesta. *(String)*\n\n### Esempio\n\n    function onPrompt(results) {\n        alert(\"You selected button number \" + results.buttonIndex + \" and entered \" + results.input1);\n    }\n    \n    navigator.notification.prompt(\n        'Please enter your name',  // message\n        onPrompt,                  // callback to invoke\n        'Registration',            // title\n        ['Ok','Exit'],             // buttonLabels\n        'Jane Doe'                 // defaultText\n    );\n    \n\n### Piattaforme supportate\n\n*   Amazon fuoco OS\n*   Android\n*   Firefox OS\n*   iOS\n*   Windows Phone 7 e 8\n*   Windows 8\n*   Windows\n\n### Stranezze Android\n\n*   Android supporta un massimo di tre pulsanti e ignora di più di quello.\n\n*   Su Android 3.0 e versioni successive, i pulsanti vengono visualizzati in ordine inverso per dispositivi che utilizzano il tema Holo.\n\n### Stranezze di Windows\n\n*   Su Windows finestra di dialogo richiesta è a causa di mancanza di tali api nativa basata su html.\n\n### Firefox OS Stranezze:\n\nNativo di blocco `window.prompt()` blocco `navigator.notification.prompt()` sono disponibili sia.\n\n## navigator.notification.beep\n\nIl dispositivo riproduce un bip sonoro.\n\n    navigator.notification.beep(times);\n    \n\n*   **times**: il numero di volte per ripetere il segnale acustico. *(Numero)*\n\n### Esempio\n\n    // Beep twice!\n    navigator.notification.beep(2);\n    \n\n### Piattaforme supportate\n\n*   Amazon fuoco OS\n*   Android\n*   BlackBerry 10\n*   iOS\n*   Tizen\n*   Windows Phone 7 e 8\n*   Windows 8\n\n### Amazon fuoco OS stranezze\n\n*   Amazon fuoco OS riproduce il **Suono di notifica** specificato sotto il pannello **Impostazioni/Display e il suono** predefinito.\n\n### Stranezze Android\n\n*   Android giochi default **Notification ringtone** specificato sotto il pannello **impostazioni/audio e Display**.\n\n### Windows Phone 7 e 8 stranezze\n\n*   Si basa su un file generico bip dalla distribuzione di Cordova.\n\n### Tizen stranezze\n\n*   Tizen implementa bip di riproduzione di un file audio tramite i media API.\n\n*   Il file beep deve essere breve, deve trovarsi in una sottodirectory di `sounds` della directory principale dell'applicazione e deve essere denominato `beep.wav`.\n"
  },
  {
    "path": "plugins/cordova-plugin-dialogs/doc/ja/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-dialogs\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-dialogs.svg)](https://travis-ci.org/apache/cordova-plugin-dialogs)\n\nこのプラグインは、グローバル `navigator.notification` オブジェクトを介していくつかネイティブ ダイアログの UI 要素へのアクセスを提供します。\n\nオブジェクトは、グローバル スコープの `ナビゲーター` に添付、それがないまで `deviceready` イベントの後。\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(navigator.notification);\n    }\n    \n\n## インストール\n\n    cordova plugin add cordova-plugin-dialogs\n    \n\n## メソッド\n\n  * `navigator.notification.alert`\n  * `navigator.notification.confirm`\n  * `navigator.notification.prompt`\n  * `navigator.notification.beep`\n\n## navigator.notification.alert\n\nカスタムの警告またはダイアログ ボックスが表示されます。 ほとんどコルドバ ネイティブ] ダイアログ ボックスの使用この機能がいくつかのプラットフォームは通常小さいカスタマイズ可能なブラウザーの `警告` 機能を使用します。\n\n    navigator.notification.alert(message, alertCallback, [title], [buttonName])\n    \n\n  * **メッセージ**: ダイアログ メッセージ。*(文字列)*\n\n  * **alertCallback**: 警告ダイアログが閉じられたときに呼び出すコールバック。*(機能)*\n\n  * **タイトル**: ダイアログのタイトル。*(文字列)*(省略可能、既定値は`Alert`)\n\n  * **buttonName**: ボタンの名前。*(文字列)*(省略可能、既定値は`OK`)\n\n### 例\n\n    function alertDismissed() {\n        // do something\n    }\n    \n    navigator.notification.alert(\n        'You are the winner!',  // message\n        alertDismissed,         // callback\n        'Game Over',            // title\n        'Done'                  // buttonName\n    );\n    \n\n### サポートされているプラットフォーム\n\n  * アマゾン火 OS\n  * アンドロイド\n  * ブラックベリー 10\n  * Firefox の OS\n  * iOS\n  * Tizen\n  * Windows Phone 7 と 8\n  * Windows 8\n  * Windows\n\n### Windows Phone 7 と 8 癖\n\n  * 組み込みのブラウザー警告がない呼び出しを次のように 1 つをバインドすることができます `alert()` 、グローバル スコープで。\n    \n        window.alert = navigator.notification.alert;\n        \n\n  * 両方の `alert` と `confirm` は非ブロッキング呼び出し、結果は非同期的にのみ利用できます。\n\n### Firefox OS 互換:\n\nネイティブ ブロック `window.alert()` と非ブロッキング `navigator.notification.alert()` があります。\n\n### ブラックベリー 10 癖\n\n`navigator.notification.alert ('text' コールバック 'title'、'text')` コールバック パラメーターは数 1 に渡されます。\n\n## navigator.notification.confirm\n\nカスタマイズ可能な確認のダイアログ ボックスが表示されます。\n\n    navigator.notification.confirm(message, confirmCallback, [title], [buttonLabels])\n    \n\n  * **メッセージ**: ダイアログ メッセージ。*(文字列)*\n\n  * **confirmCallback**: インデックス (1、2、または 3) を押されたボタンまたはダイアログ ボックスは、ボタンを押す （0） なしに解雇されたときに呼び出すコールバック。*(機能)*\n\n  * **タイトル**: ダイアログのタイトル。*(文字列)*(省略可能、既定値は`Confirm`)\n\n  * **buttonLabels**: ボタンのラベルを指定する文字列の配列。*(配列)*(省略可能、既定値は [ `OK,Cancel` ])\n\n### confirmCallback\n\n`confirmCallback` は、いずれかの確認ダイアログ ボックスでボタンを押したときに実行します。\n\nコールバックは、引数 `buttonIndex` *（番号）* は、押されたボタンのインデックス。 インデックスがインデックス 1 ベースので、値は `1`、`2`、`3` などに注意してください。\n\n### 例\n\n    function onConfirm(buttonIndex) {\n        alert('You selected button ' + buttonIndex);\n    }\n    \n    navigator.notification.confirm(\n        'You are the winner!', // message\n         onConfirm,            // callback to invoke with index of button pressed\n        'Game Over',           // title\n        ['Restart','Exit']     // buttonLabels\n    );\n    \n\n### サポートされているプラットフォーム\n\n  * アマゾン火 OS\n  * アンドロイド\n  * ブラックベリー 10\n  * Firefox の OS\n  * iOS\n  * Tizen\n  * Windows Phone 7 と 8\n  * Windows 8\n  * Windows\n\n### Windows Phone 7 と 8 癖\n\n  * 組み込みブラウザーの機能はありません `window.confirm` が割り当てることによってバインドすることができます。\n    \n        window.confirm = navigator.notification.confirm;\n        \n\n  * 呼び出しを `alert` と `confirm` では非ブロッキング、結果は非同期的にのみ使用できます。\n\n### Windows の癖\n\n  * Windows8/8.1 の MessageDialog インスタンスを 3 つ以上のボタンを追加することはできません。\n\n  * Windows Phone 8.1 に 2 つ以上のボタンを持つダイアログを表示することはできません。\n\n### Firefox OS 互換:\n\nネイティブ ブロック `window.confirm()` と非ブロッキング `navigator.notification.confirm()` があります。\n\n## navigator.notification.prompt\n\nブラウザーの `プロンプト` 機能より詳細にカスタマイズはネイティブのダイアログ ボックスが表示されます。\n\n    navigator.notification.prompt(message, promptCallback, [title], [buttonLabels], [defaultText])\n    \n\n  * **メッセージ**: ダイアログ メッセージ。*(文字列)*\n\n  * **promptCallback**: インデックス (1、2、または 3) を押されたボタンまたはダイアログ ボックスは、ボタンを押す （0） なしに解雇されたときに呼び出すコールバック。*(機能)*\n\n  * **title**: タイトル *(String)* (省略可能、既定 `プロンプト` ダイアログ)\n\n  * **buttonLabels**: ボタンのラベル *(配列)* (省略可能、既定値 `[\"OK\"、「キャンセル」]` を指定する文字列の配列)\n\n  * **defaultText**: 既定テキスト ボックスの入力値 (`文字列`) (省略可能、既定: 空の文字列)\n\n### promptCallback\n\n`promptCallback` は、プロンプト ダイアログ ボックス内のボタンのいずれかを押したときに実行します。コールバックに渡される `results` オブジェクトには、次のプロパティが含まれています。\n\n  * **buttonIndex**: 押されたボタンのインデックス。*(数)*インデックスがインデックス 1 ベースので、値は `1`、`2`、`3` などに注意してください。\n\n  * **input1**: プロンプト ダイアログ ボックスに入力したテキスト。*(文字列)*\n\n### 例\n\n    function onPrompt(results) {\n        alert(\"You selected button number \" + results.buttonIndex + \" and entered \" + results.input1);\n    }\n    \n    navigator.notification.prompt(\n        'Please enter your name',  // message\n        onPrompt,                  // callback to invoke\n        'Registration',            // title\n        ['Ok','Exit'],             // buttonLabels\n        'Jane Doe'                 // defaultText\n    );\n    \n\n### サポートされているプラットフォーム\n\n  * アマゾン火 OS\n  * アンドロイド\n  * Firefox の OS\n  * iOS\n  * Windows Phone 7 と 8\n  * Windows 8\n  * Windows\n\n### Android の癖\n\n  * Android は最大 3 つのボタンをサポートしているし、それ以上無視します。\n\n  * アンドロイド 3.0 と後、ホロのテーマを使用するデバイスを逆の順序でボタンが表示されます。\n\n### Windows の癖\n\n  * Windows プロンプト ダイアログは html ベースのようなネイティブ api の不足のためです。\n\n### Firefox OS 互換:\n\nネイティブ ブロック `window.prompt()` と非ブロッキング `navigator.notification.prompt()` があります。\n\n## navigator.notification.beep\n\nデバイス サウンドをビープ音を再生します。\n\n    navigator.notification.beep(times);\n    \n\n  * **times**: ビープ音を繰り返す回数。*(数)*\n\n### 例\n\n    // Beep twice!\n    navigator.notification.beep(2);\n    \n\n### サポートされているプラットフォーム\n\n  * アマゾン火 OS\n  * アンドロイド\n  * ブラックベリー 10\n  * iOS\n  * Tizen\n  * Windows Phone 7 と 8\n  * Windows 8\n\n### アマゾン火 OS 癖\n\n  * アマゾン火 OS デフォルト **設定/表示 ＆ サウンド** パネルの下に指定した **通知音** を果たしています。\n\n### Android の癖\n\n  * アンドロイド デフォルト **通知着信音** **設定/サウンド ＆ ディスプレイ** パネルの下に指定を果たしています。\n\n### Windows Phone 7 と 8 癖\n\n  * コルドバ分布からジェネリック ビープ音ファイルに依存します。\n\n### Tizen の癖\n\n  * Tizen は、メディア API 経由でオーディオ ファイルを再生してビープ音を実装します。\n\n  * ビープ音ファイル短い、`sounds` アプリケーションのルート ディレクトリのサブディレクトリである必要があり。、`beep.wav` という名前である必要があります。."
  },
  {
    "path": "plugins/cordova-plugin-dialogs/doc/ja/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-dialogs\n\nこのプラグインは、グローバル `navigator.notification` オブジェクトを介していくつかネイティブ ダイアログの UI 要素へのアクセスを提供します。\n\nオブジェクトは、グローバル スコープの `ナビゲーター` に添付、それがないまで `deviceready` イベントの後。\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(navigator.notification);\n    }\n    \n\n## インストール\n\n    cordova plugin add cordova-plugin-dialogs\n    \n\n## メソッド\n\n*   `navigator.notification.alert`\n*   `navigator.notification.confirm`\n*   `navigator.notification.prompt`\n*   `navigator.notification.beep`\n\n## navigator.notification.alert\n\nカスタムの警告またはダイアログ ボックスが表示されます。 ほとんどコルドバ ネイティブ] ダイアログ ボックスの使用この機能がいくつかのプラットフォームは通常小さいカスタマイズ可能なブラウザーの `警告` 機能を使用します。\n\n    navigator.notification.alert(message, alertCallback, [title], [buttonName])\n    \n\n*   **メッセージ**: ダイアログ メッセージ。*(文字列)*\n\n*   **alertCallback**: 警告ダイアログが閉じられたときに呼び出すコールバック。*(機能)*\n\n*   **タイトル**: ダイアログのタイトル。*(文字列)*(省略可能、既定値は`Alert`)\n\n*   **buttonName**: ボタンの名前。*(文字列)*(省略可能、既定値は`OK`)\n\n### 例\n\n    function alertDismissed() {\n        // do something\n    }\n    \n    navigator.notification.alert(\n        'You are the winner!',  // message\n        alertDismissed,         // callback\n        'Game Over',            // title\n        'Done'                  // buttonName\n    );\n    \n\n### サポートされているプラットフォーム\n\n*   アマゾン火 OS\n*   アンドロイド\n*   ブラックベリー 10\n*   Firefox の OS\n*   iOS\n*   Tizen\n*   Windows Phone 7 と 8\n*   Windows 8\n*   Windows\n\n### Windows Phone 7 と 8 癖\n\n*   組み込みのブラウザー警告がない呼び出しを次のように 1 つをバインドすることができます `alert()` 、グローバル スコープで。\n    \n        window.alert = navigator.notification.alert;\n        \n\n*   両方の `alert` と `confirm` は非ブロッキング呼び出し、結果は非同期的にのみ利用できます。\n\n### Firefox OS 互換:\n\nネイティブ ブロック `window.alert()` と非ブロッキング `navigator.notification.alert()` があります。\n\n### ブラックベリー 10 癖\n\n`navigator.notification.alert ('text' コールバック 'title'、'text')` コールバック パラメーターは数 1 に渡されます。\n\n## navigator.notification.confirm\n\nカスタマイズ可能な確認のダイアログ ボックスが表示されます。\n\n    navigator.notification.confirm(message, confirmCallback, [title], [buttonLabels])\n    \n\n*   **メッセージ**: ダイアログ メッセージ。*(文字列)*\n\n*   **confirmCallback**: インデックス (1、2、または 3) を押されたボタンまたはダイアログ ボックスは、ボタンを押す （0） なしに解雇されたときに呼び出すコールバック。*(機能)*\n\n*   **タイトル**: ダイアログのタイトル。*(文字列)*(省略可能、既定値は`Confirm`)\n\n*   **buttonLabels**: ボタンのラベルを指定する文字列の配列。*(配列)*(省略可能、既定値は [ `OK,Cancel` ])\n\n### confirmCallback\n\n`confirmCallback` は、いずれかの確認ダイアログ ボックスでボタンを押したときに実行します。\n\nコールバックは、引数 `buttonIndex` *（番号）* は、押されたボタンのインデックス。 インデックスがインデックス 1 ベースので、値は `1`、`2`、`3` などに注意してください。\n\n### 例\n\n    function onConfirm(buttonIndex) {\n        alert('You selected button ' + buttonIndex);\n    }\n    \n    navigator.notification.confirm(\n        'You are the winner!', // message\n         onConfirm,            // callback to invoke with index of button pressed\n        'Game Over',           // title\n        ['Restart','Exit']     // buttonLabels\n    );\n    \n\n### サポートされているプラットフォーム\n\n*   アマゾン火 OS\n*   アンドロイド\n*   ブラックベリー 10\n*   Firefox の OS\n*   iOS\n*   Tizen\n*   Windows Phone 7 と 8\n*   Windows 8\n*   Windows\n\n### Windows Phone 7 と 8 癖\n\n*   組み込みブラウザーの機能はありません `window.confirm` が割り当てることによってバインドすることができます。\n    \n        window.confirm = navigator.notification.confirm;\n        \n\n*   呼び出しを `alert` と `confirm` では非ブロッキング、結果は非同期的にのみ使用できます。\n\n### Windows の癖\n\n*   Windows8/8.1 の MessageDialog インスタンスを 3 つ以上のボタンを追加することはできません。\n\n*   Windows Phone 8.1 に 2 つ以上のボタンを持つダイアログを表示することはできません。\n\n### Firefox OS 互換:\n\nネイティブ ブロック `window.confirm()` と非ブロッキング `navigator.notification.confirm()` があります。\n\n## navigator.notification.prompt\n\nブラウザーの `プロンプト` 機能より詳細にカスタマイズはネイティブのダイアログ ボックスが表示されます。\n\n    navigator.notification.prompt(message, promptCallback, [title], [buttonLabels], [defaultText])\n    \n\n*   **message**: ダイアログ メッセージ。*(文字列)*\n\n*   **promptCallback**: インデックス (1、2、または 3) を押されたボタンまたはダイアログ ボックスは、ボタンを押す （0） なしに解雇されたときに呼び出すコールバック。*(機能)*\n\n*   **title**: タイトル *(String)* (省略可能、既定 `プロンプト` ダイアログ)\n\n*   **buttonLabels**: ボタンのラベル *(配列)* (省略可能、既定値 `[\"OK\"、「キャンセル」]` を指定する文字列の配列)\n\n*   **defaultText**: 既定テキスト ボックスの入力値 (`文字列`) (省略可能、既定: 空の文字列)\n\n### promptCallback\n\n`promptCallback` は、プロンプト ダイアログ ボックス内のボタンのいずれかを押したときに実行します。コールバックに渡される `results` オブジェクトには、次のプロパティが含まれています。\n\n*   **buttonIndex**: 押されたボタンのインデックス。*(数)*インデックスがインデックス 1 ベースので、値は `1`、`2`、`3` などに注意してください。\n\n*   **input1**: プロンプト ダイアログ ボックスに入力したテキスト。*(文字列)*\n\n### 例\n\n    function onPrompt(results) {\n        alert(\"You selected button number \" + results.buttonIndex + \" and entered \" + results.input1);\n    }\n    \n    navigator.notification.prompt(\n        'Please enter your name',  // message\n        onPrompt,                  // callback to invoke\n        'Registration',            // title\n        ['Ok','Exit'],             // buttonLabels\n        'Jane Doe'                 // defaultText\n    );\n    \n\n### サポートされているプラットフォーム\n\n*   アマゾン火 OS\n*   アンドロイド\n*   Firefox の OS\n*   iOS\n*   Windows Phone 7 と 8\n*   Windows 8\n*   Windows\n\n### Android の癖\n\n*   Android は最大 3 つのボタンをサポートしているし、それ以上無視します。\n\n*   アンドロイド 3.0 と後、ホロのテーマを使用するデバイスを逆の順序でボタンが表示されます。\n\n### Windows の癖\n\n*   Windows プロンプト ダイアログは html ベースのようなネイティブ api の不足のためです。\n\n### Firefox OS 互換:\n\nネイティブ ブロック `window.prompt()` と非ブロッキング `navigator.notification.prompt()` があります。\n\n## navigator.notification.beep\n\nデバイス サウンドをビープ音を再生します。\n\n    navigator.notification.beep(times);\n    \n\n*   **times**: ビープ音を繰り返す回数。*(数)*\n\n### 例\n\n    // Beep twice!\n    navigator.notification.beep(2);\n    \n\n### サポートされているプラットフォーム\n\n*   アマゾン火 OS\n*   アンドロイド\n*   ブラックベリー 10\n*   iOS\n*   Tizen\n*   Windows Phone 7 と 8\n*   Windows 8\n\n### アマゾン火 OS 癖\n\n*   アマゾン火 OS デフォルト **設定/表示 ＆ サウンド** パネルの下に指定した **通知音** を果たしています。\n\n### Android の癖\n\n*   アンドロイド デフォルト **通知着信音** **設定/サウンド ＆ ディスプレイ** パネルの下に指定を果たしています。\n\n### Windows Phone 7 と 8 癖\n\n*   コルドバ分布からジェネリック ビープ音ファイルに依存します。\n\n### Tizen の癖\n\n*   Tizen は、メディア API 経由でオーディオ ファイルを再生してビープ音を実装します。\n\n*   ビープ音ファイル短い、`sounds` アプリケーションのルート ディレクトリのサブディレクトリである必要があり。、`beep.wav` という名前である必要があります。.\n"
  },
  {
    "path": "plugins/cordova-plugin-dialogs/doc/ko/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-dialogs\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-dialogs.svg)](https://travis-ci.org/apache/cordova-plugin-dialogs)\n\n이 플러그인 글로벌 `navigator.notification` 개체를 통해 몇 가지 기본 대화 상자 UI 요소에 액세스할 수 있습니다.\n\n개체 `navigator` 글로벌 범위 첨부 아니에요 때까지 사용할 수 있는 `deviceready` 이벤트 후.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(navigator.notification);\n    }\n    \n\n## 설치\n\n    cordova plugin add cordova-plugin-dialogs\n    \n\n## 메서드\n\n  * `navigator.notification.alert`\n  * `navigator.notification.confirm`\n  * `navigator.notification.prompt`\n  * `navigator.notification.beep`\n\n## navigator.notification.alert\n\n사용자 지정 경고 또는 대화 상자를 보여 줍니다. 이 기능에 대 한 기본 대화 상자를 사용 하는 대부분의 코르도바 구현 하지만 일부 플랫폼은 일반적으로 덜 사용자 정의할 수 있는 브라우저의 `alert` 기능을 사용 합니다.\n\n    navigator.notification.alert(message, alertCallback, [title], [buttonName])\n    \n\n  * **message**: 대화 메시지. *(문자열)*\n\n  * **alertCallback**: 콜백을 호출할 때 경고 대화 기 각. *(기능)*\n\n  * **title**: 제목 대화 상자. *(문자열)* (옵션, 기본값:`Alert`)\n\n  * **buttonName**: 단추 이름. *(문자열)* (옵션, 기본값:`OK`)\n\n### 예를 들어\n\n    function alertDismissed() {\n        // do something\n    }\n    \n    navigator.notification.alert(\n        'You are the winner!',  // message\n        alertDismissed,         // callback\n        'Game Over',            // title\n        'Done'                  // buttonName\n    );\n    \n\n### 지원 되는 플랫폼\n\n  * 아마존 화재 운영 체제\n  * 안 드 로이드\n  * 블랙베리 10\n  * Firefox 운영 체제\n  * iOS\n  * Tizen\n  * Windows Phone 7과 8\n  * 윈도우 8\n  * 윈도우\n\n### Windows Phone 7, 8 특수\n\n  * 아니 내장 브라우저 경고 하지만 다음과 같이 전화를 바인딩할 수 있습니다 `alert()` 전역 범위에서:\n    \n        window.alert = navigator.notification.alert;\n        \n\n  * 둘 다 `alert` 와 `confirm` 는 비차단 호출, 결과 비동기적으로 사용할 수 있습니다.\n\n### 파이어 폭스 OS 단점:\n\n기본 차단 `window.alert()` 및 차단 되지 않은 `navigator.notification.alert()` 사용할 수 있습니다.\n\n### 블랙베리 10 단점\n\n`navigator.notification.alert ('텍스트', 콜백, '제목', '텍스트')` 콜백 매개 변수 1 번을 전달 됩니다.\n\n## navigator.notification.confirm\n\n사용자 정의 확인 대화 상자가 표시 됩니다.\n\n    navigator.notification.confirm(message, confirmCallback, [title], [buttonLabels])\n    \n\n  * **message**: 대화 메시지. *(문자열)*\n\n  * **confirmCallback**: 인덱스 버튼 (1, 2 또는 3) 또는 대화 상자 버튼을 누르면 (0) 없이 기 각 될 때 호출할 콜백 합니다. *(기능)*\n\n  * **title**: 제목 대화 상자. *(문자열)* (옵션, 기본값:`Confirm`)\n\n  * **buttonLabels**: 단추 레이블을 지정 하는 문자열 배열입니다. *(배열)* (옵션, 기본값은 [ `OK,Cancel` ])\n\n### confirmCallback\n\n`confirmCallback`는 사용자가 확인 대화 상자에서 단추 중 하나를 누를 때 실행 합니다.\n\n콜백이 걸립니다 인수 `buttonIndex` *(번호)를* 누르면된 버튼의 인덱스입니다. Note 인덱스에서는 인덱싱 1 시작 값은 `1`, `2`, `3`, 등등.\n\n### 예를 들어\n\n    function onConfirm(buttonIndex) {\n        alert('You selected button ' + buttonIndex);\n    }\n    \n    navigator.notification.confirm(\n        'You are the winner!', // message\n         onConfirm,            // callback to invoke with index of button pressed\n        'Game Over',           // title\n        ['Restart','Exit']     // buttonLabels\n    );\n    \n\n### 지원 되는 플랫폼\n\n  * 아마존 화재 운영 체제\n  * 안 드 로이드\n  * 블랙베리 10\n  * Firefox 운영 체제\n  * iOS\n  * Tizen\n  * Windows Phone 7과 8\n  * 윈도우 8\n  * 윈도우\n\n### Windows Phone 7, 8 특수\n\n  * 에 대 한 기본 제공 브라우저 함수가 `window.confirm` , 그러나 할당 하 여 바인딩할 수 있습니다:\n    \n        window.confirm = navigator.notification.confirm;\n        \n\n  * 호출 `alert` 및 `confirm` 되므로 차단 되지 않은 결과만 비동기적으로 사용할 수 있습니다.\n\n### 윈도우 특수\n\n  * Windows8/8.1에 3 개 이상 단추 MessageDialog 인스턴스를 추가할 수는 없습니다.\n\n  * Windows Phone 8.1에 두 개 이상의 단추와 대화 상자 표시 수는 없습니다.\n\n### 파이어 폭스 OS 단점:\n\n기본 차단 `window.confirm()` 및 차단 되지 않은 `navigator.notification.confirm()` 사용할 수 있습니다.\n\n## navigator.notification.prompt\n\n브라우저의 `프롬프트` 함수 보다 더 많은 사용자 정의 기본 대화 상자가 표시 됩니다.\n\n    navigator.notification.prompt(message, promptCallback, [title], [buttonLabels], [defaultText])\n    \n\n  * **message**: 대화 메시지. *(문자열)*\n\n  * **promptCallback**: 인덱스 버튼 (1, 2 또는 3) 또는 대화 상자 버튼을 누르면 (0) 없이 기 각 될 때 호출할 콜백 합니다. *(기능)*\n\n  * **title**: 제목 대화 상자. *(문자열)* (옵션, 기본값:`Prompt`)\n\n  * **buttonLabels**: 버튼 레이블 *(배열)* (옵션, 기본값 `[\"확인\", \"취소\"]을` 지정 하는 문자열의 배열)\n\n  * **defaultText**: 기본 텍스트 상자에 값 (`문자열`) 입력 (옵션, 기본값: 빈 문자열)\n\n### promptCallback\n\n`promptCallback`는 사용자가 프롬프트 대화 상자에서 단추 중 하나를 누를 때 실행 합니다. 콜백에 전달 된 `results` 개체에는 다음 속성이 포함 되어 있습니다.\n\n  * **buttonIndex**: 눌려진된 버튼의 인덱스. *(수)* Note 인덱스에서는 인덱싱 1 시작 값은 `1`, `2`, `3`, 등등.\n\n  * **input1**: 프롬프트 대화 상자에 입력 한 텍스트. *(문자열)*\n\n### 예를 들어\n\n    function onPrompt(results) {\n        alert(\"You selected button number \" + results.buttonIndex + \" and entered \" + results.input1);\n    }\n    \n    navigator.notification.prompt(\n        'Please enter your name',  // message\n        onPrompt,                  // callback to invoke\n        'Registration',            // title\n        ['Ok','Exit'],             // buttonLabels\n        'Jane Doe'                 // defaultText\n    );\n    \n\n### 지원 되는 플랫폼\n\n  * 아마존 화재 운영 체제\n  * 안 드 로이드\n  * Firefox 운영 체제\n  * iOS\n  * Windows Phone 7과 8\n  * 윈도우 8\n  * 윈도우\n\n### 안 드 로이드 단점\n\n  * 안 드 로이드 최대 3 개의 단추를 지원 하 고 그것 보다는 더 이상 무시 합니다.\n\n  * 안 드 로이드 3.0 및 나중에, 단추는 홀로 테마를 사용 하는 장치에 대 한 반대 순서로 표시 됩니다.\n\n### 윈도우 특수\n\n  * 윈도우에서 프롬프트 대화 같은 네이티브 api의 부족으로 인해 html 기반 이다.\n\n### 파이어 폭스 OS 단점:\n\n기본 차단 `window.prompt()` 및 차단 되지 않은 `navigator.notification.prompt()` 사용할 수 있습니다.\n\n## navigator.notification.beep\n\n장치는 경고음 소리를 재생 합니다.\n\n    navigator.notification.beep(times);\n    \n\n  * **times**: 경고음을 반복 하는 횟수. *(수)*\n\n### 예를 들어\n\n    // Beep twice!\n    navigator.notification.beep(2);\n    \n\n### 지원 되는 플랫폼\n\n  * 아마존 화재 운영 체제\n  * 안 드 로이드\n  * 블랙베리 10\n  * iOS\n  * Tizen\n  * Windows Phone 7과 8\n  * 윈도우 8\n\n### 아마존 화재 OS 단점\n\n  * 아마존 화재 운영 체제 기본 **설정/디스플레이 및 사운드** 패널에 지정 된 **알림 소리** 재생 됩니다.\n\n### 안 드 로이드 단점\n\n  * 안 드 로이드 기본 **알림 벨소리** **설정/사운드 및 디스플레이** 패널에서 지정 합니다.\n\n### Windows Phone 7, 8 특수\n\n  * 코르 도우 바 분포에서 일반 경고음 파일에 의존합니다.\n\n### Tizen 특수\n\n  * Tizen은 미디어 API 통해 오디오 파일을 재생 하 여 경고음을 구현 합니다.\n\n  * 경고음 파일 짧은 되어야 합니다, 응용 프로그램의 루트 디렉터리의 `소리` 하위 디렉터리에 위치 해야 합니다 및 `beep.wav`는 명명 된."
  },
  {
    "path": "plugins/cordova-plugin-dialogs/doc/ko/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-dialogs\n\n이 플러그인 글로벌 `navigator.notification` 개체를 통해 몇 가지 기본 대화 상자 UI 요소에 액세스할 수 있습니다.\n\n개체 `navigator` 글로벌 범위 첨부 아니에요 때까지 사용할 수 있는 `deviceready` 이벤트 후.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(navigator.notification);\n    }\n    \n\n## 설치\n\n    cordova plugin add cordova-plugin-dialogs\n    \n\n## 메서드\n\n*   `navigator.notification.alert`\n*   `navigator.notification.confirm`\n*   `navigator.notification.prompt`\n*   `navigator.notification.beep`\n\n## navigator.notification.alert\n\n사용자 지정 경고 또는 대화 상자를 보여 줍니다. 이 기능에 대 한 기본 대화 상자를 사용 하는 대부분의 코르도바 구현 하지만 일부 플랫폼은 일반적으로 덜 사용자 정의할 수 있는 브라우저의 `alert` 기능을 사용 합니다.\n\n    navigator.notification.alert(message, alertCallback, [title], [buttonName])\n    \n\n*   **message**: 대화 메시지. *(문자열)*\n\n*   **alertCallback**: 콜백을 호출할 때 경고 대화 기 각. *(기능)*\n\n*   **title**: 제목 대화 상자. *(문자열)* (옵션, 기본값:`Alert`)\n\n*   **buttonName**: 단추 이름. *(문자열)* (옵션, 기본값:`OK`)\n\n### 예를 들어\n\n    function alertDismissed() {\n        // do something\n    }\n    \n    navigator.notification.alert(\n        'You are the winner!',  // message\n        alertDismissed,         // callback\n        'Game Over',            // title\n        'Done'                  // buttonName\n    );\n    \n\n### 지원 되는 플랫폼\n\n*   아마존 화재 운영 체제\n*   안 드 로이드\n*   블랙베리 10\n*   Firefox 운영 체제\n*   iOS\n*   Tizen\n*   Windows Phone 7과 8\n*   윈도우 8\n*   윈도우\n\n### Windows Phone 7, 8 특수\n\n*   아니 내장 브라우저 경고 하지만 다음과 같이 전화를 바인딩할 수 있습니다 `alert()` 전역 범위에서:\n    \n        window.alert = navigator.notification.alert;\n        \n\n*   둘 다 `alert` 와 `confirm` 는 비차단 호출, 결과 비동기적으로 사용할 수 있습니다.\n\n### 파이어 폭스 OS 단점:\n\n기본 차단 `window.alert()` 및 차단 되지 않은 `navigator.notification.alert()` 사용할 수 있습니다.\n\n### 블랙베리 10 단점\n\n`navigator.notification.alert ('텍스트', 콜백, '제목', '텍스트')` 콜백 매개 변수 1 번을 전달 됩니다.\n\n## navigator.notification.confirm\n\n사용자 정의 확인 대화 상자가 표시 됩니다.\n\n    navigator.notification.confirm(message, confirmCallback, [title], [buttonLabels])\n    \n\n*   **message**: 대화 메시지. *(문자열)*\n\n*   **confirmCallback**: 인덱스 버튼 (1, 2 또는 3) 또는 대화 상자 버튼을 누르면 (0) 없이 기 각 될 때 호출할 콜백 합니다. *(기능)*\n\n*   **title**: 제목 대화 상자. *(문자열)* (옵션, 기본값:`Confirm`)\n\n*   **buttonLabels**: 단추 레이블을 지정 하는 문자열 배열입니다. *(배열)* (옵션, 기본값은 [ `OK,Cancel` ])\n\n### confirmCallback\n\n`confirmCallback`는 사용자가 확인 대화 상자에서 단추 중 하나를 누를 때 실행 합니다.\n\n콜백이 걸립니다 인수 `buttonIndex` *(번호)를* 누르면된 버튼의 인덱스입니다. Note 인덱스에서는 인덱싱 1 시작 값은 `1`, `2`, `3`, 등등.\n\n### 예를 들어\n\n    function onConfirm(buttonIndex) {\n        alert('You selected button ' + buttonIndex);\n    }\n    \n    navigator.notification.confirm(\n        'You are the winner!', // message\n         onConfirm,            // callback to invoke with index of button pressed\n        'Game Over',           // title\n        ['Restart','Exit']     // buttonLabels\n    );\n    \n\n### 지원 되는 플랫폼\n\n*   아마존 화재 운영 체제\n*   안 드 로이드\n*   블랙베리 10\n*   Firefox 운영 체제\n*   iOS\n*   Tizen\n*   Windows Phone 7과 8\n*   윈도우 8\n*   윈도우\n\n### Windows Phone 7, 8 특수\n\n*   에 대 한 기본 제공 브라우저 함수가 `window.confirm` , 그러나 할당 하 여 바인딩할 수 있습니다:\n    \n        window.confirm = navigator.notification.confirm;\n        \n\n*   호출 `alert` 및 `confirm` 되므로 차단 되지 않은 결과만 비동기적으로 사용할 수 있습니다.\n\n### 윈도우 특수\n\n*   Windows8/8.1에 3 개 이상 단추 MessageDialog 인스턴스를 추가할 수는 없습니다.\n\n*   Windows Phone 8.1에 두 개 이상의 단추와 대화 상자 표시 수는 없습니다.\n\n### 파이어 폭스 OS 단점:\n\n기본 차단 `window.confirm()` 및 차단 되지 않은 `navigator.notification.confirm()` 사용할 수 있습니다.\n\n## navigator.notification.prompt\n\n브라우저의 `프롬프트` 함수 보다 더 많은 사용자 정의 기본 대화 상자가 표시 됩니다.\n\n    navigator.notification.prompt(message, promptCallback, [title], [buttonLabels], [defaultText])\n    \n\n*   **message**: 대화 메시지. *(문자열)*\n\n*   **promptCallback**: 인덱스 버튼 (1, 2 또는 3) 또는 대화 상자 버튼을 누르면 (0) 없이 기 각 될 때 호출할 콜백 합니다. *(기능)*\n\n*   **title**: 제목 대화 상자. *(문자열)* (옵션, 기본값:`Prompt`)\n\n*   **buttonLabels**: 버튼 레이블 *(배열)* (옵션, 기본값 `[\"확인\", \"취소\"]을` 지정 하는 문자열의 배열)\n\n*   **defaultText**: 기본 텍스트 상자에 값 (`문자열`) 입력 (옵션, 기본값: 빈 문자열)\n\n### promptCallback\n\n`promptCallback`는 사용자가 프롬프트 대화 상자에서 단추 중 하나를 누를 때 실행 합니다. 콜백에 전달 된 `results` 개체에는 다음 속성이 포함 되어 있습니다.\n\n*   **buttonIndex**: 눌려진된 버튼의 인덱스. *(수)* Note 인덱스에서는 인덱싱 1 시작 값은 `1`, `2`, `3`, 등등.\n\n*   **input1**: 프롬프트 대화 상자에 입력 한 텍스트. *(문자열)*\n\n### 예를 들어\n\n    function onPrompt(results) {\n        alert(\"You selected button number \" + results.buttonIndex + \" and entered \" + results.input1);\n    }\n    \n    navigator.notification.prompt(\n        'Please enter your name',  // message\n        onPrompt,                  // callback to invoke\n        'Registration',            // title\n        ['Ok','Exit'],             // buttonLabels\n        'Jane Doe'                 // defaultText\n    );\n    \n\n### 지원 되는 플랫폼\n\n*   아마존 화재 운영 체제\n*   안 드 로이드\n*   Firefox 운영 체제\n*   iOS\n*   Windows Phone 7과 8\n*   윈도우 8\n*   윈도우\n\n### 안 드 로이드 단점\n\n*   안 드 로이드 최대 3 개의 단추를 지원 하 고 그것 보다는 더 이상 무시 합니다.\n\n*   안 드 로이드 3.0 및 나중에, 단추는 홀로 테마를 사용 하는 장치에 대 한 반대 순서로 표시 됩니다.\n\n### 윈도우 특수\n\n*   윈도우에서 프롬프트 대화 같은 네이티브 api의 부족으로 인해 html 기반 이다.\n\n### 파이어 폭스 OS 단점:\n\n기본 차단 `window.prompt()` 및 차단 되지 않은 `navigator.notification.prompt()` 사용할 수 있습니다.\n\n## navigator.notification.beep\n\n장치는 경고음 소리를 재생 합니다.\n\n    navigator.notification.beep(times);\n    \n\n*   **times**: 경고음을 반복 하는 횟수. *(수)*\n\n### 예를 들어\n\n    // Beep twice!\n    navigator.notification.beep(2);\n    \n\n### 지원 되는 플랫폼\n\n*   아마존 화재 운영 체제\n*   안 드 로이드\n*   블랙베리 10\n*   iOS\n*   Tizen\n*   Windows Phone 7과 8\n*   윈도우 8\n\n### 아마존 화재 OS 단점\n\n*   아마존 화재 운영 체제 기본 **설정/디스플레이 및 사운드** 패널에 지정 된 **알림 소리** 재생 됩니다.\n\n### 안 드 로이드 단점\n\n*   안 드 로이드 기본 **알림 벨소리** **설정/사운드 및 디스플레이** 패널에서 지정 합니다.\n\n### Windows Phone 7, 8 특수\n\n*   코르 도우 바 분포에서 일반 경고음 파일에 의존합니다.\n\n### Tizen 특수\n\n*   Tizen은 미디어 API 통해 오디오 파일을 재생 하 여 경고음을 구현 합니다.\n\n*   경고음 파일 짧은 되어야 합니다, 응용 프로그램의 루트 디렉터리의 `소리` 하위 디렉터리에 위치 해야 합니다 및 `beep.wav`는 명명 된.\n"
  },
  {
    "path": "plugins/cordova-plugin-dialogs/doc/pl/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-dialogs\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-dialogs.svg)](https://travis-ci.org/apache/cordova-plugin-dialogs)\n\nTen plugin umożliwia dostęp do niektórych rodzimych okna dialogowego elementy interfejsu użytkownika za pośrednictwem obiektu globalnego `navigator.notification`.\n\nMimo, że obiekt jest dołączony do globalnego zakresu `navigator`, to nie dostępne dopiero po zdarzeniu `deviceready`.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(navigator.notification);\n    }\n    \n\n## Instalacja\n\n    cordova plugin add cordova-plugin-dialogs\n    \n\n## Metody\n\n  * `navigator.notification.alert`\n  * `navigator.notification.confirm`\n  * `navigator.notification.prompt`\n  * `navigator.notification.beep`\n\n## navigator.notification.alert\n\nPokazuje niestandardowe wpisu lub okno dialogowe. Większość implementacji Cordova używać rodzimych okno dialogowe dla tej funkcji, ale niektóre platformy używać przeglądarki `alert` funkcji, która jest zazwyczaj mniej konfigurowalny.\n\n    navigator.notification.alert(message, alertCallback, [title], [buttonName])\n    \n\n  * **wiadomość**: komunikat okna dialogowego. *(String)*\n\n  * **alertCallback**: wywołanie zwrotne do wywołania, gdy okno dialogowe alert jest oddalona. *(Funkcja)*\n\n  * **tytuł**: okno tytuł. *(String)* (Opcjonalna, domyślnie`Alert`)\n\n  * **buttonName**: Nazwa przycisku. *(String)* (Opcjonalna, domyślnie`OK`)\n\n### Przykład\n\n    function alertDismissed() {\n        // do something\n    }\n    \n    navigator.notification.alert(\n        'You are the winner!',  // message\n        alertDismissed,         // callback\n        'Game Over',            // title\n        'Done'                  // buttonName\n    );\n    \n\n### Obsługiwane platformy\n\n  * Amazon Fire OS\n  * Android\n  * BlackBerry 10\n  * Firefox OS\n  * iOS\n  * Tizen\n  * Windows Phone 7 i 8\n  * Windows 8\n  * Windows\n\n### Windows Phone 7 i 8 dziwactwa\n\n  * Istnieje wpis nie wbudowana przeglądarka, ale można powiązać w następujący sposób na wywołanie `alert()` w globalnym zasięgu:\n    \n        window.alert = navigator.notification.alert;\n        \n\n  * Zarówno `alert` i `confirm` są bez blokowania połączeń, których wyniki są tylko dostępne asynchronicznie.\n\n### Firefox OS dziwactwa:\n\nDostępne są zarówno rodzimych blokuje `window.alert()` i bez blokowania `navigator.notification.alert()`.\n\n### Jeżyna 10 dziwactwa\n\nparametr wywołania zwrotnego `Navigator.Notification.alert (\"tekst\", wywołanie zwrotne, 'tytuł', 'tekst')` jest przekazywana numer 1.\n\n## navigator.notification.confirm\n\nWyświetla okno dialogowe potwierdzenia konfigurowalny.\n\n    navigator.notification.confirm(message, confirmCallback, [title], [buttonLabels])\n    \n\n  * **wiadomość**: komunikat okna dialogowego. *(String)*\n\n  * **confirmCallback**: wywołanie zwrotne do wywołania z indeksu z przycisku (1, 2 lub 3), lub gdy okno jest zwolniony bez naciśnij przycisk (0). *(Funkcja)*\n\n  * **tytuł**: okno tytuł. *(String)* (Opcjonalna, domyślnie`Confirm`)\n\n  * **buttonLabels**: tablica ciągów, określając etykiety przycisków. *(Tablica)* (Opcjonalna, domyślnie [ `OK,Cancel` ])\n\n### confirmCallback\n\n`confirmCallback` wykonuje, gdy użytkownik naciśnie klawisz jeden z przycisków w oknie dialogowym potwierdzenia.\n\nWywołanie zwrotne wymaga argumentu `buttonIndex` *(numer)*, który jest indeksem wciśnięty przycisk. Należy zauważyć, że indeks używa, na podstawie jednego indeksowania, więc wartością jest `1`, `2`, `3` itd.\n\n### Przykład\n\n    function onConfirm(buttonIndex) {\n        alert('You selected button ' + buttonIndex);\n    }\n    \n    navigator.notification.confirm(\n        'You are the winner!', // message\n         onConfirm,            // callback to invoke with index of button pressed\n        'Game Over',           // title\n        ['Restart','Exit']     // buttonLabels\n    );\n    \n\n### Obsługiwane platformy\n\n  * Amazon Fire OS\n  * Android\n  * BlackBerry 10\n  * Firefox OS\n  * iOS\n  * Tizen\n  * Windows Phone 7 i 8\n  * Windows 8\n  * Windows\n\n### Windows Phone 7 i 8 dziwactwa\n\n  * Istnieje funkcja wbudowana przeglądarka nie `window.confirm` , ale można go powiązać przypisując:\n    \n        window.confirm = navigator.notification.confirm;\n        \n\n  * Wzywa do `alert` i `confirm` są bez blokowania, więc wynik jest tylko dostępnych asynchronicznie.\n\n### Windows dziwactwa\n\n  * Na Windows8/8.1 to nie można dodać więcej niż trzy przyciski do instancji MessageDialog.\n\n  * Na Windows Phone 8.1 nie jest możliwe wyświetlić okno dialogowe z więcej niż dwoma przyciskami.\n\n### Firefox OS dziwactwa:\n\nDostępne są zarówno rodzimych blokuje `window.confirm()` i bez blokowania `navigator.notification.confirm()`.\n\n## navigator.notification.prompt\n\nWyświetla okno dialogowe macierzystego, który bardziej niż przeglądarki `prompt` funkcja.\n\n    navigator.notification.prompt(message, promptCallback, [title], [buttonLabels], [defaultText])\n    \n\n  * **wiadomość**: komunikat okna dialogowego. *(String)*\n\n  * **promptCallback**: wywołanie zwrotne do wywołania z indeksu z przycisku (1, 2 lub 3), lub gdy okno jest zwolniony bez naciśnij przycisk (0). *(Funkcja)*\n\n  * **title**: okno tytuł *(String)* (opcjonalna, domyślnie `polecenia`)\n\n  * **buttonLabels**: tablica ciągów, określając przycisk etykiety *(tablica)* (opcjonalna, domyślnie `[\"OK\", \"Anuluj\"]`)\n\n  * **defaultText**: domyślnie pole tekstowe wprowadzania wartości (`String`) (opcjonalna, domyślnie: pusty ciąg)\n\n### promptCallback\n\n`promptCallback` wykonuje, gdy użytkownik naciśnie klawisz jeden z przycisków w oknie dialogowym polecenia. Obiektu `results` przekazane do wywołania zwrotnego zawiera następujące właściwości:\n\n  * **buttonIndex**: indeks wciśnięty przycisk. *(Liczba)* Należy zauważyć, że indeks używa, na podstawie jednego indeksowania, więc wartością jest `1`, `2`, `3` itd.\n\n  * **input1**: Tekst wprowadzony w oknie polecenia. *(String)*\n\n### Przykład\n\n    function onPrompt(results) {\n        alert(\"You selected button number \" + results.buttonIndex + \" and entered \" + results.input1);\n    }\n    \n    navigator.notification.prompt(\n        'Please enter your name',  // message\n        onPrompt,                  // callback to invoke\n        'Registration',            // title\n        ['Ok','Exit'],             // buttonLabels\n        'Jane Doe'                 // defaultText\n    );\n    \n\n### Obsługiwane platformy\n\n  * Amazon Fire OS\n  * Android\n  * Firefox OS\n  * iOS\n  * Windows Phone 7 i 8\n  * Windows 8\n  * Windows\n\n### Dziwactwa Androida\n\n  * Android obsługuje maksymalnie trzy przyciski i więcej niż to ignoruje.\n\n  * Android 3.0 i nowszych przyciski są wyświetlane w kolejności odwrotnej do urządzenia, które używają tematu Holo.\n\n### Windows dziwactwa\n\n  * W systemie Windows wierzyciel okno jest oparte na języku html, ze względu na brak takich natywnego api.\n\n### Firefox OS dziwactwa:\n\nDostępne są zarówno rodzimych blokuje `window.prompt()` i bez blokowania `navigator.notification.prompt()`.\n\n## navigator.notification.beep\n\nUrządzenie odtwarza sygnał ciągły dźwięk.\n\n    navigator.notification.beep(times);\n    \n\n  * **times**: liczba powtórzeń po sygnale. *(Liczba)*\n\n### Przykład\n\n    // Beep twice!\n    navigator.notification.beep(2);\n    \n\n### Obsługiwane platformy\n\n  * Amazon Fire OS\n  * Android\n  * BlackBerry 10\n  * iOS\n  * Tizen\n  * Windows Phone 7 i 8\n  * Windows 8\n\n### Amazon ogień OS dziwactwa\n\n  * Amazon ogień OS gra domyślny **Dźwięk powiadomienia** określone w panelu **ekranu/ustawienia i dźwięk**.\n\n### Dziwactwa Androida\n\n  * Android gra domyślnie **dzwonek powiadomienia** określone w panelu **ustawień/dźwięk i wyświetlacz**.\n\n### Windows Phone 7 i 8 dziwactwa\n\n  * Opiera się na pliku rodzajowego sygnał z rozkładu Cordova.\n\n### Dziwactwa Tizen\n\n  * Tizen implementuje dźwięków przez odtwarzania pliku audio za pośrednictwem mediów API.\n\n  * Plik dźwiękowy muszą być krótkie, musi znajdować się w podkatalogu `dźwięki` w katalogu głównym aplikacji i musi być o nazwie `beep.wav`."
  },
  {
    "path": "plugins/cordova-plugin-dialogs/doc/pl/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-dialogs\n\nTen plugin umożliwia dostęp do niektórych rodzimych okna dialogowego elementy interfejsu użytkownika za pośrednictwem obiektu globalnego `navigator.notification`.\n\nMimo, że obiekt jest dołączony do globalnego zakresu `navigator`, to nie dostępne dopiero po zdarzeniu `deviceready`.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(navigator.notification);\n    }\n    \n\n## Instalacja\n\n    cordova plugin add cordova-plugin-dialogs\n    \n\n## Metody\n\n*   `navigator.notification.alert`\n*   `navigator.notification.confirm`\n*   `navigator.notification.prompt`\n*   `navigator.notification.beep`\n\n## navigator.notification.alert\n\nPokazuje niestandardowe wpisu lub okno dialogowe. Większość implementacji Cordova używać rodzimych okno dialogowe dla tej funkcji, ale niektóre platformy używać przeglądarki `alert` funkcji, która jest zazwyczaj mniej konfigurowalny.\n\n    navigator.notification.alert(message, alertCallback, [title], [buttonName])\n    \n\n*   **wiadomość**: komunikat okna dialogowego. *(String)*\n\n*   **alertCallback**: wywołanie zwrotne do wywołania, gdy okno dialogowe alert jest oddalona. *(Funkcja)*\n\n*   **tytuł**: okno tytuł. *(String)* (Opcjonalna, domyślnie`Alert`)\n\n*   **buttonName**: Nazwa przycisku. *(String)* (Opcjonalna, domyślnie`OK`)\n\n### Przykład\n\n    function alertDismissed() {\n        // do something\n    }\n    \n    navigator.notification.alert(\n        'You are the winner!',  // message\n        alertDismissed,         // callback\n        'Game Over',            // title\n        'Done'                  // buttonName\n    );\n    \n\n### Obsługiwane platformy\n\n*   Amazon Fire OS\n*   Android\n*   BlackBerry 10\n*   Firefox OS\n*   iOS\n*   Tizen\n*   Windows Phone 7 i 8\n*   Windows 8\n*   Windows\n\n### Windows Phone 7 i 8 dziwactwa\n\n*   Istnieje wpis nie wbudowana przeglądarka, ale można powiązać w następujący sposób na wywołanie `alert()` w globalnym zasięgu:\n    \n        window.alert = navigator.notification.alert;\n        \n\n*   Zarówno `alert` i `confirm` są bez blokowania połączeń, których wyniki są tylko dostępne asynchronicznie.\n\n### Firefox OS dziwactwa:\n\nDostępne są zarówno rodzimych blokuje `window.alert()` i bez blokowania `navigator.notification.alert()`.\n\n### Jeżyna 10 dziwactwa\n\nparametr wywołania zwrotnego `Navigator.Notification.alert (\"tekst\", wywołanie zwrotne, 'tytuł', 'tekst')` jest przekazywana numer 1.\n\n## navigator.notification.confirm\n\nWyświetla okno dialogowe potwierdzenia konfigurowalny.\n\n    navigator.notification.confirm(message, confirmCallback, [title], [buttonLabels])\n    \n\n*   **wiadomość**: komunikat okna dialogowego. *(String)*\n\n*   **confirmCallback**: wywołanie zwrotne do wywołania z indeksu z przycisku (1, 2 lub 3), lub gdy okno jest zwolniony bez naciśnij przycisk (0). *(Funkcja)*\n\n*   **tytuł**: okno tytuł. *(String)* (Opcjonalna, domyślnie`Confirm`)\n\n*   **buttonLabels**: tablica ciągów, określając etykiety przycisków. *(Tablica)* (Opcjonalna, domyślnie [ `OK,Cancel` ])\n\n### confirmCallback\n\n`confirmCallback` wykonuje, gdy użytkownik naciśnie klawisz jeden z przycisków w oknie dialogowym potwierdzenia.\n\nWywołanie zwrotne wymaga argumentu `buttonIndex` *(numer)*, który jest indeksem wciśnięty przycisk. Należy zauważyć, że indeks używa, na podstawie jednego indeksowania, więc wartością jest `1`, `2`, `3` itd.\n\n### Przykład\n\n    function onConfirm(buttonIndex) {\n        alert('You selected button ' + buttonIndex);\n    }\n    \n    navigator.notification.confirm(\n        'You are the winner!', // message\n         onConfirm,            // callback to invoke with index of button pressed\n        'Game Over',           // title\n        ['Restart','Exit']     // buttonLabels\n    );\n    \n\n### Obsługiwane platformy\n\n*   Amazon Fire OS\n*   Android\n*   BlackBerry 10\n*   Firefox OS\n*   iOS\n*   Tizen\n*   Windows Phone 7 i 8\n*   Windows 8\n*   Windows\n\n### Windows Phone 7 i 8 dziwactwa\n\n*   Istnieje funkcja wbudowana przeglądarka nie `window.confirm` , ale można go powiązać przypisując:\n    \n        window.confirm = navigator.notification.confirm;\n        \n\n*   Wzywa do `alert` i `confirm` są bez blokowania, więc wynik jest tylko dostępnych asynchronicznie.\n\n### Windows dziwactwa\n\n*   Na Windows8/8.1 to nie można dodać więcej niż trzy przyciski do instancji MessageDialog.\n\n*   Na Windows Phone 8.1 nie jest możliwe wyświetlić okno dialogowe z więcej niż dwoma przyciskami.\n\n### Firefox OS dziwactwa:\n\nDostępne są zarówno rodzimych blokuje `window.confirm()` i bez blokowania `navigator.notification.confirm()`.\n\n## navigator.notification.prompt\n\nWyświetla okno dialogowe macierzystego, który bardziej niż przeglądarki `prompt` funkcja.\n\n    navigator.notification.prompt(message, promptCallback, [title], [buttonLabels], [defaultText])\n    \n\n*   **message**: komunikat okna dialogowego. *(String)*\n\n*   **promptCallback**: wywołanie zwrotne do wywołania z indeksu z przycisku (1, 2 lub 3), lub gdy okno jest zwolniony bez naciśnij przycisk (0). *(Funkcja)*\n\n*   **title**: okno tytuł *(String)* (opcjonalna, domyślnie `polecenia`)\n\n*   **buttonLabels**: tablica ciągów, określając przycisk etykiety *(tablica)* (opcjonalna, domyślnie `[\"OK\", \"Anuluj\"]`)\n\n*   **defaultText**: domyślnie pole tekstowe wprowadzania wartości (`String`) (opcjonalna, domyślnie: pusty ciąg)\n\n### promptCallback\n\n`promptCallback` wykonuje, gdy użytkownik naciśnie klawisz jeden z przycisków w oknie dialogowym polecenia. Obiektu `results` przekazane do wywołania zwrotnego zawiera następujące właściwości:\n\n*   **buttonIndex**: indeks wciśnięty przycisk. *(Liczba)* Należy zauważyć, że indeks używa, na podstawie jednego indeksowania, więc wartością jest `1`, `2`, `3` itd.\n\n*   **input1**: Tekst wprowadzony w oknie polecenia. *(String)*\n\n### Przykład\n\n    function onPrompt(results) {\n        alert(\"You selected button number \" + results.buttonIndex + \" and entered \" + results.input1);\n    }\n    \n    navigator.notification.prompt(\n        'Please enter your name',  // message\n        onPrompt,                  // callback to invoke\n        'Registration',            // title\n        ['Ok','Exit'],             // buttonLabels\n        'Jane Doe'                 // defaultText\n    );\n    \n\n### Obsługiwane platformy\n\n*   Amazon Fire OS\n*   Android\n*   Firefox OS\n*   iOS\n*   Windows Phone 7 i 8\n*   Windows 8\n*   Windows\n\n### Dziwactwa Androida\n\n*   Android obsługuje maksymalnie trzy przyciski i więcej niż to ignoruje.\n\n*   Android 3.0 i nowszych przyciski są wyświetlane w kolejności odwrotnej do urządzenia, które używają tematu Holo.\n\n### Windows dziwactwa\n\n*   W systemie Windows wierzyciel okno jest oparte na języku html, ze względu na brak takich natywnego api.\n\n### Firefox OS dziwactwa:\n\nDostępne są zarówno rodzimych blokuje `window.prompt()` i bez blokowania `navigator.notification.prompt()`.\n\n## navigator.notification.beep\n\nUrządzenie odtwarza sygnał ciągły dźwięk.\n\n    navigator.notification.beep(times);\n    \n\n*   **times**: liczba powtórzeń po sygnale. *(Liczba)*\n\n### Przykład\n\n    // Beep twice!\n    navigator.notification.beep(2);\n    \n\n### Obsługiwane platformy\n\n*   Amazon Fire OS\n*   Android\n*   BlackBerry 10\n*   iOS\n*   Tizen\n*   Windows Phone 7 i 8\n*   Windows 8\n\n### Amazon ogień OS dziwactwa\n\n*   Amazon ogień OS gra domyślny **Dźwięk powiadomienia** określone w panelu **ekranu/ustawienia i dźwięk**.\n\n### Dziwactwa Androida\n\n*   Android gra domyślnie **dzwonek powiadomienia** określone w panelu **ustawień/dźwięk i wyświetlacz**.\n\n### Windows Phone 7 i 8 dziwactwa\n\n*   Opiera się na pliku rodzajowego sygnał z rozkładu Cordova.\n\n### Dziwactwa Tizen\n\n*   Tizen implementuje dźwięków przez odtwarzania pliku audio za pośrednictwem mediów API.\n\n*   Plik dźwiękowy muszą być krótkie, musi znajdować się w podkatalogu `dźwięki` w katalogu głównym aplikacji i musi być o nazwie `beep.wav`.\n"
  },
  {
    "path": "plugins/cordova-plugin-dialogs/doc/ru/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-dialogs\n\nЭтот плагин обеспечивает доступ к некоторым элементам собственного диалогового окна пользовательского интерфейса.\n\n## Установка\n\n    cordova plugin add cordova-plugin-dialogs\n    \n\n## Методы\n\n*   `navigator.notification.alert`\n*   `navigator.notification.confirm`\n*   `navigator.notification.prompt`\n*   `navigator.notification.beep`\n\n## navigator.notification.alert\n\nПоказывает окно пользовательские оповещения или диалоговое окно. Большинство реализаций Cordova использовать диалоговое окно родной для этой функции, но некоторые платформы браузера `alert` функция, которая как правило менее настраивается.\n\n    Navigator.Notification.Alert (сообщение, alertCallback, [название], [buttonName])\n    \n\n*   **сообщение**: сообщение диалога. *(Строка)*\n\n*   **alertCallback**: обратного вызова для вызова, когда закрывается диалоговое окно оповещения. *(Функция)*\n\n*   **название**: диалоговое окно название. *(Строка)* (Опционально, по умолчанию`Alert`)\n\n*   **buttonName**: имя кнопки. *(Строка)* (Опционально, по умолчанию`OK`)\n\n### Пример\n\n    function alertDismissed() {\n        // do something\n    }\n    \n    navigator.notification.alert(\n        'You are the winner!',  // message\n        alertDismissed,         // callback\n        'Game Over',            // title\n        'Done'                  // buttonName\n    );\n    \n\n### Поддерживаемые платформы\n\n*   Amazon Fire OS\n*   Android\n*   BlackBerry 10\n*   Firefox OS\n*   iOS\n*   Tizen\n*   Windows Phone 7 и 8\n*   Windows 8\n\n### Особенности Windows Phone 7 и 8\n\n*   Существует предупреждение не встроенный браузер, но можно привязать один следующим позвонить `alert()` в глобальной области действия:\n    \n        window.alert = navigator.notification.alert;\n        \n\n*   Оба `alert` и `confirm` являются не блокировка звонков, результаты которых доступны только асинхронно.\n\n### Firefox OS причуды:\n\nКак родной блокировка `window.alert()` и неблокирующий `navigator.notification.alert()` доступны.\n\n## navigator.notification.confirm\n\nОтображает диалоговое окно Настраиваемый подтверждения.\n\n    navigator.notification.confirm(message, confirmCallback, [title], [buttonLabels])\n    \n\n*   **сообщение**: сообщение диалога. *(Строка)*\n\n*   **confirmCallback**: обратного вызова с индексом кнопка нажата (1, 2 или 3) или когда диалоговое окно закрывается без нажатия кнопки (0). *(Функция)*\n\n*   **название**: диалоговое окно название. *(Строка)* (Опционально, по умолчанию`Confirm`)\n\n*   **buttonLabels**: массив строк, указав названия кнопок. *(Массив)* (Не обязательно, по умолчанию [ `OK,Cancel` ])\n\n### confirmCallback\n\n`confirmCallback`Выполняется, когда пользователь нажимает одну из кнопок в диалоговом окне подтверждения.\n\nАргументом функции обратного вызова `buttonIndex` *(номер)*, который является индекс нажатой кнопки. Обратите внимание, что индекс использует единицы индексации, поэтому значение `1` , `2` , `3` , и т.д.\n\n### Пример\n\n    function onConfirm(buttonIndex) {\n        alert('You selected button ' + buttonIndex);\n    }\n    \n    navigator.notification.confirm(\n        'You are the winner!', // message\n         onConfirm,            // callback to invoke with index of button pressed\n        'Game Over',           // title\n        ['Restart','Exit']     // buttonLabels\n    );\n    \n\n### Поддерживаемые платформы\n\n*   Amazon Fire OS\n*   Android\n*   BlackBerry 10\n*   Firefox OS\n*   iOS\n*   Tizen\n*   Windows Phone 7 и 8\n*   Windows 8\n\n### Особенности Windows Phone 7 и 8\n\n*   Нет встроенного браузера функция для `window.confirm` , но его можно привязать путем присвоения:\n    \n        window.confirm = navigator.notification.confirm;\n        \n\n*   Вызовы `alert` и `confirm` являются не блокируется, поэтому результат доступен только асинхронно.\n\n### Firefox OS причуды:\n\nКак родной блокировка `window.confirm()` и неблокирующий `navigator.notification.confirm()` доступны.\n\n## navigator.notification.prompt\n\nОтображает родной диалоговое окно более настраиваемый, чем в браузере `prompt` функции.\n\n    navigator.notification.prompt(message, promptCallback, [title], [buttonLabels], [defaultText])\n    \n\n*   **сообщение**: сообщение диалога. *(Строка)*\n\n*   **promptCallback**: обратного вызова с индексом кнопка нажата (1, 2 или 3) или когда диалоговое окно закрывается без нажатия кнопки (0). *(Функция)*\n\n*   **название**: диалоговое окно название *(String)* (опционально, по умолчанию`Prompt`)\n\n*   **buttonLabels**: массив строк, указав кнопку этикетки *(массив)* (опционально, по умолчанию`[\"OK\",\"Cancel\"]`)\n\n*   **defaultText**: по умолчанию textbox входное значение ( `String` ) (опционально, по умолчанию: пустая строка)\n\n### promptCallback\n\n`promptCallback`Выполняется, когда пользователь нажимает одну из кнопок в диалоговом окне приглашения. `results`Объект, переданный в метод обратного вызова содержит следующие свойства:\n\n*   **buttonIndex**: индекс нажатой кнопки. *(Число)* Обратите внимание, что индекс использует единицы индексации, поэтому значение `1` , `2` , `3` , и т.д.\n\n*   **INPUT1**: текст, введенный в диалоговом окне приглашения. *(Строка)*\n\n### Пример\n\n    function onPrompt(results) {\n        alert(\"You selected button number \" + results.buttonIndex + \" and entered \" + results.input1);\n    }\n    \n    navigator.notification.prompt(\n        'Please enter your name',  // message\n        onPrompt,                  // callback to invoke\n        'Registration',            // title\n        ['Ok','Exit'],             // buttonLabels\n        'Jane Doe'                 // defaultText\n    );\n    \n\n### Поддерживаемые платформы\n\n*   Amazon Fire OS\n*   Android\n*   Firefox OS\n*   iOS\n*   Windows Phone 7 и 8\n\n### Особенности Android\n\n*   Android поддерживает максимум из трех кнопок и игнорирует больше, чем это.\n\n*   На Android 3.0 и более поздних версиях кнопки отображаются в обратном порядке для устройств, которые используют тему холо.\n\n### Firefox OS причуды:\n\nКак родной блокировка `window.prompt()` и неблокирующий `navigator.notification.prompt()` доступны.\n\n## navigator.notification.beep\n\nУстройство воспроизводит звуковой сигнал звук.\n\n    navigator.notification.beep(times);\n    \n\n*   **раз**: количество раз, чтобы повторить сигнал. *(Число)*\n\n### Пример\n\n    // Beep twice!\n    navigator.notification.beep(2);\n    \n\n### Поддерживаемые платформы\n\n*   Amazon Fire OS\n*   Android\n*   BlackBerry 10\n*   iOS\n*   Tizen\n*   Windows Phone 7 и 8\n*   Windows 8\n\n### Особенности Amazon Fire OS\n\n*   Amazon Fire OS играет по умолчанию **Звук уведомления** , указанного на панели **параметров/дисплей и звук** .\n\n### Особенности Android\n\n*   Android играет по умолчанию **уведомления рингтон** указанных в панели **настройки/звук и дисплей** .\n\n### Особенности Windows Phone 7 и 8\n\n*   Опирается на общий звуковой файл из дистрибутива Кордова.\n\n### Особенности Tizen\n\n*   Tizen реализует гудков, воспроизведении аудиофайла через СМИ API.\n\n*   Звуковой файл должен быть коротким, должен быть расположен в `sounds` подкаталог корневого каталога приложения и должны быть названы`beep.wav`.\n"
  },
  {
    "path": "plugins/cordova-plugin-dialogs/doc/zh/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-dialogs\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-dialogs.svg)](https://travis-ci.org/apache/cordova-plugin-dialogs)\n\n這個外掛程式提供對一些本機對話方塊使用者介面元素，通過全球 `navigator.notification` 物件的訪問。\n\n雖然該物件附加到全球範圍內 `導航器`，它不可用直到 `deviceready` 事件之後。\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(navigator.notification);\n    }\n    \n\n## 安裝\n\n    cordova plugin add cordova-plugin-dialogs\n    \n\n## 方法\n\n  * `navigator.notification.alert`\n  * `navigator.notification.confirm`\n  * `navigator.notification.prompt`\n  * `navigator.notification.beep`\n\n## navigator.notification.alert\n\n顯示一個自訂的警報或對話方塊框。 大多數的科爾多瓦實現使用本機的對話方塊為此功能，但某些平臺上使用瀏覽器的 `alert` 功能，這是通常不那麼可自訂。\n\n    navigator.notification.alert(message, alertCallback, [title], [buttonName])\n    \n\n  * **message**： 消息對話方塊。*（String）*\n\n  * **alertCallback**： 當警報對話方塊的被解雇時要調用的回檔。*（函數）*\n\n  * **title**： 標題對話方塊。*（String）*（可選，預設值為`Alert`)\n\n  * **buttonName**： 按鈕名稱。*（字串）*（可選，預設值為`OK`)\n\n### 示例\n\n    function alertDismissed() {\n        // do something\n    }\n    \n    navigator.notification.alert(\n        'You are the winner!',  // message\n        alertDismissed,         // callback\n        'Game Over',            // title\n        'Done'                  // buttonName\n    );\n    \n\n### 支援的平臺\n\n  * 亞馬遜火 OS\n  * Android 系統\n  * 黑莓 10\n  * 火狐瀏覽器作業系統\n  * iOS\n  * Tizen\n  * Windows Phone 7 和 8\n  * Windows 8\n  * Windows\n\n### Windows Phone 7 和 8 怪癖\n\n  * 有沒有內置瀏覽器警報，但你可以綁定一個，如下所示調用 `alert()` 在全球範圍內：\n    \n        window.alert = navigator.notification.alert;\n        \n\n  * 兩個 `alert` 和 `confirm` 的非阻塞的調用，其中的結果才是可用的非同步。\n\n### 火狐瀏覽器作業系統怪癖：\n\n本機阻止 `window.alert()` 和非阻塞的 `navigator.notification.alert()` 都可。\n\n### 黑莓 10 怪癖\n\n`navigator.notification.alert ('message'、 confirmCallback、 'title'、 'buttonLabels')` 回檔參數被傳遞的數位 1。\n\n## navigator.notification.confirm\n\n顯示一個可自訂的確認對話方塊。\n\n    navigator.notification.confirm(message, confirmCallback, [title], [buttonLabels])\n    \n\n  * **message**： 消息對話方塊。*（String）*\n\n  * **confirmCallback**: 要用索引 （1、 2 或 3） 按下的按鈕，或者在沒有按下按鈕 (0) 駁回了對話方塊中時調用的回檔。*（函數）*\n\n  * **title**： 標題對話方塊。*（字串）*（可選，預設值為`Confirm`)\n\n  * **buttonLabels**： 指定按鈕標籤的字串陣列。*（陣列）*（可選，預設值為 [ `OK,Cancel` ])\n\n### confirmCallback\n\n當使用者按下確認對話方塊中的按鈕之一時，將執行 `confirmCallback`。\n\n回檔需要參數 `buttonIndex` *（編號）*，即按下的按鈕的索引。 請注意索引使用一個基於索引，因此值 `1`、 `2`、 `3` 等。\n\n### 示例\n\n    function onConfirm(buttonIndex) {\n        alert('You selected button ' + buttonIndex);\n    }\n    \n    navigator.notification.confirm(\n        'You are the winner!', // message\n         onConfirm,            // callback to invoke with index of button pressed\n        'Game Over',           // title\n        ['Restart','Exit']     // buttonLabels\n    );\n    \n\n### 支援的平臺\n\n  * 亞馬遜火 OS\n  * Android 系統\n  * 黑莓 10\n  * 火狐瀏覽器作業系統\n  * iOS\n  * Tizen\n  * Windows Phone 7 和 8\n  * Windows 8\n  * Windows\n\n### Windows Phone 7 和 8 怪癖\n\n  * 有沒有內置的瀏覽器功能的 `window.confirm` ，但你可以將它綁定通過分配：\n    \n        window.confirm = navigator.notification.confirm;\n        \n\n  * 調用到 `alert` 和 `confirm` 的非阻塞，所以結果就是只可用以非同步方式。\n\n### Windows 的怪癖\n\n  * 在 Windows8/8.1 它是不可能將超過三個按鈕添加到 MessageDialog 實例。\n\n  * 在 Windows Phone 8.1 它是不可能顯示有超過兩個按鈕的對話方塊。\n\n### 火狐瀏覽器作業系統怪癖：\n\n本機阻止 `window.confirm()` 和非阻塞的 `navigator.notification.confirm()` 都可。\n\n## navigator.notification.prompt\n\n顯示本機的對話方塊，是可定制的比瀏覽器的 `prompt` 功能。\n\n    navigator.notification.prompt(message, promptCallback, [title], [buttonLabels], [defaultText])\n    \n\n  * **message**： 消息對話方塊。*（String）*\n\n  * **promptCallback**： 要用指數 （1、 2 或 3） 按下的按鈕或對話方塊中解雇無 (0) 按下一個按鈕時調用的回檔。*（函數）*\n\n  * **title**： 標題對話方塊。*（String）*（可選，預設值為`Alert`)\n\n  * **buttonLabels**： 指定按鈕標籤 (可選，預設值為 `[\"OK\"，\"Cancel\"]` *（陣列）* 的字串陣列)\n\n  * **defaultText**: 預設文字方塊中輸入值 （`字串`） (可選，預設值： 空字串）\n\n### promptCallback\n\n當使用者按下其中一個提示對話方塊中的按鈕時，將執行 `promptCallback`。傳遞給回檔的 `results` 物件包含以下屬性：\n\n  * **buttonIndex**： 按下的按鈕的索引。*（數）*請注意索引使用一個基於索引，因此值 `1`、 `2`、 `3` 等。\n\n  * **input1**： 在提示對話方塊中輸入的文本。*（字串）*\n\n### 示例\n\n    function onPrompt(results) {\n        alert(\"You selected button number \" + results.buttonIndex + \" and entered \" + results.input1);\n    }\n    \n    navigator.notification.prompt(\n        'Please enter your name',  // message\n        onPrompt,                  // callback to invoke\n        'Registration',            // title\n        ['Ok','Exit'],             // buttonLabels\n        'Jane Doe'                 // defaultText\n    );\n    \n\n### 支援的平臺\n\n  * 亞馬遜火 OS\n  * Android 系統\n  * 火狐瀏覽器作業系統\n  * iOS\n  * Windows Phone 7 和 8\n  * Windows 8\n  * Windows\n\n### Android 的怪癖\n\n  * Android 支援最多的三個按鈕，並忽略任何更多。\n\n  * 在 Android 3.0 及更高版本，使用全息主題的設備以相反的順序顯示按鈕。\n\n### Windows 的怪癖\n\n  * 在 Windows 上提示對話方塊是基於 html 的缺乏這種本機 api。\n\n### 火狐瀏覽器作業系統怪癖：\n\n本機阻止 `window.prompt()` 和非阻塞的 `navigator.notification.prompt()` 都可。\n\n## navigator.notification.beep\n\n該設備播放提示音的聲音。\n\n    navigator.notification.beep(times);\n    \n\n  * **beep**： 次數重複在嗶嗶聲。*（數）*\n\n### 示例\n\n    // Beep twice!\n    navigator.notification.beep(2);\n    \n\n### 支援的平臺\n\n  * 亞馬遜火 OS\n  * Android 系統\n  * 黑莓 10\n  * iOS\n  * Tizen\n  * Windows Phone 7 和 8\n  * Windows 8\n\n### 亞馬遜火 OS 怪癖\n\n  * 亞馬遜火 OS 播放預設 **設置/顯示和聲音** 板下指定的 **通知聲音**。\n\n### Android 的怪癖\n\n  * 安卓系統播放預設 **通知鈴聲** **設置/聲音和顯示** 面板下指定。\n\n### Windows Phone 7 和 8 怪癖\n\n  * 依賴于泛型蜂鳴音檔從科爾多瓦分佈。\n\n### Tizen 怪癖\n\n  * Tizen 通過播放音訊檔通過媒體 API 實現的蜂鳴聲。\n\n  * 蜂鳴音檔必須很短，必須位於應用程式的根目錄中，一個 `聲音` 子目錄和必須將命名為 `beep.wav`."
  },
  {
    "path": "plugins/cordova-plugin-dialogs/doc/zh/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-dialogs\n\n這個外掛程式提供對一些本機對話方塊使用者介面元素，通過全球 `navigator.notification` 物件的訪問。\n\n雖然該物件附加到全球範圍內 `導航器`，它不可用直到 `deviceready` 事件之後。\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(navigator.notification);\n    }\n    \n\n## 安裝\n\n    cordova plugin add cordova-plugin-dialogs\n    \n\n## 方法\n\n*   `navigator.notification.alert`\n*   `navigator.notification.confirm`\n*   `navigator.notification.prompt`\n*   `navigator.notification.beep`\n\n## navigator.notification.alert\n\n顯示一個自訂的警報或對話方塊框。 大多數的科爾多瓦實現使用本機的對話方塊為此功能，但某些平臺上使用瀏覽器的 `alert` 功能，這是通常不那麼可自訂。\n\n    navigator.notification.alert(message, alertCallback, [title], [buttonName])\n    \n\n*   **message**： 消息對話方塊。*（String）*\n\n*   **alertCallback**： 當警報對話方塊的被解雇時要調用的回檔。*（函數）*\n\n*   **title**： 標題對話方塊。*（String）*（可選，預設值為`Alert`)\n\n*   **buttonName**： 按鈕名稱。*（字串）*（可選，預設值為`OK`)\n\n### 示例\n\n    function alertDismissed() {\n        // do something\n    }\n    \n    navigator.notification.alert(\n        'You are the winner!',  // message\n        alertDismissed,         // callback\n        'Game Over',            // title\n        'Done'                  // buttonName\n    );\n    \n\n### 支援的平臺\n\n*   亞馬遜火 OS\n*   Android 系統\n*   黑莓 10\n*   火狐瀏覽器作業系統\n*   iOS\n*   Tizen\n*   Windows Phone 7 和 8\n*   Windows 8\n*   Windows\n\n### Windows Phone 7 和 8 怪癖\n\n*   有沒有內置瀏覽器警報，但你可以綁定一個，如下所示調用 `alert()` 在全球範圍內：\n    \n        window.alert = navigator.notification.alert;\n        \n\n*   兩個 `alert` 和 `confirm` 的非阻塞的調用，其中的結果才是可用的非同步。\n\n### 火狐瀏覽器作業系統怪癖：\n\n本機阻止 `window.alert()` 和非阻塞的 `navigator.notification.alert()` 都可。\n\n### 黑莓 10 怪癖\n\n`navigator.notification.alert ('message'、 confirmCallback、 'title'、 'buttonLabels')` 回檔參數被傳遞的數位 1。\n\n## navigator.notification.confirm\n\n顯示一個可自訂的確認對話方塊。\n\n    navigator.notification.confirm(message, confirmCallback, [title], [buttonLabels])\n    \n\n*   **message**： 消息對話方塊。*（字串）*\n\n*   **confirmCallback**: 要用索引 （1、 2 或 3） 按下的按鈕，或者在沒有按下按鈕 (0) 駁回了對話方塊中時調用的回檔。*（函數）*\n\n*   **title**： 標題對話方塊。*（字串）*（可選，預設值為`Confirm`)\n\n*   **buttonLabels**： 指定按鈕標籤的字串陣列。*（陣列）*（可選，預設值為 [ `OK,Cancel` ])\n\n### confirmCallback\n\n當使用者按下確認對話方塊中的按鈕之一時，將執行 `confirmCallback`。\n\n回檔需要參數 `buttonIndex` *（編號）*，即按下的按鈕的索引。 請注意索引使用一個基於索引，因此值 `1`、 `2`、 `3` 等。\n\n### 示例\n\n    function onConfirm(buttonIndex) {\n        alert('You selected button ' + buttonIndex);\n    }\n    \n    navigator.notification.confirm(\n        'You are the winner!', // message\n         onConfirm,            // callback to invoke with index of button pressed\n        'Game Over',           // title\n        ['Restart','Exit']     // buttonLabels\n    );\n    \n\n### 支援的平臺\n\n*   亞馬遜火 OS\n*   Android 系統\n*   黑莓 10\n*   火狐瀏覽器作業系統\n*   iOS\n*   Tizen\n*   Windows Phone 7 和 8\n*   Windows 8\n*   Windows\n\n### Windows Phone 7 和 8 怪癖\n\n*   有沒有內置的瀏覽器功能的 `window.confirm` ，但你可以將它綁定通過分配：\n    \n        window.confirm = navigator.notification.confirm;\n        \n\n*   調用到 `alert` 和 `confirm` 的非阻塞，所以結果就是只可用以非同步方式。\n\n### Windows 的怪癖\n\n*   在 Windows8/8.1 它是不可能將超過三個按鈕添加到 MessageDialog 實例。\n\n*   在 Windows Phone 8.1 它是不可能顯示有超過兩個按鈕的對話方塊。\n\n### 火狐瀏覽器作業系統怪癖：\n\n本機阻止 `window.confirm()` 和非阻塞的 `navigator.notification.confirm()` 都可。\n\n## navigator.notification.prompt\n\n顯示本機的對話方塊，是可定制的比瀏覽器的 `prompt` 功能。\n\n    navigator.notification.prompt(message, promptCallback, [title], [buttonLabels], [defaultText])\n    \n\n*   **message**： 消息對話方塊。*（String）*\n\n*   **promptCallback**： 要用指數 （1、 2 或 3） 按下的按鈕或對話方塊中解雇無 (0) 按下一個按鈕時調用的回檔。*（函數）*\n\n*   **title**： 標題對話方塊。*（String）*（可選，預設值為`Alert`)\n\n*   **buttonLabels**： 指定按鈕標籤 (可選，預設值為 `[\"OK\"，\"Cancel\"]` *（陣列）* 的字串陣列)\n\n*   **defaultText**: 預設文字方塊中輸入值 （`字串`） (可選，預設值： 空字串）\n\n### promptCallback\n\n當使用者按下其中一個提示對話方塊中的按鈕時，將執行 `promptCallback`。傳遞給回檔的 `results` 物件包含以下屬性：\n\n*   **buttonIndex**： 按下的按鈕的索引。*（數）*請注意索引使用一個基於索引，因此值 `1`、 `2`、 `3` 等。\n\n*   **input1**： 在提示對話方塊中輸入的文本。*（字串）*\n\n### 示例\n\n    function onPrompt(results) {\n        alert(\"You selected button number \" + results.buttonIndex + \" and entered \" + results.input1);\n    }\n    \n    navigator.notification.prompt(\n        'Please enter your name',  // message\n        onPrompt,                  // callback to invoke\n        'Registration',            // title\n        ['Ok','Exit'],             // buttonLabels\n        'Jane Doe'                 // defaultText\n    );\n    \n\n### 支援的平臺\n\n*   亞馬遜火 OS\n*   Android 系統\n*   火狐瀏覽器作業系統\n*   iOS\n*   Windows Phone 7 和 8\n*   Windows 8\n*   Windows\n\n### Android 的怪癖\n\n*   Android 支援最多的三個按鈕，並忽略任何更多。\n\n*   在 Android 3.0 及更高版本，使用全息主題的設備以相反的順序顯示按鈕。\n\n### Windows 的怪癖\n\n*   在 Windows 上提示對話方塊是基於 html 的缺乏這種本機 api。\n\n### 火狐瀏覽器作業系統怪癖：\n\n本機阻止 `window.prompt()` 和非阻塞的 `navigator.notification.prompt()` 都可。\n\n## navigator.notification.beep\n\n該設備播放提示音的聲音。\n\n    navigator.notification.beep(times);\n    \n\n*   **beep**： 次數重複在嗶嗶聲。*（數）*\n\n### 示例\n\n    // Beep twice!\n    navigator.notification.beep(2);\n    \n\n### 支援的平臺\n\n*   亞馬遜火 OS\n*   Android 系統\n*   黑莓 10\n*   iOS\n*   Tizen\n*   Windows Phone 7 和 8\n*   Windows 8\n\n### 亞馬遜火 OS 怪癖\n\n*   亞馬遜火 OS 播放預設 **設置/顯示和聲音** 板下指定的 **通知聲音**。\n\n### Android 的怪癖\n\n*   安卓系統播放預設 **通知鈴聲** **設置/聲音和顯示** 面板下指定。\n\n### Windows Phone 7 和 8 怪癖\n\n*   依賴于泛型蜂鳴音檔從科爾多瓦分佈。\n\n### Tizen 怪癖\n\n*   Tizen 通過播放音訊檔通過媒體 API 實現的蜂鳴聲。\n\n*   蜂鳴音檔必須很短，必須位於應用程式的根目錄中，一個 `聲音` 子目錄和必須將命名為 `beep.wav`.\n"
  },
  {
    "path": "plugins/cordova-plugin-dialogs/package.json",
    "content": "{\n  \"name\": \"cordova-plugin-dialogs\",\n  \"version\": \"1.2.1\",\n  \"description\": \"Cordova Notification Plugin\",\n  \"cordova\": {\n    \"id\": \"cordova-plugin-dialogs\",\n    \"platforms\": [\n      \"firefoxos\",\n      \"android\",\n      \"browser\",\n      \"amazon-fireos\",\n      \"ubuntu\",\n      \"ios\",\n      \"blackberry10\",\n      \"wp7\",\n      \"wp8\",\n      \"windows8\",\n      \"windows\"\n    ]\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/apache/cordova-plugin-dialogs\"\n  },\n  \"keywords\": [\n    \"cordova\",\n    \"notification\",\n    \"ecosystem:cordova\",\n    \"cordova-firefoxos\",\n    \"cordova-android\",\n    \"cordova-browser\",\n    \"cordova-amazon-fireos\",\n    \"cordova-ubuntu\",\n    \"cordova-ios\",\n    \"cordova-blackberry10\",\n    \"cordova-wp7\",\n    \"cordova-wp8\",\n    \"cordova-windows8\",\n    \"cordova-windows\"\n  ],\n  \"scripts\": {\n    \"test\": \"npm run jshint\",\n    \"jshint\": \"node node_modules/jshint/bin/jshint www && node node_modules/jshint/bin/jshint src && node node_modules/jshint/bin/jshint tests\"\n  },\n  \"author\": \"Apache Software Foundation\",\n  \"license\": \"Apache-2.0\",\n  \"devDependencies\": {\n    \"jshint\": \"^2.6.0\"\n  }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-dialogs/plugin.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  Licensed to the Apache Software Foundation (ASF) under one\n  or more contributor license agreements.  See the NOTICE file\n  distributed with this work for additional information\n  regarding copyright ownership.  The ASF licenses this file\n  to you under the Apache License, Version 2.0 (the\n  \"License\"); you may not use this file except in compliance\n  with the License.  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing,\n  software distributed under the License is distributed on an\n  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n  KIND, either express or implied.  See the License for the\n  specific language governing permissions and limitations\n  under the License.\n-->\n\n<plugin xmlns=\"http://apache.org/cordova/ns/plugins/1.0\"\n           id=\"cordova-plugin-dialogs\"\n      version=\"1.2.1\">\n\n    <name>Notification</name>\n    <description>Cordova Notification Plugin</description>\n    <license>Apache 2.0</license>\n    <keywords>cordova,notification</keywords>\n    <repo>https://git-wip-us.apache.org/repos/asf/cordova-plugin-dialogs.git</repo>\n    <issue>https://issues.apache.org/jira/browse/CB/component/12320642</issue>\n\n    <js-module src=\"www/notification.js\" name=\"notification\">\n        <merges target=\"navigator.notification\" />\n    </js-module>\n\n    <!-- firefoxos -->\n    <platform name=\"firefoxos\">\n        <config-file target=\"config.xml\" parent=\"/*\">\n            <feature name=\"Notification\">\n                <param name=\"firefoxos-package\" value=\"Notification\" />\n            </feature>\n        </config-file>                                         \n        \n\t\t<asset src=\"www/firefoxos/notification.css\" target=\"css/notification.css\" />\n\t\t<asset src=\"www/firefoxos/danger-press.png\" target=\"img/danger-press.png\" />\n\t\t<asset src=\"www/firefoxos/danger.png\" target=\"img/danger.png\" />\n\t\t<asset src=\"www/firefoxos/default.png\" target=\"img/default.png\" />\n\t\t<asset src=\"www/firefoxos/gradient.png\" target=\"img/gradient.png\" />\n\t\t<asset src=\"www/firefoxos/pattern.png\" target=\"img/pattern.png\" />\n\t\t<asset src=\"www/firefoxos/recommend.png\" target=\"img/recommend.png\" />\n        <js-module src=\"src/firefoxos/notification.js\" name=\"dialogs-impl\">\n          <runs />\n        </js-module>\n    </platform>\n\n    <!-- android -->\n    <platform name=\"android\">\n        <config-file target=\"res/xml/config.xml\" parent=\"/*\">\n            <feature name=\"Notification\">\n                <param name=\"android-package\" value=\"org.apache.cordova.dialogs.Notification\"/>\n            </feature>\n        </config-file>\n\n        <source-file src=\"src/android/Notification.java\" target-dir=\"src/org/apache/cordova/dialogs\" />\n\n        <!-- android specific notification apis -->\n        <js-module src=\"www/android/notification.js\" name=\"notification_android\">\n            <merges target=\"navigator.notification\" />\n        </js-module>\n\n    </platform>\n\n    <!-- browser -->\n    <platform name=\"browser\">\n        <js-module src=\"www/browser/notification.js\" name=\"notification_browser\">\n            <merges target=\"navigator.notification\" />\n        </js-module>\n\n    </platform>\n    \n     <!-- amazon-fireos -->\n    <platform name=\"amazon-fireos\">\n        <config-file target=\"res/xml/config.xml\" parent=\"/*\">\n            <feature name=\"Notification\">\n                <param name=\"android-package\" value=\"org.apache.cordova.dialogs.Notification\"/>\n            </feature>\n        </config-file>\n\n        <source-file src=\"src/android/Notification.java\" target-dir=\"src/org/apache/cordova/dialogs\" />\n\n        <!-- android specific notification apis -->\n        <js-module src=\"www/android/notification.js\" name=\"notification_android\">\n            <merges target=\"navigator.notification\" />\n        </js-module>\n\n    </platform>\n\n    <!-- ubuntu -->\n    <platform name=\"ubuntu\">\n        <header-file src=\"src/ubuntu/notification.h\" />\n        <source-file src=\"src/ubuntu/notification.cpp\" />\n        <resource-file src=\"src/ubuntu/notification.qml\" />\n    </platform>\n\n    <!-- ios -->\n    <platform name=\"ios\">\n        <config-file target=\"config.xml\" parent=\"/*\">\n            <feature name=\"Notification\">\n                <param name=\"ios-package\" value=\"CDVNotification\"/>\n            </feature>\n        </config-file>\n        <header-file src=\"src/ios/CDVNotification.h\" />\n\t    <source-file src=\"src/ios/CDVNotification.m\" />\n\t    <resource-file src=\"src/ios/CDVNotification.bundle\" />\n\t\t<framework src=\"AudioToolbox.framework\" weak=\"true\" />\n    </platform>\n\n    <!-- blackberry10 -->\n    <platform name=\"blackberry10\">\n        <source-file src=\"src/blackberry10/index.js\" target-dir=\"Notification\" />\n        <config-file target=\"www/config.xml\" parent=\"/widget\">\n            <feature name=\"Notification\" value=\"Notification\"/>\n        </config-file>\n        <js-module src=\"www/blackberry10/beep.js\" name=\"beep\">\n            <clobbers target=\"window.navigator.notification.beep\" />\n        </js-module>\n        <source-file src=\"www/blackberry10/notification-beep.wav\" />\n    </platform>\n\n    <!-- wp7 -->\n    <platform name=\"wp7\">\n        <config-file target=\"config.xml\" parent=\"/*\">\n            <feature name=\"Notification\">\n                <param name=\"wp-package\" value=\"Notification\"/>\n            </feature>\n        </config-file>\n\n        <source-file src=\"src/wp/Notification.cs\" />\n        <source-file src=\"src/wp/NotificationBox.xaml.cs\" />\n        <source-file src=\"src/wp/NotificationBox.xaml\" />\n        <source-file src=\"src/wp/notification-beep.wav\" />\n    </platform>\n\n    <!-- wp8 -->\n    <platform name=\"wp8\">\n        <config-file target=\"config.xml\" parent=\"/*\">\n            <feature name=\"Notification\">\n                <param name=\"wp-package\" value=\"Notification\"/>\n            </feature>\n        </config-file>\n\n        <source-file src=\"src/wp/Notification.cs\" />\n        <source-file src=\"src/wp/NotificationBox.xaml.cs\" />\n        <source-file src=\"src/wp/NotificationBox.xaml\" />\n        <source-file src=\"src/wp/notification-beep.wav\" />\n    </platform>\n\n    <!-- windows8 -->\n    <platform name=\"windows8\">\n        <js-module src=\"src/windows/NotificationProxy.js\" name=\"NotificationProxy\">\n            <merges target=\"\" />\n        </js-module>\n    </platform>\n\n    <!-- windows -->\n    <platform name=\"windows\">\n        <js-module src=\"src/windows/NotificationProxy.js\" name=\"NotificationProxy\">\n            <merges target=\"\" />\n        </js-module>\n    </platform>\n</plugin>\n"
  },
  {
    "path": "plugins/cordova-plugin-dialogs/src/android/Notification.java",
    "content": "/*\n       Licensed to the Apache Software Foundation (ASF) under one\n       or more contributor license agreements.  See the NOTICE file\n       distributed with this work for additional information\n       regarding copyright ownership.  The ASF licenses this file\n       to you under the Apache License, Version 2.0 (the\n       \"License\"); you may not use this file except in compliance\n       with the License.  You may obtain a copy of the License at\n\n         http://www.apache.org/licenses/LICENSE-2.0\n\n       Unless required by applicable law or agreed to in writing,\n       software distributed under the License is distributed on an\n       \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n       KIND, either express or implied.  See the License for the\n       specific language governing permissions and limitations\n       under the License.\n*/\npackage org.apache.cordova.dialogs;\n\nimport org.apache.cordova.CallbackContext;\nimport org.apache.cordova.CordovaInterface;\nimport org.apache.cordova.CordovaPlugin;\nimport org.apache.cordova.LOG;\nimport org.apache.cordova.PluginResult;\nimport org.json.JSONArray;\nimport org.json.JSONException;\nimport org.json.JSONObject;\n\nimport android.annotation.SuppressLint;\nimport android.app.AlertDialog;\nimport android.app.AlertDialog.Builder;\nimport android.app.ProgressDialog;\nimport android.content.DialogInterface;\nimport android.media.Ringtone;\nimport android.media.RingtoneManager;\nimport android.net.Uri;\nimport android.widget.EditText;\nimport android.widget.TextView;\n\n\n/**\n * This class provides access to notifications on the device.\n *\n * Be aware that this implementation gets called on \n * navigator.notification.{alert|confirm|prompt}, and that there is a separate\n * implementation in org.apache.cordova.CordovaChromeClient that gets\n * called on a simple window.{alert|confirm|prompt}.\n */\npublic class Notification extends CordovaPlugin {\n\n    private static final String LOG_TAG = \"Notification\";\n    \n    public int confirmResult = -1;\n    public ProgressDialog spinnerDialog = null;\n    public ProgressDialog progressDialog = null;\n\n    /**\n     * Constructor.\n     */\n    public Notification() {\n    }\n\n    /**\n     * Executes the request and returns PluginResult.\n     *\n     * @param action            The action to execute.\n     * @param args              JSONArray of arguments for the plugin.\n     * @param callbackContext   The callback context used when calling back into JavaScript.\n     * @return                  True when the action was valid, false otherwise.\n     */\n    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {\n    \t/*\n    \t * Don't run any of these if the current activity is finishing\n    \t * in order to avoid android.view.WindowManager$BadTokenException\n    \t * crashing the app. Just return true here since false should only\n    \t * be returned in the event of an invalid action.\n    \t */\n    \tif(this.cordova.getActivity().isFinishing()) return true;\n    \t\n        if (action.equals(\"beep\")) {\n            this.beep(args.getLong(0));\n        }\n        else if (action.equals(\"alert\")) {\n            this.alert(args.getString(0), args.getString(1), args.getString(2), callbackContext);\n            return true;\n        }\n        else if (action.equals(\"confirm\")) {\n            this.confirm(args.getString(0), args.getString(1), args.getJSONArray(2), callbackContext);\n            return true;\n        }\n        else if (action.equals(\"prompt\")) {\n            this.prompt(args.getString(0), args.getString(1), args.getJSONArray(2), args.getString(3), callbackContext);\n            return true;\n        }\n        else if (action.equals(\"activityStart\")) {\n            this.activityStart(args.getString(0), args.getString(1));\n        }\n        else if (action.equals(\"activityStop\")) {\n            this.activityStop();\n        }\n        else if (action.equals(\"progressStart\")) {\n            this.progressStart(args.getString(0), args.getString(1));\n        }\n        else if (action.equals(\"progressValue\")) {\n            this.progressValue(args.getInt(0));\n        }\n        else if (action.equals(\"progressStop\")) {\n            this.progressStop();\n        }\n        else {\n            return false;\n        }\n\n        // Only alert and confirm are async.\n        callbackContext.success();\n        return true;\n    }\n\n    //--------------------------------------------------------------------------\n    // LOCAL METHODS\n    //--------------------------------------------------------------------------\n\n    /**\n     * Beep plays the default notification ringtone.\n     *\n     * @param count     Number of times to play notification\n     */\n    public void beep(final long count) {\n        cordova.getThreadPool().execute(new Runnable() {\n            public void run() {\n                Uri ringtone = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);\n                Ringtone notification = RingtoneManager.getRingtone(cordova.getActivity().getBaseContext(), ringtone);\n\n                // If phone is not set to silent mode\n                if (notification != null) {\n                    for (long i = 0; i < count; ++i) {\n                        notification.play();\n                        long timeout = 5000;\n                        while (notification.isPlaying() && (timeout > 0)) {\n                            timeout = timeout - 100;\n                            try {\n                                Thread.sleep(100);\n                            } catch (InterruptedException e) {\n                                Thread.currentThread().interrupt();\n                            }\n                        }\n                    }\n                }\n            }\n        });\n    }\n\n    /**\n     * Builds and shows a native Android alert with given Strings\n     * @param message           The message the alert should display\n     * @param title             The title of the alert\n     * @param buttonLabel       The label of the button\n     * @param callbackContext   The callback context\n     */\n    public synchronized void alert(final String message, final String title, final String buttonLabel, final CallbackContext callbackContext) {\n    \tfinal CordovaInterface cordova = this.cordova;\n\n        Runnable runnable = new Runnable() {\n            public void run() {\n\n                AlertDialog.Builder dlg = createDialog(cordova); // new AlertDialog.Builder(cordova.getActivity(), AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);\n                dlg.setMessage(message);\n                dlg.setTitle(title);\n                dlg.setCancelable(true);\n                dlg.setPositiveButton(buttonLabel,\n                        new AlertDialog.OnClickListener() {\n                            public void onClick(DialogInterface dialog, int which) {\n                                dialog.dismiss();\n                                callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, 0));\n                            }\n                        });\n                dlg.setOnCancelListener(new AlertDialog.OnCancelListener() {\n                    public void onCancel(DialogInterface dialog)\n                    {\n                        dialog.dismiss();\n                        callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, 0));\n                    }\n                });\n\n                changeTextDirection(dlg);\n            };\n        };\n        this.cordova.getActivity().runOnUiThread(runnable);\n    }\n\n    /**\n     * Builds and shows a native Android confirm dialog with given title, message, buttons.\n     * This dialog only shows up to 3 buttons.  Any labels after that will be ignored.\n     * The index of the button pressed will be returned to the JavaScript callback identified by callbackId.\n     *\n     * @param message           The message the dialog should display\n     * @param title             The title of the dialog\n     * @param buttonLabels      A comma separated list of button labels (Up to 3 buttons)\n     * @param callbackContext   The callback context.\n     */\n    public synchronized void confirm(final String message, final String title, final JSONArray buttonLabels, final CallbackContext callbackContext) {\n    \tfinal CordovaInterface cordova = this.cordova;\n\n        Runnable runnable = new Runnable() {\n            public void run() {\n                AlertDialog.Builder dlg = createDialog(cordova); // new AlertDialog.Builder(cordova.getActivity(), AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);\n                dlg.setMessage(message);\n                dlg.setTitle(title);\n                dlg.setCancelable(true);\n\n                // First button\n                if (buttonLabels.length() > 0) {\n                    try {\n                        dlg.setNegativeButton(buttonLabels.getString(0),\n                            new AlertDialog.OnClickListener() {\n                                public void onClick(DialogInterface dialog, int which) {\n                                    dialog.dismiss();\n                                    callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, 1));\n                                }\n                            });\n                    } catch (JSONException e) {\n                        LOG.d(LOG_TAG,\"JSONException on first button.\");\n                    }\n                }\n\n                // Second button\n                if (buttonLabels.length() > 1) {\n                    try {\n                        dlg.setNeutralButton(buttonLabels.getString(1),\n                            new AlertDialog.OnClickListener() {\n                                public void onClick(DialogInterface dialog, int which) {\n                                    dialog.dismiss();\n                                    callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, 2));\n                                }\n                            });\n                    } catch (JSONException e) {\n                        LOG.d(LOG_TAG,\"JSONException on second button.\");\n                    }\n                }\n\n                // Third button\n                if (buttonLabels.length() > 2) {\n                    try {\n                        dlg.setPositiveButton(buttonLabels.getString(2),\n                            new AlertDialog.OnClickListener() {\n                                public void onClick(DialogInterface dialog, int which) {\n                                  dialog.dismiss();\n                                  callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, 3));\n                                }\n                            });\n                    } catch (JSONException e) {\n                        LOG.d(LOG_TAG,\"JSONException on third button.\");\n                    }\n                }\n                dlg.setOnCancelListener(new AlertDialog.OnCancelListener() {\n                    public void onCancel(DialogInterface dialog)\n                    {\n                        dialog.dismiss();\n                        callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, 0));\n                    }\n                });\n\n                changeTextDirection(dlg);\n            };\n        };\n        this.cordova.getActivity().runOnUiThread(runnable);\n    }\n\n    /**\n     * Builds and shows a native Android prompt dialog with given title, message, buttons.\n     * This dialog only shows up to 3 buttons.  Any labels after that will be ignored.\n     * The following results are returned to the JavaScript callback identified by callbackId:\n     *     buttonIndex\t\t\tIndex number of the button selected\n     *     input1\t\t\t\tThe text entered in the prompt dialog box\n     *\n     * @param message           The message the dialog should display\n     * @param title             The title of the dialog\n     * @param buttonLabels      A comma separated list of button labels (Up to 3 buttons)\n     * @param callbackContext   The callback context.\n     */\n    public synchronized void prompt(final String message, final String title, final JSONArray buttonLabels, final String defaultText, final CallbackContext callbackContext) {\n  \t\n        final CordovaInterface cordova = this.cordova;\n       \n        Runnable runnable = new Runnable() {\n            public void run() {\n                final EditText promptInput =  new EditText(cordova.getActivity());\n                promptInput.setHint(defaultText);\n                AlertDialog.Builder dlg = createDialog(cordova); // new AlertDialog.Builder(cordova.getActivity(), AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);\n                dlg.setMessage(message);\n                dlg.setTitle(title);\n                dlg.setCancelable(true);\n                \n                dlg.setView(promptInput);\n                \n                final JSONObject result = new JSONObject();\n                \n                // First button\n                if (buttonLabels.length() > 0) {\n                    try {\n                        dlg.setNegativeButton(buttonLabels.getString(0),\n                            new AlertDialog.OnClickListener() {\n                                public void onClick(DialogInterface dialog, int which) {\n                                    dialog.dismiss();\n                                    try {\n                                        result.put(\"buttonIndex\",1);\n                                        result.put(\"input1\", promptInput.getText().toString().trim().length()==0 ? defaultText : promptInput.getText());\t\t\t\t\t\t\t\t\t\t\t\n                                    } catch (JSONException e) {\n                                        LOG.d(LOG_TAG,\"JSONException on first button.\", e);\n                                    }\n                                    callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, result));\n                                }\n                            });\n                    } catch (JSONException e) {\n                        LOG.d(LOG_TAG,\"JSONException on first button.\");\n                    }\n                }\n\n                // Second button\n                if (buttonLabels.length() > 1) {\n                    try {\n                        dlg.setNeutralButton(buttonLabels.getString(1),\n                            new AlertDialog.OnClickListener() {\n                                public void onClick(DialogInterface dialog, int which) {\n                                    dialog.dismiss();\n                                    try {\n                                        result.put(\"buttonIndex\",2);\n                                        result.put(\"input1\", promptInput.getText().toString().trim().length()==0 ? defaultText : promptInput.getText());\n                                    } catch (JSONException e) {\n                                        LOG.d(LOG_TAG,\"JSONException on second button.\", e);\n                                    }\n                                    callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, result));\n                                }\n                            });\n                    } catch (JSONException e) {\n                        LOG.d(LOG_TAG,\"JSONException on second button.\");\n                    }\n                }\n\n                // Third button\n                if (buttonLabels.length() > 2) {\n                    try {\n                        dlg.setPositiveButton(buttonLabels.getString(2),\n                            new AlertDialog.OnClickListener() {\n                                public void onClick(DialogInterface dialog, int which) {\n                                    dialog.dismiss();\n                                    try {\n                                        result.put(\"buttonIndex\",3);\n                                        result.put(\"input1\", promptInput.getText().toString().trim().length()==0 ? defaultText : promptInput.getText());\n                                    } catch (JSONException e) { \n                                        LOG.d(LOG_TAG,\"JSONException on third button.\", e);\n                                    }\n                                    callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, result));\n                                }\n                            });\n                    } catch (JSONException e) {\n                        LOG.d(LOG_TAG,\"JSONException on third button.\");\n                    }\n                }\n                dlg.setOnCancelListener(new AlertDialog.OnCancelListener() {\n                    public void onCancel(DialogInterface dialog){\n                        dialog.dismiss();\n                        try {\n                            result.put(\"buttonIndex\",0);\n                            result.put(\"input1\", promptInput.getText().toString().trim().length()==0 ? defaultText : promptInput.getText());\n                        } catch (JSONException e) { e.printStackTrace(); }\n                        callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, result));\n                    }\n                });\n\n                changeTextDirection(dlg);\n            };\n        };\n        this.cordova.getActivity().runOnUiThread(runnable);\n    }\n\n    /**\n     * Show the spinner.\n     *\n     * @param title     Title of the dialog\n     * @param message   The message of the dialog\n     */\n    public synchronized void activityStart(final String title, final String message) {\n        if (this.spinnerDialog != null) {\n            this.spinnerDialog.dismiss();\n            this.spinnerDialog = null;\n        }\n        final Notification notification = this;\n        final CordovaInterface cordova = this.cordova;\n        Runnable runnable = new Runnable() {\n            public void run() {\n                notification.spinnerDialog = createProgressDialog(cordova); // new ProgressDialog(cordova.getActivity(), AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);\n                notification.spinnerDialog.setTitle(title);\n                notification.spinnerDialog.setMessage(message);\n                notification.spinnerDialog.setCancelable(true);\n                notification.spinnerDialog.setIndeterminate(true);\n                notification.spinnerDialog.setOnCancelListener(\n                        new DialogInterface.OnCancelListener() {\n                            public void onCancel(DialogInterface dialog) {\n                                notification.spinnerDialog = null;\n                            }\n                        });\n                notification.spinnerDialog.show();\n            }\n        };\n        this.cordova.getActivity().runOnUiThread(runnable);\n    }\n\n    /**\n     * Stop spinner.\n     */\n    public synchronized void activityStop() {\n        if (this.spinnerDialog != null) {\n            this.spinnerDialog.dismiss();\n            this.spinnerDialog = null;\n        }\n    }\n\n    /**\n     * Show the progress dialog.\n     *\n     * @param title     Title of the dialog\n     * @param message   The message of the dialog\n     */\n    public synchronized void progressStart(final String title, final String message) {\n        if (this.progressDialog != null) {\n            this.progressDialog.dismiss();\n            this.progressDialog = null;\n        }\n        final Notification notification = this;\n        final CordovaInterface cordova = this.cordova;\n        Runnable runnable = new Runnable() {\n            public void run() {\n                notification.progressDialog = createProgressDialog(cordova); // new ProgressDialog(cordova.getActivity(), AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);\n                notification.progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);\n                notification.progressDialog.setTitle(title);\n                notification.progressDialog.setMessage(message);\n                notification.progressDialog.setCancelable(true);\n                notification.progressDialog.setMax(100);\n                notification.progressDialog.setProgress(0);\n                notification.progressDialog.setOnCancelListener(\n                        new DialogInterface.OnCancelListener() {\n                            public void onCancel(DialogInterface dialog) {\n                                notification.progressDialog = null;\n                            }\n                        });\n                notification.progressDialog.show();\n            }\n        };\n        this.cordova.getActivity().runOnUiThread(runnable);\n    }\n\n    /**\n     * Set value of progress bar.\n     *\n     * @param value     0-100\n     */\n    public synchronized void progressValue(int value) {\n        if (this.progressDialog != null) {\n            this.progressDialog.setProgress(value);\n        }\n    }\n\n    /**\n     * Stop progress dialog.\n     */\n    public synchronized void progressStop() {\n        if (this.progressDialog != null) {\n            this.progressDialog.dismiss();\n            this.progressDialog = null;\n        }\n    }\n    \n    @SuppressLint(\"NewApi\")\n    private AlertDialog.Builder createDialog(CordovaInterface cordova) {\n        int currentapiVersion = android.os.Build.VERSION.SDK_INT;\n        if (currentapiVersion >= android.os.Build.VERSION_CODES.HONEYCOMB) {\n            return new AlertDialog.Builder(cordova.getActivity(), AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);\n        } else {\n            return new AlertDialog.Builder(cordova.getActivity());\n        }\n    }\n\n    @SuppressLint(\"InlinedApi\")\n    private ProgressDialog createProgressDialog(CordovaInterface cordova) {\n        int currentapiVersion = android.os.Build.VERSION.SDK_INT;\n        if (currentapiVersion >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {\n            return new ProgressDialog(cordova.getActivity(), AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);\n        } else {\n            return new ProgressDialog(cordova.getActivity());\n        }\n    }\n    \n    @SuppressLint(\"NewApi\")\n    private void changeTextDirection(Builder dlg){\n        int currentapiVersion = android.os.Build.VERSION.SDK_INT;\n        dlg.create();\n        AlertDialog dialog =  dlg.show();\n        if (currentapiVersion >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {\n            TextView messageview = (TextView)dialog.findViewById(android.R.id.message);\n            messageview.setTextDirection(android.view.View.TEXT_DIRECTION_LOCALE);\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-dialogs/src/blackberry10/index.js",
    "content": "/*\n* Copyright 2013 Research In Motion Limited.\n*\n* Licensed under the Apache License, Version 2.0 (the \"License\");\n* you may not use this file except in compliance with the License.\n* You may obtain a copy of the License at\n*\n* http://www.apache.org/licenses/LICENSE-2.0\n*\n* Unless required by applicable law or agreed to in writing, software\n* distributed under the License is distributed on an \"AS IS\" BASIS,\n* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n* See the License for the specific language governing permissions and\n* limitations under the License.\n*/\n\n/* global qnx, PluginResult */\n\nfunction showDialog(args, dialogType, result) {\n    //Unpack and map the args\n    var msg = JSON.parse(decodeURIComponent(args[0])),\n    title = JSON.parse(decodeURIComponent(args[1])),\n    btnLabel = JSON.parse(decodeURIComponent(args[2]));\n\n    if (!Array.isArray(btnLabel)) {\n        //Converts to array for (string) and (string,string, ...) cases\n        btnLabel = btnLabel.split(\",\");\n    }\n\n    if (msg && typeof msg === \"string\") {\n        msg = msg.replace(/^\"|\"$/g, \"\").replace(/\\\\\"/g, '\"');\n    } else {\n        result.error(\"message is undefined\");\n        return;\n    }\n\n    var messageObj = {\n        title : title,\n        htmlmessage :  msg,\n        dialogType : dialogType,\n        optionalButtons : btnLabel\n    };\n\n    //TODO replace with getOverlayWebview() when available in webplatform\n    qnx.webplatform.getWebViews()[2].dialog.show(messageObj, function (data) {\n        if (typeof data === \"number\") {\n            //Confirm dialog call back needs to be called with one-based indexing [1,2,3 etc]\n            result.callbackOk(++data, false);\n        } else {\n            //Prompt dialog callback expects object\n            result.callbackOk({\n                buttonIndex: data.ok ? 1 : 0,\n                input1: (data.oktext) ? decodeURIComponent(data.oktext) : \"\"\n            }, false);\n        }\n    });\n\n    result.noResult(true);\n}\n\nmodule.exports = {\n    alert: function (success, fail, args, env) {\n        var result = new PluginResult(args, env);\n\n        if (Object.keys(args).length < 3) {\n            result.error(\"Notification action - alert arguments not found.\");\n        } else {\n            showDialog(args, \"CustomAsk\", result);\n        }\n    },\n    confirm: function (success, fail, args, env) {\n        var result = new PluginResult(args, env);\n\n        if (Object.keys(args).length < 3) {\n            result.error(\"Notification action - confirm arguments not found.\");\n        } else {\n            showDialog(args, \"CustomAsk\", result);\n        }\n    },\n    prompt: function (success, fail, args, env) {\n        var result = new PluginResult(args, env);\n\n        if (Object.keys(args).length < 3) {\n            result.error(\"Notification action - prompt arguments not found.\");\n        } else {\n            showDialog(args, \"JavaScriptPrompt\", result);\n        }\n    }\n};\n"
  },
  {
    "path": "plugins/cordova-plugin-dialogs/src/firefoxos/notification.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\nvar modulemapper = require('cordova/modulemapper');\n\n\nvar origOpenFunc = modulemapper.getOriginalSymbol(window, 'window.open');\n\n\nfunction _empty() {}\n\n\nfunction modal(message, callback, title, buttonLabels, domObjects) {\n    var mainWindow = window;\n    var modalWindow = origOpenFunc();\n    var modalDocument = modalWindow.document;\n\n    modalDocument.write(\n        '<html><head>' +\n        '<link rel=\"stylesheet\" type=\"text/css\" href=\"/css/index.css\" />' +\n        '<link rel=\"stylesheet\" type=\"text/css\" href=\"/css/notification.css\" />' +\n        '</head><body></body></html>');\n\n    var box = modalDocument.createElement('form');\n    box.setAttribute('role', 'dialog');\n    // prepare and append empty section\n    var section = modalDocument.createElement('section');\n    box.appendChild(section);\n    // add title\n    var boxtitle = modalDocument.createElement('h1');\n    boxtitle.appendChild(modalDocument.createTextNode(title));\n    section.appendChild(boxtitle);\n    // add message\n    var boxMessage = modalDocument.createElement('p');\n    boxMessage.appendChild(modalDocument.createTextNode(message));\n    section.appendChild(boxMessage);\n    // inject what's needed\n    if (domObjects) {\n        section.appendChild(domObjects);\n    }\n    // add buttons and assign callbackButton on click\n    var menu = modalDocument.createElement('menu');\n    box.appendChild(menu);\n    for (var index = 0; index < buttonLabels.length; index++) {\n        // TODO: last button listens to the cancel key\n        addButton(buttonLabels[index], (index+1), (index === 0));\n    }\n    modalDocument.body.appendChild(box);\n\n    function addButton(label, index, recommended) {\n        var thisButtonCallback = makeCallbackButton(index + 1);\n        var button = modalDocument.createElement('button');\n        button.appendChild(modalDocument.createTextNode(label));\n        button.addEventListener('click', thisButtonCallback, false);\n        if (recommended) {\n          // TODO: default one listens to Enter key\n          button.classList.add('recommend');\n        }\n        menu.appendChild(button);\n    }\n\n    // TODO: onUnload listens to the cancel key\n    function onUnload() {\n        var result = 0;\n        if (modalDocument.getElementById('prompt-input')) {\n            result = {\n                input1: '',\n                buttonIndex: 0\n            };\n        }\n        mainWindow.setTimeout(function() {\n            callback(result);\n        }, 10);\n    }\n    modalWindow.addEventListener('unload', onUnload, false);\n\n    // call callback and destroy modal\n    function makeCallbackButton(labelIndex) {\n        return function() {\n          if (modalWindow) {\n              modalWindow.removeEventListener('unload', onUnload, false);\n              modalWindow.close();\n          }\n          // checking if prompt\n          var promptInput = modalDocument.getElementById('prompt-input');\n          var response;\n          if (promptInput) {\n              response = {\n                input1: promptInput.value,\n                buttonIndex: labelIndex\n              };\n          }\n          response = response || labelIndex;\n          callback(response);\n        };\n    }\n}\n\nvar Notification = {\n    vibrate: function(milliseconds) {\n        navigator.vibrate(milliseconds);\n    },\n    alert: function(successCallback, errorCallback, args) {\n        var message = args[0];\n        var title = args[1];\n        var _buttonLabels = [args[2]];\n        var _callback = (successCallback || _empty);\n        modal(message, _callback, title, _buttonLabels);\n    },\n    confirm: function(successCallback, errorCallback, args) {\n        var message = args[0];\n        var title = args[1];\n        var buttonLabels = args[2];\n        var _callback = (successCallback || _empty);\n        modal(message, _callback, title, buttonLabels);\n    },\n    prompt: function(successCallback, errorCallback, args) {\n        var message = args[0];\n        var title = args[1];\n        var buttonLabels = args[2];\n        var defaultText = args[3];\n        var inputParagraph = document.createElement('p');\n        inputParagraph.classList.add('input');\n        var inputElement = document.createElement('input');\n        inputElement.setAttribute('type', 'text');\n        inputElement.id = 'prompt-input';\n        if (defaultText) {\n            inputElement.setAttribute('placeholder', defaultText);\n        }\n        inputParagraph.appendChild(inputElement);\n        modal(message, successCallback, title, buttonLabels, inputParagraph);\n    }\n};\n\n\nmodule.exports = Notification;\nrequire('cordova/exec/proxy').add('Notification', Notification);\n"
  },
  {
    "path": "plugins/cordova-plugin-dialogs/src/ios/CDVNotification.h",
    "content": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements.  See the NOTICE file\n distributed with this work for additional information\n regarding copyright ownership.  The ASF licenses this file\n to you under the Apache License, Version 2.0 (the\n \"License\"); you may not use this file except in compliance\n with the License.  You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an\n \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n KIND, either express or implied.  See the License for the\n specific language governing permissions and limitations\n under the License.\n */\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n#import <AudioToolbox/AudioServices.h>\n#import <Cordova/CDVPlugin.h>\n\n@interface CDVNotification : CDVPlugin <UIAlertViewDelegate>{}\n\n- (void)alert:(CDVInvokedUrlCommand*)command;\n- (void)confirm:(CDVInvokedUrlCommand*)command;\n- (void)prompt:(CDVInvokedUrlCommand*)command;\n- (void)beep:(CDVInvokedUrlCommand*)command;\n\n@end\n\n@interface CDVAlertView : UIAlertView {}\n@property (nonatomic, copy) NSString* callbackId;\n\n@end\n"
  },
  {
    "path": "plugins/cordova-plugin-dialogs/src/ios/CDVNotification.m",
    "content": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements.  See the NOTICE file\n distributed with this work for additional information\n regarding copyright ownership.  The ASF licenses this file\n to you under the Apache License, Version 2.0 (the\n \"License\"); you may not use this file except in compliance\n with the License.  You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an\n \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n KIND, either express or implied.  See the License for the\n specific language governing permissions and limitations\n under the License.\n */\n\n#import \"CDVNotification.h\"\n\n#define DIALOG_TYPE_ALERT @\"alert\"\n#define DIALOG_TYPE_PROMPT @\"prompt\"\n\nstatic void soundCompletionCallback(SystemSoundID ssid, void* data);\nstatic NSMutableArray *alertList = nil;\n\n@implementation CDVNotification\n\n/*\n * showDialogWithMessage - Common method to instantiate the alert view for alert, confirm, and prompt notifications.\n * Parameters:\n *  message       The alert view message.\n *  title         The alert view title.\n *  buttons       The array of customized strings for the buttons.\n *  defaultText   The input text for the textbox (if textbox exists).\n *  callbackId    The commmand callback id.\n *  dialogType    The type of alert view [alert | prompt].\n */\n- (void)showDialogWithMessage:(NSString*)message title:(NSString*)title buttons:(NSArray*)buttons defaultText:(NSString*)defaultText callbackId:(NSString*)callbackId dialogType:(NSString*)dialogType\n{\n    \n    int count = (int)[buttons count];\n#ifdef __IPHONE_8_0\n    if (NSClassFromString(@\"UIAlertController\")) {\n        \n        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];\n        \n        if ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.3) {\n            \n            CGRect alertFrame = [UIScreen mainScreen].applicationFrame;\n            \n            if (UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) {\n                // swap the values for the app frame since it is now in landscape\n                CGFloat temp = alertFrame.size.width;\n                alertFrame.size.width = alertFrame.size.height;\n                alertFrame.size.height = temp;\n            }\n            \n            alertController.view.frame =  alertFrame;\n        }\n\n        __weak CDVNotification* weakNotif = self;\n\n        for (int n = 0; n < count; n++) {\n            [alertController addAction:[UIAlertAction actionWithTitle:[buttons objectAtIndex:n]\n                                                                style:UIAlertActionStyleDefault\n                                                              handler:^(UIAlertAction * action)\n            {\n                CDVPluginResult* result;\n\n                if ([dialogType isEqualToString:DIALOG_TYPE_PROMPT])\n                {\n                    NSString* value0 = [[alertController.textFields objectAtIndex:0] text];\n                    NSDictionary* info = @{\n                        @\"buttonIndex\":@(n + 1),\n                        @\"input1\":(value0 ? value0 : [NSNull null])\n                    };\n                    result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:info];\n                }\n                else\n                {\n                    result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:(int)(n  + 1)];\n                }\n\n                [weakNotif.commandDelegate sendPluginResult:result callbackId:callbackId];\n            }]];\n        }\n        \n        if ([dialogType isEqualToString:DIALOG_TYPE_PROMPT]) {\n            \n            [alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) {\n                textField.text = defaultText;\n            }];\n        }\n        \n        if(!alertList)\n            alertList = [[NSMutableArray alloc] init];\n        [alertList addObject:alertController];\n        \n        if ([alertList count]==1) {\n            [self presentAlertcontroller];\n        }\n        \n    }\n    else\n    {\n#endif\n\n        CDVAlertView* alertView = [[CDVAlertView alloc]\n                                   initWithTitle:title\n                                   message:message\n                                   delegate:self\n                                   cancelButtonTitle:nil\n                                   otherButtonTitles:nil];\n        \n        alertView.callbackId = callbackId;\n        \n        \n        \n        for (int n = 0; n < count; n++) {\n            [alertView addButtonWithTitle:[buttons objectAtIndex:n]];\n        }\n        \n        if ([dialogType isEqualToString:DIALOG_TYPE_PROMPT]) {\n            alertView.alertViewStyle = UIAlertViewStylePlainTextInput;\n            UITextField* textField = [alertView textFieldAtIndex:0];\n            textField.text = defaultText;\n        }\n        \n        [alertView show];\n#ifdef __IPHONE_8_0\n    }\n#endif\n    \n}\n\n- (void)alert:(CDVInvokedUrlCommand*)command\n{\n    NSString* callbackId = command.callbackId;\n    NSString* message = [command argumentAtIndex:0];\n    NSString* title = [command argumentAtIndex:1];\n    NSString* buttons = [command argumentAtIndex:2];\n\n    [self showDialogWithMessage:message title:title buttons:@[buttons] defaultText:nil callbackId:callbackId dialogType:DIALOG_TYPE_ALERT];\n}\n\n- (void)confirm:(CDVInvokedUrlCommand*)command\n{\n    NSString* callbackId = command.callbackId;\n    NSString* message = [command argumentAtIndex:0];\n    NSString* title = [command argumentAtIndex:1];\n    NSArray* buttons = [command argumentAtIndex:2];\n\n    [self showDialogWithMessage:message title:title buttons:buttons defaultText:nil callbackId:callbackId dialogType:DIALOG_TYPE_ALERT];\n}\n\n- (void)prompt:(CDVInvokedUrlCommand*)command\n{\n    NSString* callbackId = command.callbackId;\n    NSString* message = [command argumentAtIndex:0];\n    NSString* title = [command argumentAtIndex:1];\n    NSArray* buttons = [command argumentAtIndex:2];\n    NSString* defaultText = [command argumentAtIndex:3];\n\n    [self showDialogWithMessage:message title:title buttons:buttons defaultText:defaultText callbackId:callbackId dialogType:DIALOG_TYPE_PROMPT];\n}\n\n/**\n  * Callback invoked when an alert dialog's buttons are clicked.\n  */\n- (void)alertView:(UIAlertView*)alertView clickedButtonAtIndex:(NSInteger)buttonIndex\n{\n    CDVAlertView* cdvAlertView = (CDVAlertView*)alertView;\n    CDVPluginResult* result;\n\n    // Determine what gets returned to JS based on the alert view type.\n    if (alertView.alertViewStyle == UIAlertViewStyleDefault) {\n        // For alert and confirm, return button index as int back to JS.\n        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:(int)(buttonIndex + 1)];\n    } else {\n        // For prompt, return button index and input text back to JS.\n        NSString* value0 = [[alertView textFieldAtIndex:0] text];\n        NSDictionary* info = @{\n            @\"buttonIndex\":@(buttonIndex + 1),\n            @\"input1\":(value0 ? value0 : [NSNull null])\n        };\n        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:info];\n    }\n    [self.commandDelegate sendPluginResult:result callbackId:cdvAlertView.callbackId];\n}\n\nstatic void playBeep(int count) {\n    SystemSoundID completeSound;\n    NSInteger cbDataCount = count;\n    NSURL* audioPath = [[NSBundle mainBundle] URLForResource:@\"CDVNotification.bundle/beep\" withExtension:@\"wav\"];\n    #if __has_feature(objc_arc)\n        AudioServicesCreateSystemSoundID((__bridge CFURLRef)audioPath, &completeSound);\n    #else\n        AudioServicesCreateSystemSoundID((CFURLRef)audioPath, &completeSound);\n    #endif\n    AudioServicesAddSystemSoundCompletion(completeSound, NULL, NULL, soundCompletionCallback, (void*)(cbDataCount-1));\n    AudioServicesPlaySystemSound(completeSound);\n}\n\nstatic void soundCompletionCallback(SystemSoundID  ssid, void* data) {\n    int count = (int)data;\n    AudioServicesRemoveSystemSoundCompletion (ssid);\n    AudioServicesDisposeSystemSoundID(ssid);\n    if (count > 0) {\n        playBeep(count);\n    }\n}\n\n- (void)beep:(CDVInvokedUrlCommand*)command\n{\n    NSNumber* count = [command argumentAtIndex:0 withDefault:[NSNumber numberWithInt:1]];\n    playBeep([count intValue]);\n}\n\n-(UIViewController *)getTopPresentedViewController {\n    UIViewController *presentingViewController = self.viewController;\n    while(presentingViewController.presentedViewController != nil && ![presentingViewController.presentedViewController isBeingDismissed])\n    {\n        presentingViewController = presentingViewController.presentedViewController;\n    }\n    return presentingViewController;\n}\n\n-(void)presentAlertcontroller {\n    \n    __weak CDVNotification* weakNotif = self;\n    [self.getTopPresentedViewController presentViewController:[alertList firstObject] animated:YES completion:^{\n        [alertList removeObject:[alertList firstObject]];\n        if ([alertList count]>0) {\n            [weakNotif presentAlertcontroller];\n        }\n    }];\n    \n}\n\n@end\n\n@implementation CDVAlertView\n\n@synthesize callbackId;\n\n@end\n"
  },
  {
    "path": "plugins/cordova-plugin-dialogs/src/ubuntu/notification.cpp",
    "content": "/*\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n */\n\n#include \"notification.h\"\n\n#include <QApplication>\n\nvoid Dialogs::beep(int scId, int ecId, int times) {\n    Q_UNUSED(scId)\n    Q_UNUSED(ecId)\n    Q_UNUSED(times)\n\n    _player.setVolume(100);\n    _player.setMedia(QUrl::fromLocalFile(\"/usr/share/sounds/ubuntu/stereo/bell.ogg\"));\n    _player.play();\n}\n\nvoid Dialogs::alert(int scId, int ecId, const QString &message, const QString &title, const QString &buttonLabel) {\n    QStringList list;\n    list.append(buttonLabel);\n\n    confirm(scId, ecId, message, title, list);\n}\n\nvoid Dialogs::confirm(int scId, int ecId, const QString &message, const QString &title, const QStringList &buttonLabels) {\n    Q_UNUSED(ecId);\n\n    if (_alertCallback) {\n        qCritical() << \"can't open second dialog\";\n        return;\n    }\n    _alertCallback = scId;\n\n    QString s1, s2, s3;\n    if (buttonLabels.size() > 0)\n        s1 = buttonLabels[0];\n    if (buttonLabels.size() > 1)\n        s2 = buttonLabels[1];\n    if (buttonLabels.size() > 2)\n        s3 = buttonLabels[2];\n\n    QString path = m_cordova->get_app_dir() + \"/../qml/notification.qml\";\n    QString qml = QString(\"PopupUtils.open(%1, root, { root: root, cordova: cordova, title: %2, text: %3, promptVisible: false, button1Text: %4, button2Text: %5, button3Text: %6 })\")\n        .arg(CordovaInternal::format(path)).arg(CordovaInternal::format(title)).arg(CordovaInternal::format(message))\n        .arg(CordovaInternal::format(s1)).arg(CordovaInternal::format(s2)).arg(CordovaInternal::format(s3));\n\n    m_cordova->execQML(qml);\n}\n\nvoid Dialogs::prompt(int scId, int ecId, const QString &message, const QString &title, const QStringList &buttonLabels, const QString &defaultText) {\n    Q_UNUSED(ecId);\n\n    if (_alertCallback) {\n        qCritical() << \"can't open second dialog\";\n        return;\n    }\n    _alertCallback = scId;\n\n    QString s1, s2, s3;\n    if (buttonLabels.size() > 0)\n        s1 = buttonLabels[0];\n    if (buttonLabels.size() > 1)\n        s2 = buttonLabels[1];\n    if (buttonLabels.size() > 2)\n        s3 = buttonLabels[2];\n    QString path = m_cordova->get_app_dir() + \"/../qml/notification.qml\";\n    QString qml = QString(\"PopupUtils.open(%1, root, { root: root, cordova: cordova, title: %2, text: %3, promptVisible: true, defaultPromptText: %7, button1Text: %4, button2Text: %5, button3Text: %6 })\")\n        .arg(CordovaInternal::format(path)).arg(CordovaInternal::format(title)).arg(CordovaInternal::format(message))\n        .arg(CordovaInternal::format(s1)).arg(CordovaInternal::format(s2))\n        .arg(CordovaInternal::format(s3)).arg(CordovaInternal::format(defaultText));\n\n    m_cordova->execQML(qml);\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-dialogs/src/ubuntu/notification.h",
    "content": "/*\n *\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n */\n\n#ifndef NOTIFICATION_H\n#define NOTIFICATION_H\n\n#include <QtQuick>\n#include <QMediaPlayer>\n#include <cplugin.h>\n#include <cordova.h>\n\nclass Dialogs: public CPlugin {\n    Q_OBJECT\npublic:\n    explicit Dialogs(Cordova *cordova): CPlugin(cordova), _alertCallback(0) {\n    }\n\n    virtual const QString fullName() override {\n        return Dialogs::fullID();\n    }\n\n    virtual const QString shortName() override {\n        return \"Notification\";\n    }\n\n    static const QString fullID() {\n        return \"Notification\";\n    }\npublic slots:\n    void beep(int scId, int ecId, int times);\n    void alert(int scId, int ecId, const QString &message, const QString &title, const QString &buttonLabel);\n    void confirm(int scId, int ecId, const QString &message, const QString &title, const QStringList &buttonLabels);\n    void prompt(int scId, int ecId, const QString &message, const QString &title, const QStringList &buttonLabels, const QString &defaultText);\n\n    void notificationDialogButtonPressed(int buttonId, const QString &text, bool prompt) {\n        if (prompt) {\n            QVariantMap res;\n            res.insert(\"buttonIndex\", buttonId);\n            res.insert(\"input1\", text);\n            this->cb(_alertCallback, res);\n        } else {\n            this->cb(_alertCallback, buttonId);\n        }\n        _alertCallback = 0;\n    }\n\nprivate:\n    int _alertCallback;\n    QMediaPlayer _player;\n};\n\n#endif\n"
  },
  {
    "path": "plugins/cordova-plugin-dialogs/src/ubuntu/notification.qml",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\nimport QtQuick 2.0\nimport Ubuntu.Components.Popups 0.1\nimport Ubuntu.Components 0.1\n\nDialog {\n    id: dialogue\n    property string button1Text\n    property string button2Text\n    property string button3Text\n    property bool promptVisible\n    property string defaultPromptText\n\n    TextField {\n        id: prompt\n        text: defaultPromptText\n        visible: promptVisible\n        focus: true\n    }\n    Button {\n        text: button1Text\n        color: \"orange\"\n        onClicked: {\n            root.exec(\"Notification\", \"notificationDialogButtonPressed\", [1, prompt.text, promptVisible]);\n            PopupUtils.close(dialogue)\n        }\n    }\n    Button {\n        text: button2Text\n        visible: button2Text.length > 0\n        color: \"orange\"\n        onClicked: {\n            root.exec(\"Notification\", \"notificationDialogButtonPressed\", [2, prompt.text, promptVisible]);\n            PopupUtils.close(dialogue)\n        }\n    }\n    Button {\n        text: button3Text\n        visible: button3Text.length > 0\n        onClicked: {\n            root.exec(\"Notification\", \"notificationDialogButtonPressed\", [3, prompt.text, promptVisible]);\n            PopupUtils.close(dialogue)\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-dialogs/src/windows/NotificationProxy.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/*global Windows:true, WinJS, toStaticHTML */\n\nvar cordova = require('cordova');\n\nvar isAlertShowing = false;\nvar alertStack = [];\n\n// CB-8928: When toStaticHTML is undefined, prompt fails to run\nvar _cleanHtml = function(html) { return html; };\nif (typeof toStaticHTML !== 'undefined') {\n    _cleanHtml = toStaticHTML;\n}\n\n// Windows does not provide native UI for promp dialog so we use some\n// simple html-based implementation until it is available\nfunction createPromptDialog(title, message, buttons, defaultText, callback) {\n\n    var isPhone = cordova.platformId == \"windows\" && WinJS.Utilities.isPhone;\n\n    var dlgWrap = document.createElement(\"div\");\n    dlgWrap.style.position = \"absolute\";\n    dlgWrap.style.width = \"100%\";\n    dlgWrap.style.height = \"100%\";\n    dlgWrap.style.backgroundColor = \"rgba(0,0,0,0.25)\";\n    dlgWrap.style.zIndex = \"100000\";\n    dlgWrap.className = \"dlgWrap\";\n\n    var dlg = document.createElement(\"div\");\n    dlg.style.width = \"100%\";\n    dlg.style.minHeight = \"180px\";\n    dlg.style.height = \"auto\";\n    dlg.style.overflow = \"auto\";\n    dlg.style.backgroundColor = \"white\";\n    dlg.style.position = \"relative\";\n    dlg.style.lineHeight = \"2\";\n\n    if (isPhone) {\n        dlg.style.padding = \"0px 5%\";\n    } else {\n        dlg.style.top = \"50%\"; // center vertically\n        dlg.style.transform = \"translateY(-50%)\";\n        dlg.style.padding = \"0px 30%\";\n    }\n\n    // dialog layout template\n    dlg.innerHTML = _cleanHtml(\"<span id='lbl-title' style='font-size: 24pt'></span><br/>\" + // title\n        \"<span id='lbl-message'></span><br/>\" + // message\n        \"<input id='prompt-input' style='width: 100%'/><br/>\"); // input fields\n\n    dlg.querySelector('#lbl-title').appendChild(document.createTextNode(title));\n    dlg.querySelector('#lbl-message').appendChild(document.createTextNode(message));\n    dlg.querySelector('#prompt-input').setAttribute('placeholder', defaultText);\n\n    function makeButtonCallback(idx) {\n        return function () {\n            var value = dlg.querySelector('#prompt-input').value;\n            dlgWrap.parentNode.removeChild(dlgWrap);\n\n            if (callback) {\n                callback({ input1: value, buttonIndex: idx });\n            }\n        };\n    }\n\n    function addButton(idx, label) {\n        var button = document.createElement('button');\n        button.style.margin = \"8px 0 8px 16px\";\n        button.style.float = \"right\";\n        button.style.fontSize = \"12pt\";\n        button.tabIndex = idx;\n        button.onclick = makeButtonCallback(idx + 1);\n        if (idx === 0) {\n            button.style.color = \"white\";\n            button.style.backgroundColor = \"#464646\";\n        } else {\n            button.style.backgroundColor = \"#cccccc\";\n        }\n        button.style.border = \"none\";\n        button.appendChild(document.createTextNode(label));\n        dlg.appendChild(button);\n    }\n\n    // reverse order is used since we align buttons to the right\n    for (var idx = buttons.length - 1; idx >= 0; idx--) {\n        addButton(idx, buttons[idx]);\n    }\n\n    dlgWrap.appendChild(dlg);\n    document.body.appendChild(dlgWrap);\n\n    // make sure input field is under focus\n    dlg.querySelector('#prompt-input').focus();\n\n    return dlgWrap;\n}\n\nmodule.exports = {\n    alert:function(win, loseX, args) {\n\n        if (isAlertShowing) {\n            var later = function () {\n                module.exports.alert(win, loseX, args);\n            };\n            alertStack.push(later);\n            return;\n        }\n        isAlertShowing = true;\n\n        var message = args[0];\n        var _title = args[1];\n        var _buttonLabel = args[2];\n\n        var md = new Windows.UI.Popups.MessageDialog(message, _title);\n        md.commands.append(new Windows.UI.Popups.UICommand(_buttonLabel));\n        md.showAsync().then(function() {\n            isAlertShowing = false;\n            if (win) {\n                win();\n            }\n\n            if (alertStack.length) {\n                setTimeout(alertStack.shift(), 0);\n            }\n\n        });\n    },\n\n    prompt: function (win, lose, args) {\n        if (isAlertShowing) {\n            var later = function () {\n                module.exports.prompt(win, lose, args);\n            };\n            alertStack.push(later);\n            return;\n        }\n\n        isAlertShowing = true;\n\n        var message = args[0],\n            title = args[1],\n            buttons = args[2],\n            defaultText = args[3];\n\n        try {\n            createPromptDialog(title, message, buttons, defaultText, function (evt) {\n                isAlertShowing = false;\n                if (win) {\n                    win(evt);\n                }\n            });\n\n        } catch (e) {\n            // set isAlertShowing flag back to false in case of exception\n            isAlertShowing = false;\n            if (alertStack.length) {\n                setTimeout(alertStack.shift(), 0);\n            }\n            // rethrow exception\n            throw e;\n        }\n    },\n\n    confirm:function(win, loseX, args) {\n\n        if (isAlertShowing) {\n            var later = function () {\n                module.exports.confirm(win, loseX, args);\n            };\n            alertStack.push(later);\n            return;\n        }\n\n        isAlertShowing = true;\n\n        try {\n            var message = args[0];\n            var _title = args[1];\n            var buttons = args[2];\n\n            var md = new Windows.UI.Popups.MessageDialog(message, _title);\n\n            buttons.forEach(function(buttonLabel) {\n                md.commands.append(new Windows.UI.Popups.UICommand(buttonLabel));\n            });\n\n            md.showAsync().then(function(res) {\n                isAlertShowing = false;\n                var result = res ? buttons.indexOf(res.label) + 1 : 0;\n                if (win) {\n                    win(result);\n                }\n                if (alertStack.length) {\n                    setTimeout(alertStack.shift(), 0);\n                }\n\n            });\n        } catch (e) {\n            // set isAlertShowing flag back to false in case of exception\n            isAlertShowing = false;\n            if (alertStack.length) {\n                setTimeout(alertStack.shift(), 0);\n            }\n            // rethrow exception\n            throw e;\n        }\n    },\n\n    beep:function(winX, loseX, args) {\n\n        // set a default args if it is not set\n        args = args && args.length ? args : [\"1\"];\n\n        var snd = new Audio('ms-winsoundevent:Notification.Default');\n        var count = parseInt(args[0]) || 1;\n        snd.msAudioCategory = \"Alerts\";\n\n        var onEvent = function () {\n            if (count > 0) {\n                snd.play();\n            } else {\n                snd.removeEventListener(\"ended\", onEvent);\n                snd = null;\n                if (winX) {\n                    winX(); // notification.js just sends null, but this is future friendly\n                }\n            }\n            count--;\n        };\n        snd.addEventListener(\"ended\", onEvent);\n        onEvent();\n\n    }\n};\n\nrequire(\"cordova/exec/proxy\").add(\"Notification\",module.exports);\n"
  },
  {
    "path": "plugins/cordova-plugin-dialogs/src/wp/Notification.cs",
    "content": "﻿/*  \n\tLicensed under the Apache License, Version 2.0 (the \"License\");\n\tyou may not use this file except in compliance with the License.\n\tYou may obtain a copy of the License at\n\t\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\t\n\tUnless required by applicable law or agreed to in writing, software\n\tdistributed under the License is distributed on an \"AS IS\" BASIS,\n\tWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n\tSee the License for the specific language governing permissions and\n\tlimitations under the License.\n*/\n\nusing System;\nusing System.Windows;\nusing System.Windows.Controls;\nusing Microsoft.Devices;\nusing System.Runtime.Serialization;\nusing System.Threading;\nusing System.Windows.Resources;\nusing Microsoft.Phone.Controls;\nusing Microsoft.Xna.Framework.Audio;\nusing WPCordovaClassLib.Cordova.UI;\nusing System.Diagnostics;\n\n\nnamespace WPCordovaClassLib.Cordova.Commands\n{\n    public class Notification : BaseCommand\n    {\n        static ProgressBar progressBar = null;\n        const int DEFAULT_DURATION = 5;\n\n        private NotificationBox notifyBox;\n\n        private class NotifBoxData\n        {\n            public NotificationBox previous {get;set;}\n            public string callbackId { get; set; }\n        }\n\n        private PhoneApplicationPage Page\n        {\n            get\n            {\n                PhoneApplicationPage page = null;\n                PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;\n                if (frame != null)\n                {\n                    page = frame.Content as PhoneApplicationPage;\n                }\n                return page;\n            }\n        }\n\n        // blink api - doesn't look like there is an equivalent api we can use...\n\n        [DataContract]\n        public class AlertOptions\n        {\n            [OnDeserializing]\n            public void OnDeserializing(StreamingContext context)\n            {\n                // set defaults\n                this.message = \"message\";\n                this.title = \"Alert\";\n                this.buttonLabel = \"ok\";\n            }\n\n            /// <summary>\n            /// message to display in the alert box\n            /// </summary>\n            [DataMember]\n            public string message;\n\n            /// <summary>\n            /// title displayed on the alert window\n            /// </summary>\n            [DataMember]\n            public string title;\n\n            /// <summary>\n            /// text to display on the button\n            /// </summary>\n            [DataMember]\n            public string buttonLabel;\n        }\n\n        [DataContract]\n        public class PromptResult\n        {\n            [DataMember]\n            public int buttonIndex;\n\n            [DataMember]\n            public string input1;\n\n            public PromptResult(int index, string text)\n            {\n                this.buttonIndex = index;\n                this.input1 = text;\n            }\n        }\n\n        public void alert(string options)\n        {\n            string[] args = JSON.JsonHelper.Deserialize<string[]>(options);\n            AlertOptions alertOpts = new AlertOptions();\n            alertOpts.message = args[0];\n            alertOpts.title = args[1];\n            alertOpts.buttonLabel = args[2];\n            string aliasCurrentCommandCallbackId = args[3];\n\n            Deployment.Current.Dispatcher.BeginInvoke(() =>\n            {\n                PhoneApplicationPage page = Page;\n                if (page != null)\n                {\n                    Grid grid = page.FindName(\"LayoutRoot\") as Grid;\n                    if (grid != null)\n                    {\n                        var previous = notifyBox;\n                        notifyBox = new NotificationBox();\n                        notifyBox.Tag = new NotifBoxData { previous = previous, callbackId = aliasCurrentCommandCallbackId };\n                        notifyBox.PageTitle.Text = alertOpts.title;\n                        notifyBox.SubTitle.Text = alertOpts.message;\n                        Button btnOK = new Button();\n                        btnOK.Content = alertOpts.buttonLabel;\n                        btnOK.Click += new RoutedEventHandler(btnOK_Click);\n                        btnOK.Tag = 1;\n                        notifyBox.ButtonPanel.Children.Add(btnOK);\n                        grid.Children.Add(notifyBox);\n\n                        if (previous == null)\n                        {\n                            page.BackKeyPress += page_BackKeyPress;\n                        }\n                    }\n                }\n                else\n                {\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.INSTANTIATION_EXCEPTION));\n                }\n            });\n        }\n\n        public void prompt(string options)\n        {\n            string[] args = JSON.JsonHelper.Deserialize<string[]>(options);\n            string message = args[0];\n            string title = args[1];\n            string buttonLabelsArray = args[2];\n            string[] buttonLabels = JSON.JsonHelper.Deserialize<string[]>(buttonLabelsArray);\n            string defaultText = args[3];\n            string aliasCurrentCommandCallbackId = args[4];\n\n            Deployment.Current.Dispatcher.BeginInvoke(() =>\n            {\n                PhoneApplicationPage page = Page;\n                if (page != null)\n                {\n                    Grid grid = page.FindName(\"LayoutRoot\") as Grid;\n                    if (grid != null)\n                    {\n                        var previous = notifyBox;\n                        notifyBox = new NotificationBox();\n                        notifyBox.Tag = new NotifBoxData { previous = previous, callbackId = aliasCurrentCommandCallbackId };\n                        notifyBox.PageTitle.Text = title;\n                        notifyBox.SubTitle.Text = message;\n\n                        //TextBox textBox = new TextBox();\n                        //textBox.Text = defaultText;\n                        //textBox.AcceptsReturn = true;\n                        //notifyBox.ContentScroller.Content = textBox;\n\n                        notifyBox.InputText.Text = defaultText;\n                        notifyBox.InputText.Visibility = Visibility.Visible;\n\n                        for (int i = 0; i < buttonLabels.Length; ++i)\n                        {\n                            Button button = new Button();\n                            button.Content = buttonLabels[i];\n                            button.Tag = i + 1;\n                            button.Click += promptBoxbutton_Click;\n                            notifyBox.ButtonPanel.Orientation = Orientation.Vertical;\n                            notifyBox.ButtonPanel.Children.Add(button);\n                        }\n\n                        grid.Children.Add(notifyBox);\n                        if (previous != null)\n                        {\n                            page.BackKeyPress += page_BackKeyPress;\n                        }\n                    }\n                }\n                else\n                {\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.INSTANTIATION_EXCEPTION));\n                }\n            });\n        }\n\n        public void confirm(string options)\n        {\n            string[] args = JSON.JsonHelper.Deserialize<string[]>(options);\n            AlertOptions alertOpts = new AlertOptions();\n            alertOpts.message = args[0];\n            alertOpts.title = args[1];\n            alertOpts.buttonLabel = args[2];\n            string aliasCurrentCommandCallbackId = args[3];\n\n            Deployment.Current.Dispatcher.BeginInvoke(() =>\n            {\n                PhoneApplicationPage page = Page;\n                if (page != null)\n                {\n                    Grid grid = page.FindName(\"LayoutRoot\") as Grid;\n                    if (grid != null)\n                    {\n                        var previous = notifyBox;\n                        notifyBox = new NotificationBox();\n                        notifyBox.Tag = new NotifBoxData { previous = previous, callbackId = aliasCurrentCommandCallbackId };\n                        notifyBox.PageTitle.Text = alertOpts.title;\n                        notifyBox.SubTitle.Text = alertOpts.message;\n\n                        string[] labels = JSON.JsonHelper.Deserialize<string[]>(alertOpts.buttonLabel);\n\n                        if (labels == null)\n                        {\n                            labels = alertOpts.buttonLabel.Split(',');\n                        }\n\n                        for (int n = 0; n < labels.Length; n++)\n                        {\n                            Button btn = new Button();\n                            btn.Content = labels[n];\n                            btn.Tag = n;\n                            btn.Click += new RoutedEventHandler(btnOK_Click);\n                            notifyBox.ButtonPanel.Children.Add(btn);\n                        }\n\n                        grid.Children.Add(notifyBox);\n                        if (previous == null)\n                        {\n                            page.BackKeyPress += page_BackKeyPress;\n                        }\n                    }\n                }\n                else\n                {\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.INSTANTIATION_EXCEPTION));\n                }\n            });\n        }\n\n        void promptBoxbutton_Click(object sender, RoutedEventArgs e)\n        {\n            Button button = sender as Button;\n            FrameworkElement promptBox = null;\n            int buttonIndex = 0;\n            string callbackId = string.Empty;\n            string text = string.Empty;\n            if (button != null)\n            {\n                buttonIndex = (int)button.Tag;\n                promptBox = button.Parent as FrameworkElement;\n                while ((promptBox = promptBox.Parent as FrameworkElement) != null &&\n                       !(promptBox is NotificationBox)) ;\n            }\n\n            if (promptBox != null)\n            {\n                NotificationBox box = promptBox as NotificationBox;\n\n                text = box.InputText.Text;\n\n                PhoneApplicationPage page = Page;\n                if (page != null)\n                {\n                    Grid grid = page.FindName(\"LayoutRoot\") as Grid;\n                    if (grid != null)\n                    {\n                        grid.Children.Remove(promptBox);\n                    }\n\n                    NotifBoxData data = promptBox.Tag as NotifBoxData;\n                    promptBox = data.previous as NotificationBox;\n                    callbackId = data.callbackId as string;\n\n                    if (promptBox == null)\n                    {\n                        page.BackKeyPress -= page_BackKeyPress;\n                    }\n                }\n            }\n            DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new PromptResult(buttonIndex, text)), callbackId);\n        }\n\n        void page_BackKeyPress(object sender, System.ComponentModel.CancelEventArgs e)\n        {\n            PhoneApplicationPage page = sender as PhoneApplicationPage;\n            string callbackId = \"\";\n            if (page != null && notifyBox != null)\n            {\n                Grid grid = page.FindName(\"LayoutRoot\") as Grid;\n                if (grid != null)\n                {\n                    grid.Children.Remove(notifyBox);\n                    NotifBoxData notifBoxData = notifyBox.Tag as NotifBoxData;\n                    notifyBox = notifBoxData.previous as NotificationBox;\n                    callbackId = notifBoxData.callbackId as string;\n                }\n                if (notifyBox == null)\n                {\n                    page.BackKeyPress -= page_BackKeyPress;\n                }\n                e.Cancel = true;\n            }\n\n            DispatchCommandResult(new PluginResult(PluginResult.Status.OK, 0), callbackId);\n        }\n\n        void btnOK_Click(object sender, RoutedEventArgs e)\n        {\n            Button btn = sender as Button;\n            FrameworkElement notifBoxParent = null;\n            int retVal = 0;\n            string callbackId = \"\";\n            if (btn != null)\n            {\n                retVal = (int)btn.Tag + 1;\n\n                notifBoxParent = btn.Parent as FrameworkElement;\n                while ((notifBoxParent = notifBoxParent.Parent as FrameworkElement) != null &&\n                       !(notifBoxParent is NotificationBox)) ;\n            }\n            if (notifBoxParent != null)\n            {\n                PhoneApplicationPage page = Page;\n                if (page != null)\n                {\n                    Grid grid = page.FindName(\"LayoutRoot\") as Grid;\n                    if (grid != null)\n                    {\n                        grid.Children.Remove(notifBoxParent);\n                    }\n\n                    NotifBoxData notifBoxData = notifBoxParent.Tag as NotifBoxData;\n                    notifyBox = notifBoxData.previous as NotificationBox;\n                    callbackId = notifBoxData.callbackId as string;\n\n                    if (notifyBox == null)\n                    {\n                        page.BackKeyPress -= page_BackKeyPress;\n                    }\n                }\n\n            }\n            DispatchCommandResult(new PluginResult(PluginResult.Status.OK, retVal), callbackId);\n        }\n\n\n\n        public void beep(string options)\n        {\n            string[] args = JSON.JsonHelper.Deserialize<string[]>(options);\n            int times = int.Parse(args[0]);\n\n            string resourcePath = BaseCommand.GetBaseURL() + \"Plugins/cordova-plugin-dialogs/notification-beep.wav\";\n\n            StreamResourceInfo sri = Application.GetResourceStream(new Uri(resourcePath, UriKind.Relative));\n\n            if (sri != null)\n            {\n                SoundEffect effect = SoundEffect.FromStream(sri.Stream);\n                SoundEffectInstance inst = effect.CreateInstance();\n                ThreadPool.QueueUserWorkItem((o) =>\n                {\n                    // cannot interact with UI !!\n                    do\n                    {\n                        inst.Play();\n                        Thread.Sleep(effect.Duration + TimeSpan.FromMilliseconds(100));\n                    }\n                    while (--times > 0);\n\n                });\n\n            }\n\n            // TODO: may need a listener to trigger DispatchCommandResult after the alarm has finished executing...\n            DispatchCommandResult();\n        }\n\n        // Display an indeterminate progress indicator\n        public void activityStart(string unused)\n        {\n\n            Deployment.Current.Dispatcher.BeginInvoke(() =>\n            {\n                PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;\n\n                if (frame != null)\n                {\n                    PhoneApplicationPage page = frame.Content as PhoneApplicationPage;\n\n                    if (page != null)\n                    {\n                        var temp = page.FindName(\"LayoutRoot\");\n                        Grid grid = temp as Grid;\n                        if (grid != null)\n                        {\n                            if (progressBar != null)\n                            {\n                                grid.Children.Remove(progressBar);\n                            }\n                            progressBar = new ProgressBar();\n                            progressBar.IsIndeterminate = true;\n                            progressBar.IsEnabled = true;\n\n                            grid.Children.Add(progressBar);\n                        }\n                    }\n                }\n            });\n        }\n\n\n        // Remove our indeterminate progress indicator\n        public void activityStop(string unused)\n        {\n            Deployment.Current.Dispatcher.BeginInvoke(() =>\n            {\n                if (progressBar != null)\n                {\n                    progressBar.IsEnabled = false;\n                    PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;\n                    if (frame != null)\n                    {\n                        PhoneApplicationPage page = frame.Content as PhoneApplicationPage;\n                        if (page != null)\n                        {\n                            Grid grid = page.FindName(\"LayoutRoot\") as Grid;\n                            if (grid != null)\n                            {\n                                grid.Children.Remove(progressBar);\n                            }\n                        }\n                    }\n                    progressBar = null;\n                }\n            });\n        }\n\n        public void vibrate(string vibrateDuration)\n        {\n\n            int msecs = 200; // set default\n\n            try\n            {\n                string[] args = JSON.JsonHelper.Deserialize<string[]>(vibrateDuration);\n\n                msecs = int.Parse(args[0]);\n                if (msecs < 1)\n                {\n                    msecs = 1;\n                }\n            }\n            catch (FormatException)\n            {\n\n            }\n\n            VibrateController.Default.Start(TimeSpan.FromMilliseconds(msecs));\n\n            // TODO: may need to add listener to trigger DispatchCommandResult when the vibration ends...\n            DispatchCommandResult();\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-dialogs/src/wp/NotificationBox.xaml",
    "content": "﻿<!--\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements.  See the NOTICE file\n distributed with this work for additional information\n regarding copyright ownership.  The ASF licenses this file\n to you under the Apache License, Version 2.0 (the\n \"License\"); you may not use this file except in compliance\n with the License.  You may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an\n \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n KIND, either express or implied.  See the License for the\n specific language governing permissions and limitations\n under the License. \n-->\n<UserControl x:Class=\"WPCordovaClassLib.Cordova.UI.NotificationBox\"\n    xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n    xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n    xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n    mc:Ignorable=\"d\"\n    FontFamily=\"{StaticResource PhoneFontFamilyNormal}\"\n    FontSize=\"{StaticResource PhoneFontSizeNormal}\"\n    Foreground=\"{StaticResource PhoneForegroundBrush}\"\n    d:DesignHeight=\"800\" d:DesignWidth=\"480\" VerticalAlignment=\"Stretch\">\n\n   <!--TitlePanel contains the name of the application and page title-->\n    <Grid x:Name=\"LayoutRoot\"\n          Background=\"{StaticResource PhoneSemitransparentBrush}\">\n        <Grid.RowDefinitions>\n            <RowDefinition Height=\"*\"></RowDefinition>\n        </Grid.RowDefinitions>\n\n        <Grid x:Name=\"TitlePanel\" \n            Grid.Row=\"0\"\n            VerticalAlignment=\"Top\"\n            Background=\"{StaticResource PhoneSemitransparentBrush}\">\n            <Grid.RowDefinitions>\n                <RowDefinition Height=\"Auto\"></RowDefinition>\n                <RowDefinition Height=\"*\"></RowDefinition>\n                <RowDefinition Height=\"Auto\"></RowDefinition>\n            </Grid.RowDefinitions>\n\n            <TextBlock x:Name=\"PageTitle\" \n                       Text=\"Title\" \n                       Margin=\"10,10\" \n                       Grid.Row=\"0\"\n                       Style=\"{StaticResource PhoneTextTitle2Style}\"/>\n            \n            <ScrollViewer x:Name=\"ContentScroller\"\n                          Grid.Row=\"1\"\n                          MinHeight=\"120\"\n                          Margin=\"10,10\">\n                <StackPanel Orientation=\"Vertical\">\n                    <TextBlock x:Name=\"SubTitle\" \n                               Text=\"Subtitle\" \n                               Width=\"Auto\"\n                               TextWrapping=\"Wrap\"\n                               Style=\"{StaticResource PhoneTextTitle3Style}\"/>\n                    <TextBox x:Name=\"InputText\" \n                             Visibility=\"Collapsed\"/>\n                </StackPanel>\n            </ScrollViewer>\n\n            <ScrollViewer HorizontalScrollBarVisibility=\"Auto\" \n                          Grid.Row=\"2\"\n                          VerticalScrollBarVisibility=\"Disabled\">       \n                <StackPanel x:Name=\"ButtonPanel\"\n                            Margin=\"10,10\"\n                            Orientation=\"Horizontal\"/>\n            </ScrollViewer>\n\n    </Grid>\n    </Grid>\n\n</UserControl>\n"
  },
  {
    "path": "plugins/cordova-plugin-dialogs/src/wp/NotificationBox.xaml.cs",
    "content": "﻿/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements.  See the NOTICE file\n distributed with this work for additional information\n regarding copyright ownership.  The ASF licenses this file\n to you under the Apache License, Version 2.0 (the\n \"License\"); you may not use this file except in compliance\n with the License.  You may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an\n \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n KIND, either express or implied.  See the License for the\n specific language governing permissions and limitations\n under the License. \n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Net;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Documents;\nusing System.Windows.Input;\nusing System.Windows.Media;\nusing System.Windows.Media.Animation;\nusing System.Windows.Shapes;\n\nnamespace WPCordovaClassLib.Cordova.UI\n{\n    public partial class NotificationBox : UserControl\n    {\n        public NotificationBox()\n        {\n            InitializeComponent();\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-dialogs/tests/plugin.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  Licensed to the Apache Software Foundation (ASF) under one\n  or more contributor license agreements.  See the NOTICE file\n  distributed with this work for additional information\n  regarding copyright ownership.  The ASF licenses this file\n  to you under the Apache License, Version 2.0 (the\n  \"License\"); you may not use this file except in compliance\n  with the License.  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing,\n  software distributed under the License is distributed on an\n  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n  KIND, either express or implied.  See the License for the\n  specific language governing permissions and limitations\n  under the License.\n-->\n\n<plugin xmlns=\"http://apache.org/cordova/ns/plugins/1.0\"\n    id=\"cordova-plugin-dialogs-tests\"\n    version=\"1.2.1\">\n    <name>Cordova Notification Plugin Tests</name>\n    <license>Apache 2.0</license>\n\n    <js-module src=\"tests.js\" name=\"tests\">\n    </js-module>\n</plugin>\n"
  },
  {
    "path": "plugins/cordova-plugin-dialogs/tests/tests.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/* jshint jasmine: true */\n/* global cordova */\n\nexports.defineAutoTests = function () {\n    describe('Notification (navigator.notification)', function () {\n        it(\"should exist\", function () {\n            expect(navigator.notification).toBeDefined();\n        });\n\n        it(\"should contain a beep function\", function () {\n            expect(typeof navigator.notification.beep).toBeDefined();\n            expect(typeof navigator.notification.beep).toBe(\"function\");\n        });\n\n        it(\"should contain an alert function\", function () {\n            expect(typeof navigator.notification.alert).toBeDefined();\n            expect(typeof navigator.notification.alert).toBe(\"function\");\n        });\n\n        it(\"should contain a confirm function\", function () {\n            expect(typeof navigator.notification.confirm).toBeDefined();\n            expect(typeof navigator.notification.confirm).toBe(\"function\");\n        });\n\n        it(\"should contain a prompt function\", function () {\n            expect(typeof navigator.notification.prompt).toBeDefined();\n            expect(typeof navigator.notification.prompt).toBe(\"function\");\n        });\n    });\n};\n\n/******************************************************************************/\n/******************************************************************************/\n/******************************************************************************/\n\nexports.defineManualTests = function (contentEl, createActionButton) {\n    var logMessage = function (message) {\n        var log = document.getElementById('info');\n        var logLine = document.createElement('div');\n        logLine.innerHTML = message;\n        log.appendChild(logLine);\n    };\n\n    var clearLog = function () {\n        var log = document.getElementById('info');\n        log.innerHTML = '';\n    };\n\n    var beep = function () {\n        console.log(\"beep()\");\n        navigator.notification.beep(3);\n    };\n\n    var alertDialog = function (message, title, button) {\n        console.log(\"alertDialog()\");\n        navigator.notification.alert(message,\n            function () {\n                console.log(\"Alert dismissed.\");\n            },\n            title, button);\n        console.log(\"After alert\");\n    };\n\n    var confirmDialogA = function (message, title, buttons) {\n        clearLog();\n        navigator.notification.confirm(message,\n            function (r) {\n                if (r === 0) {\n                    logMessage(\"Dismissed dialog without making a selection.\");\n                    console.log(\"Dismissed dialog without making a selection.\");\n                } else {\n                    console.log(\"You selected \" + r);\n                    logMessage(\"You selected \" + (buttons.split(\",\"))[r - 1]);\n                }\n            },\n            title,\n            buttons);\n    };\n\n    var confirmDialogB = function (message, title, buttons) {\n        clearLog();\n        navigator.notification.confirm(message,\n            function (r) {\n                if (r === 0) {\n                    logMessage(\"Dismissed dialog without making a selection.\");\n                    console.log(\"Dismissed dialog without making a selection.\");\n                } else {\n                    console.log(\"You selected \" + r);\n                    logMessage(\"You selected \" + buttons[r - 1]);\n                }\n            },\n            title,\n            buttons);\n    };\n\n    var promptDialog = function (message, title, buttons) {\n        clearLog();\n        navigator.notification.prompt(message,\n            function (r) {\n                if (r && r.buttonIndex === 0) {\n                    var msg = \"Dismissed dialog\";\n                    if (r.input1) {\n                        msg += \" with input: \" + r.input1;\n                    }\n                    logMessage(msg);\n                    console.log(msg);\n                } else {\n                    console.log(\"You selected \" + r.buttonIndex + \" and entered: \" + r.input1);\n                    logMessage(\"You selected \" + buttons[r.buttonIndex - 1] + \" and entered: \" + r.input1);\n                }\n            },\n            title,\n            buttons);\n    };\n\n    /******************************************************************************/\n\n    var dialogs_tests = '<div id=\"beep\"></div>' +\n        'Expected result: Device will beep (unless device is on silent). Nothing will get updated in status box.' +\n        '<h2>Dialog Tests</h2>' +\n        '<h3>Dialog boxes will pop up for each of the following tests</h3>' +\n        '<p/> <div id=\"alert\"></div>' +\n        'Expected result: Dialog will say \"You pressed alert\". Press continue to close dialog. Nothing will get updated in status box.' +\n        '<p/> <div id=\"confirm_deprecated\"></div>' +\n        'Expected result: Dialog will say \"You pressed confirm\". Press Yes, No, or Maybe to close dialog. Status box will tell you what option you selected.' +\n        '<p/> <div id=\"confirm\"></div>' +\n        'Expected result: Dialog will say \"You pressed confirm\". Press Yes, No, or Maybe, Not Sure to close dialog. Status box will tell you what option you selected, and should use 1-based indexing.' +\n        '<p/> <div id=\"prompt\"></div>' +\n        'Expected result: Dialog will say \"You pressed prompt\". Enter any message and press Yes, No, or Maybe, Not Sure to close dialog. Status box will tell you what option you selected and message you entered, and should use 1-based indexing.' +\n        '<p/> <div id=\"built_in_alert\"></div>' +\n        'Expected result: Dialog will have title \"index.html\" and say \"You pressed alert\" Press OK to close dialog. Nothing will get updated in status box.' +\n        '<p/> <div id=\"built_in_confirm\"></div>' +\n        'Expected result: Dialog will have title \"index.html\" and say \"You selected confirm\". Press Cancel or OK to close dialog. Nothing will get updated in status box.' +\n        '<p/> <div id=\"built_in_prompt\"></div>' +\n        'Expected result: Dialog will have title \"index.html\" and say \"This is a prompt\". \"Default value\" will be in text box. Press Cancel or OK to close dialog. Nothing will get updated in status box.';\n\n    contentEl.innerHTML = '<div id=\"info\"></div>' +\n        dialogs_tests;\n\n    createActionButton('Beep', function () {\n        beep();\n    }, 'beep');\n\n    createActionButton('Alert Dialog', function () {\n        alertDialog('You pressed alert.', 'Alert Dialog', 'Continue');\n    }, 'alert');\n\n    // WP8.1 detection is necessary since it doesn't support confirm dialogs with more than 2 buttons\n    var isRunningOnWP81 = cordova.platformId == \"windows\" && navigator.userAgent.indexOf('Windows Phone') > -1;\n\n    createActionButton('Confirm Dialog - Deprecated', function () {\n        var buttons = isRunningOnWP81 ? 'Yes,No' : 'Yes,No,Maybe';\n        confirmDialogA('You pressed confirm.', 'Confirm Dialog', buttons);\n    }, 'confirm_deprecated');\n\n    createActionButton('Confirm Dialog', function () {\n        var buttons = isRunningOnWP81 ? ['Yes', 'Actually, No'] : ['Yes', 'No', 'Maybe, Not Sure'];\n        confirmDialogB('You pressed confirm.', 'Confirm Dialog', buttons);\n    }, 'confirm');\n\n    createActionButton('Prompt Dialog', function () {\n        promptDialog('You pressed prompt.', 'Prompt Dialog', ['Yes', 'No', 'Maybe, Not Sure']);\n    }, 'prompt');\n\n    createActionButton('Built-in Alert Dialog', function () {\n        if (typeof alert === 'function') {\n            alert('You pressed alert');\n        }\n    }, 'built_in_alert');\n\n    createActionButton('Built-in Confirm Dialog', function () {\n        if (typeof confirm === 'function') {\n            confirm('You selected confirm');\n        }\n    }, 'built_in_confirm');\n\n    createActionButton('Built-in Prompt Dialog', function () {\n        if (typeof prompt === 'function') {\n            prompt('This is a prompt', 'Default value');\n        }\n    }, 'built_in_prompt');\n};\n"
  },
  {
    "path": "plugins/cordova-plugin-dialogs/www/android/notification.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\nvar exec = require('cordova/exec');\n\n/**\n * Provides Android enhanced notification API.\n */\nmodule.exports = {\n    activityStart : function(title, message) {\n        // If title and message not specified then mimic Android behavior of\n        // using default strings.\n        if (typeof title === \"undefined\" && typeof message == \"undefined\") {\n            title = \"Busy\";\n            message = 'Please wait...';\n        }\n\n        exec(null, null, 'Notification', 'activityStart', [ title, message ]);\n    },\n\n    /**\n     * Close an activity dialog\n     */\n    activityStop : function() {\n        exec(null, null, 'Notification', 'activityStop', []);\n    },\n\n    /**\n     * Display a progress dialog with progress bar that goes from 0 to 100.\n     *\n     * @param {String}\n     *            title Title of the progress dialog.\n     * @param {String}\n     *            message Message to display in the dialog.\n     */\n    progressStart : function(title, message) {\n        exec(null, null, 'Notification', 'progressStart', [ title, message ]);\n    },\n\n    /**\n     * Close the progress dialog.\n     */\n    progressStop : function() {\n        exec(null, null, 'Notification', 'progressStop', []);\n    },\n\n    /**\n     * Set the progress dialog value.\n     *\n     * @param {Number}\n     *            value 0-100\n     */\n    progressValue : function(value) {\n        exec(null, null, 'Notification', 'progressValue', [ value ]);\n    }\n};\n"
  },
  {
    "path": "plugins/cordova-plugin-dialogs/www/blackberry10/beep.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\nmodule.exports = function (quantity) {\n    var count = 0,\n    beepObj;\n\n    function callback() {\n        if (--count > 0) {\n            play();\n        } else {\n            beepObj.removeEventListener(\"ended\", callback);\n            beepObj = null;\n        }\n    }\n\n    function play() { \n        //create new object every time due to strage playback behaviour\n        beepObj = new Audio('local:///chrome/plugin/cordova-plugin-dialogs/notification-beep.wav');\n        beepObj.addEventListener(\"ended\", callback);\n        beepObj.play();\n    }\n\n    count += quantity || 1;\n    if (count > 0) {\n        play();\n    }\n};\n"
  },
  {
    "path": "plugins/cordova-plugin-dialogs/www/browser/notification.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n// Platform: browser\nwindow.navigator.notification = window.navigator.notification || {};\n\nmodule.exports.alert = window.navigator.notification.alert = function(message, callback) {\n    // `notification.alert` executes asynchronously\n    setTimeout(function() {\n        window.alert(message);\n        if (callback) {\n            callback();\n        }\n    }, 0);\n};\n\n\nmodule.exports.confirm = window.navigator.notification.confirm = function(message, callback) {\n    // `notification.confirm` executes asynchronously\n    setTimeout(function() {\n        var result = window.confirm(message);\n        if (callback) {\n            if (result) {\n                callback(1); // OK\n            }\n            else {\n                callback(2); // Cancel\n            }\n        }\n    }, 0);\n};\n\n\nmodule.exports.prompt = window.navigator.notification.prompt = function(message, callback, title, buttonLabels, defaultText) {\n    // `notification.prompt` executes asynchronously\n    setTimeout(function() {\n        var result = window.prompt(message,  defaultText || '');\n        if (callback) {\n            if (result === null) {\n                callback({ buttonIndex: 2, input1: '' }); // Cancel\n            }\n            else {\n                callback({ buttonIndex: 1, input1: result }); // OK\n            }\n        }\n    }, 0);\n};\n\n\nvar audioContext = (function() {\n    // Determine if the Audio API is supported by this browser\n    var AudioApi = window.AudioContext;\n    if (!AudioApi) {\n        AudioApi = window.webkitAudioContext;\n    }\n\n    if (AudioApi) {\n        // The Audio API is supported, so create a singleton instance of the AudioContext\n        return new AudioApi();\n    }\n\n    return undefined;\n}());\n\nmodule.exports.beep = window.navigator.notification.beep = function(times) {\n    if (times > 0) {\n        var BEEP_DURATION = 700;\n        var BEEP_INTERVAL = 300;\n\n        if (audioContext) {\n            // Start a beep, using the Audio API\n            var osc = audioContext.createOscillator();\n            osc.type = 0; // sounds like a \"beep\"\n            osc.connect(audioContext.destination);\n            osc.start(0);\n\n            setTimeout(function() {\n                // Stop the beep after the BEEP_DURATION\n                osc.stop(0);\n\n                if (--times > 0) {\n                    // Beep again, after a pause\n                    setTimeout(function() {\n                        navigator.notification.beep(times);\n                    }, BEEP_INTERVAL);\n                }\n\n            }, BEEP_DURATION);\n        }\n        else if (typeof(console) !== 'undefined' && typeof(console.log) === 'function') {\n            // Audio API isn't supported, so just write `beep` to the console\n            for (var i = 0; i < times; i++) {\n                console.log('Beep!');\n            }\n        }\n    }\n};\n"
  },
  {
    "path": "plugins/cordova-plugin-dialogs/www/firefoxos/notification.css",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/* Main dialog setup */\nform[role=\"dialog\"] {\n  background:\n    url(../img/pattern.png) repeat left top,\n    url(../img/gradient.png) no-repeat left top / 100% 100%;\n  overflow: hidden;\n  position: absolute;\n  z-index: 100;\n  top: 0;\n  left: 0;\n  right: 0;\n  bottom: 0;\n  padding: 1.5rem 0 7rem;\n  font-family: \"MozTT\", Sans-serif;\n  font-size: 0;\n  /* Using font-size: 0; we avoid the unwanted visual space (about 3px)\n  created by white-spaces and break lines in the code betewen inline-block elements */\n  color: #fff;\n  text-align: left;\n}\n\nform[role=\"dialog\"]:before {\n  content: \"\";\n  display: inline-block;\n  vertical-align: middle;\n  width: 0.1rem;\n  height: 100%;\n  margin-left: -0.1rem;\n}\n\nform[role=\"dialog\"] > section {\n  font-weight: lighter;\n  font-size: 1.8rem;\n  color: #FAFAFA;\n  padding: 0 1.5rem;\n  -moz-box-sizing: padding-box;\n  width: 100%;\n  display: inline-block;\n  overflow-y: scroll;\n  max-height: 100%;\n  vertical-align: middle;\n  white-space: normal;\n}\n\nform[role=\"dialog\"] h1 {\n  font-weight: normal;\n  font-size: 1.6rem;\n  line-height: 1.5em;\n  color: #fff;\n  margin: 0;\n  padding: 0 1.5rem 1rem;\n  border-bottom: 0.1rem solid #686868;\n}\n\n/* Menu & buttons setup */\nform[role=\"dialog\"] menu {\n  margin: 0;\n  padding: 1.5rem;\n  padding-bottom: 0.5rem;\n  border-top: solid 0.1rem rgba(255, 255, 255, 0.1);\n  background: #2d2d2d url(../img/pattern.png) repeat left top;\n  display: block;\n  overflow: hidden;\n  position: absolute;\n  left: 0;\n  right: 0;\n  bottom: 0;\n  text-align: center;\n}\n\nform[role=\"dialog\"] menu button::-moz-focus-inner {\n  border: none;\n  outline: none;\n}\nform[role=\"dialog\"] menu button {\n  width: 100%;\n  height: 2.4rem;\n  margin: 0 0 1rem;\n  padding: 0 1.5rem;\n  -moz-box-sizing: border-box;\n  display: inline-block;\n  vertical-align: middle;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n  overflow: hidden;\n  background: #fafafa url(../img/default.png) repeat-x left bottom/ auto 100%;\n  border: 0.1rem solid #a6a6a6;\n  border-radius: 0.3rem;\n  font: 500 1.2rem/2.4rem 'MozTT', Sans-serif;\n  color: #333;\n  text-align: center;\n  text-shadow: 0.1rem 0.1rem 0 rgba(255,255,255,0.3);\n  text-decoration: none;\n  outline: none;\n}\n\n/* Press (default & recommend) */\nform[role=\"dialog\"] menu button:active,\nform[role=\"dialog\"] menu button.recommend:active,\na.recommend[role=\"button\"]:active  {\n  border-color: #008aaa;\n  color: #333;\n}\n\n/* Recommend */\nform[role=\"dialog\"] menu button.recommend {\n  background-image: url(../img/recommend.png);\n  background-color: #00caf2;\n  border-color: #008eab;\n}\n\n/* Danger */\nform[role=\"dialog\"] menu button.danger,\na.danger[role=\"button\"] {\n  background-image: url(../img/danger.png);\n  background-color: #b70404;\n  color: #fff;\n  text-shadow: none;\n  border-color: #820000;\n}\n\n/* Danger Press */\nform[role=\"dialog\"] menu button.danger:active {\n  background-image: url(../img/danger-press.png);\n  background-color: #890707;\n}\n\n/* Disabled */\nform[role=\"dialog\"] > menu > button[disabled] {\n  background: #5f5f5f;\n  color: #4d4d4d;\n  text-shadow: none;\n  border-color: #4d4d4d;\n  pointer-events: none;\n}\n\n\nform[role=\"dialog\"] menu button:nth-child(even) {\n  margin-left: 1rem;\n}\n\nform[role=\"dialog\"] menu button,\nform[role=\"dialog\"] menu button:nth-child(odd) {\n  margin: 0 0 1rem 0;\n}\n\nform[role=\"dialog\"] menu button {\n  width: calc((100% - 1rem) / 2);\n}\n\nform[role=\"dialog\"] menu button.full {\n  width: 100%;\n}\n\n/* Specific component code */\nform[role=\"dialog\"] p {\n  word-wrap: break-word;\n  margin: 1rem 0 0;\n  padding: 0 1.5rem 1rem;\n  line-height: 3rem;\n}\n\nform[role=\"dialog\"] p img {\n  float: left;\n  margin-right: 2rem;\n}\n\nform[role=\"dialog\"] p strong {\n  font-weight: lighter;\n}\n\nform[role=\"dialog\"] p small {\n  font-size: 1.4rem;\n  font-weight: normal;\n  color: #cbcbcb;\n  display: block;\n}\n\nform[role=\"dialog\"] dl {\n  border-top: 0.1rem solid #686868;\n  margin: 1rem 0 0;\n  overflow: hidden;\n  padding-top: 1rem;\n  font-size: 1.6rem;\n  line-height: 2.2rem;\n}\n\nform[role=\"dialog\"] dl > dt {\n  clear: both;\n  float: left;\n  width: 7rem;\n  padding-left: 1.5rem;\n  font-weight: 500;\n  text-align: left;\n}\n\nform[role=\"dialog\"] dl > dd {\n  padding-right: 1.5rem;\n  font-weight: 300;\n  text-overflow: ellipsis;\n  vertical-align: top;\n  overflow: hidden;\n}\n\n/* input areas */\ninput[type=\"text\"],\ninput[type=\"password\"],\ninput[type=\"email\"],\ninput[type=\"tel\"],\ninput[type=\"search\"],\ninput[type=\"url\"],\ninput[type=\"number\"],\ntextarea {\n  -moz-box-sizing: border-box;\n  display: block;\n  overflow: hidden;\n  width: 100%;\n  height: 3rem;\n  resize: none;\n  padding: 0 1rem;\n  font-size: 1.6rem;\n  line-height: 3rem;\n  border: 0.1rem solid #ccc;\n  border-radius: 0.3rem;\n  box-shadow: none; /* override the box-shadow from the system (performance issue) */\n  background: #fff url(input_areas/images/ui/shadow.png) repeat-x;\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-dialogs/www/notification.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\nvar exec = require('cordova/exec');\nvar platform = require('cordova/platform');\n\n/**\n * Provides access to notifications on the device.\n */\n\nmodule.exports = {\n\n    /**\n     * Open a native alert dialog, with a customizable title and button text.\n     *\n     * @param {String} message              Message to print in the body of the alert\n     * @param {Function} completeCallback   The callback that is called when user clicks on a button.\n     * @param {String} title                Title of the alert dialog (default: Alert)\n     * @param {String} buttonLabel          Label of the close button (default: OK)\n     */\n    alert: function(message, completeCallback, title, buttonLabel) {\n        var _title = (typeof title === \"string\" ? title : \"Alert\");\n        var _buttonLabel = (buttonLabel || \"OK\");\n        exec(completeCallback, null, \"Notification\", \"alert\", [message, _title, _buttonLabel]);\n    },\n\n    /**\n     * Open a native confirm dialog, with a customizable title and button text.\n     * The result that the user selects is returned to the result callback.\n     *\n     * @param {String} message              Message to print in the body of the alert\n     * @param {Function} resultCallback     The callback that is called when user clicks on a button.\n     * @param {String} title                Title of the alert dialog (default: Confirm)\n     * @param {Array} buttonLabels          Array of the labels of the buttons (default: ['OK', 'Cancel'])\n     */\n    confirm: function(message, resultCallback, title, buttonLabels) {\n        var _title = (typeof title === \"string\" ? title : \"Confirm\");\n        var _buttonLabels = (buttonLabels || [\"OK\", \"Cancel\"]);\n\n        // Strings are deprecated!\n        if (typeof _buttonLabels === 'string') {\n            console.log(\"Notification.confirm(string, function, string, string) is deprecated.  Use Notification.confirm(string, function, string, array).\");\n        }\n\n        // Some platforms take an array of button label names.\n        // Other platforms take a comma separated list.\n        // For compatibility, we convert to the desired type based on the platform.\n        if (platform.id == \"amazon-fireos\" || platform.id == \"android\" || platform.id == \"ios\" ||\n            platform.id == \"windowsphone\" || platform.id == \"firefoxos\" || platform.id == \"ubuntu\" ||\n            platform.id == \"windows8\" || platform.id == \"windows\") {\n\n            if (typeof _buttonLabels === 'string') {\n                _buttonLabels = _buttonLabels.split(\",\"); // not crazy about changing the var type here\n            }\n        } else {\n            if (Array.isArray(_buttonLabels)) {\n                var buttonLabelArray = _buttonLabels;\n                _buttonLabels = buttonLabelArray.toString();\n            }\n        }\n        exec(resultCallback, null, \"Notification\", \"confirm\", [message, _title, _buttonLabels]);\n    },\n\n    /**\n     * Open a native prompt dialog, with a customizable title and button text.\n     * The following results are returned to the result callback:\n     *  buttonIndex     Index number of the button selected.\n     *  input1          The text entered in the prompt dialog box.\n     *\n     * @param {String} message              Dialog message to display (default: \"Prompt message\")\n     * @param {Function} resultCallback     The callback that is called when user clicks on a button.\n     * @param {String} title                Title of the dialog (default: \"Prompt\")\n     * @param {Array} buttonLabels          Array of strings for the button labels (default: [\"OK\",\"Cancel\"])\n     * @param {String} defaultText          Textbox input value (default: empty string)\n     */\n    prompt: function(message, resultCallback, title, buttonLabels, defaultText) {\n        var _message = (typeof message === \"string\" ? message : \"Prompt message\");\n        var _title = (typeof title === \"string\" ? title : \"Prompt\");\n        var _buttonLabels = (buttonLabels || [\"OK\",\"Cancel\"]);\n        var _defaultText = (defaultText || \"\");\n        exec(resultCallback, null, \"Notification\", \"prompt\", [_message, _title, _buttonLabels, _defaultText]);\n    },\n\n    /**\n     * Causes the device to beep.\n     * On Android, the default notification ringtone is played \"count\" times.\n     *\n     * @param {Integer} count       The number of beeps.\n     */\n    beep: function(count) {\n        var defaultedCount = count || 1;\n        exec(null, null, \"Notification\", \"beep\", [ defaultedCount ]);\n    }\n};\n"
  },
  {
    "path": "plugins/cordova-plugin-file/CONTRIBUTING.md",
    "content": "<!--\n#\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#  KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n#\n-->\n\n# Contributing to Apache Cordova\n\nAnyone can contribute to Cordova. And we need your contributions.\n\nThere are multiple ways to contribute: report bugs, improve the docs, and\ncontribute code.\n\nFor instructions on this, start with the \n[contribution overview](http://cordova.apache.org/contribute/).\n\nThe details are explained there, but the important items are:\n - Sign and submit an Apache ICLA (Contributor License Agreement).\n - Have a Jira issue open that corresponds to your contribution.\n - Run the tests so your patch doesn't break existing functionality.\n\nWe look forward to your contributions!\n"
  },
  {
    "path": "plugins/cordova-plugin-file/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License."
  },
  {
    "path": "plugins/cordova-plugin-file/NOTICE",
    "content": "Apache Cordova\nCopyright 2012 The Apache Software Foundation\n\nThis product includes software developed at\nThe Apache Software Foundation (http://www.apache.org/).\n"
  },
  {
    "path": "plugins/cordova-plugin-file/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-file.svg?branch=master)](https://travis-ci.org/apache/cordova-plugin-file)\n\n# cordova-plugin-file\n\nThis plugin implements a File API allowing read/write access to files residing on the device.\n\nThis plugin is based on several specs, including :\nThe HTML5 File API\n[http://www.w3.org/TR/FileAPI/](http://www.w3.org/TR/FileAPI/)\n\nThe (now-defunct) Directories and System extensions\nLatest:\n[http://www.w3.org/TR/2012/WD-file-system-api-20120417/](http://www.w3.org/TR/2012/WD-file-system-api-20120417/)\nAlthough most of the plugin code was written when an earlier spec was current:\n[http://www.w3.org/TR/2011/WD-file-system-api-20110419/](http://www.w3.org/TR/2011/WD-file-system-api-20110419/)\n\nIt also implements the FileWriter spec :\n[http://dev.w3.org/2009/dap/file-system/file-writer.html](http://dev.w3.org/2009/dap/file-system/file-writer.html)\n\nFor usage, please refer to HTML5 Rocks' excellent [FileSystem article.](http://www.html5rocks.com/en/tutorials/file/filesystem/)\n\nFor an overview of other storage options, refer to Cordova's\n[storage guide](http://cordova.apache.org/docs/en/edge/cordova_storage_storage.md.html).\n\nThis plugin defines global `cordova.file` object.\n\nAlthough in the global scope, it is not available until after the `deviceready` event.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(cordova.file);\n    }\n\nReport issues on the [Apache Cordova issue tracker](https://issues.apache.org/jira/issues/?jql=project%20%3D%20CB%20AND%20status%20in%20%28Open%2C%20%22In%20Progress%22%2C%20Reopened%29%20AND%20resolution%20%3D%20Unresolved%20AND%20component%20%3D%20%22Plugin%20File%22%20ORDER%20BY%20priority%20DESC%2C%20summary%20ASC%2C%20updatedDate%20DESC)\n\n## Installation\n\n    cordova plugin add cordova-plugin-file\n\n## Supported Platforms\n\n- Amazon Fire OS\n- Android\n- BlackBerry 10\n- Firefox OS\n- iOS\n- OS X\n- Windows Phone 7 and 8*\n- Windows 8*\n- Windows*\n- Browser\n\n\\* _These platforms do not support `FileReader.readAsArrayBuffer` nor `FileWriter.write(blob)`._\n\n## Where to Store Files\n\nAs of v1.2.0, URLs to important file-system directories are provided.\nEach URL is in the form _file:///path/to/spot/_, and can be converted to a\n`DirectoryEntry` using `window.resolveLocalFileSystemURL()`.\n\n* `cordova.file.applicationDirectory` - Read-only directory where the application\n  is installed. (_iOS_, _Android_, _BlackBerry 10_, _OSX_, _windows_)\n\n* `cordova.file.applicationStorageDirectory` - Root directory of the application's\n  sandbox; on iOS & windows this location is read-only (but specific subdirectories [like\n  `/Documents` on iOS or `/localState` on windows] are read-write). All data contained within\n  is private to the app. (_iOS_, _Android_, _BlackBerry 10_, _OSX_)\n\n* `cordova.file.dataDirectory` - Persistent and private data storage within the\n  application's sandbox using internal memory (on Android, if you need to use\n  external memory, use `.externalDataDirectory`). On iOS, this directory is not\n  synced with iCloud (use `.syncedDataDirectory`). (_iOS_, _Android_, _BlackBerry 10_, _windows_)\n\n* `cordova.file.cacheDirectory` -  Directory for cached data files or any files\n  that your app can re-create easily. The OS may delete these files when the device\n  runs low on storage, nevertheless, apps should not rely on the OS to delete files\n  in here. (_iOS_, _Android_, _BlackBerry 10_, _OSX_, _windows_)\n\n* `cordova.file.externalApplicationStorageDirectory` - Application space on\n  external storage. (_Android_)\n\n* `cordova.file.externalDataDirectory` - Where to put app-specific data files on\n  external storage. (_Android_)\n\n* `cordova.file.externalCacheDirectory` - Application cache on external storage.\n  (_Android_)\n\n* `cordova.file.externalRootDirectory` - External storage (SD card) root. (_Android_, _BlackBerry 10_)\n\n* `cordova.file.tempDirectory` - Temp directory that the OS can clear at will. Do not\n  rely on the OS to clear this directory; your app should always remove files as\n  applicable. (_iOS_, _OSX_, _windows_)\n\n* `cordova.file.syncedDataDirectory` - Holds app-specific files that should be synced\n  (e.g. to iCloud). (_iOS_, _windows_)\n\n* `cordova.file.documentsDirectory` - Files private to the app, but that are meaningful\n  to other application (e.g. Office files). Note that for _OSX_ this is the user's `~/Documents` directory. (_iOS_, _OSX_)\n\n* `cordova.file.sharedDirectory` - Files globally available to all applications (_BlackBerry 10_)\n\n## File System Layouts\n\nAlthough technically an implementation detail, it can be very useful to know how\nthe `cordova.file.*` properties map to physical paths on a real device.\n\n### iOS File System Layout\n\n| Device Path                                    | `cordova.file.*`            | `iosExtraFileSystems` | r/w? | persistent? | OS clears | sync | private |\n|:-----------------------------------------------|:----------------------------|:----------------------|:----:|:-----------:|:---------:|:----:|:-------:|\n| `/var/mobile/Applications/<UUID>/`             | applicationStorageDirectory | -                     | r    |     N/A     |     N/A   | N/A  |   Yes   |\n| &nbsp;&nbsp;&nbsp;`appname.app/`               | applicationDirectory        | bundle                | r    |     N/A     |     N/A   | N/A  |   Yes   |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`www/`     | -                           | -                     | r    |     N/A     |     N/A   | N/A  |   Yes   |\n| &nbsp;&nbsp;&nbsp;`Documents/`                 | documentsDirectory          | documents             | r/w  |     Yes     |     No    | Yes  |   Yes   |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`NoCloud/` | -                           | documents-nosync      | r/w  |     Yes     |     No    | No   |   Yes   |\n| &nbsp;&nbsp;&nbsp;`Library`                    | -                           | library               | r/w  |     Yes     |     No    | Yes? |   Yes   |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`NoCloud/` | dataDirectory               | library-nosync        | r/w  |     Yes     |     No    | No   |   Yes   |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`Cloud/`   | syncedDataDirectory         | -                     | r/w  |     Yes     |     No    | Yes  |   Yes   |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`Caches/`  | cacheDirectory              | cache                 | r/w  |     Yes*    |  Yes\\*\\*\\*| No   |   Yes   |\n| &nbsp;&nbsp;&nbsp;`tmp/`                       | tempDirectory               | -                     | r/w  |     No\\*\\*  |  Yes\\*\\*\\*| No   |   Yes   |\n\n\n  \\* Files persist across app restarts and upgrades, but this directory can\n     be cleared whenever the OS desires. Your app should be able to recreate any\n     content that might be deleted.\n\n\\*\\* Files may persist across app restarts, but do not rely on this behavior. Files\n     are not guaranteed to persist across updates. Your app should remove files from\n     this directory when it is applicable, as the OS does not guarantee when (or even\n     if) these files are removed.\n\n\\*\\*\\* The OS may clear the contents of this directory whenever it feels it is\n     necessary, but do not rely on this. You should clear this directory as\n     appropriate for your application.\n\n### Android File System Layout\n\n| Device Path                                     | `cordova.file.*`            | `AndroidExtraFileSystems` | r/w? | persistent? | OS clears | private |\n|:------------------------------------------------|:----------------------------|:--------------------------|:----:|:-----------:|:---------:|:-------:|\n| `file:///android_asset/`                        | applicationDirectory        |                           | r    |     N/A     |     N/A   |   Yes   |\n| `/data/data/<app-id>/`                          | applicationStorageDirectory | -                         | r/w  |     N/A     |     N/A   |   Yes   |\n| &nbsp;&nbsp;&nbsp;`cache`                       | cacheDirectory              | cache                     | r/w  |     Yes     |     Yes\\* |   Yes   |\n| &nbsp;&nbsp;&nbsp;`files`                       | dataDirectory               | files                     | r/w  |     Yes     |     No    |   Yes   |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`Documents` |                             | documents                 | r/w  |     Yes     |     No    |   Yes   |\n| `<sdcard>/`                                     | externalRootDirectory       | sdcard                    | r/w  |     Yes     |     No    |   No    |\n| &nbsp;&nbsp;&nbsp;`Android/data/<app-id>/`      | externalApplicationStorageDirectory | -                 | r/w  |     Yes     |     No    |   No    |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`cache`     | externalCacheDirectry       | cache-external            | r/w  |     Yes     |     No\\*\\*|   No    |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`files`     | externalDataDirectory       | files-external            | r/w  |     Yes     |     No    |   No    |\n\n\\* The OS may periodically clear this directory, but do not rely on this behavior. Clear\n   the contents of this directory as appropriate for your application. Should a user\n   purge the cache manually, the contents of this directory are removed.\n\n\\*\\* The OS does not clear this directory automatically; you are responsible for managing\n     the contents yourself. Should the user purge the cache manually, the contents of the\n     directory are removed.\n\n**Note**: If external storage can't be mounted, the `cordova.file.external*`\nproperties are `null`.\n\n### BlackBerry 10 File System Layout\n\n| Device Path                                                  | `cordova.file.*`            | r/w? | persistent? | OS clears | private |\n|:-------------------------------------------------------------|:----------------------------|:----:|:-----------:|:---------:|:-------:|\n| `file:///accounts/1000/appdata/<app id>/`                    | applicationStorageDirectory | r    |     N/A     |     N/A   |   Yes   |\n| &nbsp;&nbsp;&nbsp;`app/native`                               | applicationDirectory        | r    |     N/A     |     N/A   |   Yes   |\n| &nbsp;&nbsp;&nbsp;`data/webviews/webfs/temporary/local__0`   | cacheDirectory              | r/w  |     No      |     Yes   |   Yes   |\n| &nbsp;&nbsp;&nbsp;`data/webviews/webfs/persistent/local__0`  | dataDirectory               | r/w  |     Yes     |     No    |   Yes   |\n| `file:///accounts/1000/removable/sdcard`                     | externalRemovableDirectory  | r/w  |     Yes     |     No    |   No    |\n| `file:///accounts/1000/shared`                               | sharedDirectory             | r/w  |     Yes     |     No    |   No    |\n\n*Note*: When application is deployed to work perimeter, all paths are relative to /accounts/1000-enterprise.\n\n### OS X File System Layout\n\n| Device Path                                      | `cordova.file.*`            | `iosExtraFileSystems` | r/w? |  OS clears | private |\n|:-------------------------------------------------|:----------------------------|:----------------------|:----:|:---------:|:-------:|\n| `/Applications/<appname>.app/`                   | -                           | bundle                | r    |     N/A   |   Yes   |\n| &nbsp;&nbsp;&nbsp;&nbsp;`Content/Resources/`     | applicationDirectory        | -                     | r    |     N/A   |   Yes   |\n| `~/Library/Application Support/<bundle-id>/`     | applicationStorageDirectory | -                     | r/w  |     No    |   Yes   |\n| &nbsp;&nbsp;&nbsp;&nbsp;`files/`                 | dataDirectory               | -                     | r/w  |     No    |   Yes   |\n| `~/Documents/`                                   | documentsDirectory          | documents             | r/w  |     No    |    No   |\n| `~/Library/Caches/<bundle-id>/`                  | cacheDirectory              | cache                 | r/w  |     No    |   Yes   |\n| `/tmp/`                                          | tempDirectory               | -                     | r/w  |    Yes\\*  |   Yes   |\n| `/`                                              | rootDirectory               | root                  | r/w  |    No\\*\\* |    No   |\n\n**Note**: This is the layout for non sandboxed applications. I you enable sandboxing, the `applicationStorageDirectory` will be below ` ~/Library/Containers/<bundle-id>/Data/Library/Application Support`.\n\n\\* Files persist across app restarts and upgrades, but this directory can\n     be cleared whenever the OS desires. Your app should be able to recreate any\n     content that might be deleted. You should clear this directory as\n     appropriate for your application.\n\n\\*\\* Allows access to the entire file system. This is only available for non sandboxed apps.\n\n### Windows File System Layout\n\n| Device Path                                           | `cordova.file.*`            | r/w? | persistent? | OS clears | private |\n|:------------------------------------------------------|:----------------------------|:----:|:-----------:|:---------:|:-------:|\n| `ms-appdata:///`                                      | applicationDirectory        | r    |     N/A     |     N/A   |   Yes   |\n| &nbsp;&nbsp;&nbsp;`local/`                            | dataDirectory               | r/w  |     Yes     |     No    |   Yes   |\n| &nbsp;&nbsp;&nbsp;`temp/`                             | cacheDirectory              | r/w  |     No      |     Yes\\* |   Yes   |\n| &nbsp;&nbsp;&nbsp;`temp/`                             | tempDirectory               | r/w  |     No      |     Yes\\* |   Yes   |\n| &nbsp;&nbsp;&nbsp;`roaming/`                          | syncedDataDirectory         | r/w  |     Yes     |     No    |   Yes   |\n\n\\* The OS may periodically clear this directory\n\n\n## Android Quirks\n\n### Android Persistent storage location\n\nThere are multiple valid locations to store persistent files on an Android\ndevice. See [this page](http://developer.android.com/guide/topics/data/data-storage.html)\nfor an extensive discussion of the various possibilities.\n\nPrevious versions of the plugin would choose the location of the temporary and\npersistent files on startup, based on whether the device claimed that the SD\nCard (or equivalent storage partition) was mounted. If the SD Card was mounted,\nor if a large internal storage partition was available (such as on Nexus\ndevices,) then the persistent files would be stored in the root of that space.\nThis meant that all Cordova apps could see all of the files available on the\ncard.\n\nIf the SD card was not available, then previous versions would store data under\n`/data/data/<packageId>`, which isolates apps from each other, but may still\ncause data to be shared between users.\n\nIt is now possible to choose whether to store files in the internal file\nstorage location, or using the previous logic, with a preference in your\napplication's `config.xml` file. To do this, add one of these two lines to\n`config.xml`:\n\n    <preference name=\"AndroidPersistentFileLocation\" value=\"Internal\" />\n\n    <preference name=\"AndroidPersistentFileLocation\" value=\"Compatibility\" />\n\nWithout this line, the File plugin will use `Internal` as the default. If\na preference tag is present, and is not one of these values, the application\nwill not start.\n\nIf your application has previously been shipped to users, using an older (pre-\n3.0.0) version of this plugin, and has stored files in the persistent filesystem,\nthen you should set the preference to `Compatibility` if your config.xml does not specify a location for the persistent filesystem. Switching the location to\n\"Internal\" would mean that existing users who upgrade their application may be\nunable to access their previously-stored files, depending on their device.\n\nIf your application is new, or has never previously stored files in the\npersistent filesystem, then the `Internal` setting is generally recommended.\n\n### Slow recursive operations for /android_asset\n\nListing asset directories is really slow on Android. You can speed it up though, by\nadding `src/android/build-extras.gradle` to the root of your android project (also\nrequires cordova-android@4.0.0 or greater).\n\n## iOS Quirks\n\n- `cordova.file.applicationStorageDirectory` is read-only; attempting to store\n  files within the root directory will fail. Use one of the other `cordova.file.*`\n  properties defined for iOS (only `applicationDirectory` and `applicationStorageDirectory` are\n  read-only).\n- `FileReader.readAsText(blob, encoding)`\n  - The `encoding` parameter is not supported, and UTF-8 encoding is always in effect.\n\n### iOS Persistent storage location\n\nThere are two valid locations to store persistent files on an iOS device: the\nDocuments directory and the Library directory. Previous versions of the plugin\nonly ever stored persistent files in the Documents directory. This had the\nside-effect of making all of an application's files visible in iTunes, which\nwas often unintended, especially for applications which handle lots of small\nfiles, rather than producing complete documents for export, which is the\nintended purpose of the directory.\n\nIt is now possible to choose whether to store files in the documents or library\ndirectory, with a preference in your application's `config.xml` file. To do this,\nadd one of these two lines to `config.xml`:\n\n    <preference name=\"iosPersistentFileLocation\" value=\"Library\" />\n\n    <preference name=\"iosPersistentFileLocation\" value=\"Compatibility\" />\n\nWithout this line, the File plugin will use `Compatibility` as the default. If\na preference tag is present, and is not one of these values, the application\nwill not start.\n\nIf your application has previously been shipped to users, using an older (pre-\n1.0) version of this plugin, and has stored files in the persistent filesystem,\nthen you should set the preference to `Compatibility`. Switching the location to\n`Library` would mean that existing users who upgrade their application would be\nunable to access their previously-stored files.\n\nIf your application is new, or has never previously stored files in the\npersistent filesystem, then the `Library` setting is generally recommended.\n\n## Firefox OS Quirks\n\nThe File System API is not natively supported by Firefox OS and is implemented\nas a shim on top of indexedDB.\n\n* Does not fail when removing non-empty directories\n* Does not support metadata for directories\n* Methods `copyTo` and `moveTo` do not support directories\n\nThe following data paths are supported:\n* `applicationDirectory` - Uses `xhr` to get local files that are packaged with the app.\n* `dataDirectory` - For persistent app-specific data files.\n* `cacheDirectory` - Cached files that should survive app restarts (Apps should not rely\non the OS to delete files in here).\n\n## Browser Quirks\n\n### Common quirks and remarks\n- Each browser uses its own sandboxed filesystem. IE and Firefox use IndexedDB as a base.\nAll browsers use forward slash as directory separator in a path.\n- Directory entries have to be created successively.\nFor example, the call `fs.root.getDirectory('dir1/dir2', {create:true}, successCallback, errorCallback)`\nwill fail if dir1 did not exist.\n- The plugin requests user permission to use persistent storage at the application first start.\n- Plugin supports `cdvfile://localhost` (local resources) only. I.e. external resources are not supported via `cdvfile`.\n- The plugin does not follow [\"File System API 8.3 Naming restrictions\"](http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions).\n- Blob and File' `close` function is not supported.\n- `FileSaver` and `BlobBuilder` are not supported by this plugin and don't have stubs.\n- The plugin does not support `requestAllFileSystems`. This function is also missing in the specifications.\n- Entries in directory will not be removed if you use `create: true` flag for existing directory.\n- Files created via constructor are not supported. You should use entry.file method instead.\n- Each browser uses its own form for blob URL references.\n- `readAsDataURL` function is supported, but the mediatype in Chrome depends on entry name extension,\nmediatype in IE is always empty (which is the same as `text-plain` according the specification),\nthe mediatype in Firefox is always `application/octet-stream`.\nFor example, if the content is `abcdefg` then Firefox returns `data:application/octet-stream;base64,YWJjZGVmZw==`,\nIE returns `data:;base64,YWJjZGVmZw==`, Chrome returns `data:<mediatype depending on extension of entry name>;base64,YWJjZGVmZw==`.\n- `toInternalURL` returns the path in the form `file:///persistent/path/to/entry` (Firefox, IE).\nChrome returns the path in the form `cdvfile://localhost/persistent/file`.\n\n### Chrome quirks\n- Chrome filesystem is not immediately ready after device ready event. As a workaround you can subscribe to `filePluginIsReady` event.\nExample:\n```javascript\nwindow.addEventListener('filePluginIsReady', function(){ console.log('File plugin is ready');}, false);\n```\nYou can use `window.isFilePluginReadyRaised` function to check whether event was already raised.\n- window.requestFileSystem TEMPORARY and PERSISTENT filesystem quotas are not limited in Chrome.\n- To increase persistent storage in Chrome you need to call `window.initPersistentFileSystem` method. Persistent storage quota is 5 MB by default.\n- Chrome requires `--allow-file-access-from-files` run argument to support API via `file:///` protocol.\n- `File` object will be not changed if you use flag `{create:true}` when getting an existing `Entry`.\n- events `cancelable` property is set to true in Chrome. This is contrary to the [specification](http://dev.w3.org/2009/dap/file-system/file-writer.html).\n- `toURL` function in Chrome returns `filesystem:`-prefixed path depending on application host.\nFor example, `filesystem:file:///persistent/somefile.txt`, `filesystem:http://localhost:8080/persistent/somefile.txt`.\n- `toURL` function result does not contain trailing slash in case of directory entry.\nChrome resolves directories with slash-trailed urls correctly though.\n- `resolveLocalFileSystemURL` method requires the inbound `url` to have `filesystem` prefix. For example, `url` parameter for `resolveLocalFileSystemURL`\nshould be in the form `filesystem:file:///persistent/somefile.txt` as opposed to the form `file:///persistent/somefile.txt` in Android.\n- Deprecated `toNativeURL` function is not supported and does not have a stub.\n- `setMetadata` function is not stated in the specifications and not supported.\n- INVALID_MODIFICATION_ERR (code: 9) is thrown instead of SYNTAX_ERR(code: 8) on requesting of a non-existant filesystem.\n- INVALID_MODIFICATION_ERR (code: 9) is thrown instead of PATH_EXISTS_ERR(code: 12) on trying to exclusively create a file or directory, which already exists.\n- INVALID_MODIFICATION_ERR (code: 9) is thrown instead of  NO_MODIFICATION_ALLOWED_ERR(code: 6) on trying to call removeRecursively on the root file system.\n- INVALID_MODIFICATION_ERR (code: 9) is thrown instead of NOT_FOUND_ERR(code: 1) on trying to moveTo directory that does not exist.\n\n### IndexedDB-based impl quirks (Firefox and IE)\n- `.` and `..` are not supported.\n- IE does not support `file:///`-mode; only hosted mode is supported (http://localhost:xxxx).\n- Firefox filesystem size is not limited but each 50MB extension will request a user permission.\nIE10 allows up to 10mb of combined AppCache and IndexedDB used in implementation of filesystem without prompting,\nonce you hit that level you will be asked if you want to allow it to be increased up to a max of 250mb per site.\nSo `size` parameter for `requestFileSystem` function does not affect filesystem in Firefox and IE.\n- `readAsBinaryString` function is not stated in the Specs and not supported in IE and does not have a stub.\n- `file.type` is always null.\n- You should not create entry using DirectoryEntry instance callback result which was deleted.\nOtherwise, you will get a 'hanging entry'.\n- Before you can read a file, which was just written you need to get a new instance of this file.\n- `setMetadata` function, which is not stated in the Specs supports `modificationTime` field change only.\n- `copyTo` and `moveTo` functions do not support directories.\n- Directories metadata is not supported.\n- Both Entry.remove and directoryEntry.removeRecursively don't fail when removing\nnon-empty directories - directories being removed are cleaned along with contents instead.\n- `abort` and `truncate` functions are not supported.\n- progress events are not fired. For example, this handler will be not executed:\n```javascript\nwriter.onprogress = function() { /*commands*/ };\n```\n\n## Upgrading Notes\n\nIn v1.0.0 of this plugin, the `FileEntry` and `DirectoryEntry` structures have changed,\nto be more in line with the published specification.\n\nPrevious (pre-1.0.0) versions of the plugin stored the device-absolute-file-location\nin the `fullPath` property of `Entry` objects. These paths would typically look like\n\n    /var/mobile/Applications/<application UUID>/Documents/path/to/file  (iOS)\n    /storage/emulated/0/path/to/file                                    (Android)\n\nThese paths were also returned by the `toURL()` method of the `Entry` objects.\n\nWith v1.0.0, the `fullPath` attribute is the path to the file, _relative to the root of\nthe HTML filesystem_. So, the above paths would now both be represented by a `FileEntry`\nobject with a `fullPath` of\n\n    /path/to/file\n\nIf your application works with device-absolute-paths, and you previously retrieved those\npaths through the `fullPath` property of `Entry` objects, then you should update your code\nto use `entry.toURL()` instead.\n\nFor backwards compatibility, the `resolveLocalFileSystemURL()` method will accept a\ndevice-absolute-path, and will return an `Entry` object corresponding to it, as long as that\nfile exists within either the `TEMPORARY` or `PERSISTENT` filesystems.\n\nThis has particularly been an issue with the File-Transfer plugin, which previously used\ndevice-absolute-paths (and can still accept them). It has been updated to work correctly\nwith FileSystem URLs, so replacing `entry.fullPath` with `entry.toURL()` should resolve any\nissues getting that plugin to work with files on the device.\n\nIn v1.1.0 the return value of `toURL()` was changed (see [CB-6394](https://issues.apache.org/jira/browse/CB-6394))\nto return an absolute 'file://' URL. wherever possible. To ensure a 'cdvfile:'-URL you can use `toInternalURL()` now.\nThis method will now return filesystem URLs of the form\n\n    cdvfile://localhost/persistent/path/to/file\n\nwhich can be used to identify the file uniquely.\n\n## cdvfile protocol\n**Purpose**\n\n`cdvfile://localhost/persistent|temporary|another-fs-root*/path/to/file` can be used for platform-independent file paths.\ncdvfile paths are supported by core plugins - for example you can download an mp3 file to cdvfile-path via `cordova-plugin-file-transfer` and play it via `cordova-plugin-media`.\n\n__*Note__: See [Where to Store Files](#where-to-store-files), [File System Layouts](#file-system-layouts) and [Configuring the Plugin](#configuring-the-plugin-optional) for more details about available fs roots.\n\nTo use `cdvfile` as a tag' `src` you can convert it to native path via `toURL()` method of the resolved fileEntry, which you can get via `resolveLocalFileSystemURL` - see examples below.\n\nYou can also use `cdvfile://` paths directly in the DOM, for example:\n```HTML\n<img src=\"cdvfile://localhost/persistent/img/logo.png\" />\n```\n\n__Note__: This method requires following Content Security rules updates:\n* Add `cdvfile:` scheme to `Content-Security-Policy` meta tag of the index page, e.g.:\n  - `<meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self' data: gap: `**cdvfile:**` https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *\">`\n* Add `<access origin=\"cdvfile://*\" />` to `config.xml`.\n\n**Converting cdvfile:// to native path**\n\n```javascript\nresolveLocalFileSystemURL('cdvfile://localhost/temporary/path/to/file.mp4', function(entry) {\n    var nativePath = entry.toURL();\n    console.log('Native URI: ' + nativePath);\n    document.getElementById('video').src = nativePath;\n```\n\n**Converting native path to cdvfile://**\n\n```javascript\nresolveLocalFileSystemURL(nativePath, function(entry) {\n    console.log('cdvfile URI: ' + entry.toInternalURL());\n```\n\n**Using cdvfile in core plugins**\n\n```javascript\nfileTransfer.download(uri, 'cdvfile://localhost/temporary/path/to/file.mp3', function (entry) { ...\n```\n```javascript\nvar my_media = new Media('cdvfile://localhost/temporary/path/to/file.mp3', ...);\nmy_media.play();\n```\n\n#### cdvfile quirks\n- Using `cdvfile://` paths in the DOM is not supported on Windows platform (a path can be converted to native instead).\n\n\n## List of Error Codes and Meanings\nWhen an error is thrown, one of the following codes will be used.\n\n| Code | Constant                      |\n|-----:|:------------------------------|\n|    1 | `NOT_FOUND_ERR`               |\n|    2 | `SECURITY_ERR`                |\n|    3 | `ABORT_ERR`                   |\n|    4 | `NOT_READABLE_ERR`            |\n|    5 | `ENCODING_ERR`                |\n|    6 | `NO_MODIFICATION_ALLOWED_ERR` |\n|    7 | `INVALID_STATE_ERR`           |\n|    8 | `SYNTAX_ERR`                  |\n|    9 | `INVALID_MODIFICATION_ERR`    |\n|   10 | `QUOTA_EXCEEDED_ERR`          |\n|   11 | `TYPE_MISMATCH_ERR`           |\n|   12 | `PATH_EXISTS_ERR`             |\n\n## Configuring the Plugin (Optional)\n\nThe set of available filesystems can be configured per-platform. Both iOS and\nAndroid recognize a <preference> tag in `config.xml` which names the\nfilesystems to be installed. By default, all file-system roots are enabled.\n\n    <preference name=\"iosExtraFilesystems\" value=\"library,library-nosync,documents,documents-nosync,cache,bundle,root\" />\n    <preference name=\"AndroidExtraFilesystems\" value=\"files,files-external,documents,sdcard,cache,cache-external,root\" />\n\n### Android\n\n* `files`: The application's internal file storage directory\n* `files-external`: The application's external file storage directory\n* `sdcard`: The global external file storage directory (this is the root of the SD card, if one is installed). You must have the `android.permission.WRITE_EXTERNAL_STORAGE` permission to use this.\n* `cache`: The application's internal cache directory\n* `cache-external`: The application's external cache directory\n* `root`: The entire device filesystem\n\nAndroid also supports a special filesystem named \"documents\", which represents a \"/Documents/\" subdirectory within the \"files\" filesystem.\n\n### iOS\n\n* `library`: The application's Library directory\n* `documents`: The application's Documents directory\n* `cache`: The application's Cache directory\n* `bundle`: The application's bundle; the location of the app itself on disk (read-only)\n* `root`: The entire device filesystem\n\nBy default, the library and documents directories can be synced to iCloud. You can also request two additional filesystems, `library-nosync` and `documents-nosync`, which represent a special non-synced directory within the `/Library` or `/Documents` filesystem.\n"
  },
  {
    "path": "plugins/cordova-plugin-file/RELEASENOTES.md",
    "content": "<!--\n#\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n# \n# http://www.apache.org/licenses/LICENSE-2.0\n# \n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#  KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n#\n-->\n# Release Notes\n\n### 4.2.0 (Apr 15, 2016)\n* CB-10960 Uncaught `#<FileError>` in `write()` when `readyState != WRITING ?`\n* Replace `PermissionHelper.java` with `cordova-plugin-compat`\n* CB-10977 **Android** Removing global state used for permission requests\n* CB-10798, CB-10384 Fixing permissions for **Marshmallow**.\n* Fix test failure on **WP 8.1**\n* CB-10577 **Windows** `resolveLocalFileSystemURL` should omit trailing slash for file\n* CB-7862 `FileReader` reads large files in chunks with progress.\n* CB-10577 **Android** `resolveLocalFileSystemURL` should detect directory vs file.\n* CB-9753 index out of bounds on `requestFileSystem`.\n* Remove `warning` emoji, as it doesn't correctly display in the docs website: cordova.apache.org/docs/en/dev/cordova-plugin-file/index.html. This closes #166\n* CB-10636 Add `JSHint` for plugins\n* CB-10411 Error in `file.spec.129` of `cordova-plugin-file`\n\n### 4.1.1 (Feb 09, 2016)\n* Edit package.json license to match SPDX id\n* [CB-10419](https://issues.apache.org/jira/browse/CB-10419) cordova-plugin-file 4.0.0 error with browserify workflow\n\n### 4.1.0 (Jan 15, 2016)\n* added `.ratignore` file\n* CB-10319 **android** Adding reflective helper methods for permission requests\n* CB-10023 Fix `proxy not found error` on Chrome.\n* CB-8863 **ios** Fix block usage of self\n\n### 4.0.0 (Nov 18, 2015)\n* [CB-10035](https://issues.apache.org/jira/browse/CB-10035) Updated `RELEASENOTES` to be newest to oldest\n* [CB-8497](https://issues.apache.org/jira/browse/CB-8497) Fix handling of file paths with `#` character\n* Do not inject default `AndroidPersistentFileLocation` into `config.xml`\n* [CB-9891](https://issues.apache.org/jira/browse/CB-9891): Fix permission errors due to `URI encoding` inconsistency on **Android**\n* Fixed `NullPointer Exception` in **Android 5** and above due to invalid column name on cursor\n* Fix default persistent file location\n* fix `applicationDirectory` to use `ms-appx:///`\n* Add **Windows** paths to `cordova.file` object\n* [CB-9851](https://issues.apache.org/jira/browse/CB-9851) Document `cdvfile` protocol quirk - using `cdvfile://` in the `DOM` is not supported on **Windows**\n* [CB-9752](https://issues.apache.org/jira/browse/CB-9752) `getDirectory` fails on valid directory with assets filesystem\n* [CB-7253](https://issues.apache.org/jira/browse/CB-7253) `requestFileSystem` fails when no external storage is present\n* Adding permissions for **Marshmallow**. Now supports **Anrdoid 6.0**\n* Fixing contribute link.\n* always use setters to fix memory issues without `ARC` for **iOS**\n* [CB-9331](https://issues.apache.org/jira/browse/CB-9331) `getFreeDiskSpace` **iOS**.\n* override `resolveLocalFileSystemURL` by `webkitResolveLocalFileSystemURL` for **browser** platform add `.project` into git ignore list\n* Fail with `FileError.ENCODING_ERR` on encoding exception.\n* [CB-9544](https://issues.apache.org/jira/browse/CB-9544) Add file plugin for **OSX**\n* [CB-9539](https://issues.apache.org/jira/browse/CB-9539) Fixed test failure on **Android** emulator\n* Added docs on `CSP` rules needed for using `cdvfile` in DOM src. This closes #120\n* Added `cdvfile` protocol purpose description and examples\n\n### 3.0.0 (Aug 18, 2015)\n* Make Android default persistent file location internal\n* Fixed issue with file paths not existing when using browserify\n* [CB-9251](https://issues.apache.org/jira/browse/CB-9251): Changed from Intents to Preferences object as per the issue\n* [CB-9215](https://issues.apache.org/jira/browse/CB-9215) Add cordova-plugin-file manual test for windows platform\n\n### 2.1.0 (Jun 17, 2015)\n* added missing license header\n* [CB-9128](https://issues.apache.org/jira/browse/CB-9128) cordova-plugin-file documentation translation: cordova-plugin-file\n* fix npm md\n* [CB-8844](https://issues.apache.org/jira/browse/CB-8844) Increased timeout for asset tests\n* Updated resolveFileSystem.js so it can be parsed by uglifyJS\n* [CB-8860](https://issues.apache.org/jira/browse/CB-8860) cordova-plugin-file documentation translation: cordova-plugin-file\n* [CB-8792](https://issues.apache.org/jira/browse/CB-8792) Fixes reading of json files using readAsText\n\n### 2.0.0 (Apr 15, 2015)\n* [CB-8849](https://issues.apache.org/jira/browse/CB-8849) Fixed ReadAsArrayBuffer to return ArrayBuffer and not Array on WP8\n* [CB-8819](https://issues.apache.org/jira/browse/CB-8819) Fixed FileReader's readAsBinaryString on wp8\n* [CB-8746](https://issues.apache.org/jira/browse/CB-8746) gave plugin major version bump\n* [CB-8683](https://issues.apache.org/jira/browse/CB-8683) android: Fix broken unit tests from plugin rename\n* [CB-8683](https://issues.apache.org/jira/browse/CB-8683) changed plugin-id to pacakge-name\n* [CB-8653](https://issues.apache.org/jira/browse/CB-8653) properly updated translated docs to use new id\n* [CB-8653](https://issues.apache.org/jira/browse/CB-8653) updated translated docs to use new id\n* Use TRAVIS_BUILD_DIR, install paramedic by npm\n* docs: added Windows to supported platforms\n* [CB-8699](https://issues.apache.org/jira/browse/CB-8699) [CB-6428](https://issues.apache.org/jira/browse/CB-6428) Fix uncompressed assets being copied as zero length files\n* [CB-6428](https://issues.apache.org/jira/browse/CB-6428) android: Fix assets FileEntry having size of -1\n* android: Move URLforFullPath into base class (and rename to localUrlforFullPath)\n* [CB-6428](https://issues.apache.org/jira/browse/CB-6428) Mention build-extras.gradle in README\n* [CB-7109](https://issues.apache.org/jira/browse/CB-7109) android: Parse arguments off of the main thread (close #97)\n* [CB-8695](https://issues.apache.org/jira/browse/CB-8695) ios: Fix `blob.slice()` for `asset-library` URLs (close #105)\n* Tweak build-extras.gradle to just read/write to main `assets/` instead of `build/`\n* [CB-8689](https://issues.apache.org/jira/browse/CB-8689) Fix NPE in makeEntryForNativeUri (was affecting file-transfer)\n* [CB-8675](https://issues.apache.org/jira/browse/CB-8675) Revert \"CB-8351 ios: Use base64EncodedStringWithOptions instead of CordovaLib's class extension\"\n* [CB-8653](https://issues.apache.org/jira/browse/CB-8653) Updated Readme\n* [CB-8659](https://issues.apache.org/jira/browse/CB-8659): ios: 4.0.x Compatibility: Remove use of initWebView method\n* Add a cache to speed up AssetFilesystem directory listings\n* [CB-8663](https://issues.apache.org/jira/browse/CB-8663) android: Don't notify MediaScanner of private files\n* Don't log stacktrace for normal exceptions (e.g. file not found)\n* android: Don't use LimitedInputStream when reading entire file (optimization)\n* [CB-6428](https://issues.apache.org/jira/browse/CB-6428) android: Add support for directory copies from assets -> filesystem\n* android: Add `listChildren()`: Java-consumable version of `readEntriesAtLocalURL()`\n* [CB-6428](https://issues.apache.org/jira/browse/CB-6428) android: Add support for file:///android_asset URLs\n* [CB-8642](https://issues.apache.org/jira/browse/CB-8642) android: Fix content URIs not working with resolve / copy\n* Tweak tests to fail if deleteEntry fails (rather than time out)\n* android: Ensure LocalFilesystemURL can only be created with \"cdvfile\" URLs\n* android: Move CordovaResourceApi into Filesystem base class\n* android: Use `CordovaResourceApi.mapUriToFile()` rather than own custom logic in ContentFilesystem\n* android: Use Uri.parse rather than manual parsing in resolveLocalFileSystemURI\n* Tweak test case that failed twice on error rather than just once\n* android: Delete invalid JavaDoc (lint errors)\n* android: Use CordovaResourceApi rather than FileHelper\n* [CB-8032](https://issues.apache.org/jira/browse/CB-8032) - File Plugin - Add nativeURL external method support for CDVFileSystem->makeEntryForPath:isDirectory: (closes #96)\n* [CB-8567](https://issues.apache.org/jira/browse/CB-8567) Integrate TravisCI\n* [CB-8438](https://issues.apache.org/jira/browse/CB-8438) cordova-plugin-file documentation translation: cordova-plugin-file\n* [CB-8538](https://issues.apache.org/jira/browse/CB-8538) Added package.json file\n* [CB-7956](https://issues.apache.org/jira/browse/CB-7956) Add cordova-plugin-file support for browser platform\n* [CB-8423](https://issues.apache.org/jira/browse/CB-8423) Corrected usage of done() in async tests\n* [CB-8459](https://issues.apache.org/jira/browse/CB-8459) Fixes spec 111 failure due to incorrect relative paths handling\n* Code cleanup, whitespace\n* Added nativeURL property to FileEntry, implemented readAsArrayBuffer and readAsBinaryString\n\n### 1.3.3 (Feb 04, 2015)\n* [CB-7927](https://issues.apache.org/jira/browse/CB-7927) Encoding data to bytes instead of chars when writing a file.\n* ios: Fix compile warning about implicit int conversion\n* [CB-8351](https://issues.apache.org/jira/browse/CB-8351) ios: Use base64EncodedStringWithOptions instead of CordovaLib's class extension\n* [CB-8351](https://issues.apache.org/jira/browse/CB-8351) ios: Use argumentForIndex rather than NSArray extension\n* [CB-8351](https://issues.apache.org/jira/browse/CB-8351) ios: Use a local copy of valueForKeyIsNumber rather than CordovaLib's version\n* windows: Handle url's containing absolute windows path starting with drive letter and colon (encoded as %3A) through root FS\n* windows: Rework to use normal url form\n* android: refactor: Make Filesystem base class store its own name, rootUri, and rootEntry\n* android: Simplify code a bit by making makeEntryForPath not throw JSONException\n* [CB-6431](https://issues.apache.org/jira/browse/CB-6431) android: Fix plugin breaking content: URLs\n* [CB-7375](https://issues.apache.org/jira/browse/CB-7375) Never create new FileSystem instances (except on windows since they don't implement requestAllFileSystems())\n\n### 1.3.2 (Dec 02, 2014)\n* Gets rid of thread block error in File plugin\n* [CB-7917](https://issues.apache.org/jira/browse/CB-7917) Made tests file.spec.114 - 116 pass for **Windows** platform\n* [CB-7977](https://issues.apache.org/jira/browse/CB-7977) Mention `deviceready` in plugin docs\n* [CB-7602](https://issues.apache.org/jira/browse/CB-7602): Fix `isCopyOnItself` logic\n* [CB-7700](https://issues.apache.org/jira/browse/CB-7700) cordova-plugin-file documentation translation: cordova-plugin-file\n* Use one proxy for both **Windows** and **Windows8** platforms\n* [CB-6994](https://issues.apache.org/jira/browse/CB-6994) Fixes result, returned by proxy's write method\n* [fxos] update `__format__` to match `pathsPrefix`\n* [CB-6994](https://issues.apache.org/jira/browse/CB-6994) Improves merged code to be able to write a File\n* Optimize `FileProxy` for **Windows** platforms\n* Synchronize changes with **Windows** platform\n* Fix function write for big files on **Windows 8**\n* Write file in background\n* [CB-7487](https://issues.apache.org/jira/browse/CB-7487) **Android** Broadcast file write This allows MTP USB shares to show the file immediately without reboot/manual refresh using 3rd party app.\n* [CB-7700](https://issues.apache.org/jira/browse/CB-7700) cordova-plugin-file documentation translation: cordova-plugin-file\n* [CB-7571](https://issues.apache.org/jira/browse/CB-7571) Bump version of nested plugin to match parent plugin\n\n### 1.3.1 (Sep 17, 2014)\n* [CB-7471](https://issues.apache.org/jira/browse/CB-7471) cordova-plugin-file documentation translation\n* [CB-7272](https://issues.apache.org/jira/browse/CB-7272) Replace confusing \"r/o\" abbreviation with just \"r\"\n* [CB-7423](https://issues.apache.org/jira/browse/CB-7423) encode path before attempting to resolve\n* [CB-7375](https://issues.apache.org/jira/browse/CB-7375) Fix the filesystem name in resolveLocalFileSystemUri\n* [CB-7445](https://issues.apache.org/jira/browse/CB-7445) [BlackBerry10] resolveLocalFileSystemURI - change DEFAULT_SIZE to MAX_SIZE\n* [CB-7458](https://issues.apache.org/jira/browse/CB-7458) [BlackBerry10] resolveLocalFileSystemURL - add filesystem property\n* [CB-7445](https://issues.apache.org/jira/browse/CB-7445) [BlackBerry10] Add default file system size to prevent quota exceeded error on initial install\n* [CB-7431](https://issues.apache.org/jira/browse/CB-7431) Avoid calling done() twice in file.spec.109 test\n* [CB-7413](https://issues.apache.org/jira/browse/CB-7413) Adds support of 'ms-appdata://' URIs\n* [CB-7422](https://issues.apache.org/jira/browse/CB-7422) [File Tests] Use proper fileSystem to create fullPath\n* [CB-7375](https://issues.apache.org/jira/browse/CB-7375) [Entry] get proper filesystem in Entry\n* Amazon related changes.\n* [CB-7375](https://issues.apache.org/jira/browse/CB-7375) Remove leading slash statement from condition\n* Refactored much of the logic in FileMetadata constructor.  Directory.size will return 0\n* [CB-7419](https://issues.apache.org/jira/browse/CB-7419) [WP8] Added support to get metada from dir\n* [CB-7418](https://issues.apache.org/jira/browse/CB-7418) [DirectoryEntry] Added fullPath variable as part of condition\n* [CB-7417](https://issues.apache.org/jira/browse/CB-7417) [File tests] added proper matcher to compare fullPath property\n* [CB-7375](https://issues.apache.org/jira/browse/CB-7375) Partial revert to resolve WP8 failures\n* Overwrite existing file on getFile when create is true\n* [CB-7375](https://issues.apache.org/jira/browse/CB-7375) [CB-6148](https://issues.apache.org/jira/browse/CB-6148): Ensure that return values from copy and move operations reference the correct filesystem\n* [CB-6724](https://issues.apache.org/jira/browse/CB-6724) changed style detail on documentation\n* Added new js files to amazon-fireos platform.\n* Adds Windows platform\n* Fixes multiple mobilespec tests errors\n* Removed test/tests.js module from main plugin.xml\n* [CB-7094](https://issues.apache.org/jira/browse/CB-7094) renamed folder to tests + added nested plugin.xml\n* added documentation for manual tests\n* [CB-6923](https://issues.apache.org/jira/browse/CB-6923) Adding support to handle relative paths\n* Style improvements on Manual tests\n* [CB-7094](https://issues.apache.org/jira/browse/CB-7094) Ported File manual tests\n\n### 1.3.0 (Aug 06, 2014)\n* **FFOS** Remove unsupported paths from requestAllPaths\n* **FFOS** Support for resolve URI, request all paths and local app directory.\n* [CB-4263](https://issues.apache.org/jira/browse/CB-4263) set ready state to done before onload\n* [CB-7167](https://issues.apache.org/jira/browse/CB-7167) [BlackBerry10] copyTo - return wrapped entry rather than native\n* [CB-7167](https://issues.apache.org/jira/browse/CB-7167) [BlackBerry10] Add directory support to getFileMetadata\n* [CB-7167](https://issues.apache.org/jira/browse/CB-7167) [BlackBerry10] Fix tests detection of blob support (window.Blob is BlobConstructor object)\n* [CB-7161](https://issues.apache.org/jira/browse/CB-7161) [BlackBerry10] Add file system directory paths\n* [CB-7093](https://issues.apache.org/jira/browse/CB-7093) Create separate plugin.xml for new-style tests\n* [CB-7057](https://issues.apache.org/jira/browse/CB-7057) Docs update: elaborate on what directories are for\n* [CB-7093](https://issues.apache.org/jira/browse/CB-7093): Undo the effects of an old bad S&R command\n* [CB-7093](https://issues.apache.org/jira/browse/CB-7093): Remove a bunch of unneeded log messages\n* [CB-7093](https://issues.apache.org/jira/browse/CB-7093): Add JS module to plugin.xml file for auto-tests\n* [CB-7093](https://issues.apache.org/jira/browse/CB-7093) Ported automated file tests\n* **WINDOWS** remove extra function closure, not    needed\n* **WINDOWS** remove check for undefined fail(), it is defined by the proxy and always exists\n* **WINDOWS** re-apply readAsBinaryString and readAsArrayBuffer\n* **WINDOWS** Moved similar calls to be the same calls, aliased long namespaced functions\n* [CB-6127](https://issues.apache.org/jira/browse/CB-6127) Updated translations for docs.\n* [CB-6571](https://issues.apache.org/jira/browse/CB-6571) Fix getParentForLocalURL to work correctly with directories with trailing '/' (This closes #58)\n* UTTypeCopyPreferredTagWithClass returns nil mimetype for css when there is no network\n* updated spec links in docs ( en only )\n* [CB-6571](https://issues.apache.org/jira/browse/CB-6571) add trailing space it is missing in DirectoryEnty constructor.\n* [CB-6980](https://issues.apache.org/jira/browse/CB-6980) Fixing filesystem:null property in Entry\n* Add win8 support for readAsBinaryString and readAsArrayBuffer\n* [FFOS] Update FileProxy.js\n* [CB-6940](https://issues.apache.org/jira/browse/CB-6940): Fixing up commit from dzeims\n* [CB-6940](https://issues.apache.org/jira/browse/CB-6940): Android: cleanup try/catch exception handling\n* [CB-6940](https://issues.apache.org/jira/browse/CB-6940): `context.getExternal*` methods return null if sdcard isn't in mounted state, causing exceptions that prevent startup from reaching readystate\n* Fix mis-handling of filesystem reference in Entry.moveTo ('this' used in closure).\n* [CB-6902](https://issues.apache.org/jira/browse/CB-6902): Use File.lastModified rather than .lastModifiedDate\n* [CB-6922](https://issues.apache.org/jira/browse/CB-6922): Remove unused getMetadata native code\n* [CB-6922](https://issues.apache.org/jira/browse/CB-6922): Use getFileMetadata consistently to get metadata\n* changed fullPath to self.rootDocsPath\n* [CB-6890](https://issues.apache.org/jira/browse/CB-6890): Fix pluginManager access for 4.0.x branch\n\n### 1.2.1\n* [CB-6922](https://issues.apache.org/jira/browse/CB-6922) Fix inconsistent handling of lastModifiedDate and modificationTime\n* [CB-285](https://issues.apache.org/jira/browse/CB-285): Document filesystem root properties\n\n### 1.2.0 (Jun 05, 2014)\n* [CB-6127](https://issues.apache.org/jira/browse/CB-6127) Spanish and French Translations added. Github close #31\n* updated this reference to window\n* Add missing semicolon (copy & paste error)\n* Fix compiler warning about symbol in interface not matching implementation\n* Fix sorting order in supported platforms\n* ubuntu: increase quota value\n* ubuntu: Change FS URL scheme to 'cdvfile'\n* ubuntu: Return size with Entry.getMetadata() method\n* [CB-6803](https://issues.apache.org/jira/browse/CB-6803) Add license\n* Initial implementation for Firefox OS\n* Small wording tweaks\n* Fixed toURL() toInternalURL() information in the doku\n* ios: Don't fail a write of zero-length payload.\n* [CB-285](https://issues.apache.org/jira/browse/CB-285) Docs for cordova.file.\\*Directory properties\n* [CB-285](https://issues.apache.org/jira/browse/CB-285) Add cordova.file.\\*Directory properties for iOS & Android\n* [CB-3440](https://issues.apache.org/jira/browse/CB-3440) [BlackBerry10] Proxy based implementation\n* Fix typo in docs \"app-bundle\" -> \"bundle\"\n* [CB-6583](https://issues.apache.org/jira/browse/CB-6583) ios: Fix failing to create entry when space in parent path\n* [CB-6571](https://issues.apache.org/jira/browse/CB-6571) android: Make DirectoryEntry.toURL() have a trailing /\n* [CB-6491](https://issues.apache.org/jira/browse/CB-6491) add CONTRIBUTING.md\n* [CB-6525](https://issues.apache.org/jira/browse/CB-6525) android, ios: Allow file: URLs in all APIs. Fixes FileTransfer.download not being called.\n* fix the Windows 8  implementation of the getFile method\n* Update File.js for typo: lastModifiedData --> lastModifiedDate (closes #38)\n* Add error codes.\n* [CB-5980](https://issues.apache.org/jira/browse/CB-5980) Updated version and RELEASENOTES.md for release 1.0.0\n* Add NOTICE file\n* [CB-6114](https://issues.apache.org/jira/browse/CB-6114) Updated version and RELEASENOTES.md for release 1.0.1\n* [CB-5980](https://issues.apache.org/jira/browse/CB-5980) Updated version and RELEASENOTES.md for release 1.0.0\n\n### 1.1.0 (Apr 17, 2014)\n* [CB-4965](https://issues.apache.org/jira/browse/CB-4965): Remove tests from file plugin\n* Android: Allow file:/ URLs\n* [CB-6422](https://issues.apache.org/jira/browse/CB-6422): [windows8] use cordova/exec/proxy\n* [CB-6249](https://issues.apache.org/jira/browse/CB-6249): [android] Opportunistically resolve content urls to file\n* [CB-6394](https://issues.apache.org/jira/browse/CB-6394): [ios, android] Add extra filesystem roots\n* [CB-6394](https://issues.apache.org/jira/browse/CB-6394): [ios, android] Fix file resolution for the device root case\n* [CB-6394](https://issues.apache.org/jira/browse/CB-6394): [ios] Return ENCODING_ERR when fs name is not valid\n* [CB-6393](https://issues.apache.org/jira/browse/CB-6393): Change behaviour of toURL and toNativeURL\n* ios: Style: plugin initialization\n* ios: Fix handling of file URLs with encoded spaces\n* Always use Android's recommended temp file location for temporary file system\n* [CB-6352](https://issues.apache.org/jira/browse/CB-6352): Allow FileSystem objects to be serialized to JSON\n* [CB-5959](https://issues.apache.org/jira/browse/CB-5959): size is explicitly 0 if not set, file.spec.46&47 are testing the type of size\n* [CB-6242](https://issues.apache.org/jira/browse/CB-6242): [BlackBerry10] Add deprecated version of resolveLocalFileSystemURI\n* [CB-6242](https://issues.apache.org/jira/browse/CB-6242): [BlackBerry10] add file:/// prefix for toURI / toURL\n* [CB-6242](https://issues.apache.org/jira/browse/CB-6242): [BlackBerry10] Polyfill window.requestAnimationFrame for OS < 10.2\n* [CB-6242](https://issues.apache.org/jira/browse/CB-6242): [BlackBerry10] Override window.resolveLocalFileSystemURL\n* [CB-6212](https://issues.apache.org/jira/browse/CB-6212): [iOS] fix warnings compiled under arm64 64-bit\n* ios: Don't cache responses from CDVFile's URLProtocol\n* [CB-6199](https://issues.apache.org/jira/browse/CB-6199): [iOS] Fix toNativeURL() not escaping characters properly\n* [CB-6148](https://issues.apache.org/jira/browse/CB-6148): Fix cross-filesystem copy and move\n* fixed setMetadata() to use the formatted fullPath\n* corrected typo which leads to a \"comma expression\"\n* [CB-4952](https://issues.apache.org/jira/browse/CB-4952): ios: Resolve symlinks in file:// URLs\n* Add docs about the extraFileSystems preference\n* [CB-6460](https://issues.apache.org/jira/browse/CB-6460): Update license headers\n\n### 1.0.1 (Feb 28, 2014)\n* [CB-6116](https://issues.apache.org/jira/browse/CB-6116) Fix error where resolveLocalFileSystemURL would fail\n* [CB-6106](https://issues.apache.org/jira/browse/CB-6106) Add support for nativeURL attribute on Entry objects\n* [CB-6110](https://issues.apache.org/jira/browse/CB-6110) iOS: Fix typo in filesystemPathForURL: method\n* Android: Use most specific FS match when resolving file: URIs\n* iOS: Update fileSystemURLforLocalPath: to return the most match url.\n* Allow third-party plugin registration, and the total count of fs type is not limited to just 4.\n* [CB-6097](https://issues.apache.org/jira/browse/CB-6097) Added missing files for amazon-fireos platform. Added onLoad flag to true.\n* [CB-6087](https://issues.apache.org/jira/browse/CB-6087) Android, iOS: Load file plugin on startup\n* [CB-6013](https://issues.apache.org/jira/browse/CB-6013) BlackBerry10: wrap webkit prefixed called in requestAnimationFrame\n* Update plugin writers' documentation\n* [CB-6080](https://issues.apache.org/jira/browse/CB-6080) Fix file copy when src and dst are on different local file systems\n* [CB-6057](https://issues.apache.org/jira/browse/CB-6057) Add methods for plugins to convert between URLs and paths\n* [CB-6050](https://issues.apache.org/jira/browse/CB-6050) Public method for returning a FileEntry from a device file path\n* [CB-2432](https://issues.apache.org/jira/browse/CB-2432) [CB-3185](https://issues.apache.org/jira/browse/CB-3185), [CB-5975](https://issues.apache.org/jira/browse/CB-5975): Fix Android handling of content:// URLs\n* [CB-6022](https://issues.apache.org/jira/browse/CB-6022) Add upgrade notes to doc\n* [CB-5233](https://issues.apache.org/jira/browse/CB-5233) Make asset-library urls work properly on iOS\n* [CB-6012](https://issues.apache.org/jira/browse/CB-6012) Preserve query strings on cdvfile:// URLs where necessary\n* [CB-6010](https://issues.apache.org/jira/browse/CB-6010) Test properly for presence of URLforFilesystemPath method\n* [CB-5959](https://issues.apache.org/jira/browse/CB-5959) Entry.getMetadata should return size attribute\n\n### 1.0.0 (Feb 05, 2014)\n* [CB-5974](https://issues.apache.org/jira/browse/CB-5974): Use safe 'Compatibilty' mode by default\n* [CB-5915](https://issues.apache.org/jira/browse/CB-5915): [CB-5916](https://issues.apache.org/jira/browse/CB-5916): Reorganize preference code to make defaults possible\n* [CB-5974](https://issues.apache.org/jira/browse/CB-5974): Android: Don't allow File operations to continue when not configured\n* [CB-5960](https://issues.apache.org/jira/browse/CB-5960): ios: android: Properly handle parent references in getFile/getDirectory\n* [ubuntu] adopt to recent changes\n* Add default FS root to new FS objects\n* [CB-5899](https://issues.apache.org/jira/browse/CB-5899): Make DirectoryReader.readEntries return properly formatted Entry objects\n* Add constuctor params to FileUploadResult related to [CB-2421](https://issues.apache.org/jira/browse/CB-2421)\n* Fill out filesystem attribute of entities returned from resolveLocalFileSystemURL\n* [CB-5916](https://issues.apache.org/jira/browse/CB-5916): Create documents directories if they don't exist\n* [CB-5915](https://issues.apache.org/jira/browse/CB-5915): Create documents directories if they don't exist\n* [CB-5916](https://issues.apache.org/jira/browse/CB-5916): Android: Fix unfortunate NPE in config check\n* [CB-5916](https://issues.apache.org/jira/browse/CB-5916): Android: Add \"/files/\" to persistent files path\n* [CB-5915](https://issues.apache.org/jira/browse/CB-5915): ios: Update config preference (and docs) to match issue\n* [CB-5916](https://issues.apache.org/jira/browse/CB-5916): Android: Add config preference for Android persistent storage location\n* iOS: Add config preference for iOS persistent storage location\n* iOS: Android: Allow third-party plugin registration\n* Android: Expose filePlugin getter so that other plugins can register filesystems\n* Fix typos in deprecation message\n* Add backwards-compatibility shim for file-transfer\n* Android: Allow third-party plugin registration\n* [CB-5810](https://issues.apache.org/jira/browse/CB-5810) [BlackBerry10] resolve local:/// paths (application assets)\n* [CB-5774](https://issues.apache.org/jira/browse/CB-5774): create DirectoryEntry instead of FileEntry\n* Initial fix for [CB-5747](https://issues.apache.org/jira/browse/CB-5747)\n* Change default FS URL scheme to \"cdvfile\"\n* Android: Properly format content urls\n* Android, iOS: Replace \"filesystem\" protocol string with constant\n* Android: Allow absolute paths on Entry.getFile / Entry.getDirectory\n* Android: Make clear that getFile takes a path, not just a filename\n* [CB-5008](https://issues.apache.org/jira/browse/CB-5008): Rename resolveLocalFileSystemURI to resolveLocalFileSystemURL; deprecate original\n* Remove old file reference from plugin.xml\n* Android: Refactor File API\n* [CB-4899](https://issues.apache.org/jira/browse/CB-4899) [BlackBerry10] Fix resolve directories\n* [CB-5602](https://issues.apache.org/jira/browse/CB-5602) Windows8. Fix File Api mobile spec tests\n* Android: Better support for content urls and cross-filesystem copy/move ops\n* [CB-5699](https://issues.apache.org/jira/browse/CB-5699) [BlackBerry10] Update resolveLocalFileSystemURI implementation\n* [CB-5658](https://issues.apache.org/jira/browse/CB-5658) Update license comment formatting of doc/index.md\n* [CB-5658](https://issues.apache.org/jira/browse/CB-5658) Add doc.index.md for File plugin.\n* [CB-5658](https://issues.apache.org/jira/browse/CB-5658) Delete stale snapshot of plugin docs\n* [CB-5403](https://issues.apache.org/jira/browse/CB-5403): Backwards-compatibility with file:// urls where possible\n* [CB-5407](https://issues.apache.org/jira/browse/CB-5407): Fixes for ContentFilesystem\n* Android: Add method for testing backwards-compatibility of filetransfer plugin\n* iOS: Add method for testing backwards-compatiblity of filetransfer plugin\n* Android: Updates to allow FileTransfer to continue to work\n* Android: Clean up unclosed file objects\n* [CB-5407](https://issues.apache.org/jira/browse/CB-5407): Cleanup\n* [CB-5407](https://issues.apache.org/jira/browse/CB-5407): Add new Android source files to plugin.xml\n* [CB-5407](https://issues.apache.org/jira/browse/CB-5407): Move read, write and truncate methods into modules\n* [CB-5407](https://issues.apache.org/jira/browse/CB-5407): Move copy/move methods into FS modules\n* [CB-5407](https://issues.apache.org/jira/browse/CB-5407): Move getParent into FS modules\n* [CB-5407](https://issues.apache.org/jira/browse/CB-5407): Move getmetadata methods into FS modules\n* [CB-5407](https://issues.apache.org/jira/browse/CB-5407): Move readdir methods into FS modules\n* [CB-5407](https://issues.apache.org/jira/browse/CB-5407): Move remove methods into FS modules\n* [CB-5407](https://issues.apache.org/jira/browse/CB-5407): Move getFile into FS modules\n* [CB-5407](https://issues.apache.org/jira/browse/CB-5407): Start refactoring android code: Modular filesystems, rfs, rlfsurl\n* [CB-5407](https://issues.apache.org/jira/browse/CB-5407): Update android JS to use FS urls\n* [CB-5405](https://issues.apache.org/jira/browse/CB-5405): Use URL formatting for Entry.toURL\n* [CB-5532](https://issues.apache.org/jira/browse/CB-5532) Fix\n* Log file path for File exceptions.\n* Partial fix for iOS File compatibility with previous fileTransfer plugin\n* [CB-5532](https://issues.apache.org/jira/browse/CB-5532) WP8. Add binary data support to FileWriter\n* [CB-5531](https://issues.apache.org/jira/browse/CB-5531) WP8. File Api readAsText incorrectly handles position args\n* Added ubuntu platform support\n* Added amazon-fireos platform support\n* [CB-5118](https://issues.apache.org/jira/browse/CB-5118) [BlackBerry10] Add check for undefined error handler\n* [CB-5406](https://issues.apache.org/jira/browse/CB-5406): Extend public API for dependent plugins\n* [CB-5403](https://issues.apache.org/jira/browse/CB-5403): Bump File plugin major version\n* [CB-5406](https://issues.apache.org/jira/browse/CB-5406): Split iOS file plugin into modules\n* [CB-5406](https://issues.apache.org/jira/browse/CB-5406): Factor out filesystem providers in iOS\n* [CB-5408](https://issues.apache.org/jira/browse/CB-5408): Add handler for filesystem:// urls\n* [CB-5406](https://issues.apache.org/jira/browse/CB-5406): Update iOS native code to use filesystem URLs internally\n* [CB-5405](https://issues.apache.org/jira/browse/CB-5405): Update JS code to use URLs exclusively\n* [CB-4816](https://issues.apache.org/jira/browse/CB-4816) Fix file creation outside sandbox for BB10\n\n### 0.2.5 (Oct 28, 2013)\n* [CB-5129](https://issues.apache.org/jira/browse/CB-5129): Add a consistent filesystem attribute to FileEntry and DirectoryEntry objects\n* [CB-5128](https://issues.apache.org/jira/browse/CB-5128): added repo + issue tag to plugin.xml for file plugin\n* [CB-5015](https://issues.apache.org/jira/browse/CB-5015) [BlackBerry10] Add missing dependency for File.slice\n* [CB-5010](https://issues.apache.org/jira/browse/CB-5010) Incremented plugin version on dev branch.\n\n### 0.2.4 (Oct 9, 2013)\n* [CB-5020](https://issues.apache.org/jira/browse/CB-5020) - File plugin should execute on a separate thread\n* [CB-4915](https://issues.apache.org/jira/browse/CB-4915) Incremented plugin version on dev branch.\n* [CB-4504](https://issues.apache.org/jira/browse/CB-4504): Updating FileUtils.java to compensate for Java porting failures in the Android SDK. This fails because Java knows nothing about android_asset not being an actual filesystem\n\n### 0.2.3 (Sept 25, 2013)\n* [CB-4889](https://issues.apache.org/jira/browse/CB-4889) bumping&resetting version\n* [CB-4903](https://issues.apache.org/jira/browse/CB-4903) File Plugin not loading Windows8\n* [CB-4903](https://issues.apache.org/jira/browse/CB-4903) File Plugin not loading Windows8\n* [CB-4889](https://issues.apache.org/jira/browse/CB-4889) renaming references\n* [CB-4889](https://issues.apache.org/jira/browse/CB-4889) renaming org.apache.cordova.core.file to org.apache.cordova.file\n* Rename CHANGELOG.md -> RELEASENOTES.md\n* [CB-4771](https://issues.apache.org/jira/browse/CB-4771) Expose TEMPORARY and PERSISTENT constants on window.\n* Fix compiler/lint warnings\n* [CB-4764](https://issues.apache.org/jira/browse/CB-4764) Move DirectoryManager.java into file plugin\n* [CB-4763](https://issues.apache.org/jira/browse/CB-4763) Copy FileHelper.java into the plugin.\n* [CB-2901](https://issues.apache.org/jira/browse/CB-2901) [BlackBerry10] Automatically unsandbox filesystem if path is not in app sandbox\n* [CB-4752](https://issues.apache.org/jira/browse/CB-4752) Incremented plugin version on dev branch.\n\n### 0.2.1 (Sept 5, 2013)\n* [CB-4656](https://issues.apache.org/jira/browse/CB-4656) Don't add newlines in data urls within readAsDataUrl.\n* [CB-4514](https://issues.apache.org/jira/browse/CB-4514) Making DirectoryCopy Recursive\n* [iOS] Simplify the code in resolveLocalFileSystemURI\n"
  },
  {
    "path": "plugins/cordova-plugin-file/doc/de/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-file\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-file.svg)](https://travis-ci.org/apache/cordova-plugin-file)\n\nDieses Plugin implementiert eine File-API, die Lese-/Schreibzugriff Zugriff auf Dateien, die auf dem Gerät befinden.\n\nDieses Plugin basiert auf mehrere Angaben, einschließlich: die HTML5-File-API <http://www.w3.org/TR/FileAPI/>\n\nDie (heute nicht mehr existierenden) Verzeichnisse und System neuesten Erweiterungen: <http://www.w3.org/TR/2012/WD-file-system-api-20120417/> , obwohl die meisten von den Plugin-Code wurde geschrieben, als eine frühere Spec aktuell waren: <http://www.w3.org/TR/2011/WD-file-system-api-20110419/>\n\nEs implementiert auch die FileWriter Spec: <http://dev.w3.org/2009/dap/file-system/file-writer.html>\n\nVerwendung finden Sie in HTML5 Rocks ausgezeichnete [Dateisystem Artikel.](http://www.html5rocks.com/en/tutorials/file/filesystem/)\n\nFinden Sie einen Überblick über andere Speicheroptionen Cordovas [Speicher-Führer](http://cordova.apache.org/docs/en/edge/cordova_storage_storage.md.html).\n\nDieses Plugin wird global `cordova.file`-Objekt definiert.\n\nObwohl im globalen Gültigkeitsbereich, steht es nicht bis nach dem `deviceready`-Ereignis.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(cordova.file);\n    }\n    \n\n## Installation\n\n    cordova plugin add cordova-plugin-file\n    \n\n## Unterstützte Plattformen\n\n  * Amazon Fire OS\n  * Android\n  * BlackBerry 10\n  * Firefox OS\n  * iOS\n  * Windows Phone 7 und 8 *\n  * Windows 8 *\n  * Windows*\n  * Browser\n\n\\* *These platforms do not support `FileReader.readAsArrayBuffer` nor `FileWriter.write(blob)`.*\n\n## Wo Dateien gespeichert\n\nStand: V1 werden URLs auf wichtige Datei-System-Verzeichnisse zur Verfügung gestellt. Jede URL in der Form *file:///path/to/spot/* ist, und ein `DirectoryEntry` mit `window.resolveLocalFileSystemURL()` konvertiert werden können.\n\n  * `cordova.file.applicationDirectory`-Die schreibgeschützten Verzeichnis, in dem die Anwendung installiert ist. (*iOS*, *Android*, *BlackBerry 10*)\n\n  * `cordova.file.applicationStorageDirectory`-Root-Verzeichnis der Anwendungs-Sandbox; auf iOS ist schreibgeschützt (aber bestimmte Unterverzeichnisse [wie `/Documents` ] sind Lese-und Schreibzugriff). Alle enthaltene Daten ist für die app privat. ( *iOS*, *Android*, *BlackBerry 10*)\n\n  * `cordova.file.dataDirectory`-Beständige und private Datenspeicherung innerhalb der Anwendungs-Sandbox, die mit internen Speicher (auf Android, externen Speicher verwenden, verwenden Sie `.externalDataDirectory` ). Auf iOS, ist dieses Verzeichnis nicht mit iCloud synchronisiert (verwenden Sie `.syncedDataDirectory` ). (*iOS*, *Android*, *BlackBerry 10*)\n\n  * `cordova.file.cacheDirectory`-Verzeichnis der zwischengespeicherten Daten-Dateien oder Dateien, die Ihre app einfach neu erstellen können. Das Betriebssystem kann diese Dateien löschen, wenn das Gerät auf Speicher knapp wird, dennoch sollten die apps vom Betriebssystem zum Löschen von Dateien hier nicht verlassen. (*iOS*, *Android*, *BlackBerry 10*)\n\n  * `cordova.file.externalApplicationStorageDirectory`-Anwendungsraum auf externen Speicher. (*Android*)\n\n  * `cordova.file.externalDataDirectory`-Wo, app-spezifische Datendateien auf externen Speicher setzen. (*Android*)\n\n  * `cordova.file.externalCacheDirectory`-Anwendungscache auf externen Speicher. (*Android*)\n\n  * `cordova.file.externalRootDirectory`-Externer Speicher (SD-Karte) Stamm. (*Android*, *BlackBerry 10*)\n\n  * `cordova.file.tempDirectory`-Temp-Verzeichnis, dem das OS auf deaktivieren können wird. Verlassen Sie sich nicht auf das Betriebssystem, um dieses Verzeichnis zu löschen; Ihre Anwendung sollte immer Dateien gegebenenfalls entfernen. (*iOS*)\n\n  * `cordova.file.syncedDataDirectory`-Hält app-spezifische Dateien, die (z. B. auf iCloud) synchronisiert werden sollten. (*iOS*)\n\n  * `cordova.file.documentsDirectory`-Dateien für die app, aber privat sind sinnvoll, andere Anwendungen (z.B. Office-Dateien). (*iOS*)\n\n  * `cordova.file.sharedDirectory`-Dateien für alle Anwendungen (*BlackBerry 10* weltweit verfügbar)\n\n## Dateisystemlayouts\n\nObwohl technisch ein Implementierungsdetail, kann es sehr hilfreich zu wissen, wie die `cordova.file.*`-Eigenschaften physikalische Pfade auf einem echten Gerät zugeordnet sein.\n\n### iOS-Datei-System-Layout\n\n| Gerätepfad                                     | `Cordova.file.*`            | `iosExtraFileSystems` | R/w? | persistent? |  OS löscht   | Sync | Private |\n|:---------------------------------------------- |:--------------------------- |:--------------------- |:----:|:-----------:|:------------:|:----:|:-------:|\n| `/ Var/mobile/Applications/< UUID > /`   | applicationStorageDirectory | -                     |  r   |     N/A     |     N/A      | N/A  |   Ja    |\n| &nbsp;&nbsp;&nbsp;`appname.app/`               | applicationDirectory        | Bundle                |  r   |     N/A     |     N/A      | N/A  |   Ja    |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`www/`     | -                           | -                     |  r   |     N/A     |     N/A      | N/A  |   Ja    |\n| &nbsp;&nbsp;&nbsp;`Documents/`                 | documentsDirectory          | Dokumente             | R/w  |     Ja      |     Nein     |  Ja  |   Ja    |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`NoCloud/` | -                           | Dokumente-nosync      | R/w  |     Ja      |     Nein     | Nein |   Ja    |\n| &nbsp;&nbsp;&nbsp;`Library`                    | -                           | Bibliothek            | R/w  |     Ja      |     Nein     | Ja?  |   Ja    |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`NoCloud/` | dataDirectory               | Bibliothek-nosync     | R/w  |     Ja      |     Nein     | Nein |   Ja    |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`Cloud/`   | syncedDataDirectory         | -                     | R/w  |     Ja      |     Nein     |  Ja  |   Ja    |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`Caches/`  | cacheDirectory              | Cache                 | R/w  |    Ja *     | Ja**\\* | Nein |   Ja    |\n| &nbsp;&nbsp;&nbsp;`tmp/`                       | tempDirectory               | -                     | R/w  | Nein**  | Ja**\\* | Nein |   Ja    |\n\n\\ * Dateien über app-Neustarts und Upgrades beibehalten, aber dieses Verzeichnis kann gelöscht werden, wenn das OS begehrt. Ihre Anwendung sollte in der Lage, alle Inhalte neu zu erstellen, die gelöscht werden können.\n\n** -Dateien kann über app-Neustarts beizubehalten, aber verlasse dich nicht auf dieses Verhalten. Dateien sind nicht unbedingt Aktuelles beibehalten. Ihre Anwendung sollte Dateien aus diesem Verzeichnis entfernen, wenn es gilt, diese Dateien werden entfernt, da das OS nicht wann (oder auch wenn) garantiert.\n\n**\\ * The OS kann den Inhalt dieses Verzeichnisses löschen, wann immer es sich anfühlt, ist es erforderlich, aber verlassen Sie sich nicht dazu. Sie sollten dieses Verzeichnis entsprechend Ihrer Anwendung deaktivieren.\n\n### Android File System-Layout\n\n| Gerätepfad                                       | `Cordova.file.*`                    | `AndroidExtraFileSystems` | R/w? | persistent? | OS löscht  | Private |\n|:------------------------------------------------ |:----------------------------------- |:------------------------- |:----:|:-----------:|:----------:|:-------:|\n| `file:///android_asset/`                         | applicationDirectory                |                           |  r   |     N/A     |    N/A     |   Ja    |\n| `/ Data/Data/< app-Id > /`                 | applicationStorageDirectory         | -                         | R/w  |     N/A     |    N/A     |   Ja    |\n| &nbsp;&nbsp;&nbsp;`cache`                        | cacheDirectory                      | Cache                     | R/w  |     Ja      |   Ja\\*   |   Ja    |\n| &nbsp;&nbsp;&nbsp;`files`                        | dataDirectory                       | Dateien                   | R/w  |     Ja      |    Nein    |   Ja    |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`Documents`  |                                     | Dokumente                 | R/w  |     Ja      |    Nein    |   Ja    |\n| `< Sdcard > /`                             | externalRootDirectory               | sdcard                    | R/w  |     Ja      |    Nein    |  Nein   |\n| &nbsp;&nbsp;&nbsp;`Android/data/<app-id>/` | externalApplicationStorageDirectory | -                         | R/w  |     Ja      |    Nein    |  Nein   |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`cache`      | externalCacheDirectry               | Cache-extern              | R/w  |     Ja      | Nein** |  Nein   |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`files`      | externalDataDirectory               | Dateien-extern            | R/w  |     Ja      |    Nein    |  Nein   |\n\n\\ * OS kann regelmäßig dieses Verzeichnis zu löschen, aber verlasse dich nicht auf dieses Verhalten. Deaktivieren Sie den Inhalt dieses Verzeichnisses für Ihre Anwendung geeigneten. Ein Benutzer den Cache manuell löschen sollte, werden die Inhalte dieses Verzeichnisses entfernt.\n\n** Der OS nicht klar dieses Verzeichnis automatisch; Sie sind verantwortlich für die Inhalte selbst verwalten. Der Benutzer den Cache manuell löschen sollte, werden der Inhalt des Verzeichnisses entfernt.\n\n**Hinweis**: Wenn externe Speichergeräte nicht bereitgestellt werden kann, sind die `cordova.file.external*` Eigenschaften `null`.\n\n### BlackBerry 10-File-System-Layout\n\n| Gerätepfad                                                  | `Cordova.file.*`            | R/w? | persistent? | OS löscht | Private |\n|:----------------------------------------------------------- |:--------------------------- |:----:|:-----------:|:---------:|:-------:|\n| `file:///Accounts/1000/APPDATA/ < app Id > /`         | applicationStorageDirectory |  r   |     N/A     |    N/A    |   Ja    |\n| &nbsp;&nbsp;&nbsp;`app/native`                              | applicationDirectory        |  r   |     N/A     |    N/A    |   Ja    |\n| &nbsp;&nbsp;&nbsp;`data/webviews/webfs/temporary/local__0`  | cacheDirectory              | R/w  |    Nein     |    Ja     |   Ja    |\n| &nbsp;&nbsp;&nbsp;`data/webviews/webfs/persistent/local__0` | dataDirectory               | R/w  |     Ja      |   Nein    |   Ja    |\n| `file:///Accounts/1000/Removable/sdcard`                    | externalRemovableDirectory  | R/w  |     Ja      |   Nein    |  Nein   |\n| `file:///Accounts/1000/Shared`                              | sharedDirectory             | R/w  |     Ja      |   Nein    |  Nein   |\n\n*Hinweis*: Wenn die Anwendung bereitgestellt wird, um Perimeter zu arbeiten, alle Pfade sind relativ /accounts/1000-enterprise.\n\n## Android Eigenarten\n\n### Android permanenten Speicherort\n\nEs gibt mehrere gültige Speicherorte, persistente Dateien auf einem Android-Gerät zu speichern. Finden Sie auf [dieser Seite](http://developer.android.com/guide/topics/data/data-storage.html) eine ausführliche Diskussion über die verschiedenen Möglichkeiten.\n\nFrühere Versionen des Plugins wählen würde, den Speicherort der temporären und permanenten Dateien beim Start, basierend auf, ob das Gerät behauptete, dass die SD-Karte (oder gleichwertige Speicherpartition) bereitgestellt wurde. Wenn die SD-Karte eingelegt wurde, oder wenn eine große interne Speicherpartition verfügbar war (wie auf Nexus-Geräten) und dann in die Wurzel dieses Raumes, die persistenten Dateien gespeichert werden. Dies bedeutete, dass alle Cordova apps aller verfügbaren Dateien auf der Karte sehen konnte.\n\nWenn die SD-Karte nicht verfügbar war, dann Vorgängerversionen Daten unter speichern würde `/data/data/<packageId>`, die isoliert Anwendungen voneinander, aber möglicherweise noch Ursache Daten zwischen Benutzern freigegeben werden.\n\nEs ist jetzt möglich, ob Sie Dateien der internen Datei-Speicherort oder unter Verwendung der bisherigen Logik, mit einer Präferenz in der Anwendung-`config.xml`-Datei speichern möchten. Hierzu fügen Sie eine dieser zwei Zeilen zu `\"config.xml\"`:\n\n    <preference name=\"AndroidPersistentFileLocation\" value=\"Internal\" />\n    \n    <preference name=\"AndroidPersistentFileLocation\" value=\"Compatibility\" />\n    \n\nOhne diese Zeile wird das Datei Plugin `Compatibility` als Standard verwenden. Wenn ein Präferenz-Tag vorhanden ist, und nicht einen der folgenden Werte, wird die Anwendung nicht gestartet.\n\nWenn Ihre Anwendung für Benutzer zuvor versandt wird, mithilfe eines älteren (Pre-1.0) Version dieses Plugins und gespeicherte Dateien im permanenten Dateisystem hat, dann sollten Sie die Einstellung zur `Compatibility` einstellen. Wechseln die Location auf \"Internal\" würde bedeuten, dass Benutzer, die aktualisieren Sie ihre Anwendung, möglicherweise nicht auf ihre zuvor gespeicherte Dateien, abhängig von ihrem Gerät zugreifen.\n\nWenn Ihre Anwendung neu ist, oder nie zuvor Dateien im Dateisystem persistent gespeichert hat, wird die `Internal` Einstellung in der Regel empfohlen.\n\n### Langsame rekursive Operationen für /android_asset\n\nAuflisten von Verzeichnissen Vermögenswert ist wirklich langsam auf Android. Sie können beschleunigen, es oben aber durch `src/android/build-extras.gradle` in das Stammverzeichnis von Ihrem android Projekt hinzufügen (erfordert auch cordova-android@4.0.0 oder größer).\n\n## iOS Macken\n\n  * `cordova.file.applicationStorageDirectory`ist schreibgeschützt; zum Speichern von Dateien im Stammverzeichnis der Versuch schlägt fehl. Verwenden Sie eine der anderen `cordova.file.*` für iOS definierten Eigenschaften (nur `applicationDirectory` und `applicationStorageDirectory` sind schreibgeschützt).\n  * `FileReader.readAsText(blob, encoding)` \n      * Die `encoding` Parameter wird nicht unterstützt und UTF-8-Kodierung ist immer wirksam.\n\n### iOS permanenten Speicherort\n\nEs gibt zwei gültige Speicherorte persistente Dateien auf ein iOS-Gerät speichern: das Dokumenten-Verzeichnis und das Verzeichnis Library. Frühere Versionen des Plugins gespeichert immer nur persistente Dateien im Verzeichnis Dokumente. Dies hatte den Nebeneffekt einer Anwendung Dateien in iTunes, die oft unbeabsichtigte, speziell für Anwendungen, die viele kleine Dateien behandeln war, sichtbar zu machen, anstatt komplette Dokumente für den Export, die den beabsichtigten Zweck des Verzeichnisses ist zu produzieren.\n\nEs ist jetzt möglich, ob Sie Dateien in Dokumente oder Verzeichnis Library mit einer Präferenz in der Anwendung-`config.xml`-Datei speichern möchten. Hierzu fügen Sie eine dieser zwei Zeilen zu `\"config.xml\"`:\n\n    <preference name=\"iosPersistentFileLocation\" value=\"Library\" />\n    \n    <preference name=\"iosPersistentFileLocation\" value=\"Compatibility\" />\n    \n\nOhne diese Zeile wird das Datei Plugin `Compatibility` als Standard verwenden. Wenn ein Präferenz-Tag vorhanden ist, und nicht einen der folgenden Werte, wird die Anwendung nicht gestartet.\n\nWenn Ihre Anwendung für Benutzer zuvor versandt wird, mithilfe eines älteren (Pre-1.0) Version dieses Plugins und gespeicherte Dateien im permanenten Dateisystem hat, dann sollten Sie die Einstellung zur `Compatibility` einstellen. Standort zur `Library` wechseln würde bedeuten, dass Benutzer, die ihre Anwendung aktualisieren nicht in der Lage wäre, ihre zuvor gespeicherte Dateien zugreifen.\n\nWenn die Anwendung neu, oder nie zuvor Dateien im Dateisystem persistent gespeichert hat, wird die Einstellung der `Library` allgemein empfohlen.\n\n## Firefox OS Macken\n\nDer Datei-System-API wird von Firefox-OS nicht nativ unterstützt und wird als ein Shim auf IndexedDB implementiert.\n\n  * Schlägt nicht fehl, wenn Sie nicht leere Verzeichnisse entfernen\n  * Metadaten wird für Verzeichnisse nicht unterstützt.\n  * Methoden `copyTo` und `moveTo` unterstützen keine Verzeichnisse\n\nDie folgenden Datenpfade werden unterstützt: * `applicationDirectory` - `xhr` verwendet, um lokale Dateien erhalten, die mit der app verpackt sind. *`dataDirectory` - für persistente app-spezifische Daten-Dateien. *`cacheDirectory` - Cache-Dateien, die app startet überleben sollte (Apps sollten nicht vom Betriebssystem zum Löschen von Dateien hier verlassen).\n\n## Browser-Eigenheiten\n\n### Gemeinsamen Macken und Bemerkungen\n\n  * Jeder Browser verwendet ein eigene Sandbox Dateisystem. IE und Firefox verwenden IndexedDB als Basis. Alle Browser verwenden Schrägstrich als Verzeichnistrennzeichen in einem Pfad.\n  * Directory-Einträge müssen nacheinander erstellt werden. Z. B. der Aufruf `fs.root.getDirectory (\"dir1/Ordner2 ', {create:true}, SuccessCallback, ErrorCallback)` schlägt fehl, wenn dir1 nicht existierte.\n  * Das Plugin fordert Benutzer die Berechtigung zum permanenten Speicher beim ersten Start Anwendung verwenden. \n  * Plugin unterstützt `Cdvfile://localhost` (lokale Ressourcen) nur. D.h. externe Ressourcen nicht über `Cdvfile` unterstützt.\n  * Das Plugin folgt nicht [\"File System API 8.3 Naming Einschränkungen\"](http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions).\n  * BLOB und Datei \"`close`-Funktion wird nicht unterstützt.\n  * `FileSaver` und `BlobBuilder` werden von diesem Plugin nicht unterstützt und müssen nicht geboren.\n  * Das Plugin unterstützt keine `RequestAllFileSystems`. Diese Funktion fehlt auch in den Spezifikationen.\n  * Einträge im Verzeichnis werden nicht entfernt werden, wenn Sie verwenden `create: true` Flag für vorhandenes Verzeichnis.\n  * Über Konstruktor erstellte Dateien werden nicht unterstützt. Sie sollten stattdessen die entry.file-Methode verwenden.\n  * Jeder Browser verwendet eine eigene Form für Blob-URL-Verweise.\n  * `readAsDataURL`-Funktion wird unterstützt, aber die Mediatype in Chrom hängt von der Eintrag Namenerweiterung, Mediatype im IE immer leer ist (das ist dasselbe wie `Text-Plain` gemäß der Spezifikation), Mediatype in Firefox ist immer `Application/Octet-Stream`. Beispielsweise, wenn der Inhalt `Abcdefg` gibt dann Firefox `Daten: Anwendung / Octet-Stream; base64, YWJjZGVmZw ==`, IE gibt `Daten:; base64, YWJjZGVmZw ==`, Chrom gibt `Daten: < Mediatype je nach Erweiterung des Eintragsnamens >; base64, YWJjZGVmZw ==`.\n  * `ToInternalURL` gibt den Pfad zurück, in der Form `file:///persistent/path/to/entry` (Firefox, IE). Chrom gibt den Pfad zurück, in der Form `cdvfile://localhost/persistent/file`.\n\n### Chrom-Macken\n\n  * Chrom-Dateisystem ist nicht sofort nach Gerät bereit. Als Workaround können Sie `FilePluginIsReady`-Ereignis abonnieren. Beispiel: \n\n```javascript\nwindow.addEventListener('filePluginIsReady', function(){ console.log('File plugin is ready');}, false);\n```\n\n`Window.isFilePluginReadyRaised`-Funktion können Sie überprüfen, ob Ereignis bereits ausgelöst wurde. -window.requestFileSystem temporär und PERSISTENTE Dateisystem-Quoten sind nicht begrenzt, in Chrom. -Um die dauerhafte Speicherung in Chrom zu erhöhen benötigen Sie `window.initPersistentFileSystem`-Methode aufrufen. Permanenter Speicherkontingent beträgt 5 MB standardmäßig. -Chrome erforderlich `--erlauben-Datei-Zugriff-aus-Files` Argument an den Support API via `file:///` Protokoll führen. -`Datei`-Objekt wird nicht geändert werden, wenn Sie Flag verwenden `{create:true}` als einen vorhandenen `Eintrag` zu erhalten. -Veranstaltungen `cancelable`-Eigenschaft festgelegt ist in Chrom wahr. Dies widerspricht der [Spezifikation](http://dev.w3.org/2009/dap/file-system/file-writer.html). -`toURL`-Funktion in Chrome zurück `Dateisystem:`-Pfad je nach Anwendungshost vorangestellt. Z. B. `filesystem:file:///persistent/somefile.txt`, `Filesystem:http://localhost:8080/persistent/somefile.txt`. -`toURL` Funktionsergebnis enthält keine nachgestellten Schrägstrich bei Verzeichniseintrag. Chrom löst Verzeichnisse mit Schrägstrich-gezogene Urls aber korrekt. -`ResolveLocalFileSystemURL`-Methode erfordert die eingehenden `Url` `Dateisystem` Präfix haben. Beispielsweise sollte die `Url`-Parameter für `ResolveLocalFileSystemURL` in der Form `filesystem:file:///persistent/somefile.txt` im Gegensatz zu der Form `file:///persistent/somefile.txt` in Android. -Veraltete `ToNativeURL`-Funktion wird nicht unterstützt und muss keinen Stub. -`SetMetadata`-Funktion ist nicht in den Spezifikationen angegeben und nicht unterstützt. -INVALID_MODIFICATION_ERR (Code: 9) wird ausgelöst, statt SYNTAX_ERR(code: 8) auf anfordern des Dateisystems nicht existent. -INVALID_MODIFICATION_ERR (Code: 9) wird ausgelöst, anstatt PATH_EXISTS_ERR(code: 12) zu versuchen, die ausschließlich eine Datei oder ein Verzeichnis zu erstellen, die bereits vorhanden ist. -INVALID_MODIFICATION_ERR (Code: 9) wird ausgelöst, anstatt NO_MODIFICATION_ALLOWED_ERR(code: 6) zu versuchen, rufen Sie RemoveRecursively auf das Root-Dateisystem. -INVALID_MODIFICATION_ERR (Code: 9) wird ausgelöst, anstatt NOT_FOUND_ERR(code: 1) zu versuchen, MoveTo-Verzeichnis, das nicht vorhanden ist.\n\n### Auf der Grundlage von IndexedDB Impl Macken (Firefox und IE)\n\n  * `.` und `.` werden nicht unterstützt.\n  * IE unterstützt keine `file:///`-Modus; nur der Modus für gehostete ist unterstützten (Http://localhost:xxxx).\n  * Firefox Dateisystem Größe ist nicht begrenzt, aber jede 50MB-Erweiterung wird eine Benutzer die Berechtigung anzufordern. IE10 können bis zu 10mb kombinierte AppCache und IndexedDB in Implementierung des Dateisystems verwendet, ohne Aufforderung, sobald Sie dieses Niveau, werden, das Sie aufgefordert werden schlagen, wenn Sie es bis Max 250 mb pro Standort erhöht werden sollen. `Size`-Parameter für `RequestFileSystem` Funktion wirkt also nicht Dateisystem in Firefox und IE.\n  * `ReadAsBinaryString` Funktion heißt es nicht in die Angaben und in IE nicht unterstützt und muss keinen Stub.\n  * `file.Type` ist immer null.\n  * Sie sollten nicht erstellen Eintrag mit DirectoryEntry Instanz Rückrufergebnis, die gelöscht wurde. Andernfalls erhalten Sie einen \"hängende Eintrag\".\n  * Bevor Sie eine Datei lesen können, die gerade geschrieben wurde, müssen Sie eine neue Instanz dieser Datei erhalten.\n  * `SetMetadata`-Funktion, die nicht in den Specs genannt unterstützt Feldänderung nur `ModificationTime`. \n  * `CopyTo` und `MoveTo`-Funktionen unterstützen keine Verzeichnisse.\n  * Verzeichnisse-Metadaten werden nicht unterstützt.\n  * Beide Entry.remove und directoryEntry.removeRecursively nicht scheitern, wenn nicht leere Verzeichnisse entfernen - Verzeichnisse entfernt werden stattdessen zusammen mit Inhalt gereinigt.\n  * `abort` und `truncate`-Funktionen werden nicht unterstützt.\n  * Progress-Ereignisse werden nicht ausgelöst. Beispielsweise wird dieser Handler nicht ausgeführt werden:\n\n```javascript\nwriter.onprogress = function() { /*commands*/ };\n```\n\n## Upgrade Notes\n\nIn v1.0.0 dieses Plugins haben die `FileEntry` und `DirectoryEntry` Strukturen geändert, um mehr im Einklang mit der veröffentlichten Spezifikation sein.\n\nVorgängerversionen (Pre-1.0.0) des Plugins den Gerät-Absolute-Dateispeicherort in der Eigenschaft `fullPath` `Entry` Objekte gespeichert. Diese Pfade würde in der Regel aussehen\n\n    /var/mobile/Applications/<application UUID>/Documents/path/to/file  (iOS)\n    /storage/emulated/0/path/to/file                                    (Android)\n    \n\nDiese Pfade wurden auch von der `toURL()`-Methode der `Entry` Objekte zurückgegeben.\n\nMit v1.0.0 ist das `fullPath`-Attribut den Pfad zu der Datei, *relativ zum Stammverzeichnis des Dateisystems HTML*. Also, würde die oben genannten Wege jetzt beide durch ein `FileEntry`-Objekt mit einem `fullPath` von dargestellt werden\n\n    /path/to/file\n    \n\nWenn Ihre Anwendung mit absoluter Gerätepfade arbeitet und Sie zuvor diese Pfade durch die Eigenschaft `fullPath` `Entry` Objekte abgerufen, sollten dann Sie den Code, um stattdessen `entry.toURL()` verwenden aktualisieren.\n\nFür rückwärts Kompatibilität, die `resolveLocalFileSystemURL()`-Methode wird einen Absolute-Gerätepfad zu akzeptieren und kehrt ein `Entry`-Objekt entspricht, solange diese Datei in den `TEMPORARY` oder `PERSISTENT` Dateisysteme existiert.\n\nDies wurde vor allem ein Problem mit dem File-Transfer-Plugin, die zuvor-Absolute-Gerätepfade verwendet (und kann damit noch einverstanden). Es wurde überarbeitet, um mit Dateisystem-URLs korrekt zu arbeiten, damit ersetzen `entry.fullPath` mit `entry.toURL()` immer das Plugin zum Arbeiten mit Dateien auf dem Gerät Probleme lösen sollte.\n\nIn v1.1.0 wurde der Rückgabewert von `toURL()` (siehe \\[CB-6394\\] (https://issues.apache.org/jira/browse/CB-6394)) geändert, um eine absolute \"file://\" URL zurückgeben. wo immer möglich. Sicherstellung einer ' Cdvfile:'-URL können Sie an `toInternalURL()`. Diese Methode gibt jetzt Dateisystem URLs der Form zurück.\n\n    cdvfile://localhost/persistent/path/to/file\n    \n\ndie benutzt werden können, um die Datei eindeutig zu identifizieren.\n\n## Liste der Fehlercodes und Bedeutungen\n\nWenn ein Fehler ausgelöst wird, wird eines der folgenden Codes verwendet werden.\n\n| Code | Konstante                     |\n| ----:|:----------------------------- |\n|    1 | `NOT_FOUND_ERR`               |\n|    2 | `SECURITY_ERR`                |\n|    3 | `ABORT_ERR`                   |\n|    4 | `NOT_READABLE_ERR`            |\n|    5 | `ENCODING_ERR`                |\n|    6 | `NO_MODIFICATION_ALLOWED_ERR` |\n|    7 | `INVALID_STATE_ERR`           |\n|    8 | `SYNTAX_ERR`                  |\n|    9 | `INVALID_MODIFICATION_ERR`    |\n|   10 | `QUOTA_EXCEEDED_ERR`          |\n|   11 | `TYPE_MISMATCH_ERR`           |\n|   12 | `PATH_EXISTS_ERR`             |\n\n## Konfigurieren das Plugin (Optional)\n\nDie Menge der verfügbaren Dateisysteme kann pro Plattform konfiguriert sein. Erkennen von iOS und Android ein <preference> Tag in `\"config.xml\"` die Namen der Dateisysteme installiert werden. Standardmäßig sind alle Datei-System-Roots aktiviert.\n\n    <preference name=\"iosExtraFilesystems\" value=\"library,library-nosync,documents,documents-nosync,cache,bundle,root\" />\n    <preference name=\"AndroidExtraFilesystems\" value=\"files,files-external,documents,sdcard,cache,cache-external,root\" />\n    \n\n### Android\n\n  * `files`: interne Datei-Speicher-Verzeichnis der Anwendung\n  * `files-external`: Verzeichnis der Anwendung externe Datei Speicher\n  * `sdcard`: das externe Globaldatei-Speicherverzeichnis (Dies ist die Wurzel der SD-Karte, sofern installiert). Sie benötigen die Berechtigung zur Verwendung dieses `android.permission.WRITE_EXTERNAL_STORAGE`.\n  * `cache`: internen Cache-Verzeichnis der Anwendung\n  * `cache-external`: externer Cache-Verzeichnis der Anwendung\n  * `root`: das gesamte Gerät-Dateisystem\n\nAndroid unterstützt auch eine spezielle Dateisystem mit dem Namen \"documents\", die ein Unterverzeichnis \"/Documents/\" die \"files\" Dateisystem darstellt.\n\n### iOS\n\n  * `library`: Bibliothek-Verzeichnis der Anwendung\n  * `documents`: Dokumente-Verzeichnis der Anwendung\n  * `cache`: Cache-Verzeichnis der Anwendung\n  * `bundle`: die Anwendung Bündel; den Speicherort der die app selbst auf dem Datenträger (schreibgeschützt)\n  * `root`: das gesamte Gerät-Dateisystem\n\nStandardmäßig können die Bibliothek und Dokumenten-Verzeichnisse mit iCloud synchronisiert werden. Sie können auch verlangen, zwei zusätzliche Dateisysteme, `library-nosync` und `documents-nosync`, die einem speziellen nicht synchronisierten Verzeichnis innerhalb darstellen der `/Library` oder `/Documents`-Dateisystem."
  },
  {
    "path": "plugins/cordova-plugin-file/doc/de/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-file\n\nDieses Plugin implementiert eine File-API, die Lese-/Schreibzugriff Zugriff auf Dateien, die auf dem Gerät befinden.\n\nDieses Plugin basiert auf mehrere Angaben, einschließlich: die HTML5-File-API <http://www.w3.org/TR/FileAPI/>\n\nDie (heute nicht mehr existierenden) Verzeichnisse und System neuesten Erweiterungen: <http://www.w3.org/TR/2012/WD-file-system-api-20120417/> , obwohl die meisten von den Plugin-Code wurde geschrieben, als eine frühere Spec aktuell waren: <http://www.w3.org/TR/2011/WD-file-system-api-20110419/>\n\nEs implementiert auch die FileWriter Spec: <http://dev.w3.org/2009/dap/file-system/file-writer.html>\n\nVerwendung finden Sie in HTML5 Rocks ausgezeichnete [Dateisystem Artikel.][1]\n\n [1]: http://www.html5rocks.com/en/tutorials/file/filesystem/\n\nFinden Sie einen Überblick über andere Speicheroptionen Cordovas [Speicher-Führer][2].\n\n [2]: http://cordova.apache.org/docs/en/edge/cordova_storage_storage.md.html\n\nDieses Plugin wird global `cordova.file`-Objekt definiert.\n\nObwohl im globalen Gültigkeitsbereich, steht es nicht bis nach dem `deviceready`-Ereignis.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(cordova.file);\n    }\n    \n\n## Installation\n\n    cordova plugin add cordova-plugin-file\n    \n\n## Unterstützte Plattformen\n\n*   Amazon Fire OS\n*   Android\n*   BlackBerry 10\n*   Firefox OS\n*   iOS\n*   Windows Phone 7 und 8 *\n*   Windows 8 *\n*   Browser\n\n* *Diese Plattformen unterstützen nicht `FileReader.readAsArrayBuffer` noch `FileWriter.write(blob)`.*\n\n## Wo Dateien gespeichert\n\nStand: V1 werden URLs auf wichtige Datei-System-Verzeichnisse zur Verfügung gestellt. Jede URL in der Form *file:///path/to/spot/* ist, und ein `DirectoryEntry` mit `window.resolveLocalFileSystemURL()` konvertiert werden können.\n\n*   `cordova.file.applicationDirectory`-Die schreibgeschützten Verzeichnis, in dem die Anwendung installiert ist. (*iOS*, *Android*, *BlackBerry 10*)\n\n*   `cordova.file.applicationStorageDirectory`-Root-Verzeichnis der Anwendungs-Sandbox; auf iOS ist schreibgeschützt (aber bestimmte Unterverzeichnisse [wie `/Documents` ] sind Lese-und Schreibzugriff). Alle enthaltene Daten ist für die app privat. ( *iOS*, *Android*, *BlackBerry 10*)\n\n*   `cordova.file.dataDirectory`-Beständige und private Datenspeicherung innerhalb der Anwendungs-Sandbox, die mit internen Speicher (auf Android, externen Speicher verwenden, verwenden Sie `.externalDataDirectory` ). Auf iOS, ist dieses Verzeichnis nicht mit iCloud synchronisiert (verwenden Sie `.syncedDataDirectory` ). (*iOS*, *Android*, *BlackBerry 10*)\n\n*   `cordova.file.cacheDirectory`-Verzeichnis der zwischengespeicherten Daten-Dateien oder Dateien, die Ihre app einfach neu erstellen können. Das Betriebssystem kann diese Dateien löschen, wenn das Gerät auf Speicher knapp wird, dennoch sollten die apps vom Betriebssystem zum Löschen von Dateien hier nicht verlassen. (*iOS*, *Android*, *BlackBerry 10*)\n\n*   `cordova.file.externalApplicationStorageDirectory`-Anwendungsraum auf externen Speicher. (*Android*)\n\n*   `cordova.file.externalDataDirectory`-Wo, app-spezifische Datendateien auf externen Speicher setzen. (*Android*)\n\n*   `cordova.file.externalCacheDirectory`-Anwendungscache auf externen Speicher. (*Android*)\n\n*   `cordova.file.externalRootDirectory`-Externer Speicher (SD-Karte) Stamm. (*Android*, *BlackBerry 10*)\n\n*   `cordova.file.tempDirectory`-Temp-Verzeichnis, dem das OS auf deaktivieren können wird. Verlassen Sie sich nicht auf das Betriebssystem, um dieses Verzeichnis zu löschen; Ihre Anwendung sollte immer Dateien gegebenenfalls entfernen. (*iOS*)\n\n*   `cordova.file.syncedDataDirectory`-Hält app-spezifische Dateien, die (z. B. auf iCloud) synchronisiert werden sollten. (*iOS*)\n\n*   `cordova.file.documentsDirectory`-Dateien für die app, aber privat sind sinnvoll, andere Anwendungen (z.B. Office-Dateien). (*iOS*)\n\n*   `cordova.file.sharedDirectory`-Dateien für alle Anwendungen (*BlackBerry 10* weltweit verfügbar)\n\n## Dateisystemlayouts\n\nObwohl technisch ein Implementierungsdetail, kann es sehr hilfreich zu wissen, wie die `cordova.file.*`-Eigenschaften physikalische Pfade auf einem echten Gerät zugeordnet sein.\n\n### iOS-Datei-System-Layout\n\n| Gerätepfad                                   | `Cordova.file.*`            | `iosExtraFileSystems` | R/w? | persistent? | OS löscht  | Sync | Private |\n|:-------------------------------------------- |:--------------------------- |:--------------------- |:----:|:-----------:|:----------:|:----:|:-------:|\n| `/ Var/mobile/Applications/< UUID > /` | applicationStorageDirectory | -                     |  r   |     N/A     |    N/A     | N/A  |   Ja    |\n|    `appname.app/`                            | applicationDirectory        | Bundle                |  r   |     N/A     |    N/A     | N/A  |   Ja    |\n|       `www/`                                 | -                           | -                     |  r   |     N/A     |    N/A     | N/A  |   Ja    |\n|    `Documents/`                              | documentsDirectory          | Dokumente             | R/w  |     Ja      |    Nein    |  Ja  |   Ja    |\n|       `NoCloud/`                             | -                           | Dokumente-nosync      | R/w  |     Ja      |    Nein    | Nein |   Ja    |\n|    `Library`                                 | -                           | Bibliothek            | R/w  |     Ja      |    Nein    | Ja?  |   Ja    |\n|       `NoCloud/`                             | dataDirectory               | Bibliothek-nosync     | R/w  |     Ja      |    Nein    | Nein |   Ja    |\n|       `Cloud/`                               | syncedDataDirectory         | -                     | R/w  |     Ja      |    Nein    |  Ja  |   Ja    |\n|       `Caches/`                              | cacheDirectory              | Cache                 | R/w  |    Ja *     | Ja * * *| | Nein |   Ja    |\n|    `tmp/`                                    | tempDirectory               | -                     | R/w  |  Nicht * *  | Ja * * *| | Nein |   Ja    |\n\n* Dateien werden hinweg app Neustarts und Upgrades beibehalten, aber dieses Verzeichnis kann gelöscht werden, wenn das OS begehrt. Ihre Anwendung sollte in der Lage, Inhalte zu erschaffen, die möglicherweise gelöscht werden.\n\n* *-Dateien kann über app-Neustarts beizubehalten, aber verlasse dich nicht auf dieses Verhalten. Dateien sind nicht unbedingt Aktuelles beibehalten. Ihre Anwendung sollte Dateien aus diesem Verzeichnis entfernen, wenn es gilt, diese Dateien werden entfernt, da das OS nicht wann (oder auch wenn) garantiert.\n\n* * *| The OS kann den Inhalt dieses Verzeichnisses löschen, wenn es sich anfühlt, ist es erforderlich, aber verlassen Sie sich nicht dazu. Sie sollten dieses Verzeichnis entsprechend Ihrer Anwendung deaktivieren.\n\n### Android File System-Layout\n\n| Gerätepfad                        | `Cordova.file.*`                    | `AndroidExtraFileSystems` | R/w? | persistent? | OS löscht | Private |\n|:--------------------------------- |:----------------------------------- |:------------------------- |:----:|:-----------:|:---------:|:-------:|\n| `file:///android_asset/`          | applicationDirectory                |                           |  r   |     N/A     |    N/A    |   Ja    |\n| `/ Data/Data/< app-Id > /`  | applicationStorageDirectory         | -                         | R/w  |     N/A     |    N/A    |   Ja    |\n|    `cache`                        | cacheDirectory                      | Cache                     | R/w  |     Ja      |   Ja *    |   Ja    |\n|    `files`                        | dataDirectory                       | Dateien                   | R/w  |     Ja      |   Nein    |   Ja    |\n|       `Documents`                 |                                     | Dokumente                 | R/w  |     Ja      |   Nein    |   Ja    |\n| `< Sdcard > /`              | externalRootDirectory               | sdcard                    | R/w  |     Ja      |   Nein    |  Nein   |\n|    `Android/data/<app-id>/` | externalApplicationStorageDirectory | -                         | R/w  |     Ja      |   Nein    |  Nein   |\n|       `cache`                     | externalCacheDirectry               | Cache-extern              | R/w  |     Ja      | Nicht * * |  Nein   |\n|       `files`                     | externalDataDirectory               | Dateien-extern            | R/w  |     Ja      |   Nein    |  Nein   |\n\n* Das Betriebssystem kann regelmäßig dieses Verzeichnis zu löschen, aber verlasse dich nicht auf dieses Verhalten. Deaktivieren Sie den Inhalt dieses Verzeichnisses für Ihre Anwendung geeigneten. Ein Benutzer den Cache manuell löschen sollte, werden die Inhalte dieses Verzeichnisses entfernt.\n\n* * The OS nicht klar dieses Verzeichnis automatisch; Sie sind verantwortlich für die Inhalte selbst verwalten. Der Benutzer den Cache manuell löschen sollte, werden der Inhalt des Verzeichnisses entfernt.\n\n**Hinweis**: Wenn externe Speichergeräte nicht bereitgestellt werden kann, sind die `cordova.file.external*` Eigenschaften `null`.\n\n### BlackBerry 10-File-System-Layout\n\n| Gerätepfad                                          | `Cordova.file.*`            | R/w? | persistent? | OS löscht | Private |\n|:--------------------------------------------------- |:--------------------------- |:----:|:-----------:|:---------:|:-------:|\n| `file:///Accounts/1000/APPDATA/ < app Id > /` | applicationStorageDirectory |  r   |     N/A     |    N/A    |   Ja    |\n|    `app/native`                                     | applicationDirectory        |  r   |     N/A     |    N/A    |   Ja    |\n|    `data/webviews/webfs/temporary/local__0`         | cacheDirectory              | R/w  |    Nein     |    Ja     |   Ja    |\n|    `data/webviews/webfs/persistent/local__0`        | dataDirectory               | R/w  |     Ja      |   Nein    |   Ja    |\n| `file:///Accounts/1000/Removable/sdcard`            | externalRemovableDirectory  | R/w  |     Ja      |   Nein    |  Nein   |\n| `file:///Accounts/1000/Shared`                      | sharedDirectory             | R/w  |     Ja      |   Nein    |  Nein   |\n\n*Hinweis*: Wenn die Anwendung bereitgestellt wird, um Perimeter zu arbeiten, alle Pfade sind relativ /accounts/1000-enterprise.\n\n## Android Eigenarten\n\n### Android permanenten Speicherort\n\nEs gibt mehrere gültige Speicherorte, persistente Dateien auf einem Android-Gerät zu speichern. Finden Sie auf [dieser Seite][3] eine ausführliche Diskussion über die verschiedenen Möglichkeiten.\n\n [3]: http://developer.android.com/guide/topics/data/data-storage.html\n\nFrühere Versionen des Plugins wählen würde, den Speicherort der temporären und permanenten Dateien beim Start, basierend auf, ob das Gerät behauptete, dass die SD-Karte (oder gleichwertige Speicherpartition) bereitgestellt wurde. Wenn die SD-Karte eingelegt wurde, oder wenn eine große interne Speicherpartition verfügbar war (wie auf Nexus-Geräten) und dann in die Wurzel dieses Raumes, die persistenten Dateien gespeichert werden. Dies bedeutete, dass alle Cordova apps aller verfügbaren Dateien auf der Karte sehen konnte.\n\nWenn die SD-Karte nicht verfügbar war, dann Vorgängerversionen Daten unter speichern würde `/data/data/<packageId>`, die isoliert Anwendungen voneinander, aber möglicherweise noch Ursache Daten zwischen Benutzern freigegeben werden.\n\nEs ist jetzt möglich, ob Sie Dateien der internen Datei-Speicherort oder unter Verwendung der bisherigen Logik, mit einer Präferenz in der Anwendung-`config.xml`-Datei speichern möchten. Hierzu fügen Sie eine dieser zwei Zeilen zu `\"config.xml\"`:\n\n    <preference name=\"AndroidPersistentFileLocation\" value=\"Internal\" />\n    \n    <preference name=\"AndroidPersistentFileLocation\" value=\"Compatibility\" />\n    \n\nOhne diese Zeile wird das Datei Plugin `Compatibility` als Standard verwenden. Wenn ein Präferenz-Tag vorhanden ist, und nicht einen der folgenden Werte, wird die Anwendung nicht gestartet.\n\nWenn Ihre Anwendung für Benutzer zuvor versandt wird, mithilfe eines älteren (Pre-1.0) Version dieses Plugins und gespeicherte Dateien im permanenten Dateisystem hat, dann sollten Sie die Einstellung zur `Compatibility` einstellen. Wechseln die Location auf \"Internal\" würde bedeuten, dass Benutzer, die aktualisieren Sie ihre Anwendung, möglicherweise nicht auf ihre zuvor gespeicherte Dateien, abhängig von ihrem Gerät zugreifen.\n\nWenn Ihre Anwendung neu ist, oder nie zuvor Dateien im Dateisystem persistent gespeichert hat, wird die `Internal` Einstellung in der Regel empfohlen.\n\n## iOS Macken\n\n*   `cordova.file.applicationStorageDirectory`ist schreibgeschützt; zum Speichern von Dateien im Stammverzeichnis der Versuch schlägt fehl. Verwenden Sie eine der anderen `cordova.file.*` für iOS definierten Eigenschaften (nur `applicationDirectory` und `applicationStorageDirectory` sind schreibgeschützt).\n*   `FileReader.readAsText(blob, encoding)` \n    *   Die `encoding` Parameter wird nicht unterstützt und UTF-8-Kodierung ist immer wirksam.\n\n### iOS permanenten Speicherort\n\nEs gibt zwei gültige Speicherorte persistente Dateien auf ein iOS-Gerät speichern: das Dokumenten-Verzeichnis und das Verzeichnis Library. Frühere Versionen des Plugins gespeichert immer nur persistente Dateien im Verzeichnis Dokumente. Dies hatte den Nebeneffekt einer Anwendung Dateien in iTunes, die oft unbeabsichtigte, speziell für Anwendungen, die viele kleine Dateien behandeln war, sichtbar zu machen, anstatt komplette Dokumente für den Export, die den beabsichtigten Zweck des Verzeichnisses ist zu produzieren.\n\nEs ist jetzt möglich, ob Sie Dateien in Dokumente oder Verzeichnis Library mit einer Präferenz in der Anwendung-`config.xml`-Datei speichern möchten. Hierzu fügen Sie eine dieser zwei Zeilen zu `\"config.xml\"`:\n\n    <preference name=\"iosPersistentFileLocation\" value=\"Library\" />\n    \n    <preference name=\"iosPersistentFileLocation\" value=\"Compatibility\" />\n    \n\nOhne diese Zeile wird das Datei Plugin `Compatibility` als Standard verwenden. Wenn ein Präferenz-Tag vorhanden ist, und nicht einen der folgenden Werte, wird die Anwendung nicht gestartet.\n\nWenn Ihre Anwendung für Benutzer zuvor versandt wird, mithilfe eines älteren (Pre-1.0) Version dieses Plugins und gespeicherte Dateien im permanenten Dateisystem hat, dann sollten Sie die Einstellung zur `Compatibility` einstellen. Standort zur `Library` wechseln würde bedeuten, dass Benutzer, die ihre Anwendung aktualisieren nicht in der Lage wäre, ihre zuvor gespeicherte Dateien zugreifen.\n\nWenn die Anwendung neu, oder nie zuvor Dateien im Dateisystem persistent gespeichert hat, wird die Einstellung der `Library` allgemein empfohlen.\n\n## Firefox OS Macken\n\nDer Datei-System-API wird von Firefox-OS nicht nativ unterstützt und wird als ein Shim auf IndexedDB implementiert.\n\n*   Schlägt nicht fehl, wenn Sie nicht leere Verzeichnisse entfernen\n*   Metadaten wird für Verzeichnisse nicht unterstützt.\n*   Methoden `copyTo` und `moveTo` unterstützen keine Verzeichnisse\n\nDie folgenden Datenpfade werden unterstützt: * `applicationDirectory` - `xhr` verwendet, um lokale Dateien erhalten, die mit der app verpackt sind. *`dataDirectory` - für persistente app-spezifische Daten-Dateien. *`cacheDirectory` - Cache-Dateien, die app startet überleben sollte (Apps sollten nicht vom Betriebssystem zum Löschen von Dateien hier verlassen).\n\n## Browser-Eigenheiten\n\n### Gemeinsamen Macken und Bemerkungen\n\n*   Jeder Browser verwendet ein eigene Sandbox Dateisystem. IE und Firefox verwenden IndexedDB als Basis. Alle Browser verwenden Schrägstrich als Verzeichnistrennzeichen in einem Pfad.\n*   Directory-Einträge müssen nacheinander erstellt werden. Z. B. der Aufruf `fs.root.getDirectory (\"dir1/Ordner2 ', {create:true}, SuccessCallback, ErrorCallback)` schlägt fehl, wenn dir1 nicht existierte.\n*   Das Plugin fordert Benutzer die Berechtigung zum permanenten Speicher beim ersten Start Anwendung verwenden. \n*   Plugin unterstützt `Cdvfile://localhost` (lokale Ressourcen) nur. D.h. externe Ressourcen nicht über `Cdvfile` unterstützt.\n*   Das Plugin folgt nicht [\"File System API 8.3 Naming Einschränkungen\"][4].\n*   BLOB und Datei \"`close`-Funktion wird nicht unterstützt.\n*   `FileSaver` und `BlobBuilder` werden von diesem Plugin nicht unterstützt und müssen nicht geboren.\n*   Das Plugin unterstützt keine `RequestAllFileSystems`. Diese Funktion fehlt auch in den Spezifikationen.\n*   Einträge im Verzeichnis werden nicht entfernt werden, wenn Sie verwenden `create: true` Flag für vorhandenes Verzeichnis.\n*   Über Konstruktor erstellte Dateien werden nicht unterstützt. Sie sollten stattdessen die entry.file-Methode verwenden.\n*   Jeder Browser verwendet eine eigene Form für Blob-URL-Verweise.\n*   `readAsDataURL`-Funktion wird unterstützt, aber die Mediatype in Chrom hängt von der Eintrag Namenerweiterung, Mediatype im IE immer leer ist (das ist dasselbe wie `Text-Plain` gemäß der Spezifikation), Mediatype in Firefox ist immer `Application/Octet-Stream`. Beispielsweise, wenn der Inhalt `Abcdefg` gibt dann Firefox `Daten: Anwendung / Octet-Stream; base64, YWJjZGVmZw ==`, IE gibt `Daten:; base64, YWJjZGVmZw ==`, Chrom gibt `Daten: < Mediatype je nach Erweiterung des Eintragsnamens >; base64, YWJjZGVmZw ==`.\n*   `ToInternalURL` gibt den Pfad zurück, in der Form `file:///persistent/path/to/entry` (Firefox, IE). Chrom gibt den Pfad zurück, in der Form `cdvfile://localhost/persistent/file`.\n\n [4]: http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions\n\n### Chrom-Macken\n\n*   Chrom-Dateisystem ist nicht sofort nach Gerät bereit. Als Workaround können Sie `FilePluginIsReady`-Ereignis abonnieren. Beispiel: \n\n    javascript\n    window.addEventListener('filePluginIsReady', function(){ console.log('File plugin is ready');}, false);\n    \n\n`Window.isFilePluginReadyRaised`-Funktion können Sie überprüfen, ob Ereignis bereits ausgelöst wurde. -window.requestFileSystem temporär und PERSISTENTE Dateisystem-Quoten sind nicht begrenzt, in Chrom. -Um die dauerhafte Speicherung in Chrom zu erhöhen benötigen Sie `window.initPersistentFileSystem`-Methode aufrufen. Permanenter Speicherkontingent beträgt 5 MB standardmäßig. -Chrome erforderlich `--erlauben-Datei-Zugriff-aus-Files` Argument an den Support API via `file:///` Protokoll führen. -`Datei`-Objekt wird nicht geändert werden, wenn Sie Flag verwenden `{create:true}` als einen vorhandenen `Eintrag` zu erhalten. -Veranstaltungen `cancelable`-Eigenschaft festgelegt ist in Chrom wahr. Dies widerspricht der [Spezifikation][5]. -`toURL`-Funktion in Chrome zurück `Dateisystem:`-Pfad je nach Anwendungshost vorangestellt. Z. B. `filesystem:file:///persistent/somefile.txt`, `Filesystem:http://localhost:8080/persistent/somefile.txt`. -`toURL` Funktionsergebnis enthält keine nachgestellten Schrägstrich bei Verzeichniseintrag. Chrom löst Verzeichnisse mit Schrägstrich-gezogene Urls aber korrekt. -`ResolveLocalFileSystemURL`-Methode erfordert die eingehenden `Url` `Dateisystem` Präfix haben. Beispielsweise sollte die `Url`-Parameter für `ResolveLocalFileSystemURL` in der Form `filesystem:file:///persistent/somefile.txt` im Gegensatz zu der Form `file:///persistent/somefile.txt` in Android. -Veraltete `ToNativeURL`-Funktion wird nicht unterstützt und muss keinen Stub. -`SetMetadata`-Funktion ist nicht in den Spezifikationen angegeben und nicht unterstützt. -INVALID_MODIFICATION_ERR (Code: 9) wird ausgelöst, statt SYNTAX_ERR(code: 8) auf anfordern des Dateisystems nicht existent. -INVALID_MODIFICATION_ERR (Code: 9) wird ausgelöst, anstatt PATH_EXISTS_ERR(code: 12) zu versuchen, die ausschließlich eine Datei oder ein Verzeichnis zu erstellen, die bereits vorhanden ist. -INVALID_MODIFICATION_ERR (Code: 9) wird ausgelöst, anstatt NO_MODIFICATION_ALLOWED_ERR(code: 6) zu versuchen, rufen Sie RemoveRecursively auf das Root-Dateisystem. -INVALID_MODIFICATION_ERR (Code: 9) wird ausgelöst, anstatt NOT_FOUND_ERR(code: 1) zu versuchen, MoveTo-Verzeichnis, das nicht vorhanden ist.\n\n [5]: http://dev.w3.org/2009/dap/file-system/file-writer.html\n\n### Auf der Grundlage von IndexedDB Impl Macken (Firefox und IE)\n\n*   `.` und `.` werden nicht unterstützt.\n*   IE unterstützt keine `file:///`-Modus; nur der Modus für gehostete ist unterstützten (Http://localhost:xxxx).\n*   Firefox Dateisystem Größe ist nicht begrenzt, aber jede 50MB-Erweiterung wird eine Benutzer die Berechtigung anzufordern. IE10 können bis zu 10mb kombinierte AppCache und IndexedDB in Implementierung des Dateisystems verwendet, ohne Aufforderung, sobald Sie dieses Niveau, werden, das Sie aufgefordert werden schlagen, wenn Sie es bis Max 250 mb pro Standort erhöht werden sollen. `Size`-Parameter für `RequestFileSystem` Funktion wirkt also nicht Dateisystem in Firefox und IE.\n*   `ReadAsBinaryString` Funktion heißt es nicht in die Angaben und in IE nicht unterstützt und muss keinen Stub.\n*   `file.Type` ist immer null.\n*   Sie sollten nicht erstellen Eintrag mit DirectoryEntry Instanz Rückrufergebnis, die gelöscht wurde. Andernfalls erhalten Sie einen \"hängende Eintrag\".\n*   Bevor Sie eine Datei lesen können, die gerade geschrieben wurde, müssen Sie eine neue Instanz dieser Datei erhalten.\n*   `SetMetadata`-Funktion, die nicht in den Specs genannt unterstützt Feldänderung nur `ModificationTime`. \n*   `CopyTo` und `MoveTo`-Funktionen unterstützen keine Verzeichnisse.\n*   Verzeichnisse-Metadaten werden nicht unterstützt.\n*   Beide Entry.remove und directoryEntry.removeRecursively nicht scheitern, wenn nicht leere Verzeichnisse entfernen - Verzeichnisse entfernt werden stattdessen zusammen mit Inhalt gereinigt.\n*   `abort` und `truncate`-Funktionen werden nicht unterstützt.\n*   Progress-Ereignisse werden nicht ausgelöst. Beispielsweise wird dieser Handler nicht ausgeführt werden:\n\n    javascript\n    writer.onprogress = function() { /*commands*/ };\n    \n\n## Upgrade Notes\n\nIn v1.0.0 dieses Plugins haben die `FileEntry` und `DirectoryEntry` Strukturen geändert, um mehr im Einklang mit der veröffentlichten Spezifikation sein.\n\nVorgängerversionen (Pre-1.0.0) des Plugins den Gerät-Absolute-Dateispeicherort in der Eigenschaft `fullPath` `Entry` Objekte gespeichert. Diese Pfade würde in der Regel aussehen\n\n    /var/mobile/Applications/<application UUID>/Documents/path/to/file  (iOS)\n    /storage/emulated/0/path/to/file                                    (Android)\n    \n\nDiese Pfade wurden auch von der `toURL()`-Methode der `Entry` Objekte zurückgegeben.\n\nMit v1.0.0 ist das `fullPath`-Attribut den Pfad zu der Datei, *relativ zum Stammverzeichnis des Dateisystems HTML*. Also, würde die oben genannten Wege jetzt beide durch ein `FileEntry`-Objekt mit einem `fullPath` von dargestellt werden\n\n    /path/to/file\n    \n\nWenn Ihre Anwendung mit absoluter Gerätepfade arbeitet und Sie zuvor diese Pfade durch die Eigenschaft `fullPath` `Entry` Objekte abgerufen, sollten dann Sie den Code, um stattdessen `entry.toURL()` verwenden aktualisieren.\n\nFür rückwärts Kompatibilität, die `resolveLocalFileSystemURL()`-Methode wird einen Absolute-Gerätepfad zu akzeptieren und kehrt ein `Entry`-Objekt entspricht, solange diese Datei in den `TEMPORARY` oder `PERSISTENT` Dateisysteme existiert.\n\nDies wurde vor allem ein Problem mit dem File-Transfer-Plugin, die zuvor-Absolute-Gerätepfade verwendet (und kann damit noch einverstanden). Es wurde überarbeitet, um mit Dateisystem-URLs korrekt zu arbeiten, damit ersetzen `entry.fullPath` mit `entry.toURL()` immer das Plugin zum Arbeiten mit Dateien auf dem Gerät Probleme lösen sollte.\n\nIn v1.1.0 wurde der Rückgabewert von `toURL()` (siehe \\[CB-6394\\] (https://issues.apache.org/jira/browse/CB-6394)) geändert, um eine absolute \"file://\" URL zurückgeben. wo immer möglich. Sicherstellung einer ' Cdvfile:'-URL können Sie an `toInternalURL()`. Diese Methode gibt jetzt Dateisystem URLs der Form zurück.\n\n    cdvfile://localhost/persistent/path/to/file\n    \n\ndie benutzt werden können, um die Datei eindeutig zu identifizieren.\n\n## Liste der Fehlercodes und Bedeutungen\n\nWenn ein Fehler ausgelöst wird, wird eines der folgenden Codes verwendet werden.\n\n| Code | Konstante                     |\n| ----:|:----------------------------- |\n|    1 | `NOT_FOUND_ERR`               |\n|    2 | `SECURITY_ERR`                |\n|    3 | `ABORT_ERR`                   |\n|    4 | `NOT_READABLE_ERR`            |\n|    5 | `ENCODING_ERR`                |\n|    6 | `NO_MODIFICATION_ALLOWED_ERR` |\n|    7 | `INVALID_STATE_ERR`           |\n|    8 | `SYNTAX_ERR`                  |\n|    9 | `INVALID_MODIFICATION_ERR`    |\n|   10 | `QUOTA_EXCEEDED_ERR`          |\n|   11 | `TYPE_MISMATCH_ERR`           |\n|   12 | `PATH_EXISTS_ERR`             |\n\n## Konfigurieren das Plugin (Optional)\n\nDie Menge der verfügbaren Dateisysteme kann pro Plattform konfiguriert sein. Erkennen von iOS und Android ein <preference> Tag in `\"config.xml\"` die Namen der Dateisysteme installiert werden. Standardmäßig sind alle Datei-System-Roots aktiviert.\n\n    <preference name=\"iosExtraFilesystems\" value=\"library,library-nosync,documents,documents-nosync,cache,bundle,root\" />\n    <preference name=\"AndroidExtraFilesystems\" value=\"files,files-external,documents,sdcard,cache,cache-external,root\" />\n    \n\n### Android\n\n*   `files`: interne Datei-Speicher-Verzeichnis der Anwendung\n*   `files-external`: Verzeichnis der Anwendung externe Datei Speicher\n*   `sdcard`: das externe Globaldatei-Speicherverzeichnis (Dies ist die Wurzel der SD-Karte, sofern installiert). Sie benötigen die Berechtigung zur Verwendung dieses `android.permission.WRITE_EXTERNAL_STORAGE`.\n*   `cache`: internen Cache-Verzeichnis der Anwendung\n*   `cache-external`: externer Cache-Verzeichnis der Anwendung\n*   `root`: das gesamte Gerät-Dateisystem\n\nAndroid unterstützt auch eine spezielle Dateisystem mit dem Namen \"documents\", die ein Unterverzeichnis \"/Documents/\" die \"files\" Dateisystem darstellt.\n\n### iOS\n\n*   `library`: Bibliothek-Verzeichnis der Anwendung\n*   `documents`: Dokumente-Verzeichnis der Anwendung\n*   `cache`: Cache-Verzeichnis der Anwendung\n*   `bundle`: die Anwendung Bündel; den Speicherort der die app selbst auf dem Datenträger (schreibgeschützt)\n*   `root`: das gesamte Gerät-Dateisystem\n\nStandardmäßig können die Bibliothek und Dokumenten-Verzeichnisse mit iCloud synchronisiert werden. Sie können auch verlangen, zwei zusätzliche Dateisysteme, `library-nosync` und `documents-nosync`, die einem speziellen nicht synchronisierten Verzeichnis innerhalb darstellen der `/Library` oder `/Documents`-Dateisystem.\n"
  },
  {
    "path": "plugins/cordova-plugin-file/doc/de/plugins.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# Hinweise für Plugin-Entwickler\n\nDiese Notizen sind hauptsächlich für Android und iOS-Entwickler, die Plugins welche Schnittstelle mit dem Dateisystem, mit dem Plugin Datei schreiben möchten.\n\n## Arbeiten mit Cordova-Datei-System-URLs\n\nSeit der Version 1.0.0, wurde dieses Plugin verwendet URLs mit einer `cdvfile` Regelung für die gesamte Kommunikation über die Brücke, sondern als raw-Device Dateisystempfade zu JavaScript auszusetzen.\n\nAuf der Seite JavaScript bedeutet dies, dass FileEntries und DirectoryEntry-Objekt ein FullPath-Attribut haben, die relativ zum Stammverzeichnis des Dateisystems HTML ist. Wenn Ihr Plugins-JavaScript-API ein FileEntries oder DirectoryEntry-Objekt akzeptiert, rufen Sie `.toURL()` auf das Objekt vor der Übergabe an systemeigenen Code über die Brücke.\n\n### Konvertieren von Cdvfile: / / URLs auf Fileystem Pfade\n\nPlugins, die auf das Dateisystem schreiben müssen, sollten eine empfangene Datei-System-URL auf eine tatsächliche Stelle des Dateisystems zu konvertieren. Es gibt mehrere Wege, dies zu tun, je nach einheitlichen Plattform.\n\nEs ist wichtig, daran erinnern, dass nicht alle `cdvfile://` URLs sind zuweisbaren real Dateien auf das Gerät. Einige URLs verweisen auf Vermögenswerte auf Gerät nicht durch Dateien dargestellt werden, oder sogar auf Remoteressourcen verweisen können. Aufgrund dieser Möglichkeiten sollten Plugins immer testen, ob sie ein sinnvolles Ergebnis zu erhalten, wieder bei dem Versuch, die URLs in Pfade umwandeln.\n\n#### Android\n\nAuf Android, konvertiert die einfachste Methode eine `cdvfile://` URL zu einem Dateisystempfad zu verwenden ist `org.apache.cordova.CordovaResourceApi` . `CordovaResourceApi`verfügt über mehrere Methoden der verarbeiten kann `cdvfile://` URLs:\n\n    WebView ist Mitglied der Plugin-Klasse CordovaResourceApi ResourceApi = webView.getResourceApi();\n    \n    Erhalten eine file:/// URL, diese Datei auf dem Gerät / / oder die gleiche URL unverändert, wenn es eine Datei-Uri FileURL zugeordnet werden kann nicht = resourceApi.remapUri(Uri.parse(cdvfileURL));\n    \n\nEs ist auch möglich, das Plugin Datei direkt zu verwenden:\n\n    Import org.apache.cordova.file.FileUtils;\n    Import org.apache.cordova.file.FileSystem;\n    Import Java.net.MalformedURLException:;\n    \n    Erhalten Sie das Datei-Plugin aus dem Plugin-Manager FileUtils FilePlugin = (FileUtils)webView.pluginManager.getPlugin(\"File\");\n    \n    Angesichts eine URL, einen Pfad zu erhalten, denn es versuchen {String Pfad = filePlugin.filesystemPathForURL(cdvfileURL);} catch (MalformedURLException e) {/ / die Dateisystem-Url war nicht erkannt}\n    \n\nAus einem Pfad zu konvertieren eine `cdvfile://` URL:\n\n    Import org.apache.cordova.file.LocalFilesystemURL;\n    \n    Rufen Sie ein LocalFilesystemURL-Objekt für einen Gerätepfad / / oder null, wenn sie nicht als URL Cdvfile dargestellt wird.\n    LocalFilesystemURL Url = filePlugin.filesystemURLforLocalPath(path);\n    Erhalten Sie die Zeichenfolgendarstellung der URL Objekt String CdvfileURL = url.toString();\n    \n\nWenn Ihr Plugin eine Datei erstellt, und Sie dafür ein FileEntries-Objekt zurückgeben möchten, verwenden Sie das Datei-Plugin:\n\n    Zurückgeben eine JSON-Struktur geeignet für die Rückgabe an JavaScript, / / oder null, wenn diese Datei nicht als URL Cdvfile darstellbar ist.\n    JSONObject Eintrag = filePlugin.getEntryForFile(file);\n    \n\n#### iOS\n\nCordova auf iOS verwendet nicht das gleiche `CordovaResourceApi` Konzept als Android. Auf iOS sollten Sie das Datei-Plugin verwenden, zum Konvertieren von URLs und Dateisystem-Pfaden.\n\n    Rufen Sie ein CDVFilesystem URL-Objekt von einer URL-Zeichenfolge CDVFilesystemURL * Url = [CDVFilesystemURL FileSystemURLWithString:cdvfileURL];\n    Erhalten Sie einen Pfad für die URL-Objekt oder NULL, wenn es einen Dateipfad NSString * zugeordnet werden kann nicht = [FilePlugin FilesystemPathForURL:url];\n    \n    \n    Eine CDVFilesystem URL-Objekt für einen Gerätepfad abrufen oder / / gleich NULL, wenn sie nicht als URL Cdvfile dargestellt wird.\n    CDVFilesystemURL-Url = [FilePlugin FileSystemURLforLocalPath:path];\n    Erhalten Sie die Zeichenfolgendarstellung der URL Objekt NSString * CdvfileURL = [Url AbsoluteString];\n    \n\nWenn Ihr Plugin eine Datei erstellt, und Sie dafür ein FileEntries-Objekt zurückgeben möchten, verwenden Sie das Datei-Plugin:\n\n    Eine CDVFilesystem URL-Objekt für einen Gerätepfad abrufen oder / / gleich NULL, wenn sie nicht als URL Cdvfile dargestellt wird.\n    CDVFilesystemURL-Url = [FilePlugin FileSystemURLforLocalPath:path];\n    Erhalten eine Struktur zurück nach JavaScript NSDictionary * Eintrag = [FilePlugin MakeEntryForLocalURL:url]\n    \n\n#### JavaScript\n\nIn JavaScript, bekommen eine `cdvfile://` URL aus einem FileEntries oder DirectoryEntry-Objekt, rufen Sie einfach `.toURL()` drauf:\n\n    Var CdvfileURL = entry.toURL();\n    \n\nIm Plugin Antwort Handler zur Konvertierung von einer zurückgegebenen FileEntries-Struktur in einem tatsächlichen Eintrag-Objekt sollte Handlercode importieren die Datei-Erweiterung und ein neues Objekt zu erstellen:\n\n    Erstellen Sie entsprechenden Eintrag Objekt Var Eintrag;\n    Wenn (entryStruct.isDirectory) {Eintrag = neues DirectoryEntry (entryStruct.name, entryStruct.fullPath, neue FileSystem(entryStruct.filesystemName));} sonst {Eintrag = neue FileEntries (entryStruct.name, entryStruct.fullPath, neue FileSystem(entryStruct.filesystemName));}"
  },
  {
    "path": "plugins/cordova-plugin-file/doc/es/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-file\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-file.svg)](https://travis-ci.org/apache/cordova-plugin-file)\n\nEste plugin implementa una API de archivo que permite acceso de lectura/escritura a los archivos que residen en el dispositivo.\n\nEste plugin se basa en varias especificaciones, incluyendo: el HTML5 archivo API <http://www.w3.org/TR/FileAPI/>\n\nLos directorios (ahora extinto) y sistema de extensiones más recientes: <http://www.w3.org/TR/2012/WD-file-system-api-20120417/> aunque la mayor parte del código del plugin fue escrito cuando una especificación anterior era actual: <http://www.w3.org/TR/2011/WD-file-system-api-20110419/>\n\nTambién implementa la especificación de FileWriter: <http://dev.w3.org/2009/dap/file-system/file-writer.html>\n\nPara el uso, por favor, consulte 'HTML5 Rocks excelente [FileSystem artículo.](http://www.html5rocks.com/en/tutorials/file/filesystem/)\n\nPara tener una visión general de otras opciones de almacenamiento, consulte [Guía de almacenamiento Cordova](http://cordova.apache.org/docs/en/edge/cordova_storage_storage.md.html).\n\nEste plugin define global `cordova.file` objeto.\n\nAunque en el ámbito global, no estará disponible hasta después de la `deviceready` evento.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(cordova.file);\n    }\n    \n\n## Instalación\n\n    cordova plugin add cordova-plugin-file\n    \n\n## Plataformas soportadas\n\n  * Amazon fire OS\n  * Android\n  * BlackBerry 10\n  * Firefox OS\n  * iOS\n  * Windows Phone 7 y 8 *\n  * Windows 8 *\n  * Windows*\n  * Explorador\n\n\\* *These platforms do not support `FileReader.readAsArrayBuffer` nor `FileWriter.write(blob)`.*\n\n## Donde almacenar los archivos\n\nA partir de v1.2.0, URLs a directorios de sistema de archivos importantes son proporcionadas. Cada dirección URL está en la forma *file:///path/to/spot/*y se puede convertir en un `DirectoryEntry` usando`window.resolveLocalFileSystemURL()`.\n\n  * `cordova.file.applicationDirectory`-Directorio Read-only donde está instalada la aplicación. (*iOS*, *Android*, *BlackBerry 10*)\n\n  * `cordova.file.applicationStorageDirectory`-Directorio del entorno limitado de la aplicación; en iOS esta ubicación es de sólo lectura (pero subdirectorios específicos [como `/Documents` ] son de lectura y escritura). Todos los datos contenidos dentro es privado para la aplicación. ( *iOS*, *Android*, *BlackBerry 10*)\n\n  * `cordova.file.dataDirectory`-Almacenamiento de datos persistente y privadas dentro de entorno limitado de la aplicación utilizando la memoria interna (en Android, si necesitas usar memoria externa, use `.externalDataDirectory` ). En iOS, este directorio no está sincronizado con iCloud (utilice `.syncedDataDirectory` ). (*iOS*, *Android*, *BlackBerry 10*)\n\n  * `cordova.file.cacheDirectory`-Directorio para los archivos de datos almacenados en caché o los archivos que su aplicación puede volver a crear fácilmente. El sistema operativo puede borrar estos archivos cuando el dispositivo se agota en almacenamiento de información, sin embargo, aplicaciones no deben confiar en el sistema operativo para eliminar los archivos de aquí. (*iOS*, *Android*, *BlackBerry 10*)\n\n  * `cordova.file.externalApplicationStorageDirectory`-Espacio aplicación de almacenamiento externo. (*Android*)\n\n  * `cordova.file.externalDataDirectory`¿Dónde poner los archivos de datos específicos de la aplicación de almacenamiento externo. (*Android*)\n\n  * `cordova.file.externalCacheDirectory`-Caché aplicación de almacenamiento externo. (*Android*)\n\n  * `cordova.file.externalRootDirectory`-Raíz de almacenamiento externo (tarjeta SD). (*Android*, *BlackBerry 10*)\n\n  * `cordova.file.tempDirectory`-Directorio temporal que puede borrar el sistema operativo en sí. No confíe en el sistema operativo para borrar este directorio; su aplicación siempre debe eliminar archivos según corresponda. (*iOS*)\n\n  * `cordova.file.syncedDataDirectory`-Contiene los archivos de la aplicación específica que deben ser sincronizados (e.g. a iCloud). (*iOS*)\n\n  * `cordova.file.documentsDirectory`-Archivos privados a la aplicación, pero que son significativos para otra aplicación (por ejemplo archivos de Office). (*iOS*)\n\n  * `cordova.file.sharedDirectory`-Archivos disponibles globalmente para todas las aplicaciones (*BlackBerry 10*)\n\n## Diseños de sistema de archivo\n\nAunque técnicamente un detalle de la implementación, puede ser muy útil saber cómo la `cordova.file.*` mapa de propiedades en trazados físicos en un dispositivo real.\n\n### iOS diseño de sistema de archivo\n\n| Ruta de dispositivo                            | `Cordova.file.*`            | `iosExtraFileSystems` | ¿r/w? | ¿persistente? |  OS despeja   | sincronización | privado |\n|:---------------------------------------------- |:--------------------------- |:--------------------- |:-----:|:-------------:|:-------------:|:--------------:|:-------:|\n| `/ var/mobile/Applications/< UUID > /`   | applicationStorageDirectory | -                     |   r   |     N / A     |     N / A     |     N / A      |   Sí    |\n| &nbsp;&nbsp;&nbsp;`appname.app/`               | applicationDirectory        | Bundle                |   r   |     N / A     |     N / A     |     N / A      |   Sí    |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`www/`     | -                           | -                     |   r   |     N / A     |     N / A     |     N / A      |   Sí    |\n| &nbsp;&nbsp;&nbsp;`Documents/`                 | documentsDirectory          | documentos            |  r/w  |      Sí       |      No       |       Sí       |   Sí    |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`NoCloud/` | -                           | documentos-nosync     |  r/w  |      Sí       |      No       |       No       |   Sí    |\n| &nbsp;&nbsp;&nbsp;`Library`                    | -                           | Biblioteca            |  r/w  |      Sí       |      No       |      ¿Sí?      |   Sí    |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`NoCloud/` | dataDirectory               | Biblioteca-nosync     |  r/w  |      Sí       |      No       |       No       |   Sí    |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`Cloud/`   | syncedDataDirectory         | -                     |  r/w  |      Sí       |      No       |       Sí       |   Sí    |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`Caches/`  | cacheDirectory              | caché                 |  r/w  |     Sí *      | Yes**\\* |       No       |   Sí    |\n| &nbsp;&nbsp;&nbsp;`tmp/`                       | tempDirectory               | -                     |  r/w  |   No**    | Yes**\\* |       No       |   Sí    |\n\n\\ * Archivos persisten a través de reinicios de aplicación y actualizaciones, pero este directorio puede ser despejó cuando el OS deseos. Su aplicación debe ser capaz de recrear cualquier contenido que puede ser eliminado.\n\n** Archivos puede persistir a través de la aplicación se reinicia, pero no confiar en este comportamiento. Los archivos no se garantizan que persisten a través de actualizaciones. Su aplicación debe eliminar los archivos de este directorio cuando es aplicable, como el sistema operativo no garantiza cuando (o incluso si) estos archivos se quitan.\n\n**\\ * OS la puede borrar el contenido de este directorio siempre que se siente es necesario, pero no dependen de esto. Debe borrar este directorio según sea apropiado para su aplicación.\n\n### Disposición del sistema Android File\n\n| Ruta de dispositivo                              | `Cordova.file.*`                    | `AndroidExtraFileSystems` | ¿r/w? | ¿persistente? | OS despeja | privado |\n|:------------------------------------------------ |:----------------------------------- |:------------------------- |:-----:|:-------------:|:----------:|:-------:|\n| `File:///android_asset/`                         | applicationDirectory                |                           |   r   |     N / A     |   N / A    |   Sí    |\n| `/Data/data/< id de aplicación > /`        | applicationStorageDirectory         | -                         |  r/w  |     N / A     |   N / A    |   Sí    |\n| &nbsp;&nbsp;&nbsp;`cache`                        | cacheDirectory                      | caché                     |  r/w  |      Sí       |  Sí \\ *   |   Sí    |\n| &nbsp;&nbsp;&nbsp;`files`                        | dataDirectory                       | archivos                  |  r/w  |      Sí       |     No     |   Sí    |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`Documents`  |                                     | documentos                |  r/w  |      Sí       |     No     |   Sí    |\n| `< sdcard > /`                             | externalRootDirectory               | sdcard                    |  r/w  |      Sí       |     No     |   No    |\n| &nbsp;&nbsp;&nbsp;`Android/data/<app-id>/` | externalApplicationStorageDirectory | -                         |  r/w  |      Sí       |     No     |   No    |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`cache`      | externalCacheDirectry               | caché-externo             |  r/w  |      Sí       |  No**  |   No    |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`files`      | externalDataDirectory               | archivos externos         |  r/w  |      Sí       |     No     |   No    |\n\n\\ * El sistema operativo periódicamente puede borrar este directorio, pero no confiar en este comportamiento. Borrar el contenido de este directorio según sea apropiado para su aplicación. El contenido de este directorio debe un usuario purga la caché manualmente, se eliminan.\n\n** El sistema operativo no borrar este directorio automáticamente; usted es responsable de administrar el contenido usted mismo. Deberá el usuario purga la caché manualmente, se extraen los contenidos del directorio.\n\n**Nota**: Si no se puede montar de almacenamiento externo, el `cordova.file.external*` Propiedades`null`.\n\n### Disposición del sistema blackBerry 10 archivo\n\n| Ruta de dispositivo                                           | `Cordova.file.*`            | ¿r/w? | ¿persistente? | OS despeja | privado |\n|:------------------------------------------------------------- |:--------------------------- |:-----:|:-------------:|:----------:|:-------:|\n| `File:///accounts/1000/AppData/ < id de aplicación > /` | applicationStorageDirectory |   r   |     N / A     |   N / A    |   Sí    |\n| &nbsp;&nbsp;&nbsp;`app/native`                                | applicationDirectory        |   r   |     N / A     |   N / A    |   Sí    |\n| &nbsp;&nbsp;&nbsp;`data/webviews/webfs/temporary/local__0`    | cacheDirectory              |  r/w  |      No       |     Sí     |   Sí    |\n| &nbsp;&nbsp;&nbsp;`data/webviews/webfs/persistent/local__0`   | dataDirectory               |  r/w  |      Sí       |     No     |   Sí    |\n| `File:///accounts/1000/Removable/sdcard`                      | externalRemovableDirectory  |  r/w  |      Sí       |     No     |   No    |\n| `File:///accounts/1000/shared`                                | sharedDirectory             |  r/w  |      Sí       |     No     |   No    |\n\n*Nota*: cuando se implementa la aplicación al trabajo de perímetro, todos los caminos son relativos a /accounts/1000-enterprise.\n\n## Rarezas Android\n\n### Ubicación de almacenamiento persistente Android\n\nHay múltiples ubicaciones válidas para almacenar archivos persistentes en un dispositivo Android. Vea [esta página](http://developer.android.com/guide/topics/data/data-storage.html) para una extensa discusión de las distintas posibilidades.\n\nLas versiones anteriores del plugin elegiría la ubicación de los archivos temporales y persistentes en el arranque, basado en si el dispositivo afirmó que fue montado en la tarjeta SD (o partición de almacenamiento equivalente). Si fue montada en la tarjeta SD, o una partición de gran almacenamiento interno estaba disponible (como en dispositivos de Nexus,) y luego los archivos persistentes se almacenaría en la raíz de ese espacio. Esto significaba que todas las apps Cordova podían ver todos los archivos disponibles en la tarjeta.\n\nSi la tarjeta SD no estaba disponible, entonces versiones anteriores podría almacenar datos debajo de `/data/data/<packageId>` , que aísla las apps del otro, pero puede todavía causa datos para ser compartido entre los usuarios.\n\nAhora es posible elegir si desea almacenar archivos en la ubicación de almacenamiento del archivo interno, o usando la lógica anterior, con una preferencia en de la aplicación `config.xml` archivo. Para ello, añada una de estas dos líneas a `config.xml` :\n\n    <preference name=\"AndroidPersistentFileLocation\" value=\"Internal\" />\n    \n    <preference name=\"AndroidPersistentFileLocation\" value=\"Compatibility\" />\n    \n\nSin esta línea, se utilizará el archivo plugin `Compatibility` como valor predeterminado. Si una etiqueta de preferencia está presente y no es uno de estos valores, no se iniciará la aplicación.\n\nSi su solicitud se ha enviado previamente a los usuarios, usando un mayor (1.0 pre) versión de este plugin y archivos almacenados en el sistema de ficheros persistente, entonces debería establecer la preferencia en `Compatibility` . Cambiar la ubicación para \"Internal\" significa que los usuarios existentes que actualización su aplicación pueden ser incapaces de acceder a sus archivos previamente almacenadas, dependiendo de su dispositivo.\n\nSi su solicitud es nuevo, o nunca antes ha almacenado archivos en el sistema de ficheros persistente, entonces el `Internal` generalmente se recomienda el ajuste.\n\n### Operaciones recursivas lento para /android_asset\n\nListado de directorios activos es realmente lento en Android. Usted puede acelerar hacia arriba, agregando `src/android/build-extras.gradle` a la raíz de tu proyecto android (también requiere de cordova-android@4.0.0 o mayor).\n\n## iOS rarezas\n\n  * `cordova.file.applicationStorageDirectory`es de sólo lectura; intentar almacenar archivos en el directorio raíz fallará. Utilice uno de los `cordova.file.*` las propiedades definidas para iOS (sólo `applicationDirectory` y `applicationStorageDirectory` son de sólo lectura).\n  * `FileReader.readAsText(blob, encoding)` \n      * El `encoding` no se admite el parámetro, y codificación UTF-8 es siempre en efecto.\n\n### iOS ubicación de almacenamiento persistente\n\nHay dos ubicaciones válidas para almacenar archivos persistentes en un dispositivo iOS: el directorio de documentos y el directorio de biblioteca. Las versiones anteriores del plugin sólo almacenan archivos persistentes en el directorio de documentos. Esto tenía el efecto secundario de todos los archivos de la aplicación haciendo visible en iTunes, que era a menudo involuntarios, especialmente para aplicaciones que manejan gran cantidad de archivos pequeños, en lugar de producir documentos completos para la exportación, que es la finalidad del directorio.\n\nAhora es posible elegir si desea almacenar archivos en los documentos o directorio de bibliotecas, con preferencia en de la aplicación `config.xml` archivo. Para ello, añada una de estas dos líneas a `config.xml` :\n\n    <preference name=\"iosPersistentFileLocation\" value=\"Library\" />\n    \n    <preference name=\"iosPersistentFileLocation\" value=\"Compatibility\" />\n    \n\nSin esta línea, se utilizará el archivo plugin `Compatibility` como valor predeterminado. Si una etiqueta de preferencia está presente y no es uno de estos valores, no se iniciará la aplicación.\n\nSi su solicitud se ha enviado previamente a los usuarios, usando un mayor (1.0 pre) versión de este plugin y archivos almacenados en el sistema de ficheros persistente, entonces debería establecer la preferencia en `Compatibility` . Cambiar la ubicación de `Library` significa que los usuarios existentes que actualización su aplicación sería incapaces de acceder a sus archivos previamente almacenadas.\n\nSi su solicitud es nuevo, o nunca antes ha almacenado archivos en el sistema de ficheros persistente, entonces el `Library` generalmente se recomienda el ajuste.\n\n## Firefox OS rarezas\n\nLa API de sistema de archivo de forma nativa no es compatible con Firefox OS y se implementa como una cuña en la parte superior indexedDB.\n\n  * No falla cuando eliminar directorios no vacía\n  * No admite metadatos para directorios\n  * Los métodos `copyTo` y `moveTo` no son compatibles con directorios\n\nSe admiten las siguientes rutas de datos: * `applicationDirectory` -usa `xhr` para obtener los archivos locales que están envasados con la aplicación. * `dataDirectory` - Para archivos de datos específicos de aplicación persistente. * `cacheDirectory` -En caché archivos que deben sobrevivir se reinicia la aplicación (aplicaciones no deben confiar en el sistema operativo para eliminar archivos aquí).\n\n## Navegador rarezas\n\n### Rarezas y observaciones comunes\n\n  * Cada navegador utiliza su propio sistema de ficheros un espacio aislado. IE y Firefox utilizan IndexedDB como base. Todos los navegadores utilizan diagonal como separador de directorio en un camino.\n  * Las entradas de directorio deben crearse sucesivamente. Por ejemplo, la llamada `fs.root.getDirectory (' dir1/dir2 ', {create:true}, successCallback, errorCallback)` se producirá un error si no existiera dir1.\n  * El plugin solicita permiso de usuario para usar almacenamiento persistente en el primer comienzo de la aplicación. \n  * Plugin soporta `cdvfile://localhost` (recursos locales) solamente. Es decir, no se admiten los recursos externos vía `cdvfile`.\n  * El plugin no sigue [\"Archivo sistema API 8.3 nombrando restricciones\"](http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions).\n  * BLOB y archivo ' `close` la función no es compatible.\n  * `FileSaver` y `BlobBuilder` no son compatibles con este plugin y no tengo recibos.\n  * El plugin no es compatible con `requestAllFileSystems`. Esta función también está desaparecida en las especificaciones.\n  * No se quitarán las entradas de directorio Si utilizas `create: true` bandera de directorio existente.\n  * No se admiten archivos creados mediante el constructor. Debe utilizar método entry.file en su lugar.\n  * Cada navegador utiliza su propia forma de blob URL referencias.\n  * se admite la función `readAsDataURL`, pero el mediatype en cromo depende de la extensión de nombre de entrada, mediatype en IE siempre está vacío (que es lo mismo como `plain-text` según la especificación), el mediatype en Firefox siempre es `application/octet-stream`. Por ejemplo, si el contenido es `abcdefg` entonces Firefox devuelve `datos: aplicación / octet-stream; base64, YWJjZGVmZw ==`, es decir devuelve `datos:; base64, YWJjZGVmZw ==`, cromo devuelve `datos: < mediatype dependiendo de la extensión de nombre de la entrada >; base64, YWJjZGVmZw ==`.\n  * `toInternalURL` devuelve la ruta de la forma `file:///persistent/path/to/entry` (Firefox, IE). Cromo devuelve la ruta de acceso en el formulario `cdvfile://localhost/persistent/file`.\n\n### Rarezas de Chrome\n\n  * Filesystem de Chrome no es inmediatamente después de evento ready dispositivo. Como solución temporal puede suscribirse al evento `filePluginIsReady`. Ejemplo: \n\n```javascript\nwindow.addEventListener('filePluginIsReady', function(){ console.log('File plugin is ready');}, false);\n```\n\nPuede utilizar la función `window.isFilePluginReadyRaised` para verificar si ya se provoca el evento. -window.requestFileSystem temporal y persistente filesystem cuotas no están limitadas en cromo. -Para aumentar el almacenamiento persistente en cromo necesitas llamar el método `window.initPersistentFileSystem`. Cuota de almacenamiento persistente es de 5 MB por defecto. -Chrome requiere `--permitir-archivo-acceso-de-archivos` ejecutar argumento al soporte API mediante protocolo `file:///`. -`Archivo` objeto no cambiará si utilizas bandera `{create:true}` cuando una `entrada` de existente. -eventos `cancelable` propiedad está establecida en true en cromo. Esto es contrario a la [Especificación](http://dev.w3.org/2009/dap/file-system/file-writer.html). -función de `toURL` en Chrome devuelve `filesystem:`-prefijo camino dependiendo de host de la aplicación. Por ejemplo, `filesystem:file:///persistent/somefile.txt`, `filesystem:http://localhost:8080/persistent/somefile.txt`. -resultado de la función de `toURL` no contiene barra en caso de entrada en el directorio. Cromo resuelve directorios con urls slash-siguió correctamente sin embargo. -método `resolveLocalFileSystemURL` requiere la entrantes `url` que tienen prefijo `filesystem`. Por ejemplo, el parámetro de `url` para `resolveLocalFileSystemURL` debería estar en la forma `filesystem:file:///persistent/somefile.txt` en comparación con la forma `file:///persistent/somefile.txt` en Android. -Obsoleto `toNativeURL` función no es compatible y no tiene un trozo. -función de `setMetadata` no es indicada en las especificaciones y no admite. -INVALID_MODIFICATION_ERR (código: 9) se lanza en lugar de SYNTAX_ERR(code: 8) a petición de un sistema de ficheros inexistentes. -INVALID_MODIFICATION_ERR (código: 9) se lanza en vez de PATH_EXISTS_ERR(code: 12) en intentar exclusivamente crear un archivo o directorio, que ya existe. -INVALID_MODIFICATION_ERR (código: 9) se lanza en lugar de NO_MODIFICATION_ALLOWED_ERR(code: 6) para tratar de llamar a removeRecursively en el sistema de archivos raíz. -INVALID_MODIFICATION_ERR (código: 9) se lanza en vez de NOT_FOUND_ERR(code: 1) en tratar de moveTo directorio que no existe.\n\n### Impl base IndexedDB rarezas (IE y Firefox)\n\n  * `.` y `..` no son compatibles.\n  * IE no soporta `file:///`-modo; modo alojado sólo es compatible (http://localhost:xxxx).\n  * Tamaño del sistema de archivos de Firefox no es limitada pero cada extensión de 50 MB solicitará un permiso de usuario. IE10 permite hasta 10mb de combinados AppCache y IndexedDB utilizados en la implementación del sistema de ficheros sin preguntar, cuando llegas a ese nivel que se le preguntará si desea permitir que ser aumentada hasta un máximo de 250 mb por sitio. Para que `size` parámetro para la función `requestFileSystem` no afecta sistema de ficheros en Firefox y IE.\n  * la función `readAsBinaryString` no se indica en las especificaciones y no compatible con IE y no tiene un trozo.\n  * `file.type` siempre es null.\n  * No debe crear entrada utilizando DirectoryEntry resultado de devolución de llamada de instancia que fue borrado. De lo contrario, obtendrá una entrada' colgar'.\n  * Antes de que se puede leer un archivo, el cual fue escrito sólo que necesitas una nueva instancia de este archivo.\n  * la función `setMetadata`, que no es indicada en las especificaciones soporta sólo el cambio de campo `modificationTime`. \n  * `copyTo` y `moveTo` funciones no son compatibles con directorios.\n  * Metadatos de directorios no es compatible.\n  * Tanto Entry.remove y directoryEntry.removeRecursively no fallan al retirar no vacía directorios - directorios de ser eliminados se limpian junto con contenido en su lugar.\n  * `abort` y `truncate` las funciones no son compatibles.\n  * eventos de progreso no están despedidos. Por ejemplo, este controlador no ejecutará:\n\n```javascript\nwriter.onprogress = function() { /*commands*/ };\n```\n\n## Actualización de notas\n\nEn v1.0.0 de este plugin, han cambiado las estructuras `FileEntry` y `DirectoryEntry`, para estar más acorde con las especificaciones publicadas.\n\nVersiones anteriores (pre-1.0.0) del plugin almacenan el dispositivo-absoluto-archivo-ubicación en la propiedad `fullPath` de objetos de `entrada`. Estos caminos típicamente parecería\n\n    /var/mobile/Applications/<application UUID>/Documents/path/to/file  (iOS)\n    /storage/emulated/0/path/to/file                                    (Android)\n    \n\nEstas rutas también fueron devueltos por el método `toURL()` de los objetos de `entrada`.\n\nCon v1.0.0, el atributo `fullPath` es la ruta del archivo, *relativo a la raíz del sistema de archivos HTML*. Así, los caminos más arriba sería ahora ambos ser representado por un objeto `FileEntry` con un `fullPath` de\n\n    /path/to/file\n    \n\nSi su aplicación funciona con dispositivo-absoluto-caminos, y previamente obtenido esos caminos a través de la propiedad `fullPath` de objetos de `Entry`, deberá actualizar el código para utilizar `entry.toURL()` en su lugar.\n\nPara atrás compatibilidad, el método `resolveLocalFileSystemURL()` a aceptar un dispositivo-absoluto-trayectoria y devolverá un objeto de `Entry` correspondiente que, mientras exista ese archivo dentro de los sistemas de ficheros `TEMPORARY` o la `PERSISTENT`.\n\nEsto ha sido particularmente un problema con el plugin de transferencia de archivos, que anteriormente utilizado dispositivo-absoluto-caminos (y todavía puede aceptarlas). Ha sido actualizado para funcionar correctamente con sistema de ficheros URLs, para reemplazar `entry.fullPath` con `entry.toURL()` debe resolver cualquier problema conseguir ese plugin para trabajar con archivos en el dispositivo.\n\nEn v1.1.0 el valor devuelto por `toURL()` fue cambiado (consulte \\[CB-6394\\] (https://issues.apache.org/jira/browse/CB-6394)) para devolver una dirección URL absoluta 'file://'. siempre que sea posible. Para asegurar una ' cdvfile:'-URL ahora puede utilizar `toInternalURL()`. Este método devolverá ahora filesystem URLs de la forma\n\n    cdvfile://localhost/persistent/path/to/file\n    \n\nque puede utilizarse para identificar el archivo únicamente.\n\n## Lista de códigos de Error y significados\n\nCuando se produce un error, uno de los siguientes códigos se utilizará.\n\n| Código | Constante                     |\n| ------:|:----------------------------- |\n|      1 | `NOT_FOUND_ERR`               |\n|      2 | `SECURITY_ERR`                |\n|      3 | `ABORT_ERR`                   |\n|      4 | `NOT_READABLE_ERR`            |\n|      5 | `ENCODING_ERR`                |\n|      6 | `NO_MODIFICATION_ALLOWED_ERR` |\n|      7 | `INVALID_STATE_ERR`           |\n|      8 | `SYNTAX_ERR`                  |\n|      9 | `INVALID_MODIFICATION_ERR`    |\n|     10 | `QUOTA_EXCEEDED_ERR`          |\n|     11 | `TYPE_MISMATCH_ERR`           |\n|     12 | `PATH_EXISTS_ERR`             |\n\n## Configurando el Plugin (opcional)\n\nEl conjunto de los sistemas de ficheros disponibles puede ser configurado por plataforma. Tanto iOS y Android reconocen un <preference> etiqueta en el `archivo config.xml` que nombra a los sistemas de archivos para ser instalado. De forma predeterminada, se activan todas las raíces del sistema de archivos.\n\n    <preference name=\"iosExtraFilesystems\" value=\"library,library-nosync,documents,documents-nosync,cache,bundle,root\" />\n    <preference name=\"AndroidExtraFilesystems\" value=\"files,files-external,documents,sdcard,cache,cache-external,root\" />\n    \n\n### Android\n\n  * `files`: directorio de almacenamiento de archivo interno de la aplicación\n  * `files-external`: directorio de almacenamiento de archivo externo de la aplicación\n  * `sdcard`: el directorio de almacenamiento de archivo externo global (esta es la raíz de la tarjeta SD, si uno está instalado). Debe tener el permiso de `android.permission.WRITE_EXTERNAL_STORAGE` a usar esto.\n  * `cache`: directorio de memoria caché interna de la aplicación\n  * `cache-external`: directorio de caché externo de la aplicación\n  * `root`: el sistema de archivos de todo el dispositivo\n\nAndroid también es compatible con un sistema de archivos especial llamado \"documents\", que representa un subdirectorio \"/Documents/\" dentro del sistema de archivos \"archivos\".\n\n### iOS\n\n  * `library`: directorio de bibliotecas de la aplicación\n  * `documents`: directorio de documentos de la aplicación\n  * `cache`: directorio de caché de la aplicación\n  * `bundle`: paquete de la aplicación; la ubicación de la aplicación en sí mismo en el disco (sólo lectura)\n  * `root`: el sistema de archivos de todo el dispositivo\n\nDe forma predeterminada, los directorios de documentos y la biblioteca pueden ser sincronizados con iCloud. También puede solicitar dos sistemas adicionales, `library-nosync` y `documents-nosync`, que representan un directorio especial no sincronizados dentro de la `/Library` o sistema de ficheros `/Documents`."
  },
  {
    "path": "plugins/cordova-plugin-file/doc/es/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-file\n\nEste plugin implementa una API de archivo que permite acceso de lectura/escritura a los archivos que residen en el dispositivo.\n\nEste plugin se basa en varias especificaciones, incluyendo: el HTML5 archivo API <http://www.w3.org/TR/FileAPI/>\n\nLos directorios (ahora extinto) y sistema de extensiones más recientes: <http://www.w3.org/TR/2012/WD-file-system-api-20120417/> aunque la mayor parte del código del plugin fue escrito cuando una especificación anterior era actual: <http://www.w3.org/TR/2011/WD-file-system-api-20110419/>\n\nTambién implementa la especificación de FileWriter: <http://dev.w3.org/2009/dap/file-system/file-writer.html>\n\nPara el uso, por favor, consulte 'HTML5 Rocks excelente [FileSystem artículo.][1]\n\n [1]: http://www.html5rocks.com/en/tutorials/file/filesystem/\n\nPara tener una visión general de otras opciones de almacenamiento, consulte [Guía de almacenamiento Cordova][2].\n\n [2]: http://cordova.apache.org/docs/en/edge/cordova_storage_storage.md.html\n\nEste plugin define global `cordova.file` objeto.\n\nAunque en el ámbito global, no estará disponible hasta después de la `deviceready` evento.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(cordova.file);\n    }\n    \n\n## Instalación\n\n    cordova plugin add cordova-plugin-file\n    \n\n## Plataformas soportadas\n\n*   Amazon fire OS\n*   Android\n*   BlackBerry 10\n*   Firefox OS\n*   iOS\n*   Windows Phone 7 y 8 *\n*   Windows 8 *\n*   Explorador\n\n* *No son compatibles con estas plataformas `FileReader.readAsArrayBuffer` ni `FileWriter.write(blob)` .*\n\n## Donde almacenar los archivos\n\nA partir de v1.2.0, URLs a directorios de sistema de archivos importantes son proporcionadas. Cada dirección URL está en la forma *file:///path/to/spot/*y se puede convertir en un `DirectoryEntry` usando`window.resolveLocalFileSystemURL()`.\n\n*   `cordova.file.applicationDirectory`-Directorio Read-only donde está instalada la aplicación. (*iOS*, *Android*, *BlackBerry 10*)\n\n*   `cordova.file.applicationStorageDirectory`-Directorio del entorno limitado de la aplicación; en iOS esta ubicación es de sólo lectura (pero subdirectorios específicos [como `/Documents` ] son de lectura y escritura). Todos los datos contenidos dentro es privado para la aplicación. ( *iOS*, *Android*, *BlackBerry 10*)\n\n*   `cordova.file.dataDirectory`-Almacenamiento de datos persistente y privadas dentro de entorno limitado de la aplicación utilizando la memoria interna (en Android, si necesitas usar memoria externa, use `.externalDataDirectory` ). En iOS, este directorio no está sincronizado con iCloud (utilice `.syncedDataDirectory` ). (*iOS*, *Android*, *BlackBerry 10*)\n\n*   `cordova.file.cacheDirectory`-Directorio para los archivos de datos almacenados en caché o los archivos que su aplicación puede volver a crear fácilmente. El sistema operativo puede borrar estos archivos cuando el dispositivo se agota en almacenamiento de información, sin embargo, aplicaciones no deben confiar en el sistema operativo para eliminar los archivos de aquí. (*iOS*, *Android*, *BlackBerry 10*)\n\n*   `cordova.file.externalApplicationStorageDirectory`-Espacio aplicación de almacenamiento externo. (*Android*)\n\n*   `cordova.file.externalDataDirectory`¿Dónde poner los archivos de datos específicos de la aplicación de almacenamiento externo. (*Android*)\n\n*   `cordova.file.externalCacheDirectory`-Caché aplicación de almacenamiento externo. (*Android*)\n\n*   `cordova.file.externalRootDirectory`-Raíz de almacenamiento externo (tarjeta SD). (*Android*, *BlackBerry 10*)\n\n*   `cordova.file.tempDirectory`-Directorio temporal que puede borrar el sistema operativo en sí. No confíe en el sistema operativo para borrar este directorio; su aplicación siempre debe eliminar archivos según corresponda. (*iOS*)\n\n*   `cordova.file.syncedDataDirectory`-Contiene los archivos de la aplicación específica que deben ser sincronizados (e.g. a iCloud). (*iOS*)\n\n*   `cordova.file.documentsDirectory`-Archivos privados a la aplicación, pero que son significativos para otra aplicación (por ejemplo archivos de Office). (*iOS*)\n\n*   `cordova.file.sharedDirectory`-Archivos disponibles globalmente para todas las aplicaciones (*BlackBerry 10*)\n\n## Diseños de sistema de archivo\n\nAunque técnicamente un detalle de la implementación, puede ser muy útil saber cómo la `cordova.file.*` mapa de propiedades en trazados físicos en un dispositivo real.\n\n### iOS diseño de sistema de archivo\n\n| Ruta de dispositivo                          | `Cordova.file.*`            | `iosExtraFileSystems` | ¿r/w? | ¿persistente? | OS despeja | sincronización | privado |\n|:-------------------------------------------- |:--------------------------- |:--------------------- |:-----:|:-------------:|:----------:|:--------------:|:-------:|\n| `/ var/mobile/Applications/< UUID > /` | applicationStorageDirectory | -                     |   r   |     N / A     |   N / A    |     N / A      |   Sí    |\n|    `appname.app/`                            | applicationDirectory        | Bundle                |   r   |     N / A     |   N / A    |     N / A      |   Sí    |\n|       `www/`                                 | -                           | -                     |   r   |     N / A     |   N / A    |     N / A      |   Sí    |\n|    `Documents/`                              | documentsDirectory          | documentos            |  r/w  |      Sí       |     No     |       Sí       |   Sí    |\n|       `NoCloud/`                             | -                           | documentos-nosync     |  r/w  |      Sí       |     No     |       No       |   Sí    |\n|    `Library`                                 | -                           | Biblioteca            |  r/w  |      Sí       |     No     |      ¿Sí?      |   Sí    |\n|       `NoCloud/`                             | dataDirectory               | Biblioteca-nosync     |  r/w  |      Sí       |     No     |       No       |   Sí    |\n|       `Cloud/`                               | syncedDataDirectory         | -                     |  r/w  |      Sí       |     No     |       Sí       |   Sí    |\n|       `Caches/`                              | cacheDirectory              | caché                 |  r/w  |     Sí *      | Si * * *| |       No       |   Sí    |\n|    `tmp/`                                    | tempDirectory               | -                     |  r/w  |    No * *     | Si * * *| |       No       |   Sí    |\n\n* Archivos persisten a través de la aplicación se reinicia y actualizaciones, pero este directorio puede ser despejó cuando el OS desea. Su aplicación debe ser capaz de recrear cualquier contenido que puede ser eliminado.\n\n* * Archivos pueden persistir a través de la aplicación se reinicia, pero no confiar en este comportamiento. Los archivos no se garantizan que persisten a través de actualizaciones. Su aplicación debe eliminar los archivos de este directorio cuando es aplicable, como el sistema operativo no garantiza cuando (o incluso si) estos archivos se quitan.\n\n* * *| OS la puede borrar el contenido de este directorio cuando se siente que es necesario, pero no dependen de éste. Debe borrar este directorio según sea apropiado para su aplicación.\n\n### Disposición del sistema Android File\n\n| Ruta de dispositivo                       | `Cordova.file.*`                    | `AndroidExtraFileSystems` | ¿r/w? | ¿persistente? | OS despeja | privado |\n|:----------------------------------------- |:----------------------------------- |:------------------------- |:-----:|:-------------:|:----------:|:-------:|\n| `File:///android_asset/`                  | applicationDirectory                |                           |   r   |     N / A     |   N / A    |   Sí    |\n| `/Data/data/< id de aplicación > /` | applicationStorageDirectory         | -                         |  r/w  |     N / A     |   N / A    |   Sí    |\n|    `cache`                                | cacheDirectory                      | caché                     |  r/w  |      Sí       |    Sí *    |   Sí    |\n|    `files`                                | dataDirectory                       | archivos                  |  r/w  |      Sí       |     No     |   Sí    |\n|       `Documents`                         |                                     | documentos                |  r/w  |      Sí       |     No     |   Sí    |\n| `< sdcard > /`                      | externalRootDirectory               | sdcard                    |  r/w  |      Sí       |     No     |   No    |\n|    `Android/data/<app-id>/`         | externalApplicationStorageDirectory | -                         |  r/w  |      Sí       |     No     |   No    |\n|       `cache`                             | externalCacheDirectry               | caché-externo             |  r/w  |      Sí       |   No * *   |   No    |\n|       `files`                             | externalDataDirectory               | archivos externos         |  r/w  |      Sí       |     No     |   No    |\n\n* El sistema operativo puede eliminar periódicamente este directorio, pero no dependen de este comportamiento. Borrar el contenido de este directorio según sea apropiado para su aplicación. El contenido de este directorio debe un usuario purga la caché manualmente, se eliminan.\n\n* * El sistema operativo no borra este directorio automáticamente; Usted es responsable de administrar el contenido mismo. Deberá el usuario purga la caché manualmente, se extraen los contenidos del directorio.\n\n**Nota**: Si no se puede montar de almacenamiento externo, el `cordova.file.external*` Propiedades`null`.\n\n### Disposición del sistema blackBerry 10 archivo\n\n| Ruta de dispositivo                                           | `Cordova.file.*`            | ¿r/w? | ¿persistente? | OS despeja | privado |\n|:------------------------------------------------------------- |:--------------------------- |:-----:|:-------------:|:----------:|:-------:|\n| `File:///accounts/1000/AppData/ < id de aplicación > /` | applicationStorageDirectory |   r   |     N / A     |   N / A    |   Sí    |\n|    `app/native`                                               | applicationDirectory        |   r   |     N / A     |   N / A    |   Sí    |\n|    `data/webviews/webfs/temporary/local__0`                   | cacheDirectory              |  r/w  |      No       |     Sí     |   Sí    |\n|    `data/webviews/webfs/persistent/local__0`                  | dataDirectory               |  r/w  |      Sí       |     No     |   Sí    |\n| `File:///accounts/1000/Removable/sdcard`                      | externalRemovableDirectory  |  r/w  |      Sí       |     No     |   No    |\n| `File:///accounts/1000/shared`                                | sharedDirectory             |  r/w  |      Sí       |     No     |   No    |\n\n*Nota*: cuando se implementa la aplicación al trabajo de perímetro, todos los caminos son relativos a /accounts/1000-enterprise.\n\n## Rarezas Android\n\n### Ubicación de almacenamiento persistente Android\n\nHay múltiples ubicaciones válidas para almacenar archivos persistentes en un dispositivo Android. Vea [esta página][3] para una extensa discusión de las distintas posibilidades.\n\n [3]: http://developer.android.com/guide/topics/data/data-storage.html\n\nLas versiones anteriores del plugin elegiría la ubicación de los archivos temporales y persistentes en el arranque, basado en si el dispositivo afirmó que fue montado en la tarjeta SD (o partición de almacenamiento equivalente). Si fue montada en la tarjeta SD, o una partición de gran almacenamiento interno estaba disponible (como en dispositivos de Nexus,) y luego los archivos persistentes se almacenaría en la raíz de ese espacio. Esto significaba que todas las apps Cordova podían ver todos los archivos disponibles en la tarjeta.\n\nSi la tarjeta SD no estaba disponible, entonces versiones anteriores podría almacenar datos debajo de `/data/data/<packageId>` , que aísla las apps del otro, pero puede todavía causa datos para ser compartido entre los usuarios.\n\nAhora es posible elegir si desea almacenar archivos en la ubicación de almacenamiento del archivo interno, o usando la lógica anterior, con una preferencia en de la aplicación `config.xml` archivo. Para ello, añada una de estas dos líneas a `config.xml` :\n\n    < nombre de preferencia = \"AndroidPersistentFileLocation\" value = \"Internal\" / >< nombre de preferencia = \"AndroidPersistentFileLocation\" value = \"Compatibilidad\" / >\n    \n\nSin esta línea, se utilizará el archivo plugin `Compatibility` como valor predeterminado. Si una etiqueta de preferencia está presente y no es uno de estos valores, no se iniciará la aplicación.\n\nSi su solicitud se ha enviado previamente a los usuarios, usando un mayor (1.0 pre) versión de este plugin y archivos almacenados en el sistema de ficheros persistente, entonces debería establecer la preferencia en `Compatibility` . Cambiar la ubicación para \"Internal\" significa que los usuarios existentes que actualización su aplicación pueden ser incapaces de acceder a sus archivos previamente almacenadas, dependiendo de su dispositivo.\n\nSi su solicitud es nuevo, o nunca antes ha almacenado archivos en el sistema de ficheros persistente, entonces el `Internal` generalmente se recomienda el ajuste.\n\n## iOS rarezas\n\n*   `cordova.file.applicationStorageDirectory`es de sólo lectura; intentar almacenar archivos en el directorio raíz fallará. Utilice uno de los `cordova.file.*` las propiedades definidas para iOS (sólo `applicationDirectory` y `applicationStorageDirectory` son de sólo lectura).\n*   `FileReader.readAsText(blob, encoding)` \n    *   El `encoding` no se admite el parámetro, y codificación UTF-8 es siempre en efecto.\n\n### iOS ubicación de almacenamiento persistente\n\nHay dos ubicaciones válidas para almacenar archivos persistentes en un dispositivo iOS: el directorio de documentos y el directorio de biblioteca. Las versiones anteriores del plugin sólo almacenan archivos persistentes en el directorio de documentos. Esto tenía el efecto secundario de todos los archivos de la aplicación haciendo visible en iTunes, que era a menudo involuntarios, especialmente para aplicaciones que manejan gran cantidad de archivos pequeños, en lugar de producir documentos completos para la exportación, que es la finalidad del directorio.\n\nAhora es posible elegir si desea almacenar archivos en los documentos o directorio de bibliotecas, con preferencia en de la aplicación `config.xml` archivo. Para ello, añada una de estas dos líneas a `config.xml` :\n\n    <preference name=\"iosPersistentFileLocation\" value=\"Library\" />\n    \n    <preference name=\"iosPersistentFileLocation\" value=\"Compatibility\" />\n    \n\nSin esta línea, se utilizará el archivo plugin `Compatibility` como valor predeterminado. Si una etiqueta de preferencia está presente y no es uno de estos valores, no se iniciará la aplicación.\n\nSi su solicitud se ha enviado previamente a los usuarios, usando un mayor (1.0 pre) versión de este plugin y archivos almacenados en el sistema de ficheros persistente, entonces debería establecer la preferencia en `Compatibility` . Cambiar la ubicación de `Library` significa que los usuarios existentes que actualización su aplicación sería incapaces de acceder a sus archivos previamente almacenadas.\n\nSi su solicitud es nuevo, o nunca antes ha almacenado archivos en el sistema de ficheros persistente, entonces el `Library` generalmente se recomienda el ajuste.\n\n## Firefox OS rarezas\n\nLa API de sistema de archivo de forma nativa no es compatible con Firefox OS y se implementa como una cuña en la parte superior indexedDB.\n\n*   No falla cuando eliminar directorios no vacía\n*   No admite metadatos para directorios\n*   Los métodos `copyTo` y `moveTo` no son compatibles con directorios\n\nSe admiten las siguientes rutas de datos: * `applicationDirectory` -usa `xhr` para obtener los archivos locales que están envasados con la aplicación. * `dataDirectory` - Para archivos de datos específicos de aplicación persistente. * `cacheDirectory` -En caché archivos que deben sobrevivir se reinicia la aplicación (aplicaciones no deben confiar en el sistema operativo para eliminar archivos aquí).\n\n## Navegador rarezas\n\n### Rarezas y observaciones comunes\n\n*   Cada navegador utiliza su propio sistema de ficheros un espacio aislado. IE y Firefox utilizan IndexedDB como base. Todos los navegadores utilizan diagonal como separador de directorio en un camino.\n*   Las entradas de directorio deben crearse sucesivamente. Por ejemplo, la llamada `fs.root.getDirectory (' dir1/dir2 ', {create:true}, successCallback, errorCallback)` se producirá un error si no existiera dir1.\n*   El plugin solicita permiso de usuario para usar almacenamiento persistente en el primer comienzo de la aplicación. \n*   Plugin soporta `cdvfile://localhost` (recursos locales) solamente. Es decir, no se admiten los recursos externos vía `cdvfile`.\n*   El plugin no sigue [\"Archivo sistema API 8.3 nombrando restricciones\"][4].\n*   BLOB y archivo ' `close` la función no es compatible.\n*   `FileSaver` y `BlobBuilder` no son compatibles con este plugin y no tengo recibos.\n*   El plugin no es compatible con `requestAllFileSystems`. Esta función también está desaparecida en las especificaciones.\n*   No se quitarán las entradas de directorio Si utilizas `create: true` bandera de directorio existente.\n*   No se admiten archivos creados mediante el constructor. Debe utilizar método entry.file en su lugar.\n*   Cada navegador utiliza su propia forma de blob URL referencias.\n*   se admite la función `readAsDataURL`, pero el mediatype en cromo depende de la extensión de nombre de entrada, mediatype en IE siempre está vacío (que es lo mismo como `plain-text` según la especificación), el mediatype en Firefox siempre es `application/octet-stream`. Por ejemplo, si el contenido es `abcdefg` entonces Firefox devuelve `datos: aplicación / octet-stream; base64, YWJjZGVmZw ==`, es decir devuelve `datos:; base64, YWJjZGVmZw ==`, cromo devuelve `datos: < mediatype dependiendo de la extensión de nombre de la entrada >; base64, YWJjZGVmZw ==`.\n*   `toInternalURL` devuelve la ruta de la forma `file:///persistent/path/to/entry` (Firefox, IE). Cromo devuelve la ruta de acceso en el formulario `cdvfile://localhost/persistent/file`.\n\n [4]: http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions\n\n### Rarezas de Chrome\n\n*   Filesystem de Chrome no es inmediatamente después de evento ready dispositivo. Como solución temporal puede suscribirse al evento `filePluginIsReady`. Ejemplo: \n\n    javascript\n    window.addEventListener('filePluginIsReady', function(){ console.log('File plugin is ready');}, false);\n    \n\nPuede utilizar la función `window.isFilePluginReadyRaised` para verificar si ya se provoca el evento. -window.requestFileSystem temporal y persistente filesystem cuotas no están limitadas en cromo. -Para aumentar el almacenamiento persistente en cromo necesitas llamar el método `window.initPersistentFileSystem`. Cuota de almacenamiento persistente es de 5 MB por defecto. -Chrome requiere `--permitir-archivo-acceso-de-archivos` ejecutar argumento al soporte API mediante protocolo `file:///`. -`Archivo` objeto no cambiará si utilizas bandera `{create:true}` cuando una `entrada` de existente. -eventos `cancelable` propiedad está establecida en true en cromo. Esto es contrario a la [Especificación][5]. -función de `toURL` en Chrome devuelve `filesystem:`-prefijo camino dependiendo de host de la aplicación. Por ejemplo, `filesystem:file:///persistent/somefile.txt`, `filesystem:http://localhost:8080/persistent/somefile.txt`. -resultado de la función de `toURL` no contiene barra en caso de entrada en el directorio. Cromo resuelve directorios con urls slash-siguió correctamente sin embargo. -método `resolveLocalFileSystemURL` requiere la entrantes `url` que tienen prefijo `filesystem`. Por ejemplo, el parámetro de `url` para `resolveLocalFileSystemURL` debería estar en la forma `filesystem:file:///persistent/somefile.txt` en comparación con la forma `file:///persistent/somefile.txt` en Android. -Obsoleto `toNativeURL` función no es compatible y no tiene un trozo. -función de `setMetadata` no es indicada en las especificaciones y no admite. -INVALID_MODIFICATION_ERR (código: 9) se lanza en lugar de SYNTAX_ERR(code: 8) a petición de un sistema de ficheros inexistentes. -INVALID_MODIFICATION_ERR (código: 9) se lanza en vez de PATH_EXISTS_ERR(code: 12) en intentar exclusivamente crear un archivo o directorio, que ya existe. -INVALID_MODIFICATION_ERR (código: 9) se lanza en lugar de NO_MODIFICATION_ALLOWED_ERR(code: 6) para tratar de llamar a removeRecursively en el sistema de archivos raíz. -INVALID_MODIFICATION_ERR (código: 9) se lanza en vez de NOT_FOUND_ERR(code: 1) en tratar de moveTo directorio que no existe.\n\n [5]: http://dev.w3.org/2009/dap/file-system/file-writer.html\n\n### Impl base IndexedDB rarezas (IE y Firefox)\n\n*   `.` y `..` no son compatibles.\n*   IE no soporta `file:///`-modo; modo alojado sólo es compatible (http://localhost:xxxx).\n*   Tamaño del sistema de archivos de Firefox no es limitada pero cada extensión de 50 MB solicitará un permiso de usuario. IE10 permite hasta 10mb de combinados AppCache y IndexedDB utilizados en la implementación del sistema de ficheros sin preguntar, cuando llegas a ese nivel que se le preguntará si desea permitir que ser aumentada hasta un máximo de 250 mb por sitio. Para que `size` parámetro para la función `requestFileSystem` no afecta sistema de ficheros en Firefox y IE.\n*   la función `readAsBinaryString` no se indica en las especificaciones y no compatible con IE y no tiene un trozo.\n*   `file.type` siempre es null.\n*   No debe crear entrada utilizando DirectoryEntry resultado de devolución de llamada de instancia que fue borrado. De lo contrario, obtendrá una entrada' colgar'.\n*   Antes de que se puede leer un archivo, el cual fue escrito sólo que necesitas una nueva instancia de este archivo.\n*   la función `setMetadata`, que no es indicada en las especificaciones soporta sólo el cambio de campo `modificationTime`. \n*   `copyTo` y `moveTo` funciones no son compatibles con directorios.\n*   Metadatos de directorios no es compatible.\n*   Tanto Entry.remove y directoryEntry.removeRecursively no fallan al retirar no vacía directorios - directorios de ser eliminados se limpian junto con contenido en su lugar.\n*   `abort` y `truncate` las funciones no son compatibles.\n*   eventos de progreso no están despedidos. Por ejemplo, este controlador no ejecutará:\n\n    javascript\n    writer.onprogress = function() { /*commands*/ };\n    \n\n## Actualización de notas\n\nEn v1.0.0 de este plugin, han cambiado las estructuras `FileEntry` y `DirectoryEntry`, para estar más acorde con las especificaciones publicadas.\n\nVersiones anteriores (pre-1.0.0) del plugin almacenan el dispositivo-absoluto-archivo-ubicación en la propiedad `fullPath` de objetos de `entrada`. Estos caminos típicamente parecería\n\n    /var/mobile/Applications/<application UUID>/Documents/path/to/file  (iOS)\n    /storage/emulated/0/path/to/file                                    (Android)\n    \n\nEstas rutas también fueron devueltos por el método `toURL()` de los objetos de `entrada`.\n\nCon v1.0.0, el atributo `fullPath` es la ruta del archivo, *relativo a la raíz del sistema de archivos HTML*. Así, los caminos más arriba sería ahora ambos ser representado por un objeto `FileEntry` con un `fullPath` de\n\n    /path/to/file\n    \n\nSi su aplicación funciona con dispositivo-absoluto-caminos, y previamente obtenido esos caminos a través de la propiedad `fullPath` de objetos de `Entry`, deberá actualizar el código para utilizar `entry.toURL()` en su lugar.\n\nPara atrás compatibilidad, el método `resolveLocalFileSystemURL()` a aceptar un dispositivo-absoluto-trayectoria y devolverá un objeto de `Entry` correspondiente que, mientras exista ese archivo dentro de los sistemas de ficheros `TEMPORARY` o la `PERSISTENT`.\n\nEsto ha sido particularmente un problema con el plugin de transferencia de archivos, que anteriormente utilizado dispositivo-absoluto-caminos (y todavía puede aceptarlas). Ha sido actualizado para funcionar correctamente con sistema de ficheros URLs, para reemplazar `entry.fullPath` con `entry.toURL()` debe resolver cualquier problema conseguir ese plugin para trabajar con archivos en el dispositivo.\n\nEn v1.1.0 el valor devuelto por `toURL()` fue cambiado (consulte \\[CB-6394\\] (https://issues.apache.org/jira/browse/CB-6394)) para devolver una dirección URL absoluta 'file://'. siempre que sea posible. Para asegurar una ' cdvfile:'-URL ahora puede utilizar `toInternalURL()`. Este método devolverá ahora filesystem URLs de la forma\n\n    cdvfile://localhost/persistent/path/to/file\n    \n\nque puede utilizarse para identificar el archivo únicamente.\n\n## Lista de códigos de Error y significados\n\nCuando se produce un error, uno de los siguientes códigos se utilizará.\n\n| Código | Constante                     |\n| ------:|:----------------------------- |\n|      1 | `NOT_FOUND_ERR`               |\n|      2 | `SECURITY_ERR`                |\n|      3 | `ABORT_ERR`                   |\n|      4 | `NOT_READABLE_ERR`            |\n|      5 | `ENCODING_ERR`                |\n|      6 | `NO_MODIFICATION_ALLOWED_ERR` |\n|      7 | `INVALID_STATE_ERR`           |\n|      8 | `SYNTAX_ERR`                  |\n|      9 | `INVALID_MODIFICATION_ERR`    |\n|     10 | `QUOTA_EXCEEDED_ERR`          |\n|     11 | `TYPE_MISMATCH_ERR`           |\n|     12 | `PATH_EXISTS_ERR`             |\n\n## Configurando el Plugin (opcional)\n\nEl conjunto de los sistemas de ficheros disponibles puede ser configurado por plataforma. Tanto iOS y Android reconocen un <preference> etiqueta en el `archivo config.xml` que nombra a los sistemas de archivos para ser instalado. De forma predeterminada, se activan todas las raíces del sistema de archivos.\n\n    <preference name=\"iosExtraFilesystems\" value=\"library,library-nosync,documents,documents-nosync,cache,bundle,root\" />\n    <preference name=\"AndroidExtraFilesystems\" value=\"files,files-external,documents,sdcard,cache,cache-external,root\" />\n    \n\n### Android\n\n*   `files`: directorio de almacenamiento de archivo interno de la aplicación\n*   `files-external`: directorio de almacenamiento de archivo externo de la aplicación\n*   `sdcard`: el directorio de almacenamiento de archivo externo global (esta es la raíz de la tarjeta SD, si uno está instalado). Debe tener el permiso de `android.permission.WRITE_EXTERNAL_STORAGE` a usar esto.\n*   `cache`: directorio de memoria caché interna de la aplicación\n*   `cache-external`: directorio de caché externo de la aplicación\n*   `root`: el sistema de archivos de todo el dispositivo\n\nAndroid también es compatible con un sistema de archivos especial llamado \"documents\", que representa un subdirectorio \"/Documents/\" dentro del sistema de archivos \"archivos\".\n\n### iOS\n\n*   `library`: directorio de bibliotecas de la aplicación\n*   `documents`: directorio de documentos de la aplicación\n*   `cache`: directorio de caché de la aplicación\n*   `bundle`: paquete de la aplicación; la ubicación de la aplicación en sí mismo en el disco (sólo lectura)\n*   `root`: el sistema de archivos de todo el dispositivo\n\nDe forma predeterminada, los directorios de documentos y la biblioteca pueden ser sincronizados con iCloud. También puede solicitar dos sistemas adicionales, `library-nosync` y `documents-nosync`, que representan un directorio especial no sincronizados dentro de la `/Library` o sistema de ficheros `/Documents`.\n"
  },
  {
    "path": "plugins/cordova-plugin-file/doc/es/plugins.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# Notas para los desarrolladores del plugin\n\nEstas notas están pensadas principalmente para desarrolladores de Android y el iOS que quieran escribir plugins que interfaz con el sistema de ficheros usando el plugin del archivo.\n\n## Trabajar con URLs de sistema de archivo de Córdoba\n\nDesde la versión 1.0.0, este plugin ha utilizado las direcciones URL con un `cdvfile` plan para todas las comunicaciones sobre el puente, en lugar de exponer rutas de sistema de archivos de dispositivos raw para JavaScript.\n\nEn el lado de JavaScript, esto significa que los objetos FileEntry y DirectoryEntry tienen un atributo fullPath que es relativo a la raíz del sistema de archivos HTML. Si JavaScript API de tu plugin acepta un objeto FileEntry o DirectoryEntry, usted debe llamar a `.toURL()` en ese objeto antes de pasar a través del puente al código nativo.\n\n### Conversión de cdvfile: / / URL al fileystem caminos\n\nPlugins que necesita escribir en el sistema de archivos puede convertir un archivo recibido sistema URL a una ubicación de sistema de archivos real. Hay varias formas de hacerlo, dependiendo de la plataforma nativa.\n\nEs importante recordar que no todos `cdvfile://` las direcciones URL son asignables a reales archivos en el dispositivo. Algunas URLs pueden referirse a activos en dispositivos que no están representadas por archivos, o incluso pueden hacer referencia a recursos remotos. Debido a estas posibilidades, plugins siempre debe comprobar si consiguen un resultado significativo cuando tratando de convertir las URL en trazados.\n\n#### Android\n\nEn Android, el método más simple para convertir un `cdvfile://` URL a una ruta de sistema de archivos es utilizar `org.apache.cordova.CordovaResourceApi` . `CordovaResourceApi`tiene varios métodos que pueden manejar `cdvfile://` URL:\n\n    webView es un miembro de la clase Plugin CordovaResourceApi resourceApi = webView.getResourceApi();\n    \n    Obtener una URL file:/// representando este archivo en el dispositivo, / / o el mismo URL sin cambios si no se puede asignar a un archivo Uri fileURL = resourceApi.remapUri(Uri.parse(cdvfileURL));\n    \n\nTambién es posible utilizar el plugin de archivos directamente:\n\n    Import org.apache.cordova.file.FileUtils;\n    Import org.apache.cordova.file.FileSystem;\n    Import java.net.MalformedURLException;\n    \n    Obtener el archivo plugin desde el administrador de plugin FileUtils filePlugin = (FileUtils)webView.pluginManager.getPlugin(\"File\");\n    \n    Dada una URL, haz un camino para tratar de {camino de cadena = filePlugin.filesystemPathForURL(cdvfileURL);} catch (DD e) {/ / el sistema de archivos url no reconocida}\n    \n\nPara convertir de una ruta a un `cdvfile://` URL:\n\n    Import org.apache.cordova.file.LocalFilesystemURL;\n    \n    Obtener un objeto LocalFilesystemURL para una ruta, / / o null si no se puede representar como una dirección URL cdvfile.\n    LocalFilesystemURL url = filePlugin.filesystemURLforLocalPath(path);\n    Obtener la representación string de la URL objeto String cdvfileURL = url.toString();\n    \n\nSi tu plugin crea un archivo y desea devolver un objeto FileEntry para él, usar el plugin de archivos:\n\n    Devolver una estructura JSON adecuado para volver a JavaScript, / / o null si este archivo no es representable como una dirección URL cdvfile.\n    JSONObject entrada = filePlugin.getEntryForFile(file);\n    \n\n#### iOS\n\nCordova en iOS no utiliza la misma `CordovaResourceApi` concepto como Android. En iOS, debe usar el archivo plugin para convertir las direcciones URL y rutas de sistema de archivos.\n\n    Obtener un objeto URL CDVFilesystem de una URL string CDVFilesystemURL * url = [CDVFilesystemURL fileSystemURLWithString:cdvfileURL];\n    Obtener una ruta de acceso para el objeto URL, o nil si no puede ser asignado a una ruta de archivo NSString * = [filePlugin filesystemPathForURL:url];\n    \n    \n    Obtener un objeto URL CDVFilesystem para una ruta, o / / nula si no se puede representar como una dirección URL cdvfile.\n    CDVFilesystemURL * url = [filePlugin fileSystemURLforLocalPath:path];\n    Obtener la representación string de la URL objetos NSString * cdvfileURL = [enlace absoluteString];\n    \n\nSi tu plugin crea un archivo y desea devolver un objeto FileEntry para él, usar el plugin de archivos:\n\n    Obtener un objeto URL CDVFilesystem para una ruta, o / / nula si no se puede representar como una dirección URL cdvfile.\n    CDVFilesystemURL * url = [filePlugin fileSystemURLforLocalPath:path];\n    Conseguir una estructura para volver a JavaScript NSDictionary * entrada = [filePlugin makeEntryForLocalURL:url]\n    \n\n#### JavaScript\n\nEn JavaScript, para obtener un `cdvfile://` dirección URL de un objeto FileEntry o DirectoryEntry, simplemente llame al `.toURL()` en él:\n\n    var cdvfileURL = entry.toURL();\n    \n\nEn manipuladores de la respuesta del plugin, para convertir de una estructura FileEntry devuelta a un objeto real de la entrada, su código de controlador debe importar el archivo plugin y crear un nuevo objeto:\n\n    crear apropiado objeto var ingreso;\n    Si (entryStruct.isDirectory) {entrada = new DirectoryEntry (entryStruct.name, entryStruct.fullPath, FileSystem(entryStruct.filesystemName)) nuevo;} else {entrada = nuevo FileEntry (entryStruct.name, entryStruct.fullPath, nuevo FileSystem(entryStruct.filesystemName));}"
  },
  {
    "path": "plugins/cordova-plugin-file/doc/fr/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-file\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-file.svg)](https://travis-ci.org/apache/cordova-plugin-file)\n\nCe plugin implémente une API de fichier permettant l'accès en lecture/écriture aux fichiers qui résident sur le périphérique.\n\nCe plugin est basé sur plusieurs spécifications, y compris : l'API de fichier HTML5 <http://www.w3.org/TR/FileAPI/>\n\nLes répertoires (aujourd'hui disparue) et le système des extensions plus récentes : <http://www.w3.org/TR/2012/WD-file-system-api-20120417/> bien que la plupart du code du plugin a été écrit quand une technique antérieure était en vigueur : <http://www.w3.org/TR/2011/WD-file-system-api-20110419/>\n\nIl met également en œuvre la spécification FileWriter : <http://dev.w3.org/2009/dap/file-system/file-writer.html>\n\nPour son utilisation, veuillez vous reporter au HTML5 Rocks' excellent [article de système de fichiers.](http://www.html5rocks.com/en/tutorials/file/filesystem/)\n\nPour un aperçu des autres options de stockage, consultez [guide d'entreposage de Cordova](http://cordova.apache.org/docs/en/edge/cordova_storage_storage.md.html).\n\nCe plugin définit global `cordova.file` objet.\n\nBien que dans la portée globale, il n'est pas disponible jusqu'après la `deviceready` événement.\n\n    document.addEventListener (« deviceready », onDeviceReady, false) ;\n    function onDeviceReady() {console.log(cordova.file);}\n    \n\n## Installation\n\n    cordova plugin add cordova-plugin-file\n    \n\n## Plates-formes supportées\n\n  * Amazon Fire OS\n  * Android\n  * BlackBerry 10\n  * Firefox OS\n  * iOS\n  * Windows Phone 7 et 8 *\n  * Windows 8 *\n  * Windows*\n  * Navigateur\n\n\\* *These platforms do not support `FileReader.readAsArrayBuffer` nor `FileWriter.write(blob)`.*\n\n## Emplacement de stockage des fichiers\n\nÀ partir de v1.2.0, URL vers des répertoires de système de fichiers importants est fournis. Chaque URL est dans la forme *file:///path/to/spot/*et peut être converti en un `DirectoryEntry` à l'aide`window.resolveLocalFileSystemURL()`.\n\n  * `cordova.file.applicationDirectory`-Lecture seule répertoire où l'application est installée. (*iOS*, *Android*, *BlackBerry 10*)\n\n  * `cordova.file.applicationStorageDirectory`-Répertoire racine du bac à sable de l'application ; cet endroit est en lecture seule sur iOS (mais les sous-répertoires spécifiques [comme `/Documents` ] sont en lecture / écriture). Toutes les données qu'il contient est privé de l'application. ( *iOS*, *Android*, *BlackBerry 10*)\n\n  * `cordova.file.dataDirectory`-Stockage des données persistants et privés au sein de bac à sable de l'application à l'aide de la mémoire interne (sur Android, si vous avez besoin d'utiliser une mémoire externe, utilisez `.externalDataDirectory` ). Sur iOS, ce répertoire n'est pas synchronisé avec iCloud (utiliser `.syncedDataDirectory` ). (*iOS*, *Android*, *BlackBerry 10*)\n\n  * `cordova.file.cacheDirectory`-Répertoire pour les fichiers de données en mémoire cache ou les fichiers que votre application peut recréer facilement. L'OS peut supprimer ces fichiers lorsque l'appareil faiblit sur stockage, néanmoins, les applications ne doivent pas compter sur l'OS pour supprimer les fichiers ici. (*iOS*, *Android*, *BlackBerry 10*)\n\n  * `cordova.file.externalApplicationStorageDirectory`-Espace l'application sur le stockage externe. (*Android*)\n\n  * `cordova.file.externalDataDirectory`-Où placer les fichiers de données d'application spécifiques sur le stockage externe. (*Android*)\n\n  * `cordova.file.externalCacheDirectory`-Cache de l'application sur le stockage externe. (*Android*)\n\n  * `cordova.file.externalRootDirectory`-Racine de stockage externe (carte SD). (*Android*, *BlackBerry 10*)\n\n  * `cordova.file.tempDirectory`-Répertoire temp que l'OS peut effacer à volonté. Ne comptez pas sur l'OS pour effacer ce répertoire ; votre application doit toujours supprimer les fichiers selon le cas. (*iOS*)\n\n  * `cordova.file.syncedDataDirectory`-Contient des fichiers d'app spécifique qui doivent se synchroniser (par exemple à iCloud). (*iOS*)\n\n  * `cordova.file.documentsDirectory`-Fichiers privés à l'app, mais qui sont significatives pour l'autre application (par exemple les fichiers Office). (*iOS*)\n\n  * `cordova.file.sharedDirectory`-Fichiers disponibles globalement à toutes les applications (*BlackBerry 10*)\n\n## Structures de système de fichiers\n\nBien que techniquement un détail d'implémentation, il peut être très utile de savoir comment les `cordova.file.*` carte de propriétés à des chemins d'accès physiques sur un périphérique réel.\n\n### iOS agencement de système de fichier\n\n| Chemin de l'unité                              | `Cordova.file.*`            | `iosExtraFileSystems` | r/w ? | persistants ? |   OS efface   | Sync  | privé |\n|:---------------------------------------------- |:--------------------------- |:--------------------- |:-----:|:-------------:|:-------------:|:-----:|:-----:|\n| `/ var/mobile/Applications/< UUID > /`   | applicationStorageDirectory | -                     |   r   |      N/A      |      N/A      |  N/A  |  Oui  |\n| &nbsp;&nbsp;&nbsp;`appname.app/`               | applicationDirectory        | Bundle                |   r   |      N/A      |      N/A      |  N/A  |  Oui  |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`www/`     | -                           | -                     |   r   |      N/A      |      N/A      |  N/A  |  Oui  |\n| &nbsp;&nbsp;&nbsp;`Documents/`                 | documentsDirectory          | documents             |  r/w  |      Oui      |      Non      |  Oui  |  Oui  |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`NoCloud/` | -                           | documents-nosync      |  r/w  |      Oui      |      Non      |  Non  |  Oui  |\n| &nbsp;&nbsp;&nbsp;`Library`                    | -                           | Bibliothèque          |  r/w  |      Oui      |      Non      | Oui ? |  Oui  |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`NoCloud/` | dataDirectory               | Bibliothèque-nosync   |  r/w  |      Oui      |      Non      |  Non  |  Oui  |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`Cloud/`   | syncedDataDirectory         | -                     |  r/w  |      Oui      |      Non      |  Oui  |  Oui  |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`Caches/`  | cacheDirectory              | cache                 |  r/w  |     Oui *     | Oui**\\* |  Non  |  Oui  |\n| &nbsp;&nbsp;&nbsp;`tmp/`                       | tempDirectory               | -                     |  r/w  |   Non**   | Oui**\\* |  Non  |  Oui  |\n\n\\ * Fichiers persistent à travers l'application redémarre et mises à niveau, mais ce répertoire peut être effacé à chaque fois que le système d'exploitation désire. Votre application doit être en mesure de recréer tout contenu qui pourrait être supprimé.\n\n** Fichiers peuvent persister redémarrages de l'application, mais ne vous fiez pas ce comportement. Les fichiers ne sont pas garantis à persister dans l'ensemble de mises à jour. Votre application doit supprimer les fichiers de ce répertoire lorsqu'elle s'applique, comme le système d'exploitation ne garantit pas quand (ou même si) ces fichiers sont supprimés.\n\n**\\ * Le système d'exploitation peut effacer le contenu de ce répertoire chaque fois qu'il se sent il est nécessaire, mais ne comptez pas là-dessus. Vous devez supprimer ce répertoire comme approprié pour votre application.\n\n### Agencement de système de fichiers Android\n\n| Chemin de l'unité                                | `Cordova.file.*`                    | `AndroidExtraFileSystems` | r/w ? | persistants ? | OS efface | privé |\n|:------------------------------------------------ |:----------------------------------- |:------------------------- |:-----:|:-------------:|:---------:|:-----:|\n| `file:///android_asset/`                         | applicationDirectory                |                           |   r   |      N/A      |    N/A    |  Oui  |\n| `/ données/data/app < id > /`              | applicationStorageDirectory         | -                         |  r/w  |      N/A      |    N/A    |  Oui  |\n| &nbsp;&nbsp;&nbsp;`cache`                        | cacheDirectory                      | cache                     |  r/w  |      Oui      |  Oui\\ *  |  Oui  |\n| &nbsp;&nbsp;&nbsp;`files`                        | dataDirectory                       | fichiers                  |  r/w  |      Oui      |    Non    |  Oui  |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`Documents`  |                                     | documents                 |  r/w  |      Oui      |    Non    |  Oui  |\n| `< sdcard > /`                             | externalRootDirectory               | sdcard                    |  r/w  |      Oui      |    Non    |  Non  |\n| &nbsp;&nbsp;&nbsp;`Android/data/<app-id>/` | externalApplicationStorageDirectory | -                         |  r/w  |      Oui      |    Non    |  Non  |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`cache`      | externalCacheDirectry               | cache-externe             |  r/w  |      Oui      | Non** |  Non  |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`files`      | externalDataDirectory               | fichiers externes         |  r/w  |      Oui      |    Non    |  Non  |\n\n\\ * L'OS peut effacer périodiquement ce répertoire, mais ne vous fiez pas ce comportement. Effacer le contenu de ce répertoire comme approprié pour votre application. Un utilisateur doit purger le cache manuellement, le contenu de ce répertoire est supprimé.\n\n** Le système d'exploitation n'efface pas ce répertoire automatiquement ; vous êtes chargé de gérer le contenu vous-même. L'utilisateur devrait purger le cache manuellement, le contenu du répertoire est supprimé.\n\n**Remarque**: si le stockage externe ne peut pas être monté, les `cordova.file.external*` sont des propriétés`null`.\n\n### Configuration du système blackBerry 10 fichier\n\n| Chemin de l'unité                                           | `Cordova.file.*`            | r/w ? | persistants ? | OS efface | privé |\n|:----------------------------------------------------------- |:--------------------------- |:-----:|:-------------:|:---------:|:-----:|\n| `file:///Accounts/1000/AppData/ < id app > /`         | applicationStorageDirectory |   r   |      N/A      |    N/A    |  Oui  |\n| &nbsp;&nbsp;&nbsp;`app/native`                              | applicationDirectory        |   r   |      N/A      |    N/A    |  Oui  |\n| &nbsp;&nbsp;&nbsp;`data/webviews/webfs/temporary/local__0`  | cacheDirectory              |  r/w  |      Non      |    Oui    |  Oui  |\n| &nbsp;&nbsp;&nbsp;`data/webviews/webfs/persistent/local__0` | dataDirectory               |  r/w  |      Oui      |    Non    |  Oui  |\n| `file:///Accounts/1000/Removable/sdcard`                    | externalRemovableDirectory  |  r/w  |      Oui      |    Non    |  Non  |\n| `file:///Accounts/1000/Shared`                              | sharedDirectory             |  r/w  |      Oui      |    Non    |  Non  |\n\n*Remarque*: lorsque l'application est déployée dans le périmètre de travail, tous les chemins sont par rapport à /accounts/1000-enterprise.\n\n## Quirks Android\n\n### Emplacement de stockage persistant Android\n\nIl y a plusieurs emplacements valides pour stocker des fichiers persistants sur un appareil Android. Voir [cette page](http://developer.android.com/guide/topics/data/data-storage.html) pour une analyse approfondie des diverses possibilités.\n\nLes versions précédentes du plugin choisirait l'emplacement des fichiers temporaires et persistantes au démarrage, basé sur la question de savoir si le dispositif réclamé que la carte SD (ou une partition de stockage équivalent) a été montée. Si la carte SD a été montée, ou si une partition de stockage interne importante était disponible (comme sur les appareils Nexus,) puis les fichiers persistants seraient stockés dans la racine de cet espace. Cela signifie que toutes les apps de Cordova pouvaient voir tous les fichiers disponibles sur la carte.\n\nSi la carte SD n'était pas disponible, les versions précédentes pourraient stocker des données sous `/data/data/<packageId>` , qui isole des apps de l'autre, mais peut encore cause données à partager entre les utilisateurs.\n\nIl est maintenant possible de choisir de stocker les fichiers dans l'emplacement de stockage de fichier interne, ou en utilisant la logique précédente, avec une préférence au sein de votre application `config.xml` fichier. Pour ce faire, ajoutez l'un de ces deux lignes de `config.xml` :\n\n    < nom de l'option = « AndroidPersistentFileLocation » value = « Internal » / >< nom de préférence = « AndroidPersistentFileLocation » value = « Compatibilité » / >\n    \n\nSans cette ligne, utilisera le fichier plugin `Compatibility` par défaut. Si une balise de préférence est présente et n'est pas une des valeurs suivantes, l'application ne démarrera pas.\n\nSi votre application a déjà été expédiée aux utilisateurs, en utilisant une ancienne (avant 1.0) version de ce plugin et dispose des fichiers stockés dans le système de fichiers persistant, alors vous devez définir la préférence au `Compatibility` . Commutation de l'emplacement « Internal » signifierait que les utilisateurs existants qui mettre à niveau leur application peuvent être impossible d'accéder à leurs fichiers déjà enregistrés, selon leur appareil.\n\nSi votre application est nouvelle ou a jamais précédemment stocké les fichiers dans le système de fichiers persistant, puis la `Internal` réglage est généralement recommandé.\n\n### Opérations récursives lent pour /android_asset\n\nListe des répertoires actifs est vraiment lent sur Android. Vous pouvez accélérer il vers le haut, en ajoutant `src/android/build-extras.gradle` à la racine de votre projet android (requiert également cordova-android@4.0.0 ou supérieur).\n\n## Notes au sujet d'iOS\n\n  * `cordova.file.applicationStorageDirectory`est en lecture seule ; tentative de stocker des fichiers dans le répertoire racine échoue. Utilisez l'une de l'autre `cordova.file.*` les propriétés définies pour iOS (seulement `applicationDirectory` et `applicationStorageDirectory` sont en lecture seule).\n  * `FileReader.readAsText(blob, encoding)` \n      * Le `encoding` paramètre n'est pas pris en charge, et le codage UTF-8 est toujours en vigueur.\n\n### emplacement de stockage persistant d'iOS\n\nIl y a deux emplacements valides pour stocker des fichiers persistants sur un appareil iOS : le répertoire de Documents et le répertoire de la bibliothèque. Les versions précédentes du plugin stockaient ne jamais fichiers persistants dans le répertoire de Documents. Cela a eu l'effet secondaire de rendre tous les fichiers de l'application visible dans iTunes, qui était souvent inattendus, en particulier pour les applications qui traitent beaucoup de petits fichiers, plutôt que de produire des documents complets destinés à l'exportation, qui est l'objectif visé par le répertoire.\n\nIl est maintenant possible de choisir de stocker les fichiers dans le répertoire de bibliothèque, avec une préférence au sein de votre application ou de documents `config.xml` fichier. Pour ce faire, ajoutez l'un de ces deux lignes de `config.xml` :\n\n    < nom de l'option = « iosPersistentFileLocation » value = « Library » / >< nom de préférence = « iosPersistentFileLocation » value = « Compatibilité » / >\n    \n\nSans cette ligne, utilisera le fichier plugin `Compatibility` par défaut. Si une balise de préférence est présente et n'est pas une des valeurs suivantes, l'application ne démarrera pas.\n\nSi votre application a déjà été expédiée aux utilisateurs, en utilisant une ancienne (avant 1.0) version de ce plugin et dispose des fichiers stockés dans le système de fichiers persistant, alors vous devez définir la préférence au `Compatibility` . Changer l'emplacement de `Library` voudrait dire que les utilisateurs existants qui mettre à niveau leur application serait incapables d'accéder à leurs fichiers déjà enregistrés.\n\nSi votre application est nouvelle ou a jamais précédemment stocké les fichiers dans le système de fichiers persistant, puis la `Library` réglage est généralement recommandé.\n\n## Firefox OS Quirks\n\nL'API de système de fichier n'est pas nativement pris en charge par Firefox OS et est implémentée comme une cale d'épaisseur sur le dessus d'indexedDB.\n\n  * Ne manque pas lors de la suppression des répertoires non vide\n  * Ne supporte pas les métadonnées pour les répertoires\n  * Méthodes `copyTo` et `moveTo` ne prennent pas en charge les répertoires\n\nLes chemins de données suivants sont pris en charge: * `applicationDirectory` -utilise `xhr` pour obtenir des fichiers les qui sont emballées avec l'app. * `dataDirectory` - Pour les fichiers de données persistantes de app spécifique. * `cacheDirectory` -Mise en cache de fichiers qui doivent survivre les redémarrages de l'application (les applications ne doivent pas compter sur le système d'exploitation pour supprimer les fichiers ici).\n\n## Bizarreries navigateur\n\n### Commune de bizarreries et de remarques\n\n  * Chaque navigateur utilise son propre système de fichiers en bac à sable. IE et Firefox utilisent IndexedDB comme base. Tous les navigateurs utilisent oblique comme séparateur de répertoire dans un chemin d'accès.\n  * Entrées d'annuaire doivent être créées successivement. Par exemple, l'appel `fs.root.getDirectory (' dir1/dir2 ', {create:true}, successCallback, errorCallback)` échouera si dir1 n'existait pas.\n  * Le plugin demande utilisateur l'autorisation d'utiliser le stockage persistant lors du premier démarrage d'application. \n  * Plugin supporte `cdvfile://localhost` (ressources locales) seulement. C'est-à-dire les ressources externes ne sont pas supportés par l'intermédiaire de `cdvfile`.\n  * Le plugin ne suit pas les [\"Restrictions de nommage des fichiers système API 8.3\"](http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions).\n  * BLOB et le fichier \"`close` la fonction n'est pas pris en charge.\n  * `FileSaver` et `BlobBuilder` ne sont pas pris en charge par ce plugin et n'ont stubs.\n  * Le plugin ne supporte pas les `requestAllFileSystems`. Cette fonction est également absent dans les cahier des charges.\n  * Inscriptions dans l'annuaire ne seront pas supprimées si vous utilisez `create: true` drapeau pour le répertoire existant.\n  * Fichiers créés via le constructeur ne sont pas pris en charge. Vous devez plutôt utiliser entry.file méthode.\n  * Chaque navigateur utilise sa propre forme de références URL blob.\n  * `readAsDataURL` fonction est prise en charge, mais le mediatype en Chrome dépend de l'extension entrée, mediatype dans IE est toujours vide (qui est le même que le `texte-plaine` selon la spécification), le mediatype dans Firefox est toujours `application/octet-stream`. Par exemple, si le contenu est `abcdefg` puis Firefox renvoie `données : application / octet-stream ; base64, YWJjZGVmZw ==`, c'est à dire les retours `données:; base64, YWJjZGVmZw ==`, retours de Chrome `données : < mediatype selon l'extension de nom d'entrée > ; base64, YWJjZGVmZw ==`.\n  * `toInternalURL` retourne le chemin d'accès dans le formulaire `file:///persistent/path/to/entry` (Firefox, IE). Chrome retourne le chemin d'accès dans le formulaire `cdvfile://localhost/persistent/file`.\n\n### Bizarreries de chrome\n\n  * Chrome filesystem n'est pas prête immédiatement après l'événement ready périphérique. Pour contourner le problème, vous pouvez vous abonner à l'événement `filePluginIsReady`. Exemple : \n\n```javascript\nwindow.addEventListener('filePluginIsReady', function(){ console.log('File plugin is ready');}, false);\n```\n\nVous pouvez utiliser la fonction `window.isFilePluginReadyRaised` pour vérifier si les événement était déjà déclenché. -quotas de window.requestFileSystem temporaire et permanent de système de fichiers ne sont pas limités en Chrome. -Pour augmenter le stockage persistant en Chrome, vous devez appeler la méthode `window.initPersistentFileSystem`. Quota de stockage persistant est 5 Mo par défaut. -Chrome nécessite `--permettre-fichier-accès-de-fichiers` exécuter l'argument au support API via le protocole `file:///`. -`Fichier` objet changera pas si vous utilisez le drapeau `{create:true}` lors du passage d'une `entrée` existante. -événements `annulables` propriété a la valeur true dans Chrome. Il s'agit à l'encontre de la [spécification](http://dev.w3.org/2009/dap/file-system/file-writer.html). -`toURL` renvoie à Chrome `système de fichiers :`-préfixe de chemin d'accès selon l'application hôte. Par exemple, `filesystem:file:///persistent/somefile.txt`, `filesystem:http://localhost:8080/persistent/somefile.txt`. -résultat de la fonction `toURL` ne contient-elle pas de barre oblique dans le cas d'entrée d'annuaire. Chrome résout répertoires avec barre oblique-trainés URL correctement cependant. -`resolveLocalFileSystemURL` méthode nécessite l' entrant `url` préfixe de `système de fichiers`. Par exemple, le paramètre `d'url` pour `resolveLocalFileSystemURL` devrait être dans la forme `filesystem:file:///persistent/somefile.txt` par opposition à la forme `file:///persistent/somefile.txt` dans Android. -Déconseillée `toNativeURL` fonction n'est pas prise en charge et n'est pas une ébauche. -fonction de `setMetadata` n'est pas stipulée dans le devis et pas pris en charge. -INVALID_MODIFICATION_ERR (code: 9) est levée au lieu de SYNTAX_ERR(code: 8) sur la demande d'un système de fichier inexistant. -INVALID_MODIFICATION_ERR (code: 9) est levée au lieu de PATH_EXISTS_ERR(code: 12) à essayer de créer exclusivement un fichier ou un répertoire, qui existe déjà. -INVALID_MODIFICATION_ERR (code: 9) est levée au lieu de NO_MODIFICATION_ALLOWED_ERR(code: 6) à essayer d'appeler removeRecursively sur le système de fichiers racine. -INVALID_MODIFICATION_ERR (code: 9) est levée au lieu de NOT_FOUND_ERR(code: 1) en essayant de moveTo répertoire qui n'existe pas.\n\n### Base IndexedDB impl bizarreries (Firefox et IE)\n\n  * `.` et `.` ne sont pas pris en charge.\n  * IE ne prend pas en charge les `file:///`-mode ; seul le mode hébergé est pris en charge (http://localhost:xxxx).\n  * Taille de système de fichiers de Firefox n'est pas limité, mais chaque extension de 50Mo demandera une autorisation de l'utilisateur. IE10 permet jusqu'à 10 Mo de combiné AppCache et IndexedDB utilisés dans la mise en œuvre du système de fichiers sans demander de confirmation, une fois que vous atteignez ce niveau, Qu'on vous demandera si vous souhaitez lui permettre d'être augmentée jusqu'à un maximum de 250 Mo par site. Si le paramètre de `taille` pour la fonction `requestFileSystem` n'affecte pas le système de fichiers dans Firefox et IE.\n  * fonction de `readAsBinaryString` n'est pas indiquée dans les spécifications et pas pris en charge dans Internet Explorer et n'a pas une ébauche.\n  * `file.type` est toujours null.\n  * Vous ne devez pas créer en utilisant le résultat du callback instance DirectoryEntry qui avait été supprimée. Sinon, vous obtiendrez une « entrée de pendaison ».\n  * Avant que vous pouvez lire un fichier qui a été écrit juste que vous devez obtenir une nouvelle instance de ce fichier.\n  * `setMetadata` fonction, qui n'est pas indiquée dans les spécifications supporte `modificationTime` changement de champ seulement. \n  * fonctions `copyTo` et `moveTo` ne supportent pas les répertoires.\n  * Répertoires métadonnées ne sont pas pris en charge.\n  * Les deux Entry.remove et directoryEntry.removeRecursively ne manquent pas lors de la suppression des répertoires non-vides - répertoires retirés sont nettoyés avec contenu au lieu de cela.\n  * fonctions `abort` et `truncate` ne sont pas supportées.\n  * événements de progression ne sont pas déclenchés. Par exemple, ce gestionnaire ne sera pas exécuté :\n\n```javascript\nwriter.onprogress = function() { /*commands*/ };\n```\n\n## Notes de mise à niveau\n\nV1.0.0 de ce plugin, les structures `FileEntry` et `DirectoryEntry` ont changé, pour être plus conforme à la spécification publiée.\n\nLes versions précédentes de (pré-1.0.0) du plugin stockaient le dispositif-absolu--emplacement du fichier dans la propriété `fullPath` d'objets `d'entrée`. Ces chemins seraient présente généralement comme\n\n    / var/mobile/Applications/< application UUID >/Documents/chemin/vers/fichier (iOS), /storage/emulated/0/path/to/file (Android)\n    \n\nCes chemins ont été également retournés par la méthode de `toURL()` les objets `d'entrée`.\n\nAvec v1.0.0, l'attribut `fullPath` est le chemin d'accès au fichier, *par rapport à la racine du système de fichiers HTML*. Ainsi, les chemins d'accès ci-dessus seraient maintenant tous les deux être représentée par un objet `FileEntry` avec un `fullPath` de\n\n    /path/to/file\n    \n\nSi votre application fonctionne avec le dispositif-absolu-chemins et que vous avez récupéré précédemment ces chemins d'accès par le biais de la propriété `fullPath` d'objets `d'entrée`, puis vous devez mettre à jour votre code afin d'utiliser `entry.toURL()` à la place.\n\nPour vers l'arrière la compatibilité, la méthode `resolveLocalFileSystemURL()` sera un chemin absolu de l'unité et retourne un objet `Entry` correspondant à elle, tant que ce fichier existe au sein des systèmes de fichiers les `TEMPORARY` ou `PERSISTENT`.\n\nCela a été particulièrement un problème avec le plugin de transfert de fichiers, qui autrefois périphérique-absolu-chemins (et peut encore accepter). Il a été mis à jour pour fonctionner correctement avec le système de fichiers URL, afin de remplacer `entry.fullPath` par `entry.toURL()` devrait résoudre tout problème obtenir ce plugin pour travailler avec des fichiers sur le périphérique.\n\nDans v1.1.0 la valeur de retour de `toURL()` a été changée (voir \\[CB-6394\\] (https://issues.apache.org/jira/browse/CB-6394)) pour renvoyer une URL absolue \"file://\". dans la mesure du possible. Pour assurer un ' cdvfile:'-URL, vous pouvez utiliser `toInternalURL()` maintenant. Cette méthode retourne maintenant filesystem URL du formulaire\n\n    cdvfile://localhost/persistent/path/to/file\n    \n\nqui peut servir à identifier de manière unique le fichier.\n\n## Liste des Codes d'erreur et leur signification\n\nLorsqu'une erreur est levée, l'un des codes suivants sera utilisé.\n\n| Code | Constant                      |\n| ----:|:----------------------------- |\n|    1 | `NOT_FOUND_ERR`               |\n|    2 | `SECURITY_ERR`                |\n|    3 | `ABORT_ERR`                   |\n|    4 | `NOT_READABLE_ERR`            |\n|    5 | `ENCODING_ERR`                |\n|    6 | `NO_MODIFICATION_ALLOWED_ERR` |\n|    7 | `INVALID_STATE_ERR`           |\n|    8 | `SYNTAX_ERR`                  |\n|    9 | `INVALID_MODIFICATION_ERR`    |\n|   10 | `QUOTA_EXCEEDED_ERR`          |\n|   11 | `TYPE_MISMATCH_ERR`           |\n|   12 | `PATH_EXISTS_ERR`             |\n\n## Configuration du Plugin (facultatif)\n\nL'ensemble des systèmes de fichiers disponibles peut être configurée par plate-forme. Les iOS et Android reconnaissent une <preference> balise dans le `fichier config.xml` qui nomme les systèmes de fichiers à installer. Par défaut, toutes les racines du système de fichiers sont activées.\n\n    <preference name=\"iosExtraFilesystems\" value=\"library,library-nosync,documents,documents-nosync,cache,bundle,root\" />\n    <preference name=\"AndroidExtraFilesystems\" value=\"files,files-external,documents,sdcard,cache,cache-external,root\" />\n    \n\n### Android\n\n  * `files` : répertoire de stockage de fichier interne de l'application\n  * `files-external` : répertoire de l'application de stockage de fichier externe\n  * `sdcard` : le répertoire de stockage global fichier externe (c'est la racine de la carte SD, s'il est installé). Vous devez avoir la permission de `android.permission.WRITE_EXTERNAL_STORAGE` de l'utiliser.\n  * `cache` : répertoire de cache interne de l'application\n  * `cache-external` : répertoire de cache externe de l'application\n  * `root` : le système de fichiers de tout dispositif\n\nAndroid prend également en charge un système de fichiers spécial nommé « documents », qui représente un sous-répertoire « / Documents / » dans le système de fichiers « files ».\n\n### iOS\n\n  * `library` : répertoire de bibliothèque de l'application\n  * `documents` : répertoire de Documents de l'application\n  * `cache` : répertoire de Cache de l'application\n  * `bundle` : bundle de l'application ; l'emplacement de l'application elle-même sur disque (lecture seule)\n  * `root` : le système de fichiers de tout dispositif\n\nPar défaut, vous peuvent synchroniser les répertoires de la bibliothèque et les documents à iCloud. Vous pouvez également demander des deux systèmes de fichiers supplémentaires, `library-nosync` et `documents-nosync`, qui représentent un répertoire spécial non synchronisées dans le `/Library` ou système de fichiers `/ Documents`."
  },
  {
    "path": "plugins/cordova-plugin-file/doc/fr/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-file\n\nCe plugin implémente une API de fichier permettant l'accès en lecture/écriture aux fichiers qui résident sur le périphérique.\n\nCe plugin est basé sur plusieurs spécifications, y compris : l'API de fichier HTML5 <http://www.w3.org/TR/FileAPI/>\n\nLes répertoires (aujourd'hui disparue) et le système des extensions plus récentes : <http://www.w3.org/TR/2012/WD-file-system-api-20120417/> bien que la plupart du code du plugin a été écrit quand une technique antérieure était en vigueur : <http://www.w3.org/TR/2011/WD-file-system-api-20110419/>\n\nIl met également en œuvre la spécification FileWriter : <http://dev.w3.org/2009/dap/file-system/file-writer.html>\n\nPour son utilisation, veuillez vous reporter au HTML5 Rocks' excellent [article de système de fichiers.][1]\n\n [1]: http://www.html5rocks.com/en/tutorials/file/filesystem/\n\nPour un aperçu des autres options de stockage, consultez [guide d'entreposage de Cordova][2].\n\n [2]: http://cordova.apache.org/docs/en/edge/cordova_storage_storage.md.html\n\nCe plugin définit global `cordova.file` objet.\n\nBien que dans la portée globale, il n'est pas disponible jusqu'après la `deviceready` événement.\n\n    document.addEventListener (« deviceready », onDeviceReady, false) ;\n    function onDeviceReady() {console.log(cordova.file);}\n    \n\n## Installation\n\n    Cordova plugin ajouter cordova-plugin-file\n    \n\n## Plates-formes prises en charge\n\n*   Amazon Fire OS\n*   Android\n*   BlackBerry 10\n*   Firefox OS\n*   iOS\n*   Windows Phone 7 et 8 *\n*   Windows 8 *\n*   Navigateur\n\n* *Ces plates-formes ne supportent pas `FileReader.readAsArrayBuffer` ni `FileWriter.write(blob)` .*\n\n## Emplacement de stockage des fichiers\n\nÀ partir de v1.2.0, URL vers des répertoires de système de fichiers importants est fournis. Chaque URL est dans la forme *file:///path/to/spot/*et peut être converti en un `DirectoryEntry` à l'aide`window.resolveLocalFileSystemURL()`.\n\n*   `cordova.file.applicationDirectory`-Lecture seule répertoire où l'application est installée. (*iOS*, *Android*, *BlackBerry 10*)\n\n*   `cordova.file.applicationStorageDirectory`-Répertoire racine du bac à sable de l'application ; cet endroit est en lecture seule sur iOS (mais les sous-répertoires spécifiques [comme `/Documents` ] sont en lecture / écriture). Toutes les données qu'il contient est privé de l'application. ( *iOS*, *Android*, *BlackBerry 10*)\n\n*   `cordova.file.dataDirectory`-Stockage des données persistants et privés au sein de bac à sable de l'application à l'aide de la mémoire interne (sur Android, si vous avez besoin d'utiliser une mémoire externe, utilisez `.externalDataDirectory` ). Sur iOS, ce répertoire n'est pas synchronisé avec iCloud (utiliser `.syncedDataDirectory` ). (*iOS*, *Android*, *BlackBerry 10*)\n\n*   `cordova.file.cacheDirectory`-Répertoire pour les fichiers de données en mémoire cache ou les fichiers que votre application peut recréer facilement. L'OS peut supprimer ces fichiers lorsque l'appareil faiblit sur stockage, néanmoins, les applications ne doivent pas compter sur l'OS pour supprimer les fichiers ici. (*iOS*, *Android*, *BlackBerry 10*)\n\n*   `cordova.file.externalApplicationStorageDirectory`-Espace l'application sur le stockage externe. (*Android*)\n\n*   `cordova.file.externalDataDirectory`-Où placer les fichiers de données d'application spécifiques sur le stockage externe. (*Android*)\n\n*   `cordova.file.externalCacheDirectory`-Cache de l'application sur le stockage externe. (*Android*)\n\n*   `cordova.file.externalRootDirectory`-Racine de stockage externe (carte SD). (*Android*, *BlackBerry 10*)\n\n*   `cordova.file.tempDirectory`-Répertoire temp que l'OS peut effacer à volonté. Ne comptez pas sur l'OS pour effacer ce répertoire ; votre application doit toujours supprimer les fichiers selon le cas. (*iOS*)\n\n*   `cordova.file.syncedDataDirectory`-Contient des fichiers d'app spécifique qui doivent se synchroniser (par exemple à iCloud). (*iOS*)\n\n*   `cordova.file.documentsDirectory`-Fichiers privés à l'app, mais qui sont significatives pour l'autre application (par exemple les fichiers Office). (*iOS*)\n\n*   `cordova.file.sharedDirectory`-Fichiers disponibles globalement à toutes les applications (*BlackBerry 10*)\n\n## Structures de système de fichiers\n\nBien que techniquement un détail d'implémentation, il peut être très utile de savoir comment les `cordova.file.*` carte de propriétés à des chemins d'accès physiques sur un périphérique réel.\n\n### iOS agencement de système de fichier\n\n| Chemin de l'unité                            | `Cordova.file.*`            | `iosExtraFileSystems` | r/w ? | persistants ? |  OS efface  | Sync  | privé |\n|:-------------------------------------------- |:--------------------------- |:--------------------- |:-----:|:-------------:|:-----------:|:-----:|:-----:|\n| `/ var/mobile/Applications/< UUID > /` | applicationStorageDirectory | -                     |   r   |      N/A      |     N/A     |  N/A  |  Oui  |\n|    `appname.app/`                            | applicationDirectory        | Bundle                |   r   |      N/A      |     N/A     |  N/A  |  Oui  |\n|       `www/`                                 | -                           | -                     |   r   |      N/A      |     N/A     |  N/A  |  Oui  |\n|    `Documents/`                              | documentsDirectory          | documents             |  r/w  |      Oui      |     Non     |  Oui  |  Oui  |\n|       `NoCloud/`                             | -                           | documents-nosync      |  r/w  |      Oui      |     Non     |  Non  |  Oui  |\n|    `Library`                                 | -                           | Bibliothèque          |  r/w  |      Oui      |     Non     | Oui ? |  Oui  |\n|       `NoCloud/`                             | dataDirectory               | Bibliothèque-nosync   |  r/w  |      Oui      |     Non     |  Non  |  Oui  |\n|       `Cloud/`                               | syncedDataDirectory         | -                     |  r/w  |      Oui      |     Non     |  Oui  |  Oui  |\n|       `Caches/`                              | cacheDirectory              | cache                 |  r/w  |     Oui *     | Oui * * *| |  Non  |  Oui  |\n|    `tmp/`                                    | tempDirectory               | -                     |  r/w  |    Ne * *     | Oui * * *| |  Non  |  Oui  |\n\n* Fichiers persistent à travers les redémarrages de l'application et mises à niveau, mais ce répertoire peut être effacé à chaque fois que les désirs de l'OS. Votre application doit être en mesure de recréer tout contenu qui pourrait être supprimé.\n\n* * Fichiers peuvent persister redémarrages de l'application, mais ne vous fiez pas ce comportement. Les fichiers ne sont pas garantis à persister dans l'ensemble de mises à jour. Votre application doit supprimer les fichiers de ce répertoire lorsqu'elle s'applique, comme le système d'exploitation ne garantit pas quand (ou même si) ces fichiers sont supprimés.\n\n* * *| L'OS peut effacer le contenu de ce répertoire chaque fois qu'il se sent il est nécessaire, mais ne comptez pas là-dessus. Vous devez supprimer ce répertoire comme approprié pour votre application.\n\n### Agencement de système de fichiers Android\n\n| Chemin de l'unité                   | `Cordova.file.*`                    | `AndroidExtraFileSystems` | r/w ? | persistants ? | OS efface | privé |\n|:----------------------------------- |:----------------------------------- |:------------------------- |:-----:|:-------------:|:---------:|:-----:|\n| `file:///android_asset/`            | applicationDirectory                |                           |   r   |      N/A      |    N/A    |  Oui  |\n| `/ données/data/app < id > /` | applicationStorageDirectory         | -                         |  r/w  |      N/A      |    N/A    |  Oui  |\n|    `cache`                          | cacheDirectory                      | cache                     |  r/w  |      Oui      |   Oui *   |  Oui  |\n|    `files`                          | dataDirectory                       | fichiers                  |  r/w  |      Oui      |    Non    |  Oui  |\n|       `Documents`                   |                                     | documents                 |  r/w  |      Oui      |    Non    |  Oui  |\n| `< sdcard > /`                | externalRootDirectory               | sdcard                    |  r/w  |      Oui      |    Non    |  Non  |\n|    `Android/data/<app-id>/`   | externalApplicationStorageDirectory | -                         |  r/w  |      Oui      |    Non    |  Non  |\n|       `cache`                       | externalCacheDirectry               | cache-externe             |  r/w  |      Oui      |  Ne * *   |  Non  |\n|       `files`                       | externalDataDirectory               | fichiers externes         |  r/w  |      Oui      |    Non    |  Non  |\n\n* Le système d'exploitation peut effacer périodiquement ce répertoire, mais ne vous fiez pas ce comportement. Effacer le contenu de ce répertoire comme approprié pour votre application. Un utilisateur doit purger le cache manuellement, le contenu de ce répertoire est supprimé.\n\n* * The OS vous n'effacez pas ce répertoire automatiquement ; vous êtes chargé de gérer le contenu vous-même. L'utilisateur devrait purger le cache manuellement, le contenu du répertoire est supprimé.\n\n**Remarque**: si le stockage externe ne peut pas être monté, les `cordova.file.external*` sont des propriétés`null`.\n\n### Configuration du système blackBerry 10 fichier\n\n| Chemin de l'unité                                   | `Cordova.file.*`            | r/w ? | persistants ? | OS efface | privé |\n|:--------------------------------------------------- |:--------------------------- |:-----:|:-------------:|:---------:|:-----:|\n| `file:///Accounts/1000/AppData/ < id app > /` | applicationStorageDirectory |   r   |      N/A      |    N/A    |  Oui  |\n|    `app/native`                                     | applicationDirectory        |   r   |      N/A      |    N/A    |  Oui  |\n|    `data/webviews/webfs/temporary/local__0`         | cacheDirectory              |  r/w  |      Non      |    Oui    |  Oui  |\n|    `data/webviews/webfs/persistent/local__0`        | dataDirectory               |  r/w  |      Oui      |    Non    |  Oui  |\n| `file:///Accounts/1000/Removable/sdcard`            | externalRemovableDirectory  |  r/w  |      Oui      |    Non    |  Non  |\n| `file:///Accounts/1000/Shared`                      | sharedDirectory             |  r/w  |      Oui      |    Non    |  Non  |\n\n*Remarque*: lorsque l'application est déployée dans le périmètre de travail, tous les chemins sont par rapport à /accounts/1000-enterprise.\n\n## Quirks Android\n\n### Emplacement de stockage persistant Android\n\nIl y a plusieurs emplacements valides pour stocker des fichiers persistants sur un appareil Android. Voir [cette page][3] pour une analyse approfondie des diverses possibilités.\n\n [3]: http://developer.android.com/guide/topics/data/data-storage.html\n\nLes versions précédentes du plugin choisirait l'emplacement des fichiers temporaires et persistantes au démarrage, basé sur la question de savoir si le dispositif réclamé que la carte SD (ou une partition de stockage équivalent) a été montée. Si la carte SD a été montée, ou si une partition de stockage interne importante était disponible (comme sur les appareils Nexus,) puis les fichiers persistants seraient stockés dans la racine de cet espace. Cela signifie que toutes les apps de Cordova pouvaient voir tous les fichiers disponibles sur la carte.\n\nSi la carte SD n'était pas disponible, les versions précédentes pourraient stocker des données sous `/data/data/<packageId>` , qui isole des apps de l'autre, mais peut encore cause données à partager entre les utilisateurs.\n\nIl est maintenant possible de choisir de stocker les fichiers dans l'emplacement de stockage de fichier interne, ou en utilisant la logique précédente, avec une préférence au sein de votre application `config.xml` fichier. Pour ce faire, ajoutez l'un de ces deux lignes de `config.xml` :\n\n    < nom de l'option = « AndroidPersistentFileLocation » value = « Internal » / >< nom de préférence = « AndroidPersistentFileLocation » value = « Compatibilité » / >\n    \n\nSans cette ligne, utilisera le fichier plugin `Compatibility` par défaut. Si une balise de préférence est présente et n'est pas une des valeurs suivantes, l'application ne démarrera pas.\n\nSi votre application a déjà été expédiée aux utilisateurs, en utilisant une ancienne (avant 1.0) version de ce plugin et dispose des fichiers stockés dans le système de fichiers persistant, alors vous devez définir la préférence au `Compatibility` . Commutation de l'emplacement « Internal » signifierait que les utilisateurs existants qui mettre à niveau leur application peuvent être impossible d'accéder à leurs fichiers déjà enregistrés, selon leur appareil.\n\nSi votre application est nouvelle ou a jamais précédemment stocké les fichiers dans le système de fichiers persistant, puis la `Internal` réglage est généralement recommandé.\n\n## iOS Quirks\n\n*   `cordova.file.applicationStorageDirectory`est en lecture seule ; tentative de stocker des fichiers dans le répertoire racine échoue. Utilisez l'une de l'autre `cordova.file.*` les propriétés définies pour iOS (seulement `applicationDirectory` et `applicationStorageDirectory` sont en lecture seule).\n*   `FileReader.readAsText(blob, encoding)` \n    *   Le `encoding` paramètre n'est pas pris en charge, et le codage UTF-8 est toujours en vigueur.\n\n### emplacement de stockage persistant d'iOS\n\nIl y a deux emplacements valides pour stocker des fichiers persistants sur un appareil iOS : le répertoire de Documents et le répertoire de la bibliothèque. Les versions précédentes du plugin stockaient ne jamais fichiers persistants dans le répertoire de Documents. Cela a eu l'effet secondaire de rendre tous les fichiers de l'application visible dans iTunes, qui était souvent inattendus, en particulier pour les applications qui traitent beaucoup de petits fichiers, plutôt que de produire des documents complets destinés à l'exportation, qui est l'objectif visé par le répertoire.\n\nIl est maintenant possible de choisir de stocker les fichiers dans le répertoire de bibliothèque, avec une préférence au sein de votre application ou de documents `config.xml` fichier. Pour ce faire, ajoutez l'un de ces deux lignes de `config.xml` :\n\n    < nom de l'option = « iosPersistentFileLocation » value = « Library » / >< nom de préférence = « iosPersistentFileLocation » value = « Compatibilité » / >\n    \n\nSans cette ligne, utilisera le fichier plugin `Compatibility` par défaut. Si une balise de préférence est présente et n'est pas une des valeurs suivantes, l'application ne démarrera pas.\n\nSi votre application a déjà été expédiée aux utilisateurs, en utilisant une ancienne (avant 1.0) version de ce plugin et dispose des fichiers stockés dans le système de fichiers persistant, alors vous devez définir la préférence au `Compatibility` . Changer l'emplacement de `Library` voudrait dire que les utilisateurs existants qui mettre à niveau leur application serait incapables d'accéder à leurs fichiers déjà enregistrés.\n\nSi votre application est nouvelle ou a jamais précédemment stocké les fichiers dans le système de fichiers persistant, puis la `Library` réglage est généralement recommandé.\n\n## Firefox OS Quirks\n\nL'API de système de fichier n'est pas nativement pris en charge par Firefox OS et est implémentée comme une cale d'épaisseur sur le dessus d'indexedDB.\n\n*   Ne manque pas lors de la suppression des répertoires non vide\n*   Ne supporte pas les métadonnées pour les répertoires\n*   Méthodes `copyTo` et `moveTo` ne prennent pas en charge les répertoires\n\nLes chemins de données suivants sont pris en charge: * `applicationDirectory` -utilise `xhr` pour obtenir des fichiers les qui sont emballées avec l'app. * `dataDirectory` - Pour les fichiers de données persistantes de app spécifique. * `cacheDirectory` -Mise en cache de fichiers qui doivent survivre les redémarrages de l'application (les applications ne doivent pas compter sur le système d'exploitation pour supprimer les fichiers ici).\n\n## Bizarreries navigateur\n\n### Commune de bizarreries et de remarques\n\n*   Chaque navigateur utilise son propre système de fichiers en bac à sable. IE et Firefox utilisent IndexedDB comme base. Tous les navigateurs utilisent oblique comme séparateur de répertoire dans un chemin d'accès.\n*   Entrées d'annuaire doivent être créées successivement. Par exemple, l'appel `fs.root.getDirectory (' dir1/dir2 ', {create:true}, successCallback, errorCallback)` échouera si dir1 n'existait pas.\n*   Le plugin demande utilisateur l'autorisation d'utiliser le stockage persistant lors du premier démarrage d'application. \n*   Plugin supporte `cdvfile://localhost` (ressources locales) seulement. C'est-à-dire les ressources externes ne sont pas supportés par l'intermédiaire de `cdvfile`.\n*   Le plugin ne suit pas les [\"Restrictions de nommage des fichiers système API 8.3\"][4].\n*   BLOB et le fichier \"`close` la fonction n'est pas pris en charge.\n*   `FileSaver` et `BlobBuilder` ne sont pas pris en charge par ce plugin et n'ont stubs.\n*   Le plugin ne supporte pas les `requestAllFileSystems`. Cette fonction est également absent dans les cahier des charges.\n*   Inscriptions dans l'annuaire ne seront pas supprimées si vous utilisez `create: true` drapeau pour le répertoire existant.\n*   Fichiers créés via le constructeur ne sont pas pris en charge. Vous devez plutôt utiliser entry.file méthode.\n*   Chaque navigateur utilise sa propre forme de références URL blob.\n*   `readAsDataURL` fonction est prise en charge, mais le mediatype en Chrome dépend de l'extension entrée, mediatype dans IE est toujours vide (qui est le même que le `texte-plaine` selon la spécification), le mediatype dans Firefox est toujours `application/octet-stream`. Par exemple, si le contenu est `abcdefg` puis Firefox renvoie `données : application / octet-stream ; base64, YWJjZGVmZw ==`, c'est à dire les retours `données:; base64, YWJjZGVmZw ==`, retours de Chrome `données : < mediatype selon l'extension de nom d'entrée > ; base64, YWJjZGVmZw ==`.\n*   `toInternalURL` retourne le chemin d'accès dans le formulaire `file:///persistent/path/to/entry` (Firefox, IE). Chrome retourne le chemin d'accès dans le formulaire `cdvfile://localhost/persistent/file`.\n\n [4]: http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions\n\n### Bizarreries de chrome\n\n*   Chrome filesystem n'est pas prête immédiatement après l'événement ready périphérique. Pour contourner le problème, vous pouvez vous abonner à l'événement `filePluginIsReady`. Exemple : \n\n    javascript\n    window.addEventListener('filePluginIsReady', function(){ console.log('File plugin is ready');}, false);\n    \n\nVous pouvez utiliser la fonction `window.isFilePluginReadyRaised` pour vérifier si les événement était déjà déclenché. -quotas de window.requestFileSystem temporaire et permanent de système de fichiers ne sont pas limités en Chrome. -Pour augmenter le stockage persistant en Chrome, vous devez appeler la méthode `window.initPersistentFileSystem`. Quota de stockage persistant est 5 Mo par défaut. -Chrome nécessite `--permettre-fichier-accès-de-fichiers` exécuter l'argument au support API via le protocole `file:///`. -`Fichier` objet changera pas si vous utilisez le drapeau `{create:true}` lors du passage d'une `entrée` existante. -événements `annulables` propriété a la valeur true dans Chrome. Il s'agit à l'encontre de la [spécification][5]. -`toURL` renvoie à Chrome `système de fichiers :`-préfixe de chemin d'accès selon l'application hôte. Par exemple, `filesystem:file:///persistent/somefile.txt`, `filesystem:http://localhost:8080/persistent/somefile.txt`. -résultat de la fonction `toURL` ne contient-elle pas de barre oblique dans le cas d'entrée d'annuaire. Chrome résout répertoires avec barre oblique-trainés URL correctement cependant. -`resolveLocalFileSystemURL` méthode nécessite l' entrant `url` préfixe de `système de fichiers`. Par exemple, le paramètre `d'url` pour `resolveLocalFileSystemURL` devrait être dans la forme `filesystem:file:///persistent/somefile.txt` par opposition à la forme `file:///persistent/somefile.txt` dans Android. -Déconseillée `toNativeURL` fonction n'est pas prise en charge et n'est pas une ébauche. -fonction de `setMetadata` n'est pas stipulée dans le devis et pas pris en charge. -INVALID_MODIFICATION_ERR (code: 9) est levée au lieu de SYNTAX_ERR(code: 8) sur la demande d'un système de fichier inexistant. -INVALID_MODIFICATION_ERR (code: 9) est levée au lieu de PATH_EXISTS_ERR(code: 12) à essayer de créer exclusivement un fichier ou un répertoire, qui existe déjà. -INVALID_MODIFICATION_ERR (code: 9) est levée au lieu de NO_MODIFICATION_ALLOWED_ERR(code: 6) à essayer d'appeler removeRecursively sur le système de fichiers racine. -INVALID_MODIFICATION_ERR (code: 9) est levée au lieu de NOT_FOUND_ERR(code: 1) en essayant de moveTo répertoire qui n'existe pas.\n\n [5]: http://dev.w3.org/2009/dap/file-system/file-writer.html\n\n### Base IndexedDB impl bizarreries (Firefox et IE)\n\n*   `.` et `.` ne sont pas pris en charge.\n*   IE ne prend pas en charge les `file:///`-mode ; seul le mode hébergé est pris en charge (http://localhost:xxxx).\n*   Taille de système de fichiers de Firefox n'est pas limité, mais chaque extension de 50Mo demandera une autorisation de l'utilisateur. IE10 permet jusqu'à 10 Mo de combiné AppCache et IndexedDB utilisés dans la mise en œuvre du système de fichiers sans demander de confirmation, une fois que vous atteignez ce niveau, Qu'on vous demandera si vous souhaitez lui permettre d'être augmentée jusqu'à un maximum de 250 Mo par site. Si le paramètre de `taille` pour la fonction `requestFileSystem` n'affecte pas le système de fichiers dans Firefox et IE.\n*   fonction de `readAsBinaryString` n'est pas indiquée dans les spécifications et pas pris en charge dans Internet Explorer et n'a pas une ébauche.\n*   `file.type` est toujours null.\n*   Vous ne devez pas créer en utilisant le résultat du callback instance DirectoryEntry qui avait été supprimée. Sinon, vous obtiendrez une « entrée de pendaison ».\n*   Avant que vous pouvez lire un fichier qui a été écrit juste que vous devez obtenir une nouvelle instance de ce fichier.\n*   `setMetadata` fonction, qui n'est pas indiquée dans les spécifications supporte `modificationTime` changement de champ seulement. \n*   fonctions `copyTo` et `moveTo` ne supportent pas les répertoires.\n*   Répertoires métadonnées ne sont pas pris en charge.\n*   Les deux Entry.remove et directoryEntry.removeRecursively ne manquent pas lors de la suppression des répertoires non-vides - répertoires retirés sont nettoyés avec contenu au lieu de cela.\n*   fonctions `abort` et `truncate` ne sont pas supportées.\n*   événements de progression ne sont pas déclenchés. Par exemple, ce gestionnaire ne sera pas exécuté :\n\n    javascript\n    writer.onprogress = function() { /*commands*/ };\n    \n\n## Notes de mise à niveau\n\nV1.0.0 de ce plugin, les structures `FileEntry` et `DirectoryEntry` ont changé, pour être plus conforme à la spécification publiée.\n\nLes versions précédentes de (pré-1.0.0) du plugin stockaient le dispositif-absolu--emplacement du fichier dans la propriété `fullPath` d'objets `d'entrée`. Ces chemins seraient présente généralement comme\n\n    / var/mobile/Applications/< application UUID >/Documents/chemin/vers/fichier (iOS), /storage/emulated/0/path/to/file (Android)\n    \n\nCes chemins ont été également retournés par la méthode de `toURL()` les objets `d'entrée`.\n\nAvec v1.0.0, l'attribut `fullPath` est le chemin d'accès au fichier, *par rapport à la racine du système de fichiers HTML*. Ainsi, les chemins d'accès ci-dessus seraient maintenant tous les deux être représentée par un objet `FileEntry` avec un `fullPath` de\n\n    /path/to/file\n    \n\nSi votre application fonctionne avec le dispositif-absolu-chemins et que vous avez récupéré précédemment ces chemins d'accès par le biais de la propriété `fullPath` d'objets `d'entrée`, puis vous devez mettre à jour votre code afin d'utiliser `entry.toURL()` à la place.\n\nPour vers l'arrière la compatibilité, la méthode `resolveLocalFileSystemURL()` sera un chemin absolu de l'unité et retourne un objet `Entry` correspondant à elle, tant que ce fichier existe au sein des systèmes de fichiers les `TEMPORARY` ou `PERSISTENT`.\n\nCela a été particulièrement un problème avec le plugin de transfert de fichiers, qui autrefois périphérique-absolu-chemins (et peut encore accepter). Il a été mis à jour pour fonctionner correctement avec le système de fichiers URL, afin de remplacer `entry.fullPath` par `entry.toURL()` devrait résoudre tout problème obtenir ce plugin pour travailler avec des fichiers sur le périphérique.\n\nDans v1.1.0 la valeur de retour de `toURL()` a été changée (voir \\[CB-6394\\] (https://issues.apache.org/jira/browse/CB-6394)) pour renvoyer une URL absolue \"file://\". dans la mesure du possible. Pour assurer un ' cdvfile:'-URL, vous pouvez utiliser `toInternalURL()` maintenant. Cette méthode retourne maintenant filesystem URL du formulaire\n\n    cdvfile://localhost/persistent/path/to/file\n    \n\nqui peut servir à identifier de manière unique le fichier.\n\n## Liste des Codes d'erreur et leur signification\n\nLorsqu'une erreur est levée, l'un des codes suivants sera utilisé.\n\n| Code | Constant                      |\n| ----:|:----------------------------- |\n|    1 | `NOT_FOUND_ERR`               |\n|    2 | `SECURITY_ERR`                |\n|    3 | `ABORT_ERR`                   |\n|    4 | `NOT_READABLE_ERR`            |\n|    5 | `ENCODING_ERR`                |\n|    6 | `NO_MODIFICATION_ALLOWED_ERR` |\n|    7 | `INVALID_STATE_ERR`           |\n|    8 | `SYNTAX_ERR`                  |\n|    9 | `INVALID_MODIFICATION_ERR`    |\n|   10 | `QUOTA_EXCEEDED_ERR`          |\n|   11 | `TYPE_MISMATCH_ERR`           |\n|   12 | `PATH_EXISTS_ERR`             |\n\n## Configuration du Plugin (facultatif)\n\nL'ensemble des systèmes de fichiers disponibles peut être configurée par plate-forme. Les iOS et Android reconnaissent une <preference> balise dans le `fichier config.xml` qui nomme les systèmes de fichiers à installer. Par défaut, toutes les racines du système de fichiers sont activées.\n\n    <preference name=\"iosExtraFilesystems\" value=\"library,library-nosync,documents,documents-nosync,cache,bundle,root\" />\n    <preference name=\"AndroidExtraFilesystems\" value=\"files,files-external,documents,sdcard,cache,cache-external,root\" />\n    \n\n### Android\n\n*   `files` : répertoire de stockage de fichier interne de l'application\n*   `files-external` : répertoire de l'application de stockage de fichier externe\n*   `sdcard` : le répertoire de stockage global fichier externe (c'est la racine de la carte SD, s'il est installé). Vous devez avoir la permission de `android.permission.WRITE_EXTERNAL_STORAGE` de l'utiliser.\n*   `cache` : répertoire de cache interne de l'application\n*   `cache-external` : répertoire de cache externe de l'application\n*   `root` : le système de fichiers de tout dispositif\n\nAndroid prend également en charge un système de fichiers spécial nommé « documents », qui représente un sous-répertoire « / Documents / » dans le système de fichiers « files ».\n\n### iOS\n\n*   `library` : répertoire de bibliothèque de l'application\n*   `documents` : répertoire de Documents de l'application\n*   `cache` : répertoire de Cache de l'application\n*   `bundle` : bundle de l'application ; l'emplacement de l'application elle-même sur disque (lecture seule)\n*   `root` : le système de fichiers de tout dispositif\n\nPar défaut, vous peuvent synchroniser les répertoires de la bibliothèque et les documents à iCloud. Vous pouvez également demander des deux systèmes de fichiers supplémentaires, `library-nosync` et `documents-nosync`, qui représentent un répertoire spécial non synchronisées dans le `/Library` ou système de fichiers `/ Documents`.\n"
  },
  {
    "path": "plugins/cordova-plugin-file/doc/fr/plugins.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# Notes pour les développeurs de plugins\n\nCes notes sont principalement destinés à des développeurs Android et iOS qui veulent écrire des plugins qui interface avec le système de fichiers en utilisant le fichier plugin.\n\n## Travailler avec Cordova fichier système URL\n\nDepuis la version 1.0.0, ce plugin utilise des URL avec un `cdvfile` guichet pour toutes les communications sur le pont, plutôt que d'exposer des chemins de système de fichiers de périphérique brut à JavaScript.\n\nDu côté du JavaScript, cela signifie que les objets FileEntry et DirectoryEntry ont un attribut fullPath qui est relatif à la racine du système de fichiers HTML. Si votre plugin JavaScript API accepte un objet FileEntry ou DirectoryEntry, vous devez appeler `.toURL()` sur cet objet avant de le passer sur le pont en code natif.\n\n### Conversion de cdvfile: / / URL aux chemins d'accès fileystem\n\nPlugins qui ont besoin d'écrire dans le système de fichiers pouvez convertir un fichier reçu système URL vers un emplacement de système de fichiers réels. Il y a plusieurs façons de le faire, selon la plate-forme native.\n\nIl est important de rappeler que pas tous les `cdvfile://` URL sont cartographiables à des fichiers sur le périphérique. Certaines URL peut faire référence aux actifs sur les périphériques qui ne sont pas représentés par des fichiers, ou peuvent même faire référence aux ressources distantes. En raison de ces possibilités, plugins devraient toujours tester si ils obtiennent un résultat significatif retour lorsque vous essayez de convertir les URL aux chemins d'accès.\n\n#### Androïde\n\nSur Android, la méthode la plus simple pour convertir un `cdvfile://` URL vers un chemin d'accès de système de fichiers est d'utiliser `org.apache.cordova.CordovaResourceApi` . `CordovaResourceApi`possède plusieurs méthodes qui peuvent gérer `cdvfile://` URL :\n\n    webView est membre de la Plugin classe CordovaResourceApi resourceApi = webView.getResourceApi() ;\n    \n    Obtenir une URL file:/// représentant ce fichier sur le périphérique, / / ou le même URL inchangée si elle ne peut pas être mappée à un fichier Uri fileURL = resourceApi.remapUri(Uri.parse(cdvfileURL)) ;\n    \n\nIl est également possible d'utiliser le fichier plugin directement :\n\n    Import org.apache.cordova.file.FileUtils ;\n    Import org.apache.cordova.file.FileSystem ;\n    java.net.MalformedURLException d'importation ;\n    \n    Téléchargez le fichier plugin depuis le gestionnaire de plugin FileUtils filePlugin = (FileUtils)webView.pluginManager.getPlugin(\"File\") ;\n    \n    En donnant une URL, obtenir un chemin d'accès pour essayer {String path = filePlugin.filesystemPathForURL(cdvfileURL);} catch (MalformedURLException e) {/ / l'url du système de fichiers n'a pas été reconnu}\n    \n\nPour convertir un chemin d'accès à un `cdvfile://` URL :\n\n    Import org.apache.cordova.file.LocalFilesystemURL ;\n    \n    Obtenir un objet LocalFilesystemURL pour un chemin de périphérique, / / ou null si elle ne peut être représentée sous forme d'URL cdvfile.\n    LocalFilesystemURL url = filePlugin.filesystemURLforLocalPath(path) ;\n    Obtenir la chaîne représentant l'URL objet String cdvfileURL = url.toString() ;\n    \n\nSi votre plugin crée un fichier et que vous souhaitez renvoyer un objet FileEntry pour cela, utilisez le fichier plugin :\n\n    Retourne une structure JSON approprié pour revenir en JavaScript, / / ou null si ce fichier n'est pas représentable sous forme d'URL cdvfile.\n    JSONObject entrée = filePlugin.getEntryForFile(file) ;\n    \n\n#### iOS\n\nCordova sur iOS n'utilise pas le même `CordovaResourceApi` concept d'Android. Sur iOS, vous devez utiliser le fichier plugin pour convertir entre les URL et les chemins d'accès de système de fichiers.\n\n    Obtenir un objet URL CDVFilesystem partir d'une chaîne d'URL CDVFilesystemURL * url = [CDVFilesystemURL fileSystemURLWithString:cdvfileURL] ;\n    Obtenir un chemin d'accès de l'objet URL, ou zéro si elle ne peut pas être mappée à un chemin de fichier NSString * = [filePlugin filesystemPathForURL:url] ;\n    \n    \n    Obtenir un objet CDVFilesystem URL pour un chemin de périphérique, ou / / zéro si elle ne peut être représentée sous forme d'URL cdvfile.\n    CDVFilesystemURL * url = [filePlugin fileSystemURLforLocalPath:path] ;\n    Obtenir la représentation de chaîne de l'objet NSString * cdvfileURL URL = [url absoluteString] ;\n    \n\nSi votre plugin crée un fichier et que vous souhaitez renvoyer un objet FileEntry pour cela, utilisez le fichier plugin :\n\n    Obtenir un objet CDVFilesystem URL pour un chemin de périphérique, ou / / zéro si elle ne peut être représentée sous forme d'URL cdvfile.\n    CDVFilesystemURL * url = [filePlugin fileSystemURLforLocalPath:path] ;\n    Obtenir une structure pour revenir à JavaScript NSDictionary * entrée = [filePlugin makeEntryForLocalURL:url]\n    \n\n#### JavaScript\n\nEn JavaScript, pour obtenir un `cdvfile://` URL d'un objet FileEntry ou DirectoryEntry, il suffit d'appeler `.toURL()` à ce sujet :\n\n    var cdvfileURL = entry.toURL() ;\n    \n\nDans gestionnaires de plugin de réponse, pour convertir une structure FileEntry retournée vers un objet réel de l'entrée, votre code de gestionnaire doit importer le fichier plugin et créer un nouvel objet :\n\n    créer l'entrée de var d'objet entrée appropriée ;\n    Si (entryStruct.isDirectory) {entrée = new DirectoryEntry (entryStruct.name, entryStruct.fullPath, nouveau FileSystem(entryStruct.filesystemName));} else {entrée = nouvelle FileEntry (entryStruct.name, entryStruct.fullPath, nouvelle FileSystem(entryStruct.filesystemName));}"
  },
  {
    "path": "plugins/cordova-plugin-file/doc/it/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-file\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-file.svg)](https://travis-ci.org/apache/cordova-plugin-file)\n\nQuesto plugin implementa un API File permettendo l'accesso di lettura/scrittura ai file che risiedono sul dispositivo.\n\nQuesto plugin si basa su diverse specifiche, tra cui: The HTML5 File API <http://www.w3.org/TR/FileAPI/>\n\nLe directory (ormai defunta) e il sistema delle estensioni più recenti: <http://www.w3.org/TR/2012/WD-file-system-api-20120417/> anche se la maggior parte del codice plugin è stato scritto quando una spec precedenti era corrente: <http://www.w3.org/TR/2011/WD-file-system-api-20110419/>\n\nImplementa inoltre FileWriter spec: <http://dev.w3.org/2009/dap/file-system/file-writer.html>\n\nPer l'utilizzo, fare riferimento a HTML5 Rocks' eccellente [articolo FileSystem.](http://www.html5rocks.com/en/tutorials/file/filesystem/)\n\nPer una panoramica delle altre opzioni di archiviazione, consultare [Guida di archiviazione di Cordova](http://cordova.apache.org/docs/en/edge/cordova_storage_storage.md.html).\n\nQuesto plugin definisce oggetto global `cordova.file`.\n\nAnche se in ambito globale, non è disponibile fino a dopo l'evento `deviceready`.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(cordova.file);\n    }\n    \n\n## Installazione\n\n    cordova plugin add cordova-plugin-file\n    \n\n## Piattaforme supportate\n\n  * Amazon fuoco OS\n  * Android\n  * BlackBerry 10\n  * Firefox OS\n  * iOS\n  * Windows Phone 7 e 8 *\n  * Windows 8 *\n  * Windows*\n  * Browser\n\n\\* *These platforms do not support `FileReader.readAsArrayBuffer` nor `FileWriter.write(blob)`.*\n\n## Dove memorizzare i file\n\nA partire dalla v 1.2.0, vengono forniti gli URL per le directory importanti file di sistema. Ogni URL è nella forma *file:///path/to/spot/* e può essere convertito in un `DirectoryEntry` utilizzando `window.resolveLocalFileSystemURL()`.\n\n  * `cordova.file.applicationDirectory`-Sola lettura directory dove è installato l'applicazione. (*iOS*, *Android*, *BlackBerry 10*)\n\n  * `cordova.file.applicationStorageDirectory`-Directory radice di sandbox dell'applicazione; su iOS questa posizione è in sola lettura (ma sottodirectory specifiche [come `/Documents` ] sono di sola lettura). Tutti i dati contenuti all'interno è privato all'app. ( *iOS*, *Android*, *BlackBerry 10*)\n\n  * `cordova.file.dataDirectory`-Archiviazione dati persistente e privati nella sandbox dell'applicazione utilizzando la memoria interna (su Android, se è necessario utilizzare la memoria esterna, utilizzare `.externalDataDirectory` ). IOS, questa directory non è sincronizzata con iCloud (utilizzare `.syncedDataDirectory` ). (*iOS*, *Android*, *BlackBerry 10*)\n\n  * `cordova.file.cacheDirectory`-Directory per i file memorizzati nella cache di dati o qualsiasi file che app possibile ricreare facilmente. L'OS può eliminare questi file quando il dispositivo viene eseguito basso sull'archiviazione, tuttavia, apps non deve basarsi sul sistema operativo per cancellare i file qui. (*iOS*, *Android*, *BlackBerry 10*)\n\n  * `cordova.file.externalApplicationStorageDirectory`-Spazio applicazione su storage esterno. (*Android*)\n\n  * `cordova.file.externalDataDirectory`-Dove mettere i file di dati specifico app su storage esterno. (*Android*)\n\n  * `cordova.file.externalCacheDirectory`-Cache applicazione su storage esterno. (*Android*)\n\n  * `cordova.file.externalRootDirectory`-Radice di archiviazione esterna (scheda SD). (*Android*, *BlackBerry, 10*)\n\n  * `cordova.file.tempDirectory`-Temp directory che l'OS è possibile cancellare a volontà. Non fare affidamento sul sistema operativo per cancellare questa directory; l'app deve sempre rimuovere file come applicabile. (*iOS*)\n\n  * `cordova.file.syncedDataDirectory`-Contiene i file app specifiche che devono essere sincronizzati (per esempio a iCloud). (*iOS*)\n\n  * `cordova.file.documentsDirectory`-I file privati per le app, ma che sono significativi per altre applicazioni (ad esempio i file di Office). (*iOS*)\n\n  * `cordova.file.sharedDirectory`-File disponibili globalmente a tutte le applicazioni (*BlackBerry 10*)\n\n## Layout dei file di sistema\n\nAnche se tecnicamente un dettaglio di implementazione, può essere molto utile per conoscere come le proprietà `cordova.file.*` mappa di percorsi fisici su un dispositivo reale.\n\n### iOS File sistema Layout\n\n| Percorso dispositivo                           | `Cordova.file.*`            | `iosExtraFileSystems` | r/w? | persistente? | OS cancella  | sincronizzazione | privato |\n|:---------------------------------------------- |:--------------------------- |:--------------------- |:----:|:------------:|:------------:|:----------------:|:-------:|\n| `/ var/mobile/Applications/< UUID > /`   | applicationStorageDirectory | -                     |  r   |     N/A      |     N/A      |       N/A        |   Sì    |\n| &nbsp;&nbsp;&nbsp;`appname.app/`               | applicationDirectory        | bundle                |  r   |     N/A      |     N/A      |       N/A        |   Sì    |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`www/`     | -                           | -                     |  r   |     N/A      |     N/A      |       N/A        |   Sì    |\n| &nbsp;&nbsp;&nbsp;`Documents/`                 | documentsDirectory          | documenti             | r/w  |      Sì      |      No      |        Sì        |   Sì    |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`NoCloud/` | -                           | nosync-documenti      | r/w  |      Sì      |      No      |        No        |   Sì    |\n| &nbsp;&nbsp;&nbsp;`Library`                    | -                           | libreria              | r/w  |      Sì      |      No      |       Sì?        |   Sì    |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`NoCloud/` | dataDirectory               | nosync-libreria       | r/w  |      Sì      |      No      |        No        |   Sì    |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`Cloud/`   | syncedDataDirectory         | -                     | r/w  |      Sì      |      No      |        Sì        |   Sì    |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`Caches/`  | cacheDirectory              | cache                 | r/w  |     Sì *     | Sì**\\* |        No        |   Sì    |\n| &nbsp;&nbsp;&nbsp;`tmp/`                       | tempDirectory               | -                     | r/w  |   No**   | Sì**\\* |        No        |   Sì    |\n\n\\ * File persistono tra riavvii app e aggiornamenti, ma questa directory può essere cancellata ogni volta che il sistema operativo desideri. L'app dovrebbe essere in grado di ricreare qualsiasi contenuto che potrebbe essere eliminato.\n\n** File possono persistere riavvii del app, ma non fare affidamento su questo comportamento. I file non sono garantiti a persistere attraverso gli aggiornamenti. L'app deve rimuovere i file dalla directory quando è applicabile, come il sistema operativo non garantisce quando (o anche se) questi file vengono rimossi.\n\n**\\ * The OS può cancellare il contenuto di questa directory ogni volta che si sente è necessario, ma non fare affidamento su questo. Si dovrebbe cancellare questa directory come adatto per l'applicazione.\n\n### Layout sistema Android File\n\n| Percorso dispositivo                             | `Cordova.file.*`                    | `AndroidExtraFileSystems` | r/w? | persistente? | OS cancella | privato |\n|:------------------------------------------------ |:----------------------------------- |:------------------------- |:----:|:------------:|:-----------:|:-------:|\n| `File:///android_asset/`                         | applicationDirectory                |                           |  r   |     N/A      |     N/A     |   Sì    |\n| `< app-id > /dati/dati / /`                | applicationStorageDirectory         | -                         | r/w  |     N/A      |     N/A     |   Sì    |\n| &nbsp;&nbsp;&nbsp;`cache`                        | cacheDirectory                      | cache                     | r/w  |      Sì      |   Sì\\*    |   Sì    |\n| &nbsp;&nbsp;&nbsp;`files`                        | dataDirectory                       | file                      | r/w  |      Sì      |     No      |   Sì    |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`Documents`  |                                     | documenti                 | r/w  |      Sì      |     No      |   Sì    |\n| `< sdcard > /`                             | externalRootDirectory               | sdcard                    | r/w  |      Sì      |     No      |   No    |\n| &nbsp;&nbsp;&nbsp;`Android/data/<app-id>/` | externalApplicationStorageDirectory | -                         | r/w  |      Sì      |     No      |   No    |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`cache`      | externalCacheDirectry               | cache-esterno             | r/w  |      Sì      |  No**   |   No    |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`files`      | externalDataDirectory               | file-esterno              | r/w  |      Sì      |     No      |   No    |\n\n\\ * Il sistema operativo può cancellare periodicamente questa directory, ma non fare affidamento su questo comportamento. Cancellare il contenuto di questa directory come adatto per l'applicazione. Il contenuto di questa directory dovrebbe un utente eliminare manualmente la cache, vengono rimossi.\n\n** Il sistema operativo non cancella questa directory automaticamente; Siete responsabili di gestire i contenuti da soli. Il contenuto della directory dovrebbe l'utente eliminare manualmente la cache, vengono rimossi.\n\n**Nota**: se la memorizzazione esterna non può essere montato, le proprietà `cordova.file.external*` sono `null`.\n\n### BlackBerry 10 File sistema Layout\n\n| Percorso dispositivo                                        | `Cordova.file.*`            | r/w? | persistente? | OS cancella | privato |\n|:----------------------------------------------------------- |:--------------------------- |:----:|:------------:|:-----------:|:-------:|\n| `File:///accounts/1000/AppData/ < id app > /`         | applicationStorageDirectory |  r   |     N/A      |     N/A     |   Sì    |\n| &nbsp;&nbsp;&nbsp;`app/native`                              | applicationDirectory        |  r   |     N/A      |     N/A     |   Sì    |\n| &nbsp;&nbsp;&nbsp;`data/webviews/webfs/temporary/local__0`  | cacheDirectory              | r/w  |      No      |     Sì      |   Sì    |\n| &nbsp;&nbsp;&nbsp;`data/webviews/webfs/persistent/local__0` | dataDirectory               | r/w  |      Sì      |     No      |   Sì    |\n| `File:///accounts/1000/Removable/sdcard`                    | externalRemovableDirectory  | r/w  |      Sì      |     No      |   No    |\n| `File:///accounts/1000/Shared`                              | sharedDirectory             | r/w  |      Sì      |     No      |   No    |\n\n*Nota*: quando l'applicazione viene distribuita a lavorare perimetrale, tutti i percorsi sono relativi a /accounts/1000-enterprise.\n\n## Stranezze Android\n\n### Posizione di archiviazione persistente Android\n\nCi sono più percorsi validi per memorizzare i file persistenti su un dispositivo Android. Vedi [questa pagina](http://developer.android.com/guide/topics/data/data-storage.html) per un'ampia discussione delle varie possibilità.\n\nVersioni precedenti del plugin avrebbe scelto il percorso dei file temporanei e permanenti su avvio, in base se il dispositivo ha sostenuto che la scheda SD (o partizione storage equivalente) è stato montato. Se è stata montata sulla scheda SD o una partizione di storage interno grande era disponibile (come sui dispositivi Nexus,) allora saranno memorizzati i file persistenti nella radice di quello spazio. Questo significava che tutte le apps di Cordova poteva vedere tutti i file disponibili sulla carta.\n\nSe la scheda SD non era disponibile, poi versioni precedenti vuoi memorizzare dati sotto `/data/data/<packageId>`, che isola i apps da altro, ma può ancora causa dati da condividere tra gli utenti.\n\nOra è possibile scegliere se memorizzare i file nel percorso di archiviazione di file interno o utilizzando la logica precedente, con una preferenza nel file `config. xml` dell'applicazione. Per fare questo, aggiungere una di queste due linee al `file config. xml`:\n\n    <preference name=\"AndroidPersistentFileLocation\" value=\"Internal\" />\n    \n    <preference name=\"AndroidPersistentFileLocation\" value=\"Compatibility\" />\n    \n\nSenza questa linea, il File del plugin utilizzerà la `Compatibility` come predefinito. Se è presente un tag di preferenza e non è uno di questi valori, l'applicazione non si avvia.\n\nSe l'applicazione è stato spedito in precedenza agli utenti, utilizzando un vecchio (pre-1.0) versione di questo plugin e ha i file memorizzati nel filesystem persistente, allora si dovrebbe impostare la preferenza di `Compatibility`. La posizione su \"Interno\" di commutazione significherebbe che gli utenti esistenti che aggiornare la loro applicazione potrebbero essere Impossibile accedere ai loro file precedentemente memorizzati, a seconda del loro dispositivo.\n\nSe l'applicazione è nuova, o ha mai precedentemente memorizzati i file nel filesystem persistente, è generalmente consigliato l'impostazione `Internal`.\n\n### Operazioni ricorsive lento per /android_asset\n\nL'elencazione delle directory asset è veramente lento su Android. È possibile velocizzare e fino anche se, con l'aggiunta di `src/android/build-extras.gradle` alla radice del tuo progetto android (richiede anche cordova-android@4.0.0 o superiore).\n\n## iOS stranezze\n\n  * `cordova.file.applicationStorageDirectory`è di sola lettura; tentativo di memorizzare i file all'interno della directory radice avrà esito negativo. Utilizzare uno degli altri `cordova.file.*` proprietà definite per iOS (solo `applicationDirectory` e `applicationStorageDirectory` sono di sola lettura).\n  * `FileReader.readAsText(blob, encoding)` \n      * Il `encoding` parametro non è supportato, e codifica UTF-8 è sempre attivo.\n\n### posizione di archiviazione persistente di iOS\n\nCi sono due percorsi validi per memorizzare i file persistenti su un dispositivo iOS: la directory documenti e la biblioteca. Precedenti versioni del plugin archiviati solo mai persistenti file nella directory documenti. Questo ha avuto l'effetto collaterale di tutti i file di un'applicazione che rende visibili in iTunes, che era spesso involontaria, soprattutto per le applicazioni che gestiscono un sacco di piccoli file, piuttosto che produrre documenti completi per l'esportazione, che è la destinazione della directory.\n\nOra è possibile scegliere se memorizzare i file nella directory di libreria, con una preferenza nel file `config. xml` dell'applicazione o documenti. Per fare questo, aggiungere una di queste due linee al `file config. xml`:\n\n    <preference name=\"iosPersistentFileLocation\" value=\"Library\" />\n    \n    <preference name=\"iosPersistentFileLocation\" value=\"Compatibility\" />\n    \n\nSenza questa linea, il File del plugin utilizzerà la `Compatibility` come predefinito. Se è presente un tag di preferenza e non è uno di questi valori, l'applicazione non si avvia.\n\nSe l'applicazione è stato spedito in precedenza agli utenti, utilizzando un vecchio (pre-1.0) versione di questo plugin e ha i file memorizzati nel filesystem persistente, allora si dovrebbe impostare la preferenza di `Compatibility`. La posizione di commutazione alla `libreria` significherebbe che gli utenti esistenti che aggiornare la loro applicazione è in grado di accedere ai loro file precedentemente memorizzati.\n\nSe l'applicazione è nuova, o ha mai precedentemente memorizzati i file nel filesystem persistente, è generalmente consigliato l'impostazione della `Library`.\n\n## Firefox OS stranezze\n\nL'API di sistema del File non è supportato nativamente dal sistema operativo Firefox e viene implementato come uno spessore in cima indexedDB.\n\n  * Non manca quando si rimuove le directory non vuota\n  * Non supporta i metadati per le directory\n  * Metodi `copyTo` e `moveTo` non supporta le directory\n\nSono supportati i seguenti percorsi di dati: * `applicationDirectory` - utilizza `xhr` per ottenere i file locali che sono confezionati con l'app. *`dataDirectory` - per i file di dati persistenti app specifiche. *`cacheDirectory` - file memorizzati nella cache che dovrebbe sopravvivere si riavvia app (applicazioni non devono basarsi sull'OS di eliminare i file qui).\n\n## Stranezze browser\n\n### Stranezze e osservazioni comuni\n\n  * Ogni browser utilizza il proprio filesystem in modalità sandbox. IE e Firefox utilizzare IndexedDB come base. Tutti i browser utilizzano barra come separatore di directory in un percorso.\n  * Le voci di directory devono essere creato successivamente. Ad esempio, la chiamata `fs.root.getDirectory (' dir1/dir2 ', {create:true}, successCallback, errorCallback)` non riuscirà se non esistesse dir1.\n  * Il plugin richiede autorizzazione utente per utilizzare un archivio permanente presso il primo avvio dell'applicazione. \n  * Plugin supporta `cdvfile://localhost` (risorse locali) solo. Cioè risorse esterne non sono supportate tramite `cdvfile`.\n  * Il plugin non segue [\"Limitazioni di denominazione 8.3 File sistema API\"](http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions).\n  * BLOB e File' `close` la funzione non è supportata.\n  * `FileSaver` e `BlobBuilder` non sono supportati da questo plugin e non hanno gli stub.\n  * Il plugin non supporta `requestAllFileSystems`. Questa funzione manca anche nelle specifiche.\n  * Entrate nella directory non verranno rimossi se si utilizza `create: true` bandiera per directory esistente.\n  * Non sono supportati i file creati tramite il costruttore. È invece necessario utilizzare il metodo entry.file.\n  * Ogni browser utilizza la propria forma per riferimenti URL blob.\n  * `readAsDataURL` funzione è supportata, ma il mediatype in Chrome dipende dall'estensione di voce, mediatype in IE è sempre vuota (che è lo stesso come `text-plain` secondo la specifica), il mediatype in Firefox è sempre `application/octet-stream`. Ad esempio, se il contenuto è `abcdefg` quindi Firefox restituisce `dati: applicazione / octet-stream; base64, YWJjZGVmZw = =`, cioè restituisce `dati:; base64, YWJjZGVmZw = =`, Chrome restituisce `dati: < mediatype a seconda dell'estensione del nome della voce >; base64, YWJjZGVmZw = =`.\n  * `toInternalURL` restituisce il percorso in forma `file:///persistent/path/to/entry` (Firefox, IE). Chrome restituisce il percorso nella forma `cdvfile://localhost/persistent/file`.\n\n### Stranezze di cromo\n\n  * Cromo filesystem non è subito pronto dopo evento ready dispositivo. Come soluzione alternativa, è possibile iscriversi all'evento `filePluginIsReady`. Esempio: \n\n```javascript\nwindow.addEventListener('filePluginIsReady', function(){ console.log('File plugin is ready');}, false);\n```\n\nÈ possibile utilizzare la funzione `window.isFilePluginReadyRaised` per verificare se evento già è stato generato. -quote di filesystem TEMPORARY e PERSISTENT window.requestFileSystem non sono limitate in Chrome. -Per aumentare la memoria persistente in Chrome è necessario chiamare il metodo `window.initPersistentFileSystem`. Quota di archiviazione persistente è di 5 MB per impostazione predefinita. -Chrome richiede `-consentire-file-accesso-da-file` eseguire argomento a supporto API tramite protocollo `file:///`. -`File` oggetto non cambierà se si utilizza il flag `{create:true}` quando ottenendo un' esistente `entrata`. -eventi `cancelable` è impostata su true in Chrome. Ciò è in contrasto con la [specifica](http://dev.w3.org/2009/dap/file-system/file-writer.html). -funzione `toURL` Chrome restituisce `filesystem:`-premessi percorso a seconda dell'applicazione host. Ad esempio, `filesystem:file:///persistent/somefile.txt`, `filesystem:http://localhost:8080/persistent/somefile.txt`. -`toURL` risultato di funzione non contiene una barra finale in caso di voce di directory. Chrome risolve le directory con gli URL slash-trainati però correttamente. -`resolveLocalFileSystemURL` metodo richiede in ingresso `url` avere il prefisso del `file System`. Ad esempio, il parametro `url` per `resolveLocalFileSystemURL` dovrebbe essere nella forma `filesystem:file:///persistent/somefile.txt` in contrasto con la forma `file:///persistent/somefile.txt` in Android. -Obsoleto `toNativeURL` funzione non è supportata e non dispone di uno stub. -funzione `setMetadata` non è indicato nelle specifiche e non supportato. -INVALID_MODIFICATION_ERR (codice: 9) viene generata invece di SYNTAX_ERR(code: 8) su richiesta di un filesystem inesistente. -INVALID_MODIFICATION_ERR (codice: 9) viene generata invece di PATH_EXISTS_ERR(code: 12) sul tentativo di creare esclusivamente un file o una directory, che esiste già. -INVALID_MODIFICATION_ERR (codice: 9) viene generata invece di NO_MODIFICATION_ALLOWED_ERR(code: 6) sul tentativo di chiamare removeRecursively su file system root. -INVALID_MODIFICATION_ERR (codice: 9) viene generata invece di NOT_FOUND_ERR(code: 1) sul tentativo moveTo directory che non esiste.\n\n### Stranezze impl IndexedDB-basato (Firefox e IE)\n\n  * `.` e `.` non sono supportati.\n  * IE non supporta `file:///`-modalità; modalità solo ospitata è supportato (http://localhost:xxxx).\n  * Dimensione filesystem Firefox non è limitata, ma ogni estensione 50MB sarà richiesta un'autorizzazione dell'utente. IE10 consente fino a 10mb di combinato AppCache e IndexedDB utilizzato nell'implementazione del filesystem senza chiedere conferma, una volta premuto quel livello che vi verrà chiesto se si desidera consentire ad essere aumentata fino a un max di 250 mb per ogni sito. Quindi la `size` parametro per la funzione `requestFileSystem` non influisce il filesystem in Firefox e IE.\n  * `readAsBinaryString` funzione non è indicato nelle specifiche e non supportati in IE e non dispone di uno stub.\n  * `file.Type` è sempre null.\n  * Non è necessario creare la voce utilizzando il risultato del callback istanza DirectoryEntry che è stato eliminato. In caso contrario, si otterrà una 'voce di sospensione'.\n  * Prima è possibile leggere un file che è stato appena scritto è necessario ottenere una nuova istanza di questo file.\n  * supporta la funzione `setMetadata`, che non è indicato nelle specifiche `modificationTime` cambiamento di campo solo. \n  * funzioni `copyTo` e `moveTo` non supporta le directory.\n  * Le directory metadati non sono supportato.\n  * Sia Entry.remove e directoryEntry.removeRecursively non fallire quando si rimuove le directory non vuota - directory da rimuovere vengono pulite invece insieme al contenuto.\n  * `abort` e `truncate` le funzioni non sono supportate.\n  * non vengono generati eventi di progresso. Ad esempio, questo gestore verrà non eseguito:\n\n```javascript\nwriter.onprogress = function() { /*commands*/ };\n```\n\n## Note di aggiornamento\n\nIn v 1.0.0 di questo plugin, le strutture `FileEntry` e `DirectoryEntry` sono cambiati, per essere più in linea con le specifiche pubblicate.\n\nVersioni precedenti (pre-1.0.0) del plugin archiviati il dispositivo-assoluto--percorso del file nella proprietà `fullPath` di oggetti della `voce`. In genere questi percorsi si sarebbe simile\n\n    /var/mobile/Applications/<application UUID>/Documents/path/to/file  (iOS)\n    /storage/emulated/0/path/to/file                                    (Android)\n    \n\nQuesti percorsi sono stati anche restituiti dal metodo `toURL()` degli oggetti `Entry`.\n\nCon v 1.0.0, l'attributo `fullPath` è il percorso del file, *rispetto alla radice del filesystem HTML*. Così, i percorsi sopra sarebbe ora sia rappresentato da un oggetto `FileEntry` con un `fullPath` di\n\n    /path/to/file\n    \n\nSe l'applicazione funziona con dispositivo-assoluto-percorsi, e precedentemente recuperato quei percorsi attraverso la proprietà `fullPath` della `voce` oggetti, è necessario aggiornare il codice per utilizzare `entry.toURL()` invece.\n\nPer indietro la compatibilità, il metodo `resolveLocalFileSystemURL()` verrà accettare un dispositivo-assoluto-percorso e restituirà un oggetto di `entrata` corrispondente ad essa, fintanto che il file esiste all'interno del filesystem la `temporanea` o `permanente`.\n\nQuesto particolare è stato un problema con il plugin di trasferimento File, che in precedenza utilizzati percorsi-dispositivo-assoluto (e ancora può accoglierli). Esso è stato aggiornato per funzionare correttamente con gli URL di FileSystem, così sostituendo `entry.fullPath` con `entry.toURL()` dovrebbe risolvere eventuali problemi ottenendo quel plugin per lavorare con i file nel dispositivo.\n\nIn v 1.1.0 il valore restituito di `toURL()` è stato cambiato (vedere \\[CB-6394\\] (https://issues.apache.org/jira/browse/CB-6394)) per restituire un URL assoluto 'file://'. ove possibile. Per assicurare un ' cdvfile:'-URL, è possibile utilizzare `toInternalURL()` ora. Questo metodo restituirà ora filesystem URL del modulo\n\n    cdvfile://localhost/persistent/path/to/file\n    \n\nche può essere utilizzato per identificare univocamente il file.\n\n## Elenco dei codici di errore e significati\n\nQuando viene generato un errore, uno dei seguenti codici da utilizzare.\n\n| Codice | Costante                      |\n| ------:|:----------------------------- |\n|      1 | `NOT_FOUND_ERR`               |\n|      2 | `SECURITY_ERR`                |\n|      3 | `ABORT_ERR`                   |\n|      4 | `NOT_READABLE_ERR`            |\n|      5 | `ENCODING_ERR`                |\n|      6 | `NO_MODIFICATION_ALLOWED_ERR` |\n|      7 | `INVALID_STATE_ERR`           |\n|      8 | `SYNTAX_ERR`                  |\n|      9 | `INVALID_MODIFICATION_ERR`    |\n|     10 | `QUOTA_EXCEEDED_ERR`          |\n|     11 | `TYPE_MISMATCH_ERR`           |\n|     12 | `PATH_EXISTS_ERR`             |\n\n## Configurare il Plugin (opzionale)\n\nIl set di filesystem disponibili può essere configurato per ogni piattaforma. Sia iOS che Android riconoscere un <preference> Tag nel `file config. xml` che nomina il filesystem per essere installato. Per impostazione predefinita, tutte le radici del file system sono abilitate.\n\n    <preference name=\"iosExtraFilesystems\" value=\"library,library-nosync,documents,documents-nosync,cache,bundle,root\" />\n    <preference name=\"AndroidExtraFilesystems\" value=\"files,files-external,documents,sdcard,cache,cache-external,root\" />\n    \n\n### Android\n\n  * `files`: directory di archiviazione di file interno dell'applicazione\n  * `files-external`: directory di archiviazione dell'applicazione file esterno\n  * `sdcard`: la directory di archiviazione di file esterni globale (questa è la radice della scheda SD, se uno è installato). È necessario disporre dell'autorizzazione `android.permission.WRITE_EXTERNAL_STORAGE` utilizzare questo.\n  * `cache`: la cache interna directory applicazione\n  * `cache-external`: directory di cache esterna dell'applicazione\n  * `root`: il dispositivo intero filesystem\n\nAndroid supporta anche un filesystem speciale denominato \"documenti\", che rappresenta una sottodirectory \"/ documenti /\" all'interno del filesystem \"files\".\n\n### iOS\n\n  * `library`: la directory dell'applicazione libreria\n  * `documents`: la directory dell'applicazione documenti\n  * `cache`: la Cache directory applicazione\n  * `bundle`: bundle dell'applicazione; la posizione dell'app sul disco (sola lettura)\n  * `root`: il dispositivo intero filesystem\n\nPer impostazione predefinita, la directory di libreria e documenti può essere sincronizzata a iCloud. È anche possibile richiedere due filesystem aggiuntivi, `library-nosync` e `documents-nosync`, che rappresentano una speciale directory non sincronizzati entro il `/Library` o filesystem `/Documents`."
  },
  {
    "path": "plugins/cordova-plugin-file/doc/it/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-file\n\nQuesto plugin implementa un API File permettendo l'accesso di lettura/scrittura ai file che risiedono sul dispositivo.\n\nQuesto plugin si basa su diverse specifiche, tra cui: The HTML5 File API <http://www.w3.org/TR/FileAPI/>\n\nLe directory (ormai defunta) e il sistema delle estensioni più recenti: <http://www.w3.org/TR/2012/WD-file-system-api-20120417/> anche se la maggior parte del codice plugin è stato scritto quando una spec precedenti era corrente: <http://www.w3.org/TR/2011/WD-file-system-api-20110419/>\n\nImplementa inoltre FileWriter spec: <http://dev.w3.org/2009/dap/file-system/file-writer.html>\n\nPer l'utilizzo, fare riferimento a HTML5 Rocks' eccellente [articolo FileSystem.][1]\n\n [1]: http://www.html5rocks.com/en/tutorials/file/filesystem/\n\nPer una panoramica delle altre opzioni di archiviazione, consultare [Guida di archiviazione di Cordova][2].\n\n [2]: http://cordova.apache.org/docs/en/edge/cordova_storage_storage.md.html\n\nQuesto plugin definisce oggetto global `cordova.file`.\n\nAnche se in ambito globale, non è disponibile fino a dopo l'evento `deviceready`.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(cordova.file);\n    }\n    \n\n## Installazione\n\n    cordova plugin add cordova-plugin-file\n    \n\n## Piattaforme supportate\n\n*   Amazon fuoco OS\n*   Android\n*   BlackBerry 10\n*   Firefox OS\n*   iOS\n*   Windows Phone 7 e 8 *\n*   Windows 8 *\n*   Browser\n\n* *Queste piattaforme non supportano `FileReader.readAsArrayBuffer` né `FileWriter.write(blob)`.*\n\n## Dove memorizzare i file\n\nA partire dalla v 1.2.0, vengono forniti gli URL per le directory importanti file di sistema. Ogni URL è nella forma *file:///path/to/spot/* e può essere convertito in un `DirectoryEntry` utilizzando `window.resolveLocalFileSystemURL()`.\n\n*   `cordova.file.applicationDirectory`-Sola lettura directory dove è installato l'applicazione. (*iOS*, *Android*, *BlackBerry 10*)\n\n*   `cordova.file.applicationStorageDirectory`-Directory radice di sandbox dell'applicazione; su iOS questa posizione è in sola lettura (ma sottodirectory specifiche [come `/Documents` ] sono di sola lettura). Tutti i dati contenuti all'interno è privato all'app. ( *iOS*, *Android*, *BlackBerry 10*)\n\n*   `cordova.file.dataDirectory`-Archiviazione dati persistente e privati nella sandbox dell'applicazione utilizzando la memoria interna (su Android, se è necessario utilizzare la memoria esterna, utilizzare `.externalDataDirectory` ). IOS, questa directory non è sincronizzata con iCloud (utilizzare `.syncedDataDirectory` ). (*iOS*, *Android*, *BlackBerry 10*)\n\n*   `cordova.file.cacheDirectory`-Directory per i file memorizzati nella cache di dati o qualsiasi file che app possibile ricreare facilmente. L'OS può eliminare questi file quando il dispositivo viene eseguito basso sull'archiviazione, tuttavia, apps non deve basarsi sul sistema operativo per cancellare i file qui. (*iOS*, *Android*, *BlackBerry 10*)\n\n*   `cordova.file.externalApplicationStorageDirectory`-Spazio applicazione su storage esterno. (*Android*)\n\n*   `cordova.file.externalDataDirectory`-Dove mettere i file di dati specifico app su storage esterno. (*Android*)\n\n*   `cordova.file.externalCacheDirectory`-Cache applicazione su storage esterno. (*Android*)\n\n*   `cordova.file.externalRootDirectory`-Radice di archiviazione esterna (scheda SD). (*Android*, *BlackBerry, 10*)\n\n*   `cordova.file.tempDirectory`-Temp directory che l'OS è possibile cancellare a volontà. Non fare affidamento sul sistema operativo per cancellare questa directory; l'app deve sempre rimuovere file come applicabile. (*iOS*)\n\n*   `cordova.file.syncedDataDirectory`-Contiene i file app specifiche che devono essere sincronizzati (per esempio a iCloud). (*iOS*)\n\n*   `cordova.file.documentsDirectory`-I file privati per le app, ma che sono significativi per altre applicazioni (ad esempio i file di Office). (*iOS*)\n\n*   `cordova.file.sharedDirectory`-File disponibili globalmente a tutte le applicazioni (*BlackBerry 10*)\n\n## Layout dei file di sistema\n\nAnche se tecnicamente un dettaglio di implementazione, può essere molto utile per conoscere come le proprietà `cordova.file.*` mappa di percorsi fisici su un dispositivo reale.\n\n### iOS File sistema Layout\n\n| Percorso dispositivo                         | `Cordova.file.*`            | `iosExtraFileSystems` | r/w? | persistente? | OS cancella | sincronizzazione | privato |\n|:-------------------------------------------- |:--------------------------- |:--------------------- |:----:|:------------:|:-----------:|:----------------:|:-------:|\n| `/ var/mobile/Applications/< UUID > /` | applicationStorageDirectory | -                     |  r   |     N/A      |     N/A     |       N/A        |   Sì    |\n|    `appname.app/`                            | applicationDirectory        | bundle                |  r   |     N/A      |     N/A     |       N/A        |   Sì    |\n|       `www/`                                 | -                           | -                     |  r   |     N/A      |     N/A     |       N/A        |   Sì    |\n|    `Documents/`                              | documentsDirectory          | documenti             | r/w  |      Sì      |     No      |        Sì        |   Sì    |\n|       `NoCloud/`                             | -                           | nosync-documenti      | r/w  |      Sì      |     No      |        No        |   Sì    |\n|    `Library`                                 | -                           | libreria              | r/w  |      Sì      |     No      |       Sì?        |   Sì    |\n|       `NoCloud/`                             | dataDirectory               | nosync-libreria       | r/w  |      Sì      |     No      |        No        |   Sì    |\n|       `Cloud/`                               | syncedDataDirectory         | -                     | r/w  |      Sì      |     No      |        Sì        |   Sì    |\n|       `Caches/`                              | cacheDirectory              | cache                 | r/w  |     Sì *     | Sì * * *|  |        No        |   Sì    |\n|    `tmp/`                                    | tempDirectory               | -                     | r/w  |    No * *    | Sì * * *|  |        No        |   Sì    |\n\n* File persistono attraverso riavvii app e aggiornamenti, ma questa directory può essere azzerata ogni volta che desideri l'OS. L'app dovrebbe essere in grado di ricreare qualsiasi contenuto che potrebbe essere eliminato.\n\n* * File può persistere attraverso app riavvii, ma non fare affidamento su questo comportamento. I file non sono garantiti a persistere attraverso gli aggiornamenti. L'app deve rimuovere i file dalla directory quando è applicabile, come il sistema operativo non garantisce quando (o anche se) questi file vengono rimossi.\n\n* * *| Il sistema operativo può cancellare il contenuto di questa directory ogni volta che si sente è necessario, ma non fare affidamento su questo. Si dovrebbe cancellare questa directory come adatto per l'applicazione.\n\n### Layout sistema Android File\n\n| Percorso dispositivo              | `Cordova.file.*`                    | `AndroidExtraFileSystems` | r/w? | persistente? | OS cancella | privato |\n|:--------------------------------- |:----------------------------------- |:------------------------- |:----:|:------------:|:-----------:|:-------:|\n| `File:///android_asset/`          | applicationDirectory                |                           |  r   |     N/A      |     N/A     |   Sì    |\n| `< app-id > /dati/dati / /` | applicationStorageDirectory         | -                         | r/w  |     N/A      |     N/A     |   Sì    |\n|    `cache`                        | cacheDirectory                      | cache                     | r/w  |      Sì      |    Sì *     |   Sì    |\n|    `files`                        | dataDirectory                       | file                      | r/w  |      Sì      |     No      |   Sì    |\n|       `Documents`                 |                                     | documenti                 | r/w  |      Sì      |     No      |   Sì    |\n| `< sdcard > /`              | externalRootDirectory               | sdcard                    | r/w  |      Sì      |     No      |   No    |\n|    `Android/data/<app-id>/` | externalApplicationStorageDirectory | -                         | r/w  |      Sì      |     No      |   No    |\n|       `cache`                     | externalCacheDirectry               | cache-esterno             | r/w  |      Sì      |   No * *    |   No    |\n|       `files`                     | externalDataDirectory               | file-esterno              | r/w  |      Sì      |     No      |   No    |\n\n* Il sistema operativo può cancellare periodicamente questa directory, ma non fare affidamento su questo comportamento. Cancellare il contenuto di questa directory come adatto per l'applicazione. Il contenuto di questa directory dovrebbe un utente eliminare manualmente la cache, vengono rimossi.\n\n* * Il sistema operativo non cancella questa directory automaticamente; Tu sei responsabile per la gestione dei contenuti da soli. Il contenuto della directory dovrebbe l'utente eliminare manualmente la cache, vengono rimossi.\n\n**Nota**: se la memorizzazione esterna non può essere montato, le proprietà `cordova.file.external*` sono `null`.\n\n### BlackBerry 10 File sistema Layout\n\n| Percorso dispositivo                                | `Cordova.file.*`            | r/w? | persistente? | OS cancella | privato |\n|:--------------------------------------------------- |:--------------------------- |:----:|:------------:|:-----------:|:-------:|\n| `File:///accounts/1000/AppData/ < id app > /` | applicationStorageDirectory |  r   |     N/A      |     N/A     |   Sì    |\n|    `app/native`                                     | applicationDirectory        |  r   |     N/A      |     N/A     |   Sì    |\n|    `data/webviews/webfs/temporary/local__0`         | cacheDirectory              | r/w  |      No      |     Sì      |   Sì    |\n|    `data/webviews/webfs/persistent/local__0`        | dataDirectory               | r/w  |      Sì      |     No      |   Sì    |\n| `File:///accounts/1000/Removable/sdcard`            | externalRemovableDirectory  | r/w  |      Sì      |     No      |   No    |\n| `File:///accounts/1000/Shared`                      | sharedDirectory             | r/w  |      Sì      |     No      |   No    |\n\n*Nota*: quando l'applicazione viene distribuita a lavorare perimetrale, tutti i percorsi sono relativi a /accounts/1000-enterprise.\n\n## Stranezze Android\n\n### Posizione di archiviazione persistente Android\n\nCi sono più percorsi validi per memorizzare i file persistenti su un dispositivo Android. Vedi [questa pagina][3] per un'ampia discussione delle varie possibilità.\n\n [3]: http://developer.android.com/guide/topics/data/data-storage.html\n\nVersioni precedenti del plugin avrebbe scelto il percorso dei file temporanei e permanenti su avvio, in base se il dispositivo ha sostenuto che la scheda SD (o partizione storage equivalente) è stato montato. Se è stata montata sulla scheda SD o una partizione di storage interno grande era disponibile (come sui dispositivi Nexus,) allora saranno memorizzati i file persistenti nella radice di quello spazio. Questo significava che tutte le apps di Cordova poteva vedere tutti i file disponibili sulla carta.\n\nSe la scheda SD non era disponibile, poi versioni precedenti vuoi memorizzare dati sotto `/data/data/<packageId>`, che isola i apps da altro, ma può ancora causa dati da condividere tra gli utenti.\n\nOra è possibile scegliere se memorizzare i file nel percorso di archiviazione di file interno o utilizzando la logica precedente, con una preferenza nel file `config. xml` dell'applicazione. Per fare questo, aggiungere una di queste due linee al `file config. xml`:\n\n    <preference name=\"AndroidPersistentFileLocation\" value=\"Internal\" />\n    \n    <preference name=\"AndroidPersistentFileLocation\" value=\"Compatibility\" />\n    \n\nSenza questa linea, il File del plugin utilizzerà la `Compatibility` come predefinito. Se è presente un tag di preferenza e non è uno di questi valori, l'applicazione non si avvia.\n\nSe l'applicazione è stato spedito in precedenza agli utenti, utilizzando un vecchio (pre-1.0) versione di questo plugin e ha i file memorizzati nel filesystem persistente, allora si dovrebbe impostare la preferenza di `Compatibility`. La posizione su \"Interno\" di commutazione significherebbe che gli utenti esistenti che aggiornare la loro applicazione potrebbero essere Impossibile accedere ai loro file precedentemente memorizzati, a seconda del loro dispositivo.\n\nSe l'applicazione è nuova, o ha mai precedentemente memorizzati i file nel filesystem persistente, è generalmente consigliato l'impostazione `Internal`.\n\n## iOS stranezze\n\n*   `cordova.file.applicationStorageDirectory`è di sola lettura; tentativo di memorizzare i file all'interno della directory radice avrà esito negativo. Utilizzare uno degli altri `cordova.file.*` proprietà definite per iOS (solo `applicationDirectory` e `applicationStorageDirectory` sono di sola lettura).\n*   `FileReader.readAsText(blob, encoding)` \n    *   Il `encoding` parametro non è supportato, e codifica UTF-8 è sempre attivo.\n\n### posizione di archiviazione persistente di iOS\n\nCi sono due percorsi validi per memorizzare i file persistenti su un dispositivo iOS: la directory documenti e la biblioteca. Precedenti versioni del plugin archiviati solo mai persistenti file nella directory documenti. Questo ha avuto l'effetto collaterale di tutti i file di un'applicazione che rende visibili in iTunes, che era spesso involontaria, soprattutto per le applicazioni che gestiscono un sacco di piccoli file, piuttosto che produrre documenti completi per l'esportazione, che è la destinazione della directory.\n\nOra è possibile scegliere se memorizzare i file nella directory di libreria, con una preferenza nel file `config. xml` dell'applicazione o documenti. Per fare questo, aggiungere una di queste due linee al `file config. xml`:\n\n    <preference name=\"iosPersistentFileLocation\" value=\"Library\" />\n    \n    <preference name=\"iosPersistentFileLocation\" value=\"Compatibility\" />\n    \n\nSenza questa linea, il File del plugin utilizzerà la `Compatibility` come predefinito. Se è presente un tag di preferenza e non è uno di questi valori, l'applicazione non si avvia.\n\nSe l'applicazione è stato spedito in precedenza agli utenti, utilizzando un vecchio (pre-1.0) versione di questo plugin e ha i file memorizzati nel filesystem persistente, allora si dovrebbe impostare la preferenza di `Compatibility`. La posizione di commutazione alla `libreria` significherebbe che gli utenti esistenti che aggiornare la loro applicazione è in grado di accedere ai loro file precedentemente memorizzati.\n\nSe l'applicazione è nuova, o ha mai precedentemente memorizzati i file nel filesystem persistente, è generalmente consigliato l'impostazione della `Library`.\n\n## Firefox OS stranezze\n\nL'API di sistema del File non è supportato nativamente dal sistema operativo Firefox e viene implementato come uno spessore in cima indexedDB.\n\n*   Non manca quando si rimuove le directory non vuota\n*   Non supporta i metadati per le directory\n*   Metodi `copyTo` e `moveTo` non supporta le directory\n\nSono supportati i seguenti percorsi di dati: * `applicationDirectory` - utilizza `xhr` per ottenere i file locali che sono confezionati con l'app. *`dataDirectory` - per i file di dati persistenti app specifiche. *`cacheDirectory` - file memorizzati nella cache che dovrebbe sopravvivere si riavvia app (applicazioni non devono basarsi sull'OS di eliminare i file qui).\n\n## Stranezze browser\n\n### Stranezze e osservazioni comuni\n\n*   Ogni browser utilizza il proprio filesystem in modalità sandbox. IE e Firefox utilizzare IndexedDB come base. Tutti i browser utilizzano barra come separatore di directory in un percorso.\n*   Le voci di directory devono essere creato successivamente. Ad esempio, la chiamata `fs.root.getDirectory (' dir1/dir2 ', {create:true}, successCallback, errorCallback)` non riuscirà se non esistesse dir1.\n*   Il plugin richiede autorizzazione utente per utilizzare un archivio permanente presso il primo avvio dell'applicazione. \n*   Plugin supporta `cdvfile://localhost` (risorse locali) solo. Cioè risorse esterne non sono supportate tramite `cdvfile`.\n*   Il plugin non segue [\"Limitazioni di denominazione 8.3 File sistema API\"][4].\n*   BLOB e File' `close` la funzione non è supportata.\n*   `FileSaver` e `BlobBuilder` non sono supportati da questo plugin e non hanno gli stub.\n*   Il plugin non supporta `requestAllFileSystems`. Questa funzione manca anche nelle specifiche.\n*   Entrate nella directory non verranno rimossi se si utilizza `create: true` bandiera per directory esistente.\n*   Non sono supportati i file creati tramite il costruttore. È invece necessario utilizzare il metodo entry.file.\n*   Ogni browser utilizza la propria forma per riferimenti URL blob.\n*   `readAsDataURL` funzione è supportata, ma il mediatype in Chrome dipende dall'estensione di voce, mediatype in IE è sempre vuota (che è lo stesso come `text-plain` secondo la specifica), il mediatype in Firefox è sempre `application/octet-stream`. Ad esempio, se il contenuto è `abcdefg` quindi Firefox restituisce `dati: applicazione / octet-stream; base64, YWJjZGVmZw = =`, cioè restituisce `dati:; base64, YWJjZGVmZw = =`, Chrome restituisce `dati: < mediatype a seconda dell'estensione del nome della voce >; base64, YWJjZGVmZw = =`.\n*   `toInternalURL` restituisce il percorso in forma `file:///persistent/path/to/entry` (Firefox, IE). Chrome restituisce il percorso nella forma `cdvfile://localhost/persistent/file`.\n\n [4]: http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions\n\n### Stranezze di cromo\n\n*   Cromo filesystem non è subito pronto dopo evento ready dispositivo. Come soluzione alternativa, è possibile iscriversi all'evento `filePluginIsReady`. Esempio: \n\n    javascript\n    window.addEventListener('filePluginIsReady', function(){ console.log('File plugin is ready');}, false);\n    \n\nÈ possibile utilizzare la funzione `window.isFilePluginReadyRaised` per verificare se evento già è stato generato. -quote di filesystem TEMPORARY e PERSISTENT window.requestFileSystem non sono limitate in Chrome. -Per aumentare la memoria persistente in Chrome è necessario chiamare il metodo `window.initPersistentFileSystem`. Quota di archiviazione persistente è di 5 MB per impostazione predefinita. -Chrome richiede `-consentire-file-accesso-da-file` eseguire argomento a supporto API tramite protocollo `file:///`. -`File` oggetto non cambierà se si utilizza il flag `{create:true}` quando ottenendo un' esistente `entrata`. -eventi `cancelable` è impostata su true in Chrome. Ciò è in contrasto con la [specifica][5]. -funzione `toURL` Chrome restituisce `filesystem:`-premessi percorso a seconda dell'applicazione host. Ad esempio, `filesystem:file:///persistent/somefile.txt`, `filesystem:http://localhost:8080/persistent/somefile.txt`. -`toURL` risultato di funzione non contiene una barra finale in caso di voce di directory. Chrome risolve le directory con gli URL slash-trainati però correttamente. -`resolveLocalFileSystemURL` metodo richiede in ingresso `url` avere il prefisso del `file System`. Ad esempio, il parametro `url` per `resolveLocalFileSystemURL` dovrebbe essere nella forma `filesystem:file:///persistent/somefile.txt` in contrasto con la forma `file:///persistent/somefile.txt` in Android. -Obsoleto `toNativeURL` funzione non è supportata e non dispone di uno stub. -funzione `setMetadata` non è indicato nelle specifiche e non supportato. -INVALID_MODIFICATION_ERR (codice: 9) viene generata invece di SYNTAX_ERR(code: 8) su richiesta di un filesystem inesistente. -INVALID_MODIFICATION_ERR (codice: 9) viene generata invece di PATH_EXISTS_ERR(code: 12) sul tentativo di creare esclusivamente un file o una directory, che esiste già. -INVALID_MODIFICATION_ERR (codice: 9) viene generata invece di NO_MODIFICATION_ALLOWED_ERR(code: 6) sul tentativo di chiamare removeRecursively su file system root. -INVALID_MODIFICATION_ERR (codice: 9) viene generata invece di NOT_FOUND_ERR(code: 1) sul tentativo moveTo directory che non esiste.\n\n [5]: http://dev.w3.org/2009/dap/file-system/file-writer.html\n\n### Stranezze impl IndexedDB-basato (Firefox e IE)\n\n*   `.` e `.` non sono supportati.\n*   IE non supporta `file:///`-modalità; modalità solo ospitata è supportato (http://localhost:xxxx).\n*   Dimensione filesystem Firefox non è limitata, ma ogni estensione 50MB sarà richiesta un'autorizzazione dell'utente. IE10 consente fino a 10mb di combinato AppCache e IndexedDB utilizzato nell'implementazione del filesystem senza chiedere conferma, una volta premuto quel livello che vi verrà chiesto se si desidera consentire ad essere aumentata fino a un max di 250 mb per ogni sito. Quindi la `size` parametro per la funzione `requestFileSystem` non influisce il filesystem in Firefox e IE.\n*   `readAsBinaryString` funzione non è indicato nelle specifiche e non supportati in IE e non dispone di uno stub.\n*   `file.Type` è sempre null.\n*   Non è necessario creare la voce utilizzando il risultato del callback istanza DirectoryEntry che è stato eliminato. In caso contrario, si otterrà una 'voce di sospensione'.\n*   Prima è possibile leggere un file che è stato appena scritto è necessario ottenere una nuova istanza di questo file.\n*   supporta la funzione `setMetadata`, che non è indicato nelle specifiche `modificationTime` cambiamento di campo solo. \n*   funzioni `copyTo` e `moveTo` non supporta le directory.\n*   Le directory metadati non sono supportato.\n*   Sia Entry.remove e directoryEntry.removeRecursively non fallire quando si rimuove le directory non vuota - directory da rimuovere vengono pulite invece insieme al contenuto.\n*   `abort` e `truncate` le funzioni non sono supportate.\n*   non vengono generati eventi di progresso. Ad esempio, questo gestore verrà non eseguito:\n\n    javascript\n    writer.onprogress = function() { /*commands*/ };\n    \n\n## Note di aggiornamento\n\nIn v 1.0.0 di questo plugin, le strutture `FileEntry` e `DirectoryEntry` sono cambiati, per essere più in linea con le specifiche pubblicate.\n\nVersioni precedenti (pre-1.0.0) del plugin archiviati il dispositivo-assoluto--percorso del file nella proprietà `fullPath` di oggetti della `voce`. In genere questi percorsi si sarebbe simile\n\n    /var/mobile/Applications/<application UUID>/Documents/path/to/file  (iOS)\n    /storage/emulated/0/path/to/file                                    (Android)\n    \n\nQuesti percorsi sono stati anche restituiti dal metodo `toURL()` degli oggetti `Entry`.\n\nCon v 1.0.0, l'attributo `fullPath` è il percorso del file, *rispetto alla radice del filesystem HTML*. Così, i percorsi sopra sarebbe ora sia rappresentato da un oggetto `FileEntry` con un `fullPath` di\n\n    /path/to/file\n    \n\nSe l'applicazione funziona con dispositivo-assoluto-percorsi, e precedentemente recuperato quei percorsi attraverso la proprietà `fullPath` della `voce` oggetti, è necessario aggiornare il codice per utilizzare `entry.toURL()` invece.\n\nPer indietro la compatibilità, il metodo `resolveLocalFileSystemURL()` verrà accettare un dispositivo-assoluto-percorso e restituirà un oggetto di `entrata` corrispondente ad essa, fintanto che il file esiste all'interno del filesystem la `temporanea` o `permanente`.\n\nQuesto particolare è stato un problema con il plugin di trasferimento File, che in precedenza utilizzati percorsi-dispositivo-assoluto (e ancora può accoglierli). Esso è stato aggiornato per funzionare correttamente con gli URL di FileSystem, così sostituendo `entry.fullPath` con `entry.toURL()` dovrebbe risolvere eventuali problemi ottenendo quel plugin per lavorare con i file nel dispositivo.\n\nIn v 1.1.0 il valore restituito di `toURL()` è stato cambiato (vedere \\[CB-6394\\] (https://issues.apache.org/jira/browse/CB-6394)) per restituire un URL assoluto 'file://'. ove possibile. Per assicurare un ' cdvfile:'-URL, è possibile utilizzare `toInternalURL()` ora. Questo metodo restituirà ora filesystem URL del modulo\n\n    cdvfile://localhost/persistent/path/to/file\n    \n\nche può essere utilizzato per identificare univocamente il file.\n\n## Elenco dei codici di errore e significati\n\nQuando viene generato un errore, uno dei seguenti codici da utilizzare.\n\n| Codice | Costante                      |\n| ------:|:----------------------------- |\n|      1 | `NOT_FOUND_ERR`               |\n|      2 | `SECURITY_ERR`                |\n|      3 | `ABORT_ERR`                   |\n|      4 | `NOT_READABLE_ERR`            |\n|      5 | `ENCODING_ERR`                |\n|      6 | `NO_MODIFICATION_ALLOWED_ERR` |\n|      7 | `INVALID_STATE_ERR`           |\n|      8 | `SYNTAX_ERR`                  |\n|      9 | `INVALID_MODIFICATION_ERR`    |\n|     10 | `QUOTA_EXCEEDED_ERR`          |\n|     11 | `TYPE_MISMATCH_ERR`           |\n|     12 | `PATH_EXISTS_ERR`             |\n\n## Configurare il Plugin (opzionale)\n\nIl set di filesystem disponibili può essere configurato per ogni piattaforma. Sia iOS che Android riconoscere un <preference> Tag nel `file config. xml` che nomina il filesystem per essere installato. Per impostazione predefinita, tutte le radici del file system sono abilitate.\n\n    <preference name=\"iosExtraFilesystems\" value=\"library,library-nosync,documents,documents-nosync,cache,bundle,root\" />\n    <preference name=\"AndroidExtraFilesystems\" value=\"files,files-external,documents,sdcard,cache,cache-external,root\" />\n    \n\n### Android\n\n*   `files`: directory di archiviazione di file interno dell'applicazione\n*   `files-external`: directory di archiviazione dell'applicazione file esterno\n*   `sdcard`: la directory di archiviazione di file esterni globale (questa è la radice della scheda SD, se uno è installato). È necessario disporre dell'autorizzazione `android.permission.WRITE_EXTERNAL_STORAGE` utilizzare questo.\n*   `cache`: la cache interna directory applicazione\n*   `cache-external`: directory di cache esterna dell'applicazione\n*   `root`: il dispositivo intero filesystem\n\nAndroid supporta anche un filesystem speciale denominato \"documenti\", che rappresenta una sottodirectory \"/ documenti /\" all'interno del filesystem \"files\".\n\n### iOS\n\n*   `library`: la directory dell'applicazione libreria\n*   `documents`: la directory dell'applicazione documenti\n*   `cache`: la Cache directory applicazione\n*   `bundle`: bundle dell'applicazione; la posizione dell'app sul disco (sola lettura)\n*   `root`: il dispositivo intero filesystem\n\nPer impostazione predefinita, la directory di libreria e documenti può essere sincronizzata a iCloud. È anche possibile richiedere due filesystem aggiuntivi, `library-nosync` e `documents-nosync`, che rappresentano una speciale directory non sincronizzati entro il `/Library` o filesystem `/Documents`.\n"
  },
  {
    "path": "plugins/cordova-plugin-file/doc/it/plugins.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# Note per gli sviluppatori di plugin\n\nQueste note sono destinate principalmente per gli sviluppatori di Android e iOS che vogliono scrivere plugin quale interfaccia con il sistema di file utilizzando il File plugin.\n\n## Lavorando con URL di sistema file di Cordova\n\nDalla versione 1.0.0, questo plugin ha utilizzato gli URL con un `cdvfile` schema per tutte le comunicazioni oltre il ponte, piuttosto che esporre i percorsi del file system di dispositivo raw a JavaScript.\n\nSul lato JavaScript, questo significa che gli oggetti FileEntry e DirectoryEntry dispongano di un attributo fullPath che è relativo alla directory principale del sistema di file HTML. Se API JavaScript del vostro plugin accetta un oggetto FileEntry o DirectoryEntry, è necessario chiamare `.toURL()` su quell'oggetto prima di passarlo attraverso il ponte in codice nativo.\n\n### Conversione cdvfile: / / URL ai percorsi fileystem\n\nPlugin che hanno bisogno di scrivere il filesystem può essere necessario convertire un URL di sistema del file ricevuto in un percorso effettivo filesystem. Ci sono diversi modi di fare questo, a seconda della piattaforma nativa.\n\nÈ importante ricordare che non tutti i `cdvfile://` URL sono mappabili ai veri file sul dispositivo. Alcuni URL può riferirsi a beni sul dispositivo che non sono rappresentate da file, o possono anche fare riferimento a risorse remote. A causa di queste possibilità, plugin dovrebbe sempre verificare se ottengono un risultato significativo indietro quando si tenta di convertire gli URL in percorsi.\n\n#### Android\n\nSu Android, il metodo più semplice per convertire un `cdvfile://` URL a un percorso di file System è quello di utilizzare `org.apache.cordova.CordovaResourceApi` . `CordovaResourceApi`dispone di diversi metodi che è possono gestire `cdvfile://` URL:\n\n    webView è un membro del Plugin classe CordovaResourceApi resourceApi = webView.getResourceApi();\n    \n    Ottenere un URL file:/// che rappresenta questo file sul dispositivo, / / o lo stesso URL invariata se non può essere mappato a un file Uri fileURL = resourceApi.remapUri(Uri.parse(cdvfileURL));\n    \n\nÈ anche possibile utilizzare direttamente il File plugin:\n\n    importazione org.apache.cordova.file.FileUtils;\n    importazione org.apache.cordova.file.FileSystem;\n    importazione java.net.MalformedURLException;\n    \n    Ottenere il File plugin dal gestore plugin FileUtils filePlugin = (FileUtils)webView.pluginManager.getPlugin(\"File\");\n    \n    Dato un URL, ottenere un percorso per esso prova {String path = filePlugin.filesystemPathForURL(cdvfileURL);}} catch (MalformedURLException e) {/ / l'url del file System non è stato riconosciuto}\n    \n\nConvertire da un percorso a un `cdvfile://` URL:\n\n    importazione org.apache.cordova.file.LocalFilesystemURL;\n    \n    Ottenere un oggetto LocalFilesystemURL per un percorso di dispositivo, / / oppure null se non può essere rappresentata come un URL di cdvfile.\n    LocalFilesystemURL url = filePlugin.filesystemURLforLocalPath(path);\n    Ottenere la rappresentazione di stringa dell'URL oggetto String cdvfileURL = url.toString();\n    \n\nSe il vostro plugin crea un file e si desidera restituire un oggetto FileEntry per esso, utilizzare il File plugin:\n\n    Restituire una struttura JSON appropriato per restituire a JavaScript, / / o null se questo file non è rappresentabile come un URL di cdvfile.\n    Voce di JSONObject = filePlugin.getEntryForFile(file);\n    \n\n#### iOS\n\nCordova su iOS non utilizza lo stesso `CordovaResourceApi` concetto come Android. Su iOS, si dovrebbe utilizzare il plugin File per convertire tra URL e percorsi di file System.\n\n    Ottenere un oggetto CDVFilesystem URL da una stringa CDVFilesystemURL * url = [CDVFilesystemURL fileSystemURLWithString:cdvfileURL];\n    Ottenere un percorso per l'oggetto URL, o zero se non può essere mappato a un percorso di file NSString * = [filePlugin filesystemPathForURL:url];\n    \n    \n    Ottenere un oggetto CDVFilesystem URL per un percorso di dispositivo, o / / nullo se non può essere rappresentata come un URL di cdvfile.\n    CDVFilesystemURL * url = [filePlugin fileSystemURLforLocalPath:path];\n    Ottenere la rappresentazione di stringa dell'URL oggetto NSString * cdvfileURL = [absoluteString url];\n    \n\nSe il vostro plugin crea un file e si desidera restituire un oggetto FileEntry per esso, utilizzare il File plugin:\n\n    Ottenere un oggetto CDVFilesystem URL per un percorso di dispositivo, o / / nullo se non può essere rappresentata come un URL di cdvfile.\n    CDVFilesystemURL * url = [filePlugin fileSystemURLforLocalPath:path];\n    Ottenere una struttura per tornare alla voce JavaScript NSDictionary * = [filePlugin makeEntryForLocalURL:url]\n    \n\n#### JavaScript\n\nIn JavaScript, per ottenere un `cdvfile://` URL da un oggetto FileEntry o DirectoryEntry, semplicemente chiamare `.toURL()` su di esso:\n\n    var cdvfileURL = entry.toURL();\n    \n\nNei gestori di risposta del plugin, per convertire da una struttura FileEntry restituita in un oggetto reale di voce, il codice del gestore dovrebbe importare il File plugin e creare un nuovo oggetto:\n\n    creare la voce appropriata a voce oggetto var;\n    Se (entryStruct.isDirectory) {voce = new DirectoryEntry (entryStruct.name, entryStruct.fullPath, nuovo FileSystem(entryStruct.filesystemName));} altro {voce = FileEntry nuovo (entryStruct.name, entryStruct.fullPath, nuovo FileSystem(entryStruct.filesystemName));}"
  },
  {
    "path": "plugins/cordova-plugin-file/doc/ja/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-file\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-file.svg)](https://travis-ci.org/apache/cordova-plugin-file)\n\nこのプラグインは、デバイス上のファイルへの読み取り/書き込みアクセスを許可するファイル API を実装します。\n\nこのプラグインを含む、いくつかの仕様に基づいています：、HTML5 File API の<http://www.w3.org/TR/FileAPI/>\n\n（今は亡き) ディレクトリとシステムは、最新の拡張機能: <http://www.w3.org/TR/2012/WD-file-system-api-20120417/>プラグインのコードのほとんどはときに、以前の仕様に書かれていたが現在は： <http://www.w3.org/TR/2011/WD-file-system-api-20110419/>\n\nFileWriter 仕様も実装しています: <http://dev.w3.org/2009/dap/file-system/file-writer.html>\n\n使用法を参照してください HTML5 岩 ' 優秀な[ファイルシステム記事](http://www.html5rocks.com/en/tutorials/file/filesystem/)。\n\n他のストレージ オプションの概要については、コルドバの[ストレージ ・ ガイド](http://cordova.apache.org/docs/en/edge/cordova_storage_storage.md.html)を参照してください。.\n\nこのプラグインでは、グローバル `cordova.file` オブジェクトを定義します。\n\nグローバル スコープではあるがそれがないまで `deviceready` イベントの後です。\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(cordova.file);\n    }\n    \n\n## インストール\n\n    cordova plugin add cordova-plugin-file\n    \n\n## サポートされているプラットフォーム\n\n  * アマゾン火 OS\n  * アンドロイド\n  * ブラックベリー 10\n  * Firefox の OS\n  * iOS\n  * Windows Phone 7 と 8 *\n  * Windows 8 *\n  * Windows*\n  * ブラウザー\n\n\\* *These platforms do not support `FileReader.readAsArrayBuffer` nor `FileWriter.write(blob)`.*\n\n## ファイルを保存する場所\n\nV1.2.0、現在重要なファイル システム ディレクトリへの Url を提供しています。 各 URL はフォーム *file:///path/to/spot/* で、`window.resolveLocalFileSystemURL()` を使用する `DirectoryEntry` に変換することができます。.\n\n  * `cordova.file.applicationDirectory`-読み取り専用のディレクトリは、アプリケーションがインストールされています。（*iOS*、*アンドロイド*、*ブラックベリー 10*)\n\n  * `cordova.file.applicationStorageDirectory`-アプリケーションのサンド ボックス; のルート ディレクトリiOS でこの場所が読み取り専用 （特定のサブディレクトリが [のような `/Documents` ] は、読み取り/書き込み)。 内に含まれるすべてのデータは、アプリケーションにプライベートです。 （ *iOS*、*アンドロイド*、*ブラックベリー 10*)\n\n  * `cordova.file.dataDirectory`内部メモリを使用して、アプリケーションのサンド ボックス内で永続なプライベート データ ストレージ （外部メモリを使用する必要がある場合使用して Android 上で `.externalDataDirectory` )。 IOS は、このディレクトリは iCloud と同期されません (使用する `.syncedDataDirectory` )。 （*iOS*、*アンドロイド*、*ブラックベリー 10*)\n\n  * `cordova.file.cacheDirectory`-キャッシュされたデータ ファイルやアプリに簡単に再作成できる任意のファイルのディレクトリ。 ストレージ デバイスが不足したときに、OS がこれらのファイルを削除可能性があります、それにもかかわらず、アプリはここにファイルを削除する OS に依存しないでください。 （*iOS*、*アンドロイド*、*ブラックベリー 10*)\n\n  * `cordova.file.externalApplicationStorageDirectory`外部ストレージのアプリケーション領域。（*アンドロイド*)\n\n  * `cordova.file.externalDataDirectory`-外部ストレージ上のアプリ固有のデータ ファイルを配置する場所。（*アンドロイド*)\n\n  * `cordova.file.externalCacheDirectory`外部ストレージにアプリケーション キャッシュ。（*アンドロイド*)\n\n  * `cordova.file.externalRootDirectory`-外部ストレージ (SD カード) ルート。（*アンドロイド*、*ブラックベリー 10*)\n\n  * `cordova.file.tempDirectory`-OS をクリアすることができます temp ディレクトリが。 このディレクトリ; オフに OS に依存しません。アプリが常に該当するファイルを削除します。 (*iOS*)\n\n  * `cordova.file.syncedDataDirectory`-（例えば iCloud) に同期する必要がありますアプリケーション固有のファイルを保持します。(*iOS*)\n\n  * `cordova.file.documentsDirectory`-ファイル、アプリケーションにプライベートは他のアプリケーション (Office ファイルなど） を意味です。(*iOS*)\n\n  * `cordova.file.sharedDirectory`すべてのアプリケーション (*ブラックベリー 10*にグローバルに使用できるファイル)\n\n## ファイル ・ システム ・ レイアウト\n\n技術的に実装の詳細、非常にどのように `cordova.file.*` プロパティは、実際のデバイス上の物理パスにマップを知っておくと便利することができます。\n\n### iOS ファイル システムのレイアウト\n\n| デバイス ・ パス                                      | `cordova.file.*`            | `iosExtraFileSystems` | r/w ですか？ | 永続的なですか？  |  OS を消去します   |   同期   | プライベート |\n|:---------------------------------------------- |:--------------------------- |:--------------------- |:--------:|:---------:|:------------:|:------:|:------:|\n| `/var/モバイル/アプリケーション/< UUID >/`           | applicationStorageDirectory | -                     |    r     |    N/A    |     N/A      |  N/A   |   はい   |\n| &nbsp;&nbsp;&nbsp;`appname.app/`               | ディレクトリ                      | バンドル                  |    r     |    N/A    |     N/A      |  N/A   |   はい   |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`www/`     | -                           | -                     |    r     |    N/A    |     N/A      |  N/A   |   はい   |\n| &nbsp;&nbsp;&nbsp;`Documents/`                 | documentsDirectory          | ドキュメント                |   r/w    |    はい     |     いいえ      |   はい   |   はい   |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`NoCloud/` | -                           | ドキュメント nosync         |   r/w    |    はい     |     いいえ      |  いいえ   |   はい   |\n| &nbsp;&nbsp;&nbsp;`Library`                    | -                           | ライブラリ                 |   r/w    |    はい     |     いいえ      | はいですか？ |   はい   |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`NoCloud/` | dataDirectory               | ライブラリ nosync          |   r/w    |    はい     |     いいえ      |  いいえ   |   はい   |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`Cloud/`   | syncedDataDirectory         | -                     |   r/w    |    はい     |     いいえ      |   はい   |   はい   |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`Caches/`  | cacheDirectory              | キャッシュ                 |   r/w    |   はい *    | はい**\\* |  いいえ   |   はい   |\n| &nbsp;&nbsp;&nbsp;`tmp/`                       | tempDirectory               | -                     |   r/w    | いいえ** | はい**\\* |  いいえ   |   はい   |\n\n\\ * アプリ再起動やアップグレード、永続化ファイルしますが、OS を希望するたびに、このディレクトリを削除することができます。アプリは削除可能性があります任意のコンテンツを再現することができるはず。\n\n**ファイルはアプリ再起動の間続くことがありますが、この動作に依存しないでください。 ファイルは、更新を維持するは保証されません。 アプリが該当する場合このディレクトリからファイルを削除する必要があります、これらのファイルが削除されるとき (または場合でも)、OS は保証しません。\n\n**\\ * OS はそれ、必要だと感じているときにこのディレクトリの内容を消去可能性があります、これに依存しないようにします。 この適切なディレクトリに、アプリケーションをオフにする必要があります。\n\n### 人造人間ファイル ・ システム ・ レイアウト\n\n| デバイス ・ パス                                        | `cordova.file.*`                    | `AndroidExtraFileSystems` | r/w ですか？ | 永続的なですか？ | OS を消去します | プライベート |\n|:------------------------------------------------ |:----------------------------------- |:------------------------- |:--------:|:--------:|:---------:|:------:|\n| `file:///android_asset/`                         | ディレクトリ                              |                           |    r     |   N/A    |    N/A    |   はい   |\n| `/データ/データ/< app id >/`                     | applicationStorageDirectory         | -                         |   r/w    |   N/A    |    N/A    |   はい   |\n| &nbsp;&nbsp;&nbsp;`cache`                        | cacheDirectory                      | キャッシュ                     |   r/w    |    はい    |  はい\\ *   |   はい   |\n| &nbsp;&nbsp;&nbsp;`files`                        | dataDirectory                       | ファイル                      |   r/w    |    はい    |    いいえ    |   はい   |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`Documents`  |                                     | ドキュメント                    |   r/w    |    はい    |    いいえ    |   はい   |\n| `< sd カード >/`                              | externalRootDirectory               | sd カード                    |   r/w    |    はい    |    いいえ    |  いいえ   |\n| &nbsp;&nbsp;&nbsp;`Android/data/<app-id>/` | externalApplicationStorageDirectory | -                         |   r/w    |    はい    |    いいえ    |  いいえ   |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`cache`      | externalCacheDirectry               | 外部キャッシュ                   |   r/w    |    はい    | いいえ** |  いいえ   |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`files`      | externalDataDirectory               | 外部ファイル                    |   r/w    |    はい    |    いいえ    |  いいえ   |\n\n\\ * OS は定期的にこのディレクトリを消去可能性がありますが、この動作に依存しないでください。 アプリケーションの必要に応じてこのディレクトリの内容をオフにします。 ユーザーは手動でキャッシュを削除する必要があります、このディレクトリの内容が削除されます。\n\n** OS はこのディレクトリを自動的にはクリアされません内容を自分で管理する責任があります。 ユーザは手動でキャッシュを消去する必要があります、ディレクトリの内容が削除されます。\n\n**注**: 外部記憶装置をマウントできない場合は、`cordova.file.external*` プロパティを `null`.\n\n### ブラックベリー 10 ファイル ・ システム ・ レイアウト\n\n| デバイス ・ パス                                                   | `cordova.file.*`            | r/w ですか？ | 永続的なですか？ | OS を消去します | プライベート |\n|:----------------------------------------------------------- |:--------------------------- |:--------:|:--------:|:---------:|:------:|\n| `file:///accounts/1000/appdata/< app id >/`           | applicationStorageDirectory |    r     |   N/A    |    N/A    |   はい   |\n| &nbsp;&nbsp;&nbsp;`app/native`                              | ディレクトリ                      |    r     |   N/A    |    N/A    |   はい   |\n| &nbsp;&nbsp;&nbsp;`data/webviews/webfs/temporary/local__0`  | cacheDirectory              |   r/w    |   いいえ    |    はい     |   はい   |\n| &nbsp;&nbsp;&nbsp;`data/webviews/webfs/persistent/local__0` | dataDirectory               |   r/w    |    はい    |    いいえ    |   はい   |\n| `file:///accounts/1000/removable/sdcard`                    | externalRemovableDirectory  |   r/w    |    はい    |    いいえ    |  いいえ   |\n| `file:///accounts/1000/shared`                              | sharedDirectory             |   r/w    |    はい    |    いいえ    |  いいえ   |\n\n*注*: すべてのパスは/accounts/1000-enterprise 基準に境界を動作するようにアプリケーションを展開するとき。\n\n## Android の癖\n\n### Android の永続的なストレージの場所\n\nAndroid のデバイスに永続的なファイルを格納する複数の有効な場所があります。 さまざまな可能性について広範な議論のための [このページ](http://developer.android.com/guide/topics/data/data-storage.html) を参照してください。\n\n以前のバージョンのプラグインは、デバイスの SD カード （または同等のストレージ パーティション） マウントされていたと主張したかどうかに基づいて、起動時に一時と永続的なファイルの場所を選ぶでしょう。 SD カードがマウントされている場合、または大規模な内部ストレージ パーティションが利用可能な場合 (ようネクサス デバイス上） し、永続的なファイルは、その領域のルートに格納されます。 これはすべての Cordova アプリ見ることができる利用可能なファイルのすべてのカードに意味しました。\n\nSD カードがない場合、以前のバージョンがデータを格納する `/data/data/<packageId>`、お互いからアプリを分離するが、まだ原因可能性がありますユーザー間で共有するデータ。\n\n内部ファイルの保存場所やアプリケーションの `config.xml` ファイルに優先順位を持つ以前のロジックを使用してファイルを保存するかどうかを選択することが可能です今。 これを行うに、`config.xml` に次の 2 行のいずれかを追加します。\n\n    <preference name=\"AndroidPersistentFileLocation\" value=\"Internal\" />\n    \n    <preference name=\"AndroidPersistentFileLocation\" value=\"Compatibility\" />\n    \n\nこの行がなければファイル プラグインはデフォルトとして `Compatibility` を使用します。優先タグが存在し、これらの値の 1 つではない場合、アプリケーションは起動しません。\n\nアプリケーションは、ユーザーに以前出荷されている場合、古い (前 1.0） を使用して、このプラグインのバージョンし、永続的なファイルシステムに保存されているファイルには `Compatibility` を設定する必要があります。 自分のアプリケーションをアップグレードする既存のユーザーを彼らの装置によって、以前に保存されたファイルにアクセスすることができることがあることを意味する「内部」に場所をスイッチングします。\n\nアプリケーションは、新しい、または永続的なファイルシステムにファイルが格納され以前は決して場合、`内部` 設定一般的に推奨されます。\n\n### /Android_asset の低速の再帰的な操作\n\nアセット ディレクトリの一覧表示は、人造人間本当に遅いです。 それをスピードアップすることができます`src/android/build-extras.gradle`を android プロジェクトのルートに追加することによって、最大 (また cordova-android@4.0.0 が必要ですまたはそれ以上)。\n\n## iOS の癖\n\n  * `cordova.file.applicationStorageDirectory`読み取り専用;ルート ディレクトリ内のファイルを保存しようは失敗します。 他の 1 つを使用して `cordova.file.*` iOS のため定義されているプロパティ (のみ `applicationDirectory` と `applicationStorageDirectory` は読み取り専用)。\n  * `FileReader.readAsText(blob, encoding)` \n      * `encoding`パラメーターはサポートされていませんし、utf-8 エンコーディングが常に有効です。\n\n### iOS の永続的なストレージの場所\n\nIOS デバイスに永続的なファイルを格納する 2 つの有効な場所がある: ドキュメントとライブラリのディレクトリ。 プラグインの以前のバージョンは、唯一のこれまでドキュメント ディレクトリに永続的なファイルを格納されます。 これは、ディレクトリの目的は、輸出のための完全なドキュメントを作成するのではなくなかったがしばしば意図されていたり、特に多数の小さいファイルを処理するアプリケーションの場合、iTunes に表示されているすべてのアプリケーションのファイルを作るの副作用があった。\n\nドキュメントまたはアプリケーションの `config.xml` ファイルに優先順位のライブラリ ディレクトリにファイルを保存するかどうかを選択することが可能です今。 これを行うに、`config.xml` に次の 2 行のいずれかを追加します。\n\n    <preference name=\"iosPersistentFileLocation\" value=\"Library\" />\n    \n    <preference name=\"iosPersistentFileLocation\" value=\"Compatibility\" />\n    \n\nこの行がなければファイル プラグインはデフォルトとして `Compatibility` を使用します。優先タグが存在し、これらの値の 1 つではない場合、アプリケーションは起動しません。\n\nアプリケーションは、ユーザーに以前出荷されている場合、古い (前 1.0） を使用して、このプラグインのバージョンし、永続的なファイルシステムに保存されているファイルには `Compatibility` を設定する必要があります。 自分のアプリケーションをアップグレードする既存のユーザーを以前に保存されたファイルにアクセスすることができるだろうことを意味する `Library` に場所をスイッチングします。\n\nアプリケーションは、新しい、または永続的なファイルシステムにファイルが格納され以前は決して場合、`Library` 設定一般的に推奨されます。\n\n## Firefox OS 癖\n\nファイル システム API Firefox OS でネイティブ サポートされていないと、indexedDB の上にシムとして実装されています。\n\n  * 空でないディレクトリを削除するときに失敗しません\n  * ディレクトリのメタデータをサポートしていません\n  * 方法 `copyTo` と `moveTo` ディレクトリをサポートしていません\n\n次のデータ パスがサポートされています: * `applicationDirectory` - `xhr` を使用して、アプリケーションと共にパッケージ化されるローカル ファイルを取得します。 * `dataDirectory` - 永続的なアプリケーション固有のデータ ファイル。 * `cacheDirectory` - アプリケーションの再起動後も維持する必要がありますキャッシュ ファイル (アプリはここにファイルを削除する OS に依存しないでください)。\n\n## ブラウザーの癖\n\n### 共通の癖と発言\n\n  * 各ブラウザーはサンド ボックス化されたファイルシステムを使用します。IE と Firefox IndexedDB をベースとして使用します。すべてのブラウザーは、パスにディレクトリの区切り記号としてスラッシュを使用します。\n  * ディレクトリ エントリは連続して作成されなければなりません。 たとえば、コール `fs.root.getDirectory ('dir1 dir2'、{create:true}、successCallback、解り)` dir1 が存在しなかった場合は失敗します。\n  * プラグインは、永続的なストレージ アプリケーションの最初の起動時に使用するユーザーのアクセス許可を要求します。 \n  * プラグインは、`cdvfile://localhost` (ローカル リソース) をサポートしているだけです。すなわち外部リソースは、`cdvfile` を介してサポートされていません.\n  * プラグインに [制限」のファイル システム API の 8.3 命名規則](http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions) に従っていません。.\n  * Blob およびファイル ' `close` 関数はサポートされていません。\n  * `FileSaver` と `BlobBuilder` このプラグインでサポートされていないスタブを持っていません。\n  * プラグインは、`requestAllFileSystems` をサポートしません。この関数は、仕様で行方不明にも。\n  * ディレクトリ内のエントリを使用すると削除されません `create: true` 既存ディレクトリのフラグ。\n  * コンス トラクターで作成されたファイルはサポートされていません。代わりに entry.file メソッドを使用する必要があります。\n  * 各ブラウザーは blob URL 参照の独自のフォームを使用します。\n  * `readAsDataURL` 関数はサポートされてがクロムメッキで mediatype エントリ名の拡張子によって異なります、IE でメディアの種類は、常に空 （`text-plain` に従って、仕様と同じである）、Firefox でメディアの種類は常に `アプリケーションまたはオクテット-ストリーム`。 たとえば、コンテンツが場合 `abcdefg` し Firefox を返します `データ: アプリケーション/オクテット ストリーム、base64、YWJjZGVmZw = =`、すなわちを返します `データ:; base64、YWJjZGVmZw = =`、クロムを返します `データ: < エントリ名の拡張子によって mediatype >; base64、YWJjZGVmZw = =`.\n  * `toInternalURL` フォーム `file:///persistent/path/to/entry` （Firefox、IE） のパスを返します。 クロムの `cdvfile://localhost/persistent/file` フォームのパスを返します.\n\n### クロムの癖\n\n  * デバイスの準備ができているイベント後クローム ファイルシステムはすぐに準備ができています。回避策としては `filePluginIsReady` イベントにサブスクライブできます。例: \n\n```javascript\nwindow.addEventListener('filePluginIsReady', function(){ console.log('File plugin is ready');}, false);\n```\n\n`window.isFilePluginReadyRaised` 関数を使用して、イベントが既に発生したかどうかを確認できます。 -Chrome に window.requestFileSystem 一時と永続的なファイル ・ システムのクォータの制限はありません。 -クロム内の永続ストレージを増加する `window.initPersistentFileSystem` メソッドを呼び出す必要があります。 永続的な記憶域のクォータは、既定では 5 MB です。 クロムが必要です `--許可-ファイル-アクセス--ファイルから` `file:///` プロトコル経由でサポート API に引数を実行します。 -`ファイル` オブジェクト フラグを使用する場合ない変更されます `{create:true}` 既存の `エントリ` を取得するとき。 -イベント `cancelable` プロパティを設定するクロムの場合は true。 これは [仕様](http://dev.w3.org/2009/dap/file-system/file-writer.html) に反して。 -クロムメッキで `網` 関数を返します `ファイルシステム：`-アプリケーションのホストによってパスのプレフィックスします。 たとえば、`filesystem:file:///persistent/somefile.txt`、`filesystem:http://localhost:8080/persistent/somefile.txt`。 -`toURL` の関数の結果にはディレクトリ エントリ場合末尾にスラッシュが含まれていません。 クロムは、スラッシュ後塵 url を持つディレクトリが正しく解決されるも。 -`resolveLocalFileSystemURL` メソッドは、受信 `url` が `ファイルシステム` のプレフィックスが必要です。 たとえば、`resolveLocalFileSystemURL` の `url` パラメーター フォーム `filesystem:file:///persistent/somefile.txt` で人造人間フォーム `file:///persistent/somefile.txt` とは対照的にする必要があります。 -廃止された `toNativeURL` 関数はサポートされていません、スタブはありません。 -`setMetadata` 関数は、仕様に記載されていないありサポートされていません。 -INVALID_MODIFICATION_ERR （コード: 9) の代わりにスローされた SYNTAX_ERR(code: 8) の非実在しないファイルシステムの依頼を。 -INVALID_MODIFICATION_ERR （コード: 9) の代わりにスローされた PATH_EXISTS_ERR(code: 12)、排他的なファイルまたはディレクトリを作成しようとするが既に存在します。 -INVALID_MODIFICATION_ERR （コード: 9) の代わりにスローされた NO_MODIFICATION_ALLOWED_ERR(code: 6) ルート ・ ファイル ・ システムで removeRecursively を呼び出すをしようとして。 -INVALID_MODIFICATION_ERR （コード: 9) の代わりにスローされた NOT_FOUND_ERR(code: 1) [moveto] ディレクトリが存在しないをしようとして。\n\n### IndexedDB ベース インプレ癖 （Firefox と IE）\n\n  * `.` `です。` はサポートされていません。\n  * IE は `file:///` をサポートしていません-モード;ホスト モードのみがサポートされている (http://localhost:xxxx) です。\n  * Firefox のファイルシステムのサイズは無制限ですが各 50 MB の拡張機能がユーザーのアクセス許可を要求します。 IE10 は最大 10 mb の複合 AppCache と IndexedDB を求めず、サイトごとに 250 mb の最大値まで増加を許可するかどうかをたずねられますそのレベルに当ればファイルシステムの実装で使用することができます。 `RequestFileSystem` 関数の `size` パラメーターは、Firefox と IE のファイルシステムには影響しません。\n  * `readAsBinaryString` 関数の仕様に記載されていない、IE でサポートされていないと、スタブを持っていません。\n  * `file.type` は、常に null です。\n  * 削除された DirectoryEntry インスタンスのコールバックの結果を使用してエントリを作成しないでください。それ以外の場合は、'ハンギングのエントリ' が表示されます。\n  * ちょうど書かれていた、ファイルを読むことができます前にこのファイルの新しいインスタンスを取得する必要があります。\n  * `setMetadata` 関数は、仕様に記載されていない `modificationTime` フィールド変更のみをサポートします。 \n  * `copyTo` と `moveTo` 関数ディレクトリをサポートしていません。\n  * ディレクトリのメタデータはサポートされていません。\n  * 両方の Entry.remove と directoryEntry.removeRecursively は空でないディレクトリを削除するときを失敗しない - 削除されるディレクトリ コンテンツと共にを掃除している代わりに。\n  * `abort` し、`truncate` 機能はサポートされていません。\n  * 進行状況イベントは起動しません。たとえば、このハンドラーがない実行されます。\n\n```javascript\nwriter.onprogress = function() { /*commands*/ };\n```\n\n## ノートをアップグレードします。\n\nこのプラグインのデベロッパー、公開された仕様に合うように、`認証` と `DirectoryEntry` の構造が変更されました。\n\nプラグインの前 (pre 1.0.0) バージョンはデバイス絶対ファイル場所 `エントリ` オブジェクトの `fullPath` プロパティに格納されます。これらのパスはようになります通常\n\n    /var/mobile/Applications/<application UUID>/Documents/path/to/file  (iOS)\n    /storage/emulated/0/path/to/file                                    (Android)\n    \n\nこれらのパスはまた `Entry` オブジェクトの `toURL()` メソッドによって返されます。\n\nデベロッパー、`fullPath` 属性は *HTML ファイルシステムのルートに対する相対パス* のファイルへのパス。 したがって、上記のパスは今両方の `fullPath` と `FileEntry` オブジェクトで表される\n\n    /path/to/file\n    \n\nデバイス絶対パスとアプリケーション動作以前 `Entry` オブジェクトの `fullPath` プロパティを使用してこれらのパスを取得した場合は、代わりに `entry.toURL()` を使用するコードを更新する必要があります。\n\n下位互換性、`resolveLocalFileSystemURL()` メソッドは、デバイス絶対パスを受け入れるし、は、`TEMPORARY` または `PERSISTENT` ファイル ・ システム内でそのファイルが存在する限り、それに対応する `Entry` オブジェクトを返します。\n\nこれは特に以前デバイス絶対パスを使用してファイル転送のプラグインで問題となっている （そしてまだそれらを受け入れることができます）。 それがデバイス上のファイルで動作するプラグインを得る問題を解決する必要があります `entry.toURL()` で `entry.fullPath` を置き換えるので、ファイルシステムの Url で正常に動作にアップデートされました。\n\nV1.1.0 の `toURL()` の戻り値に変更されました (\\[CB-6394\\] (https://issues.apache.org/jira/browse/CB-6394) を参照) を絶対 'file://' で始まる URL を返します。 可能な限り。 確保するために、' cdvfile:'-`toInternalURL()` を今すぐ使用できます URL。 このメソッドは、フォームのファイルシステムの Url を返します今\n\n    cdvfile://localhost/persistent/path/to/file\n    \n\nこれはファイルを一意に識別するために使用できます。\n\n## エラー コードと意味のリスト\n\nエラーがスローされると、次のコードのいずれかが使用されます。\n\n| コード | 定数                            |\n| ---:|:----------------------------- |\n|   1 | `NOT_FOUND_ERR`               |\n|   2 | `SECURITY_ERR`                |\n|   3 | `ABORT_ERR`                   |\n|   4 | `NOT_READABLE_ERR`            |\n|   5 | `ENCODING_ERR`                |\n|   6 | `NO_MODIFICATION_ALLOWED_ERR` |\n|   7 | `INVALID_STATE_ERR`           |\n|   8 | `SYNTAX_ERR`                  |\n|   9 | `INVALID_MODIFICATION_ERR`    |\n|  10 | `QUOTA_EXCEEDED_ERR`          |\n|  11 | `TYPE_MISMATCH_ERR`           |\n|  12 | `PATH_EXISTS_ERR`             |\n\n## (省略可能) プラグインを構成します。\n\n利用可能なファイルシステムのセットは構成されたプラットフォームをすることができます。IOS と Android の両方を認識します。 <preference> タグ `config.xml` をインストールするファイルシステムの名前します。既定では、すべてのファイル システムのルートが有効になります。\n\n    <preference name=\"iosExtraFilesystems\" value=\"library,library-nosync,documents,documents-nosync,cache,bundle,root\" />\n    <preference name=\"AndroidExtraFilesystems\" value=\"files,files-external,documents,sdcard,cache,cache-external,root\" />\n    \n\n### アンドロイド\n\n  * `files`： アプリケーションの内部ファイルのストレージ ディレクトリ\n  * `files-external`: アプリケーションの外部のファイルのストレージ ディレクトリ\n  * `sdcard`：、グローバル外部ストレージ ディレクトリをファイル (これは SD カードのルートがインストールされている場合)。 これを使用するには、`android.permission.WRITE_EXTERNAL_STORAGE` 権限が必要です。\n  * `cache`： アプリケーションの内部キャッシュ ディレクトリ\n  * `cache-external`： 外部キャッシュのアプリケーションのディレクトリ\n  * `root`： デバイス全体のファイルシステム\n\nアンドロイドを「ファイル」ファイルシステム内の\"ドキュメント/\"サブディレクトリを表す\"ドキュメント\"という名前の特殊なファイルシステムもサポートしています。\n\n### iOS\n\n  * `library`: ライブラリのアプリケーションのディレクトリ\n  * `documents`: ドキュメントのアプリケーションのディレクトリ\n  * `cache`: キャッシュのアプリケーションのディレクトリ\n  * `bundle`: アプリケーションバンドル;アプリ自体 (読み取りのみ) ディスク上の場所\n  * `root`： デバイス全体のファイルシステム\n\n既定では、ライブラリとドキュメント ディレクトリを iCloud に同期できます。 2 つの追加のファイルシステム、`library-nosync` および `documents-nosync` を表す、特別な非同期ディレクトリ内を要求することもできます、`/Library` または `Documents/` ファイルシステム。"
  },
  {
    "path": "plugins/cordova-plugin-file/doc/ja/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-file\n\nこのプラグインは、デバイス上のファイルへの読み取り/書き込みアクセスを許可するファイル API を実装します。\n\nこのプラグインを含む、いくつかの仕様に基づいています：、HTML5 File API の<http://www.w3.org/TR/FileAPI/>\n\n（今は亡き) ディレクトリとシステムは、最新の拡張機能: <http://www.w3.org/TR/2012/WD-file-system-api-20120417/>プラグインのコードのほとんどはときに、以前の仕様に書かれていたが現在は： <http://www.w3.org/TR/2011/WD-file-system-api-20110419/>\n\nFileWriter 仕様も実装しています: <http://dev.w3.org/2009/dap/file-system/file-writer.html>\n\n使用法を参照してください HTML5 岩 ' 優秀な[ファイルシステム記事][1]。\n\n [1]: http://www.html5rocks.com/en/tutorials/file/filesystem/\n\n他のストレージ オプションの概要については、コルドバの[ストレージ ・ ガイド][2]を参照してください。.\n\n [2]: http://cordova.apache.org/docs/en/edge/cordova_storage_storage.md.html\n\nこのプラグインでは、グローバル `cordova.file` オブジェクトを定義します。\n\nグローバル スコープではあるがそれがないまで `deviceready` イベントの後です。\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(cordova.file);\n    }\n    \n\n## インストール\n\n    cordova plugin add cordova-plugin-file\n    \n\n## サポートされているプラットフォーム\n\n*   アマゾン火 OS\n*   アンドロイド\n*   ブラックベリー 10\n*   Firefox の OS\n*   iOS\n*   Windows Phone 7 と 8 *\n*   Windows 8 *\n*   ブラウザー\n\n* *`FileReader.readAsArrayBuffer` も `FileWriter.write(blob)` もこれらのプラットフォームはサポートしていません*。\n\n## ファイルを保存する場所\n\nV1.2.0、現在重要なファイル システム ディレクトリへの Url を提供しています。 各 URL はフォーム *file:///path/to/spot/* で、`window.resolveLocalFileSystemURL()` を使用する `DirectoryEntry` に変換することができます。.\n\n*   `cordova.file.applicationDirectory`-読み取り専用のディレクトリは、アプリケーションがインストールされています。（*iOS*、*アンドロイド*、*ブラックベリー 10*)\n\n*   `cordova.file.applicationStorageDirectory`-アプリケーションのサンド ボックス; のルート ディレクトリiOS でこの場所が読み取り専用 （特定のサブディレクトリが [のような `/Documents` ] は、読み取り/書き込み)。 内に含まれるすべてのデータは、アプリケーションにプライベートです。 （ *iOS*、*アンドロイド*、*ブラックベリー 10*)\n\n*   `cordova.file.dataDirectory`内部メモリを使用して、アプリケーションのサンド ボックス内で永続なプライベート データ ストレージ （外部メモリを使用する必要がある場合使用して Android 上で `.externalDataDirectory` )。 IOS は、このディレクトリは iCloud と同期されません (使用する `.syncedDataDirectory` )。 （*iOS*、*アンドロイド*、*ブラックベリー 10*)\n\n*   `cordova.file.cacheDirectory`-キャッシュされたデータ ファイルやアプリに簡単に再作成できる任意のファイルのディレクトリ。 ストレージ デバイスが不足したときに、OS がこれらのファイルを削除可能性があります、それにもかかわらず、アプリはここにファイルを削除する OS に依存しないでください。 （*iOS*、*アンドロイド*、*ブラックベリー 10*)\n\n*   `cordova.file.externalApplicationStorageDirectory`外部ストレージのアプリケーション領域。（*アンドロイド*)\n\n*   `cordova.file.externalDataDirectory`-外部ストレージ上のアプリ固有のデータ ファイルを配置する場所。（*アンドロイド*)\n\n*   `cordova.file.externalCacheDirectory`外部ストレージにアプリケーション キャッシュ。（*アンドロイド*)\n\n*   `cordova.file.externalRootDirectory`-外部ストレージ (SD カード) ルート。（*アンドロイド*、*ブラックベリー 10*)\n\n*   `cordova.file.tempDirectory`-OS をクリアすることができます temp ディレクトリが。 このディレクトリ; オフに OS に依存しません。アプリが常に該当するファイルを削除します。 (*iOS*)\n\n*   `cordova.file.syncedDataDirectory`-（例えば iCloud) に同期する必要がありますアプリケーション固有のファイルを保持します。(*iOS*)\n\n*   `cordova.file.documentsDirectory`-ファイル、アプリケーションにプライベートは他のアプリケーション (Office ファイルなど） を意味です。(*iOS*)\n\n*   `cordova.file.sharedDirectory`すべてのアプリケーション (*ブラックベリー 10*にグローバルに使用できるファイル)\n\n## ファイル ・ システム ・ レイアウト\n\n技術的に実装の詳細、非常にどのように `cordova.file.*` プロパティは、実際のデバイス上の物理パスにマップを知っておくと便利することができます。\n\n### iOS ファイル システムのレイアウト\n\n| デバイス ・ パス                            | `cordova.file.*`            | `iosExtraFileSystems` | r/w ですか？ | 永続的なですか？ | OS を消去します  |   同期   | プライベート |\n|:------------------------------------ |:--------------------------- |:--------------------- |:--------:|:--------:|:----------:|:------:|:------:|\n| `/var/モバイル/アプリケーション/< UUID >/` | applicationStorageDirectory | -                     |    r     |   N/A    |    N/A     |  N/A   |   はい   |\n|    `appname.app/`                    | ディレクトリ                      | バンドル                  |    r     |   N/A    |    N/A     |  N/A   |   はい   |\n|       `www/`                         | -                           | -                     |    r     |   N/A    |    N/A     |  N/A   |   はい   |\n|    `Documents/`                      | documentsDirectory          | ドキュメント                |   r/w    |    はい    |    いいえ     |   はい   |   はい   |\n|       `NoCloud/`                     | -                           | ドキュメント nosync         |   r/w    |    はい    |    いいえ     |  いいえ   |   はい   |\n|    `Library`                         | -                           | ライブラリ                 |   r/w    |    はい    |    いいえ     | はいですか？ |   はい   |\n|       `NoCloud/`                     | dataDirectory               | ライブラリ nosync          |   r/w    |    はい    |    いいえ     |  いいえ   |   はい   |\n|       `Cloud/`                       | syncedDataDirectory         | -                     |   r/w    |    はい    |    いいえ     |   はい   |   はい   |\n|       `Caches/`                      | cacheDirectory              | キャッシュ                 |   r/w    |   はい *   | はい * * *| |  いいえ   |   はい   |\n|    `tmp/`                            | tempDirectory               | -                     |   r/w    | いいえ * *  | はい * * *| |  いいえ   |   はい   |\n\n* アプリを再起動し、アップグレードとの間でファイルを保持が、OS を希望するたびにこのディレクトリを削除することができます。アプリを削除可能性があります任意のコンテンツを再作成することができる必要があります。\n\n* * ファイル アプリケーション再起動を渡って続くことがありますが、この動作に依存しないでください。 ファイルは、更新を維持するは保証されません。 アプリが該当する場合このディレクトリからファイルを削除する必要があります、これらのファイルが削除されるとき (または場合でも)、OS は保証しません。\n\n* * *| OS はそれ、必要だと感じているときにこのディレクトリの内容を消去可能性がありますが、これに依存しません。 この適切なディレクトリに、アプリケーションをオフにする必要があります。\n\n### 人造人間ファイル ・ システム ・ レイアウト\n\n| デバイス ・ パス                         | `cordova.file.*`                    | `AndroidExtraFileSystems` | r/w ですか？ | 永続的なですか？ | OS を消去します | プライベート |\n|:--------------------------------- |:----------------------------------- |:------------------------- |:--------:|:--------:|:---------:|:------:|\n| `file:///android_asset/`          | ディレクトリ                              |                           |    r     |   N/A    |    N/A    |   はい   |\n| `/データ/データ/< app id >/`      | applicationStorageDirectory         | -                         |   r/w    |   N/A    |    N/A    |   はい   |\n|    `cache`                        | cacheDirectory                      | キャッシュ                     |   r/w    |    はい    |   はい *    |   はい   |\n|    `files`                        | dataDirectory                       | ファイル                      |   r/w    |    はい    |    いいえ    |   はい   |\n|       `Documents`                 |                                     | ドキュメント                    |   r/w    |    はい    |    いいえ    |   はい   |\n| `< sd カード >/`               | externalRootDirectory               | sd カード                    |   r/w    |    はい    |    いいえ    |  いいえ   |\n|    `Android/data/<app-id>/` | externalApplicationStorageDirectory | -                         |   r/w    |    はい    |    いいえ    |  いいえ   |\n|       `cache`                     | externalCacheDirectry               | 外部キャッシュ                   |   r/w    |    はい    |  いいえ * *  |  いいえ   |\n|       `files`                     | externalDataDirectory               | 外部ファイル                    |   r/w    |    はい    |    いいえ    |  いいえ   |\n\n* OS このディレクトリを定期的に消去可能性がありますが、この動作に依存しないでください。 アプリケーションの必要に応じてこのディレクトリの内容をオフにします。 ユーザーは手動でキャッシュを削除する必要があります、このディレクトリの内容が削除されます。\n\n* * OS はこのディレクトリは自動的にクリアされません自分でコンテンツを管理するために責任があります。 ユーザは手動でキャッシュを消去する必要があります、ディレクトリの内容が削除されます。\n\n**注**: 外部記憶装置をマウントできない場合は、`cordova.file.external*` プロパティを `null`.\n\n### ブラックベリー 10 ファイル ・ システム ・ レイアウト\n\n| デバイス ・ パス                                         | `cordova.file.*`            | r/w ですか？ | 永続的なですか？ | OS を消去します | プライベート |\n|:------------------------------------------------- |:--------------------------- |:--------:|:--------:|:---------:|:------:|\n| `file:///accounts/1000/appdata/< app id >/` | applicationStorageDirectory |    r     |   N/A    |    N/A    |   はい   |\n|    `app/native`                                   | ディレクトリ                      |    r     |   N/A    |    N/A    |   はい   |\n|    `data/webviews/webfs/temporary/local__0`       | cacheDirectory              |   r/w    |   いいえ    |    はい     |   はい   |\n|    `data/webviews/webfs/persistent/local__0`      | dataDirectory               |   r/w    |    はい    |    いいえ    |   はい   |\n| `file:///accounts/1000/removable/sdcard`          | externalRemovableDirectory  |   r/w    |    はい    |    いいえ    |  いいえ   |\n| `file:///accounts/1000/shared`                    | sharedDirectory             |   r/w    |    はい    |    いいえ    |  いいえ   |\n\n*注*: すべてのパスは/accounts/1000-enterprise 基準に境界を動作するようにアプリケーションを展開するとき。\n\n## Android の癖\n\n### Android の永続的なストレージの場所\n\nAndroid のデバイスに永続的なファイルを格納する複数の有効な場所があります。 さまざまな可能性について広範な議論のための [このページ][3] を参照してください。\n\n [3]: http://developer.android.com/guide/topics/data/data-storage.html\n\n以前のバージョンのプラグインは、デバイスの SD カード （または同等のストレージ パーティション） マウントされていたと主張したかどうかに基づいて、起動時に一時と永続的なファイルの場所を選ぶでしょう。 SD カードがマウントされている場合、または大規模な内部ストレージ パーティションが利用可能な場合 (ようネクサス デバイス上） し、永続的なファイルは、その領域のルートに格納されます。 これはすべての Cordova アプリ見ることができる利用可能なファイルのすべてのカードに意味しました。\n\nSD カードがない場合、以前のバージョンがデータを格納する `/data/data/<packageId>`、お互いからアプリを分離するが、まだ原因可能性がありますユーザー間で共有するデータ。\n\n内部ファイルの保存場所やアプリケーションの `config.xml` ファイルに優先順位を持つ以前のロジックを使用してファイルを保存するかどうかを選択することが可能です今。 これを行うに、`config.xml` に次の 2 行のいずれかを追加します。\n\n    <preference name=\"AndroidPersistentFileLocation\" value=\"Internal\" />\n    \n    <preference name=\"AndroidPersistentFileLocation\" value=\"Compatibility\" />\n    \n\nこの行がなければファイル プラグインはデフォルトとして `Compatibility` を使用します。優先タグが存在し、これらの値の 1 つではない場合、アプリケーションは起動しません。\n\nアプリケーションは、ユーザーに以前出荷されている場合、古い (前 1.0） を使用して、このプラグインのバージョンし、永続的なファイルシステムに保存されているファイルには `Compatibility` を設定する必要があります。 自分のアプリケーションをアップグレードする既存のユーザーを彼らの装置によって、以前に保存されたファイルにアクセスすることができることがあることを意味する「内部」に場所をスイッチングします。\n\nアプリケーションは、新しい、または永続的なファイルシステムにファイルが格納され以前は決して場合、`内部` 設定一般的に推奨されます。\n\n## iOS の癖\n\n*   `cordova.file.applicationStorageDirectory`読み取り専用;ルート ディレクトリ内のファイルを保存しようは失敗します。 他の 1 つを使用して `cordova.file.*` iOS のため定義されているプロパティ (のみ `applicationDirectory` と `applicationStorageDirectory` は読み取り専用)。\n*   `FileReader.readAsText(blob, encoding)` \n    *   `encoding`パラメーターはサポートされていませんし、utf-8 エンコーディングが常に有効です。\n\n### iOS の永続的なストレージの場所\n\nIOS デバイスに永続的なファイルを格納する 2 つの有効な場所がある: ドキュメントとライブラリのディレクトリ。 プラグインの以前のバージョンは、唯一のこれまでドキュメント ディレクトリに永続的なファイルを格納されます。 これは、ディレクトリの目的は、輸出のための完全なドキュメントを作成するのではなくなかったがしばしば意図されていたり、特に多数の小さいファイルを処理するアプリケーションの場合、iTunes に表示されているすべてのアプリケーションのファイルを作るの副作用があった。\n\nドキュメントまたはアプリケーションの `config.xml` ファイルに優先順位のライブラリ ディレクトリにファイルを保存するかどうかを選択することが可能です今。 これを行うに、`config.xml` に次の 2 行のいずれかを追加します。\n\n    <preference name=\"iosPersistentFileLocation\" value=\"Library\" />\n    \n    <preference name=\"iosPersistentFileLocation\" value=\"Compatibility\" />\n    \n\nこの行がなければファイル プラグインはデフォルトとして `Compatibility` を使用します。優先タグが存在し、これらの値の 1 つではない場合、アプリケーションは起動しません。\n\nアプリケーションは、ユーザーに以前出荷されている場合、古い (前 1.0） を使用して、このプラグインのバージョンし、永続的なファイルシステムに保存されているファイルには `Compatibility` を設定する必要があります。 自分のアプリケーションをアップグレードする既存のユーザーを以前に保存されたファイルにアクセスすることができるだろうことを意味する `Library` に場所をスイッチングします。\n\nアプリケーションは、新しい、または永続的なファイルシステムにファイルが格納され以前は決して場合、`Library` 設定一般的に推奨されます。\n\n## Firefox OS 癖\n\nファイル システム API Firefox OS でネイティブ サポートされていないと、indexedDB の上にシムとして実装されています。\n\n*   空でないディレクトリを削除するときに失敗しません\n*   ディレクトリのメタデータをサポートしていません\n*   方法 `copyTo` と `moveTo` ディレクトリをサポートしていません\n\n次のデータ パスがサポートされています: * `applicationDirectory` - `xhr` を使用して、アプリケーションと共にパッケージ化されるローカル ファイルを取得します。 * `dataDirectory` - 永続的なアプリケーション固有のデータ ファイル。 * `cacheDirectory` - アプリケーションの再起動後も維持する必要がありますキャッシュ ファイル (アプリはここにファイルを削除する OS に依存しないでください)。\n\n## ブラウザーの癖\n\n### 共通の癖と発言\n\n*   各ブラウザーはサンド ボックス化されたファイルシステムを使用します。IE と Firefox IndexedDB をベースとして使用します。すべてのブラウザーは、パスにディレクトリの区切り記号としてスラッシュを使用します。\n*   ディレクトリ エントリは連続して作成されなければなりません。 たとえば、コール `fs.root.getDirectory ('dir1 dir2'、{create:true}、successCallback、解り)` dir1 が存在しなかった場合は失敗します。\n*   プラグインは、永続的なストレージ アプリケーションの最初の起動時に使用するユーザーのアクセス許可を要求します。 \n*   プラグインは、`cdvfile://localhost` (ローカル リソース) をサポートしているだけです。すなわち外部リソースは、`cdvfile` を介してサポートされていません.\n*   プラグインに [制限」のファイル システム API の 8.3 命名規則][4] に従っていません。.\n*   Blob およびファイル ' `close` 関数はサポートされていません。\n*   `FileSaver` と `BlobBuilder` このプラグインでサポートされていないスタブを持っていません。\n*   プラグインは、`requestAllFileSystems` をサポートしません。この関数は、仕様で行方不明にも。\n*   ディレクトリ内のエントリを使用すると削除されません `create: true` 既存ディレクトリのフラグ。\n*   コンス トラクターで作成されたファイルはサポートされていません。代わりに entry.file メソッドを使用する必要があります。\n*   各ブラウザーは blob URL 参照の独自のフォームを使用します。\n*   `readAsDataURL` 関数はサポートされてがクロムメッキで mediatype エントリ名の拡張子によって異なります、IE でメディアの種類は、常に空 （`text-plain` に従って、仕様と同じである）、Firefox でメディアの種類は常に `アプリケーションまたはオクテット-ストリーム`。 たとえば、コンテンツが場合 `abcdefg` し Firefox を返します `データ: アプリケーション/オクテット ストリーム、base64、YWJjZGVmZw = =`、すなわちを返します `データ:; base64、YWJjZGVmZw = =`、クロムを返します `データ: < エントリ名の拡張子によって mediatype >; base64、YWJjZGVmZw = =`.\n*   `toInternalURL` フォーム `file:///persistent/path/to/entry` （Firefox、IE） のパスを返します。 クロムの `cdvfile://localhost/persistent/file` フォームのパスを返します.\n\n [4]: http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions\n\n### クロムの癖\n\n*   デバイスの準備ができているイベント後クローム ファイルシステムはすぐに準備ができています。回避策としては `filePluginIsReady` イベントにサブスクライブできます。例: \n\n    javascript\n    window.addEventListener('filePluginIsReady', function(){ console.log('File plugin is ready');}, false);\n    \n\n`window.isFilePluginReadyRaised` 関数を使用して、イベントが既に発生したかどうかを確認できます。 -Chrome に window.requestFileSystem 一時と永続的なファイル ・ システムのクォータの制限はありません。 -クロム内の永続ストレージを増加する `window.initPersistentFileSystem` メソッドを呼び出す必要があります。 永続的な記憶域のクォータは、既定では 5 MB です。 クロムが必要です `--許可-ファイル-アクセス--ファイルから` `file:///` プロトコル経由でサポート API に引数を実行します。 -`ファイル` オブジェクト フラグを使用する場合ない変更されます `{create:true}` 既存の `エントリ` を取得するとき。 -イベント `cancelable` プロパティを設定するクロムの場合は true。 これは [仕様][5] に反して。 -クロムメッキで `網` 関数を返します `ファイルシステム：`-アプリケーションのホストによってパスのプレフィックスします。 たとえば、`filesystem:file:///persistent/somefile.txt`、`filesystem:http://localhost:8080/persistent/somefile.txt`。 -`toURL` の関数の結果にはディレクトリ エントリ場合末尾にスラッシュが含まれていません。 クロムは、スラッシュ後塵 url を持つディレクトリが正しく解決されるも。 -`resolveLocalFileSystemURL` メソッドは、受信 `url` が `ファイルシステム` のプレフィックスが必要です。 たとえば、`resolveLocalFileSystemURL` の `url` パラメーター フォーム `filesystem:file:///persistent/somefile.txt` で人造人間フォーム `file:///persistent/somefile.txt` とは対照的にする必要があります。 -廃止された `toNativeURL` 関数はサポートされていません、スタブはありません。 -`setMetadata` 関数は、仕様に記載されていないありサポートされていません。 -INVALID_MODIFICATION_ERR （コード: 9) の代わりにスローされた SYNTAX_ERR(code: 8) の非実在しないファイルシステムの依頼を。 -INVALID_MODIFICATION_ERR （コード: 9) の代わりにスローされた PATH_EXISTS_ERR(code: 12)、排他的なファイルまたはディレクトリを作成しようとするが既に存在します。 -INVALID_MODIFICATION_ERR （コード: 9) の代わりにスローされた NO_MODIFICATION_ALLOWED_ERR(code: 6) ルート ・ ファイル ・ システムで removeRecursively を呼び出すをしようとして。 -INVALID_MODIFICATION_ERR （コード: 9) の代わりにスローされた NOT_FOUND_ERR(code: 1) [moveto] ディレクトリが存在しないをしようとして。\n\n [5]: http://dev.w3.org/2009/dap/file-system/file-writer.html\n\n### IndexedDB ベース インプレ癖 （Firefox と IE）\n\n*   `.` `です。` はサポートされていません。\n*   IE は `file:///` をサポートしていません-モード;ホスト モードのみがサポートされている (http://localhost:xxxx) です。\n*   Firefox のファイルシステムのサイズは無制限ですが各 50 MB の拡張機能がユーザーのアクセス許可を要求します。 IE10 は最大 10 mb の複合 AppCache と IndexedDB を求めず、サイトごとに 250 mb の最大値まで増加を許可するかどうかをたずねられますそのレベルに当ればファイルシステムの実装で使用することができます。 `RequestFileSystem` 関数の `size` パラメーターは、Firefox と IE のファイルシステムには影響しません。\n*   `readAsBinaryString` 関数の仕様に記載されていない、IE でサポートされていないと、スタブを持っていません。\n*   `file.type` は、常に null です。\n*   削除された DirectoryEntry インスタンスのコールバックの結果を使用してエントリを作成しないでください。それ以外の場合は、'ハンギングのエントリ' が表示されます。\n*   ちょうど書かれていた、ファイルを読むことができます前にこのファイルの新しいインスタンスを取得する必要があります。\n*   `setMetadata` 関数は、仕様に記載されていない `modificationTime` フィールド変更のみをサポートします。 \n*   `copyTo` と `moveTo` 関数ディレクトリをサポートしていません。\n*   ディレクトリのメタデータはサポートされていません。\n*   両方の Entry.remove と directoryEntry.removeRecursively は空でないディレクトリを削除するときを失敗しない - 削除されるディレクトリ コンテンツと共にを掃除している代わりに。\n*   `abort` し、`truncate` 機能はサポートされていません。\n*   進行状況イベントは起動しません。たとえば、このハンドラーがない実行されます。\n\n    javascript\n    writer.onprogress = function() { /*commands*/ };\n    \n\n## ノートをアップグレードします。\n\nこのプラグインのデベロッパー、公開された仕様に合うように、`認証` と `DirectoryEntry` の構造が変更されました。\n\nプラグインの前 (pre 1.0.0) バージョンはデバイス絶対ファイル場所 `エントリ` オブジェクトの `fullPath` プロパティに格納されます。これらのパスはようになります通常\n\n    /var/mobile/Applications/<application UUID>/Documents/path/to/file  (iOS)\n    /storage/emulated/0/path/to/file                                    (Android)\n    \n\nこれらのパスはまた `Entry` オブジェクトの `toURL()` メソッドによって返されます。\n\nデベロッパー、`fullPath` 属性は *HTML ファイルシステムのルートに対する相対パス* のファイルへのパス。 したがって、上記のパスは今両方の `fullPath` と `FileEntry` オブジェクトで表される\n\n    /path/to/file\n    \n\nデバイス絶対パスとアプリケーション動作以前 `Entry` オブジェクトの `fullPath` プロパティを使用してこれらのパスを取得した場合は、代わりに `entry.toURL()` を使用するコードを更新する必要があります。\n\n下位互換性、`resolveLocalFileSystemURL()` メソッドは、デバイス絶対パスを受け入れるし、は、`TEMPORARY` または `PERSISTENT` ファイル ・ システム内でそのファイルが存在する限り、それに対応する `Entry` オブジェクトを返します。\n\nこれは特に以前デバイス絶対パスを使用してファイル転送のプラグインで問題となっている （そしてまだそれらを受け入れることができます）。 それがデバイス上のファイルで動作するプラグインを得る問題を解決する必要があります `entry.toURL()` で `entry.fullPath` を置き換えるので、ファイルシステムの Url で正常に動作にアップデートされました。\n\nV1.1.0 の `toURL()` の戻り値に変更されました (\\[CB-6394\\] (https://issues.apache.org/jira/browse/CB-6394) を参照) を絶対 'file://' で始まる URL を返します。 可能な限り。 確保するために、' cdvfile:'-`toInternalURL()` を今すぐ使用できます URL。 このメソッドは、フォームのファイルシステムの Url を返します今\n\n    cdvfile://localhost/persistent/path/to/file\n    \n\nこれはファイルを一意に識別するために使用できます。\n\n## エラー コードと意味のリスト\n\nエラーがスローされると、次のコードのいずれかが使用されます。\n\n| コード | 定数                            |\n| ---:|:----------------------------- |\n|   1 | `NOT_FOUND_ERR`               |\n|   2 | `SECURITY_ERR`                |\n|   3 | `ABORT_ERR`                   |\n|   4 | `NOT_READABLE_ERR`            |\n|   5 | `ENCODING_ERR`                |\n|   6 | `NO_MODIFICATION_ALLOWED_ERR` |\n|   7 | `INVALID_STATE_ERR`           |\n|   8 | `SYNTAX_ERR`                  |\n|   9 | `INVALID_MODIFICATION_ERR`    |\n|  10 | `QUOTA_EXCEEDED_ERR`          |\n|  11 | `TYPE_MISMATCH_ERR`           |\n|  12 | `PATH_EXISTS_ERR`             |\n\n## (省略可能) プラグインを構成します。\n\n利用可能なファイルシステムのセットは構成されたプラットフォームをすることができます。IOS と Android の両方を認識します。 <preference> タグ `config.xml` をインストールするファイルシステムの名前します。既定では、すべてのファイル システムのルートが有効になります。\n\n    <preference name=\"iosExtraFilesystems\" value=\"library,library-nosync,documents,documents-nosync,cache,bundle,root\" />\n    <preference name=\"AndroidExtraFilesystems\" value=\"files,files-external,documents,sdcard,cache,cache-external,root\" />\n    \n\n### アンドロイド\n\n*   `files`： アプリケーションの内部ファイルのストレージ ディレクトリ\n*   `files-external`: アプリケーションの外部のファイルのストレージ ディレクトリ\n*   `sdcard`：、グローバル外部ストレージ ディレクトリをファイル (これは SD カードのルートがインストールされている場合)。 これを使用するには、`android.permission.WRITE_EXTERNAL_STORAGE` 権限が必要です。\n*   `cache`： アプリケーションの内部キャッシュ ディレクトリ\n*   `cache-external`： 外部キャッシュのアプリケーションのディレクトリ\n*   `root`： デバイス全体のファイルシステム\n\nアンドロイドを「ファイル」ファイルシステム内の\"ドキュメント/\"サブディレクトリを表す\"ドキュメント\"という名前の特殊なファイルシステムもサポートしています。\n\n### iOS\n\n*   `library`: ライブラリのアプリケーションのディレクトリ\n*   `documents`: ドキュメントのアプリケーションのディレクトリ\n*   `cache`: キャッシュのアプリケーションのディレクトリ\n*   `bundle`: アプリケーションバンドル;アプリ自体 (読み取りのみ) ディスク上の場所\n*   `root`： デバイス全体のファイルシステム\n\n既定では、ライブラリとドキュメント ディレクトリを iCloud に同期できます。 2 つの追加のファイルシステム、`library-nosync` および `documents-nosync` を表す、特別な非同期ディレクトリ内を要求することもできます、`/Library` または `Documents/` ファイルシステム。\n"
  },
  {
    "path": "plugins/cordova-plugin-file/doc/ja/plugins.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# プラグイン開発者のためのメモ\n\nこれらのノートは主に Android と iOS 開発者インタ フェース ファイルのプラグインを使用してファイル システムでプラグインを書きたい人向け。\n\n## コルドバのファイル システムの Url での作業\n\nバージョン 1.0.0 では、以来、このプラグインを含む Url を使用する `cdvfile` JavaScript に raw デバイス ファイル システムのパスを公開するのではなく、橋の上のすべての通信方式します。\n\nJavaScript 側では、これはファイルと DirectoryEntry オブジェクトに HTML ファイル システムのルートを基準として、fullPath 属性があることを意味します。 あなたのプラグインの JavaScript API がファイルまたは DirectoryEntry オブジェクトを受け入れる場合を呼び出す必要があります `.toURL()` 橋を渡ってそれをネイティブ コードに渡す前にそのオブジェクトの。\n\n### Cdvfile に変換する://fileystem のパスに Url\n\nファイルシステムへの書き込みする必要があるプラグインは、実際のファイルシステムの場所に受信したファイル システム URL に変換する必要があります。ネイティブ プラットフォームによって、これを行うための複数の方法があります。\n\nそれを覚えていることが重要ですすべて `cdvfile://` の Url がデバイス上の実際のファイルをマッピング可能な。 いくつかの Url は、ファイルでは表されないまたはリモート リソースを参照することができますもデバイス上の資産を参照できます。 これらの可能性のためのプラグインは、戻るときにパスに Url を変換しようとして、彼らは意味のある結果を得るかどうか常にテスト必要があります。\n\n#### アンドロイド\n\nアンドロイド, に変換する最も簡単な方法で、 `cdvfile://` を使用するファイルシステムのパスに URL は `org.apache.cordova.CordovaResourceApi` 。 `CordovaResourceApi`扱うことができるいくつかの方法は、 `cdvfile://` の Url:\n\n    webView プラグイン クラス CordovaResourceApi resourceApi のメンバーである = webView.getResourceApi()。\n    \n    デバイスでこのファイルを表す file:///URL を取得//ファイル Uri fileURL にマップできない場合、同じ URL は変更されません = resourceApi.remapUri(Uri.parse(cdvfileURL));\n    \n\nまた、ファイルのプラグインを直接使用することが可能です。\n\n    インポート org.apache.cordova.file.FileUtils;\n    インポート org.apache.cordova.file.FileSystem;\n    インポート java.net.MalformedURLException;\n    \n    プラグイン マネージャーからファイルのプラグインを入手してコマンド filePlugin = (FileUtils)webView.pluginManager.getPlugin(\"File\");\n    \n    それを試みるためにパスを取得 URL を指定すると、{文字列パス = filePlugin.filesystemPathForURL(cdvfileURL);} キャッチ (MalformedURLException e) {/ファイルシステムの url が認識されませんでした/}\n    \n\nパスから変換する、 `cdvfile://` URL:\n\n    インポート org.apache.cordova.file.LocalFilesystemURL;\n    \n    デバイス ・ パスの LocalFilesystemURL オブジェクトを取得//cdvfile URL として表現できない場合は null。\n    LocalFilesystemURL url = filePlugin.filesystemURLforLocalPath(path);\n    URL オブジェクトの文字列 cdvfileURL の文字列表現を取得する = url.toString();\n    \n\nあなたのプラグインは、ファイルを作成しをファイル オブジェクトを返す場合、ファイルのプラグインを使用します。\n\n    JavaScript を返すときに適した JSON 構造を返す//このファイルは cdvfile URL として表現できない場合は null。\n    JSONObject エントリ = filePlugin.getEntryForFile(file);\n    \n\n#### iOS\n\nIOS のコルドバは同じを使用しない `CordovaResourceApi` アンドロイドとしての概念。IOS では、Url とファイルシステムのパスの間を変換するファイル プラグインを使用する必要があります。\n\n    URL の文字列 CDVFilesystemURL * url から CDVFilesystem URL オブジェクトを取得 [CDVFilesystemURL fileSystemURLWithString:cdvfileURL];\n    ファイル NSString * パスにマップできない場合は nil または URL オブジェクトのパスを取得 [filePlugin filesystemPathForURL:url];\n    \n    \n    デバイス ・ パスの CDVFilesystem の URL オブジェクトを取得または//cdvfile URL として表現できない場合は nil です。\n    CDVFilesystemURL の url = [filePlugin fileSystemURLforLocalPath:path];\n    URL オブジェクト NSString * cdvfileURL の文字列表現を取得する = [url absoluteString];\n    \n\nあなたのプラグインは、ファイルを作成しをファイル オブジェクトを返す場合、ファイルのプラグインを使用します。\n\n    デバイス ・ パスの CDVFilesystem の URL オブジェクトを取得または//cdvfile URL として表現できない場合は nil です。\n    CDVFilesystemURL の url = [filePlugin fileSystemURLforLocalPath:path];\n    JavaScript NSDictionary * エントリに戻る構造を得る = [filePlugin makeEntryForLocalURL:url]\n    \n\n#### Java スクリプトの設定\n\nJava スクリプトの設定を取得するに、 `cdvfile://` ファイルまたは DirectoryEntry オブジェクトからの URL を呼び出して、 `.toURL()` それを。\n\n    var cdvfileURL = entry.toURL();\n    \n\nプラグイン応答ハンドラーに返された FileEntry 構造体の実際のエントリ オブジェクトを変換する、ハンドラーのコード ファイルのプラグインをインポート、新しいオブジェクトを作成します。\n\n    適切なエントリ オブジェクト var エントリを作成します。\n    場合 (entryStruct.isDirectory) {エントリ = 新しい DirectoryEntry (entryStruct.name、entryStruct.fullPath、新しい FileSystem(entryStruct.filesystemName));} 他 {エントリ = 新しいファイル (entryStruct.name、entryStruct.fullPath、新しい FileSystem(entryStruct.filesystemName));}"
  },
  {
    "path": "plugins/cordova-plugin-file/doc/ko/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-file\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-file.svg)](https://travis-ci.org/apache/cordova-plugin-file)\n\n이 플러그인은 장치에 있는 파일에 대 한 읽기/쓰기 액세스를 허용 하는 파일 API를 구현 합니다.\n\n이 플러그인을 포함 한 몇 가지 사양에 따라: HTML5 파일 API는 <http://www.w3.org/TR/FileAPI/>\n\n(지금은 없어진) 디렉터리와 시스템 확장 최신: <http://www.w3.org/TR/2012/WD-file-system-api-20120417/> 플러그인 코드의 대부분은 때 이전 사양 작성 되었습니다 있지만 현재는: <http://www.w3.org/TR/2011/WD-file-system-api-20110419/>\n\n그것은 또한 FileWriter 사양 구현: <http://dev.w3.org/2009/dap/file-system/file-writer.html>\n\n사용을 참조 하십시오 HTML5 바위 ' 우수한 [파일 시스템 문서.](http://www.html5rocks.com/en/tutorials/file/filesystem/)\n\n다른 저장소 옵션에 대 한 개요, 코르도바의 [저장소 가이드](http://cordova.apache.org/docs/en/edge/cordova_storage_storage.md.html) 를 참조합니다.\n\n이 플러그인 글로벌 `cordova.file` 개체를 정의합니다.\n\n전역 범위에 있지만 그것은 불가능까지 `deviceready` 이벤트 후.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(cordova.file);\n    }\n    \n\n## 설치\n\n    cordova plugin add cordova-plugin-file\n    \n\n## 지원 되는 플랫폼\n\n  * 아마존 화재 운영 체제\n  * 안 드 로이드\n  * 블랙베리 10\n  * Firefox 운영 체제\n  * iOS\n  * Windows Phone 7과 8 *\n  * 윈도우 8 *\n  * Windows*\n  * 브라우저\n\n\\* *These platforms do not support `FileReader.readAsArrayBuffer` nor `FileWriter.write(blob)`.*\n\n## 파일을 저장할 위치를\n\nV1.2.0, 현재 중요 한 파일 시스템 디렉터리에 Url도 제공 됩니다. 각 URL 형태 *file:///path/to/spot/* 이며 `DirectoryEntry` `window.resolveLocalFileSystemURL()`를 사용 하 여 변환할 수 있습니다..\n\n  * `cordova.file.applicationDirectory`-읽기 전용 디렉터리는 응용 프로그램을 설치 합니다. (*iOS*, *안 드 로이드*, *블랙베리 10*)\n\n  * `cordova.file.applicationStorageDirectory`응용 프로그램의 샌드박스;의 루트 디렉터리 iOS에이 위치에는 읽기 전용 (특정 하위 디렉토리만 [같은 `/Documents` ]은 읽기 / 쓰기). 포함 된 모든 데이터는 응용 프로그램에 전용. ( *iOS*, *안 드 로이드*, *블랙베리 10*)\n\n  * `cordova.file.dataDirectory`-내부 메모리를 사용 하 여 응용 프로그램의 샌드박스 내에서 영구 및 개인 데이터 스토리지 (안 드 로이드, 외부 메모리를 사용 해야 하는 경우 사용 하 여 `.externalDataDirectory` ). IOS에이 디렉터리 iCloud와 동기화 되지 되 (를 사용 하 여 `.syncedDataDirectory` ). (*iOS*, *안 드 로이드*, *블랙베리 10*)\n\n  * `cordova.file.cacheDirectory`-디렉터리 캐시 데이터 파일 또는 모든 파일을 당신의 app를 다시 쉽게 만들 수 있습니다. 운영 체제 장치 저장소 부족 하면 이러한 파일을 삭제할 수 있습니다, 그리고 그럼에도 불구 하 고, 애플 리 케이 션 여기에 파일을 삭제 하려면 운영 체제에 의존 하지 말아야 합니다. (*iOS*, *안 드 로이드*, *블랙베리 10*)\n\n  * `cordova.file.externalApplicationStorageDirectory`-응용 프로그램 외부 저장 공간입니다. (*안 드 로이드*)\n\n  * `cordova.file.externalDataDirectory`-외부 저장소에 응용 프로그램 특정 데이터 파일을 넣어 어디. (*안 드 로이드*)\n\n  * `cordova.file.externalCacheDirectory`외부 저장소에 응용 프로그램 캐시입니다. (*안 드 로이드*)\n\n  * `cordova.file.externalRootDirectory`-외부 저장 (SD 카드) 루트입니다. (*안 드 로이드*, *블랙베리 10*)\n\n  * `cordova.file.tempDirectory`-운영 체제에서 지울 수 있습니다 임시 디렉터리 것입니다. 이 디렉터리;를 운영 체제에 의존 하지 마십시오 귀하의 응용 프로그램 항상 해당 하는 경우 파일을 제거 해야 합니다. (*iOS*)\n\n  * `cordova.file.syncedDataDirectory`-(ICloud)를 예를 들어 동기화 해야 하는 응용 프로그램 관련 파일을 보유 하 고 있습니다. (*iOS*)\n\n  * `cordova.file.documentsDirectory`-파일 애플 리 케이 션, 하지만 그 개인은 다른 응용 프로그램 (예: Office 파일)에 의미입니다. (*iOS*)\n\n  * `cordova.file.sharedDirectory`-모든 응용 프로그램 (*블랙베리 10* 에 전세계적으로 사용 가능한 파일)\n\n## 파일 시스템 레이아웃\n\n하지만 구현 세부 사항을 기술적으로 `cordova.file.*` 속성 실제 장치에 실제 경로에 매핑하는 방법을 아는 것이 매우 유용할 수 있습니다.\n\n### iOS 파일 시스템 레이아웃\n\n| 장치 경로                                          | `cordova.file.*`            | `iosExtraFileSystems` | r/w? |   영구?    |    OS 지웁니다    | 동기화 | 개인 |\n|:---------------------------------------------- |:--------------------------- |:--------------------- |:----:|:--------:|:-------------:|:---:|:--:|\n| `/ var/모바일/응용 프로그램/< UUID > /`           | applicationStorageDirectory | -                     |  r   |   N/A    |      N/A      | N/A | 예  |\n| &nbsp;&nbsp;&nbsp;`appname.app/`               | applicationDirectory        | 번들                    |  r   |   N/A    |      N/A      | N/A | 예  |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`www/`     | -                           | -                     |  r   |   N/A    |      N/A      | N/A | 예  |\n| &nbsp;&nbsp;&nbsp;`Documents/`                 | documentsDirectory          | 문서                    | r/w  |    예     |      없음       |  예  | 예  |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`NoCloud/` | -                           | 문서 nosync             | r/w  |    예     |      없음       | 없음  | 예  |\n| &nbsp;&nbsp;&nbsp;`Library`                    | -                           | 라이브러리                 | r/w  |    예     |      없음       | 그래? | 예  |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`NoCloud/` | dataDirectory               | 라이브러리 nosync          | r/w  |    예     |      없음       | 없음  | 예  |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`Cloud/`   | syncedDataDirectory         | -                     | r/w  |    예     |      없음       |  예  | 예  |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`Caches/`  | cacheDirectory              | 캐시                    | r/w  |   예 *    | Yes**\\* | 없음  | 예  |\n| &nbsp;&nbsp;&nbsp;`tmp/`                       | tempDirectory               | -                     | r/w  | No** | Yes**\\* | 없음  | 예  |\n\n\\ * 파일 응용 프로그램 다시 시작 및 업그레이드, 유지 하지만 때마다 OS 욕망이 디렉터리를 지울 수 있습니다. 앱 삭제 될 수 있습니다 모든 콘텐츠를 다시 만들 수 있어야 합니다.\n\n** 파일 응용 프로그램 다시 시작에서 지속 될 수 있습니다 하지만이 동작에 의존 하지 마십시오. 파일 여러 업데이트를 보장 하지 않습니다. 때 해당 앱이이 디렉터리에서 파일을 제거 해야, 이러한 파일을 제거할 때 (또는 경우에도) 운영 체제 보증 하지 않습니다으로.\n\n**\\ * OS 그것이 필요를 느낀다 언제 든 지이 디렉터리의 내용을 취소 수 있습니다 하지만 이것에 의존 하지 마십시오. 이 디렉터리를 응용 프로그램에 대 한 적절 한 선택을 취소 해야 합니다.\n\n### 안 드 로이드 파일 시스템 레이아웃\n\n| 장치 경로                                            | `cordova.file.*`                    | `AndroidExtraFileSystems` | r/w? | 영구? | OS 지웁니다  | 개인 |\n|:------------------------------------------------ |:----------------------------------- |:------------------------- |:----:|:---:|:--------:|:--:|\n| `file:///android_asset/`                         | applicationDirectory                |                           |  r   | N/A |   N/A    | 예  |\n| `/data/데이터/< app id > /`                   | applicationStorageDirectory         | -                         | r/w  | N/A |   N/A    | 예  |\n| &nbsp;&nbsp;&nbsp;`cache`                        | cacheDirectory                      | 캐시                        | r/w  |  예  |  예\\*   | 예  |\n| &nbsp;&nbsp;&nbsp;`files`                        | dataDirectory                       | 파일                        | r/w  |  예  |    없음    | 예  |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`Documents`  |                                     | 문서                        | r/w  |  예  |    없음    | 예  |\n| `< sdcard > /`                             | externalRootDirectory               | sdcard                    | r/w  |  예  |    없음    | 없음 |\n| &nbsp;&nbsp;&nbsp;`Android/data/<app-id>/` | externalApplicationStorageDirectory | -                         | r/w  |  예  |    없음    | 없음 |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`cache`      | externalCacheDirectry               | 외부 캐시                     | r/w  |  예  | 없음** | 없음 |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`files`      | externalDataDirectory               | 파일 외부                     | r/w  |  예  |    없음    | 없음 |\n\n\\ * 운영 체제 정기적으로이 디렉터리 삭제 수 있지만이 동작에 의존 하지 마십시오. 이 응용 프로그램이 디렉터리의 내용을 취소 합니다. 사용자 수동으로 캐시 제거 해야,이 디렉터리의 내용은 제거 됩니다.\n\n** 운영 체제 자동으로;이 디렉터리를 삭제 하지 않습니다 내용을 직접 관리에 대 한 책임이 있습니다. 사용자 수동으로 캐시 제거 합니다, 디렉터리의 내용은 제거 됩니다.\n\n**참고**: 외부 저장소를 탑재할 수 없는 경우 `cordova.file.external*` 속성은 `null`.\n\n### 블랙베리 10 파일 시스템 레이아웃\n\n| 장치 경로                                                       | `cordova.file.*`            | r/w? | 영구? | OS 지웁니다 | 개인 |\n|:----------------------------------------------------------- |:--------------------------- |:----:|:---:|:-------:|:--:|\n| `file:///accounts/1000/appdata/ < app id > /`         | applicationStorageDirectory |  r   | N/A |   N/A   | 예  |\n| &nbsp;&nbsp;&nbsp;`app/native`                              | applicationDirectory        |  r   | N/A |   N/A   | 예  |\n| &nbsp;&nbsp;&nbsp;`data/webviews/webfs/temporary/local__0`  | cacheDirectory              | r/w  | 없음  |    예    | 예  |\n| &nbsp;&nbsp;&nbsp;`data/webviews/webfs/persistent/local__0` | dataDirectory               | r/w  |  예  |   없음    | 예  |\n| `file:///accounts/1000/removable/sdcard`                    | externalRemovableDirectory  | r/w  |  예  |   없음    | 없음 |\n| `file:///accounts/1000/shared`                              | sharedDirectory             | r/w  |  예  |   없음    | 없음 |\n\n*참고*: 모든 경로 /accounts/1000-enterprise를 기준으로 응용 프로그램 경계를 작동 하도록 배포 될 때.\n\n## 안 드 로이드 단점\n\n### 안 드 로이드 영구 저장 위치\n\n안 드 로이드 장치에 영구 파일을 저장할 여러 유효한 위치가 있다. 다양 한 가능성의 광범위 한 토론에 대 한 [이 페이지](http://developer.android.com/guide/topics/data/data-storage.html)를 참조 하십시오.\n\n플러그인의 이전 버전을 시작할 때, 장치는 SD 카드 (또는 해당 스토리지 파티션) 탑재 했다 주장 하는 여부에 따라 임시 및 영구 파일의 위치를 선택 합니다. SD 카드 마운트, 또는 큰 내부 스토리지 파티션에 사용할 수 있었습니다 (같은 넥서스 장치에) 그 후에 영구 파일 공간의 루트에 저장 됩니다. 이 모든 코르 도우 바 애플 리 케이 션 카드에 모두 사용할 수 있는 파일을 볼 수 있는 의미 합니다.\n\nSD 카드는 사용할 수 있는 경우 이전 버전에서 데이터 저장 `/data/data/<packageId>`는 서로 다른 애플 리 케이 션을 분리 하지만 여전히 원인 데이터를 사용자 간에 공유할 수 있습니다.\n\n그것은 지금 내부 파일 저장 위치 또는 응용 프로그램의 `config.xml` 파일에 기본 설정으로 이전 논리를 사용 하 여 파일을 저장할 것인지를 선택할 수 있습니다. 이렇게 하려면 `config.xml`에이 두 줄 중 하나를 추가:\n\n    <preference name=\"AndroidPersistentFileLocation\" value=\"Internal\" />\n    \n    <preference name=\"AndroidPersistentFileLocation\" value=\"Compatibility\" />\n    \n\n이 줄이 없으면 파일 플러그인은 기본적으로 `Compatibility`을 사용 합니다. 기본 태그,이 이러한 값 중 하나가 아닌 경우에 응용 프로그램이 시작 되지 않습니다.\n\n이전 (사전 1.0)을 사용 하는 경우 응용 프로그램 사용자에 게 발송 되었다 이전,이 플러그인의 버전 영구 파일 시스템에 저장 된 파일은 그리고 `Compatibility` 환경 설정을 설정 해야 합니다. \"내부\"의 위치 전환 그들의 응용 프로그램을 업그레이드 기존 사용자의 그들의 장치에 따라 그들의 이전에 저장 된 파일에 액세스할 수 수 있다는 뜻입니다.\n\n경우 응용 프로그램은 새로운, 또는 이전 영구 파일 시스템에 파일을 저장, `Internal` 설정은 일반적으로 권장 됩니다.\n\n### /Android_asset에 대 한 느린 재귀 작업\n\n자산 디렉터리를 나열 하는 것은 안 드 로이드에 정말 느리다입니다. 속도 높일 수 있습니다 하지만, 안 드 로이드 프로젝트의 루트에 `src/android/build-extras.gradle` 를 추가 하 여 최대 (cordova-android@4.0.0 필요 이상).\n\n## iOS 단점\n\n  * `cordova.file.applicationStorageDirectory`읽기 전용; 루트 디렉터리 내에서 파일을 저장 하려고에 실패 합니다. 다른 중 하나를 사용 하 여 `cordova.file.*` iOS에 대해 정의 된 속성 (만 `applicationDirectory` 와 `applicationStorageDirectory` 는 읽기 전용).\n  * `FileReader.readAsText(blob, encoding)` \n      * `encoding`매개 변수는 지원 되지 않습니다, 및 효과에 항상 u t F-8 인코딩을 합니다.\n\n### iOS 영구 저장소 위치\n\nIOS 디바이스에 영구 파일을 저장할 두 개의 유효한 위치가 있다: 문서 디렉터리 및 라이브러리 디렉터리. 플러그인의 이전 버전은 오직 문서 디렉토리에 영구 파일을 저장. 이 부작용 보다는 아니었다 수시로 특히 많은 작은 파일을 처리 하는 응용 프로그램에 대 한 의도, iTunes에 표시 모든 응용 프로그램 파일을 만드는 디렉터리의 용도 내보내기에 대 한 완전 한 문서를 생산 했다.\n\n그것은 지금 문서 또는 응용 프로그램의 `config.xml` 파일에 기본 설정으로 라이브러리 디렉토리에 파일을 저장할 것인지를 선택할 수 있습니다. 이렇게 하려면 `config.xml`에이 두 줄 중 하나를 추가:\n\n    <preference name=\"iosPersistentFileLocation\" value=\"Library\" />\n    \n    <preference name=\"iosPersistentFileLocation\" value=\"Compatibility\" />\n    \n\n이 줄이 없으면 파일 플러그인은 기본적으로 `Compatibility`을 사용 합니다. 기본 태그,이 이러한 값 중 하나가 아닌 경우에 응용 프로그램이 시작 되지 않습니다.\n\n이전 (사전 1.0)을 사용 하는 경우 응용 프로그램 사용자에 게 발송 되었다 이전,이 플러그인의 버전 영구 파일 시스템에 저장 된 파일은 그리고 `Compatibility` 환경 설정을 설정 해야 합니다. `Library`에 위치를 스위칭 기존 사용자에 게 응용 프로그램을 업그레이 드의 그들의 이전에 저장 된 파일에 액세스할 수 것을 의미할 것입니다.\n\n경우 응용 프로그램은 새로운, 또는 이전 영구 파일 시스템에 파일을 저장, `Library` 설정은 일반적으로 권장 됩니다.\n\n## 파이어 폭스 OS 단점\n\n파일 시스템 API Firefox 운영 체제에서 기본적으로 지원 하지 및 indexedDB 위에 심으로 구현 됩니다.\n\n  * 비어 있지 않은 디렉터리를 제거할 때 실패 하지 않습니다.\n  * 디렉터리에 대 한 메타 데이터를 지원 하지 않습니다.\n  * 메서드 `copyTo` 및 `moveTo` 디렉터리를 지원 하지 않습니다\n\n다음 데이터 경로 지원 됩니다: * `applicationDirectory`-`xhr`를 사용 하 여 로컬 파일을 응용 프로그램 패키지를 가져옵니다. * `dataDirectory`-영구 응용 프로그램 특정 데이터 파일에 대 한. * `cacheDirectory`-응용 프로그램 다시 시작 해야 하는 캐시 된 파일 (애플 리 케이 션은 여기에 파일을 삭제 하려면 운영 체제에 의존 하지 말아야).\n\n## 브라우저 만지면\n\n### 일반적인 단점 및 설명\n\n  * 각 브라우저는 샌드박스 자체 파일 시스템을 사용합니다. IE와 파이어 폭스 기반으로 IndexedDB를 사용합니다. 모든 브라우저는 경로에서 디렉터리 구분 기호로 슬래시를 사용합니다.\n  * 디렉터리 항목을 연속적으로 만들 수 있다. 예를 들어 전화 `fs.root.getDirectory ('dir1/dir2 ', {create:true}, successCallback, errorCallback)` d i r 1 존재 하지 않은 경우 실패 합니다.\n  * 플러그인 응용 프로그램 처음 시작할 영구 저장소를 사용 하 여 사용자 권한을 요청 합니다. \n  * 플러그인 지원 `cdvfile://localhost` (로컬 리소스)만. 즉, 외부 리소스는 `cdvfile`를 통해 지원 되지 않습니다..\n  * 플러그인 [\"파일 시스템 API 8.3 명명 제한\"을](http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions) 수행 하지 않습니다..\n  * Blob 및 파일 ' `close` 함수는 지원 되지 않습니다.\n  * `FileSaver` 및 `BlobBuilder`는이 플러그 접속식에 의해 지원 되지 않습니다 그리고 명세서를 필요가 없습니다.\n  * 플러그인 `requestAllFileSystems`를 지원 하지 않습니다. 이 함수는 또한 사양에 빠진.\n  * 사용 하는 경우 디렉터리에서 항목 제거 되지 것입니다 `create: true` 기존 디렉터리에 대 한 플래그.\n  * 생성자를 통해 생성 된 파일은 지원 되지 않습니다. Entry.file 메서드를 대신 사용 해야 합니다.\n  * 각 브라우저 blob URL 참조에 대 한 그것의 자신의 형태를 사용합니다.\n  * `readAsDataURL` 기능을 지원 하지만 크롬에서 mediatype 항목 이름 확장명에 따라 달라 집니다, 그리고 mediatype IE에는 항상 빈 (`텍스트 일반` 사양에 따라 동일), 파이어 폭스에서 mediatype은 항상 `응용 프로그램/8 진수 스트림`. 예를 들어, 콘텐츠는 `abcdefg` 다음 파이어 폭스 반환 `데이터: 응용 프로그램 / 8 진수 스트림; base64, YWJjZGVmZw = =`, 즉 반환 `데이터:; base64, YWJjZGVmZw = =`, 반환 크롬 `데이터: < 항목 이름의 확장에 따라 mediatype >; base64, YWJjZGVmZw = =`.\n  * `toInternalURL` 양식 `file:///persistent/path/to/entry` (파이어 폭스, 인터넷 익스플로러)에서 경로 반환합니다. 크롬 양식 `cdvfile://localhost/persistent/file`에 경로 반환합니다..\n\n### 크롬 특수\n\n  * 크롬 파일 시스템 장치 준비 이벤트 후 즉시 준비 되지 않습니다. 문제를 해결 하려면 `filePluginIsReady` 이벤트를 구독할 수 있습니다. 예를 들어: \n\n```javascript\nwindow.addEventListener('filePluginIsReady', function(){ console.log('File plugin is ready');}, false);\n```\n\n`Window.isFilePluginReadyRaised` 함수를 사용 하 여 이벤트가 이미 발생 여부를 확인할 수 있습니다. -window.requestFileSystem 임시 및 영구 파일 시스템 할당량 크롬에 제한 되지 않습니다. -크롬에서 영구 저장소를 증가 하려면 `window.initPersistentFileSystem` 메서드를 호출 해야 합니다. 영구 저장소 할당량은 기본적으로 5 메가바이트입니다. -크롬 필요 `-허용-파일-액세스-에서-파일` `file:///` 프로토콜을 통해 지원 API 인수를 실행 합니다. -플래그를 사용 하면 `파일` 개체 하지 변경할 수 `{create:true}` 때 기존 `항목`. -행사 `cancelable` 속성이로 설정 된 크롬에서. 이 [사양](http://dev.w3.org/2009/dap/file-system/file-writer.html) 대조적 이다. -크롬에서 `toURL` 함수 반환 합니다 `파일 시스템:`-응용 프로그램 호스트에 따라 경로 앞에. 예를 들어, `filesystem:file:///persistent/somefile.txt`, `filesystem:http://localhost:8080/persistent/somefile.txt`. -`toURL` 함수 결과 디렉터리 항목의 경우에 후행 슬래시를 포함 하지 않습니다. 크롬 하지만 제대로 붙여 슬래시 url이 포함 된 디렉터리 해결합니다. -`resolveLocalFileSystemURL` 메서드 인바운드 `url`을 `파일 시스템` 접두사가 필요 합니다. 예를 들어, `url` 매개 변수 `resolveLocalFileSystemURL`에 대 한 안 드 로이드에서 양식 `file:///persistent/somefile.txt` 반대로 양식 `filesystem:file:///persistent/somefile.txt`에 있어야 합니다. -사용 되지 않는 `toNativeURL` 함수는 지원 되지 않습니다 및 stub에는 없습니다. -`setMetadata` 함수는 규격에 명시 되지 않은 및 지원 되지 않습니다. -INVALID_MODIFICATION_ERR (코드: 9) 대신 throw 됩니다 SYNTAX_ERR(code: 8) 비 existant 파일 시스템의 요청에. -INVALID_MODIFICATION_ERR (코드: 9) 대신 throw 됩니다 PATH_EXISTS_ERR(code: 12) 독점적으로 파일 또는 디렉터리를 만들 려,는 이미 존재 합니다. -INVALID_MODIFICATION_ERR (코드: 9) 대신 throw 됩니다 NO_MODIFICATION_ALLOWED_ERR(code: 6) 루트 파일 시스템에 removeRecursively을 호출 하려고 합니다. -INVALID_MODIFICATION_ERR (코드: 9) 대신 throw 됩니다 NOT_FOUND_ERR(code: 1) moveTo 디렉터리 존재 하지 않는 것을 시도에.\n\n### IndexedDB 기반 구현이 특수 (파이어 폭스와 IE)\n\n  * `.` `.`는 지원 되지 않습니다.\n  * IE `file:///`를 지원 하지 않습니다-모드; 호스트 모드 지원된 (http://localhost:xxxx)입니다.\n  * 파이어 폭스 파일 시스템 크기 제한 이지만 각 50MB 확장 사용자 권한을 요청 합니다. IE10 최대 10 mb 결합 AppCache 및 IndexedDB 묻는 사이트 당 250 mb의 최대 최대 증가 될 수 있도록 하려는 경우 해당 수준에 충돌 한 번 메시지를 표시 하지 않고 파일 시스템의 구현에 사용을 허용 한다. 그래서 `size` 매개 변수 `requestFileSystem` 함수에 대 한 파이어 폭스와 IE에서 파일 시스템 영향을 주지 않습니다.\n  * `readAsBinaryString` 함수 사양에 명시 되지 않은 IE에서 지원 되지 않으며 stub에는 없습니다.\n  * `file.type`은 항상 null입니다.\n  * 하지 항목 삭제 된 DirectoryEntry 인스턴스의 콜백 결과 사용 하 여 만들어야 합니다. 그렇지 않으면, '교수형 항목'을 얻을 것 이다.\n  * 그냥 작성 된 파일을 읽을 수 있는이 파일의 새 인스턴스를 얻으려면 해야 합니다.\n  * `setMetadata` 함수는 사양에 명시 되지 않은 지원 `modificationTime` 필드 변경에만 해당 합니다. \n  * `copyTo` 및 `moveTo` 함수는 디렉터리를 지원 하지 않습니다.\n  * 디렉터리 메타 데이터는 지원 되지 않습니다.\n  * 둘 다 Entry.remove와 directoryEntry.removeRecursively 비어 있지 않은 디렉터리를 제거할 때 실패 하지 않습니다-디렉터리 제거 되는 대신 내용을 함께 청소.\n  * `abort` 및 `truncate` 함수 지원 되지 않습니다.\n  * 진행 이벤트가 발생 하지 합니다. 예를 들어,이 처리기 하지 실행 됩니다.\n\n```javascript\nwriter.onprogress = function() { /*commands*/ };\n```\n\n## 업그레이드 노트\n\n이 플러그인의 v1.0.0에 게시 된 사양에 맞춰 더 많은 것 `FileEntry` 및 `DirectoryEntry` 구조 변경 되었습니다.\n\n플러그인의 이전 (pre-1.0.0) 버전 장치 절대 파일 위치 `Entry` 개체의 `fullPath` 속성에 저장 됩니다. 이러한 경로 일반적으로 같습니다.\n\n    /var/mobile/Applications/<application UUID>/Documents/path/to/file  (iOS)\n    /storage/emulated/0/path/to/file                                    (Android)\n    \n\n이러한 경로 `항목` 개체의 `toURL()` 메서드에서 반환 했다.\n\nV1.0.0, `fullPath` 속성은 *HTML 파일 시스템의 루트에 상대적인* 파일의 경로를. 그래서, 위의 경로 지금 둘 다의 `fullPath`와 `FileEntry` 개체에 의해 표현 될 것 이다\n\n    /path/to/file\n    \n\n응용 프로그램 작동 장치 절대 경로, 이전 `항목` 개체의 `fullPath` 속성을 통해 그 경로 검색 하는 경우에, 당신은 대신 `entry.toURL()`를 사용 하 여 코드를 업데이트 해야 합니다.\n\n대 한 뒤 호환성, `resolveLocalFileSystemURL()` 메서드는 장치-절대-경로 수락 하 고 그 파일 중 `TEMPORARY` 또는 `PERSISTENT` 파일 시스템 내에서 존재 하는 경우, 해당 `Entry` 개체를 반환 합니다.\n\n이 특히 이전 장치 절대 경로 사용 하는 파일 전송 플러그인에 문제가 있다 (그리고 아직도 그들을 받아들일 수.) 그것은 `entry.toURL()`와 `entry.fullPath`를 대체 확인 장치에 파일을 사용 하는 플러그인을 지 고 그래서 파일 시스템 Url와 함께 제대로 작동 하려면 업데이트 되었습니다.\n\nV1.1.0에 `toURL()`의 반환 값 (\\[CB-6394\\] (https://issues.apache.org/jira/browse/CB-6394) 참조)로 바뀌었다 'file://' 절대 URL을 반환. 가능 하다 면. 보장 하는 ' cdvfile:'-URL `toInternalURL()`를 지금 사용할 수 있습니다. 이 메서드 이제 양식의 파일 Url을 반환 합니다.\n\n    cdvfile://localhost/persistent/path/to/file\n    \n\n어떤 파일을 고유 하 게 식별 하려면 사용할 수 있습니다.\n\n## 오류 코드 및 의미의 목록\n\n오류가 throw 됩니다 때 다음 코드 중 하나가 사용 됩니다.\n\n| 코드 | 상수                            |\n| --:|:----------------------------- |\n|  1 | `NOT_FOUND_ERR`               |\n|  2 | `SECURITY_ERR`                |\n|  3 | `ABORT_ERR`                   |\n|  4 | `NOT_READABLE_ERR`            |\n|  5 | `ENCODING_ERR`                |\n|  6 | `NO_MODIFICATION_ALLOWED_ERR` |\n|  7 | `INVALID_STATE_ERR`           |\n|  8 | `SYNTAX_ERR`                  |\n|  9 | `INVALID_MODIFICATION_ERR`    |\n| 10 | `QUOTA_EXCEEDED_ERR`          |\n| 11 | `TYPE_MISMATCH_ERR`           |\n| 12 | `PATH_EXISTS_ERR`             |\n\n## (선택 사항) 플러그인 구성\n\n사용 가능한 파일 시스템의 집합 플랫폼 당 구성된 될 수 있습니다. IOS와 안 드 로이드를 인식 한 <preference> `config.xml` 설치 될 파일 시스템 이름에 태그. 기본적으로 모든 파일 시스템 루트 사용할 수 있습니다.\n\n    <preference name=\"iosExtraFilesystems\" value=\"library,library-nosync,documents,documents-nosync,cache,bundle,root\" />\n    <preference name=\"AndroidExtraFilesystems\" value=\"files,files-external,documents,sdcard,cache,cache-external,root\" />\n    \n\n### 안 드 로이드\n\n  * `files`: 응용 프로그램의 내부 파일 저장 디렉토리\n  * `files-external`: 응용 프로그램의 외부 파일 저장 디렉토리\n  * `sdcard`: 글로벌 외부 파일 저장 디렉토리 (이것은 SD 카드의 루트 설치 된 경우). 이것을 사용 하려면 `android.permission.WRITE_EXTERNAL_STORAGE` 권한이 있어야 합니다.\n  * `cache`: 응용 프로그램의 내부 캐시 디렉터리\n  * `cache-external`: 응용 프로그램의 외부 캐시 디렉터리\n  * `root`: 전체 장치 파일 시스템\n\n안 드 로이드는 또한 \"파일\" 파일 시스템 내에서 \"/ 문서 /\" 하위 디렉토리를 나타내는 \"문서\" 라는 특별 한 파일을 지원 합니다.\n\n### iOS\n\n  * `library`: 응용 프로그램의 라이브러리 디렉터리\n  * `documents`: 응용 프로그램의 문서 디렉토리\n  * `cache`: 응용 프로그램의 캐시 디렉터리\n  * `bundle`: 응용 프로그램의 번들; (읽기 전용) 디스크에 응용 프로그램 자체의 위치\n  * `root`: 전체 장치 파일 시스템\n\n기본적으로 라이브러리 및 문서 디렉토리 iCloud에 동기화 할 수 있습니다. 또한 2 개의 추가적인 파일 시스템, `library-nosync` 및 `documents-nosync`, 내 특별 한 동기화 되지 않은 디렉터리를 대표 하는 요청할 수 있습니다는 `/Library` 또는 `/Documents` 파일 시스템."
  },
  {
    "path": "plugins/cordova-plugin-file/doc/ko/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-file\n\n이 플러그인은 장치에 있는 파일에 대 한 읽기/쓰기 액세스를 허용 하는 파일 API를 구현 합니다.\n\n이 플러그인을 포함 한 몇 가지 사양에 따라: HTML5 파일 API는 <http://www.w3.org/TR/FileAPI/>\n\n(지금은 없어진) 디렉터리와 시스템 확장 최신: <http://www.w3.org/TR/2012/WD-file-system-api-20120417/> 플러그인 코드의 대부분은 때 이전 사양 작성 되었습니다 있지만 현재는: <http://www.w3.org/TR/2011/WD-file-system-api-20110419/>\n\n그것은 또한 FileWriter 사양 구현: <http://dev.w3.org/2009/dap/file-system/file-writer.html>\n\n사용을 참조 하십시오 HTML5 바위 ' 우수한 [파일 시스템 문서.][1]\n\n [1]: http://www.html5rocks.com/en/tutorials/file/filesystem/\n\n다른 저장소 옵션에 대 한 개요, 코르도바의 [저장소 가이드][2] 를 참조합니다.\n\n [2]: http://cordova.apache.org/docs/en/edge/cordova_storage_storage.md.html\n\n이 플러그인 글로벌 `cordova.file` 개체를 정의합니다.\n\n전역 범위에 있지만 그것은 불가능까지 `deviceready` 이벤트 후.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(cordova.file);\n    }\n    \n\n## 설치\n\n    cordova plugin add cordova-plugin-file\n    \n\n## 지원 되는 플랫폼\n\n*   아마존 화재 운영 체제\n*   안 드 로이드\n*   블랙베리 10\n*   Firefox 운영 체제\n*   iOS\n*   Windows Phone 7과 8 *\n*   윈도우 8 *\n*   브라우저\n\n* *`FileReader.readAsArrayBuffer`도 `FileWriter.write(blob)`이 플랫폼을 지원 하지 않습니다.*\n\n## 파일을 저장할 위치를\n\nV1.2.0, 현재 중요 한 파일 시스템 디렉터리에 Url도 제공 됩니다. 각 URL 형태 *file:///path/to/spot/* 이며 `DirectoryEntry` `window.resolveLocalFileSystemURL()`를 사용 하 여 변환할 수 있습니다..\n\n*   `cordova.file.applicationDirectory`-읽기 전용 디렉터리는 응용 프로그램을 설치 합니다. (*iOS*, *안 드 로이드*, *블랙베리 10*)\n\n*   `cordova.file.applicationStorageDirectory`응용 프로그램의 샌드박스;의 루트 디렉터리 iOS에이 위치에는 읽기 전용 (특정 하위 디렉토리만 [같은 `/Documents` ]은 읽기 / 쓰기). 포함 된 모든 데이터는 응용 프로그램에 전용. ( *iOS*, *안 드 로이드*, *블랙베리 10*)\n\n*   `cordova.file.dataDirectory`-내부 메모리를 사용 하 여 응용 프로그램의 샌드박스 내에서 영구 및 개인 데이터 스토리지 (안 드 로이드, 외부 메모리를 사용 해야 하는 경우 사용 하 여 `.externalDataDirectory` ). IOS에이 디렉터리 iCloud와 동기화 되지 되 (를 사용 하 여 `.syncedDataDirectory` ). (*iOS*, *안 드 로이드*, *블랙베리 10*)\n\n*   `cordova.file.cacheDirectory`-디렉터리 캐시 데이터 파일 또는 모든 파일을 당신의 app를 다시 쉽게 만들 수 있습니다. 운영 체제 장치 저장소 부족 하면 이러한 파일을 삭제할 수 있습니다, 그리고 그럼에도 불구 하 고, 애플 리 케이 션 여기에 파일을 삭제 하려면 운영 체제에 의존 하지 말아야 합니다. (*iOS*, *안 드 로이드*, *블랙베리 10*)\n\n*   `cordova.file.externalApplicationStorageDirectory`-응용 프로그램 외부 저장 공간입니다. (*안 드 로이드*)\n\n*   `cordova.file.externalDataDirectory`-외부 저장소에 응용 프로그램 특정 데이터 파일을 넣어 어디. (*안 드 로이드*)\n\n*   `cordova.file.externalCacheDirectory`외부 저장소에 응용 프로그램 캐시입니다. (*안 드 로이드*)\n\n*   `cordova.file.externalRootDirectory`-외부 저장 (SD 카드) 루트입니다. (*안 드 로이드*, *블랙베리 10*)\n\n*   `cordova.file.tempDirectory`-운영 체제에서 지울 수 있습니다 임시 디렉터리 것입니다. 이 디렉터리;를 운영 체제에 의존 하지 마십시오 귀하의 응용 프로그램 항상 해당 하는 경우 파일을 제거 해야 합니다. (*iOS*)\n\n*   `cordova.file.syncedDataDirectory`-(ICloud)를 예를 들어 동기화 해야 하는 응용 프로그램 관련 파일을 보유 하 고 있습니다. (*iOS*)\n\n*   `cordova.file.documentsDirectory`-파일 애플 리 케이 션, 하지만 그 개인은 다른 응용 프로그램 (예: Office 파일)에 의미입니다. (*iOS*)\n\n*   `cordova.file.sharedDirectory`-모든 응용 프로그램 (*블랙베리 10* 에 전세계적으로 사용 가능한 파일)\n\n## 파일 시스템 레이아웃\n\n하지만 구현 세부 사항을 기술적으로 `cordova.file.*` 속성 실제 장치에 실제 경로에 매핑하는 방법을 아는 것이 매우 유용할 수 있습니다.\n\n### iOS 파일 시스템 레이아웃\n\n| 장치 경로                                | `cordova.file.*`            | `iosExtraFileSystems` | r/w? |  영구?   |  OS 지웁니다  | 동기화 | 개인 |\n|:------------------------------------ |:--------------------------- |:--------------------- |:----:|:------:|:---------:|:---:|:--:|\n| `/ var/모바일/응용 프로그램/< UUID > /` | applicationStorageDirectory | -                     |  r   |  N/A   |    N/A    | N/A | 예  |\n|    `appname.app/`                    | applicationDirectory        | 번들                    |  r   |  N/A   |    N/A    | N/A | 예  |\n|       `www/`                         | -                           | -                     |  r   |  N/A   |    N/A    | N/A | 예  |\n|    `Documents/`                      | documentsDirectory          | 문서                    | r/w  |   예    |    없음     |  예  | 예  |\n|       `NoCloud/`                     | -                           | 문서 nosync             | r/w  |   예    |    없음     | 없음  | 예  |\n|    `Library`                         | -                           | 라이브러리                 | r/w  |   예    |    없음     | 그래? | 예  |\n|       `NoCloud/`                     | dataDirectory               | 라이브러리 nosync          | r/w  |   예    |    없음     | 없음  | 예  |\n|       `Cloud/`                       | syncedDataDirectory         | -                     | r/w  |   예    |    없음     |  예  | 예  |\n|       `Caches/`                      | cacheDirectory              | 캐시                    | r/w  |  예 *   | 예 * * *| | 없음  | 예  |\n|    `tmp/`                            | tempDirectory               | -                     | r/w  | 아니 * * | 예 * * *| | 없음  | 예  |\n\n* 파일 응용 프로그램 다시 시작 및 업그레이드, 유지 하지만 OS 욕망 언제 든 지이 디렉터리를 지울 수 있습니다. 앱 삭제 될 수 있습니다 모든 콘텐츠를 다시 만들 수 있어야 합니다.\n\n* * 파일 응용 프로그램 다시 시작에서 지속 될 수 있습니다 하지만이 동작에 의존 하지 마십시오. 파일 여러 업데이트를 보장 하지 않습니다. 때 해당 앱이이 디렉터리에서 파일을 제거 해야, 이러한 파일을 제거할 때 (또는 경우에도) 운영 체제 보증 하지 않습니다으로.\n\n* * *| OS 그것이 필요를 느낀다 언제 든 지이 디렉터리의 내용을 취소 될 수 있습니다 하지만 이것에 의존 하지 마십시오. 이 디렉터리를 응용 프로그램에 대 한 적절 한 선택을 취소 해야 합니다.\n\n### 안 드 로이드 파일 시스템 레이아웃\n\n| 장치 경로                             | `cordova.file.*`                    | `AndroidExtraFileSystems` | r/w? | 영구? | OS 지웁니다 | 개인 |\n|:--------------------------------- |:----------------------------------- |:------------------------- |:----:|:---:|:-------:|:--:|\n| `file:///android_asset/`          | applicationDirectory                |                           |  r   | N/A |   N/A   | 예  |\n| `/data/데이터/< app id > /`    | applicationStorageDirectory         | -                         | r/w  | N/A |   N/A   | 예  |\n|    `cache`                        | cacheDirectory                      | 캐시                        | r/w  |  예  |   예 *   | 예  |\n|    `files`                        | dataDirectory                       | 파일                        | r/w  |  예  |   없음    | 예  |\n|       `Documents`                 |                                     | 문서                        | r/w  |  예  |   없음    | 예  |\n| `< sdcard > /`              | externalRootDirectory               | sdcard                    | r/w  |  예  |   없음    | 없음 |\n|    `Android/data/<app-id>/` | externalApplicationStorageDirectory | -                         | r/w  |  예  |   없음    | 없음 |\n|       `cache`                     | externalCacheDirectry               | 외부 캐시                     | r/w  |  예  | 아니 * *  | 없음 |\n|       `files`                     | externalDataDirectory               | 파일 외부                     | r/w  |  예  |   없음    | 없음 |\n\n* OS 수 있습니다 정기적으로이 디렉터리에 있지만이 동작에 의존 하지 마십시오. 이 응용 프로그램이 디렉터리의 내용을 취소 합니다. 사용자 수동으로 캐시 제거 해야,이 디렉터리의 내용은 제거 됩니다.\n\n* * OS 지워지지 않습니다이 디렉터리 자동으로; 콘텐츠를 관리 하기 위한 책임이 있습니다. 사용자 수동으로 캐시 제거 합니다, 디렉터리의 내용은 제거 됩니다.\n\n**참고**: 외부 저장소를 탑재할 수 없는 경우 `cordova.file.external*` 속성은 `null`.\n\n### 블랙베리 10 파일 시스템 레이아웃\n\n| 장치 경로                                               | `cordova.file.*`            | r/w? | 영구? | OS 지웁니다 | 개인 |\n|:--------------------------------------------------- |:--------------------------- |:----:|:---:|:-------:|:--:|\n| `file:///accounts/1000/appdata/ < app id > /` | applicationStorageDirectory |  r   | N/A |   N/A   | 예  |\n|    `app/native`                                     | applicationDirectory        |  r   | N/A |   N/A   | 예  |\n|    `data/webviews/webfs/temporary/local__0`         | cacheDirectory              | r/w  | 없음  |    예    | 예  |\n|    `data/webviews/webfs/persistent/local__0`        | dataDirectory               | r/w  |  예  |   없음    | 예  |\n| `file:///accounts/1000/removable/sdcard`            | externalRemovableDirectory  | r/w  |  예  |   없음    | 없음 |\n| `file:///accounts/1000/shared`                      | sharedDirectory             | r/w  |  예  |   없음    | 없음 |\n\n*참고*: 모든 경로 /accounts/1000-enterprise를 기준으로 응용 프로그램 경계를 작동 하도록 배포 될 때.\n\n## 안 드 로이드 단점\n\n### 안 드 로이드 영구 저장 위치\n\n안 드 로이드 장치에 영구 파일을 저장할 여러 유효한 위치가 있다. 다양 한 가능성의 광범위 한 토론에 대 한 [이 페이지][3]를 참조 하십시오.\n\n [3]: http://developer.android.com/guide/topics/data/data-storage.html\n\n플러그인의 이전 버전을 시작할 때, 장치는 SD 카드 (또는 해당 스토리지 파티션) 탑재 했다 주장 하는 여부에 따라 임시 및 영구 파일의 위치를 선택 합니다. SD 카드 마운트, 또는 큰 내부 스토리지 파티션에 사용할 수 있었습니다 (같은 넥서스 장치에) 그 후에 영구 파일 공간의 루트에 저장 됩니다. 이 모든 코르 도우 바 애플 리 케이 션 카드에 모두 사용할 수 있는 파일을 볼 수 있는 의미 합니다.\n\nSD 카드는 사용할 수 있는 경우 이전 버전에서 데이터 저장 `/data/data/<packageId>`는 서로 다른 애플 리 케이 션을 분리 하지만 여전히 원인 데이터를 사용자 간에 공유할 수 있습니다.\n\n그것은 지금 내부 파일 저장 위치 또는 응용 프로그램의 `config.xml` 파일에 기본 설정으로 이전 논리를 사용 하 여 파일을 저장할 것인지를 선택할 수 있습니다. 이렇게 하려면 `config.xml`에이 두 줄 중 하나를 추가:\n\n    <preference name=\"AndroidPersistentFileLocation\" value=\"Internal\" />\n    \n    <preference name=\"AndroidPersistentFileLocation\" value=\"Compatibility\" />\n    \n\n이 줄이 없으면 파일 플러그인은 기본적으로 `Compatibility`을 사용 합니다. 기본 태그,이 이러한 값 중 하나가 아닌 경우에 응용 프로그램이 시작 되지 않습니다.\n\n이전 (사전 1.0)을 사용 하는 경우 응용 프로그램 사용자에 게 발송 되었다 이전,이 플러그인의 버전 영구 파일 시스템에 저장 된 파일은 그리고 `Compatibility` 환경 설정을 설정 해야 합니다. \"내부\"의 위치 전환 그들의 응용 프로그램을 업그레이드 기존 사용자의 그들의 장치에 따라 그들의 이전에 저장 된 파일에 액세스할 수 수 있다는 뜻입니다.\n\n경우 응용 프로그램은 새로운, 또는 이전 영구 파일 시스템에 파일을 저장, `Internal` 설정은 일반적으로 권장 됩니다.\n\n## iOS 단점\n\n*   `cordova.file.applicationStorageDirectory`읽기 전용; 루트 디렉터리 내에서 파일을 저장 하려고에 실패 합니다. 다른 중 하나를 사용 하 여 `cordova.file.*` iOS에 대해 정의 된 속성 (만 `applicationDirectory` 와 `applicationStorageDirectory` 는 읽기 전용).\n*   `FileReader.readAsText(blob, encoding)` \n    *   `encoding`매개 변수는 지원 되지 않습니다, 및 효과에 항상 u t F-8 인코딩을 합니다.\n\n### iOS 영구 저장소 위치\n\nIOS 디바이스에 영구 파일을 저장할 두 개의 유효한 위치가 있다: 문서 디렉터리 및 라이브러리 디렉터리. 플러그인의 이전 버전은 오직 문서 디렉토리에 영구 파일을 저장. 이 부작용 보다는 아니었다 수시로 특히 많은 작은 파일을 처리 하는 응용 프로그램에 대 한 의도, iTunes에 표시 모든 응용 프로그램 파일을 만드는 디렉터리의 용도 내보내기에 대 한 완전 한 문서를 생산 했다.\n\n그것은 지금 문서 또는 응용 프로그램의 `config.xml` 파일에 기본 설정으로 라이브러리 디렉토리에 파일을 저장할 것인지를 선택할 수 있습니다. 이렇게 하려면 `config.xml`에이 두 줄 중 하나를 추가:\n\n    <preference name=\"iosPersistentFileLocation\" value=\"Library\" />\n    \n    <preference name=\"iosPersistentFileLocation\" value=\"Compatibility\" />\n    \n\n이 줄이 없으면 파일 플러그인은 기본적으로 `Compatibility`을 사용 합니다. 기본 태그,이 이러한 값 중 하나가 아닌 경우에 응용 프로그램이 시작 되지 않습니다.\n\n이전 (사전 1.0)을 사용 하는 경우 응용 프로그램 사용자에 게 발송 되었다 이전,이 플러그인의 버전 영구 파일 시스템에 저장 된 파일은 그리고 `Compatibility` 환경 설정을 설정 해야 합니다. `Library`에 위치를 스위칭 기존 사용자에 게 응용 프로그램을 업그레이 드의 그들의 이전에 저장 된 파일에 액세스할 수 것을 의미할 것입니다.\n\n경우 응용 프로그램은 새로운, 또는 이전 영구 파일 시스템에 파일을 저장, `Library` 설정은 일반적으로 권장 됩니다.\n\n## 파이어 폭스 OS 단점\n\n파일 시스템 API Firefox 운영 체제에서 기본적으로 지원 하지 및 indexedDB 위에 심으로 구현 됩니다.\n\n*   비어 있지 않은 디렉터리를 제거할 때 실패 하지 않습니다.\n*   디렉터리에 대 한 메타 데이터를 지원 하지 않습니다.\n*   메서드 `copyTo` 및 `moveTo` 디렉터리를 지원 하지 않습니다\n\n다음 데이터 경로 지원 됩니다: * `applicationDirectory`-`xhr`를 사용 하 여 로컬 파일을 응용 프로그램 패키지를 가져옵니다. * `dataDirectory`-영구 응용 프로그램 특정 데이터 파일에 대 한. * `cacheDirectory`-응용 프로그램 다시 시작 해야 하는 캐시 된 파일 (애플 리 케이 션은 여기에 파일을 삭제 하려면 운영 체제에 의존 하지 말아야).\n\n## 브라우저 만지면\n\n### 일반적인 단점 및 설명\n\n*   각 브라우저는 샌드박스 자체 파일 시스템을 사용합니다. IE와 파이어 폭스 기반으로 IndexedDB를 사용합니다. 모든 브라우저는 경로에서 디렉터리 구분 기호로 슬래시를 사용합니다.\n*   디렉터리 항목을 연속적으로 만들 수 있다. 예를 들어 전화 `fs.root.getDirectory ('dir1/dir2 ', {create:true}, successCallback, errorCallback)` d i r 1 존재 하지 않은 경우 실패 합니다.\n*   플러그인 응용 프로그램 처음 시작할 영구 저장소를 사용 하 여 사용자 권한을 요청 합니다. \n*   플러그인 지원 `cdvfile://localhost` (로컬 리소스)만. 즉, 외부 리소스는 `cdvfile`를 통해 지원 되지 않습니다..\n*   플러그인 [\"파일 시스템 API 8.3 명명 제한\"을][4] 수행 하지 않습니다..\n*   Blob 및 파일 ' `close` 함수는 지원 되지 않습니다.\n*   `FileSaver` 및 `BlobBuilder`는이 플러그 접속식에 의해 지원 되지 않습니다 그리고 명세서를 필요가 없습니다.\n*   플러그인 `requestAllFileSystems`를 지원 하지 않습니다. 이 함수는 또한 사양에 빠진.\n*   사용 하는 경우 디렉터리에서 항목 제거 되지 것입니다 `create: true` 기존 디렉터리에 대 한 플래그.\n*   생성자를 통해 생성 된 파일은 지원 되지 않습니다. Entry.file 메서드를 대신 사용 해야 합니다.\n*   각 브라우저 blob URL 참조에 대 한 그것의 자신의 형태를 사용합니다.\n*   `readAsDataURL` 기능을 지원 하지만 크롬에서 mediatype 항목 이름 확장명에 따라 달라 집니다, 그리고 mediatype IE에는 항상 빈 (`텍스트 일반` 사양에 따라 동일), 파이어 폭스에서 mediatype은 항상 `응용 프로그램/8 진수 스트림`. 예를 들어, 콘텐츠는 `abcdefg` 다음 파이어 폭스 반환 `데이터: 응용 프로그램 / 8 진수 스트림; base64, YWJjZGVmZw = =`, 즉 반환 `데이터:; base64, YWJjZGVmZw = =`, 반환 크롬 `데이터: < 항목 이름의 확장에 따라 mediatype >; base64, YWJjZGVmZw = =`.\n*   `toInternalURL` 양식 `file:///persistent/path/to/entry` (파이어 폭스, 인터넷 익스플로러)에서 경로 반환합니다. 크롬 양식 `cdvfile://localhost/persistent/file`에 경로 반환합니다..\n\n [4]: http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions\n\n### 크롬 특수\n\n*   크롬 파일 시스템 장치 준비 이벤트 후 즉시 준비 되지 않습니다. 문제를 해결 하려면 `filePluginIsReady` 이벤트를 구독할 수 있습니다. 예를 들어: \n\n    javascript\n    window.addEventListener('filePluginIsReady', function(){ console.log('File plugin is ready');}, false);\n    \n\n`Window.isFilePluginReadyRaised` 함수를 사용 하 여 이벤트가 이미 발생 여부를 확인할 수 있습니다. -window.requestFileSystem 임시 및 영구 파일 시스템 할당량 크롬에 제한 되지 않습니다. -크롬에서 영구 저장소를 증가 하려면 `window.initPersistentFileSystem` 메서드를 호출 해야 합니다. 영구 저장소 할당량은 기본적으로 5 메가바이트입니다. -크롬 필요 `-허용-파일-액세스-에서-파일` `file:///` 프로토콜을 통해 지원 API 인수를 실행 합니다. -플래그를 사용 하면 `파일` 개체 하지 변경할 수 `{create:true}` 때 기존 `항목`. -행사 `cancelable` 속성이로 설정 된 크롬에서. 이 [사양][5] 대조적 이다. -크롬에서 `toURL` 함수 반환 합니다 `파일 시스템:`-응용 프로그램 호스트에 따라 경로 앞에. 예를 들어, `filesystem:file:///persistent/somefile.txt`, `filesystem:http://localhost:8080/persistent/somefile.txt`. -`toURL` 함수 결과 디렉터리 항목의 경우에 후행 슬래시를 포함 하지 않습니다. 크롬 하지만 제대로 붙여 슬래시 url이 포함 된 디렉터리 해결합니다. -`resolveLocalFileSystemURL` 메서드 인바운드 `url`을 `파일 시스템` 접두사가 필요 합니다. 예를 들어, `url` 매개 변수 `resolveLocalFileSystemURL`에 대 한 안 드 로이드에서 양식 `file:///persistent/somefile.txt` 반대로 양식 `filesystem:file:///persistent/somefile.txt`에 있어야 합니다. -사용 되지 않는 `toNativeURL` 함수는 지원 되지 않습니다 및 stub에는 없습니다. -`setMetadata` 함수는 규격에 명시 되지 않은 및 지원 되지 않습니다. -INVALID_MODIFICATION_ERR (코드: 9) 대신 throw 됩니다 SYNTAX_ERR(code: 8) 비 existant 파일 시스템의 요청에. -INVALID_MODIFICATION_ERR (코드: 9) 대신 throw 됩니다 PATH_EXISTS_ERR(code: 12) 독점적으로 파일 또는 디렉터리를 만들 려,는 이미 존재 합니다. -INVALID_MODIFICATION_ERR (코드: 9) 대신 throw 됩니다 NO_MODIFICATION_ALLOWED_ERR(code: 6) 루트 파일 시스템에 removeRecursively을 호출 하려고 합니다. -INVALID_MODIFICATION_ERR (코드: 9) 대신 throw 됩니다 NOT_FOUND_ERR(code: 1) moveTo 디렉터리 존재 하지 않는 것을 시도에.\n\n [5]: http://dev.w3.org/2009/dap/file-system/file-writer.html\n\n### IndexedDB 기반 구현이 특수 (파이어 폭스와 IE)\n\n*   `.` `.`는 지원 되지 않습니다.\n*   IE `file:///`를 지원 하지 않습니다-모드; 호스트 모드 지원된 (http://localhost:xxxx)입니다.\n*   파이어 폭스 파일 시스템 크기 제한 이지만 각 50MB 확장 사용자 권한을 요청 합니다. IE10 최대 10 mb 결합 AppCache 및 IndexedDB 묻는 사이트 당 250 mb의 최대 최대 증가 될 수 있도록 하려는 경우 해당 수준에 충돌 한 번 메시지를 표시 하지 않고 파일 시스템의 구현에 사용을 허용 한다. 그래서 `size` 매개 변수 `requestFileSystem` 함수에 대 한 파이어 폭스와 IE에서 파일 시스템 영향을 주지 않습니다.\n*   `readAsBinaryString` 함수 사양에 명시 되지 않은 IE에서 지원 되지 않으며 stub에는 없습니다.\n*   `file.type`은 항상 null입니다.\n*   하지 항목 삭제 된 DirectoryEntry 인스턴스의 콜백 결과 사용 하 여 만들어야 합니다. 그렇지 않으면, '교수형 항목'을 얻을 것 이다.\n*   그냥 작성 된 파일을 읽을 수 있는이 파일의 새 인스턴스를 얻으려면 해야 합니다.\n*   `setMetadata` 함수는 사양에 명시 되지 않은 지원 `modificationTime` 필드 변경에만 해당 합니다. \n*   `copyTo` 및 `moveTo` 함수는 디렉터리를 지원 하지 않습니다.\n*   디렉터리 메타 데이터는 지원 되지 않습니다.\n*   둘 다 Entry.remove와 directoryEntry.removeRecursively 비어 있지 않은 디렉터리를 제거할 때 실패 하지 않습니다-디렉터리 제거 되는 대신 내용을 함께 청소.\n*   `abort` 및 `truncate` 함수 지원 되지 않습니다.\n*   진행 이벤트가 발생 하지 합니다. 예를 들어,이 처리기 하지 실행 됩니다.\n\n    javascript\n    writer.onprogress = function() { /*commands*/ };\n    \n\n## 업그레이드 노트\n\n이 플러그인의 v1.0.0에 게시 된 사양에 맞춰 더 많은 것 `FileEntry` 및 `DirectoryEntry` 구조 변경 되었습니다.\n\n플러그인의 이전 (pre-1.0.0) 버전 장치 절대 파일 위치 `Entry` 개체의 `fullPath` 속성에 저장 됩니다. 이러한 경로 일반적으로 같습니다.\n\n    /var/mobile/Applications/<application UUID>/Documents/path/to/file  (iOS)\n    /storage/emulated/0/path/to/file                                    (Android)\n    \n\n이러한 경로 `항목` 개체의 `toURL()` 메서드에서 반환 했다.\n\nV1.0.0, `fullPath` 속성은 *HTML 파일 시스템의 루트에 상대적인* 파일의 경로를. 그래서, 위의 경로 지금 둘 다의 `fullPath`와 `FileEntry` 개체에 의해 표현 될 것 이다\n\n    /path/to/file\n    \n\n응용 프로그램 작동 장치 절대 경로, 이전 `항목` 개체의 `fullPath` 속성을 통해 그 경로 검색 하는 경우에, 당신은 대신 `entry.toURL()`를 사용 하 여 코드를 업데이트 해야 합니다.\n\n대 한 뒤 호환성, `resolveLocalFileSystemURL()` 메서드는 장치-절대-경로 수락 하 고 그 파일 중 `TEMPORARY` 또는 `PERSISTENT` 파일 시스템 내에서 존재 하는 경우, 해당 `Entry` 개체를 반환 합니다.\n\n이 특히 이전 장치 절대 경로 사용 하는 파일 전송 플러그인에 문제가 있다 (그리고 아직도 그들을 받아들일 수.) 그것은 `entry.toURL()`와 `entry.fullPath`를 대체 확인 장치에 파일을 사용 하는 플러그인을 지 고 그래서 파일 시스템 Url와 함께 제대로 작동 하려면 업데이트 되었습니다.\n\nV1.1.0에 `toURL()`의 반환 값 (\\[CB-6394\\] (https://issues.apache.org/jira/browse/CB-6394) 참조)로 바뀌었다 'file://' 절대 URL을 반환. 가능 하다 면. 보장 하는 ' cdvfile:'-URL `toInternalURL()`를 지금 사용할 수 있습니다. 이 메서드 이제 양식의 파일 Url을 반환 합니다.\n\n    cdvfile://localhost/persistent/path/to/file\n    \n\n어떤 파일을 고유 하 게 식별 하려면 사용할 수 있습니다.\n\n## 오류 코드 및 의미의 목록\n\n오류가 throw 됩니다 때 다음 코드 중 하나가 사용 됩니다.\n\n| 코드 | 상수                            |\n| --:|:----------------------------- |\n|  1 | `NOT_FOUND_ERR`               |\n|  2 | `SECURITY_ERR`                |\n|  3 | `ABORT_ERR`                   |\n|  4 | `NOT_READABLE_ERR`            |\n|  5 | `ENCODING_ERR`                |\n|  6 | `NO_MODIFICATION_ALLOWED_ERR` |\n|  7 | `INVALID_STATE_ERR`           |\n|  8 | `SYNTAX_ERR`                  |\n|  9 | `INVALID_MODIFICATION_ERR`    |\n| 10 | `QUOTA_EXCEEDED_ERR`          |\n| 11 | `TYPE_MISMATCH_ERR`           |\n| 12 | `PATH_EXISTS_ERR`             |\n\n## (선택 사항) 플러그인 구성\n\n사용 가능한 파일 시스템의 집합 플랫폼 당 구성된 될 수 있습니다. IOS와 안 드 로이드를 인식 한 <preference> `config.xml` 설치 될 파일 시스템 이름에 태그. 기본적으로 모든 파일 시스템 루트 사용할 수 있습니다.\n\n    <preference name=\"iosExtraFilesystems\" value=\"library,library-nosync,documents,documents-nosync,cache,bundle,root\" />\n    <preference name=\"AndroidExtraFilesystems\" value=\"files,files-external,documents,sdcard,cache,cache-external,root\" />\n    \n\n### 안 드 로이드\n\n*   `files`: 응용 프로그램의 내부 파일 저장 디렉토리\n*   `files-external`: 응용 프로그램의 외부 파일 저장 디렉토리\n*   `sdcard`: 글로벌 외부 파일 저장 디렉토리 (이것은 SD 카드의 루트 설치 된 경우). 이것을 사용 하려면 `android.permission.WRITE_EXTERNAL_STORAGE` 권한이 있어야 합니다.\n*   `cache`: 응용 프로그램의 내부 캐시 디렉터리\n*   `cache-external`: 응용 프로그램의 외부 캐시 디렉터리\n*   `root`: 전체 장치 파일 시스템\n\n안 드 로이드는 또한 \"파일\" 파일 시스템 내에서 \"/ 문서 /\" 하위 디렉토리를 나타내는 \"문서\" 라는 특별 한 파일을 지원 합니다.\n\n### iOS\n\n*   `library`: 응용 프로그램의 라이브러리 디렉터리\n*   `documents`: 응용 프로그램의 문서 디렉토리\n*   `cache`: 응용 프로그램의 캐시 디렉터리\n*   `bundle`: 응용 프로그램의 번들; (읽기 전용) 디스크에 응용 프로그램 자체의 위치\n*   `root`: 전체 장치 파일 시스템\n\n기본적으로 라이브러리 및 문서 디렉토리 iCloud에 동기화 할 수 있습니다. 또한 2 개의 추가적인 파일 시스템, `library-nosync` 및 `documents-nosync`, 내 특별 한 동기화 되지 않은 디렉터리를 대표 하는 요청할 수 있습니다는 `/Library` 또는 `/Documents` 파일 시스템.\n"
  },
  {
    "path": "plugins/cordova-plugin-file/doc/ko/plugins.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# 플러그인 개발자를 위한 노트\n\n이 노트는 주로 파일 플러그인을 사용 하 여 파일 시스템 플러그인 인터페이스를 작성 하 고 싶은 안 드 로이드와 iOS 개발자를 위한 것입니다.\n\n## 코르 도우 바 파일 시스템 Url 사용\n\n버전 1.0.0, 이후이 플러그인과 Url 사용 하고있다는 `cdvfile` 교량, 모든 통신에 대 한 제도 보다는 자바 원시 장치 파일 시스템 경로 노출.\n\n자바 스크립트 측면에서 즉 그 FileEntry 및 DirectoryEntry 개체 fullPath 속성을 HTML 파일 시스템의 루트에 상대적입니다. FileEntry 또는 DirectoryEntry 개체를 수락 하는 플러그인의 자바 API를 호출 해야 `.toURL()` 다리에 걸쳐 네이티브 코드에 전달 하기 전에 해당 개체에.\n\n### Cdvfile 변환: / / fileystem 경로 Url\n\n플러그인 파일 시스템을 작성 하는 실제 파일 시스템 위치에 받은 파일 시스템 URL을 변환 할 수 있습니다. 이렇게, 네이티브 플랫폼에 따라 여러 방법이 있다.\n\n기억 하는 것이 중요 하다 모든 `cdvfile://` Url은 실제 파일 장치에 매핑. 일부 Url 파일에 의해 표현 되지 않는 또는 심지어 원격 리소스를 참조할 수 있는 장치에 자산을 참조할 수 있습니다. 이러한 가능성 때문에 플러그인 경로를 Url을 변환 하려고 할 때 다시 의미 있는 결과 얻을 지 여부를 항상 테스트 해야 합니다.\n\n#### 안 드 로이드\n\n안 드 로이드, 변환 하는 간단한 방법에는 `cdvfile://` URL을 파일 시스템 경로 사용 하는 `org.apache.cordova.CordovaResourceApi` . `CordovaResourceApi`처리할 수 있는 여러 가지 방법에는 `cdvfile://` Url:\n\n    webView 플러그인 클래스 CordovaResourceApi resourceApi의 멤버인 = webView.getResourceApi();\n    \n    장치에이 파일을 나타내는 file:/// URL 얻기 / / 같은 URL 변경 파일 Uri fileURL에 매핑할 수 없는 경우 또는 = resourceApi.remapUri(Uri.parse(cdvfileURL));\n    \n\n그것은 또한 파일 플러그인을 직접 사용할 수 있습니다:\n\n    가져오기 org.apache.cordova.file.FileUtils;\n    가져오기 org.apache.cordova.file.FileSystem;\n    가져오기 java.net.MalformedURLException;\n    \n    플러그인 관리자에서 파일 플러그인을 얻을 FileUtils filePlugin = (FileUtils)webView.pluginManager.getPlugin(\"File\");\n    \n    그것 시도 대 한 경로 얻을 URL을 감안할 때, {문자열 경로 = filePlugin.filesystemPathForURL(cdvfileURL);} catch (MalformedURLException e) {/ / 파일 시스템 url 인식 되지 않았습니다}\n    \n\n경로를 변환 하는 `cdvfile://` URL:\n\n    가져오기 org.apache.cordova.file.LocalFilesystemURL;\n    \n    장치 경로 대 한 LocalFilesystemURL 개체를 가져오기 / / cdvfile URL로 나타낼 수 없는 경우 null.\n    LocalFilesystemURL url = filePlugin.filesystemURLforLocalPath(path);\n    URL 개체 문자열 cdvfileURL의 문자열 표현을 = url.toString();\n    \n\n플러그인 파일을 만들고 그것에 대 한 FileEntry 개체를 반환 하려면, 파일 플러그인을 사용.\n\n    JSON 구조를 JavaScript에 반환을 위한 적당 한 반환 / /이 파일은 cdvfile URL로 표현 하는 경우 null.\n    JSONObject 항목 = filePlugin.getEntryForFile(file);\n    \n\n#### iOS\n\nIOS에서 코르도바 같은 사용 하지 않는 `CordovaResourceApi` 안 드 로이드 개념. Ios, Url 및 파일 시스템 경로 사이 변환 파일 플러그인을 사용 해야 합니다.\n\n    URL 문자열 CDVFilesystemURL * url에서 CDVFilesystem URL 개체를 가져오기 = [CDVFilesystemURL fileSystemURLWithString:cdvfileURL];\n    파일 NSString * 경로에 매핑할 수 없는 경우 URL 개체 또는 없음에 대 한 경로 얻을 = [filePlugin filesystemPathForURL:url];\n    \n    \n    장치 경로 대 한 CDVFilesystem URL 개체를 가져오기 또는 / / 없음 cdvfile URL로 나타낼 수 없는 경우.\n    CDVFilesystemURL * url = [filePlugin fileSystemURLforLocalPath:path];\n    URL 개체 NSString * cdvfileURL의 문자열 표현을 = [url absoluteString];\n    \n\n플러그인 파일을 만들고 그것에 대 한 FileEntry 개체를 반환 하려면, 파일 플러그인을 사용.\n\n    장치 경로 대 한 CDVFilesystem URL 개체를 가져오기 또는 / / 없음 cdvfile URL로 나타낼 수 없는 경우.\n    CDVFilesystemURL * url = [filePlugin fileSystemURLforLocalPath:path];\n    자바 스크립트 NSDictionary * 항목으로 돌아가려면 구조를 얻을 = [filePlugin makeEntryForLocalURL:url]\n    \n\n#### 자바 스크립트\n\n자바 스크립트에는 `cdvfile://` FileEntry 또는 DirectoryEntry 개체에서 URL 호출 `.toURL()` 그것에:\n\n    var cdvfileURL = entry.toURL();\n    \n\n플러그인 응답 처리기에서 실제 항목 개체로 반환 된 FileEntry 구조에서 변환 처리기 코드 해야 파일 플러그인 가져오고 새 개체를 만들:\n\n    적절 한 항목 개체 var 항목;\n    경우 (entryStruct.isDirectory) {항목 = 새 DirectoryEntry (entryStruct.name, entryStruct.fullPath, 새로운 FileSystem(entryStruct.filesystemName));} 다른 {항목 = 새로운 FileEntry (entryStruct.name, entryStruct.fullPath, 새로운 FileSystem(entryStruct.filesystemName));}"
  },
  {
    "path": "plugins/cordova-plugin-file/doc/pl/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-file\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-file.svg)](https://travis-ci.org/apache/cordova-plugin-file)\n\nTen plugin implementuje API pliku, dzięki czemu dostęp do odczytu i zapisu do plików znajdujących się na urządzeniu.\n\nTen plugin jest oparty na kilka specyfikacje, w tym: HTML5 File API <http://www.w3.org/TR/FileAPI/>\n\nKatalogi (nieistniejącego już) i System Najnowsze rozszerzenia: <http://www.w3.org/TR/2012/WD-file-system-api-20120417/> , chociaż większość z ten plugin kod został napisany podczas wcześniejszych specyfikacji były aktualne: <http://www.w3.org/TR/2011/WD-file-system-api-20110419/>\n\nTo również implementuje specyfikację FileWriter: <http://dev.w3.org/2009/dap/file-system/file-writer.html>\n\nWykorzystania, prosimy odnieść się do skały HTML5 doskonałe [plików art.](http://www.html5rocks.com/en/tutorials/file/filesystem/)\n\nOmówienie innych opcji przechowywania odnoszą się do Cordova z [magazynu przewodnik](http://cordova.apache.org/docs/en/edge/cordova_storage_storage.md.html).\n\nTen plugin określa globalne `cordova.file` obiektu.\n\nChociaż w globalnym zasięgu, to nie dostępne dopiero po `deviceready` imprezie.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(cordova.file);\n    }\n    \n\n## Instalacja\n\n    cordova plugin add cordova-plugin-file\n    \n\n## Obsługiwane platformy\n\n  * Amazon Fire OS\n  * Android\n  * BlackBerry 10\n  * Firefox OS\n  * iOS\n  * Windows Phone 7 i 8 *\n  * Windows 8 *\n  * Windows*\n  * Przeglądarka\n\n\\* *These platforms do not support `FileReader.readAsArrayBuffer` nor `FileWriter.write(blob)`.*\n\n## Gdzie przechowywać pliki\n\nOd v1.2.0 znajdują się adresy URL do katalogów ważne systemu plików. Każdy adres URL jest w formie *file:///path/to/spot/* i mogą być konwertowane na `DirectoryEntry` za pomocą `window.resolveLocalFileSystemURL()`.\n\n  * `cordova.file.applicationDirectory`-Tylko do odczytu katalogu gdzie jest zainstalowana aplikacja. (*iOS*, *Android*, *BlackBerry 10*)\n\n  * `cordova.file.applicationStorageDirectory`-Katalogu obszaru izolowanego aplikacji; na iOS to miejsce jest tylko do odczytu (ale podkatalogów określonego [jak `/Documents` ] są odczytu i zapisu). Wszystkie dane zawarte w jest prywatną do aplikacji. ( *iOS*, *Android*, *BlackBerry 10*)\n\n  * `cordova.file.dataDirectory`-Trwałe i prywatne dane magazynowanie w izolowanym aplikacji przy użyciu pamięci wewnętrznej (na Android, jeśli trzeba użyć zewnętrznej pamięci, należy użyć `.externalDataDirectory` ). Na iOS, Katalog ten nie jest zsynchronizowane z iCloud (za pomocą `.syncedDataDirectory` ). (*iOS*, *Android*, *BlackBerry 10*)\n\n  * `cordova.file.cacheDirectory`-Katalog dla plików buforowanych danych lub pliki, które aplikacji ponownie można łatwo tworzyć. System operacyjny może usunąć te pliki, gdy urządzenie działa niski na przechowywanie, niemniej jednak aplikacje nie powinny polegać na OS, aby usunąć pliki tutaj. (*iOS*, *Android*, *BlackBerry 10*)\n\n  * `cordova.file.externalApplicationStorageDirectory`-Stosowania przestrzeni na zewnętrznej pamięci masowej. (*Android*)\n\n  * `cordova.file.externalDataDirectory`-Gdzie umieścić pliki danych specyficznych dla aplikacji na zewnętrznej pamięci masowej. (*Android*)\n\n  * `cordova.file.externalCacheDirectory`-Pamięci podręcznej aplikacji na zewnętrznej pamięci masowej. (*Android*)\n\n  * `cordova.file.externalRootDirectory`-Korzeń zewnętrznej pamięci masowej (karty SD). (*Android*, *BlackBerry 10*)\n\n  * `cordova.file.tempDirectory`-Temp katalogu systemu operacyjnego można wyczyścić w będzie. Nie należy polegać na OS wobec usunąć ten katalog; aplikacji należy zawsze usunąć pliki jako obowiązujące. (*iOS*)\n\n  * `cordova.file.syncedDataDirectory`-Posiada pliki specyficzne dla aplikacji, które powinny być zsynchronizowane (np. do iCloud). (*iOS*)\n\n  * `cordova.file.documentsDirectory`-Pliki prywatne do aplikacji, ale że mają znaczenie dla innych aplikacji (np. plików pakietu Office). (*iOS*)\n\n  * `cordova.file.sharedDirectory`-Pliki dostępne na całym świecie do wszystkich aplikacji (*BlackBerry 10*)\n\n## Plik System układy\n\nChociaż technicznie implementacyjnym, może być bardzo przydatne wiedzieć, jak `cordova.file.*` właściwości mapy fizycznej ścieżki na prawdziwe urządzenie.\n\n### iOS układ systemu plików\n\n| Ścieżka urządzenia                             | `Cordova.File.*`            | `iosExtraFileSystems` | r/w? | trwałe?  |   Czyści OS   | Synchronizacja | prywatne |\n|:---------------------------------------------- |:--------------------------- |:--------------------- |:----:|:--------:|:-------------:|:--------------:|:--------:|\n| `/ var/mobile/Applications/< UUID > /`   | applicationStorageDirectory | -                     |  r   |   N/D!   |     N/D!      |      N/D!      |   Tak    |\n| &nbsp;&nbsp;&nbsp;`appname.app/`               | applicationDirectory        | pakiet                |  r   |   N/D!   |     N/D!      |      N/D!      |   Tak    |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`www/`     | -                           | -                     |  r   |   N/D!   |     N/D!      |      N/D!      |   Tak    |\n| &nbsp;&nbsp;&nbsp;`Documents/`                 | documentsDirectory          | dokumenty             | r/w  |   Tak    |      Nr       |      Tak       |   Tak    |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`NoCloud/` | -                           | dokumenty nosync      | r/w  |   Tak    |      Nr       |       Nr       |   Tak    |\n| &nbsp;&nbsp;&nbsp;`Library`                    | -                           | Biblioteka            | r/w  |   Tak    |      Nr       |      Tak?      |   Tak    |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`NoCloud/` | dataDirectory               | Biblioteka nosync     | r/w  |   Tak    |      Nr       |       Nr       |   Tak    |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`Cloud/`   | syncedDataDirectory         | -                     | r/w  |   Tak    |      Nr       |      Tak       |   Tak    |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`Caches/`  | cacheDirectory              | pamięci podręcznej    | r/w  |  Tak *   | Yes**\\* |       Nr       |   Tak    |\n| &nbsp;&nbsp;&nbsp;`tmp/`                       | tempDirectory               | -                     | r/w  | No** | Yes**\\* |       Nr       |   Tak    |\n\n\\ * Pliki utrzymywały aplikacja zostanie ponownie uruchomiony i uaktualnienia, ale w tym katalogu mogą być rozliczone przy każdym OS pragnień. Aplikacji należy umożliwić odtworzenie treści, które mogą być usunięte.\n\n** Plików może utrzymywać się po ponownym uruchomieniu aplikacji, ale nie opierają się na tym zachowaniu. Pliki nie są gwarantowane w aktualizacji. Aplikacji należy usunąć pliki z tego katalogu, gdy ma to zastosowanie, ponieważ system operacyjny nie gwarantuje Kiedy (lub nawet jeśli) te pliki zostaną usunięte.\n\n**\\ * System operacyjny może wyczyścić zawartość tego katalogu, gdy czuje, że jest to konieczne, ale nie powoływać się na to. Należy wyczyścić ten katalog jako odpowiednie dla aplikacji.\n\n### Układ systemu Android plików\n\n| Ścieżka urządzenia                               | `Cordova.File.*`                    | `AndroidExtraFileSystems`       | r/w? | trwałe? | Czyści OS | prywatne |\n|:------------------------------------------------ |:----------------------------------- |:------------------------------- |:----:|:-------:|:---------:|:--------:|\n| `file:///android_asset/`                         | applicationDirectory                |                                 |  r   |  N/D!   |   N/D!    |   Tak    |\n| `/Data/danych/< Aplikacja id > /`          | applicationStorageDirectory         | -                               | r/w  |  N/D!   |   N/D!    |   Tak    |\n| &nbsp;&nbsp;&nbsp;`cache`                        | cacheDirectory                      | pamięci podręcznej              | r/w  |   Tak   |  Yes\\ *  |   Tak    |\n| &nbsp;&nbsp;&nbsp;`files`                        | dataDirectory                       | pliki                           | r/w  |   Tak   |    Nr     |   Tak    |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`Documents`  |                                     | dokumenty                       | r/w  |   Tak   |    Nr     |   Tak    |\n| `< sdcard > /`                             | externalRootDirectory               | sdcard                          | r/w  |   Tak   |    Nr     |    Nr    |\n| &nbsp;&nbsp;&nbsp;`Android/data/<app-id>/` | externalApplicationStorageDirectory | -                               | r/w  |   Tak   |    Nr     |    Nr    |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`cache`      | externalCacheDirectry               | zewnętrznych pamięci podręcznej | r/w  |   Tak   | No**  |    Nr    |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`files`      | externalDataDirectory               | zewnętrznych plików             | r/w  |   Tak   |    Nr     |    Nr    |\n\n\\ * OS może okresowo usunąć ten katalog, ale nie opierają się na tym zachowaniu. Wyczyść zawartość tego katalogu jako odpowiednie dla danej aplikacji. Należy użytkownik przeczyścić pamięć podręczną ręcznie, zawartość w tym katalogu są usuwane.\n\n** OS nie usunąć ten katalog automatycznie; Jesteś odpowiedzialny za zarządzanie zawartość siebie. Należy użytkownik przeczyścić pamięć podręczną ręcznie, zawartość katalogu są usuwane.\n\n**Uwaga**: Jeśli nie mogą być montowane pamięci masowej, właściwości `cordova.file.external*` są `wartości null`.\n\n### Układ systemu plików blackBerry 10\n\n| Ścieżka urządzenia                                          | `Cordova.File.*`            | r/w? | trwałe? | Czyści OS | prywatne |\n|:----------------------------------------------------------- |:--------------------------- |:----:|:-------:|:---------:|:--------:|\n| `file:///accounts/1000/AppData/ < id aplikacji > /`   | applicationStorageDirectory |  r   |  N/D!   |   N/D!    |   Tak    |\n| &nbsp;&nbsp;&nbsp;`app/native`                              | applicationDirectory        |  r   |  N/D!   |   N/D!    |   Tak    |\n| &nbsp;&nbsp;&nbsp;`data/webviews/webfs/temporary/local__0`  | cacheDirectory              | r/w  |   Nr    |    Tak    |   Tak    |\n| &nbsp;&nbsp;&nbsp;`data/webviews/webfs/persistent/local__0` | dataDirectory               | r/w  |   Tak   |    Nr     |   Tak    |\n| `file:///accounts/1000/Removable/sdcard`                    | externalRemovableDirectory  | r/w  |   Tak   |    Nr     |    Nr    |\n| `file:///accounts/1000/Shared`                              | sharedDirectory             | r/w  |   Tak   |    Nr     |    Nr    |\n\n*Uwaga*: gdy aplikacja jest rozmieszczana do pracy obwodu, wszystkie ścieżki są względne do /accounts/1000-enterprise.\n\n## Dziwactwa Androida\n\n### Lokalizacja przechowywania trwałych Android\n\nIstnieje wiele prawidłowe lokalizacje do przechowywania trwałych plików na telefonie z systemem Android. Zobacz [tę stronę](http://developer.android.com/guide/topics/data/data-storage.html) do szerokiej dyskusji o różnych możliwościach.\n\nPoprzednie wersje pluginu wybrać lokalizację plików tymczasowych i trwałe podczas uruchamiania, czy urządzenie twierdził, że karta SD (lub równoważne magazynowanie podzia³) był montowany w oparciu. Czy karta SD została zamontowana, czy duży wewnętrzny magazynowanie podzia³ był dostępny (takie jak na Nexus urządzenia,) a następnie trwałe pliki będą przechowywane w katalogu głównego tego miejsca. Oznaczało to, że wszystkie aplikacje Cordova może Zobacz wszystkie pliki dostępne na karcie.\n\nJeśli karta SD nie był dostępny, a następnie poprzednie wersje będzie przechowywać dane w `/data/data/<packageId>`, która izoluje aplikacje od siebie, ale nadal może spowodować danych, które mają być współużytkowane przez użytkowników.\n\nTeraz jest możliwe, aby zdecydować, czy do przechowywania plików w lokalizacji magazynu plików, lub przy użyciu poprzednich logiki, z preferencją w aplikacji w pliku `config.xml`. Aby to zrobić, Dodaj jedną z tych dwóch linii do `pliku config.xml`:\n\n    <preference name=\"AndroidPersistentFileLocation\" value=\"Internal\" />\n    \n    <preference name=\"AndroidPersistentFileLocation\" value=\"Compatibility\" />\n    \n\nBez tej linii wtyczki pliku będzie używać `Compatibility` jako domyślny. Jeśli znacznik preferencji jest obecny i to nie jedną z tych wartości, aplikacja nie zostanie uruchomiona.\n\nJeśli aplikacja wcześniej zostało wysłane do użytkowników, przy użyciu starszych (pre-1.0) wersję tego pluginu i ma zapisane na dysku pliki w trwałych plików, a następnie należy ustawić preferencje do `Compatibility`. Przełączania lokalizacji do \"Internal\" oznacza, że istniejących użytkowników, którzy ich aplikacja może być niesłabnący wobec dostęp ich wcześniej zapisane pliki, w zależności od ich urządzenie.\n\nJeśli aplikacja jest nowy, lub ma nigdy wcześniej przechowywane pliki w systemie plików trwałe, ustawienie `Internal` generalnie jest zalecane.\n\n### Powolny cyklicznych operacji dla /android_asset\n\nLista katalogów aktywów jest bardzo powolny na Android. Można przyspieszyć to się jednak przez dodanie `src/android/build-extras.gradle` do katalogu głównego projektu android (również wymaga cordova-android@4.0.0 lub większej).\n\n## Dziwactwa iOS\n\n  * `cordova.file.applicationStorageDirectory`jest tylko do odczytu; próby przechowywania plików w katalogu głównym zakończy się niepowodzeniem. Użyj jednego z innych `cordova.file.*` właściwości zdefiniowane dla iOS (tylko `applicationDirectory` i `applicationStorageDirectory` są tylko do odczytu).\n  * `FileReader.readAsText(blob, encoding)` \n      * `encoding`Parametr nie jest obsługiwana, i kodowanie UTF-8 jest zawsze w efekcie.\n\n### iOS lokalizacja przechowywania trwałych\n\nIstnieją dwa ważne miejsca trwałe pliki na urządzenia iOS: katalogu dokumentów i katalogu biblioteki. Poprzednie wersje pluginu tylko kiedykolwiek przechowywane trwałe pliki w katalogu dokumentów. To miał ten efekt uboczny od rozpoznawalności wszystkie pliki aplikacji w iTunes, który był często niezamierzone, zwłaszcza dla aplikacji, które obsługują wiele małych plików, zamiast produkuje kompletne dokumenty do wywozu, który jest przeznaczenie katalogu.\n\nTeraz jest możliwe, aby zdecydować, czy do przechowywania plików w dokumentach lub katalogu biblioteki, z preferencją w pliku `config.xml` aplikacji. Aby to zrobić, Dodaj jedną z tych dwóch linii do `pliku config.xml`:\n\n    <preference name=\"iosPersistentFileLocation\" value=\"Library\" />\n    \n    <preference name=\"iosPersistentFileLocation\" value=\"Compatibility\" />\n    \n\nBez tej linii wtyczki pliku będzie używać `Compatibility` jako domyślny. Jeśli znacznik preferencji jest obecny i to nie jedną z tych wartości, aplikacja nie zostanie uruchomiona.\n\nJeśli aplikacja wcześniej zostało wysłane do użytkowników, przy użyciu starszych (pre-1.0) wersję tego pluginu i ma zapisane na dysku pliki w trwałych plików, a następnie należy ustawić preferencje do `Compatibility`. Przełączania lokalizacji do `Library` oznaczałoby, że istniejących użytkowników, którzy ich aplikacja będzie niesłabnący wobec dostęp ich wcześniej zapisane pliki.\n\nJeśli aplikacja jest nowy, lub nigdy wcześniej przechowywane pliki w trwałych plików, ustawień `Library` ogólnie jest zalecane.\n\n## Firefox OS dziwactwa\n\nAPI systemu plików nie jest obsługiwany macierzyście przez Firefox OS i jest zaimplementowany jako podkładki na indexedDB.\n\n  * Nie usuwając niepuste katalogi\n  * Nie obsługuje metadane dla katalogów\n  * Metody `copyTo` i `moveTo` nie obsługuje katalogi\n\nObsługiwane są następujące ścieżki danych: * `applicationDirectory` - używa `xhr`, aby uzyskać lokalne pliki, które są pakowane z aplikacji. * `dataDirectory` - na trwałe dane specyficzne dla aplikacji pliki. * `cacheDirectory` - buforowanych plików, które powinny przetrwać ponowne uruchomienie aplikacji (aplikacje nie powinny polegać na OS, aby usunąć pliki tutaj).\n\n## Quirks przeglądarki\n\n### Wspólne dziwactw i uwagi\n\n  * Każda przeglądarka używa własnej piaskownicy plików. IE i Firefox Użyj IndexedDB jako podstawa. Wszystkie przeglądarki za pomocą ukośnika jako separatora katalogu ścieżka.\n  * Wpisy w katalogu mają być tworzone sukcesywnie. Na przykład wywołanie `fs.root.getDirectory (' dir1/dir2 ', {create:true}, successCallback, errorCallback)` zakończy się niepowodzeniem, jeśli nie istnieje dir1.\n  * Plugin żądania użytkownika uprawnień do używania trwałe przechowywanie przy pierwszym uruchomieniu aplikacji. \n  * Wtyczka obsługuje `cdvfile://localhost` (lokalne zasoby) tylko. Czyli zewnętrznych zasobów nie są obsługiwane przez `cdvfile`.\n  * Plugin nie następować po [\"Plik API systemu nazw 8.3 ograniczenia\"](http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions).\n  * Obiektu BLOB i pliku \"`close` funkcja nie jest obsługiwana.\n  * `FileSaver` i `BlobBuilder` nie są obsługiwane przez ten plugin i nie ma artykułów.\n  * Plugin nie obsługuje `requestAllFileSystems`. Ta funkcja jest również brak w specyfikacji.\n  * Wpisy w katalogu nie zostaną usunięte, jeśli używasz `create: true` flaga dla istniejącego katalogu.\n  * Pliki utworzone za pomocą konstruktora nie są obsługiwane. Zamiast tego należy użyć metody entry.file.\n  * Każda przeglądarka używa własnej postaci URL odwołania blob.\n  * `readAsDataURL` funkcja jest obsługiwana, ale mediatype w Chrome zależy od wejścia z rozszerzeniem, mediatype w IE zawsze jest pusty (który jest taki sam jak `zwykły tekst` według specyfikacji), mediatype w Firefox jest zawsze `aplikacji/oktet strumień`. Na przykład, jeśli treść jest `abcdefg` Firefox wraca z `danych: stosowanie / octet-stream, base64, YWJjZGVmZw ==`, czyli zwraca `danych:; base64, YWJjZGVmZw ==`, Chrome zwraca `danych: < mediatype w zależności od rozszerzenia nazwy; > base64, YWJjZGVmZw ==`.\n  * `toInternalURL` zwraca ścieżkę w postaci `file:///persistent/path/to/entry` (Firefox, IE). Chrom zwraca ścieżkę w postaci `cdvfile://localhost/persistent/file`.\n\n### Dziwactwa chrom\n\n  * Chrom plików nie jest od razu gotowy po gotowe urządzenia. Jako rozwiązanie alternatywne można subskrybować zdarzenia `filePluginIsReady`. Przykład: \n\n```javascript\nwindow.addEventListener('filePluginIsReady', function(){ console.log('File plugin is ready');}, false);\n```\n\nFunkcja `window.isFilePluginReadyRaised` służy do sprawdzenia, czy zdarzenie już została podniesiona. -kwoty plików tymczasowych i trwałe window.requestFileSystem nie są ograniczone w Chrome. -W celu zwiększenia trwałego magazynu w Chrome, należy wywołać metodę `window.initPersistentFileSystem`. Domyślnie trwałe dyskowa jest 5 MB. -Chrome wymaga `--pozwalają--dostęp z plików` uruchomić argument na poparcie API za pośrednictwem protokołu `file:///`. -`Plik` obiekt będzie nie zmieniło jeśli flaga `{create:true}` gdy już istniejący `wpis`. -wydarzenia `zwrotu` właściwość jest zestaw true w Chrome. Jest to sprzeczne ze [specyfikacji](http://dev.w3.org/2009/dap/file-system/file-writer.html). -Funkcja `toURL` w Chrome zwraca `plików:`-poprzedzona ścieżką w zależności od aplikacji hosta. Na przykład, `filesystem:file:///persistent/somefile.txt`, `filesystem:http://localhost:8080/persistent/somefile.txt`. -wynik funkcji `toURL` nie zawierają ukośnika w wpis w katalogu. Chrom usuwa katalogi z ciąć doczepiane adresów URL poprawnie choć. -Metoda `resolveLocalFileSystemURL` wymaga przychodzących `url` mają prefiks `plików`. Na przykład parametr `adresu url` do `resolveLocalFileSystemURL` powinny być w formie `filesystem:file:///persistent/somefile.txt`, w przeciwieństwie do formularza `file:///persistent/somefile.txt` w Android. -Przestarzałe `toNativeURL` funkcja nie jest obsługiwana i nie tylko. -Funkcja `setMetadata` jest nie podane w specyfikacji i nie jest obsługiwane. -INVALID_MODIFICATION_ERR (kod: 9) jest generowany zamiast SYNTAX_ERR(code: 8) na żądanie nieistniejącą plików. -INVALID_MODIFICATION_ERR (kod: 9) jest generowany zamiast PATH_EXISTS_ERR(code: 12) próbuje stworzyć wyłącznie pliku lub katalogu, który już istnieje. -INVALID_MODIFICATION_ERR (kod: 9) jest generowany zamiast NO_MODIFICATION_ALLOWED_ERR(code: 6) na próby wywołania removeRecursively w głównym systemie plików. -INVALID_MODIFICATION_ERR (kod: 9) jest generowany zamiast NOT_FOUND_ERR(code: 1) na trudny do katalogu moveTo, który nie istnieje.\n\n### Na bazie IndexedDB impl dziwactw (Firefox i IE)\n\n  * `.` i `.` nie są obsługiwane.\n  * IE obsługuje `file:///`-tryb; tylko obsługiwane tryb jest obsługiwany (http://localhost:xxxx).\n  * Rozmiar plików Firefox nie jest ograniczona, ale każde rozszerzenie 50MB zwróci użytkownikowi uprawnienia. IE10 pozwala maksymalnie 10mb połączone \"appcache\" i IndexedDB używane w implementacji systemu plików bez monitowania, gdy trafisz na tym poziomie, które uzyskasz, jeśli chcesz mogła ona zostać zwiększony do max 250mb na stronie. Więc `rozmiar` parametru funkcja `requestFileSystem` nie wpływa na system plików Firefox i IE.\n  * `readAsBinaryString` funkcja nie jest określona w specyfikacji i nie obsługiwane w IE i nie tylko.\n  * `File.Type` ma zawsze wartość null.\n  * Nie należy utworzyć wpis za pomocą DirectoryEntry wystąpienie wynik wywołania zwrotnego, który został usunięty. W przeciwnym razie dostaniesz wpisem\"wiszące\".\n  * Zanim będzie można przeczytać plik, który został napisany tylko trzeba uzyskać nowe wystąpienie tego pliku.\n  * Funkcja `setMetadata`, która nie jest określona w specyfikacji obsługuje tylko zmian pola `modificationTime`. \n  * `copyTo` i `moveTo` funkcji nie obsługuje katalogi.\n  * Metadanych w katalogów nie jest obsługiwana.\n  * Zarówno Entry.remove i directoryEntry.removeRecursively nie usuwając niepuste katalogi - katalogi są usuwane są czyszczone z treści zamiast.\n  * `abort` i `truncate` funkcje nie są obsługiwane.\n  * zdarzenia postępu nie są zwalniani. Na przykład to obsługa będzie nie wykonywane:\n\n```javascript\nwriter.onprogress = function() { /*commands*/ };\n```\n\n## Uaktualniania notatek\n\nW v1.0.0 tego pluginu struktury `FileEntry` i `DirectoryEntry` zmieniły się więcej zgodnie z opublikowaną specyfikacją.\n\nPoprzednie wersje (pre-1.0.0) plugin przechowywane urządzenia bezwzględna plik lokalizacja we właściwości `fullPath` `wpis` obiektów. Te ścieżki zazwyczaj będzie wyglądać\n\n    /var/mobile/Applications/<application UUID>/Documents/path/to/file  (iOS)\n    /storage/emulated/0/path/to/file                                    (Android)\n    \n\nTe ścieżki były także zwracany przez metodę `toURL()` `Entry` obiektów.\n\nZ v1.0.0 atrybut `fullPath` jest ścieżką do pliku, *względem katalogu głównego systemu plików HTML*. Tak powyżej ścieżki będzie teraz zarówno być reprezentowane przez obiekt `FileEntry` z `fullPath` o\n\n    /path/to/file\n    \n\nJeśli aplikacja działa z ścieżki bezwzględnej urządzeń, i możesz wcześniej źródło tych ścieżek przez właściwość `fullPath` `wpis` obiektów, należy zaktualizować kod, aby zamiast tego użyj `entry.toURL()`.\n\nDla wstecznej kompatybilności, Metoda `resolveLocalFileSystemURL()` będzie zaakceptować urządzenia ścieżka bezwzględna i zwróci obiekt `Entry` odpowiadający, tak długo, jak ten plik istnieje w albo `TEMPORARY` lub `PERSISTENT` systemy plików.\n\nTo szczególnie został problem z pluginem transferu plików, które poprzednio używane ścieżki bezwzględnej urządzeń (i wciąż można je przyjąć). Została zaktualizowana do pracy poprawnie z adresów URL plików, więc wymiana `entry.fullPath` z `entry.toURL()` powinno rozwiązać wszelkie problemy dostawanie ten plugin do pracy z plików w pamięci urządzenia.\n\nW v1.1.0 wartość zwracana przez `toURL()` został zmieniony (patrz \\[CB-6394\\] (https://issues.apache.org/jira/browse/CB-6394)) zwraca adres URL absolutnej \"file://\". wszędzie tam, gdzie jest to możliwe. Aby zapewnić ' cdvfile:'-URL można użyć `toInternalURL()` teraz. Ta metoda zwróci teraz adresy URL plików formularza\n\n    cdvfile://localhost/persistent/path/to/file\n    \n\nktóry służy do jednoznacznej identyfikacji pliku.\n\n## Wykaz kodów błędów i ich znaczenie\n\nGdy błąd jest generowany, jeden z następujących kodów będzie służyć.\n\n| Kod | Stała                         |\n| ---:|:----------------------------- |\n|   1 | `NOT_FOUND_ERR`               |\n|   2 | `SECURITY_ERR`                |\n|   3 | `ABORT_ERR`                   |\n|   4 | `NOT_READABLE_ERR`            |\n|   5 | `ENCODING_ERR`                |\n|   6 | `NO_MODIFICATION_ALLOWED_ERR` |\n|   7 | `INVALID_STATE_ERR`           |\n|   8 | `SYNTAX_ERR`                  |\n|   9 | `INVALID_MODIFICATION_ERR`    |\n|  10 | `QUOTA_EXCEEDED_ERR`          |\n|  11 | `TYPE_MISMATCH_ERR`           |\n|  12 | `PATH_EXISTS_ERR`             |\n\n## Konfigurowanie wtyczka (opcjonalny)\n\nZestaw dostępnych plików może być skonfigurowany na platformie. Zarówno iOS i Android <preference> Tag w `pliku config.xml`, których nazwy plików do instalacji. Domyślnie włączone są wszystkie korzenie systemu plików.\n\n    <preference name=\"iosExtraFilesystems\" value=\"library,library-nosync,documents,documents-nosync,cache,bundle,root\" />\n    <preference name=\"AndroidExtraFilesystems\" value=\"files,files-external,documents,sdcard,cache,cache-external,root\" />\n    \n\n### Android\n\n  * `files`: katalogu przechowywania plików aplikacji\n  * `files-external`: katalog aplikacji zewnętrznych plików\n  * `sdcard`: katalog globalny plik zewnętrzny (to jest głównym karty SD, jeśli jedna jest zainstalowana). Musi mieć uprawnienia `android.permission.WRITE_EXTERNAL_STORAGE` wobec używać ten.\n  * `cache`: katalogu wewnętrznej pamięci podręcznej aplikacji\n  * `cache-external`: katalogu aplikacji zewnętrznych pamięci podręcznej\n  * `root`: całe urządzenie systemu plików\n\nAndroid obsługuje również specjalnych plików o nazwie \"dokumenty\", który reprezentuje podkatalog \"/ dokumenty /\" w ramach systemu plików \"pliki\".\n\n### iOS\n\n  * `library`: katalog biblioteki aplikacji\n  * `documents`: dokumenty katalogu aplikacji\n  * `cache`: katalogu pamięci podręcznej aplikacji\n  * `bundle`: pakiet aplikacji; Lokalizacja aplikacji na dysku (tylko do odczytu)\n  * `root`: całe urządzenie systemu plików\n\nDomyślnie katalogi biblioteki i dokumenty mogą być synchronizowane iCloud. Można również zażądać dwóch dodatkowych plików, `library-nosync` i `documents-nosync`, które stanowią specjalny katalog nie zsynchronizowane w `/Library` lub systemu plików `/Documents`."
  },
  {
    "path": "plugins/cordova-plugin-file/doc/pl/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-file\n\nTen plugin implementuje API pliku, dzięki czemu dostęp do odczytu i zapisu do plików znajdujących się na urządzeniu.\n\nTen plugin jest oparty na kilka specyfikacje, w tym: HTML5 File API <http://www.w3.org/TR/FileAPI/>\n\nKatalogi (nieistniejącego już) i System Najnowsze rozszerzenia: <http://www.w3.org/TR/2012/WD-file-system-api-20120417/> , chociaż większość z ten plugin kod został napisany podczas wcześniejszych specyfikacji były aktualne: <http://www.w3.org/TR/2011/WD-file-system-api-20110419/>\n\nTo również implementuje specyfikację FileWriter: <http://dev.w3.org/2009/dap/file-system/file-writer.html>\n\nWykorzystania, prosimy odnieść się do skały HTML5 doskonałe [plików art.][1]\n\n [1]: http://www.html5rocks.com/en/tutorials/file/filesystem/\n\nOmówienie innych opcji przechowywania odnoszą się do Cordova z [magazynu przewodnik][2].\n\n [2]: http://cordova.apache.org/docs/en/edge/cordova_storage_storage.md.html\n\nTen plugin określa globalne `cordova.file` obiektu.\n\nChociaż w globalnym zasięgu, to nie dostępne dopiero po `deviceready` imprezie.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(cordova.file);\n    }\n    \n\n## Instalacja\n\n    cordova plugin add cordova-plugin-file\n    \n\n## Obsługiwane platformy\n\n*   Amazon Fire OS\n*   Android\n*   BlackBerry 10\n*   Firefox OS\n*   iOS\n*   Windows Phone 7 i 8 *\n*   Windows 8 *\n*   Przeglądarka\n\n* *Nie obsługują tych platform, `FileReader.readAsArrayBuffer` ani `FileWriter.write(blob)`.*\n\n## Gdzie przechowywać pliki\n\nOd v1.2.0 znajdują się adresy URL do katalogów ważne systemu plików. Każdy adres URL jest w formie *file:///path/to/spot/* i mogą być konwertowane na `DirectoryEntry` za pomocą `window.resolveLocalFileSystemURL()`.\n\n*   `cordova.file.applicationDirectory`-Tylko do odczytu katalogu gdzie jest zainstalowana aplikacja. (*iOS*, *Android*, *BlackBerry 10*)\n\n*   `cordova.file.applicationStorageDirectory`-Katalogu obszaru izolowanego aplikacji; na iOS to miejsce jest tylko do odczytu (ale podkatalogów określonego [jak `/Documents` ] są odczytu i zapisu). Wszystkie dane zawarte w jest prywatną do aplikacji. ( *iOS*, *Android*, *BlackBerry 10*)\n\n*   `cordova.file.dataDirectory`-Trwałe i prywatne dane magazynowanie w izolowanym aplikacji przy użyciu pamięci wewnętrznej (na Android, jeśli trzeba użyć zewnętrznej pamięci, należy użyć `.externalDataDirectory` ). Na iOS, Katalog ten nie jest zsynchronizowane z iCloud (za pomocą `.syncedDataDirectory` ). (*iOS*, *Android*, *BlackBerry 10*)\n\n*   `cordova.file.cacheDirectory`-Katalog dla plików buforowanych danych lub pliki, które aplikacji ponownie można łatwo tworzyć. System operacyjny może usunąć te pliki, gdy urządzenie działa niski na przechowywanie, niemniej jednak aplikacje nie powinny polegać na OS, aby usunąć pliki tutaj. (*iOS*, *Android*, *BlackBerry 10*)\n\n*   `cordova.file.externalApplicationStorageDirectory`-Stosowania przestrzeni na zewnętrznej pamięci masowej. (*Android*)\n\n*   `cordova.file.externalDataDirectory`-Gdzie umieścić pliki danych specyficznych dla aplikacji na zewnętrznej pamięci masowej. (*Android*)\n\n*   `cordova.file.externalCacheDirectory`-Pamięci podręcznej aplikacji na zewnętrznej pamięci masowej. (*Android*)\n\n*   `cordova.file.externalRootDirectory`-Korzeń zewnętrznej pamięci masowej (karty SD). (*Android*, *BlackBerry 10*)\n\n*   `cordova.file.tempDirectory`-Temp katalogu systemu operacyjnego można wyczyścić w będzie. Nie należy polegać na OS wobec usunąć ten katalog; aplikacji należy zawsze usunąć pliki jako obowiązujące. (*iOS*)\n\n*   `cordova.file.syncedDataDirectory`-Posiada pliki specyficzne dla aplikacji, które powinny być zsynchronizowane (np. do iCloud). (*iOS*)\n\n*   `cordova.file.documentsDirectory`-Pliki prywatne do aplikacji, ale że mają znaczenie dla innych aplikacji (np. plików pakietu Office). (*iOS*)\n\n*   `cordova.file.sharedDirectory`-Pliki dostępne na całym świecie do wszystkich aplikacji (*BlackBerry 10*)\n\n## Plik System układy\n\nChociaż technicznie implementacyjnym, może być bardzo przydatne wiedzieć, jak `cordova.file.*` właściwości mapy fizycznej ścieżki na prawdziwe urządzenie.\n\n### iOS układ systemu plików\n\n| Ścieżka urządzenia                           | `Cordova.File.*`            | `iosExtraFileSystems` | r/w? | trwałe? |  Czyści OS  | Synchronizacja | prywatne |\n|:-------------------------------------------- |:--------------------------- |:--------------------- |:----:|:-------:|:-----------:|:--------------:|:--------:|\n| `/ var/mobile/Applications/< UUID > /` | applicationStorageDirectory | -                     |  r   |  N/D!   |    N/D!     |      N/D!      |   Tak    |\n|    `appname.app/`                            | applicationDirectory        | pakiet                |  r   |  N/D!   |    N/D!     |      N/D!      |   Tak    |\n|       `www/`                                 | -                           | -                     |  r   |  N/D!   |    N/D!     |      N/D!      |   Tak    |\n|    `Documents/`                              | documentsDirectory          | dokumenty             | r/w  |   Tak   |     Nr      |      Tak       |   Tak    |\n|       `NoCloud/`                             | -                           | dokumenty nosync      | r/w  |   Tak   |     Nr      |       Nr       |   Tak    |\n|    `Library`                                 | -                           | Biblioteka            | r/w  |   Tak   |     Nr      |      Tak?      |   Tak    |\n|       `NoCloud/`                             | dataDirectory               | Biblioteka nosync     | r/w  |   Tak   |     Nr      |       Nr       |   Tak    |\n|       `Cloud/`                               | syncedDataDirectory         | -                     | r/w  |   Tak   |     Nr      |      Tak       |   Tak    |\n|       `Caches/`                              | cacheDirectory              | pamięci podręcznej    | r/w  |  Tak *  | Tak * * *| |       Nr       |   Tak    |\n|    `tmp/`                                    | tempDirectory               | -                     | r/w  | Nie * * | Tak * * *| |       Nr       |   Tak    |\n\n* Pliki utrzymywały aplikacja zostanie ponownie uruchomiony i uaktualnienia, ale w tym katalogu mogą być rozliczone, gdy OS pragnienia. Aplikacji powinny być w stanie odtworzyć zawartość, która może być usunięta.\n\n* * Plików może utrzymywać się po ponownym uruchomieniu aplikacji, ale nie opierają się na tym zachowaniu. Pliki nie są gwarantowane w aktualizacji. Aplikacji należy usunąć pliki z tego katalogu, gdy ma to zastosowanie, ponieważ system operacyjny nie gwarantuje Kiedy (lub nawet jeśli) te pliki zostaną usunięte.\n\n* * *| System operacyjny może wyczyścić zawartość w tym katalogu, gdy czuje, że jest to konieczne, ale nie powoływać się na to. Należy wyczyścić ten katalog jako odpowiednie dla aplikacji.\n\n### Układ systemu Android plików\n\n| Ścieżka urządzenia                      | `Cordova.File.*`                    | `AndroidExtraFileSystems`       | r/w? | trwałe? | Czyści OS | prywatne |\n|:--------------------------------------- |:----------------------------------- |:------------------------------- |:----:|:-------:|:---------:|:--------:|\n| `file:///android_asset/`                | applicationDirectory                |                                 |  r   |  N/D!   |   N/D!    |   Tak    |\n| `/Data/danych/< Aplikacja id > /` | applicationStorageDirectory         | -                               | r/w  |  N/D!   |   N/D!    |   Tak    |\n|    `cache`                              | cacheDirectory                      | pamięci podręcznej              | r/w  |   Tak   |   Tak *   |   Tak    |\n|    `files`                              | dataDirectory                       | pliki                           | r/w  |   Tak   |    Nr     |   Tak    |\n|       `Documents`                       |                                     | dokumenty                       | r/w  |   Tak   |    Nr     |   Tak    |\n| `< sdcard > /`                    | externalRootDirectory               | sdcard                          | r/w  |   Tak   |    Nr     |    Nr    |\n|    `Android/data/<app-id>/`       | externalApplicationStorageDirectory | -                               | r/w  |   Tak   |    Nr     |    Nr    |\n|       `cache`                           | externalCacheDirectry               | zewnętrznych pamięci podręcznej | r/w  |   Tak   |  Nie * *  |    Nr    |\n|       `files`                           | externalDataDirectory               | zewnętrznych plików             | r/w  |   Tak   |    Nr     |    Nr    |\n\n* System operacyjny może okresowo usunąć ten katalog, ale nie opierają się na tym zachowaniu. Wyczyść zawartość tego katalogu jako odpowiednie dla danej aplikacji. Należy użytkownik przeczyścić pamięć podręczną ręcznie, zawartość w tym katalogu są usuwane.\n\n* * System operacyjny nie usunąć ten katalog automatycznie; Jesteś odpowiedzialny za zarządzanie zawartość siebie. Należy użytkownik przeczyścić pamięć podręczną ręcznie, zawartość katalogu są usuwane.\n\n**Uwaga**: Jeśli nie mogą być montowane pamięci masowej, właściwości `cordova.file.external*` są `wartości null`.\n\n### Układ systemu plików blackBerry 10\n\n| Ścieżka urządzenia                                        | `Cordova.File.*`            | r/w? | trwałe? | Czyści OS | prywatne |\n|:--------------------------------------------------------- |:--------------------------- |:----:|:-------:|:---------:|:--------:|\n| `file:///accounts/1000/AppData/ < id aplikacji > /` | applicationStorageDirectory |  r   |  N/D!   |   N/D!    |   Tak    |\n|    `app/native`                                           | applicationDirectory        |  r   |  N/D!   |   N/D!    |   Tak    |\n|    `data/webviews/webfs/temporary/local__0`               | cacheDirectory              | r/w  |   Nr    |    Tak    |   Tak    |\n|    `data/webviews/webfs/persistent/local__0`              | dataDirectory               | r/w  |   Tak   |    Nr     |   Tak    |\n| `file:///accounts/1000/Removable/sdcard`                  | externalRemovableDirectory  | r/w  |   Tak   |    Nr     |    Nr    |\n| `file:///accounts/1000/Shared`                            | sharedDirectory             | r/w  |   Tak   |    Nr     |    Nr    |\n\n*Uwaga*: gdy aplikacja jest rozmieszczana do pracy obwodu, wszystkie ścieżki są względne do /accounts/1000-enterprise.\n\n## Dziwactwa Androida\n\n### Lokalizacja przechowywania trwałych Android\n\nIstnieje wiele prawidłowe lokalizacje do przechowywania trwałych plików na telefonie z systemem Android. Zobacz [tę stronę][3] do szerokiej dyskusji o różnych możliwościach.\n\n [3]: http://developer.android.com/guide/topics/data/data-storage.html\n\nPoprzednie wersje pluginu wybrać lokalizację plików tymczasowych i trwałe podczas uruchamiania, czy urządzenie twierdził, że karta SD (lub równoważne magazynowanie podzia³) był montowany w oparciu. Czy karta SD została zamontowana, czy duży wewnętrzny magazynowanie podzia³ był dostępny (takie jak na Nexus urządzenia,) a następnie trwałe pliki będą przechowywane w katalogu głównego tego miejsca. Oznaczało to, że wszystkie aplikacje Cordova może Zobacz wszystkie pliki dostępne na karcie.\n\nJeśli karta SD nie był dostępny, a następnie poprzednie wersje będzie przechowywać dane w `/data/data/<packageId>`, która izoluje aplikacje od siebie, ale nadal może spowodować danych, które mają być współużytkowane przez użytkowników.\n\nTeraz jest możliwe, aby zdecydować, czy do przechowywania plików w lokalizacji magazynu plików, lub przy użyciu poprzednich logiki, z preferencją w aplikacji w pliku `config.xml`. Aby to zrobić, Dodaj jedną z tych dwóch linii do `pliku config.xml`:\n\n    <preference name=\"AndroidPersistentFileLocation\" value=\"Internal\" />\n    \n    <preference name=\"AndroidPersistentFileLocation\" value=\"Compatibility\" />\n    \n\nBez tej linii wtyczki pliku będzie używać `Compatibility` jako domyślny. Jeśli znacznik preferencji jest obecny i to nie jedną z tych wartości, aplikacja nie zostanie uruchomiona.\n\nJeśli aplikacja wcześniej zostało wysłane do użytkowników, przy użyciu starszych (pre-1.0) wersję tego pluginu i ma zapisane na dysku pliki w trwałych plików, a następnie należy ustawić preferencje do `Compatibility`. Przełączania lokalizacji do \"Internal\" oznacza, że istniejących użytkowników, którzy ich aplikacja może być niesłabnący wobec dostęp ich wcześniej zapisane pliki, w zależności od ich urządzenie.\n\nJeśli aplikacja jest nowy, lub ma nigdy wcześniej przechowywane pliki w systemie plików trwałe, ustawienie `Internal` generalnie jest zalecane.\n\n## Dziwactwa iOS\n\n*   `cordova.file.applicationStorageDirectory`jest tylko do odczytu; próby przechowywania plików w katalogu głównym zakończy się niepowodzeniem. Użyj jednego z innych `cordova.file.*` właściwości zdefiniowane dla iOS (tylko `applicationDirectory` i `applicationStorageDirectory` są tylko do odczytu).\n*   `FileReader.readAsText(blob, encoding)` \n    *   `encoding`Parametr nie jest obsługiwana, i kodowanie UTF-8 jest zawsze w efekcie.\n\n### iOS lokalizacja przechowywania trwałych\n\nIstnieją dwa ważne miejsca trwałe pliki na urządzenia iOS: katalogu dokumentów i katalogu biblioteki. Poprzednie wersje pluginu tylko kiedykolwiek przechowywane trwałe pliki w katalogu dokumentów. To miał ten efekt uboczny od rozpoznawalności wszystkie pliki aplikacji w iTunes, który był często niezamierzone, zwłaszcza dla aplikacji, które obsługują wiele małych plików, zamiast produkuje kompletne dokumenty do wywozu, który jest przeznaczenie katalogu.\n\nTeraz jest możliwe, aby zdecydować, czy do przechowywania plików w dokumentach lub katalogu biblioteki, z preferencją w pliku `config.xml` aplikacji. Aby to zrobić, Dodaj jedną z tych dwóch linii do `pliku config.xml`:\n\n    <preference name=\"iosPersistentFileLocation\" value=\"Library\" />\n    \n    <preference name=\"iosPersistentFileLocation\" value=\"Compatibility\" />\n    \n\nBez tej linii wtyczki pliku będzie używać `Compatibility` jako domyślny. Jeśli znacznik preferencji jest obecny i to nie jedną z tych wartości, aplikacja nie zostanie uruchomiona.\n\nJeśli aplikacja wcześniej zostało wysłane do użytkowników, przy użyciu starszych (pre-1.0) wersję tego pluginu i ma zapisane na dysku pliki w trwałych plików, a następnie należy ustawić preferencje do `Compatibility`. Przełączania lokalizacji do `Library` oznaczałoby, że istniejących użytkowników, którzy ich aplikacja będzie niesłabnący wobec dostęp ich wcześniej zapisane pliki.\n\nJeśli aplikacja jest nowy, lub nigdy wcześniej przechowywane pliki w trwałych plików, ustawień `Library` ogólnie jest zalecane.\n\n## Firefox OS dziwactwa\n\nAPI systemu plików nie jest obsługiwany macierzyście przez Firefox OS i jest zaimplementowany jako podkładki na indexedDB.\n\n*   Nie usuwając niepuste katalogi\n*   Nie obsługuje metadane dla katalogów\n*   Metody `copyTo` i `moveTo` nie obsługuje katalogi\n\nObsługiwane są następujące ścieżki danych: * `applicationDirectory` - używa `xhr`, aby uzyskać lokalne pliki, które są pakowane z aplikacji. * `dataDirectory` - na trwałe dane specyficzne dla aplikacji pliki. * `cacheDirectory` - buforowanych plików, które powinny przetrwać ponowne uruchomienie aplikacji (aplikacje nie powinny polegać na OS, aby usunąć pliki tutaj).\n\n## Quirks przeglądarki\n\n### Wspólne dziwactw i uwagi\n\n*   Każda przeglądarka używa własnej piaskownicy plików. IE i Firefox Użyj IndexedDB jako podstawa. Wszystkie przeglądarki za pomocą ukośnika jako separatora katalogu ścieżka.\n*   Wpisy w katalogu mają być tworzone sukcesywnie. Na przykład wywołanie `fs.root.getDirectory (' dir1/dir2 ', {create:true}, successCallback, errorCallback)` zakończy się niepowodzeniem, jeśli nie istnieje dir1.\n*   Plugin żądania użytkownika uprawnień do używania trwałe przechowywanie przy pierwszym uruchomieniu aplikacji. \n*   Wtyczka obsługuje `cdvfile://localhost` (lokalne zasoby) tylko. Czyli zewnętrznych zasobów nie są obsługiwane przez `cdvfile`.\n*   Plugin nie następować po [\"Plik API systemu nazw 8.3 ograniczenia\"][4].\n*   Obiektu BLOB i pliku \"`close` funkcja nie jest obsługiwana.\n*   `FileSaver` i `BlobBuilder` nie są obsługiwane przez ten plugin i nie ma artykułów.\n*   Plugin nie obsługuje `requestAllFileSystems`. Ta funkcja jest również brak w specyfikacji.\n*   Wpisy w katalogu nie zostaną usunięte, jeśli używasz `create: true` flaga dla istniejącego katalogu.\n*   Pliki utworzone za pomocą konstruktora nie są obsługiwane. Zamiast tego należy użyć metody entry.file.\n*   Każda przeglądarka używa własnej postaci URL odwołania blob.\n*   `readAsDataURL` funkcja jest obsługiwana, ale mediatype w Chrome zależy od wejścia z rozszerzeniem, mediatype w IE zawsze jest pusty (który jest taki sam jak `zwykły tekst` według specyfikacji), mediatype w Firefox jest zawsze `aplikacji/oktet strumień`. Na przykład, jeśli treść jest `abcdefg` Firefox wraca z `danych: stosowanie / octet-stream, base64, YWJjZGVmZw ==`, czyli zwraca `danych:; base64, YWJjZGVmZw ==`, Chrome zwraca `danych: < mediatype w zależności od rozszerzenia nazwy; > base64, YWJjZGVmZw ==`.\n*   `toInternalURL` zwraca ścieżkę w postaci `file:///persistent/path/to/entry` (Firefox, IE). Chrom zwraca ścieżkę w postaci `cdvfile://localhost/persistent/file`.\n\n [4]: http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions\n\n### Dziwactwa chrom\n\n*   Chrom plików nie jest od razu gotowy po gotowe urządzenia. Jako rozwiązanie alternatywne można subskrybować zdarzenia `filePluginIsReady`. Przykład: \n\n    javascript\n    window.addEventListener('filePluginIsReady', function(){ console.log('File plugin is ready');}, false);\n    \n\nFunkcja `window.isFilePluginReadyRaised` służy do sprawdzenia, czy zdarzenie już została podniesiona. -kwoty plików tymczasowych i trwałe window.requestFileSystem nie są ograniczone w Chrome. -W celu zwiększenia trwałego magazynu w Chrome, należy wywołać metodę `window.initPersistentFileSystem`. Domyślnie trwałe dyskowa jest 5 MB. -Chrome wymaga `--pozwalają--dostęp z plików` uruchomić argument na poparcie API za pośrednictwem protokołu `file:///`. -`Plik` obiekt będzie nie zmieniło jeśli flaga `{create:true}` gdy już istniejący `wpis`. -wydarzenia `zwrotu` właściwość jest zestaw true w Chrome. Jest to sprzeczne ze [specyfikacji][5]. -Funkcja `toURL` w Chrome zwraca `plików:`-poprzedzona ścieżką w zależności od aplikacji hosta. Na przykład, `filesystem:file:///persistent/somefile.txt`, `filesystem:http://localhost:8080/persistent/somefile.txt`. -wynik funkcji `toURL` nie zawierają ukośnika w wpis w katalogu. Chrom usuwa katalogi z ciąć doczepiane adresów URL poprawnie choć. -Metoda `resolveLocalFileSystemURL` wymaga przychodzących `url` mają prefiks `plików`. Na przykład parametr `adresu url` do `resolveLocalFileSystemURL` powinny być w formie `filesystem:file:///persistent/somefile.txt`, w przeciwieństwie do formularza `file:///persistent/somefile.txt` w Android. -Przestarzałe `toNativeURL` funkcja nie jest obsługiwana i nie tylko. -Funkcja `setMetadata` jest nie podane w specyfikacji i nie jest obsługiwane. -INVALID_MODIFICATION_ERR (kod: 9) jest generowany zamiast SYNTAX_ERR(code: 8) na żądanie nieistniejącą plików. -INVALID_MODIFICATION_ERR (kod: 9) jest generowany zamiast PATH_EXISTS_ERR(code: 12) próbuje stworzyć wyłącznie pliku lub katalogu, który już istnieje. -INVALID_MODIFICATION_ERR (kod: 9) jest generowany zamiast NO_MODIFICATION_ALLOWED_ERR(code: 6) na próby wywołania removeRecursively w głównym systemie plików. -INVALID_MODIFICATION_ERR (kod: 9) jest generowany zamiast NOT_FOUND_ERR(code: 1) na trudny do katalogu moveTo, który nie istnieje.\n\n [5]: http://dev.w3.org/2009/dap/file-system/file-writer.html\n\n### Na bazie IndexedDB impl dziwactw (Firefox i IE)\n\n*   `.` i `.` nie są obsługiwane.\n*   IE obsługuje `file:///`-tryb; tylko obsługiwane tryb jest obsługiwany (http://localhost:xxxx).\n*   Rozmiar plików Firefox nie jest ograniczona, ale każde rozszerzenie 50MB zwróci użytkownikowi uprawnienia. IE10 pozwala maksymalnie 10mb połączone \"appcache\" i IndexedDB używane w implementacji systemu plików bez monitowania, gdy trafisz na tym poziomie, które uzyskasz, jeśli chcesz mogła ona zostać zwiększony do max 250mb na stronie. Więc `rozmiar` parametru funkcja `requestFileSystem` nie wpływa na system plików Firefox i IE.\n*   `readAsBinaryString` funkcja nie jest określona w specyfikacji i nie obsługiwane w IE i nie tylko.\n*   `File.Type` ma zawsze wartość null.\n*   Nie należy utworzyć wpis za pomocą DirectoryEntry wystąpienie wynik wywołania zwrotnego, który został usunięty. W przeciwnym razie dostaniesz wpisem\"wiszące\".\n*   Zanim będzie można przeczytać plik, który został napisany tylko trzeba uzyskać nowe wystąpienie tego pliku.\n*   Funkcja `setMetadata`, która nie jest określona w specyfikacji obsługuje tylko zmian pola `modificationTime`. \n*   `copyTo` i `moveTo` funkcji nie obsługuje katalogi.\n*   Metadanych w katalogów nie jest obsługiwana.\n*   Zarówno Entry.remove i directoryEntry.removeRecursively nie usuwając niepuste katalogi - katalogi są usuwane są czyszczone z treści zamiast.\n*   `abort` i `truncate` funkcje nie są obsługiwane.\n*   zdarzenia postępu nie są zwalniani. Na przykład to obsługa będzie nie wykonywane:\n\n    javascript\n    writer.onprogress = function() { /*commands*/ };\n    \n\n## Uaktualniania notatek\n\nW v1.0.0 tego pluginu struktury `FileEntry` i `DirectoryEntry` zmieniły się więcej zgodnie z opublikowaną specyfikacją.\n\nPoprzednie wersje (pre-1.0.0) plugin przechowywane urządzenia bezwzględna plik lokalizacja we właściwości `fullPath` `wpis` obiektów. Te ścieżki zazwyczaj będzie wyglądać\n\n    /var/mobile/Applications/<application UUID>/Documents/path/to/file  (iOS)\n    /storage/emulated/0/path/to/file                                    (Android)\n    \n\nTe ścieżki były także zwracany przez metodę `toURL()` `Entry` obiektów.\n\nZ v1.0.0 atrybut `fullPath` jest ścieżką do pliku, *względem katalogu głównego systemu plików HTML*. Tak powyżej ścieżki będzie teraz zarówno być reprezentowane przez obiekt `FileEntry` z `fullPath` o\n\n    /path/to/file\n    \n\nJeśli aplikacja działa z ścieżki bezwzględnej urządzeń, i możesz wcześniej źródło tych ścieżek przez właściwość `fullPath` `wpis` obiektów, należy zaktualizować kod, aby zamiast tego użyj `entry.toURL()`.\n\nDla wstecznej kompatybilności, Metoda `resolveLocalFileSystemURL()` będzie zaakceptować urządzenia ścieżka bezwzględna i zwróci obiekt `Entry` odpowiadający, tak długo, jak ten plik istnieje w albo `TEMPORARY` lub `PERSISTENT` systemy plików.\n\nTo szczególnie został problem z pluginem transferu plików, które poprzednio używane ścieżki bezwzględnej urządzeń (i wciąż można je przyjąć). Została zaktualizowana do pracy poprawnie z adresów URL plików, więc wymiana `entry.fullPath` z `entry.toURL()` powinno rozwiązać wszelkie problemy dostawanie ten plugin do pracy z plików w pamięci urządzenia.\n\nW v1.1.0 wartość zwracana przez `toURL()` został zmieniony (patrz \\[CB-6394\\] (https://issues.apache.org/jira/browse/CB-6394)) zwraca adres URL absolutnej \"file://\". wszędzie tam, gdzie jest to możliwe. Aby zapewnić ' cdvfile:'-URL można użyć `toInternalURL()` teraz. Ta metoda zwróci teraz adresy URL plików formularza\n\n    cdvfile://localhost/persistent/path/to/file\n    \n\nktóry służy do jednoznacznej identyfikacji pliku.\n\n## Wykaz kodów błędów i ich znaczenie\n\nGdy błąd jest generowany, jeden z następujących kodów będzie służyć.\n\n| Kod | Stała                         |\n| ---:|:----------------------------- |\n|   1 | `NOT_FOUND_ERR`               |\n|   2 | `SECURITY_ERR`                |\n|   3 | `ABORT_ERR`                   |\n|   4 | `NOT_READABLE_ERR`            |\n|   5 | `ENCODING_ERR`                |\n|   6 | `NO_MODIFICATION_ALLOWED_ERR` |\n|   7 | `INVALID_STATE_ERR`           |\n|   8 | `SYNTAX_ERR`                  |\n|   9 | `INVALID_MODIFICATION_ERR`    |\n|  10 | `QUOTA_EXCEEDED_ERR`          |\n|  11 | `TYPE_MISMATCH_ERR`           |\n|  12 | `PATH_EXISTS_ERR`             |\n\n## Konfigurowanie wtyczka (opcjonalny)\n\nZestaw dostępnych plików może być skonfigurowany na platformie. Zarówno iOS i Android <preference> Tag w `pliku config.xml`, których nazwy plików do instalacji. Domyślnie włączone są wszystkie korzenie systemu plików.\n\n    <preference name=\"iosExtraFilesystems\" value=\"library,library-nosync,documents,documents-nosync,cache,bundle,root\" />\n    <preference name=\"AndroidExtraFilesystems\" value=\"files,files-external,documents,sdcard,cache,cache-external,root\" />\n    \n\n### Android\n\n*   `files`: katalogu przechowywania plików aplikacji\n*   `files-external`: katalog aplikacji zewnętrznych plików\n*   `sdcard`: katalog globalny plik zewnętrzny (to jest głównym karty SD, jeśli jedna jest zainstalowana). Musi mieć uprawnienia `android.permission.WRITE_EXTERNAL_STORAGE` wobec używać ten.\n*   `cache`: katalogu wewnętrznej pamięci podręcznej aplikacji\n*   `cache-external`: katalogu aplikacji zewnętrznych pamięci podręcznej\n*   `root`: całe urządzenie systemu plików\n\nAndroid obsługuje również specjalnych plików o nazwie \"dokumenty\", który reprezentuje podkatalog \"/ dokumenty /\" w ramach systemu plików \"pliki\".\n\n### iOS\n\n*   `library`: katalog biblioteki aplikacji\n*   `documents`: dokumenty katalogu aplikacji\n*   `cache`: katalogu pamięci podręcznej aplikacji\n*   `bundle`: pakiet aplikacji; Lokalizacja aplikacji na dysku (tylko do odczytu)\n*   `root`: całe urządzenie systemu plików\n\nDomyślnie katalogi biblioteki i dokumenty mogą być synchronizowane iCloud. Można również zażądać dwóch dodatkowych plików, `library-nosync` i `documents-nosync`, które stanowią specjalny katalog nie zsynchronizowane w `/Library` lub systemu plików `/Documents`.\n"
  },
  {
    "path": "plugins/cordova-plugin-file/doc/pl/plugins.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# Uwagi dla programistów wtyczki\n\nTe notatki są przeznaczone przede wszystkim dla Androida i iOS deweloperów, którzy chcieli pisac pluginy które interfejs z systemu plików za pomocą wtyczki pliku.\n\n## Praca z Cordova pliku system adresów URL\n\nOd wersji 1.0.0, ten plugin ma używane adresy URL z `cdvfile` system dla wszystkich komunikacji przez most, a nie narażać urządzenia raw ścieżki systemu plików JavaScript.\n\nNa stronie JavaScript oznacza to, że FileEntry i DirectoryEntry obiekty mają fullPath atrybut, który jest głównym systemie plików HTML. Jeśli twój plugin JavaScript API akceptuje obiektu FileEntry lub DirectoryEntry, należy zadzwonić `.toURL()` dla tego obiektu przed przekazaniem Altpradl do kodu macierzystego.\n\n### Konwersja cdvfile: / / URL do ścieżki fileystem\n\nWtyczek, które trzeba pisać do systemu plików może chcesz przekonwertować odebranych plików systemu adres URL lokalizacji rzeczywistych plików. Istnieje wiele sposobów robi to, w zależności od macierzystego platformy.\n\nWażne jest, aby pamiętać, że nie wszystkie `cdvfile://` adresy URL są można zmapować na prawdziwe pliki w urządzeniu. Niektóre adresy URL może odnosić się do aktywów na urządzeniu, które nie są reprezentowane przez pliki, lub nawet może odnosić się do zasobów zdalnych. Ze względu na te możliwości wtyczki należy zawsze sprawdzić, czy się znaczącego wyniku powrót podczas próby konwersji adresów URL do ścieżki.\n\n#### Androida\n\nNa Android, najprostsza metoda konwersji `cdvfile://` URL do ścieżki systemu plików jest użycie `org.apache.cordova.CordovaResourceApi` . `CordovaResourceApi`jest kilka metod, które mogą obsługiwać `cdvfile://` adresów URL:\n\n    Widok sieci Web jest członkiem Plugin klasy CordovaResourceApi resourceApi = webView.getResourceApi();\n    \n    Uzyskać URL file:/// reprezentujących ten plik na urządzeniu / / lub ten sam adres URL niezmienione, jeśli nie mogą być mapowane do pliku fileURL Uri = resourceApi.remapUri(Uri.parse(cdvfileURL));\n    \n\nJest również możliwe, aby korzystać z wtyczki pliku bezpośrednio:\n\n    org.apache.cordova.file.FileUtils przywóz;\n    org.apache.cordova.file.FileSystem przywóz;\n    java.net.MalformedURLException przywóz;\n    \n    Uzyskać pliku plugin manager wtyczki FileUtils filePlugin = (FileUtils)webView.pluginManager.getPlugin(\"File\");\n    \n    Biorąc pod uwagę adres URL, uzyskać ścieżkę dla to spróbuj {String ścieżka = filePlugin.filesystemPathForURL(cdvfileURL);} catch (MalformedURLException e) {/ / url plików nie było uznane}\n    \n\nDo przeliczenia ścieżki do `cdvfile://` URL:\n\n    org.apache.cordova.file.LocalFilesystemURL przywóz;\n    \n    Uzyskanie obiektu LocalFilesystemURL na ścieżkę urządzenia / / lub null, jeśli nie może być reprezentowana jako adres URL cdvfile.\n    LocalFilesystemURL url = filePlugin.filesystemURLforLocalPath(path);\n    Dostać reprezentację ciąg adresu URL obiektu String cdvfileURL = url.toString();\n    \n\nJeśli twój plugin tworzy plik, i chcesz zwraca obiekt FileEntry dla niego, użyj pliku plugin:\n\n    Zwraca JSON struktura nadaje się do powrotu do JavaScript, / / lub null, jeśli ten plik nie jest reprezentować jako adres URL cdvfile.\n    Wpis JSONObject = filePlugin.getEntryForFile(file);\n    \n\n#### iOS\n\nCordova na iOS nie korzystać z tego samego `CordovaResourceApi` koncepcji jak Android. Na iOS należy użyć pliku plugin do konwersji między adresach URL i ścieżkach plików.\n\n    Uzyskać obiekt CDVFilesystem URL URL url ciąg CDVFilesystemURL * = [CDVFilesystemURL fileSystemURLWithString:cdvfileURL];\n    Uzyskać ścieżkę dla URL obiektu, stawka zerowa, jeśli nie mogą być mapowane do ścieżki pliku NSString * = [filePlugin filesystemPathForURL:url];\n    \n    \n    Dostać CDVFilesystem URL obiektu na ścieżkę urządzenia lub / / zerowe, jeśli nie może być reprezentowana jako adres URL cdvfile.\n    CDVFilesystemURL * url = [filePlugin fileSystemURLforLocalPath:path];\n    Dostać reprezentację ciąg adresu URL obiektu NSString * cdvfileURL = [url absoluteString];\n    \n\nJeśli twój plugin tworzy plik, i chcesz zwraca obiekt FileEntry dla niego, użyj pliku plugin:\n\n    Dostać CDVFilesystem URL obiektu na ścieżkę urządzenia lub / / zerowe, jeśli nie może być reprezentowana jako adres URL cdvfile.\n    CDVFilesystemURL * url = [filePlugin fileSystemURLforLocalPath:path];\n    Struktura wrócić do JavaScript NSDictionary * wpis = [filePlugin makeEntryForLocalURL:url]\n    \n\n#### JavaScript\n\nW JavaScript, aby uzyskać `cdvfile://` adres URL z obiektu FileEntry lub DirectoryEntry, wystarczy zadzwonić `.toURL()` na to:\n\n    var cdvfileURL = entry.toURL();\n    \n\nW plugin reakcji obsługi przerobić od zwróconych struktury FileEntry do rzeczywistego obiektu wejścia, kod obsługi należy zaimportować pliku plugin i utworzyć nowy obiekt:\n\n    utworzyć odpowiedni wpis obiektu var wpis;\n    Jeśli (entryStruct.isDirectory) {wpis = nowy DirectoryEntry (entryStruct.name, entryStruct.fullPath, nowe FileSystem(entryStruct.filesystemName));} jeszcze {wpis = nowy FileEntry (entryStruct.name, entryStruct.fullPath, nowe FileSystem(entryStruct.filesystemName));}"
  },
  {
    "path": "plugins/cordova-plugin-file/doc/plugins.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\nNotes for plugin developers\n===========================\n\nThese notes are primarily intended for Android and iOS developers who want to write plugins which interface with the file system using the File plugin.\n\nWorking with Cordova file system URLs\n-------------------------------------\n\nSince version 1.0.0, this plugin has used URLs with a `cdvfile` scheme for all communication over the bridge, rather than exposing raw device file system paths to JavaScript. \n\nOn the JavaScript side, this means that FileEntry and DirectoryEntry objects have a fullPath attribute which is relative to the root of the HTML file system. If your plugin's JavaScript API accepts a FileEntry or DirectoryEntry object, you should call `.toURL()` on that object before passing it across the bridge to native code.\n\n### Converting cdvfile:// URLs to fileystem paths\n\nPlugins which need to write to the filesystem may want to convert a received file system URL to an actual filesystem location. There are multiple ways of doing this, depending on the native platform.\n\nIt is important to remember that not all `cdvfile://` URLs are mappable to real files on the device. Some URLs can refer to assets on device which are not represented by files, or can even refer to remote resources. Because of these possibilities, plugins should always test whether they get a meaningful result back when trying to convert URLs to paths.\n\n#### Android\n\nOn Android, the simplest method to convert a `cdvfile://` URL to a filesystem path is to use `org.apache.cordova.CordovaResourceApi`. `CordovaResourceApi` has several methods which can handle `cdvfile://` URLs:\n\n    // webView is a member of the Plugin class\n    CordovaResourceApi resourceApi = webView.getResourceApi();\n\n    // Obtain a file:/// URL representing this file on the device,\n    // or the same URL unchanged if it cannot be mapped to a file\n    Uri fileURL = resourceApi.remapUri(Uri.parse(cdvfileURL));\n\nIt is also possible to use the File plugin directly:\n\n    import org.apache.cordova.file.FileUtils;\n    import org.apache.cordova.file.FileSystem;\n    import java.net.MalformedURLException;\n\n    // Get the File plugin from the plugin manager\n    FileUtils filePlugin = (FileUtils)webView.pluginManager.getPlugin(\"File\");\n\n    // Given a URL, get a path for it\n    try {\n        String path = filePlugin.filesystemPathForURL(cdvfileURL);\n    } catch (MalformedURLException e) {\n        // The filesystem url wasn't recognized\n    }\n\nTo convert from a path to a `cdvfile://` URL:\n\n    import org.apache.cordova.file.LocalFilesystemURL;\n\n    // Get a LocalFilesystemURL object for a device path,\n    // or null if it cannot be represented as a cdvfile URL.\n    LocalFilesystemURL url = filePlugin.filesystemURLforLocalPath(path);\n    // Get the string representation of the URL object\n    String cdvfileURL = url.toString();\n\nIf your plugin creates a file, and you want to return a FileEntry object for it, use the File plugin:\n\n    // Return a JSON structure suitable for returning to JavaScript,\n    // or null if this file is not representable as a cdvfile URL.\n    JSONObject entry = filePlugin.getEntryForFile(file);\n\n#### iOS\n\nCordova on iOS does not use the same `CordovaResourceApi` concept as Android. On iOS, you should use the File plugin to convert between URLs and filesystem paths.\n\n    // Get a CDVFilesystem URL object from a URL string\n    CDVFilesystemURL* url = [CDVFilesystemURL fileSystemURLWithString:cdvfileURL];\n    // Get a path for the URL object, or nil if it cannot be mapped to a file\n    NSString* path = [filePlugin filesystemPathForURL:url];\n    \n\n    // Get a CDVFilesystem URL object for a device path, or\n    // nil if it cannot be represented as a cdvfile URL.\n    CDVFilesystemURL* url = [filePlugin fileSystemURLforLocalPath:path];\n    // Get the string representation of the URL object\n    NSString* cdvfileURL = [url absoluteString];\n\nIf your plugin creates a file, and you want to return a FileEntry object for it, use the File plugin:\n\n    // Get a CDVFilesystem URL object for a device path, or\n    // nil if it cannot be represented as a cdvfile URL.\n    CDVFilesystemURL* url = [filePlugin fileSystemURLforLocalPath:path];\n    // Get a structure to return to JavaScript\n    NSDictionary* entry = [filePlugin makeEntryForLocalURL:url]\n\n#### JavaScript\n\nIn JavaScript, to get a `cdvfile://` URL from a FileEntry or DirectoryEntry object, simply call `.toURL()` on it:\n\n    var cdvfileURL = entry.toURL();\n\nIn plugin response handlers, to convert from a returned FileEntry structure to an actual Entry object, your handler code should import the File plugin and create a new object:\n\n    // create appropriate Entry object\n    var entry;\n    if (entryStruct.isDirectory) {\n        entry = new DirectoryEntry(entryStruct.name, entryStruct.fullPath, new FileSystem(entryStruct.filesystemName));\n    } else {\n        entry = new FileEntry(entryStruct.name, entryStruct.fullPath, new FileSystem(entryStruct.filesystemName));\n    }\n\n"
  },
  {
    "path": "plugins/cordova-plugin-file/doc/ru/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-file\n\nЭтот плагин реализует API файла, позволяя доступ на чтение и запись в файлы, находящиеся на устройстве.\n\nЭтот плагин основан на нескольких спецификации, в том числе: HTML5 API файла <http://www.w3.org/TR/FileAPI/>\n\n(Ныне несуществующей) каталоги и систему расширений Последнее: <http://www.w3.org/TR/2012/WD-file-system-api-20120417/> , хотя большая часть кода, плагин был написан, когда ранее спец был текущим: <http://www.w3.org/TR/2011/WD-file-system-api-20110419/>\n\nОн также реализует уничтожал spec: <http://dev.w3.org/2009/dap/file-system/file-writer.html>\n\nДля использования, пожалуйста, обратитесь к HTML5 скалы отличные [файловой системы статьи.][1]\n\n [1]: http://www.html5rocks.com/en/tutorials/file/filesystem/\n\nОбзор других вариантов хранения найти Cordova [хранения руководства][2].\n\n [2]: http://cordova.apache.org/docs/en/edge/cordova_storage_storage.md.html\n\n## Установка\n\n    cordova plugin add cordova-plugin-file\n    \n\n## Поддерживаемые платформы\n\n*   Amazon Fire OS\n*   Android\n*   BlackBerry 10\n*   Firefox OS\n*   iOS\n*   Windows Phone 7 и 8 *\n*   Windows 8 *\n\n* *Эти платформы не поддерживают `FileReader.readAsArrayBuffer` , ни `FileWriter.write(blob)` .*\n\n## Где хранить файлы\n\nПо состоянию на v1.2.0 приведены URL-адреса для важных файлов в системные каталоги. Каждый URL-адрес в виде *file:///path/to/spot/*и может быть преобразован в `DirectoryEntry` с помощью`window.resolveLocalFileSystemURL()`.\n\n*   `cordova.file.applicationDirectory`-Каталог только для чтения, где установлено приложение. (*iOS*, *Android*, *BlackBerry 10*)\n\n*   `cordova.file.applicationStorageDirectory`-Корневой каталог приложения в песочнице; на iOS это место только для чтения (но определенных подкаталогов [как `/Documents` ], чтения записи). Все данные, содержащиеся в частных в приложение. ( *iOS*, *Android*, *BlackBerry 10*)\n\n*   `cordova.file.dataDirectory`-Хранения стойкие и частных данных в приложения в песочнице с использованием внутренней памяти (на Android, если необходимо использовать внешнюю память, использовать `.externalDataDirectory` ). На iOS, этот каталог не синхронизируется с iCloud (использование `.syncedDataDirectory` ). (*iOS*, *Android*, *BlackBerry 10*)\n\n*   `cordova.file.cacheDirectory`-Каталог для кэшированных данных файлов или все файлы, которые ваше приложение может повторно создать легко. ОС может удалить эти файлы, когда устройства хватает на хранение, тем не менее, приложения не должны опираться на OS, чтобы удалить файлы здесь. (*iOS*, *Android*, *BlackBerry 10*)\n\n*   `cordova.file.externalApplicationStorageDirectory`-Пространство приложения на внешнем хранилище. (*Android*)\n\n*   `cordova.file.externalDataDirectory`-Куда положить файлы данных конкретного приложения на внешнем хранилище. (*Android*)\n\n*   `cordova.file.externalCacheDirectory`-Применение кэш на внешние накопители. (*Android*)\n\n*   `cordova.file.externalRootDirectory`-Корень внешние накопители (SD карта). (*Android*, *BlackBerry 10*)\n\n*   `cordova.file.tempDirectory`-Временный каталог, что ОС можно снять на будет. Не следует полагаться на OS, чтобы очистить этот каталог; Ваше приложение всегда следует удалять файлы в соответствующих случаях. (*iOS*)\n\n*   `cordova.file.syncedDataDirectory`-Содержит файлы приложения, которые должны быть синхронизированы (например, к iCloud). (*iOS*)\n\n*   `cordova.file.documentsDirectory`-Файлы для приложения, но это являются значимыми для других приложений (например, файлы Office). (*iOS*)\n\n*   `cordova.file.sharedDirectory`-Файлы глобально доступной для всех приложений (*BlackBerry 10*)\n\n## Макеты файловой системы\n\nХотя технически деталь реализации, она может быть очень полезно знать как `cordova.file.*` карта свойства физические пути на реальном устройстве.\n\n### iOS расположения файловой системы\n\n| Путь к устройству                              | `Cordova.File.*`            | `iosExtraFileSystems` | r/w? | стойкие? | Очищает ОС | Синхронизация | частные |\n|:---------------------------------------------- |:--------------------------- |:--------------------- |:----:|:--------:|:----------:|:-------------:|:-------:|\n| `/ var/мобильного/применения/< UUID > /` | applicationStorageDirectory | -                     |  r   |   Н/Д    |    Н/Д     |      Н/Д      |   Да    |\n|    `appname.app/`                              | applicationDirectory        | расслоение            |  r   |   Н/Д    |    Н/Д     |      Н/Д      |   Да    |\n|       `www/`                                   | -                           | -                     |  r   |   Н/Д    |    Н/Д     |      Н/Д      |   Да    |\n|    `Documents/`                                | documentsDirectory          | документы             | r/w  |    Да    |    Нет     |      Да       |   Да    |\n|       `NoCloud/`                               | -                           | документы nosync      | r/w  |    Да    |    Нет     |      Нет      |   Да    |\n|    `Library`                                   | -                           | Библиотека            | r/w  |    Да    |    Нет     |      Да?      |   Да    |\n|       `NoCloud/`                               | dataDirectory               | Библиотека nosync     | r/w  |    Да    |    Нет     |      Нет      |   Да    |\n|       `Cloud/`                                 | syncedDataDirectory         | -                     | r/w  |    Да    |    Нет     |      Да       |   Да    |\n|       `Caches/`                                | cacheDirectory              | кэш                   | r/w  |   Да *   | Да * * *| |      Нет      |   Да    |\n|    `tmp/`                                      | tempDirectory               | -                     | r/w  |  Не * *  | Да * * *| |      Нет      |   Да    |\n\n* Файлы сохраняются приложения перезагрузки и обновления, но этот каталог может быть очищен, когда ОС желаний. Ваше приложение должно иметь возможность воссоздать любое содержание, которое может быть удалено.\n\n* * Файлы могут сохраняться перезагрузками app, но не полагайтесь на это поведение. Для продолжения обновления файлов не гарантируется. Приложение должно удалить файлы из этого каталога, когда это применимо, как операционная система не гарантирует когда (или даже если) эти файлы будут удалены.\n\n* * *| ОС может очистить содержимое этого каталога, когда он считает это необходимым, но не полагайтесь на это. Необходимо снять этот каталог в зависимости от вашего приложения.\n\n### Расположения Android файловой системы\n\n| Путь к устройству                 | `Cordova.File.*`                    | `AndroidExtraFileSystems` | r/w? | стойкие? | Очищает ОС | частные |\n|:--------------------------------- |:----------------------------------- |:------------------------- |:----:|:--------:|:----------:|:-------:|\n| `File:///android_asset/`          | applicationDirectory                |                           |  r   |   Н/Д    |    Н/Д     |   Да    |\n| `/ Data/data/< app-id > /`  | applicationStorageDirectory         | -                         | r/w  |   Н/Д    |    Н/Д     |   Да    |\n|    `cache`                        | cacheDirectory                      | кэш                       | r/w  |    Да    |    Да *    |   Да    |\n|    `files`                        | dataDirectory                       | файлы                     | r/w  |    Да    |    Нет     |   Да    |\n|       `Documents`                 |                                     | документы                 | r/w  |    Да    |    Нет     |   Да    |\n| `< sdcard > /`              | externalRootDirectory               | SDCard                    | r/w  |    Да    |    Нет     |   Нет   |\n|    `Android/data/<app-id>/` | externalApplicationStorageDirectory | -                         | r/w  |    Да    |    Нет     |   Нет   |\n|       `cache`                     | externalCacheDirectry               | кэш внешние               | r/w  |    Да    |   Не * *   |   Нет   |\n|       `files`                     | externalDataDirectory               | файлы внешние             | r/w  |    Да    |    Нет     |   Нет   |\n\n* ОС может периодически удалять этот каталог, но не полагайтесь на это поведение. Очистите содержимое этого каталога в зависимости от вашего приложения. Если пользователь вручную очистить кэш, содержимое этого каталога будут удалены.\n\n* * ОС не ясно этот каталог автоматически; Вы несете ответственность за управление содержимым самостоятельно. Если пользователь вручную очистить кэш, содержимое каталога будут удалены.\n\n**Примечание**: Если нельзя монтировать внешние накопители, `cordova.file.external*` Свойства`null`.\n\n### BlackBerry 10 расположения файловой системы\n\n| Путь к устройству                                   | `Cordova.File.*`            | r/w? | стойкие? | Очищает ОС | частные |\n|:--------------------------------------------------- |:--------------------------- |:----:|:--------:|:----------:|:-------:|\n| `File:///Accounts/1000/AppData/ < app id > /` | applicationStorageDirectory |  r   |   Н/Д    |    Н/Д     |   Да    |\n|    `app/native`                                     | applicationDirectory        |  r   |   Н/Д    |    Н/Д     |   Да    |\n|    `data/webviews/webfs/temporary/local__0`         | cacheDirectory              | r/w  |   Нет    |     Да     |   Да    |\n|    `data/webviews/webfs/persistent/local__0`        | dataDirectory               | r/w  |    Да    |    Нет     |   Да    |\n| `File:///Accounts/1000/Removable/SDCard`            | externalRemovableDirectory  | r/w  |    Да    |    Нет     |   Нет   |\n| `File:///Accounts/1000/Shared`                      | sharedDirectory             | r/w  |    Да    |    Нет     |   Нет   |\n\n*Примечание*: при развертывании приложения для работы периметра, все пути относительны /accounts/1000-enterprise.\n\n## Особенности Android\n\n### Местоположение Android постоянного хранения\n\nЕсть несколько допустимых мест для хранения постоянных файлов на устройстве Android. Смотрите [эту страницу][3] для широкого обсуждения различных возможностей.\n\n [3]: http://developer.android.com/guide/topics/data/data-storage.html\n\nПредыдущие версии плагина будет выбирать расположение временных и постоянных файлов при запуске, основанный на ли устройство утверждал, что SD-карта (или эквивалентные хранения раздел) был смонтирован. Если была смонтирована SD-карты, или если большой внутренней памяти раздел был доступен (такие как на устройствах Nexus,), то постоянные файлы будут храниться в корне этого пространства. Это означало, что все apps Cordova могли видеть все файлы, имеющиеся на карте.\n\nЕсли SD-карты не был доступен, то предыдущих версий будет хранить данные в `/data/data/<packageId>` , которая изолирует приложения друг от друга, но все еще может причина данные распределяются между пользователями.\n\nЭто теперь можно выбрать, следует ли хранить файлы в месте хранения внутренних файлов, или с использованием предыдущей логики, с предпочтением в вашем приложении `config.xml` файл. Чтобы сделать это, добавить один из этих двух линий в `config.xml` :\n\n    <preference name=\"AndroidPersistentFileLocation\" value=\"Internal\" />\n    \n    <preference name=\"AndroidPersistentFileLocation\" value=\"Compatibility\" />\n    \n\nБез этой линии, будет использовать файл плагина `Compatibility` по умолчанию. Если тег предпочтений присутствует и не является одним из этих значений, приложение не запустится.\n\nЕсли ранее была отгружена приложения для пользователей, используя старые (до 1.0) версию этого плагина и имеет сохраненные файлы в файловой системе постоянных, то вы должны установить предпочтения `Compatibility` . Переключение местоположение для «Внутреннего» будет означать, что существующие пользователи, которые обновить их применение может быть не в состоянии получить доступ к их сохраненные ранее файлы, в зависимости от их устройства.\n\nЕсли ваше приложение является новым или ранее никогда не хранит файлы в стойких файловой системы, то `Internal` как правило рекомендуется настройка.\n\n## Особенности iOS\n\n*   `cordova.file.applicationStorageDirectory`доступен только для чтения; попытка хранения файлов в корневом каталоге не удастся. Использовать один из других `cordova.file.*` свойства, определенные для iOS (только `applicationDirectory` и `applicationStorageDirectory` доступны только для чтения).\n*   `FileReader.readAsText(blob, encoding)` \n    *   `encoding`Параметр не поддерживается, и UTF-8 кодирование действует всегда.\n\n### iOS место постоянного хранения\n\nСуществует два допустимых местоположений для хранения постоянных файлов на устройства iOS: документы каталогов и библиотека. Предыдущие версии плагина только когда-либо постоянные файлы хранятся в папке документы. Это был побочный эффект делает все файлы приложения в iTunes, который часто был непреднамеренным, особенно для приложений, которые обрабатывают большое количество мелких файлов, вместо того, чтобы производить полный комплект документов для экспорта, который является цель каталога.\n\nЭто теперь можно выбрать, следует ли хранить файлы в документы или каталоге библиотеки, с предпочтением в вашем приложении `config.xml` файл. Чтобы сделать это, добавить один из этих двух линий в `config.xml` :\n\n    <preference name=\"iosPersistentFileLocation\" value=\"Library\" />\n    \n    <preference name=\"iosPersistentFileLocation\" value=\"Compatibility\" />\n    \n\nБез этой линии, будет использовать файл плагина `Compatibility` по умолчанию. Если тег предпочтений присутствует и не является одним из этих значений, приложение не запустится.\n\nЕсли ранее была отгружена приложения для пользователей, используя старые (до 1.0) версию этого плагина и имеет сохраненные файлы в файловой системе постоянных, то вы должны установить предпочтения `Compatibility` . Переключение расположения `Library` будет означать, что существующих пользователей обновить их применения будет не в состоянии получить доступ к их сохраненные ранее файлы.\n\nЕсли ваше приложение является новым или ранее никогда не хранит файлы в стойких файловой системы, то `Library` как правило рекомендуется настройка.\n\n## Особенности Firefox OS\n\nAPI файловой системы изначально не поддерживается Firefox OS и реализуется как оболочка поверх indexedDB.\n\n*   Не вынимая непустые каталоги\n*   Не поддерживает метаданные для каталогов\n*   Методы `copyTo` и `moveTo` не поддерживает каталоги\n\nПоддерживаются следующие пути данных: * `applicationDirectory` -использует `xhr` чтобы получить локальные файлы, которые упакованы с приложением. * `dataDirectory` - Для постоянных данных конкретного приложения файлов. * `cacheDirectory` -Кэшированных файлов, которые должны выжить перезагрузки приложения (Apps не следует полагаться на OS, чтобы удалить файлы из здесь).\n\n## Обновление примечания\n\nВ v1.0.0 этого плагина `FileEntry` и `DirectoryEntry` структур изменились, более соответствует опубликованной спецификации.\n\nПредыдущий (pre-1.0.0) версии плагина хранятся устройства Абсолют файл расположение в `fullPath` свойства `Entry` объектов. Эти пути обычно будет выглядеть\n\n    /var/mobile/Applications/<application UUID>/Documents/path/to/file  (iOS)\n    /storage/emulated/0/path/to/file                                    (Android)\n    \n\nЭти пути также были возвращены `toURL()` метода `Entry` объектов.\n\nС v1.0.0 `fullPath` атрибут является путь к файлу, *заданный относительно корня файловой системы HTML*. Таким образом, выше пути будет теперь оба быть представлено `FileEntry` объект с `fullPath` из\n\n    /path/to/file\n    \n\nЕсли ваше приложение работает с устройства Абсолют путями, и ранее были получены эти пути через `fullPath` свойства `Entry` объектов, то вам следует обновить код для использования `entry.toURL()` вместо этого.\n\nДля обратной совместимости, `resolveLocalFileSystemURL()` метод будет принимать путь Абсолют устройства и будет возвращать `Entry` объект, соответствующий его, до тех пор, как этот файл существует в рамках либо `TEMPORARY` или `PERSISTENT` файловых систем.\n\nЭто особенно была проблема с плагином передачи файлов, который ранее использовался устройства Абсолют пути (и все еще может принять их). Он был обновлен для корректной работы с файловой системы URL, так что замена `entry.fullPath` с `entry.toURL()` должен решить любые вопросы, получить этот плагин для работы с файлами на устройстве.\n\nВ v1.1.0 возвращаемое значение из `toURL()` был изменен (см. \\[CB-6394\\] (https://issues.apache.org/jira/browse/CB-6394)) для возвращения URL-адрес абсолютным «file://». где это возможно. Для обеспечения ' cdvfile:'-вы можете использовать URL-адрес `toInternalURL()` сейчас. Этот метод будет возвращать теперь файловой системы URL формы\n\n    cdvfile://localhost/persistent/path/to/file\n    \n\nкоторый может использоваться для уникальной идентификации файла.\n\n## Список кодов ошибок и значения\n\nКогда возникает ошибка, один из следующих кодов будет использоваться.\n\n| Код | Постоянная                    |\n| ---:|:----------------------------- |\n|   1 | `NOT_FOUND_ERR`               |\n|   2 | `SECURITY_ERR`                |\n|   3 | `ABORT_ERR`                   |\n|   4 | `NOT_READABLE_ERR`            |\n|   5 | `ENCODING_ERR`                |\n|   6 | `NO_MODIFICATION_ALLOWED_ERR` |\n|   7 | `INVALID_STATE_ERR`           |\n|   8 | `SYNTAX_ERR`                  |\n|   9 | `INVALID_MODIFICATION_ERR`    |\n|  10 | `QUOTA_EXCEEDED_ERR`          |\n|  11 | `TYPE_MISMATCH_ERR`           |\n|  12 | `PATH_EXISTS_ERR`             |\n\n## Настройка плагина (опционально)\n\nНабор доступных файловых систем может быть настроен на платформе. IOS и Android признают <preference> тег в `config.xml` имена которых файловые системы для установки. По умолчанию включены все корни файловой системы.\n\n    <preference name=\"iosExtraFilesystems\" value=\"library,library-nosync,documents,documents-nosync,cache,bundle,root\" />\n    <preference name=\"AndroidExtraFilesystems\" value=\"files,files-external,documents,sdcard,cache,cache-external,root\" />\n    \n\n### Android\n\n*   `files`: Каталог для хранения внутреннего файла приложения\n*   `files-external`: Каталог хранения внешнего файла приложения\n*   `sdcard`: Глобальный внешний файл каталог хранения (это корень SD-карты, если таковая установлена). Вы должны иметь `android.permission.WRITE_EXTERNAL_STORAGE` разрешение использовать это.\n*   `cache`: Каталог внутреннего кэша приложения\n*   `cache-external`: Каталог приложения внешней кэш-памяти\n*   `root`: Все устройство файловой системы\n\nAndroid поддерживает также Специальный файловую систему под названием «документы», которая представляет подкаталог «/ документы /» в пределах файловой системы «файлы».\n\n### iOS\n\n*   `library`: Каталог библиотеки приложения\n*   `documents`: Каталог документов приложения\n*   `cache`: Каталог кэша приложения\n*   `bundle`: Пакет приложения; расположение самого приложения на диске (только для чтения)\n*   `root`: Все устройство файловой системы\n\nПо умолчанию каталоги библиотеки и документы можно синхронизировать с iCloud. Вы также можете заказать два дополнительных файловых систем, `library-nosync` и `documents-nosync` , которые представляют Специальный каталог не синхронизируются в `/Library` или `/Documents` файловой системы.\n"
  },
  {
    "path": "plugins/cordova-plugin-file/doc/ru/plugins.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# Примечания для разработчиков плагинов\n\nЭти примечания предназначены прежде всего для Android и iOS разработчиков, которые хотят писать плагины какой интерфейс с файловой системой, с помощью файла плагина.\n\n## Работа с Кордова файловой системы URL\n\nНачиная с версии 1.0.0, этот плагин использует URL-адресов с `cdvfile` схема для всех коммуникации через мост, а не подвергая пути файловой системы raw устройства для JavaScript.\n\nНа стороне JavaScript это означает, что объекты DirectoryEntry и FileEntry fullPath атрибут, который является по отношению к корневой файловой системе HTML. Если ваш плагин JavaScript API принимает объект DirectoryEntry или FileEntry, необходимо вызвать `.toURL()` для этого объекта перед передачей их через мост в машинный код.\n\n### Преобразование cdvfile: / / URL-адреса в пути fileystem\n\nПлагины, которые нужно написать в файловой системе может потребоваться преобразовать URL-адреса системы полученный файл в место фактической файловой системы. Существует несколько способов сделать это, в зависимости от родной платформе.\n\nВажно помнить, что не все `cdvfile://` URL-адреса являются отображаемыми файлами на устройстве. Некоторые URL может относиться к активам на устройстве, которые не представлены файлы, или может даже обратиться к удаленным ресурсам. Из-за эти возможности плагины следует всегда проверять ли они получают результат обратно при попытке преобразовать URL-адреса в пути.\n\n#### Android\n\nНа Android, самый простой способ для преобразования `cdvfile://` URL-адрес к пути файловой системы заключается в использовании `cordova-plugin-CordovaResourceApi` . `CordovaResourceApi`Есть несколько методов, которые можно обработать `cdvfile://` URL-адреса:\n\n    // webView is a member of the Plugin class\n    CordovaResourceApi resourceApi = webView.getResourceApi();\n    \n    // Obtain a file:/// URL representing this file on the device,\n    // or the same URL unchanged if it cannot be mapped to a file\n    Uri fileURL = resourceApi.remapUri(Uri.parse(cdvfileURL));\n    \n\nЭто также можно использовать плагин файл непосредственно:\n\n    import cordova-plugin-file.FileUtils;\n    import cordova-plugin-file.FileSystem;\n    import java.net.MalformedURLException;\n    \n    // Get the File plugin from the plugin manager\n    FileUtils filePlugin = (FileUtils)webView.pluginManager.getPlugin(\"File\");\n    \n    // Given a URL, get a path for it\n    try {\n        String path = filePlugin.filesystemPathForURL(cdvfileURL);\n    } catch (MalformedURLException e) {\n        // The filesystem url wasn't recognized\n    }\n    \n\nДля преобразования пути к `cdvfile://` URL-адрес:\n\n    import cordova-plugin-file.LocalFilesystemURL;\n    \n    // Get a LocalFilesystemURL object for a device path,\n    // or null if it cannot be represented as a cdvfile URL.\n    LocalFilesystemURL url = filePlugin.filesystemURLforLocalPath(path);\n    // Get the string representation of the URL object\n    String cdvfileURL = url.toString();\n    \n\nЕсли ваш плагин создает файл, и вы хотите вернуть объект FileEntry для него, используйте файл плагина:\n\n    // Return a JSON structure suitable for returning to JavaScript,\n    // or null if this file is not representable as a cdvfile URL.\n    JSONObject entry = filePlugin.getEntryForFile(file);\n    \n\n#### iOS\n\nКордова на iOS не использовать те же `CordovaResourceApi` понятие, как Android. На iOS вы должны использовать файл плагин для преобразования URL-адреса и пути файловой системы.\n\n    // Get a CDVFilesystem URL object from a URL string\n    CDVFilesystemURL* url = [CDVFilesystemURL fileSystemURLWithString:cdvfileURL];\n    // Get a path for the URL object, or nil if it cannot be mapped to a file\n    NSString* path = [filePlugin filesystemPathForURL:url];\n    \n    \n    // Get a CDVFilesystem URL object for a device path, or\n    // nil if it cannot be represented as a cdvfile URL.\n    CDVFilesystemURL* url = [filePlugin fileSystemURLforLocalPath:path];\n    // Get the string representation of the URL object\n    NSString* cdvfileURL = [url absoluteString];\n    \n\nЕсли ваш плагин создает файл, и вы хотите вернуть объект FileEntry для него, используйте файл плагина:\n\n    // Get a CDVFilesystem URL object for a device path, or\n    // nil if it cannot be represented as a cdvfile URL.\n    CDVFilesystemURL* url = [filePlugin fileSystemURLforLocalPath:path];\n    // Get a structure to return to JavaScript\n    NSDictionary* entry = [filePlugin makeEntryForLocalURL:url]\n    \n\n#### JavaScript\n\nВ JavaScript, чтобы получить `cdvfile://` URL от объекта DirectoryEntry или FileEntry, просто позвоните `.toURL()` на него:\n\n    var cdvfileURL = entry.toURL();\n    \n\nВ плагин обработчики ответ для преобразования из возвращаемой структуры FileEntry объект фактического вступления, код обработчика следует импортировать файл плагина и создайте новый объект:\n\n    // create appropriate Entry object\n    var entry;\n    if (entryStruct.isDirectory) {\n        entry = new DirectoryEntry(entryStruct.name, entryStruct.fullPath, new FileSystem(entryStruct.filesystemName));\n    } else {\n        entry = new FileEntry(entryStruct.name, entryStruct.fullPath, new FileSystem(entryStruct.filesystemName));\n    }\n"
  },
  {
    "path": "plugins/cordova-plugin-file/doc/zh/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-file\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-file.svg)](https://travis-ci.org/apache/cordova-plugin-file)\n\n這個外掛程式實現檔 API 允許對檔駐留在該設備上的讀/寫訪問。\n\n這個外掛程式基於幾個規格，包括： HTML5 檔 API [HTTP://www.w3.org/TR/FileAPI/](http://www.w3.org/TR/FileAPI/)\n\n（現已解散） 目錄和系統擴展最新： [HTTP://www.w3.org/TR/2012/WD-file-system-api-20120417/](http://www.w3.org/TR/2012/WD-file-system-api-20120417/)雖然大部分的外掛程式代碼寫時較早的規格是當前： [HTTP://www.w3.org/TR/2011/WD-file-system-api-20110419/](http://www.w3.org/TR/2011/WD-file-system-api-20110419/)\n\n它還實現 FileWriter 規格： [HTTP://dev.w3.org/2009/dap/file-system/file-writer.html](http://dev.w3.org/2009/dap/file-system/file-writer.html)\n\n用法，請參閱對 HTML5 的岩石優秀[檔案系統文章。](http://www.html5rocks.com/en/tutorials/file/filesystem/)\n\n其他存儲選項的概述，請參閱科爾多瓦的[存儲指南](http://cordova.apache.org/docs/en/edge/cordova_storage_storage.md.html).\n\n這個外掛程式定義全球 `cordova.file` 物件。\n\n雖然在全球範圍內，它不可用直到 `deviceready` 事件之後。\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(cordova.file);\n    }\n    \n\n## 安裝\n\n    cordova plugin add cordova-plugin-file\n    \n\n## 支援的平臺\n\n  * 亞馬遜火 OS\n  * Android 系統\n  * 黑莓 10\n  * 火狐瀏覽器作業系統\n  * iOS\n  * Windows Phone 7 和 8 *\n  * Windows 8 *\n  * Windows*\n  * 瀏覽器\n\n\\* *These platforms do not support `FileReader.readAsArrayBuffer` nor `FileWriter.write(blob)`.*\n\n## 存儲檔的位置\n\n截至 v1.2.0，提供重要的檔案系統目錄的 Url。 每個 URL 位於表單 *file:///path/to/spot/*，和可以轉換為使用 `window.resolveLocalFileSystemURL()` 的 `DirectoryEntry`.\n\n  * `cordova.file.applicationDirectory`-唯讀目錄在哪裡安裝的應用程式。（*iOS*、*安卓*、*黑莓 10*)\n\n  * `cordova.file.applicationStorageDirectory`-根目錄下的應用程式的沙箱 ；在 iOS 上此位置是唯讀 （但特定的子目錄 [像 `/Documents` ] 都是讀寫）。 中包含的所有資料都是私有的應用程式。 （ *iOS*、*安卓*、*黑莓 10*)\n\n  * `cordova.file.dataDirectory`資料持久性和私有資料存儲在內部記憶體使用的應用程式的沙箱內 （在安卓系統，如果你需要使用外部儲存體，使用 `.externalDataDirectory` ）。 在 iOS，此目錄不與 iCloud 同步 （使用 `.syncedDataDirectory` ）。 （*iOS*、*安卓*、*黑莓 10*)\n\n  * `cordova.file.cacheDirectory`-緩存的資料檔案或您的應用程式重新可以輕鬆地創建的任何檔的目錄。 作業系統可能會刪除這些檔，該設備在存儲上運行低時，然而，應用程式不應依賴的作業系統，請刪除檔在這裡。 （*iOS*、*安卓*、*黑莓 10*)\n\n  * `cordova.file.externalApplicationStorageDirectory`-應用程式外部存儲上的空間。（*安卓*)\n\n  * `cordova.file.externalDataDirectory`-放在外部存儲特定于應用程式的資料檔案的位置。（*安卓*)\n\n  * `cordova.file.externalCacheDirectory`-在外部存儲應用程式緩存。（*安卓*)\n\n  * `cordova.file.externalRootDirectory`-外部存儲 （SD 卡） 的根。（*安卓*、*黑莓 10*)\n\n  * `cordova.file.tempDirectory`-OS 可以清除時的空目錄會。 不依賴于 OS，以清除此目錄 ；您的應用程式，應總是移除作為適用的檔。 （*iOS*)\n\n  * `cordova.file.syncedDataDirectory`-保存應同步 （例如到 iCloud） 的特定于應用程式的檔。（*iOS*)\n\n  * `cordova.file.documentsDirectory`-檔私有的應用程式，但這是對其他應用程式 （例如 Office 檔） 有意義。（*iOS*)\n\n  * `cordova.file.sharedDirectory`-對所有應用程式 （*黑莓 10*全域可用的檔)\n\n## 檔案系統佈局\n\n雖然技術上實現的細節，它可以是很有必要瞭解如何 `cordova.file.*` 屬性對應到實體路徑在實際設備上。\n\n### iOS 檔案系統佈局\n\n| 設備路徑                                           | `cordova.file.*`            | `iosExtraFileSystems` | r/w 嗎？ |  持續性嗎？  |    OS 清除     | 同步  | 私人 |\n|:---------------------------------------------- |:--------------------------- |:--------------------- |:------:|:-------:|:------------:|:---:|:--:|\n| `/ 無功/移動/應用程式/< UUID > /`                | applicationStorageDirectory | -                     |   r    |   不適用   |     不適用      | 不適用 | 是啊 |\n| &nbsp;&nbsp;&nbsp;`appname.app/`               | applicationDirectory        | 束                     |   r    |   不適用   |     不適用      | 不適用 | 是啊 |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`www/`     | -                           | -                     |   r    |   不適用   |     不適用      | 不適用 | 是啊 |\n| &nbsp;&nbsp;&nbsp;`Documents/`                 | documentsDirectory          | 檔                     |  r/w   |   是啊    |      無       | 是啊  | 是啊 |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`NoCloud/` | -                           | 檔 nosync              |  r/w   |   是啊    |      無       |  無  | 是啊 |\n| &nbsp;&nbsp;&nbsp;`Library`                    | -                           | 圖書館                   |  r/w   |   是啊    |      無       | 是嗎？ | 是啊 |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`NoCloud/` | dataDirectory               | 圖書館 nosync            |  r/w   |   是啊    |      無       |  無  | 是啊 |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`Cloud/`   | syncedDataDirectory         | -                     |  r/w   |   是啊    |      無       | 是啊  | 是啊 |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`Caches/`  | cacheDirectory              | 快取記憶體                 |  r/w   |  是啊 *   | 是啊**\\* |  無  | 是啊 |\n| &nbsp;&nbsp;&nbsp;`tmp/`                       | tempDirectory               | -                     |  r/w   | 無** | 是啊**\\* |  無  | 是啊 |\n\n\\ * 檔堅持跨應用程式重新開機和升級，但每當 OS 的欲望，可以清除此目錄。您的應用程式應該能夠重新創建任何內容可能會被刪除。\n\n**檔可能會持續整個應用程式重新開機，但不是依賴于這種行為。 不保證檔在更新之間持續存在。 您的應用程式時適用，是應該刪除此目錄的檔，因為作業系統並不能保證何時 （或即使） 中刪除這些檔。\n\n**\\ * 作業系統可能會清除此目錄的內容，每當它感覺它是必要的但做不依賴于此。 你應該清除此目錄為適合您的應用程式。\n\n### Android 的檔案系統佈局\n\n| 設備路徑                                             | `cordova.file.*`                    | `AndroidExtraFileSystems` | r/w 嗎？ | 持續性嗎？ |  OS 清除  | 私人 |\n|:------------------------------------------------ |:----------------------------------- |:------------------------- |:------:|:-----:|:-------:|:--:|\n| `file:///android_asset/`                         | applicationDirectory                |                           |   r    |  不適用  |   不適用   | 是啊 |\n| `/ 資料資料/< 應用程式 id > /`                     | applicationStorageDirectory         | -                         |  r/w   |  不適用  |   不適用   | 是啊 |\n| &nbsp;&nbsp;&nbsp;`cache`                        | cacheDirectory                      | 快取記憶體                     |  r/w   |  是啊   | 是啊\\*  | 是啊 |\n| &nbsp;&nbsp;&nbsp;`files`                        | dataDirectory                       | 檔                         |  r/w   |  是啊   |    無    | 是啊 |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`Documents`  |                                     | 檔                         |  r/w   |  是啊   |    無    | 是啊 |\n| `< sd 卡 > /`                               | externalRootDirectory               | sd 卡                      |  r/w   |  是啊   |    無    | 無  |\n| &nbsp;&nbsp;&nbsp;`Android/data/<app-id>/` | externalApplicationStorageDirectory | -                         |  r/w   |  是啊   |    無    | 無  |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`cache`      | externalCacheDirectry               | 外部快取記憶體                   |  r/w   |  是啊   | 無** | 無  |\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`files`      | externalDataDirectory               | 外部檔                       |  r/w   |  是啊   |    無    | 無  |\n\n\\ * 作業系統可能定期清除此目錄，但不是依賴于這種行為。 清除此為適合您的應用程式的目錄的內容。 使用者應手動清除緩存，將刪除此目錄的內容。\n\n** OS 不會清除此目錄自動;你是負責管理自己的內容。 使用者應手動清除緩存，目錄中的內容將被刪除。\n\n**注**： 如果外部存儲無法裝入，`cordova.file.external*` 屬性為 `空`.\n\n### 黑莓 10 檔案系統佈局\n\n| 設備路徑                                                        | `cordova.file.*`            | r/w 嗎？ | 持續性嗎？ | OS 清除 | 私人 |\n|:----------------------------------------------------------- |:--------------------------- |:------:|:-----:|:-----:|:--:|\n| `file:///accounts/1000/appdata/ < 應用程式 id > /`        | applicationStorageDirectory |   r    |  不適用  |  不適用  | 是啊 |\n| &nbsp;&nbsp;&nbsp;`app/native`                              | applicationDirectory        |   r    |  不適用  |  不適用  | 是啊 |\n| &nbsp;&nbsp;&nbsp;`data/webviews/webfs/temporary/local__0`  | cacheDirectory              |  r/w   |   無   |  是啊   | 是啊 |\n| &nbsp;&nbsp;&nbsp;`data/webviews/webfs/persistent/local__0` | dataDirectory               |  r/w   |  是啊   |   無   | 是啊 |\n| `file:///accounts/1000/removable/sdcard`                    | externalRemovableDirectory  |  r/w   |  是啊   |   無   | 無  |\n| `file:///accounts/1000/shared`                              | sharedDirectory             |  r/w   |  是啊   |   無   | 無  |\n\n*注意*： 當應用程式部署工作週邊時，所有路徑都是相對於 /accounts/1000-enterprise。\n\n## Android 的怪癖\n\n### Android 的持久性存儲位置\n\n有很多有效的位置來存儲持久性檔在 Android 設備上。 請參閱 [此頁面](http://developer.android.com/guide/topics/data/data-storage.html) 的各種可能性進行廣泛討論。\n\n以前版本的外掛程式會選擇在啟動時，基於該設備是否聲稱 SD 卡 （或等效存儲分區） 展開，臨時和永久檔的位置。 如果被掛載 SD 卡，或一個大的內部存儲分區可用 （如 nexus 系列設備上） 然後持久性檔將存儲在該空間的根目錄中。 這意味著所有的科爾多瓦應用程式可以看到所有可用的檔在卡片上。\n\n如果 SD 卡不是可用的那麼以前的版本中將存儲資料下的 `/data/data/<packageId>`，其中隔離應用程式從彼此，但仍可能導致使用者之間共用的資料。\n\n現在可以選擇是否將檔存儲在內部檔的存儲位置，或使用以前的邏輯，與您的應用程式的 `config.xml` 檔中的偏好。 要執行此操作，請將以下兩行之一添加到 `config.xml`：\n\n    <preference name=\"AndroidPersistentFileLocation\" value=\"Internal\" />\n    \n    <preference name=\"AndroidPersistentFileLocation\" value=\"Compatibility\" />\n    \n\n如果這條線，沒有檔外掛程式將使用 `Compatibility` 作為預設值。如果首選項標記存在，並不是這些值之一，應用程式將無法啟動。\n\n如果您的應用程式以前已被運到使用者，使用較舊的 （預 1.0） 版本的這個外掛程式，並具有持久性的檔，系統中存儲的檔，然後您應該設置 `Compatibility` 偏好。 切換到\"Internal\"的位置，將意味著現有使用者升級他們的應用程式可能無法訪問他們以前存儲的檔，具體取決於他們的設備。\n\n如果您的應用程式是新的或以前從未有持久性的檔案系統中存儲檔，那麼通常建議使用 `Internal` 設置。\n\n### 緩慢的遞迴操作為 /android_asset 的\n\n上市資產目錄是在 android 系統很慢的。 你可以讓時間加速了不過，通過將`src/android/build-extras.gradle`添加到您的 android 專案的根 (也需要 cordova-android@4.0.0 或更高版本)。\n\n## iOS 的怪癖\n\n  * `cordova.file.applicationStorageDirectory`是唯讀的 ；試圖存儲內的根目錄中的檔將會失敗。 使用的另一個 `cordova.file.*` 為 iOS 定義的屬性 （只有 `applicationDirectory` 和 `applicationStorageDirectory` 都是唯讀）。\n  * `FileReader.readAsText(blob, encoding)` \n      * `encoding`參數不受支援，而 utf-8 編碼總是效果。\n\n### iOS 的持久性存儲位置\n\n有兩個有效的位置來存儲持久性在 iOS 設備上的檔： 檔目錄和圖書館目錄。 以前版本的外掛程式永遠只能將持久性檔存儲在文檔目錄中。 這已經使所有應用程式檔可見在 iTunes，往往是無意為之，尤其是對於處理大量小檔的應用程式中，而不是生產供出口，該目錄的既定的目標是證件齊全的副作用。\n\n現在可以選擇是否將檔存儲在檔或庫目錄，與您的應用程式的 `config.xml` 檔中的偏好。 要執行此操作，請將以下兩行之一添加到 `config.xml`：\n\n    <preference name=\"iosPersistentFileLocation\" value=\"Library\" />\n    \n    <preference name=\"iosPersistentFileLocation\" value=\"Compatibility\" />\n    \n\n如果這條線，沒有檔外掛程式將使用 `Compatibility` 作為預設值。如果首選項標記存在，並不是這些值之一，應用程式將無法啟動。\n\n如果您的應用程式以前已被運到使用者，使用較舊的 （預 1.0） 版本的這個外掛程式，並具有持久性的檔，系統中存儲的檔，然後您應該設置 `Compatibility` 偏好。 切換到 `Library` 的位置，將意味著現有使用者升級他們的應用程式將無法訪問他們以前存儲的檔。\n\n如果您的應用程式是新的或以前從未有持久性的檔案系統中存儲檔，那麼通常建議使用 `Internal` 設置。\n\n## 火狐瀏覽器作業系統的怪癖\n\n檔案系統 API 本身不支援火狐瀏覽器的作業系統，作為墊片在 indexedDB 上實現的。\n\n  * 不會失敗時刪除非空的目錄\n  * 不支援中繼資料的目錄\n  * 方法 `copyTo` 和 `moveTo` 不支援目錄\n\n支援以下資料路徑： * `applicationDirectory`-使用 `xhr` 獲取與應用程式打包的本地檔。 `dataDirectory`-用於持久性的特定于應用程式的資料檔案。 `cacheDirectory`-生存應重新開機應用程式的快取檔案 （應用程式不應依賴作業系統來刪除檔在這裡）。\n\n## 瀏覽器的怪癖\n\n### 常見的怪癖和備註\n\n  * 每個瀏覽器使用其自己的沙箱檔案系統。IE 和火狐瀏覽器使用 IndexedDB 作為一個基地。所有瀏覽器都使用正斜杠作為路徑中的目錄分隔符號。\n  * 目錄條目不得不先後創建。 例如，調用 `fs.root.getDirectory (' dir1/dir2 '，{create:true}，successCallback，errorCallback）`，如果不存在 dir1 將失敗。\n  * 外掛程式將請求使用者許可權，以便在應用程式初次開機使用持久性存儲。 \n  * 外掛程式支援 `cdvfile://localhost` （本地資源） 只。通過 `cdvfile` 不支援外部資源即.\n  * 該外掛程式不遵循 [\"檔案系統 API 8.3 命名限制\"](http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions).\n  * Blob 和檔 ' `close` 功能不受支援。\n  * `FileSaver` 和 `BlobBuilder` 不支援這個外掛程式，沒有存根 (stub)。\n  * 該外掛程式不支援 `requestAllFileSystems`。這個功能也是缺少規範中。\n  * 在目錄中的條目將不會被刪除，如果您使用 `create: true` 標誌為現有目錄。\n  * 不支援通過建構函式創建的檔。你應該使用 entry.file 方法。\n  * 每個瀏覽器使用它自己的形式為 blob 的 URL 引用。\n  * 支援 `readAsDataURL` 功能，但在 Chrome 中的媒體類型取決於輸入副檔名，在 IE 中的媒體類型都始終空著 （這是 `純文字` 按照說明書一樣），在 Firefox 中的媒體類型始終是 `應用程式/八位位元組流`。 例如，如果內容是 `abcdefg` 然後火狐瀏覽器返回 `資料： 應用程式 / 八位位元組流 ； base64，YWJjZGVmZw = =`，即返回 `資料： ； base64，YWJjZGVmZw = =`，鉻返回 `資料： < 媒體類型根據擴展條目名稱 > ； base64，YWJjZGVmZw = =`.\n  * 在表單 `file:///persistent/path/to/entry` 火狐瀏覽器 IE），`toInternalURL` 返回的路徑。 鉻在表單 `cdvfile://localhost/persistent/file` 返回的路徑.\n\n### 鉻的怪癖\n\n  * 設備準備好事件之後，chrome 檔案系統並不能立即準備。作為一種變通方法，您可以訂閱到 `filePluginIsReady` 事件。示例： \n\n```javascript\nwindow.addEventListener('filePluginIsReady', function(){ console.log('File plugin is ready');}, false);\n```\n\n你可以使用 `window.isFilePluginReadyRaised` 函數來檢查是否已經引發了事件。 -window.requestFileSystem 臨時和永久性檔案系統配額並不局限于鉻。 為增加中鉻的持久性存儲，您需要調用 `window.initPersistentFileSystem` 方法。 預設情況下，持久性存儲配額為 5 MB。 鉻需要 `— — 允許--訪問-從-檔` 通過 `file:///` 協定運行參數對 API 的支援。 -如果您使用標誌，將不更改 `檔` 物件 `{create:true}` 現有 `條目` 的時候。 -事件 `可取消` 屬性設置為 true 在 Chrome 中。 這是違反了 [規範](http://dev.w3.org/2009/dap/file-system/file-writer.html)。 -中鉻的 `toURL` 函數返回 `檔案系統：`-首碼路徑具體取決於應用程式主機。 例如，`filesystem:file:///persistent/somefile.txt`，`filesystem:HTTP://localhost:8080/persistent/somefile.txt`。 -`toURL` 函數結果不包含尾部反斜線在目錄條目的情況下。 鉻雖然正確解析目錄帶斜杠落後的 url。 -`resolveLocalFileSystemURL` 方法需要入站的 `url` 必須具有 `檔案系統` 首碼。 例如，`resolveLocalFileSystemURL` 的 `url` 參數應在表單 `filesystem:file:///persistent/somefile.txt` 而不是表單 `file:///persistent/somefile.txt` 在安卓系統。 -不推薦使用 `toNativeURL` 函數不受支援，並且沒有存根 (stub)。 -`setMetadata` 功能是沒有說出的規格，並且不支援。 -INVALID_MODIFICATION_ERR (代碼: 9） 而不是引發 SYNTAX_ERR(code: 8) 上請求一個不存在的檔案系統。 -INVALID_MODIFICATION_ERR (代碼: 9） 而不是引發 PATH_EXISTS_ERR(code: 12) 上嘗試專門創建一個檔或目錄，它已經存在。 -INVALID_MODIFICATION_ERR (代碼: 9） 而不是引發 NO_MODIFICATION_ALLOWED_ERR(code: 6) 在試圖調用 removeRecursively 的根檔案系統上。 -INVALID_MODIFICATION_ERR (代碼: 9） 而不是引發 NOT_FOUND_ERR(code: 1) 試到 moveTo 目錄不存在。\n\n### 基於 IndexedDB 的 impl 怪癖 （Firefox 和 IE）\n\n  * `.` 和 `.` 不受支援。\n  * IE 不支援 `file:///`-模式 ；只有託管的模式是支援 （HTTP://localhost:xxxx）。\n  * 火狐瀏覽器的檔案系統大小不是有限，但每個 50 MB 擴展會要求使用者的許可權。 IE10 允許達 10 mb 的 AppCache 和 IndexedDB 檔案系統的實現中使用而不會提示，一旦你達到這一水準你會詢問您是否允許它增加到每個網站的 250 mb 的最大合併。 所以 `requestFileSystem` 函數的 `大小` 參數並不影響檔案系統相容 Firefox 和 IE。\n  * `readAsBinaryString` 函數在規範中沒有注明不支援在 IE 中和沒有存根 (stub)。\n  * `file.type` 始終為 null。\n  * 您不應創建條目使用已刪除的目錄實例回檔結果。否則，你會得到一個 '掛條目'。\n  * 您可以讀取一個檔，其中只是寫之前你需要獲得的此檔的新實例。\n  * `setMetadata` 函數，在規範中沒有注明支援 `modificationTime` 欄位的更改。 \n  * `copyTo` 和 `moveTo` 函數不支援目錄。\n  * 不支援目錄的中繼資料。\n  * 兩個 Entry.remove 和 directoryEntry.removeRecursively 不失敗時刪除非空的目錄-相反與內容一起清理目錄被刪除。\n  * 不支援 `abort` 和 `truncate` 函數。\n  * 進度事件不會觸發。例如，將不執行此處理程式：\n\n```javascript\nwriter.onprogress = function() { /*commands*/ };\n```\n\n## 升級筆記\n\n在這個外掛程式 v1.0.0，`FileEntry` 和 `DirectoryEntry` 的結構已經改變，以更加一致的已發表說明書。\n\n以前 (pre-1.0.0） 版本的外掛程式中 `輸入` 物件的 `完整路徑` 屬性存放裝置固定檔案位置。這些路徑通常會看起來像\n\n    /var/mobile/Applications/<application UUID>/Documents/path/to/file  (iOS)\n    /storage/emulated/0/path/to/file                                    (Android)\n    \n\n這些路徑還返回的 `Entry` 物件的 `toURL()` 方法。\n\n與 v1.0.0，`完整路徑` 屬性是到檔中，*相對於 HTML 檔案系統的根目錄* 的路徑。 因此，上述路徑會現在都由一個 `FileEntry` 物件的 `完整路徑`，\n\n    /path/to/file\n    \n\n如果您的應用程式與設備-絕對路徑，並且您以前檢索到這些路徑通過 `條目` 物件的 `完整路徑` 屬性，然後您應該更新您的代碼以改用 `entry.toURL()`。\n\n為向後相容性，`resolveLocalFileSystemURL()` 方法將接受一個設備-絕對路徑，並將返回相應的 `條目` 物件，只要在 `臨時` 或 `永久性` 的檔案系統內的檔是否存在。\n\n這尤其是一直與檔案傳輸外掛程式，以前使用設備絕對路徑的問題 (和仍然可以接受他們)。 已更新它能夠正常運行與檔案系統的 Url，所以用 `entry.toURL()` 替換 `entry.fullPath` 應解決任何問題，得到該外掛程式來處理設備上的檔。\n\n在 v1.1.0 `toURL()` 的傳回值被更改 （見 [CB-6394] （HTTPs://issues.apache.org/jira/browse/CB-6394）） 為返回絕對 file:// URL。 只要有可能。 確保 'cdvfile：' — — 你現在可以用 `toInternalURL()` 的 URL。 現在，此方法將返回檔案系統表單的 Url\n\n    cdvfile://localhost/persistent/path/to/file\n    \n\n它可以用於唯一地標識該檔。\n\n## 錯誤代碼及其含義的清單中\n\n當拋出一個錯誤時，將使用以下代碼之一。\n\n| 代碼 | 恒                             |\n| --:|:----------------------------- |\n|  1 | `NOT_FOUND_ERR`               |\n|  2 | `SECURITY_ERR`                |\n|  3 | `ABORT_ERR`                   |\n|  4 | `NOT_READABLE_ERR`            |\n|  5 | `ENCODING_ERR`                |\n|  6 | `NO_MODIFICATION_ALLOWED_ERR` |\n|  7 | `INVALID_STATE_ERR`           |\n|  8 | `SYNTAX_ERR`                  |\n|  9 | `INVALID_MODIFICATION_ERR`    |\n| 10 | `QUOTA_EXCEEDED_ERR`          |\n| 11 | `TYPE_MISMATCH_ERR`           |\n| 12 | `PATH_EXISTS_ERR`             |\n\n## 配置外掛程式 （可選）\n\n可用的檔案系統的一整套可以配置每個平臺。IOS 和安卓系統認識到 <preference> 在 `config.xml` 名稱要安裝的檔案系統中的標記。預設情況下，啟用所有檔案系統的根。\n\n    <preference name=\"iosExtraFilesystems\" value=\"library,library-nosync,documents,documents-nosync,cache,bundle,root\" />\n    <preference name=\"AndroidExtraFilesystems\" value=\"files,files-external,documents,sdcard,cache,cache-external,root\" />\n    \n\n### Android 系統\n\n  * `files`： 該應用程式的內部檔存儲目錄\n  * `files-external`： 應用程式的外部檔存儲目錄\n  * `sdcard`： 全球外部檔存儲目錄 （如果安裝了一個，這是 SD 卡的根目錄）。 你必須具有 `android.permission.WRITE_EXTERNAL_STORAGE` 許可權，用這個。\n  * `cache`： 應用程式的內部緩存目錄\n  * `cache-external`： 應用程式的外部快取記憶體目錄\n  * `root`： 整個設備的檔案系統\n\n安卓系統還支援特殊的檔命名為\"檔\"，表示\"/ 檔 /\"\"檔\"的檔案系統中的子目錄。\n\n### iOS\n\n  * `library`： 應用程式的庫目錄\n  * `documents`： 應用程式的檔目錄\n  * `cache`： 應用程式的緩存目錄\n  * `bundle`： 應用程式的包 ；應用程式本身 （唯讀） 的磁片上的位置\n  * `root`： 整個設備的檔案系統\n\n預設情況下，圖書館和檔目錄可以同步到 iCloud。 您也可以要求兩個額外的檔案系統、 `library-nosync` 和 `documents-nosync`，代表一個特殊的非同步目錄內 `/Library` 或 `/Documents` 的檔案系統。"
  },
  {
    "path": "plugins/cordova-plugin-file/doc/zh/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-file\n\n這個外掛程式實現檔 API 允許對檔駐留在該設備上的讀/寫訪問。\n\n這個外掛程式基於幾個規格，包括： HTML5 檔 API [HTTP://www.w3.org/TR/FileAPI/][1]\n\n [1]: http://www.w3.org/TR/FileAPI/\n\n（現已解散） 目錄和系統擴展最新： [HTTP://www.w3.org/TR/2012/WD-file-system-api-20120417/][2]雖然大部分的外掛程式代碼寫時較早的規格是當前： [HTTP://www.w3.org/TR/2011/WD-file-system-api-20110419/][3]\n\n [2]: http://www.w3.org/TR/2012/WD-file-system-api-20120417/\n [3]: http://www.w3.org/TR/2011/WD-file-system-api-20110419/\n\n它還實現 FileWriter 規格： [HTTP://dev.w3.org/2009/dap/file-system/file-writer.html][4]\n\n [4]: http://dev.w3.org/2009/dap/file-system/file-writer.html\n\n用法，請參閱對 HTML5 的岩石優秀[檔案系統文章。][5]\n\n [5]: http://www.html5rocks.com/en/tutorials/file/filesystem/\n\n其他存儲選項的概述，請參閱科爾多瓦的[存儲指南][6].\n\n [6]: http://cordova.apache.org/docs/en/edge/cordova_storage_storage.md.html\n\n這個外掛程式定義全球 `cordova.file` 物件。\n\n雖然在全球範圍內，它不可用直到 `deviceready` 事件之後。\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(cordova.file);\n    }\n    \n\n## 安裝\n\n    cordova plugin add cordova-plugin-file\n    \n\n## 支援的平臺\n\n*   亞馬遜火 OS\n*   Android 系統\n*   黑莓 10\n*   火狐瀏覽器的作業系統\n*   iOS\n*   Windows Phone 7 和 8 *\n*   Windows 8 *\n*   瀏覽器\n\n* *這些平臺不支援 `FileReader.readAsArrayBuffer` 或 `FileWriter.write(blob)`.*\n\n## 存儲檔的位置\n\n截至 v1.2.0，提供重要的檔案系統目錄的 Url。 每個 URL 位於表單 *file:///path/to/spot/*，和可以轉換為使用 `window.resolveLocalFileSystemURL()` 的 `DirectoryEntry`.\n\n*   `cordova.file.applicationDirectory`-唯讀目錄在哪裡安裝的應用程式。（*iOS*、*安卓*、*黑莓 10*)\n\n*   `cordova.file.applicationStorageDirectory`-根目錄下的應用程式的沙箱 ；在 iOS 上此位置是唯讀 （但特定的子目錄 [像 `/Documents` ] 都是讀寫）。 中包含的所有資料都是私有的應用程式。 （ *iOS*、*安卓*、*黑莓 10*)\n\n*   `cordova.file.dataDirectory`資料持久性和私有資料存儲在內部記憶體使用的應用程式的沙箱內 （在安卓系統，如果你需要使用外部儲存體，使用 `.externalDataDirectory` ）。 在 iOS，此目錄不與 iCloud 同步 （使用 `.syncedDataDirectory` ）。 （*iOS*、*安卓*、*黑莓 10*)\n\n*   `cordova.file.cacheDirectory`-緩存的資料檔案或您的應用程式重新可以輕鬆地創建的任何檔的目錄。 作業系統可能會刪除這些檔，該設備在存儲上運行低時，然而，應用程式不應依賴的作業系統，請刪除檔在這裡。 （*iOS*、*安卓*、*黑莓 10*)\n\n*   `cordova.file.externalApplicationStorageDirectory`-應用程式外部存儲上的空間。（*安卓*)\n\n*   `cordova.file.externalDataDirectory`-放在外部存儲特定于應用程式的資料檔案的位置。（*安卓*)\n\n*   `cordova.file.externalCacheDirectory`-在外部存儲應用程式緩存。（*安卓*)\n\n*   `cordova.file.externalRootDirectory`-外部存儲 （SD 卡） 的根。（*安卓*、*黑莓 10*)\n\n*   `cordova.file.tempDirectory`-OS 可以清除時的空目錄會。 不依賴于 OS，以清除此目錄 ；您的應用程式，應總是移除作為適用的檔。 （*iOS*)\n\n*   `cordova.file.syncedDataDirectory`-保存應同步 （例如到 iCloud） 的特定于應用程式的檔。（*iOS*)\n\n*   `cordova.file.documentsDirectory`-檔私有的應用程式，但這是對其他應用程式 （例如 Office 檔） 有意義。（*iOS*)\n\n*   `cordova.file.sharedDirectory`-對所有應用程式 （*黑莓 10*全域可用的檔)\n\n## 檔案系統佈局\n\n雖然技術上實現的細節，它可以是很有必要瞭解如何 `cordova.file.*` 屬性對應到實體路徑在實際設備上。\n\n### iOS 檔案系統佈局\n\n| 設備路徑                            | `cordova.file.*`            | `iosExtraFileSystems` | r/w 嗎？ | 持續性嗎？  |   OS 清除    | 同步  | 私人 |\n|:------------------------------- |:--------------------------- |:--------------------- |:------:|:------:|:----------:|:---:|:--:|\n| `/ 無功/移動/應用程式/< UUID > /` | applicationStorageDirectory | -                     |   r    |  不適用   |    不適用     | 不適用 | 是啊 |\n|    `appname.app/`               | applicationDirectory        | 束                     |   r    |  不適用   |    不適用     | 不適用 | 是啊 |\n|       `www/`                    | -                           | -                     |   r    |  不適用   |    不適用     | 不適用 | 是啊 |\n|    `Documents/`                 | documentsDirectory          | 檔                     |  r/w   |   是啊   |     無      | 是啊  | 是啊 |\n|       `NoCloud/`                | -                           | 檔 nosync              |  r/w   |   是啊   |     無      |  無  | 是啊 |\n|    `Library`                    | -                           | 圖書館                   |  r/w   |   是啊   |     無      | 是嗎？ | 是啊 |\n|       `NoCloud/`                | dataDirectory               | 圖書館 nosync            |  r/w   |   是啊   |     無      |  無  | 是啊 |\n|       `Cloud/`                  | syncedDataDirectory         | -                     |  r/w   |   是啊   |     無      | 是啊  | 是啊 |\n|       `Caches/`                 | cacheDirectory              | 快取記憶體                 |  r/w   |  是啊 *  | 是的 * * *| |  無  | 是啊 |\n|    `tmp/`                       | tempDirectory               | -                     |  r/w   | 沒有 * * | 是的 * * *| |  無  | 是啊 |\n\n* 檔堅持跨應用程式重新開機和升級，但是每當作業系統的欲望，可以清除此目錄。您的應用程式應該能夠重新創建任何內容可能會被刪除。\n\n* * 檔可能會持續整個應用程式重新開機，但不要依賴此行為。 不保證檔在更新之間持續存在。 您的應用程式時適用，是應該刪除此目錄的檔，因為作業系統並不能保證何時 （或即使） 中刪除這些檔。\n\n* * *| 作業系統可能會清除此目錄的內容，每當它感覺它是必要的但不要依賴于此。 你應該清除此目錄為適合您的應用程式。\n\n### Android 的檔案系統佈局\n\n| 設備路徑                              | `cordova.file.*`                    | `AndroidExtraFileSystems` | r/w 嗎？ | 持續性嗎？ | OS 清除  | 私人 |\n|:--------------------------------- |:----------------------------------- |:------------------------- |:------:|:-----:|:------:|:--:|\n| `file:///android_asset/`          | applicationDirectory                |                           |   r    |  不適用  |  不適用   | 是啊 |\n| `/ 資料資料/< 應用程式 id > /`      | applicationStorageDirectory         | -                         |  r/w   |  不適用  |  不適用   | 是啊 |\n|    `cache`                        | cacheDirectory                      | 快取記憶體                     |  r/w   |  是啊   |  是啊 *  | 是啊 |\n|    `files`                        | dataDirectory                       | 檔                         |  r/w   |  是啊   |   無    | 是啊 |\n|       `Documents`                 |                                     | 檔                         |  r/w   |  是啊   |   無    | 是啊 |\n| `< sd 卡 > /`                | externalRootDirectory               | sd 卡                      |  r/w   |  是啊   |   無    | 無  |\n|    `Android/data/<app-id>/` | externalApplicationStorageDirectory | -                         |  r/w   |  是啊   |   無    | 無  |\n|       `cache`                     | externalCacheDirectry               | 外部快取記憶體                   |  r/w   |  是啊   | 沒有 * * | 無  |\n|       `files`                     | externalDataDirectory               | 外部檔                       |  r/w   |  是啊   |   無    | 無  |\n\n* 的作業系統可能會定期清除此目錄中，但不是依賴于這種行為。 清除此為適合您的應用程式的目錄的內容。 使用者應手動清除緩存，將刪除此目錄的內容。\n\n* * 作業系統不會自動清除此目錄你是負責管理自己的內容。 使用者應手動清除緩存，目錄中的內容將被刪除。\n\n**注**： 如果外部存儲無法裝入，`cordova.file.external*` 屬性為 `空`.\n\n### 黑莓 10 檔案系統佈局\n\n| 設備路徑                                                 | `cordova.file.*`            | r/w 嗎？ | 持續性嗎？ | OS 清除 | 私人 |\n|:---------------------------------------------------- |:--------------------------- |:------:|:-----:|:-----:|:--:|\n| `file:///accounts/1000/appdata/ < 應用程式 id > /` | applicationStorageDirectory |   r    |  不適用  |  不適用  | 是啊 |\n|    `app/native`                                      | applicationDirectory        |   r    |  不適用  |  不適用  | 是啊 |\n|    `data/webviews/webfs/temporary/local__0`          | cacheDirectory              |  r/w   |   無   |  是啊   | 是啊 |\n|    `data/webviews/webfs/persistent/local__0`         | dataDirectory               |  r/w   |  是啊   |   無   | 是啊 |\n| `file:///accounts/1000/removable/sdcard`             | externalRemovableDirectory  |  r/w   |  是啊   |   無   | 無  |\n| `file:///accounts/1000/shared`                       | sharedDirectory             |  r/w   |  是啊   |   無   | 無  |\n\n*注意*： 當應用程式部署工作週邊時，所有路徑都是相對於 /accounts/1000-enterprise。\n\n## Android 的怪癖\n\n### Android 的持久性存儲位置\n\n有很多有效的位置來存儲持久性檔在 Android 設備上。 請參閱 [此頁面][7] 的各種可能性進行廣泛討論。\n\n [7]: http://developer.android.com/guide/topics/data/data-storage.html\n\n以前版本的外掛程式會選擇在啟動時，基於該設備是否聲稱 SD 卡 （或等效存儲分區） 展開，臨時和永久檔的位置。 如果被掛載 SD 卡，或一個大的內部存儲分區可用 （如 nexus 系列設備上） 然後持久性檔將存儲在該空間的根目錄中。 這意味著所有的科爾多瓦應用程式可以看到所有可用的檔在卡片上。\n\n如果 SD 卡不是可用的那麼以前的版本中將存儲資料下的 `/data/data/<packageId>`，其中隔離應用程式從彼此，但仍可能導致使用者之間共用的資料。\n\n現在可以選擇是否將檔存儲在內部檔的存儲位置，或使用以前的邏輯，與您的應用程式的 `config.xml` 檔中的偏好。 要執行此操作，請將以下兩行之一添加到 `config.xml`：\n\n    <preference name=\"AndroidPersistentFileLocation\" value=\"Internal\" />\n    \n    <preference name=\"AndroidPersistentFileLocation\" value=\"Compatibility\" />\n    \n\n如果這條線，沒有檔外掛程式將使用 `Compatibility` 作為預設值。如果首選項標記存在，並不是這些值之一，應用程式將無法啟動。\n\n如果您的應用程式以前已被運到使用者，使用較舊的 （預 1.0） 版本的這個外掛程式，並具有持久性的檔，系統中存儲的檔，然後您應該設置 `Compatibility` 偏好。 切換到\"Internal\"的位置，將意味著現有使用者升級他們的應用程式可能無法訪問他們以前存儲的檔，具體取決於他們的設備。\n\n如果您的應用程式是新的或以前從未有持久性的檔案系統中存儲檔，那麼通常建議使用 `Internal` 設置。\n\n## iOS 的怪癖\n\n*   `cordova.file.applicationStorageDirectory`是唯讀的 ；試圖存儲內的根目錄中的檔將會失敗。 使用的另一個 `cordova.file.*` 為 iOS 定義的屬性 （只有 `applicationDirectory` 和 `applicationStorageDirectory` 都是唯讀）。\n*   `FileReader.readAsText(blob, encoding)` \n    *   `encoding`參數不受支援，而 utf-8 編碼總是效果。\n\n### iOS 的持久性存儲位置\n\n有兩個有效的位置來存儲持久性在 iOS 設備上的檔： 檔目錄和圖書館目錄。 以前版本的外掛程式永遠只能將持久性檔存儲在文檔目錄中。 這已經使所有應用程式檔可見在 iTunes，往往是無意為之，尤其是對於處理大量小檔的應用程式中，而不是生產供出口，該目錄的既定的目標是證件齊全的副作用。\n\n現在可以選擇是否將檔存儲在檔或庫目錄，與您的應用程式的 `config.xml` 檔中的偏好。 要執行此操作，請將以下兩行之一添加到 `config.xml`：\n\n    <preference name=\"iosPersistentFileLocation\" value=\"Library\" />\n    \n    <preference name=\"iosPersistentFileLocation\" value=\"Compatibility\" />\n    \n\n如果這條線，沒有檔外掛程式將使用 `Compatibility` 作為預設值。如果首選項標記存在，並不是這些值之一，應用程式將無法啟動。\n\n如果您的應用程式以前已被運到使用者，使用較舊的 （預 1.0） 版本的這個外掛程式，並具有持久性的檔，系統中存儲的檔，然後您應該設置 `Compatibility` 偏好。 切換到 `Library` 的位置，將意味著現有使用者升級他們的應用程式將無法訪問他們以前存儲的檔。\n\n如果您的應用程式是新的或以前從未有持久性的檔案系統中存儲檔，那麼通常建議使用 `Internal` 設置。\n\n## 火狐瀏覽器作業系統的怪癖\n\n檔案系統 API 本身不支援火狐瀏覽器的作業系統，作為墊片在 indexedDB 上實現的。\n\n*   不會失敗時刪除非空的目錄\n*   不支援中繼資料的目錄\n*   方法 `copyTo` 和 `moveTo` 不支援目錄\n\n支援以下資料路徑： * `applicationDirectory`-使用 `xhr` 獲取與應用程式打包的本地檔。 `dataDirectory`-用於持久性的特定于應用程式的資料檔案。 `cacheDirectory`-生存應重新開機應用程式的快取檔案 （應用程式不應依賴作業系統來刪除檔在這裡）。\n\n## 瀏覽器的怪癖\n\n### 常見的怪癖和備註\n\n*   每個瀏覽器使用其自己的沙箱檔案系統。IE 和火狐瀏覽器使用 IndexedDB 作為一個基地。所有瀏覽器都使用正斜杠作為路徑中的目錄分隔符號。\n*   目錄條目不得不先後創建。 例如，調用 `fs.root.getDirectory (' dir1/dir2 '，{create:true}，successCallback，errorCallback）`，如果不存在 dir1 將失敗。\n*   外掛程式將請求使用者許可權，以便在應用程式初次開機使用持久性存儲。 \n*   外掛程式支援 `cdvfile://localhost` （本地資源） 只。通過 `cdvfile` 不支援外部資源即.\n*   該外掛程式不遵循 [\"檔案系統 API 8.3 命名限制\"][8].\n*   Blob 和檔 ' `close` 功能不受支援。\n*   `FileSaver` 和 `BlobBuilder` 不支援這個外掛程式，沒有存根 (stub)。\n*   該外掛程式不支援 `requestAllFileSystems`。這個功能也是缺少規範中。\n*   在目錄中的條目將不會被刪除，如果您使用 `create: true` 標誌為現有目錄。\n*   不支援通過建構函式創建的檔。你應該使用 entry.file 方法。\n*   每個瀏覽器使用它自己的形式為 blob 的 URL 引用。\n*   支援 `readAsDataURL` 功能，但在 Chrome 中的媒體類型取決於輸入副檔名，在 IE 中的媒體類型都始終空著 （這是 `純文字` 按照說明書一樣），在 Firefox 中的媒體類型始終是 `應用程式/八位位元組流`。 例如，如果內容是 `abcdefg` 然後火狐瀏覽器返回 `資料： 應用程式 / 八位位元組流 ； base64，YWJjZGVmZw = =`，即返回 `資料： ； base64，YWJjZGVmZw = =`，鉻返回 `資料： < 媒體類型根據擴展條目名稱 > ； base64，YWJjZGVmZw = =`.\n*   在表單 `file:///persistent/path/to/entry` 火狐瀏覽器 IE），`toInternalURL` 返回的路徑。 鉻在表單 `cdvfile://localhost/persistent/file` 返回的路徑.\n\n [8]: http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions\n\n### 鉻的怪癖\n\n*   設備準備好事件之後，chrome 檔案系統並不能立即準備。作為一種變通方法，您可以訂閱到 `filePluginIsReady` 事件。示例： \n\n    javascript\n    window.addEventListener('filePluginIsReady', function(){ console.log('File plugin is ready');}, false);\n    \n\n你可以使用 `window.isFilePluginReadyRaised` 函數來檢查是否已經引發了事件。 -window.requestFileSystem 臨時和永久性檔案系統配額並不局限于鉻。 為增加中鉻的持久性存儲，您需要調用 `window.initPersistentFileSystem` 方法。 預設情況下，持久性存儲配額為 5 MB。 鉻需要 `— — 允許--訪問-從-檔` 通過 `file:///` 協定運行參數對 API 的支援。 -如果您使用標誌，將不更改 `檔` 物件 `{create:true}` 現有 `條目` 的時候。 -事件 `可取消` 屬性設置為 true 在 Chrome 中。 這是違反了 [規範][4]。 -中鉻的 `toURL` 函數返回 `檔案系統：`-首碼路徑具體取決於應用程式主機。 例如，`filesystem:file:///persistent/somefile.txt`，`filesystem:HTTP://localhost:8080/persistent/somefile.txt`。 -`toURL` 函數結果不包含尾部反斜線在目錄條目的情況下。 鉻雖然正確解析目錄帶斜杠落後的 url。 -`resolveLocalFileSystemURL` 方法需要入站的 `url` 必須具有 `檔案系統` 首碼。 例如，`resolveLocalFileSystemURL` 的 `url` 參數應在表單 `filesystem:file:///persistent/somefile.txt` 而不是表單 `file:///persistent/somefile.txt` 在安卓系統。 -不推薦使用 `toNativeURL` 函數不受支援，並且沒有存根 (stub)。 -`setMetadata` 功能是沒有說出的規格，並且不支援。 -INVALID_MODIFICATION_ERR (代碼: 9） 而不是引發 SYNTAX_ERR(code: 8) 上請求一個不存在的檔案系統。 -INVALID_MODIFICATION_ERR (代碼: 9） 而不是引發 PATH_EXISTS_ERR(code: 12) 上嘗試專門創建一個檔或目錄，它已經存在。 -INVALID_MODIFICATION_ERR (代碼: 9） 而不是引發 NO_MODIFICATION_ALLOWED_ERR(code: 6) 在試圖調用 removeRecursively 的根檔案系統上。 -INVALID_MODIFICATION_ERR (代碼: 9） 而不是引發 NOT_FOUND_ERR(code: 1) 試到 moveTo 目錄不存在。\n\n### 基於 IndexedDB 的 impl 怪癖 （Firefox 和 IE）\n\n*   `.` 和 `.` 不受支援。\n*   IE 不支援 `file:///`-模式 ；只有託管的模式是支援 （HTTP://localhost:xxxx）。\n*   火狐瀏覽器的檔案系統大小不是有限，但每個 50 MB 擴展會要求使用者的許可權。 IE10 允許達 10 mb 的 AppCache 和 IndexedDB 檔案系統的實現中使用而不會提示，一旦你達到這一水準你會詢問您是否允許它增加到每個網站的 250 mb 的最大合併。 所以 `requestFileSystem` 函數的 `大小` 參數並不影響檔案系統相容 Firefox 和 IE。\n*   `readAsBinaryString` 函數在規範中沒有注明不支援在 IE 中和沒有存根 (stub)。\n*   `file.type` 始終為 null。\n*   您不應創建條目使用已刪除的目錄實例回檔結果。否則，你會得到一個 '掛條目'。\n*   您可以讀取一個檔，其中只是寫之前你需要獲得的此檔的新實例。\n*   `setMetadata` 函數，在規範中沒有注明支援 `modificationTime` 欄位的更改。 \n*   `copyTo` 和 `moveTo` 函數不支援目錄。\n*   不支援目錄的中繼資料。\n*   兩個 Entry.remove 和 directoryEntry.removeRecursively 不失敗時刪除非空的目錄-相反與內容一起清理目錄被刪除。\n*   不支援 `abort` 和 `truncate` 函數。\n*   進度事件不會觸發。例如，將不執行此處理程式：\n\n    javascript\n    writer.onprogress = function() { /*commands*/ };\n    \n\n## 升級筆記\n\n在這個外掛程式 v1.0.0，`FileEntry` 和 `DirectoryEntry` 的結構已經改變，以更加一致的已發表說明書。\n\n以前 (pre-1.0.0） 版本的外掛程式中 `輸入` 物件的 `完整路徑` 屬性存放裝置固定檔案位置。這些路徑通常會看起來像\n\n    /var/mobile/Applications/<application UUID>/Documents/path/to/file  (iOS)\n    /storage/emulated/0/path/to/file                                    (Android)\n    \n\n這些路徑還返回的 `Entry` 物件的 `toURL()` 方法。\n\n與 v1.0.0，`完整路徑` 屬性是到檔中，*相對於 HTML 檔案系統的根目錄* 的路徑。 因此，上述路徑會現在都由一個 `FileEntry` 物件的 `完整路徑`，\n\n    /path/to/file\n    \n\n如果您的應用程式與設備-絕對路徑，並且您以前檢索到這些路徑通過 `條目` 物件的 `完整路徑` 屬性，然後您應該更新您的代碼以改用 `entry.toURL()`。\n\n為向後相容性，`resolveLocalFileSystemURL()` 方法將接受一個設備-絕對路徑，並將返回相應的 `條目` 物件，只要在 `臨時` 或 `永久性` 的檔案系統內的檔是否存在。\n\n這尤其是一直與檔案傳輸外掛程式，以前使用設備絕對路徑的問題 (和仍然可以接受他們)。 已更新它能夠正常運行與檔案系統的 Url，所以用 `entry.toURL()` 替換 `entry.fullPath` 應解決任何問題，得到該外掛程式來處理設備上的檔。\n\n在 v1.1.0 `toURL()` 的傳回值被更改 （見 [CB-6394] （HTTPs://issues.apache.org/jira/browse/CB-6394）） 為返回絕對 file:// URL。 只要有可能。 確保 'cdvfile：' — — 你現在可以用 `toInternalURL()` 的 URL。 現在，此方法將返回檔案系統表單的 Url\n\n    cdvfile://localhost/persistent/path/to/file\n    \n\n它可以用於唯一地標識該檔。\n\n## 錯誤代碼及其含義的清單中\n\n當拋出一個錯誤時，將使用以下代碼之一。\n\n| 代碼 | 恒                             |\n| --:|:----------------------------- |\n|  1 | `NOT_FOUND_ERR`               |\n|  2 | `SECURITY_ERR`                |\n|  3 | `ABORT_ERR`                   |\n|  4 | `NOT_READABLE_ERR`            |\n|  5 | `ENCODING_ERR`                |\n|  6 | `NO_MODIFICATION_ALLOWED_ERR` |\n|  7 | `INVALID_STATE_ERR`           |\n|  8 | `SYNTAX_ERR`                  |\n|  9 | `INVALID_MODIFICATION_ERR`    |\n| 10 | `QUOTA_EXCEEDED_ERR`          |\n| 11 | `TYPE_MISMATCH_ERR`           |\n| 12 | `PATH_EXISTS_ERR`             |\n\n## 配置外掛程式 （可選）\n\n可用的檔案系統的一整套可以配置每個平臺。IOS 和安卓系統認識到 <preference> 在 `config.xml` 名稱要安裝的檔案系統中的標記。預設情況下，啟用所有檔案系統的根。\n\n    <preference name=\"iosExtraFilesystems\" value=\"library,library-nosync,documents,documents-nosync,cache,bundle,root\" />\n    <preference name=\"AndroidExtraFilesystems\" value=\"files,files-external,documents,sdcard,cache,cache-external,root\" />\n    \n\n### Android 系統\n\n*   `files`： 該應用程式的內部檔存儲目錄\n*   `files-external`： 應用程式的外部檔存儲目錄\n*   `sdcard`： 全球外部檔存儲目錄 （如果安裝了一個，這是 SD 卡的根目錄）。 你必須具有 `android.permission.WRITE_EXTERNAL_STORAGE` 許可權，用這個。\n*   `cache`： 應用程式的內部緩存目錄\n*   `cache-external`： 應用程式的外部快取記憶體目錄\n*   `root`： 整個設備的檔案系統\n\n安卓系統還支援特殊的檔命名為\"檔\"，表示\"/ 檔 /\"\"檔\"的檔案系統中的子目錄。\n\n### iOS\n\n*   `library`： 應用程式的庫目錄\n*   `documents`： 應用程式的檔目錄\n*   `cache`： 應用程式的緩存目錄\n*   `bundle`： 應用程式的包 ；應用程式本身 （唯讀） 的磁片上的位置\n*   `root`： 整個設備的檔案系統\n\n預設情況下，圖書館和檔目錄可以同步到 iCloud。 您也可以要求兩個額外的檔案系統、 `library-nosync` 和 `documents-nosync`，代表一個特殊的非同步目錄內 `/Library` 或 `/Documents` 的檔案系統。\n"
  },
  {
    "path": "plugins/cordova-plugin-file/doc/zh/plugins.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# 外掛程式開發人員注意事項\n\n這些筆記主要用於 Android 和 iOS 開發者想要編寫外掛程式的介面與使用檔外掛程式的檔案系統。\n\n## 工作與科爾多瓦檔案系統 Url\n\n自從版本 1.0.0，這個外掛程式一直使用 Url 與 `cdvfile` 大橋，計畫為所有通信，而不是揭露 JavaScript 的原始設備檔案系統路徑。\n\n在 JavaScript 方面，這意味著 FileEntry 和 DirectoryEntry 的物件有一個完整路徑屬性是相對於 HTML 檔案系統的根目錄。 如果你的外掛程式的 JavaScript API 接受一個 FileEntry 或 DirectoryEntry 的物件，你應該打電話給 `.toURL()` 對該物件之前將它從橋上傳遞給本機代碼。\n\n### 轉換 cdvfile: / / fileystem 路徑的 Url\n\n需要寫入到檔案系統的外掛程式可能想要將接收的檔案系統 URL 轉換為實際的檔案系統位置。有做這，根據本機平臺的多種方式。\n\n很重要的是要記住，並不是所有 `cdvfile://` Url 是可映射到設備上的實際檔。 某些 Url 可以指在設備上沒有代表的檔，或甚至可以引用遠端資源的資產。 由於這些可能性，外掛程式應始終測試是否回來時試圖將 Url 轉換成路徑得到有意義的結果。\n\n#### 安卓系統\n\n在 android 系統，最簡單的方法來轉換 `cdvfile://` 檔案系統路徑的 URL 是使用 `org.apache.cordova.CordovaResourceApi` 。 `CordovaResourceApi`有幾種方法，可處理 `cdvfile://` 網址:\n\n    web 視圖是成員的外掛程式類 CordovaResourceApi resourceApi = webView.getResourceApi();\n    \n    獲取表示此檔在設備上，file:/// URL / / 或 URL 相同變的如果它不能映射到檔 Uri fileURL = resourceApi.remapUri(Uri.parse(cdvfileURL));\n    \n\n它也是可以直接使用檔外掛程式:\n\n    導入 org.apache.cordova.file.FileUtils;\n    導入 org.apache.cordova.file.FileSystem;\n    導入 java.net.MalformedURLException;\n    \n    得到檔外掛程式外掛程式管理器從 FileUtils filePlugin = (FileUtils)webView.pluginManager.getPlugin(\"File\");\n    \n    給定 URL，得到的路徑，因為它嘗試 {字串路徑 = filePlugin.filesystemPathForURL(cdvfileURL);} 趕上 (MalformedURLException e) {/ / 檔案系統 url 不承認}\n    \n\n要轉換到的路徑從 `cdvfile://` URL:\n\n    導入 org.apache.cordova.file.LocalFilesystemURL;\n    \n    獲取設備的路徑，一個 LocalFilesystemURL 物件 / / 或如果它不能表示為 cdvfile 的 URL，則為 null。\n    LocalFilesystemURL url = filePlugin.filesystemURLforLocalPath(path);\n    得到的字串表示形式的 URL 物件字串 cdvfileURL = url.toString();\n    \n\n如果你的外掛程式創建一個檔，並且您想要為它返回一個 FileEntry 物件，使用該檔的外掛程式:\n\n    返回一個 JSON 結構適合於回到 JavaScript，/ / 或如果此檔不是可表示為 cdvfile 的 URL，則為 null。\n    JSONObject 條目 = filePlugin.getEntryForFile(file);\n    \n\n#### iOS\n\n科爾多瓦在 iOS 上的不使用相同 `CordovaResourceApi` 作為 android 系統的概念。在 iOS，應使用檔外掛程式 Url 和檔案系統路徑之間進行轉換。\n\n    獲取一個物件，CDVFilesystem URL 從 url 字串 CDVFilesystemURL * = [CDVFilesystemURL fileSystemURLWithString:cdvfileURL];\n    獲取路徑 URL 物件，或為零，如果它不能映射到檔 NSString * 路徑 = [filePlugin filesystemPathForURL:url];\n    \n    \n    CDVFilesystem URL 物件獲取設備的路徑，或 / / 為零，如果它不能表示為 cdvfile 的 URL。\n    CDVFilesystemURL * url = [filePlugin fileSystemURLforLocalPath:path];\n    得到的字串表示形式的 URL 物件 NSString * cdvfileURL = [url absoluteString];\n    \n\n如果你的外掛程式創建一個檔，並且您想要為它返回一個 FileEntry 物件，使用該檔的外掛程式:\n\n    CDVFilesystem URL 物件獲取設備的路徑，或 / / 為零，如果它不能表示為 cdvfile 的 URL。\n    CDVFilesystemURL * url = [filePlugin fileSystemURLforLocalPath:path];\n    得到一個結構來返回進入 JavaScript NSDictionary * = [filePlugin makeEntryForLocalURL:url]\n    \n\n#### JavaScript\n\n在 JavaScript 中，得到 `cdvfile://` URL 從 FileEntry 或 DirectoryEntry 的物件，只需調用 `.toURL()` 對它:\n\n    var cdvfileURL = entry.toURL();\n    \n\n在外掛程式回應處理常式，將從返回的 FileEntry 結構轉換為實際的條目物件，處理常式代碼應該導入檔外掛程式和創建新的物件:\n\n    創建適當的條目物件 var 條目;\n    如果 (entryStruct.isDirectory) {條目 = 新目錄 (entryStruct.name，entryStruct.fullPath，新 FileSystem(entryStruct.filesystemName));} 其他 {條目 = 新的 FileEntry (entryStruct.name，entryStruct.fullPath，新 FileSystem(entryStruct.filesystemName));}"
  },
  {
    "path": "plugins/cordova-plugin-file/package.json",
    "content": "{\n  \"name\": \"cordova-plugin-file\",\n  \"version\": \"4.2.0\",\n  \"description\": \"Cordova File Plugin\",\n  \"cordova\": {\n    \"id\": \"cordova-plugin-file\",\n    \"platforms\": [\n      \"android\",\n      \"amazon-fireos\",\n      \"ubuntu\",\n      \"ios\",\n      \"osx\",\n      \"wp7\",\n      \"wp8\",\n      \"blackberry10\",\n      \"windows8\",\n      \"windows\",\n      \"firefoxos\"\n    ]\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/apache/cordova-plugin-file\"\n  },\n  \"keywords\": [\n    \"cordova\",\n    \"file\",\n    \"ecosystem:cordova\",\n    \"cordova-android\",\n    \"cordova-amazon-fireos\",\n    \"cordova-ubuntu\",\n    \"cordova-ios\",\n    \"cordova-osx\",\n    \"cordova-wp7\",\n    \"cordova-wp8\",\n    \"cordova-blackberry10\",\n    \"cordova-windows8\",\n    \"cordova-windows\",\n    \"cordova-firefoxos\"\n  ],\n  \"scripts\": {\n    \"test\": \"npm run jshint\",\n    \"jshint\": \"node node_modules/jshint/bin/jshint www && node node_modules/jshint/bin/jshint src && node node_modules/jshint/bin/jshint tests\"\n  },\n  \"author\": \"Apache Software Foundation\",\n  \"license\": \"Apache-2.0\",\n  \"devDependencies\": {\n    \"jshint\": \"^2.6.0\"\n  }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-file/plugin.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  Licensed to the Apache Software Foundation (ASF) under one\n  or more contributor license agreements.  See the NOTICE file\n  distributed with this work for additional information\n  regarding copyright ownership.  The ASF licenses this file\n  to you under the Apache License, Version 2.0 (the\n  \"License\"); you may not use this file except in compliance\n  with the License.  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing,\n  software distributed under the License is distributed on an\n  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n  KIND, either express or implied.  See the License for the\n  specific language governing permissions and limitations\n  under the License.\n-->\n\n<plugin xmlns=\"http://apache.org/cordova/ns/plugins/1.0\"\nxmlns:android=\"http://schemas.android.com/apk/res/android\"\n           id=\"cordova-plugin-file\"\n      version=\"4.2.0\">\n    <name>File</name>\n    <description>Cordova File Plugin</description>\n    <license>Apache 2.0</license>\n    <keywords>cordova,file</keywords>\n    <repo>https://git-wip-us.apache.org/repos/asf/cordova-plugin-file.git</repo>\n    <issue>https://issues.apache.org/jira/browse/CB/component/12320651</issue>\n    <dependency id=\"cordova-plugin-compat\" version=\"^1.0.0\" />\n\n    <js-module src=\"www/DirectoryEntry.js\" name=\"DirectoryEntry\">\n        <clobbers target=\"window.DirectoryEntry\" />\n    </js-module>\n\n    <js-module src=\"www/DirectoryReader.js\" name=\"DirectoryReader\">\n        <clobbers target=\"window.DirectoryReader\" />\n    </js-module>\n\n    <js-module src=\"www/Entry.js\" name=\"Entry\">\n        <clobbers target=\"window.Entry\" />\n    </js-module>\n\n    <js-module src=\"www/File.js\" name=\"File\">\n        <clobbers target=\"window.File\" />\n    </js-module>\n\n    <js-module src=\"www/FileEntry.js\" name=\"FileEntry\">\n        <clobbers target=\"window.FileEntry\" />\n    </js-module>\n\n    <js-module src=\"www/FileError.js\" name=\"FileError\">\n        <clobbers target=\"window.FileError\" />\n    </js-module>\n\n    <js-module src=\"www/FileReader.js\" name=\"FileReader\">\n        <clobbers target=\"window.FileReader\" />\n    </js-module>\n\n    <js-module src=\"www/FileSystem.js\" name=\"FileSystem\">\n        <clobbers target=\"window.FileSystem\" />\n    </js-module>\n\n    <js-module src=\"www/FileUploadOptions.js\" name=\"FileUploadOptions\">\n        <clobbers target=\"window.FileUploadOptions\" />\n    </js-module>\n\n    <js-module src=\"www/FileUploadResult.js\" name=\"FileUploadResult\">\n        <clobbers target=\"window.FileUploadResult\" />\n    </js-module>\n\n    <js-module src=\"www/FileWriter.js\" name=\"FileWriter\">\n        <clobbers target=\"window.FileWriter\" />\n    </js-module>\n\n    <js-module src=\"www/Flags.js\" name=\"Flags\">\n        <clobbers target=\"window.Flags\" />\n    </js-module>\n\n    <js-module src=\"www/LocalFileSystem.js\" name=\"LocalFileSystem\">\n        <!-- Non-standards way -->\n        <clobbers target=\"window.LocalFileSystem\" />\n        <!-- Standards-compliant way -->\n        <merges target=\"window\" />\n    </js-module>\n\n    <js-module src=\"www/Metadata.js\" name=\"Metadata\">\n        <clobbers target=\"window.Metadata\" />\n    </js-module>\n\n    <js-module src=\"www/ProgressEvent.js\" name=\"ProgressEvent\">\n        <clobbers target=\"window.ProgressEvent\" />\n    </js-module>\n\n    <js-module src=\"www/fileSystems.js\" name=\"fileSystems\" />\n\n    <js-module src=\"www/requestFileSystem.js\" name=\"requestFileSystem\">\n        <clobbers target=\"window.requestFileSystem\" />\n    </js-module>\n\n    <js-module src=\"www/resolveLocalFileSystemURI.js\" name=\"resolveLocalFileSystemURI\">\n        <merges target=\"window\" />\n    </js-module>\n\n    <!-- Required for browserify: we always link module below as there is conditional reference\n    to this module from requestFileSystem and resolveLocalFileSystemURI modules. -->\n    <js-module src=\"www/browser/isChrome.js\" name=\"isChrome\">\n        <runs />\n    </js-module>\n\n    <info>\nThe Android Persistent storage location now defaults to \"Internal\". Please check this plugins README to see if you application needs any changes in its config.xml.\n\nIf this is a new application no changes are required.\n\nIf this is an update to an existing application that did not specify an \"AndroidPersistentFileLocation\" you may need to add:\n\n      \"&lt;preference name=\"AndroidPersistentFileLocation\" value=\"Compatibility\" /&gt;\"\n\nto config.xml in order for the application to find previously stored files.\n\n    </info>\n\n    <!-- android -->\n    <platform name=\"android\">\n        <config-file target=\"res/xml/config.xml\" parent=\"/*\">\n            <feature name=\"File\" >\n                <param name=\"android-package\" value=\"org.apache.cordova.file.FileUtils\"/>\n                <param name=\"onload\" value=\"true\" />\n            </feature>\n        </config-file>\n\n        <config-file target=\"AndroidManifest.xml\" parent=\"/*\">\n            <uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" />\n        </config-file>\n\n        <source-file src=\"src/android/EncodingException.java\" target-dir=\"src/org/apache/cordova/file\" />\n        <source-file src=\"src/android/FileExistsException.java\" target-dir=\"src/org/apache/cordova/file\" />\n        <source-file src=\"src/android/InvalidModificationException.java\" target-dir=\"src/org/apache/cordova/file\" />\n        <source-file src=\"src/android/NoModificationAllowedException.java\" target-dir=\"src/org/apache/cordova/file\" />\n        <source-file src=\"src/android/TypeMismatchException.java\" target-dir=\"src/org/apache/cordova/file\" />\n        <source-file src=\"src/android/FileUtils.java\" target-dir=\"src/org/apache/cordova/file\" />\n        <source-file src=\"src/android/DirectoryManager.java\" target-dir=\"src/org/apache/cordova/file\" />\n        <source-file src=\"src/android/LocalFilesystemURL.java\" target-dir=\"src/org/apache/cordova/file\" />\n        <source-file src=\"src/android/Filesystem.java\" target-dir=\"src/org/apache/cordova/file\" />\n        <source-file src=\"src/android/LocalFilesystem.java\" target-dir=\"src/org/apache/cordova/file\" />\n        <source-file src=\"src/android/ContentFilesystem.java\" target-dir=\"src/org/apache/cordova/file\" />\n        <source-file src=\"src/android/AssetFilesystem.java\" target-dir=\"src/org/apache/cordova/file\" />\n        <source-file src=\"src/android/PendingRequests.java\" target-dir=\"src/org/apache/cordova/file\" />\n\n        <!-- android specific file apis -->\n        <js-module src=\"www/android/FileSystem.js\" name=\"androidFileSystem\">\n            <merges target=\"FileSystem\" />\n        </js-module>\n        <js-module src=\"www/fileSystems-roots.js\" name=\"fileSystems-roots\">\n            <runs/>\n        </js-module>\n        <js-module src=\"www/fileSystemPaths.js\" name=\"fileSystemPaths\">\n            <merges target=\"cordova\" />\n            <runs/>\n        </js-module>\n    </platform>\n\n    <!-- amazon-fireos -->\n    <platform name=\"amazon-fireos\">\n        <config-file target=\"res/xml/config.xml\" parent=\"/*\">\n            <feature name=\"File\" >\n                <param name=\"android-package\" value=\"org.apache.cordova.file.FileUtils\"/>\n                <param name=\"onload\" value=\"true\" />\n            </feature>\n        </config-file>\n\n        <config-file target=\"AndroidManifest.xml\" parent=\"/*\">\n            <uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" />\n        </config-file>\n\n        <source-file src=\"src/android/EncodingException.java\" target-dir=\"src/org/apache/cordova/file\" />\n        <source-file src=\"src/android/FileExistsException.java\" target-dir=\"src/org/apache/cordova/file\" />\n        <source-file src=\"src/android/InvalidModificationException.java\" target-dir=\"src/org/apache/cordova/file\" />\n        <source-file src=\"src/android/NoModificationAllowedException.java\" target-dir=\"src/org/apache/cordova/file\" />\n        <source-file src=\"src/android/TypeMismatchException.java\" target-dir=\"src/org/apache/cordova/file\" />\n        <source-file src=\"src/android/FileUtils.java\" target-dir=\"src/org/apache/cordova/file\" />\n        <source-file src=\"src/android/DirectoryManager.java\" target-dir=\"src/org/apache/cordova/file\" />\n        <source-file src=\"src/android/LocalFilesystemURL.java\" target-dir=\"src/org/apache/cordova/file\" />\n        <source-file src=\"src/android/Filesystem.java\" target-dir=\"src/org/apache/cordova/file\" />\n        <source-file src=\"src/android/LocalFilesystem.java\" target-dir=\"src/org/apache/cordova/file\" />\n        <source-file src=\"src/android/ContentFilesystem.java\" target-dir=\"src/org/apache/cordova/file\" />\n        <source-file src=\"src/android/AssetFilesystem.java\" target-dir=\"src/org/apache/cordova/file\" />\n\n\n        <!-- android specific file apis -->\n        <js-module src=\"www/android/FileSystem.js\" name=\"androidFileSystem\">\n            <merges target=\"window.FileSystem\" />\n        </js-module>\n        <js-module src=\"www/fileSystems-roots.js\" name=\"fileSystems-roots\">\n            <runs/>\n        </js-module>\n        <js-module src=\"www/fileSystemPaths.js\" name=\"fileSystemPaths\">\n            <merges target=\"cordova\" />\n            <runs/>\n        </js-module>\n    </platform>\n\n    <!-- ubuntu -->\n    <platform name=\"ubuntu\">\n        <header-file src=\"src/ubuntu/file.h\" />\n        <source-file src=\"src/ubuntu/file.cpp\" />\n        <js-module src=\"www/ubuntu/FileSystem.js\" name=\"ubuntuFileSystem1\">\n            <merges target=\"window.FileSystem\" />\n        </js-module>\n        <js-module src=\"www/ubuntu/FileWriter.js\" name=\"FileWriter1\">\n            <merges target=\"window.FileWriter\" />\n        </js-module>\n        <js-module src=\"www/ubuntu/fileSystems-roots.js\" name=\"fileSystems-roots\">\n            <runs/>\n        </js-module>\n    </platform>\n\n    <!-- ios -->\n    <platform name=\"ios\">\n        <config-file target=\"config.xml\" parent=\"/*\">\n            <feature name=\"File\">\n                <param name=\"ios-package\" value=\"CDVFile\" />\n                <param name=\"onload\" value=\"true\" />\n            </feature>\n        </config-file>\n        <header-file src=\"src/ios/CDVFile.h\" />\n        <source-file src=\"src/ios/CDVFile.m\" />\n        <header-file src=\"src/ios/CDVLocalFilesystem.h\" />\n        <source-file src=\"src/ios/CDVLocalFilesystem.m\" />\n        <header-file src=\"src/ios/CDVAssetLibraryFilesystem.h\" />\n        <source-file src=\"src/ios/CDVAssetLibraryFilesystem.m\" />\n\n        <!-- ios specific file apis -->\n        <js-module src=\"www/ios/FileSystem.js\" name=\"iosFileSystem\">\n            <merges target=\"FileSystem\" />\n        </js-module>\n\n        <js-module src=\"www/fileSystems-roots.js\" name=\"fileSystems-roots\">\n            <runs/>\n        </js-module>\n\n        <js-module src=\"www/fileSystemPaths.js\" name=\"fileSystemPaths\">\n            <merges target=\"cordova\" />\n            <runs/>\n        </js-module>\n\n        <framework src=\"AssetsLibrary.framework\" />\n        <framework src=\"MobileCoreServices.framework\" />\n    </platform>\n\n    <!-- osx -->\n    <platform name=\"osx\">\n        <config-file target=\"config.xml\" parent=\"/*\">\n            <feature name=\"File\">\n                <param name=\"ios-package\" value=\"CDVFile\" />\n                <param name=\"onload\" value=\"true\" />\n            </feature>\n        </config-file>\n        <header-file src=\"src/osx/CDVFile.h\" />\n        <source-file src=\"src/osx/CDVFile.m\" />\n        <header-file src=\"src/osx/CDVLocalFilesystem.h\" />\n        <source-file src=\"src/osx/CDVLocalFilesystem.m\" />\n\n        <!-- osx specific file apis -->\n        <js-module src=\"www/osx/FileSystem.js\" name=\"osxFileSystem\">\n            <merges target=\"FileSystem\" />\n        </js-module>\n\n        <js-module src=\"www/fileSystems-roots.js\" name=\"fileSystems-roots\">\n            <runs/>\n        </js-module>\n\n        <js-module src=\"www/fileSystemPaths.js\" name=\"fileSystemPaths\">\n            <merges target=\"cordova\" />\n            <runs/>\n        </js-module>\n    </platform>\n\n    <!-- wp7 -->\n    <platform name=\"wp7\">\n        <config-file target=\"config.xml\" parent=\"/*\">\n            <feature name=\"File\">\n                <param name=\"wp-package\" value=\"File\"/>\n            </feature>\n        </config-file>\n\n        <source-file src=\"src/wp/File.cs\" />\n\n        <!-- wp specific file apis -->\n        <js-module src=\"www/wp/FileUploadOptions.js\" name=\"FileUploadOptions1\">\n            <merges target=\"window.FileUploadOptions\" />\n        </js-module>\n\n    </platform>\n\n    <!-- wp8 -->\n    <platform name=\"wp8\">\n        <config-file target=\"config.xml\" parent=\"/*\">\n            <feature name=\"File\">\n                <param name=\"wp-package\" value=\"File\"/>\n            </feature>\n        </config-file>\n\n        <source-file src=\"src/wp/File.cs\" />\n\n        <!-- wp specific file apis -->\n        <js-module src=\"www/wp/FileUploadOptions.js\" name=\"FileUploadOptions1\">\n            <merges target=\"window.FileUploadOptions\" />\n        </js-module>\n\n    </platform>\n\n    <!-- blackberry10 -->\n    <platform name=\"blackberry10\">\n        <config-file target=\"www/config.xml\" parent=\"/widget\">\n            <feature name=\"File\" value=\"File\" />\n        </config-file>\n        <js-module src=\"www/blackberry10/FileProxy.js\" name=\"FileProxy\" >\n            <runs />\n        </js-module>\n        <js-module src=\"www/blackberry10/info.js\" name=\"bb10FileSystemInfo\">\n            <runs />\n        </js-module>\n        <js-module src=\"www/blackberry10/createEntryFromNative.js\" name=\"bb10CreateEntryFromNative\">\n            <runs />\n        </js-module>\n        <js-module src=\"www/blackberry10/requestAnimationFrame.js\" name=\"bb10RequestAnimationFrame\">\n            <runs />\n        </js-module>\n        <js-module src=\"www/blackberry10/FileSystem.js\" name=\"bb10FileSystem\">\n            <merges target=\"window.FileSystem\" />\n        </js-module>\n        <js-module src=\"www/fileSystems-roots.js\" name=\"fileSystems-roots\">\n            <runs/>\n        </js-module>\n        <js-module src=\"www/fileSystemPaths.js\" name=\"fileSystemPaths\">\n            <merges target=\"cordova\" />\n        </js-module>\n        <js-module src=\"www/blackberry10/copyTo.js\" name=\"copyToProxy\" />\n        <js-module src=\"www/blackberry10/getDirectory.js\" name=\"getDirectoryProxy\" />\n        <js-module src=\"www/blackberry10/getFile.js\" name=\"getFileProxy\" />\n        <js-module src=\"www/blackberry10/getFileMetadata.js\" name=\"getFileMetadataProxy\" />\n        <js-module src=\"www/blackberry10/getMetadata.js\" name=\"getMetadataProxy\" />\n        <js-module src=\"www/blackberry10/getParent.js\" name=\"getParentProxy\" />\n        <js-module src=\"www/blackberry10/moveTo.js\" name=\"moveToProxy\" />\n        <js-module src=\"www/blackberry10/readAsArrayBuffer.js\" name=\"readAsArrayBufferProxy\" />\n        <js-module src=\"www/blackberry10/readAsBinaryString.js\" name=\"readAsBinaryStringProxy\" />\n        <js-module src=\"www/blackberry10/readAsDataURL.js\" name=\"readAsDataURLProxy\" />\n        <js-module src=\"www/blackberry10/readAsText.js\" name=\"readAsTextProxy\" />\n        <js-module src=\"www/blackberry10/readEntries.js\" name=\"readEntriesProxy\" />\n        <js-module src=\"www/blackberry10/remove.js\" name=\"removeProxy\" />\n        <js-module src=\"www/blackberry10/removeRecursively.js\" name=\"removeRecursivelyProxy\" />\n        <js-module src=\"www/blackberry10/resolveLocalFileSystemURI.js\" name=\"resolveLocalFileSystemURIProxy\" />\n        <js-module src=\"www/blackberry10/requestAllFileSystems.js\" name=\"requestAllFileSystemsProxy\" />\n        <js-module src=\"www/blackberry10/requestFileSystem.js\" name=\"requestFileSystemProxy\" />\n        <js-module src=\"www/blackberry10/setMetadata.js\" name=\"setMetadataProxy\" />\n        <js-module src=\"www/blackberry10/truncate.js\" name=\"truncateProxy\" />\n        <js-module src=\"www/blackberry10/write.js\" name=\"writeProxy\" />\n        <source-file src=\"src/blackberry10/index.js\" target-dir=\"File\" />\n    </platform>\n\n    <!-- windows8 -->\n    <platform name=\"windows8\">\n        <js-module src=\"src/windows/FileProxy.js\" name=\"FileProxy\">\n            <merges target=\"\" />\n        </js-module>\n\n        <js-module src=\"www/fileSystemPaths.js\" name=\"fileSystemPaths\">\n            <merges target=\"cordova\" />\n            <runs/>\n        </js-module>\n    </platform>\n\n    <!-- windows -->\n    <platform name=\"windows\">\n        <js-module src=\"src/windows/FileProxy.js\" name=\"FileProxy\">\n            <merges target=\"\" />\n        </js-module>\n\n        <js-module src=\"www/fileSystemPaths.js\" name=\"fileSystemPaths\">\n            <merges target=\"cordova\" />\n            <runs/>\n        </js-module>\n    </platform>\n\n    <!-- firefox os -->\n    <platform name=\"firefoxos\">\n        <js-module src=\"src/firefoxos/FileProxy.js\" name=\"FileProxy\">\n            <runs />\n        </js-module>\n\n        <js-module src=\"www/fileSystemPaths.js\" name=\"fileSystemPaths\">\n            <merges target=\"cordova\" />\n            <runs/>\n        </js-module>\n\n        <!-- Firefox OS specific file apis -->\n        <js-module src=\"www/firefoxos/FileSystem.js\" name=\"firefoxFileSystem\">\n            <merges target=\"window.FileSystem\" />\n        </js-module>\n    </platform>\n\n    <platform name=\"browser\">\n        <!-- File for Chrome -->\n        <js-module src=\"www/browser/Preparing.js\" name=\"Preparing\">\n            <runs />\n        </js-module>\n\n        <js-module src=\"src/browser/FileProxy.js\" name=\"browserFileProxy\">\n            <runs />\n        </js-module>\n\n        <js-module src=\"www/fileSystemPaths.js\" name=\"fileSystemPaths\">\n            <merges target=\"cordova\" />\n            <runs />\n        </js-module>\n\n        <js-module src=\"www/browser/FileSystem.js\" name=\"firefoxFileSystem\">\n            <merges target=\"window.FileSystem\" />\n        </js-module>\n    </platform>\n\n</plugin>\n"
  },
  {
    "path": "plugins/cordova-plugin-file/src/android/AssetFilesystem.java",
    "content": "/*\n       Licensed to the Apache Software Foundation (ASF) under one\n       or more contributor license agreements.  See the NOTICE file\n       distributed with this work for additional information\n       regarding copyright ownership.  The ASF licenses this file\n       to you under the Apache License, Version 2.0 (the\n       \"License\"); you may not use this file except in compliance\n       with the License.  You may obtain a copy of the License at\n\n         http://www.apache.org/licenses/LICENSE-2.0\n\n       Unless required by applicable law or agreed to in writing,\n       software distributed under the License is distributed on an\n       \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n       KIND, either express or implied.  See the License for the\n       specific language governing permissions and limitations\n       under the License.\n */\npackage org.apache.cordova.file;\n\nimport android.content.res.AssetManager;\nimport android.net.Uri;\nimport android.util.Log;\n\nimport org.apache.cordova.CordovaResourceApi;\nimport org.json.JSONArray;\nimport org.json.JSONException;\nimport org.json.JSONObject;\n\nimport java.io.File;\nimport java.io.FileNotFoundException;\nimport java.io.IOException;\nimport java.io.ObjectInputStream;\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class AssetFilesystem extends Filesystem {\n\n    private final AssetManager assetManager;\n\n    // A custom gradle hook creates the cdvasset.manifest file, which speeds up asset listing a tonne.\n    // See: http://stackoverflow.com/questions/16911558/android-assetmanager-list-incredibly-slow\n    private static Object listCacheLock = new Object();\n    private static boolean listCacheFromFile;\n    private static Map<String, String[]> listCache;\n    private static Map<String, Long> lengthCache;\n\n    private void lazyInitCaches() {\n        synchronized (listCacheLock) {\n            if (listCache == null) {\n                ObjectInputStream ois = null;\n                try {\n                    ois = new ObjectInputStream(assetManager.open(\"cdvasset.manifest\"));\n                    listCache = (Map<String, String[]>) ois.readObject();\n                    lengthCache = (Map<String, Long>) ois.readObject();\n                    listCacheFromFile = true;\n                } catch (ClassNotFoundException e) {\n                    e.printStackTrace();\n                } catch (IOException e) {\n                    // Asset manifest won't exist if the gradle hook isn't set up correctly.\n                } finally {\n                    if (ois != null) {\n                        try {\n                            ois.close();\n                        } catch (IOException e) {\n                        }\n                    }\n                }\n                if (listCache == null) {\n                    Log.w(\"AssetFilesystem\", \"Asset manifest not found. Recursive copies and directory listing will be slow.\");\n                    listCache = new HashMap<String, String[]>();\n                }\n            }\n        }\n    }\n\n    private String[] listAssets(String assetPath) throws IOException {\n        if (assetPath.startsWith(\"/\")) {\n            assetPath = assetPath.substring(1);\n        }\n        if (assetPath.endsWith(\"/\")) {\n            assetPath = assetPath.substring(0, assetPath.length() - 1);\n        }\n        lazyInitCaches();\n        String[] ret = listCache.get(assetPath);\n        if (ret == null) {\n            if (listCacheFromFile) {\n                ret = new String[0];\n            } else {\n                ret = assetManager.list(assetPath);\n                listCache.put(assetPath, ret);\n            }\n        }\n        return ret;\n    }\n\n    private long getAssetSize(String assetPath) throws FileNotFoundException {\n        if (assetPath.startsWith(\"/\")) {\n            assetPath = assetPath.substring(1);\n        }\n        lazyInitCaches();\n        if (lengthCache != null) {\n            Long ret = lengthCache.get(assetPath);\n            if (ret == null) {\n                throw new FileNotFoundException(\"Asset not found: \" + assetPath);\n            }\n            return ret;\n        }\n        CordovaResourceApi.OpenForReadResult offr = null;\n        try {\n            offr = resourceApi.openForRead(nativeUriForFullPath(assetPath));\n            long length = offr.length;\n            if (length < 0) {\n                // available() doesn't always yield the file size, but for assets it does.\n                length = offr.inputStream.available();\n            }\n            return length;\n        } catch (IOException e) {\n            throw new FileNotFoundException(\"File not found: \" + assetPath);\n        } finally {\n            if (offr != null) {\n                try {\n                    offr.inputStream.close();\n                } catch (IOException e) {\n                }\n            }\n        }\n    }\n\n    public AssetFilesystem(AssetManager assetManager, CordovaResourceApi resourceApi) {\n        super(Uri.parse(\"file:///android_asset/\"), \"assets\", resourceApi);\n        this.assetManager = assetManager;\n\t}\n\n    @Override\n    public Uri toNativeUri(LocalFilesystemURL inputURL) {\n        return nativeUriForFullPath(inputURL.path);\n    }\n\n    @Override\n    public LocalFilesystemURL toLocalUri(Uri inputURL) {\n        if (!\"file\".equals(inputURL.getScheme())) {\n            return null;\n        }\n        File f = new File(inputURL.getPath());\n        // Removes and duplicate /s (e.g. file:///a//b/c)\n        Uri resolvedUri = Uri.fromFile(f);\n        String rootUriNoTrailingSlash = rootUri.getEncodedPath();\n        rootUriNoTrailingSlash = rootUriNoTrailingSlash.substring(0, rootUriNoTrailingSlash.length() - 1);\n        if (!resolvedUri.getEncodedPath().startsWith(rootUriNoTrailingSlash)) {\n            return null;\n        }\n        String subPath = resolvedUri.getEncodedPath().substring(rootUriNoTrailingSlash.length());\n        // Strip leading slash\n        if (!subPath.isEmpty()) {\n            subPath = subPath.substring(1);\n        }\n        Uri.Builder b = new Uri.Builder()\n            .scheme(LocalFilesystemURL.FILESYSTEM_PROTOCOL)\n            .authority(\"localhost\")\n            .path(name);\n        if (!subPath.isEmpty()) {\n            b.appendEncodedPath(subPath);\n        }\n        if (isDirectory(subPath) || inputURL.getPath().endsWith(\"/\")) {\n            // Add trailing / for directories.\n            b.appendEncodedPath(\"\");\n        }\n        return LocalFilesystemURL.parse(b.build());\n    }\n\n    private boolean isDirectory(String assetPath) {\n        try {\n            return listAssets(assetPath).length != 0;\n        } catch (IOException e) {\n            return false;\n        }\n    }\n\n    @Override\n    public LocalFilesystemURL[] listChildren(LocalFilesystemURL inputURL) throws FileNotFoundException {\n        String pathNoSlashes = inputURL.path.substring(1);\n        if (pathNoSlashes.endsWith(\"/\")) {\n            pathNoSlashes = pathNoSlashes.substring(0, pathNoSlashes.length() - 1);\n        }\n\n        String[] files;\n        try {\n            files = listAssets(pathNoSlashes);\n        } catch (IOException e) {\n            throw new FileNotFoundException();\n        }\n\n        LocalFilesystemURL[] entries = new LocalFilesystemURL[files.length];\n        for (int i = 0; i < files.length; ++i) {\n            entries[i] = localUrlforFullPath(new File(inputURL.path, files[i]).getPath());\n        }\n        return entries;\n\t}\n\n    @Override\n    public JSONObject getFileForLocalURL(LocalFilesystemURL inputURL,\n                                         String path, JSONObject options, boolean directory)\n            throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException {\n        if (options != null && options.optBoolean(\"create\")) {\n            throw new UnsupportedOperationException(\"Assets are read-only\");\n        }\n\n        // Check whether the supplied path is absolute or relative\n        if (directory && !path.endsWith(\"/\")) {\n            path += \"/\";\n        }\n\n        LocalFilesystemURL requestedURL;\n        if (path.startsWith(\"/\")) {\n            requestedURL = localUrlforFullPath(normalizePath(path));\n        } else {\n            requestedURL = localUrlforFullPath(normalizePath(inputURL.path + \"/\" + path));\n        }\n\n        // Throws a FileNotFoundException if it doesn't exist.\n        getFileMetadataForLocalURL(requestedURL);\n\n        boolean isDir = isDirectory(requestedURL.path);\n        if (directory && !isDir) {\n            throw new TypeMismatchException(\"path doesn't exist or is file\");\n        } else if (!directory && isDir) {\n            throw new TypeMismatchException(\"path doesn't exist or is directory\");\n        }\n\n        // Return the directory\n        return makeEntryForURL(requestedURL);\n    }\n\n    @Override\n\tpublic JSONObject getFileMetadataForLocalURL(LocalFilesystemURL inputURL) throws FileNotFoundException {\n        JSONObject metadata = new JSONObject();\n        long size = inputURL.isDirectory ? 0 : getAssetSize(inputURL.path);\n        try {\n        \tmetadata.put(\"size\", size);\n        \tmetadata.put(\"type\", inputURL.isDirectory ? \"text/directory\" : resourceApi.getMimeType(toNativeUri(inputURL)));\n        \tmetadata.put(\"name\", new File(inputURL.path).getName());\n        \tmetadata.put(\"fullPath\", inputURL.path);\n        \tmetadata.put(\"lastModifiedDate\", 0);\n        } catch (JSONException e) {\n            return null;\n        }\n        return metadata;\n\t}\n\n\t@Override\n\tpublic boolean canRemoveFileAtLocalURL(LocalFilesystemURL inputURL) {\n\t\treturn false;\n\t}\n\n    @Override\n    long writeToFileAtURL(LocalFilesystemURL inputURL, String data, int offset, boolean isBinary) throws NoModificationAllowedException, IOException {\n        throw new NoModificationAllowedException(\"Assets are read-only\");\n    }\n\n    @Override\n    long truncateFileAtURL(LocalFilesystemURL inputURL, long size) throws IOException, NoModificationAllowedException {\n        throw new NoModificationAllowedException(\"Assets are read-only\");\n    }\n\n    @Override\n    String filesystemPathForURL(LocalFilesystemURL url) {\n        return null;\n    }\n\n    @Override\n    LocalFilesystemURL URLforFilesystemPath(String path) {\n        return null;\n    }\n\n    @Override\n    boolean removeFileAtLocalURL(LocalFilesystemURL inputURL) throws InvalidModificationException, NoModificationAllowedException {\n        throw new NoModificationAllowedException(\"Assets are read-only\");\n    }\n\n    @Override\n    boolean recursiveRemoveFileAtLocalURL(LocalFilesystemURL inputURL) throws NoModificationAllowedException {\n        throw new NoModificationAllowedException(\"Assets are read-only\");\n    }\n\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-file/src/android/ContentFilesystem.java",
    "content": "/*\n       Licensed to the Apache Software Foundation (ASF) under one\n       or more contributor license agreements.  See the NOTICE file\n       distributed with this work for additional information\n       regarding copyright ownership.  The ASF licenses this file\n       to you under the Apache License, Version 2.0 (the\n       \"License\"); you may not use this file except in compliance\n       with the License.  You may obtain a copy of the License at\n\n         http://www.apache.org/licenses/LICENSE-2.0\n\n       Unless required by applicable law or agreed to in writing,\n       software distributed under the License is distributed on an\n       \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n       KIND, either express or implied.  See the License for the\n       specific language governing permissions and limitations\n       under the License.\n */\npackage org.apache.cordova.file;\n\nimport android.content.ContentResolver;\nimport android.content.Context;\nimport android.database.Cursor;\nimport android.net.Uri;\nimport android.provider.DocumentsContract;\nimport android.provider.MediaStore;\nimport android.provider.OpenableColumns;\nimport java.io.File;\nimport java.io.FileNotFoundException;\nimport java.io.IOException;\nimport org.apache.cordova.CordovaResourceApi;\nimport org.json.JSONException;\nimport org.json.JSONObject;\n\npublic class ContentFilesystem extends Filesystem {\n\n    private final Context context;\n\n\tpublic ContentFilesystem(Context context, CordovaResourceApi resourceApi) {\n\t\tsuper(Uri.parse(\"content://\"), \"content\", resourceApi);\n        this.context = context;\n\t}\n\n    @Override\n    public Uri toNativeUri(LocalFilesystemURL inputURL) {\n        String authorityAndPath = inputURL.uri.getEncodedPath().substring(this.name.length() + 2);\n        if (authorityAndPath.length() < 2) {\n            return null;\n        }\n        String ret = \"content://\" + authorityAndPath;\n        String query = inputURL.uri.getEncodedQuery();\n        if (query != null) {\n            ret += '?' + query;\n        }\n        String frag = inputURL.uri.getEncodedFragment();\n        if (frag != null) {\n            ret += '#' + frag;\n        }\n        return Uri.parse(ret);\n    }\n\n    @Override\n    public LocalFilesystemURL toLocalUri(Uri inputURL) {\n        if (!\"content\".equals(inputURL.getScheme())) {\n            return null;\n        }\n        String subPath = inputURL.getEncodedPath();\n        if (subPath.length() > 0) {\n            subPath = subPath.substring(1);\n        }\n        Uri.Builder b = new Uri.Builder()\n            .scheme(LocalFilesystemURL.FILESYSTEM_PROTOCOL)\n            .authority(\"localhost\")\n            .path(name)\n            .appendPath(inputURL.getAuthority());\n        if (subPath.length() > 0) {\n            b.appendEncodedPath(subPath);\n        }\n        Uri localUri = b.encodedQuery(inputURL.getEncodedQuery())\n            .encodedFragment(inputURL.getEncodedFragment())\n            .build();\n        return LocalFilesystemURL.parse(localUri);\n    }\n\n    @Override\n\tpublic JSONObject getFileForLocalURL(LocalFilesystemURL inputURL,\n\t\t\tString fileName, JSONObject options, boolean directory) throws IOException, TypeMismatchException, JSONException {\n        throw new UnsupportedOperationException(\"getFile() not supported for content:. Use resolveLocalFileSystemURL instead.\");\n\t}\n\n\t@Override\n\tpublic boolean removeFileAtLocalURL(LocalFilesystemURL inputURL)\n\t\t\tthrows NoModificationAllowedException {\n        Uri contentUri = toNativeUri(inputURL);\n\t\ttry {\n            context.getContentResolver().delete(contentUri, null, null);\n\t\t} catch (UnsupportedOperationException t) {\n\t\t\t// Was seeing this on the File mobile-spec tests on 4.0.3 x86 emulator.\n\t\t\t// The ContentResolver applies only when the file was registered in the\n\t\t\t// first case, which is generally only the case with images.\n            throw new NoModificationAllowedException(\"Deleting not supported for content uri: \" + contentUri);\n\t\t}\n        return true;\n\t}\n\n\t@Override\n\tpublic boolean recursiveRemoveFileAtLocalURL(LocalFilesystemURL inputURL)\n\t\t\tthrows NoModificationAllowedException {\n\t\tthrow new NoModificationAllowedException(\"Cannot remove content url\");\n\t}\n\n    @Override\n    public LocalFilesystemURL[] listChildren(LocalFilesystemURL inputURL) throws FileNotFoundException {\n        throw new UnsupportedOperationException(\"readEntriesAtLocalURL() not supported for content:. Use resolveLocalFileSystemURL instead.\");\n    }\n\n\t@Override\n\tpublic JSONObject getFileMetadataForLocalURL(LocalFilesystemURL inputURL) throws FileNotFoundException {\n        long size = -1;\n        long lastModified = 0;\n        Uri nativeUri = toNativeUri(inputURL);\n        String mimeType = resourceApi.getMimeType(nativeUri);\n        Cursor cursor = openCursorForURL(nativeUri);\n        try {\n        \tif (cursor != null && cursor.moveToFirst()) {\n        \t\tsize = resourceSizeForCursor(cursor);\n                Long modified = lastModifiedDateForCursor(cursor);\n                if (modified != null)\n                    lastModified = modified.longValue();\n        \t} else {\n                // Some content providers don't support cursors at all!\n                CordovaResourceApi.OpenForReadResult offr = resourceApi.openForRead(nativeUri);\n    \t\t\tsize = offr.length;\n        \t}\n        } catch (IOException e) {\n            throw new FileNotFoundException();\n        } finally {\n        \tif (cursor != null)\n        \t\tcursor.close();\n        }\n\n        JSONObject metadata = new JSONObject();\n        try {\n        \tmetadata.put(\"size\", size);\n        \tmetadata.put(\"type\", mimeType);\n        \tmetadata.put(\"name\", name);\n        \tmetadata.put(\"fullPath\", inputURL.path);\n        \tmetadata.put(\"lastModifiedDate\", lastModified);\n        } catch (JSONException e) {\n        \treturn null;\n        }\n        return metadata;\n\t}\n\n\t@Override\n\tpublic long writeToFileAtURL(LocalFilesystemURL inputURL, String data,\n\t\t\tint offset, boolean isBinary) throws NoModificationAllowedException {\n        throw new NoModificationAllowedException(\"Couldn't write to file given its content URI\");\n    }\n\t@Override\n\tpublic long truncateFileAtURL(LocalFilesystemURL inputURL, long size)\n\t\t\tthrows NoModificationAllowedException {\n        throw new NoModificationAllowedException(\"Couldn't truncate file given its content URI\");\n\t}\n\n\tprotected Cursor openCursorForURL(Uri nativeUri) {\n        ContentResolver contentResolver = context.getContentResolver();\n        try {\n            return contentResolver.query(nativeUri, null, null, null, null);\n        } catch (UnsupportedOperationException e) {\n            return null;\n        }\n\t}\n\n\tprivate Long resourceSizeForCursor(Cursor cursor) {\n        int columnIndex = cursor.getColumnIndex(OpenableColumns.SIZE);\n        if (columnIndex != -1) {\n            String sizeStr = cursor.getString(columnIndex);\n            if (sizeStr != null) {\n            \treturn Long.parseLong(sizeStr);\n            }\n        }\n        return null;\n\t}\n\t\n\tprotected Long lastModifiedDateForCursor(Cursor cursor) {\n        int columnIndex = cursor.getColumnIndex(MediaStore.MediaColumns.DATE_MODIFIED);\n        if (columnIndex == -1) {\n            columnIndex = cursor.getColumnIndex(DocumentsContract.Document.COLUMN_LAST_MODIFIED);\n        }\n        if (columnIndex != -1) {\n            String dateStr = cursor.getString(columnIndex);\n            if (dateStr != null) {\n                return Long.parseLong(dateStr);\n            }\n        }\n        return null;\n\t}\n\n    @Override\n    public String filesystemPathForURL(LocalFilesystemURL url) {\n        File f = resourceApi.mapUriToFile(toNativeUri(url));\n        return f == null ? null : f.getAbsolutePath();\n    }\n\n\t@Override\n\tpublic LocalFilesystemURL URLforFilesystemPath(String path) {\n\t\t// Returns null as we don't support reverse mapping back to content:// URLs\n\t\treturn null;\n\t}\n\n\t@Override\n\tpublic boolean canRemoveFileAtLocalURL(LocalFilesystemURL inputURL) {\n\t\treturn true;\n\t}\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-file/src/android/DirectoryManager.java",
    "content": "/*\n       Licensed to the Apache Software Foundation (ASF) under one\n       or more contributor license agreements.  See the NOTICE file\n       distributed with this work for additional information\n       regarding copyright ownership.  The ASF licenses this file\n       to you under the Apache License, Version 2.0 (the\n       \"License\"); you may not use this file except in compliance\n       with the License.  You may obtain a copy of the License at\n\n         http://www.apache.org/licenses/LICENSE-2.0\n\n       Unless required by applicable law or agreed to in writing,\n       software distributed under the License is distributed on an\n       \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n       KIND, either express or implied.  See the License for the\n       specific language governing permissions and limitations\n       under the License.\n*/\npackage org.apache.cordova.file;\n\nimport android.os.Environment;\nimport android.os.StatFs;\n\nimport java.io.File;\n\n/**\n * This class provides file directory utilities.\n * All file operations are performed on the SD card.\n *\n * It is used by the FileUtils class.\n */\npublic class DirectoryManager {\n\n    @SuppressWarnings(\"unused\")\n    private static final String LOG_TAG = \"DirectoryManager\";\n\n    /**\n     * Determine if a file or directory exists.\n     * @param name\t\t\t\tThe name of the file to check.\n     * @return\t\t\t\t\tT=exists, F=not found\n     */\n    public static boolean testFileExists(String name) {\n        boolean status;\n\n        // If SD card exists\n        if ((testSaveLocationExists()) && (!name.equals(\"\"))) {\n            File path = Environment.getExternalStorageDirectory();\n            File newPath = constructFilePaths(path.toString(), name);\n            status = newPath.exists();\n        }\n        // If no SD card\n        else {\n            status = false;\n        }\n        return status;\n    }\n\n    /**\n     * Get the free space in external storage\n     *\n     * @return \t\tSize in KB or -1 if not available\n     */\n    public static long getFreeExternalStorageSpace() {\n        String status = Environment.getExternalStorageState();\n        long freeSpaceInBytes = 0;\n\n        // Check if external storage exists\n        if (status.equals(Environment.MEDIA_MOUNTED)) {\n            freeSpaceInBytes = getFreeSpaceInBytes(Environment.getExternalStorageDirectory().getPath());\n        } else {\n            // If no external storage then return -1\n            return -1;\n        }\n\n        return freeSpaceInBytes / 1024;\n    }\n\n    /**\n     * Given a path return the number of free bytes in the filesystem containing the path.\n     *\n     * @param path to the file system\n     * @return free space in bytes\n     */\n    public static long getFreeSpaceInBytes(String path) {\n        try {\n            StatFs stat = new StatFs(path);\n            long blockSize = stat.getBlockSize();\n            long availableBlocks = stat.getAvailableBlocks();\n            return availableBlocks * blockSize;\n        } catch (IllegalArgumentException e) {\n            // The path was invalid. Just return 0 free bytes.\n            return 0;\n        }\n    }\n\n    /**\n     * Determine if SD card exists.\n     *\n     * @return\t\t\t\tT=exists, F=not found\n     */\n    public static boolean testSaveLocationExists() {\n        String sDCardStatus = Environment.getExternalStorageState();\n        boolean status;\n\n        // If SD card is mounted\n        if (sDCardStatus.equals(Environment.MEDIA_MOUNTED)) {\n            status = true;\n        }\n\n        // If no SD card\n        else {\n            status = false;\n        }\n        return status;\n    }\n\n    /**\n     * Create a new file object from two file paths.\n     *\n     * @param file1\t\t\tBase file path\n     * @param file2\t\t\tRemaining file path\n     * @return\t\t\t\tFile object\n     */\n    private static File constructFilePaths (String file1, String file2) {\n        File newPath;\n        if (file2.startsWith(file1)) {\n            newPath = new File(file2);\n        }\n        else {\n            newPath = new File(file1 + \"/\" + file2);\n        }\n        return newPath;\n    }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-file/src/android/EncodingException.java",
    "content": "/*\n       Licensed to the Apache Software Foundation (ASF) under one\n       or more contributor license agreements.  See the NOTICE file\n       distributed with this work for additional information\n       regarding copyright ownership.  The ASF licenses this file\n       to you under the Apache License, Version 2.0 (the\n       \"License\"); you may not use this file except in compliance\n       with the License.  You may obtain a copy of the License at\n\n         http://www.apache.org/licenses/LICENSE-2.0\n\n       Unless required by applicable law or agreed to in writing,\n       software distributed under the License is distributed on an\n       \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n       KIND, either express or implied.  See the License for the\n       specific language governing permissions and limitations\n       under the License.\n*/\n\npackage org.apache.cordova.file;\n\n@SuppressWarnings(\"serial\")\npublic class EncodingException extends Exception {\n\n    public EncodingException(String message) {\n        super(message);\n    }\n\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-file/src/android/FileExistsException.java",
    "content": "/*\n       Licensed to the Apache Software Foundation (ASF) under one\n       or more contributor license agreements.  See the NOTICE file\n       distributed with this work for additional information\n       regarding copyright ownership.  The ASF licenses this file\n       to you under the Apache License, Version 2.0 (the\n       \"License\"); you may not use this file except in compliance\n       with the License.  You may obtain a copy of the License at\n\n         http://www.apache.org/licenses/LICENSE-2.0\n\n       Unless required by applicable law or agreed to in writing,\n       software distributed under the License is distributed on an\n       \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n       KIND, either express or implied.  See the License for the\n       specific language governing permissions and limitations\n       under the License.\n*/\n\npackage org.apache.cordova.file;\n\n@SuppressWarnings(\"serial\")\npublic class FileExistsException extends Exception {\n\n    public FileExistsException(String msg) {\n        super(msg);\n    }\n\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-file/src/android/FileUtils.java",
    "content": "/*\n       Licensed to the Apache Software Foundation (ASF) under one\n       or more contributor license agreements.  See the NOTICE file\n       distributed with this work for additional information\n       regarding copyright ownership.  The ASF licenses this file\n       to you under the Apache License, Version 2.0 (the\n       \"License\"); you may not use this file except in compliance\n       with the License.  You may obtain a copy of the License at\n\n         http://www.apache.org/licenses/LICENSE-2.0\n\n       Unless required by applicable law or agreed to in writing,\n       software distributed under the License is distributed on an\n       \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n       KIND, either express or implied.  See the License for the\n       specific language governing permissions and limitations\n       under the License.\n */\npackage org.apache.cordova.file;\n\nimport android.Manifest;\nimport android.app.Activity;\nimport android.content.Context;\nimport android.content.pm.PackageManager;\nimport android.net.Uri;\nimport android.os.Build;\nimport android.os.Environment;\nimport android.util.Base64;\nimport android.util.Log;\n\nimport org.apache.cordova.CallbackContext;\nimport org.apache.cordova.CordovaInterface;\nimport org.apache.cordova.CordovaPlugin;\nimport org.apache.cordova.CordovaWebView;\nimport org.apache.cordova.PermissionHelper;\nimport org.apache.cordova.PluginResult;\n\nimport org.json.JSONArray;\nimport org.json.JSONException;\nimport org.json.JSONObject;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.File;\nimport java.io.FileNotFoundException;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.net.MalformedURLException;\nimport java.security.Permission;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.HashSet;\n\n/**\n * This class provides file and directory services to JavaScript.\n */\npublic class FileUtils extends CordovaPlugin {\n    private static final String LOG_TAG = \"FileUtils\";\n\n    public static int NOT_FOUND_ERR = 1;\n    public static int SECURITY_ERR = 2;\n    public static int ABORT_ERR = 3;\n\n    public static int NOT_READABLE_ERR = 4;\n    public static int ENCODING_ERR = 5;\n    public static int NO_MODIFICATION_ALLOWED_ERR = 6;\n    public static int INVALID_STATE_ERR = 7;\n    public static int SYNTAX_ERR = 8;\n    public static int INVALID_MODIFICATION_ERR = 9;\n    public static int QUOTA_EXCEEDED_ERR = 10;\n    public static int TYPE_MISMATCH_ERR = 11;\n    public static int PATH_EXISTS_ERR = 12;\n\n    /*\n     * Permission callback codes\n     */\n\n    public static final int ACTION_GET_FILE = 0;\n    public static final int ACTION_WRITE = 1;\n    public static final int ACTION_GET_DIRECTORY = 2;\n\n    public static final int WRITE = 3;\n    public static final int READ = 4;\n\n    public static int UNKNOWN_ERR = 1000;\n\n    private boolean configured = false;\n\n    private PendingRequests pendingRequests;\n\n\n\n    /*\n     * We need both read and write when accessing the storage, I think.\n     */\n\n    private String [] permissions = {\n            Manifest.permission.READ_EXTERNAL_STORAGE,\n            Manifest.permission.WRITE_EXTERNAL_STORAGE };\n\n    // This field exists only to support getEntry, below, which has been deprecated\n    private static FileUtils filePlugin;\n\n    private interface FileOp {\n        void run(JSONArray args) throws Exception;\n    }\n\n    private ArrayList<Filesystem> filesystems;\n\n    public void registerFilesystem(Filesystem fs) {\n    \tif (fs != null && filesystemForName(fs.name)== null) {\n    \t\tthis.filesystems.add(fs);\n    \t}\n    }\n\n    private Filesystem filesystemForName(String name) {\n    \tfor (Filesystem fs:filesystems) {\n    \t\tif (fs != null && fs.name != null && fs.name.equals(name)) {\n    \t\t\treturn fs;\n    \t\t}\n    \t}\n    \treturn null;\n    }\n\n    protected String[] getExtraFileSystemsPreference(Activity activity) {\n        String fileSystemsStr = preferences.getString(\"androidextrafilesystems\", \"files,files-external,documents,sdcard,cache,cache-external,root\");\n        return fileSystemsStr.split(\",\");\n    }\n\n    protected void registerExtraFileSystems(String[] filesystems, HashMap<String, String> availableFileSystems) {\n        HashSet<String> installedFileSystems = new HashSet<String>();\n\n        /* Register filesystems in order */\n        for (String fsName : filesystems) {\n            if (!installedFileSystems.contains(fsName)) {\n                String fsRoot = availableFileSystems.get(fsName);\n                if (fsRoot != null) {\n                    File newRoot = new File(fsRoot);\n                    if (newRoot.mkdirs() || newRoot.isDirectory()) {\n                        registerFilesystem(new LocalFilesystem(fsName, webView.getContext(), webView.getResourceApi(), newRoot));\n                        installedFileSystems.add(fsName);\n                    } else {\n                       Log.d(LOG_TAG, \"Unable to create root dir for filesystem \\\"\" + fsName + \"\\\", skipping\");\n                    }\n                } else {\n                    Log.d(LOG_TAG, \"Unrecognized extra filesystem identifier: \" + fsName);\n                }\n            }\n        }\n    }\n\n    protected HashMap<String, String> getAvailableFileSystems(Activity activity) {\n        Context context = activity.getApplicationContext();\n        HashMap<String, String> availableFileSystems = new HashMap<String,String>();\n\n        availableFileSystems.put(\"files\", context.getFilesDir().getAbsolutePath());\n        availableFileSystems.put(\"documents\", new File(context.getFilesDir(), \"Documents\").getAbsolutePath());\n        availableFileSystems.put(\"cache\", context.getCacheDir().getAbsolutePath());\n        availableFileSystems.put(\"root\", \"/\");\n        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {\n          try {\n            availableFileSystems.put(\"files-external\", context.getExternalFilesDir(null).getAbsolutePath());\n            availableFileSystems.put(\"sdcard\", Environment.getExternalStorageDirectory().getAbsolutePath());\n            availableFileSystems.put(\"cache-external\", context.getExternalCacheDir().getAbsolutePath());\n          }\n          catch(NullPointerException e) {\n              Log.d(LOG_TAG, \"External storage unavailable, check to see if USB Mass Storage Mode is on\");\n          }\n        }\n\n        return availableFileSystems;\n    }\n\n    @Override\n    public void initialize(CordovaInterface cordova, CordovaWebView webView) {\n    \tsuper.initialize(cordova, webView);\n    \tthis.filesystems = new ArrayList<Filesystem>();\n        this.pendingRequests = new PendingRequests();\n\n    \tString tempRoot = null;\n    \tString persistentRoot = null;\n\n    \tActivity activity = cordova.getActivity();\n    \tString packageName = activity.getPackageName();\n\n        String location = preferences.getString(\"androidpersistentfilelocation\", \"internal\");\n\n    \ttempRoot = activity.getCacheDir().getAbsolutePath();\n    \tif (\"internal\".equalsIgnoreCase(location)) {\n    \t\tpersistentRoot = activity.getFilesDir().getAbsolutePath() + \"/files/\";\n    \t\tthis.configured = true;\n    \t} else if (\"compatibility\".equalsIgnoreCase(location)) {\n    \t\t/*\n    \t\t *  Fall-back to compatibility mode -- this is the logic implemented in\n    \t\t *  earlier versions of this plugin, and should be maintained here so\n    \t\t *  that apps which were originally deployed with older versions of the\n    \t\t *  plugin can continue to provide access to files stored under those\n    \t\t *  versions.\n    \t\t */\n    \t\tif (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {\n    \t\t\tpersistentRoot = Environment.getExternalStorageDirectory().getAbsolutePath();\n    \t\t\ttempRoot = Environment.getExternalStorageDirectory().getAbsolutePath() +\n    \t\t\t\t\t\"/Android/data/\" + packageName + \"/cache/\";\n    \t\t} else {\n    \t\t\tpersistentRoot = \"/data/data/\" + packageName;\n    \t\t}\n    \t\tthis.configured = true;\n    \t}\n\n    \tif (this.configured) {\n\t\t\t// Create the directories if they don't exist.\n\t\t\tFile tmpRootFile = new File(tempRoot);\n            File persistentRootFile = new File(persistentRoot);\n            tmpRootFile.mkdirs();\n            persistentRootFile.mkdirs();\n\n    \t\t// Register initial filesystems\n    \t\t// Note: The temporary and persistent filesystems need to be the first two\n    \t\t// registered, so that they will match window.TEMPORARY and window.PERSISTENT,\n    \t\t// per spec.\n    \t\tthis.registerFilesystem(new LocalFilesystem(\"temporary\", webView.getContext(), webView.getResourceApi(), tmpRootFile));\n    \t\tthis.registerFilesystem(new LocalFilesystem(\"persistent\", webView.getContext(), webView.getResourceApi(), persistentRootFile));\n    \t\tthis.registerFilesystem(new ContentFilesystem(webView.getContext(), webView.getResourceApi()));\n            this.registerFilesystem(new AssetFilesystem(webView.getContext().getAssets(), webView.getResourceApi()));\n\n            registerExtraFileSystems(getExtraFileSystemsPreference(activity), getAvailableFileSystems(activity));\n\n    \t\t// Initialize static plugin reference for deprecated getEntry method\n    \t\tif (filePlugin == null) {\n    \t\t\tFileUtils.filePlugin = this;\n    \t\t}\n    \t} else {\n    \t\tLog.e(LOG_TAG, \"File plugin configuration error: Please set AndroidPersistentFileLocation in config.xml to one of \\\"internal\\\" (for new applications) or \\\"compatibility\\\" (for compatibility with previous versions)\");\n    \t\tactivity.finish();\n    \t}\n    }\n\n    public static FileUtils getFilePlugin() {\n\t\treturn filePlugin;\n\t}\n\n\tprivate Filesystem filesystemForURL(LocalFilesystemURL localURL) {\n    \tif (localURL == null) return null;\n    \treturn filesystemForName(localURL.fsName);\n    }\n\n    @Override\n    public Uri remapUri(Uri uri) {\n        // Remap only cdvfile: URLs (not content:).\n        if (!LocalFilesystemURL.FILESYSTEM_PROTOCOL.equals(uri.getScheme())) {\n            return null;\n        }\n        try {\n        \tLocalFilesystemURL inputURL = LocalFilesystemURL.parse(uri);\n        \tFilesystem fs = this.filesystemForURL(inputURL);\n        \tif (fs == null) {\n        \t\treturn null;\n        \t}\n        \tString path = fs.filesystemPathForURL(inputURL);\n        \tif (path != null) {\n        \t\treturn Uri.parse(\"file://\" + fs.filesystemPathForURL(inputURL));\n        \t}\n        \treturn null;\n        } catch (IllegalArgumentException e) {\n        \treturn null;\n        }\n    }\n\n    public boolean execute(String action, final String rawArgs, final CallbackContext callbackContext) {\n        if (!configured) {\n            callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, \"File plugin is not configured. Please see the README.md file for details on how to update config.xml\"));\n            return true;\n        }\n        if (action.equals(\"testSaveLocationExists\")) {\n            threadhelper(new FileOp() {\n                public void run(JSONArray args) {\n                    boolean b = DirectoryManager.testSaveLocationExists();\n                    callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, b));\n                }\n            }, rawArgs, callbackContext);\n        }\n        else if (action.equals(\"getFreeDiskSpace\")) {\n            threadhelper( new FileOp( ){\n                public void run(JSONArray args) {\n                    // The getFreeDiskSpace plugin API is not documented, but some apps call it anyway via exec().\n                    // For compatibility it always returns free space in the primary external storage, and\n                    // does NOT fallback to internal store if external storage is unavailable.\n                    long l = DirectoryManager.getFreeExternalStorageSpace();\n                    callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, l));\n                }\n            }, rawArgs, callbackContext);\n        }\n        else if (action.equals(\"testFileExists\")) {\n            threadhelper( new FileOp( ){\n                public void run(JSONArray args) throws JSONException {\n                    String fname=args.getString(0);\n                    boolean b = DirectoryManager.testFileExists(fname);\n                    callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, b));\n                }\n            }, rawArgs, callbackContext);\n        }\n        else if (action.equals(\"testDirectoryExists\")) {\n            threadhelper( new FileOp( ){\n                public void run(JSONArray args) throws JSONException {\n                    String fname=args.getString(0);\n                    boolean b = DirectoryManager.testFileExists(fname);\n                    callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, b));\n                }\n            }, rawArgs, callbackContext);\n        }\n        else if (action.equals(\"readAsText\")) {\n            threadhelper( new FileOp( ){\n                public void run(JSONArray args) throws JSONException, MalformedURLException {\n                    String encoding = args.getString(1);\n                    int start = args.getInt(2);\n                    int end = args.getInt(3);\n                    String fname=args.getString(0);\n                    readFileAs(fname, start, end, callbackContext, encoding, PluginResult.MESSAGE_TYPE_STRING);\n                }\n            }, rawArgs, callbackContext);\n        }\n        else if (action.equals(\"readAsDataURL\")) {\n            threadhelper( new FileOp( ){\n                public void run(JSONArray args) throws JSONException, MalformedURLException  {\n                    int start = args.getInt(1);\n                    int end = args.getInt(2);\n                    String fname=args.getString(0);\n                    readFileAs(fname, start, end, callbackContext, null, -1);\n                }\n            }, rawArgs, callbackContext);\n        }\n        else if (action.equals(\"readAsArrayBuffer\")) {\n            threadhelper( new FileOp( ){\n                public void run(JSONArray args) throws JSONException, MalformedURLException  {\n                    int start = args.getInt(1);\n                    int end = args.getInt(2);\n                    String fname=args.getString(0);\n                    readFileAs(fname, start, end, callbackContext, null, PluginResult.MESSAGE_TYPE_ARRAYBUFFER);\n                }\n            }, rawArgs, callbackContext);\n        }\n        else if (action.equals(\"readAsBinaryString\")) {\n            threadhelper( new FileOp( ){\n                public void run(JSONArray args) throws JSONException, MalformedURLException  {\n                    int start = args.getInt(1);\n                    int end = args.getInt(2);\n                    String fname=args.getString(0);\n                    readFileAs(fname, start, end, callbackContext, null, PluginResult.MESSAGE_TYPE_BINARYSTRING);\n                }\n            }, rawArgs, callbackContext);\n        }\n        else if (action.equals(\"write\")) {\n            threadhelper( new FileOp( ){\n                public void run(JSONArray args) throws JSONException, FileNotFoundException, IOException, NoModificationAllowedException {\n                    String fname=args.getString(0);\n                    String nativeURL = resolveLocalFileSystemURI(fname).getString(\"nativeURL\");\n                    String data=args.getString(1);\n                    int offset=args.getInt(2);\n                    Boolean isBinary=args.getBoolean(3);\n\n                    if(needPermission(nativeURL, WRITE)) {\n                        getWritePermission(rawArgs, ACTION_WRITE, callbackContext);\n                    }\n                    else {\n                        long fileSize = write(fname, data, offset, isBinary);\n                        callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, fileSize));\n                    }\n\n                }\n            }, rawArgs, callbackContext);\n        }\n        else if (action.equals(\"truncate\")) {\n            threadhelper( new FileOp( ){\n                public void run(JSONArray args) throws JSONException, FileNotFoundException, IOException, NoModificationAllowedException {\n                    String fname=args.getString(0);\n                    int offset=args.getInt(1);\n                    long fileSize = truncateFile(fname, offset);\n                    callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, fileSize));\n                }\n            }, rawArgs, callbackContext);\n        }\n        else if (action.equals(\"requestAllFileSystems\")) {\n            threadhelper( new FileOp( ){\n                public void run(JSONArray args) throws IOException, JSONException {\n                    callbackContext.success(requestAllFileSystems());\n                }\n            }, rawArgs, callbackContext);\n        } else if (action.equals(\"requestAllPaths\")) {\n            cordova.getThreadPool().execute(\n                    new Runnable() {\n                        public void run() {\n                        \ttry {\n\t\t\t\t\tcallbackContext.success(requestAllPaths());\n\t\t\t\t} catch (JSONException e) {\n\t\t\t\t\t// TODO Auto-generated catch block\n\t\t\t\t\te.printStackTrace();\n\t\t\t\t}\n                        }\n                    }\n            );\n        } else if (action.equals(\"requestFileSystem\")) {\n            threadhelper( new FileOp( ){\n                public void run(JSONArray args) throws JSONException {\n                    int fstype = args.getInt(0);\n                    long requiredSize = args.optLong(1);\n                    requestFileSystem(fstype, requiredSize, callbackContext);\n                }\n            }, rawArgs, callbackContext);\n        }\n        else if (action.equals(\"resolveLocalFileSystemURI\")) {\n            threadhelper( new FileOp( ){\n                public void run(JSONArray args) throws IOException, JSONException {\n                    String fname=args.getString(0);\n                    JSONObject obj = resolveLocalFileSystemURI(fname);\n                    callbackContext.success(obj);\n                }\n            }, rawArgs, callbackContext);\n        }\n        else if (action.equals(\"getFileMetadata\")) {\n            threadhelper( new FileOp( ){\n                public void run(JSONArray args) throws FileNotFoundException, JSONException, MalformedURLException {\n                    String fname=args.getString(0);\n                    JSONObject obj = getFileMetadata(fname);\n                    callbackContext.success(obj);\n                }\n            }, rawArgs, callbackContext);\n        }\n        else if (action.equals(\"getParent\")) {\n            threadhelper( new FileOp( ){\n                public void run(JSONArray args) throws JSONException, IOException {\n                    String fname=args.getString(0);\n                    JSONObject obj = getParent(fname);\n                    callbackContext.success(obj);\n                }\n            }, rawArgs, callbackContext);\n        }\n        else if (action.equals(\"getDirectory\")) {\n            threadhelper( new FileOp( ){\n                public void run(JSONArray args) throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException {\n                    String dirname = args.getString(0);\n                    String path = args.getString(1);\n                    String nativeURL = resolveLocalFileSystemURI(dirname).getString(\"nativeURL\");\n                    boolean containsCreate = (args.isNull(2)) ? false : args.getJSONObject(2).optBoolean(\"create\", false);\n\n                    if(containsCreate && needPermission(nativeURL, WRITE)) {\n                        getWritePermission(rawArgs, ACTION_GET_DIRECTORY, callbackContext);\n                    }\n                    else if(!containsCreate && needPermission(nativeURL, READ)) {\n                        getReadPermission(rawArgs, ACTION_GET_DIRECTORY, callbackContext);\n                    }\n                    else {\n                        JSONObject obj = getFile(dirname, path, args.optJSONObject(2), true);\n                        callbackContext.success(obj);\n                    }\n                }\n            }, rawArgs, callbackContext);\n        }\n        else if (action.equals(\"getFile\")) {\n            threadhelper( new FileOp( ){\n                public void run(JSONArray args) throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException {\n                    String dirname = args.getString(0);\n                    String path = args.getString(1);\n                    String nativeURL = resolveLocalFileSystemURI(dirname).getString(\"nativeURL\");\n                    boolean containsCreate = (args.isNull(2)) ? false : args.getJSONObject(2).optBoolean(\"create\", false);\n\n                    if(containsCreate && needPermission(nativeURL, WRITE)) {\n                        getWritePermission(rawArgs, ACTION_GET_FILE, callbackContext);\n                    }\n                    else if(!containsCreate && needPermission(nativeURL, READ)) {\n                        getReadPermission(rawArgs, ACTION_GET_FILE, callbackContext);\n                    }\n                    else {\n                        JSONObject obj = getFile(dirname, path, args.optJSONObject(2), false);\n                        callbackContext.success(obj);\n                    }\n                }\n            }, rawArgs, callbackContext);\n        }\n        else if (action.equals(\"remove\")) {\n            threadhelper( new FileOp( ){\n                public void run(JSONArray args) throws JSONException, NoModificationAllowedException, InvalidModificationException, MalformedURLException {\n                    String fname=args.getString(0);\n                    boolean success = remove(fname);\n                    if (success) {\n                        callbackContext.success();\n                    } else {\n                        callbackContext.error(FileUtils.NO_MODIFICATION_ALLOWED_ERR);\n                    }\n                }\n            }, rawArgs, callbackContext);\n        }\n        else if (action.equals(\"removeRecursively\")) {\n            threadhelper( new FileOp( ){\n                public void run(JSONArray args) throws JSONException, FileExistsException, MalformedURLException, NoModificationAllowedException {\n                    String fname=args.getString(0);\n                    boolean success = removeRecursively(fname);\n                    if (success) {\n                        callbackContext.success();\n                    } else {\n                        callbackContext.error(FileUtils.NO_MODIFICATION_ALLOWED_ERR);\n                    }\n                }\n            }, rawArgs, callbackContext);\n        }\n        else if (action.equals(\"moveTo\")) {\n            threadhelper( new FileOp( ){\n                public void run(JSONArray args) throws JSONException, NoModificationAllowedException, IOException, InvalidModificationException, EncodingException, FileExistsException {\n                    String fname=args.getString(0);\n                    String newParent=args.getString(1);\n                    String newName=args.getString(2);\n                    JSONObject entry = transferTo(fname, newParent, newName, true);\n                    callbackContext.success(entry);\n                }\n            }, rawArgs, callbackContext);\n        }\n        else if (action.equals(\"copyTo\")) {\n            threadhelper( new FileOp( ){\n                public void run(JSONArray args) throws JSONException, NoModificationAllowedException, IOException, InvalidModificationException, EncodingException, FileExistsException {\n                    String fname=args.getString(0);\n                    String newParent=args.getString(1);\n                    String newName=args.getString(2);\n                    JSONObject entry = transferTo(fname, newParent, newName, false);\n                    callbackContext.success(entry);\n                }\n            }, rawArgs, callbackContext);\n        }\n        else if (action.equals(\"readEntries\")) {\n            threadhelper( new FileOp( ){\n                public void run(JSONArray args) throws FileNotFoundException, JSONException, MalformedURLException {\n                    String fname=args.getString(0);\n                    JSONArray entries = readEntries(fname);\n                    callbackContext.success(entries);\n                }\n            }, rawArgs, callbackContext);\n        }\n        else if (action.equals(\"_getLocalFilesystemPath\")) {\n            // Internal method for testing: Get the on-disk location of a local filesystem url.\n            // [Currently used for testing file-transfer]\n            threadhelper( new FileOp( ){\n                public void run(JSONArray args) throws FileNotFoundException, JSONException, MalformedURLException {\n                    String localURLstr = args.getString(0);\n                    String fname = filesystemPathForURL(localURLstr);\n                    callbackContext.success(fname);\n                }\n            }, rawArgs, callbackContext);\n        }\n        else {\n            return false;\n        }\n        return true;\n    }\n\n    private void getReadPermission(String rawArgs, int action, CallbackContext callbackContext) {\n        int requestCode = pendingRequests.createRequest(rawArgs, action, callbackContext);\n        PermissionHelper.requestPermission(this, requestCode, Manifest.permission.READ_EXTERNAL_STORAGE);\n    }\n\n    private void getWritePermission(String rawArgs, int action, CallbackContext callbackContext) {\n        int requestCode = pendingRequests.createRequest(rawArgs, action, callbackContext);\n        PermissionHelper.requestPermission(this, requestCode, Manifest.permission.WRITE_EXTERNAL_STORAGE);\n    }\n\n    private boolean hasReadPermission() {\n        return PermissionHelper.hasPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE);\n    }\n\n    private boolean hasWritePermission() {\n        return PermissionHelper.hasPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);\n    }\n\n    private boolean needPermission(String nativeURL, int permissionType) throws JSONException {\n        JSONObject j = requestAllPaths();\n        String[] allowedStorageDirectories = {j.getString(\"applicationStorageDirectory\"), j.getString(\"externalApplicationStorageDirectory\")};\n\n        if(permissionType == READ && hasReadPermission()) {\n            return false;\n        }\n        else if(permissionType == WRITE && hasWritePermission()) {\n            return false;\n        }\n\n        // Permission required if the native url lies outside the allowed storage directories\n        for(String directory : allowedStorageDirectories) {\n            if(nativeURL.startsWith(directory)) {\n                return false;\n            }\n        }\n        return true;\n    }\n\n\n    public LocalFilesystemURL resolveNativeUri(Uri nativeUri) {\n        LocalFilesystemURL localURL = null;\n\n        // Try all installed filesystems. Return the best matching URL\n        // (determined by the shortest resulting URL)\n        for (Filesystem fs : filesystems) {\n            LocalFilesystemURL url = fs.toLocalUri(nativeUri);\n            if (url != null) {\n                // A shorter fullPath implies that the filesystem is a better\n                // match for the local path than the previous best.\n                if (localURL == null || (url.uri.toString().length() < localURL.toString().length())) {\n                    localURL = url;\n                }\n            }\n        }\n        return localURL;\n    }\n\n    /*\n     * These two native-only methods can be used by other plugins to translate between\n     * device file system paths and URLs. By design, there is no direct JavaScript\n     * interface to these methods.\n     */\n\n    public String filesystemPathForURL(String localURLstr) throws MalformedURLException {\n        try {\n            LocalFilesystemURL inputURL = LocalFilesystemURL.parse(localURLstr);\n            Filesystem fs = this.filesystemForURL(inputURL);\n            if (fs == null) {\n                throw new MalformedURLException(\"No installed handlers for this URL\");\n            }\n            return fs.filesystemPathForURL(inputURL);\n        } catch (IllegalArgumentException e) {\n            throw new MalformedURLException(\"Unrecognized filesystem URL\");\n        }\n    }\n\n    public LocalFilesystemURL filesystemURLforLocalPath(String localPath) {\n        LocalFilesystemURL localURL = null;\n        int shortestFullPath = 0;\n\n        // Try all installed filesystems. Return the best matching URL\n        // (determined by the shortest resulting URL)\n        for (Filesystem fs: filesystems) {\n            LocalFilesystemURL url = fs.URLforFilesystemPath(localPath);\n            if (url != null) {\n                // A shorter fullPath implies that the filesystem is a better\n                // match for the local path than the previous best.\n                if (localURL == null || (url.path.length() < shortestFullPath)) {\n                    localURL = url;\n                    shortestFullPath = url.path.length();\n                }\n            }\n        }\n        return localURL;\n    }\n\n\n\t/* helper to execute functions async and handle the result codes\n     *\n     */\n    private void threadhelper(final FileOp f, final String rawArgs, final CallbackContext callbackContext){\n        cordova.getThreadPool().execute(new Runnable() {\n            public void run() {\n                try {\n                    JSONArray args = new JSONArray(rawArgs);\n                    f.run(args);\n                } catch ( Exception e) {\n                    if( e instanceof EncodingException){\n                        callbackContext.error(FileUtils.ENCODING_ERR);\n                    } else if(e instanceof FileNotFoundException) {\n                        callbackContext.error(FileUtils.NOT_FOUND_ERR);\n                    } else if(e instanceof FileExistsException) {\n                        callbackContext.error(FileUtils.PATH_EXISTS_ERR);\n                    } else if(e instanceof NoModificationAllowedException ) {\n                        callbackContext.error(FileUtils.NO_MODIFICATION_ALLOWED_ERR);\n                    } else if(e instanceof InvalidModificationException ) {\n                        callbackContext.error(FileUtils.INVALID_MODIFICATION_ERR);\n                    } else if(e instanceof MalformedURLException ) {\n                        callbackContext.error(FileUtils.ENCODING_ERR);\n                    } else if(e instanceof IOException ) {\n                        callbackContext.error(FileUtils.INVALID_MODIFICATION_ERR);\n                    } else if(e instanceof EncodingException ) {\n                        callbackContext.error(FileUtils.ENCODING_ERR);\n                    } else if(e instanceof TypeMismatchException ) {\n                        callbackContext.error(FileUtils.TYPE_MISMATCH_ERR);\n                    } else if(e instanceof JSONException ) {\n                        callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));\n                    } else {\n                        e.printStackTrace();\n                    \tcallbackContext.error(FileUtils.UNKNOWN_ERR);\n                    }\n                }\n            }\n        });\n    }\n\n    /**\n     * Allows the user to look up the Entry for a file or directory referred to by a local URI.\n     *\n     * @param uriString of the file/directory to look up\n     * @return a JSONObject representing a Entry from the filesystem\n     * @throws MalformedURLException if the url is not valid\n     * @throws FileNotFoundException if the file does not exist\n     * @throws IOException if the user can't read the file\n     * @throws JSONException\n     */\n    private JSONObject resolveLocalFileSystemURI(String uriString) throws IOException, JSONException {\n        if (uriString == null) {\n            throw new MalformedURLException(\"Unrecognized filesystem URL\");\n        }\n        Uri uri = Uri.parse(uriString);\n        boolean isNativeUri = false;\n\n        LocalFilesystemURL inputURL = LocalFilesystemURL.parse(uri);\n        if (inputURL == null) {\n            /* Check for file://, content:// urls */\n            inputURL = resolveNativeUri(uri);\n            isNativeUri = true;\n        }\n\n        try {\n            Filesystem fs = this.filesystemForURL(inputURL);\n            if (fs == null) {\n                throw new MalformedURLException(\"No installed handlers for this URL\");\n            }\n            if (fs.exists(inputURL)) {\n                if (!isNativeUri) {\n                    // If not already resolved as native URI, resolve to a native URI and back to\n                    // fix the terminating slash based on whether the entry is a directory or file.\n                    inputURL = fs.toLocalUri(fs.toNativeUri(inputURL));\n                }\n\n                return fs.getEntryForLocalURL(inputURL);\n            }\n        } catch (IllegalArgumentException e) {\n            throw new MalformedURLException(\"Unrecognized filesystem URL\");\n        }\n        throw new FileNotFoundException();\n    }\n\n    /**\n     * Read the list of files from this directory.\n     *\n     * @return a JSONArray containing JSONObjects that represent Entry objects.\n     * @throws FileNotFoundException if the directory is not found.\n     * @throws JSONException\n     * @throws MalformedURLException\n     */\n    private JSONArray readEntries(String baseURLstr) throws FileNotFoundException, JSONException, MalformedURLException {\n        try {\n        \tLocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr);\n        \tFilesystem fs = this.filesystemForURL(inputURL);\n        \tif (fs == null) {\n        \t\tthrow new MalformedURLException(\"No installed handlers for this URL\");\n        \t}\n        \treturn fs.readEntriesAtLocalURL(inputURL);\n\n        } catch (IllegalArgumentException e) {\n        \tthrow new MalformedURLException(\"Unrecognized filesystem URL\");\n        }\n    }\n\n    /**\n     * A setup method that handles the move/copy of files/directories\n     *\n     * @param newName for the file directory to be called, if null use existing file name\n     * @param move if false do a copy, if true do a move\n     * @return a Entry object\n     * @throws NoModificationAllowedException\n     * @throws IOException\n     * @throws InvalidModificationException\n     * @throws EncodingException\n     * @throws JSONException\n     * @throws FileExistsException\n     */\n    private JSONObject transferTo(String srcURLstr, String destURLstr, String newName, boolean move) throws JSONException, NoModificationAllowedException, IOException, InvalidModificationException, EncodingException, FileExistsException {\n        if (srcURLstr == null || destURLstr == null) {\n            // either no source or no destination provided\n        \tthrow new FileNotFoundException();\n        }\n\n        LocalFilesystemURL srcURL = LocalFilesystemURL.parse(srcURLstr);\n        LocalFilesystemURL destURL = LocalFilesystemURL.parse(destURLstr);\n\n        Filesystem srcFs = this.filesystemForURL(srcURL);\n        Filesystem destFs = this.filesystemForURL(destURL);\n\n        // Check for invalid file name\n        if (newName != null && newName.contains(\":\")) {\n            throw new EncodingException(\"Bad file name\");\n        }\n\n        return destFs.copyFileToURL(destURL, newName, srcFs, srcURL, move);\n    }\n\n    /**\n     * Deletes a directory and all of its contents, if any. In the event of an error\n     * [e.g. trying to delete a directory that contains a file that cannot be removed],\n     * some of the contents of the directory may be deleted.\n     * It is an error to attempt to delete the root directory of a filesystem.\n     *\n     * @return a boolean representing success of failure\n     * @throws FileExistsException\n     * @throws NoModificationAllowedException\n     * @throws MalformedURLException\n     */\n    private boolean removeRecursively(String baseURLstr) throws FileExistsException, NoModificationAllowedException, MalformedURLException {\n        try {\n        \tLocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr);\n        \t// You can't delete the root directory.\n        \tif (\"\".equals(inputURL.path) || \"/\".equals(inputURL.path)) {\n        \t\tthrow new NoModificationAllowedException(\"You can't delete the root directory\");\n        \t}\n\n        \tFilesystem fs = this.filesystemForURL(inputURL);\n        \tif (fs == null) {\n        \t\tthrow new MalformedURLException(\"No installed handlers for this URL\");\n        \t}\n        \treturn fs.recursiveRemoveFileAtLocalURL(inputURL);\n\n        } catch (IllegalArgumentException e) {\n        \tthrow new MalformedURLException(\"Unrecognized filesystem URL\");\n        }\n    }\n\n\n    /**\n     * Deletes a file or directory. It is an error to attempt to delete a directory that is not empty.\n     * It is an error to attempt to delete the root directory of a filesystem.\n     *\n     * @return a boolean representing success of failure\n     * @throws NoModificationAllowedException\n     * @throws InvalidModificationException\n     * @throws MalformedURLException\n     */\n    private boolean remove(String baseURLstr) throws NoModificationAllowedException, InvalidModificationException, MalformedURLException {\n        try {\n        \tLocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr);\n        \t// You can't delete the root directory.\n        \tif (\"\".equals(inputURL.path) || \"/\".equals(inputURL.path)) {\n\n        \t\tthrow new NoModificationAllowedException(\"You can't delete the root directory\");\n        \t}\n\n        \tFilesystem fs = this.filesystemForURL(inputURL);\n        \tif (fs == null) {\n        \t\tthrow new MalformedURLException(\"No installed handlers for this URL\");\n        \t}\n        \treturn fs.removeFileAtLocalURL(inputURL);\n\n        } catch (IllegalArgumentException e) {\n        \tthrow new MalformedURLException(\"Unrecognized filesystem URL\");\n        }\n    }\n\n    /**\n     * Creates or looks up a file.\n     *\n     * @param baseURLstr base directory\n     * @param path file/directory to lookup or create\n     * @param options specify whether to create or not\n     * @param directory if true look up directory, if false look up file\n     * @return a Entry object\n     * @throws FileExistsException\n     * @throws IOException\n     * @throws TypeMismatchException\n     * @throws EncodingException\n     * @throws JSONException\n     */\n    private JSONObject getFile(String baseURLstr, String path, JSONObject options, boolean directory) throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException {\n        try {\n        \tLocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr);\n        \tFilesystem fs = this.filesystemForURL(inputURL);\n        \tif (fs == null) {\n        \t\tthrow new MalformedURLException(\"No installed handlers for this URL\");\n        \t}\n        \treturn fs.getFileForLocalURL(inputURL, path, options, directory);\n\n        } catch (IllegalArgumentException e) {\n        \tthrow new MalformedURLException(\"Unrecognized filesystem URL\");\n        }\n\n    }\n\n    /**\n     * Look up the parent DirectoryEntry containing this Entry.\n     * If this Entry is the root of its filesystem, its parent is itself.\n     */\n    private JSONObject getParent(String baseURLstr) throws JSONException, IOException {\n        try {\n        \tLocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr);\n        \tFilesystem fs = this.filesystemForURL(inputURL);\n        \tif (fs == null) {\n        \t\tthrow new MalformedURLException(\"No installed handlers for this URL\");\n        \t}\n        \treturn fs.getParentForLocalURL(inputURL);\n\n        } catch (IllegalArgumentException e) {\n        \tthrow new MalformedURLException(\"Unrecognized filesystem URL\");\n        }\n    }\n\n    /**\n     * Returns a File that represents the current state of the file that this FileEntry represents.\n     *\n     * @return returns a JSONObject represent a W3C File object\n     */\n    private JSONObject getFileMetadata(String baseURLstr) throws FileNotFoundException, JSONException, MalformedURLException {\n        try {\n        \tLocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr);\n        \tFilesystem fs = this.filesystemForURL(inputURL);\n        \tif (fs == null) {\n        \t\tthrow new MalformedURLException(\"No installed handlers for this URL\");\n        \t}\n        \treturn fs.getFileMetadataForLocalURL(inputURL);\n\n        } catch (IllegalArgumentException e) {\n        \tthrow new MalformedURLException(\"Unrecognized filesystem URL\");\n        }\n    }\n\n    /**\n     * Requests a filesystem in which to store application data.\n     *\n     * @param type of file system requested\n     * @param requiredSize required free space in the file system in bytes\n     * @param callbackContext context for returning the result or error\n     * @throws JSONException\n     */\n    private void requestFileSystem(int type, long requiredSize, final CallbackContext callbackContext) throws JSONException {\n        Filesystem rootFs = null;\n        try {\n            rootFs = this.filesystems.get(type);\n        } catch (ArrayIndexOutOfBoundsException e) {\n            // Pass null through\n        }\n        if (rootFs == null) {\n            callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, FileUtils.NOT_FOUND_ERR));\n        } else {\n            // If a nonzero required size was specified, check that the retrieved filesystem has enough free space.\n            long availableSize = 0;\n            if (requiredSize > 0) {\n                availableSize = rootFs.getFreeSpaceInBytes();\n            }\n\n            if (availableSize < requiredSize) {\n                callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, FileUtils.QUOTA_EXCEEDED_ERR));\n            } else {\n                JSONObject fs = new JSONObject();\n                fs.put(\"name\", rootFs.name);\n                fs.put(\"root\", rootFs.getRootEntry());\n                callbackContext.success(fs);\n            }\n        }\n    }\n\n    /**\n     * Requests a filesystem in which to store application data.\n     *\n     * @return a JSONObject representing the file system\n     */\n    private JSONArray requestAllFileSystems() throws IOException, JSONException {\n        JSONArray ret = new JSONArray();\n        for (Filesystem fs : filesystems) {\n            ret.put(fs.getRootEntry());\n        }\n        return ret;\n    }\n\n    private static String toDirUrl(File f) {\n        return Uri.fromFile(f).toString() + '/';\n    }\n\n    private JSONObject requestAllPaths() throws JSONException {\n        Context context = cordova.getActivity();\n        JSONObject ret = new JSONObject();\n        ret.put(\"applicationDirectory\", \"file:///android_asset/\");\n        ret.put(\"applicationStorageDirectory\", toDirUrl(context.getFilesDir().getParentFile()));\n        ret.put(\"dataDirectory\", toDirUrl(context.getFilesDir()));\n        ret.put(\"cacheDirectory\", toDirUrl(context.getCacheDir()));\n        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {\n          try {\n            ret.put(\"externalApplicationStorageDirectory\", toDirUrl(context.getExternalFilesDir(null).getParentFile()));\n            ret.put(\"externalDataDirectory\", toDirUrl(context.getExternalFilesDir(null)));\n            ret.put(\"externalCacheDirectory\", toDirUrl(context.getExternalCacheDir()));\n            ret.put(\"externalRootDirectory\", toDirUrl(Environment.getExternalStorageDirectory()));\n          }\n          catch(NullPointerException e) {\n            /* If external storage is unavailable, context.getExternal* returns null */\n              Log.d(LOG_TAG, \"Unable to access these paths, most liklely due to USB storage\");\n          }\n        }\n        return ret;\n    }\n\n   /**\n     * Returns a JSON object representing the given File. Internal APIs should be modified\n     * to use URLs instead of raw FS paths wherever possible, when interfacing with this plugin.\n     *\n     * @param file the File to convert\n     * @return a JSON representation of the given File\n     * @throws JSONException\n     */\n    public JSONObject getEntryForFile(File file) throws JSONException {\n        JSONObject entry;\n\n        for (Filesystem fs : filesystems) {\n             entry = fs.makeEntryForFile(file);\n             if (entry != null) {\n                 return entry;\n             }\n        }\n        return null;\n    }\n\n    /**\n     * Returns a JSON object representing the given File. Deprecated, as this is only used by\n     * FileTransfer, and because it is a static method that should really be an instance method,\n     * since it depends on the actual filesystem roots in use. Internal APIs should be modified\n     * to use URLs instead of raw FS paths wherever possible, when interfacing with this plugin.\n     *\n     * @param file the File to convert\n     * @return a JSON representation of the given File\n     * @throws JSONException\n     */\n    @Deprecated\n    public static JSONObject getEntry(File file) throws JSONException {\n \t\tif (getFilePlugin() != null) {\n             return getFilePlugin().getEntryForFile(file);\n\t\t}\n\t\treturn null;\n    }\n\n    /**\n     * Read the contents of a file.\n     * This is done in a background thread; the result is sent to the callback.\n     *\n     * @param start             Start position in the file.\n     * @param end               End position to stop at (exclusive).\n     * @param callbackContext   The context through which to send the result.\n     * @param encoding          The encoding to return contents as.  Typical value is UTF-8. (see http://www.iana.org/assignments/character-sets)\n     * @param resultType        The desired type of data to send to the callback.\n     * @return                  Contents of file.\n     */\n    public void readFileAs(final String srcURLstr, final int start, final int end, final CallbackContext callbackContext, final String encoding, final int resultType) throws MalformedURLException {\n        try {\n        \tLocalFilesystemURL inputURL = LocalFilesystemURL.parse(srcURLstr);\n        \tFilesystem fs = this.filesystemForURL(inputURL);\n        \tif (fs == null) {\n        \t\tthrow new MalformedURLException(\"No installed handlers for this URL\");\n        \t}\n\n            fs.readFileAtURL(inputURL, start, end, new Filesystem.ReadFileCallback() {\n                public void handleData(InputStream inputStream, String contentType) {\n            \t\ttry {\n                        ByteArrayOutputStream os = new ByteArrayOutputStream();\n                        final int BUFFER_SIZE = 8192;\n                        byte[] buffer = new byte[BUFFER_SIZE];\n\n                        for (;;) {\n                            int bytesRead = inputStream.read(buffer, 0, BUFFER_SIZE);\n\n                            if (bytesRead <= 0) {\n                                break;\n                            }\n                            os.write(buffer, 0, bytesRead);\n                        }\n\n            \t\t\tPluginResult result;\n            \t\t\tswitch (resultType) {\n            \t\t\tcase PluginResult.MESSAGE_TYPE_STRING:\n                            result = new PluginResult(PluginResult.Status.OK, os.toString(encoding));\n            \t\t\t\tbreak;\n            \t\t\tcase PluginResult.MESSAGE_TYPE_ARRAYBUFFER:\n                            result = new PluginResult(PluginResult.Status.OK, os.toByteArray());\n            \t\t\t\tbreak;\n            \t\t\tcase PluginResult.MESSAGE_TYPE_BINARYSTRING:\n                            result = new PluginResult(PluginResult.Status.OK, os.toByteArray(), true);\n            \t\t\t\tbreak;\n            \t\t\tdefault: // Base64.\n                        byte[] base64 = Base64.encode(os.toByteArray(), Base64.NO_WRAP);\n            \t\t\tString s = \"data:\" + contentType + \";base64,\" + new String(base64, \"US-ASCII\");\n            \t\t\tresult = new PluginResult(PluginResult.Status.OK, s);\n            \t\t\t}\n\n            \t\t\tcallbackContext.sendPluginResult(result);\n            \t\t} catch (IOException e) {\n            \t\t\tLog.d(LOG_TAG, e.getLocalizedMessage());\n            \t\t\tcallbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, NOT_READABLE_ERR));\n                    }\n            \t}\n            });\n\n\n        } catch (IllegalArgumentException e) {\n        \tthrow new MalformedURLException(\"Unrecognized filesystem URL\");\n        } catch (FileNotFoundException e) {\n        \tcallbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, NOT_FOUND_ERR));\n        } catch (IOException e) {\n        \tLog.d(LOG_TAG, e.getLocalizedMessage());\n        \tcallbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, NOT_READABLE_ERR));\n        }\n    }\n\n\n    /**\n     * Write contents of file.\n     *\n     * @param data\t\t\t\tThe contents of the file.\n     * @param offset\t\t\tThe position to begin writing the file.\n     * @param isBinary          True if the file contents are base64-encoded binary data\n     */\n    /**/\n    public long write(String srcURLstr, String data, int offset, boolean isBinary) throws FileNotFoundException, IOException, NoModificationAllowedException {\n        try {\n        \tLocalFilesystemURL inputURL = LocalFilesystemURL.parse(srcURLstr);\n        \tFilesystem fs = this.filesystemForURL(inputURL);\n        \tif (fs == null) {\n        \t\tthrow new MalformedURLException(\"No installed handlers for this URL\");\n        \t}\n\n            long x = fs.writeToFileAtURL(inputURL, data, offset, isBinary); Log.d(\"TEST\",srcURLstr + \": \"+x); return x;\n        } catch (IllegalArgumentException e) {\n        \tthrow new MalformedURLException(\"Unrecognized filesystem URL\");\n        }\n\n    }\n\n    /**\n     * Truncate the file to size\n     */\n    private long truncateFile(String srcURLstr, long size) throws FileNotFoundException, IOException, NoModificationAllowedException {\n        try {\n        \tLocalFilesystemURL inputURL = LocalFilesystemURL.parse(srcURLstr);\n        \tFilesystem fs = this.filesystemForURL(inputURL);\n        \tif (fs == null) {\n        \t\tthrow new MalformedURLException(\"No installed handlers for this URL\");\n        \t}\n\n            return fs.truncateFileAtURL(inputURL, size);\n        } catch (IllegalArgumentException e) {\n        \tthrow new MalformedURLException(\"Unrecognized filesystem URL\");\n        }\n    }\n\n\n    /*\n     * Handle the response\n     */\n\n    public void onRequestPermissionResult(int requestCode, String[] permissions,\n                                          int[] grantResults) throws JSONException {\n\n        final PendingRequests.Request req = pendingRequests.getAndRemove(requestCode);\n        if (req != null) {\n            for(int r:grantResults)\n            {\n                if(r == PackageManager.PERMISSION_DENIED)\n                {\n                    req.getCallbackContext().sendPluginResult(new PluginResult(PluginResult.Status.ERROR, SECURITY_ERR));\n                    return;\n                }\n            }\n            switch(req.getAction())\n            {\n                case ACTION_GET_FILE:\n                    threadhelper( new FileOp( ){\n                        public void run(JSONArray args) throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException {\n                            String dirname = args.getString(0);\n\n                            String path = args.getString(1);\n                            JSONObject obj = getFile(dirname, path, args.optJSONObject(2), false);\n                            req.getCallbackContext().success(obj);\n                        }\n                    }, req.getRawArgs(), req.getCallbackContext());\n                    break;\n                case ACTION_GET_DIRECTORY:\n                    threadhelper( new FileOp( ){\n                        public void run(JSONArray args) throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException {\n                            String dirname = args.getString(0);\n\n                            String path = args.getString(1);\n                            JSONObject obj = getFile(dirname, path, args.optJSONObject(2), true);\n                            req.getCallbackContext().success(obj);\n                        }\n                    }, req.getRawArgs(), req.getCallbackContext());\n                    break;\n                case ACTION_WRITE:\n                    threadhelper( new FileOp( ){\n                        public void run(JSONArray args) throws JSONException, FileNotFoundException, IOException, NoModificationAllowedException {\n                            String fname=args.getString(0);\n                            String data=args.getString(1);\n                            int offset=args.getInt(2);\n                            Boolean isBinary=args.getBoolean(3);\n                            long fileSize = write(fname, data, offset, isBinary);\n                            req.getCallbackContext().sendPluginResult(new PluginResult(PluginResult.Status.OK, fileSize));\n                        }\n                    }, req.getRawArgs(), req.getCallbackContext());\n                    break;\n            }\n        } else {\n           Log.d(LOG_TAG, \"Received permission callback for unknown request code\");\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-file/src/android/Filesystem.java",
    "content": "/*\n       Licensed to the Apache Software Foundation (ASF) under one\n       or more contributor license agreements.  See the NOTICE file\n       distributed with this work for additional information\n       regarding copyright ownership.  The ASF licenses this file\n       to you under the Apache License, Version 2.0 (the\n       \"License\"); you may not use this file except in compliance\n       with the License.  You may obtain a copy of the License at\n\n         http://www.apache.org/licenses/LICENSE-2.0\n\n       Unless required by applicable law or agreed to in writing,\n       software distributed under the License is distributed on an\n       \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n       KIND, either express or implied.  See the License for the\n       specific language governing permissions and limitations\n       under the License.\n */\npackage org.apache.cordova.file;\n\nimport android.net.Uri;\n\nimport java.io.File;\nimport java.io.FileNotFoundException;\nimport java.io.FilterInputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.util.ArrayList;\nimport java.util.Arrays;\n\nimport org.apache.cordova.CordovaResourceApi;\nimport org.json.JSONArray;\nimport org.json.JSONException;\nimport org.json.JSONObject;\n\npublic abstract class Filesystem {\n\n    protected final Uri rootUri;\n    protected final CordovaResourceApi resourceApi;\n    public final String name;\n    private JSONObject rootEntry;\n\n    public Filesystem(Uri rootUri, String name, CordovaResourceApi resourceApi) {\n        this.rootUri = rootUri;\n        this.name = name;\n        this.resourceApi = resourceApi;\n    }\n\n    public interface ReadFileCallback {\n\t\tpublic void handleData(InputStream inputStream, String contentType) throws IOException;\n\t}\n\n    public static JSONObject makeEntryForURL(LocalFilesystemURL inputURL, Uri nativeURL) {\n        try {\n            String path = inputURL.path;\n            int end = path.endsWith(\"/\") ? 1 : 0;\n            String[] parts = path.substring(0, path.length() - end).split(\"/+\");\n            String fileName = parts[parts.length - 1];\n\n            JSONObject entry = new JSONObject();\n            entry.put(\"isFile\", !inputURL.isDirectory);\n            entry.put(\"isDirectory\", inputURL.isDirectory);\n            entry.put(\"name\", fileName);\n            entry.put(\"fullPath\", path);\n            // The file system can't be specified, as it would lead to an infinite loop,\n            // but the filesystem name can be.\n            entry.put(\"filesystemName\", inputURL.fsName);\n            // Backwards compatibility\n            entry.put(\"filesystem\", \"temporary\".equals(inputURL.fsName) ? 0 : 1);\n\n            String nativeUrlStr = nativeURL.toString();\n            if (inputURL.isDirectory && !nativeUrlStr.endsWith(\"/\")) {\n                nativeUrlStr += \"/\";\n            }\n            entry.put(\"nativeURL\", nativeUrlStr);\n            return entry;\n        } catch (JSONException e) {\n            e.printStackTrace();\n            throw new RuntimeException(e);\n        }\n    }\n\n    public JSONObject makeEntryForURL(LocalFilesystemURL inputURL) {\n        Uri nativeUri = toNativeUri(inputURL);\n        return nativeUri == null ? null : makeEntryForURL(inputURL, nativeUri);\n    }\n\n    public JSONObject makeEntryForNativeUri(Uri nativeUri) {\n        LocalFilesystemURL inputUrl = toLocalUri(nativeUri);\n        return inputUrl == null ? null : makeEntryForURL(inputUrl, nativeUri);\n    }\n\n    public JSONObject getEntryForLocalURL(LocalFilesystemURL inputURL) throws IOException {\n        return makeEntryForURL(inputURL);\n    }\n\n    public JSONObject makeEntryForFile(File file) {\n        return makeEntryForNativeUri(Uri.fromFile(file));\n    }\n\n    abstract JSONObject getFileForLocalURL(LocalFilesystemURL inputURL, String path,\n\t\t\tJSONObject options, boolean directory) throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException;\n\n\tabstract boolean removeFileAtLocalURL(LocalFilesystemURL inputURL) throws InvalidModificationException, NoModificationAllowedException;\n\n\tabstract boolean recursiveRemoveFileAtLocalURL(LocalFilesystemURL inputURL) throws FileExistsException, NoModificationAllowedException;\n\n\tabstract LocalFilesystemURL[] listChildren(LocalFilesystemURL inputURL) throws FileNotFoundException;\n\n    public final JSONArray readEntriesAtLocalURL(LocalFilesystemURL inputURL) throws FileNotFoundException {\n        LocalFilesystemURL[] children = listChildren(inputURL);\n        JSONArray entries = new JSONArray();\n        if (children != null) {\n            for (LocalFilesystemURL url : children) {\n                entries.put(makeEntryForURL(url));\n            }\n        }\n        return entries;\n    }\n\n\tabstract JSONObject getFileMetadataForLocalURL(LocalFilesystemURL inputURL) throws FileNotFoundException;\n\n    public Uri getRootUri() {\n        return rootUri;\n    }\n\n    public boolean exists(LocalFilesystemURL inputURL) {\n        try {\n            getFileMetadataForLocalURL(inputURL);\n        } catch (FileNotFoundException e) {\n            return false;\n        }\n        return true;\n    }\n\n    public Uri nativeUriForFullPath(String fullPath) {\n        Uri ret = null;\n        if (fullPath != null) {\n            String encodedPath = Uri.fromFile(new File(fullPath)).getEncodedPath();\n            if (encodedPath.startsWith(\"/\")) {\n                encodedPath = encodedPath.substring(1);\n            }\n            ret = rootUri.buildUpon().appendEncodedPath(encodedPath).build();\n        }\n        return ret;\n    }\n\n    public LocalFilesystemURL localUrlforFullPath(String fullPath) {\n        Uri nativeUri = nativeUriForFullPath(fullPath);\n        if (nativeUri != null) {\n            return toLocalUri(nativeUri);\n        }\n        return null;\n    }\n\n    /**\n     * Removes multiple repeated //s, and collapses processes ../s.\n     */\n    protected static String normalizePath(String rawPath) {\n        // If this is an absolute path, trim the leading \"/\" and replace it later\n        boolean isAbsolutePath = rawPath.startsWith(\"/\");\n        if (isAbsolutePath) {\n            rawPath = rawPath.replaceFirst(\"/+\", \"\");\n        }\n        ArrayList<String> components = new ArrayList<String>(Arrays.asList(rawPath.split(\"/+\")));\n        for (int index = 0; index < components.size(); ++index) {\n            if (components.get(index).equals(\"..\")) {\n                components.remove(index);\n                if (index > 0) {\n                    components.remove(index-1);\n                    --index;\n                }\n            }\n        }\n        StringBuilder normalizedPath = new StringBuilder();\n        for(String component: components) {\n            normalizedPath.append(\"/\");\n            normalizedPath.append(component);\n        }\n        if (isAbsolutePath) {\n            return normalizedPath.toString();\n        } else {\n            return normalizedPath.toString().substring(1);\n        }\n    }\n\n    /**\n     * Gets the free space in bytes available on this filesystem.\n     * Subclasses may override this method to return nonzero free space.\n     */\n    public long getFreeSpaceInBytes() {\n        return 0;\n    }\n\n    public abstract Uri toNativeUri(LocalFilesystemURL inputURL);\n    public abstract LocalFilesystemURL toLocalUri(Uri inputURL);\n\n    public JSONObject getRootEntry() {\n        if (rootEntry == null) {\n            rootEntry = makeEntryForNativeUri(rootUri);\n        }\n        return rootEntry;\n    }\n\n\tpublic JSONObject getParentForLocalURL(LocalFilesystemURL inputURL) throws IOException {\n        Uri parentUri = inputURL.uri;\n        String parentPath = new File(inputURL.uri.getPath()).getParent();\n        if (!\"/\".equals(parentPath)) {\n            parentUri = inputURL.uri.buildUpon().path(parentPath + '/').build();\n\t\t}\n\t\treturn getEntryForLocalURL(LocalFilesystemURL.parse(parentUri));\n\t}\n\n    protected LocalFilesystemURL makeDestinationURL(String newName, LocalFilesystemURL srcURL, LocalFilesystemURL destURL, boolean isDirectory) {\n        // I know this looks weird but it is to work around a JSON bug.\n        if (\"null\".equals(newName) || \"\".equals(newName)) {\n            newName = srcURL.uri.getLastPathSegment();;\n        }\n\n        String newDest = destURL.uri.toString();\n        if (newDest.endsWith(\"/\")) {\n            newDest = newDest + newName;\n        } else {\n            newDest = newDest + \"/\" + newName;\n        }\n        if (isDirectory) {\n            newDest += '/';\n        }\n        return LocalFilesystemURL.parse(newDest);\n    }\n\n\t/* Read a source URL (possibly from a different filesystem, srcFs,) and copy it to\n\t * the destination URL on this filesystem, optionally with a new filename.\n\t * If move is true, then this method should either perform an atomic move operation\n\t * or remove the source file when finished.\n\t */\n    public JSONObject copyFileToURL(LocalFilesystemURL destURL, String newName,\n            Filesystem srcFs, LocalFilesystemURL srcURL, boolean move) throws IOException, InvalidModificationException, JSONException, NoModificationAllowedException, FileExistsException {\n        // First, check to see that we can do it\n        if (move && !srcFs.canRemoveFileAtLocalURL(srcURL)) {\n            throw new NoModificationAllowedException(\"Cannot move file at source URL\");\n        }\n        final LocalFilesystemURL destination = makeDestinationURL(newName, srcURL, destURL, srcURL.isDirectory);\n\n        Uri srcNativeUri = srcFs.toNativeUri(srcURL);\n\n        CordovaResourceApi.OpenForReadResult ofrr = resourceApi.openForRead(srcNativeUri);\n        OutputStream os = null;\n        try {\n            os = getOutputStreamForURL(destination);\n        } catch (IOException e) {\n            ofrr.inputStream.close();\n            throw e;\n        }\n        // Closes streams.\n        resourceApi.copyResource(ofrr, os);\n\n        if (move) {\n            srcFs.removeFileAtLocalURL(srcURL);\n        }\n        return getEntryForLocalURL(destination);\n    }\n\n    public OutputStream getOutputStreamForURL(LocalFilesystemURL inputURL) throws IOException {\n        return resourceApi.openOutputStream(toNativeUri(inputURL));\n    }\n\n    public void readFileAtURL(LocalFilesystemURL inputURL, long start, long end,\n                              ReadFileCallback readFileCallback) throws IOException {\n        CordovaResourceApi.OpenForReadResult ofrr = resourceApi.openForRead(toNativeUri(inputURL));\n        if (end < 0) {\n            end = ofrr.length;\n        }\n        long numBytesToRead = end - start;\n        try {\n            if (start > 0) {\n                ofrr.inputStream.skip(start);\n            }\n            InputStream inputStream = ofrr.inputStream;\n            if (end < ofrr.length) {\n                inputStream = new LimitedInputStream(inputStream, numBytesToRead);\n            }\n            readFileCallback.handleData(inputStream, ofrr.mimeType);\n        } finally {\n            ofrr.inputStream.close();\n        }\n    }\n\n\tabstract long writeToFileAtURL(LocalFilesystemURL inputURL, String data, int offset,\n\t\t\tboolean isBinary) throws NoModificationAllowedException, IOException;\n\n\tabstract long truncateFileAtURL(LocalFilesystemURL inputURL, long size)\n\t\t\tthrows IOException, NoModificationAllowedException;\n\n\t// This method should return null if filesystem urls cannot be mapped to paths\n\tabstract String filesystemPathForURL(LocalFilesystemURL url);\n\n\tabstract LocalFilesystemURL URLforFilesystemPath(String path);\n\n\tabstract boolean canRemoveFileAtLocalURL(LocalFilesystemURL inputURL);\n\n    protected class LimitedInputStream extends FilterInputStream {\n        long numBytesToRead;\n        public LimitedInputStream(InputStream in, long numBytesToRead) {\n            super(in);\n            this.numBytesToRead = numBytesToRead;\n        }\n        @Override\n        public int read() throws IOException {\n            if (numBytesToRead <= 0) {\n                return -1;\n            }\n            numBytesToRead--;\n            return in.read();\n        }\n        @Override\n        public int read(byte[] buffer, int byteOffset, int byteCount) throws IOException {\n            if (numBytesToRead <= 0) {\n                return -1;\n            }\n            int bytesToRead = byteCount;\n            if (byteCount > numBytesToRead) {\n                bytesToRead = (int)numBytesToRead; // Cast okay; long is less than int here.\n            }\n            int numBytesRead = in.read(buffer, byteOffset, bytesToRead);\n            numBytesToRead -= numBytesRead;\n            return numBytesRead;\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-file/src/android/InvalidModificationException.java",
    "content": "/*\n       Licensed to the Apache Software Foundation (ASF) under one\n       or more contributor license agreements.  See the NOTICE file\n       distributed with this work for additional information\n       regarding copyright ownership.  The ASF licenses this file\n       to you under the Apache License, Version 2.0 (the\n       \"License\"); you may not use this file except in compliance\n       with the License.  You may obtain a copy of the License at\n\n         http://www.apache.org/licenses/LICENSE-2.0\n\n       Unless required by applicable law or agreed to in writing,\n       software distributed under the License is distributed on an\n       \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n       KIND, either express or implied.  See the License for the\n       specific language governing permissions and limitations\n       under the License.\n*/\n\n\npackage org.apache.cordova.file;\n\n@SuppressWarnings(\"serial\")\npublic class InvalidModificationException extends Exception {\n\n    public InvalidModificationException(String message) {\n        super(message);\n    }\n\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-file/src/android/LocalFilesystem.java",
    "content": "/*\n       Licensed to the Apache Software Foundation (ASF) under one\n       or more contributor license agreements.  See the NOTICE file\n       distributed with this work for additional information\n       regarding copyright ownership.  The ASF licenses this file\n       to you under the Apache License, Version 2.0 (the\n       \"License\"); you may not use this file except in compliance\n       with the License.  You may obtain a copy of the License at\n\n         http://www.apache.org/licenses/LICENSE-2.0\n\n       Unless required by applicable law or agreed to in writing,\n       software distributed under the License is distributed on an\n       \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n       KIND, either express or implied.  See the License for the\n       specific language governing permissions and limitations\n       under the License.\n */\npackage org.apache.cordova.file;\n\nimport java.io.ByteArrayInputStream;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileNotFoundException;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.io.RandomAccessFile;\nimport java.nio.channels.FileChannel;\nimport org.apache.cordova.CordovaResourceApi;\nimport org.json.JSONException;\nimport org.json.JSONObject;\n\nimport android.os.Build;\nimport android.os.Environment;\nimport android.util.Base64;\nimport android.net.Uri;\nimport android.content.Context;\nimport android.content.Intent;\n\npublic class LocalFilesystem extends Filesystem {\n    private final Context context;\n\n    public LocalFilesystem(String name, Context context, CordovaResourceApi resourceApi, File fsRoot) {\n        super(Uri.fromFile(fsRoot).buildUpon().appendEncodedPath(\"\").build(), name, resourceApi);\n        this.context = context;\n    }\n\n    public String filesystemPathForFullPath(String fullPath) {\n\t    return new File(rootUri.getPath(), fullPath).toString();\n\t}\n\n\t@Override\n\tpublic String filesystemPathForURL(LocalFilesystemURL url) {\n\t\treturn filesystemPathForFullPath(url.path);\n\t}\n\n\tprivate String fullPathForFilesystemPath(String absolutePath) {\n\t\tif (absolutePath != null && absolutePath.startsWith(rootUri.getPath())) {\n\t\t\treturn absolutePath.substring(rootUri.getPath().length() - 1);\n\t\t}\n\t\treturn null;\n\t}\n\n    @Override\n    public Uri toNativeUri(LocalFilesystemURL inputURL) {\n        return nativeUriForFullPath(inputURL.path);\n    }\n\n    @Override\n    public LocalFilesystemURL toLocalUri(Uri inputURL) {\n        if (!\"file\".equals(inputURL.getScheme())) {\n            return null;\n        }\n        File f = new File(inputURL.getPath());\n        // Removes and duplicate /s (e.g. file:///a//b/c)\n        Uri resolvedUri = Uri.fromFile(f);\n        String rootUriNoTrailingSlash = rootUri.getEncodedPath();\n        rootUriNoTrailingSlash = rootUriNoTrailingSlash.substring(0, rootUriNoTrailingSlash.length() - 1);\n        if (!resolvedUri.getEncodedPath().startsWith(rootUriNoTrailingSlash)) {\n            return null;\n        }\n        String subPath = resolvedUri.getEncodedPath().substring(rootUriNoTrailingSlash.length());\n        // Strip leading slash\n        if (!subPath.isEmpty()) {\n            subPath = subPath.substring(1);\n        }\n        Uri.Builder b = new Uri.Builder()\n            .scheme(LocalFilesystemURL.FILESYSTEM_PROTOCOL)\n            .authority(\"localhost\")\n            .path(name);\n        if (!subPath.isEmpty()) {\n            b.appendEncodedPath(subPath);\n        }\n        if (f.isDirectory()) {\n            // Add trailing / for directories.\n            b.appendEncodedPath(\"\");\n        }\n        return LocalFilesystemURL.parse(b.build());\n    }\n\n\t@Override\n\tpublic LocalFilesystemURL URLforFilesystemPath(String path) {\n\t    return localUrlforFullPath(fullPathForFilesystemPath(path));\n\t}\n\n\t@Override\n\tpublic JSONObject getFileForLocalURL(LocalFilesystemURL inputURL,\n\t\t\tString path, JSONObject options, boolean directory) throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException {\n        boolean create = false;\n        boolean exclusive = false;\n\n        if (options != null) {\n            create = options.optBoolean(\"create\");\n            if (create) {\n                exclusive = options.optBoolean(\"exclusive\");\n            }\n        }\n\n        // Check for a \":\" character in the file to line up with BB and iOS\n        if (path.contains(\":\")) {\n            throw new EncodingException(\"This path has an invalid \\\":\\\" in it.\");\n        }\n\n        LocalFilesystemURL requestedURL;\n\n        // Check whether the supplied path is absolute or relative\n        if (directory && !path.endsWith(\"/\")) {\n            path += \"/\";\n        }\n        if (path.startsWith(\"/\")) {\n        \trequestedURL = localUrlforFullPath(normalizePath(path));\n        } else {\n        \trequestedURL = localUrlforFullPath(normalizePath(inputURL.path + \"/\" + path));\n        }\n\n        File fp = new File(this.filesystemPathForURL(requestedURL));\n\n        if (create) {\n            if (exclusive && fp.exists()) {\n                throw new FileExistsException(\"create/exclusive fails\");\n            }\n            if (directory) {\n                fp.mkdir();\n            } else {\n                fp.createNewFile();\n            }\n            if (!fp.exists()) {\n                throw new FileExistsException(\"create fails\");\n            }\n        }\n        else {\n            if (!fp.exists()) {\n                throw new FileNotFoundException(\"path does not exist\");\n            }\n            if (directory) {\n                if (fp.isFile()) {\n                    throw new TypeMismatchException(\"path doesn't exist or is file\");\n                }\n            } else {\n                if (fp.isDirectory()) {\n                    throw new TypeMismatchException(\"path doesn't exist or is directory\");\n                }\n            }\n        }\n\n        // Return the directory\n        return makeEntryForURL(requestedURL);\n\t}\n\n\t@Override\n\tpublic boolean removeFileAtLocalURL(LocalFilesystemURL inputURL) throws InvalidModificationException {\n\n        File fp = new File(filesystemPathForURL(inputURL));\n\n        // You can't delete a directory that is not empty\n        if (fp.isDirectory() && fp.list().length > 0) {\n            throw new InvalidModificationException(\"You can't delete a directory that is not empty.\");\n        }\n\n        return fp.delete();\n\t}\n\n    @Override\n    public boolean exists(LocalFilesystemURL inputURL) {\n        File fp = new File(filesystemPathForURL(inputURL));\n        return fp.exists();\n    }\n\n    @Override\n    public long getFreeSpaceInBytes() {\n        return DirectoryManager.getFreeSpaceInBytes(rootUri.getPath());\n    }\n\n    @Override\n\tpublic boolean recursiveRemoveFileAtLocalURL(LocalFilesystemURL inputURL) throws FileExistsException {\n        File directory = new File(filesystemPathForURL(inputURL));\n    \treturn removeDirRecursively(directory);\n\t}\n\n\tprotected boolean removeDirRecursively(File directory) throws FileExistsException {\n        if (directory.isDirectory()) {\n            for (File file : directory.listFiles()) {\n                removeDirRecursively(file);\n            }\n        }\n\n        if (!directory.delete()) {\n            throw new FileExistsException(\"could not delete: \" + directory.getName());\n        } else {\n            return true;\n        }\n\t}\n\n    @Override\n    public LocalFilesystemURL[] listChildren(LocalFilesystemURL inputURL) throws FileNotFoundException {\n        File fp = new File(filesystemPathForURL(inputURL));\n\n        if (!fp.exists()) {\n            // The directory we are listing doesn't exist so we should fail.\n            throw new FileNotFoundException();\n        }\n\n        File[] files = fp.listFiles();\n        if (files == null) {\n            // inputURL is a directory\n            return null;\n        }\n        LocalFilesystemURL[] entries = new LocalFilesystemURL[files.length];\n        for (int i = 0; i < files.length; i++) {\n            entries[i] = URLforFilesystemPath(files[i].getPath());\n        }\n\n        return entries;\n\t}\n\n\t@Override\n\tpublic JSONObject getFileMetadataForLocalURL(LocalFilesystemURL inputURL) throws FileNotFoundException {\n        File file = new File(filesystemPathForURL(inputURL));\n\n        if (!file.exists()) {\n            throw new FileNotFoundException(\"File at \" + inputURL.uri + \" does not exist.\");\n        }\n\n        JSONObject metadata = new JSONObject();\n        try {\n            // Ensure that directories report a size of 0\n        \tmetadata.put(\"size\", file.isDirectory() ? 0 : file.length());\n        \tmetadata.put(\"type\", resourceApi.getMimeType(Uri.fromFile(file)));\n        \tmetadata.put(\"name\", file.getName());\n        \tmetadata.put(\"fullPath\", inputURL.path);\n        \tmetadata.put(\"lastModifiedDate\", file.lastModified());\n        } catch (JSONException e) {\n        \treturn null;\n        }\n        return metadata;\n\t}\n\n    private void copyFile(Filesystem srcFs, LocalFilesystemURL srcURL, File destFile, boolean move) throws IOException, InvalidModificationException, NoModificationAllowedException {\n        if (move) {\n            String realSrcPath = srcFs.filesystemPathForURL(srcURL);\n            if (realSrcPath != null) {\n                File srcFile = new File(realSrcPath);\n                if (srcFile.renameTo(destFile)) {\n                    return;\n                }\n                // Trying to rename the file failed.  Possibly because we moved across file system on the device.\n            }\n        }\n\n        CordovaResourceApi.OpenForReadResult offr = resourceApi.openForRead(srcFs.toNativeUri(srcURL));\n        copyResource(offr, new FileOutputStream(destFile));\n\n        if (move) {\n            srcFs.removeFileAtLocalURL(srcURL);\n        }\n    }\n\n    private void copyDirectory(Filesystem srcFs, LocalFilesystemURL srcURL, File dstDir, boolean move) throws IOException, NoModificationAllowedException, InvalidModificationException, FileExistsException {\n        if (move) {\n            String realSrcPath = srcFs.filesystemPathForURL(srcURL);\n            if (realSrcPath != null) {\n                File srcDir = new File(realSrcPath);\n                // If the destination directory already exists and is empty then delete it.  This is according to spec.\n                if (dstDir.exists()) {\n                    if (dstDir.list().length > 0) {\n                        throw new InvalidModificationException(\"directory is not empty\");\n                    }\n                    dstDir.delete();\n                }\n                // Try to rename the directory\n                if (srcDir.renameTo(dstDir)) {\n                    return;\n                }\n                // Trying to rename the file failed.  Possibly because we moved across file system on the device.\n            }\n        }\n\n        if (dstDir.exists()) {\n            if (dstDir.list().length > 0) {\n                throw new InvalidModificationException(\"directory is not empty\");\n            }\n        } else {\n            if (!dstDir.mkdir()) {\n                // If we can't create the directory then fail\n                throw new NoModificationAllowedException(\"Couldn't create the destination directory\");\n            }\n        }\n\n        LocalFilesystemURL[] children = srcFs.listChildren(srcURL);\n        for (LocalFilesystemURL childLocalUrl : children) {\n            File target = new File(dstDir, new File(childLocalUrl.path).getName());\n            if (childLocalUrl.isDirectory) {\n                copyDirectory(srcFs, childLocalUrl, target, false);\n            } else {\n                copyFile(srcFs, childLocalUrl, target, false);\n            }\n        }\n\n        if (move) {\n            srcFs.recursiveRemoveFileAtLocalURL(srcURL);\n        }\n    }\n\n\t@Override\n\tpublic JSONObject copyFileToURL(LocalFilesystemURL destURL, String newName,\n\t\t\tFilesystem srcFs, LocalFilesystemURL srcURL, boolean move) throws IOException, InvalidModificationException, JSONException, NoModificationAllowedException, FileExistsException {\n\n\t\t// Check to see if the destination directory exists\n        String newParent = this.filesystemPathForURL(destURL);\n        File destinationDir = new File(newParent);\n        if (!destinationDir.exists()) {\n            // The destination does not exist so we should fail.\n            throw new FileNotFoundException(\"The source does not exist\");\n        }\n\n        // Figure out where we should be copying to\n        final LocalFilesystemURL destinationURL = makeDestinationURL(newName, srcURL, destURL, srcURL.isDirectory);\n\n        Uri dstNativeUri = toNativeUri(destinationURL);\n        Uri srcNativeUri = srcFs.toNativeUri(srcURL);\n        // Check to see if source and destination are the same file\n        if (dstNativeUri.equals(srcNativeUri)) {\n            throw new InvalidModificationException(\"Can't copy onto itself\");\n        }\n\n        if (move && !srcFs.canRemoveFileAtLocalURL(srcURL)) {\n            throw new InvalidModificationException(\"Source URL is read-only (cannot move)\");\n        }\n\n        File destFile = new File(dstNativeUri.getPath());\n        if (destFile.exists()) {\n            if (!srcURL.isDirectory && destFile.isDirectory()) {\n                throw new InvalidModificationException(\"Can't copy/move a file to an existing directory\");\n            } else if (srcURL.isDirectory && destFile.isFile()) {\n                throw new InvalidModificationException(\"Can't copy/move a directory to an existing file\");\n            }\n        }\n\n        if (srcURL.isDirectory) {\n            // E.g. Copy /sdcard/myDir to /sdcard/myDir/backup\n            if (dstNativeUri.toString().startsWith(srcNativeUri.toString() + '/')) {\n                throw new InvalidModificationException(\"Can't copy directory into itself\");\n            }\n            copyDirectory(srcFs, srcURL, destFile, move);\n        } else {\n            copyFile(srcFs, srcURL, destFile, move);\n        }\n        return makeEntryForURL(destinationURL);\n\t}\n\n\t@Override\n\tpublic long writeToFileAtURL(LocalFilesystemURL inputURL, String data,\n\t\t\tint offset, boolean isBinary) throws IOException, NoModificationAllowedException {\n\n        boolean append = false;\n        if (offset > 0) {\n            this.truncateFileAtURL(inputURL, offset);\n            append = true;\n        }\n\n        byte[] rawData;\n        if (isBinary) {\n            rawData = Base64.decode(data, Base64.DEFAULT);\n        } else {\n            rawData = data.getBytes();\n        }\n        ByteArrayInputStream in = new ByteArrayInputStream(rawData);\n        try\n        {\n        \tbyte buff[] = new byte[rawData.length];\n            String absolutePath = filesystemPathForURL(inputURL);\n            FileOutputStream out = new FileOutputStream(absolutePath, append);\n            try {\n            \tin.read(buff, 0, buff.length);\n            \tout.write(buff, 0, rawData.length);\n            \tout.flush();\n            } finally {\n            \t// Always close the output\n            \tout.close();\n            }\n            if (isPublicDirectory(absolutePath)) {\n                broadcastNewFile(Uri.fromFile(new File(absolutePath)));\n            }\n        }\n        catch (NullPointerException e)\n        {\n            // This is a bug in the Android implementation of the Java Stack\n            NoModificationAllowedException realException = new NoModificationAllowedException(inputURL.toString());\n            throw realException;\n        }\n\n        return rawData.length;\n\t}\n\n    private boolean isPublicDirectory(String absolutePath) {\n        // TODO: should expose a way to scan app's private files (maybe via a flag).\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {\n            // Lollipop has a bug where SD cards are null.\n            for (File f : context.getExternalMediaDirs()) {\n                if(f != null && absolutePath.startsWith(f.getAbsolutePath())) {\n                    return true;\n                }\n            }\n        }\n\n        String extPath = Environment.getExternalStorageDirectory().getAbsolutePath();\n        return absolutePath.startsWith(extPath);\n    }\n\n     /**\n     * Send broadcast of new file so files appear over MTP\n     */\n    private void broadcastNewFile(Uri nativeUri) {\n        Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, nativeUri);\n        context.sendBroadcast(intent);\n    }\n\n\t@Override\n\tpublic long truncateFileAtURL(LocalFilesystemURL inputURL, long size) throws IOException {\n        File file = new File(filesystemPathForURL(inputURL));\n\n        if (!file.exists()) {\n            throw new FileNotFoundException(\"File at \" + inputURL.uri + \" does not exist.\");\n        }\n\n        RandomAccessFile raf = new RandomAccessFile(filesystemPathForURL(inputURL), \"rw\");\n        try {\n            if (raf.length() >= size) {\n                FileChannel channel = raf.getChannel();\n                channel.truncate(size);\n                return size;\n            }\n\n            return raf.length();\n        } finally {\n            raf.close();\n        }\n\n\n\t}\n\n\t@Override\n\tpublic boolean canRemoveFileAtLocalURL(LocalFilesystemURL inputURL) {\n\t\tString path = filesystemPathForURL(inputURL);\n\t\tFile file = new File(path);\n\t\treturn file.exists();\n\t}\n\n    // This is a copy & paste from CordovaResource API that is required since CordovaResourceApi\n    // has a bug pre-4.0.0.\n    // TODO: Once cordova-android@4.0.0 is released, delete this copy and make the plugin depend on\n    // 4.0.0 with an engine tag.\n    private static void copyResource(CordovaResourceApi.OpenForReadResult input, OutputStream outputStream) throws IOException {\n        try {\n            InputStream inputStream = input.inputStream;\n            if (inputStream instanceof FileInputStream && outputStream instanceof FileOutputStream) {\n                FileChannel inChannel = ((FileInputStream)input.inputStream).getChannel();\n                FileChannel outChannel = ((FileOutputStream)outputStream).getChannel();\n                long offset = 0;\n                long length = input.length;\n                if (input.assetFd != null) {\n                    offset = input.assetFd.getStartOffset();\n                }\n                // transferFrom()'s 2nd arg is a relative position. Need to set the absolute\n                // position first.\n                inChannel.position(offset);\n                outChannel.transferFrom(inChannel, 0, length);\n            } else {\n                final int BUFFER_SIZE = 8192;\n                byte[] buffer = new byte[BUFFER_SIZE];\n\n                for (;;) {\n                    int bytesRead = inputStream.read(buffer, 0, BUFFER_SIZE);\n\n                    if (bytesRead <= 0) {\n                        break;\n                    }\n                    outputStream.write(buffer, 0, bytesRead);\n                }\n            }\n        } finally {\n            input.inputStream.close();\n            if (outputStream != null) {\n                outputStream.close();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-file/src/android/LocalFilesystemURL.java",
    "content": "/*\n       Licensed to the Apache Software Foundation (ASF) under one\n       or more contributor license agreements.  See the NOTICE file\n       distributed with this work for additional information\n       regarding copyright ownership.  The ASF licenses this file\n       to you under the Apache License, Version 2.0 (the\n       \"License\"); you may not use this file except in compliance\n       with the License.  You may obtain a copy of the License at\n\n         http://www.apache.org/licenses/LICENSE-2.0\n\n       Unless required by applicable law or agreed to in writing,\n       software distributed under the License is distributed on an\n       \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n       KIND, either express or implied.  See the License for the\n       specific language governing permissions and limitations\n       under the License.\n */\npackage org.apache.cordova.file;\n\nimport android.net.Uri;\n\npublic class LocalFilesystemURL {\n\t\n\tpublic static final String FILESYSTEM_PROTOCOL = \"cdvfile\";\n\n    public final Uri uri;\n    public final String fsName;\n    public final String path;\n    public final boolean isDirectory;\n\n\tprivate LocalFilesystemURL(Uri uri, String fsName, String fsPath, boolean isDirectory) {\n\t\tthis.uri = uri;\n        this.fsName = fsName;\n        this.path = fsPath;\n        this.isDirectory = isDirectory;\n\t}\n\n    public static LocalFilesystemURL parse(Uri uri) {\n        if (!FILESYSTEM_PROTOCOL.equals(uri.getScheme())) {\n            return null;\n        }\n        String path = uri.getPath();\n        if (path.length() < 1) {\n            return null;\n        }\n        int firstSlashIdx = path.indexOf('/', 1);\n        if (firstSlashIdx < 0) {\n            return null;\n        }\n        String fsName = path.substring(1, firstSlashIdx);\n        path = path.substring(firstSlashIdx);\n        boolean isDirectory = path.charAt(path.length() - 1) == '/';\n        return new LocalFilesystemURL(uri, fsName, path, isDirectory);\n    }\n\n    public static LocalFilesystemURL parse(String uri) {\n        return parse(Uri.parse(uri));\n    }\n\n    public String toString() {\n        return uri.toString();\n    }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-file/src/android/NoModificationAllowedException.java",
    "content": "/*\n       Licensed to the Apache Software Foundation (ASF) under one\n       or more contributor license agreements.  See the NOTICE file\n       distributed with this work for additional information\n       regarding copyright ownership.  The ASF licenses this file\n       to you under the Apache License, Version 2.0 (the\n       \"License\"); you may not use this file except in compliance\n       with the License.  You may obtain a copy of the License at\n\n         http://www.apache.org/licenses/LICENSE-2.0\n\n       Unless required by applicable law or agreed to in writing,\n       software distributed under the License is distributed on an\n       \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n       KIND, either express or implied.  See the License for the\n       specific language governing permissions and limitations\n       under the License.\n*/\n\npackage org.apache.cordova.file;\n\n@SuppressWarnings(\"serial\")\npublic class NoModificationAllowedException extends Exception {\n\n    public NoModificationAllowedException(String message) {\n        super(message);\n    }\n\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-file/src/android/PendingRequests.java",
    "content": "/*\r\n       Licensed to the Apache Software Foundation (ASF) under one\r\n       or more contributor license agreements.  See the NOTICE file\r\n       distributed with this work for additional information\r\n       regarding copyright ownership.  The ASF licenses this file\r\n       to you under the Apache License, Version 2.0 (the\r\n       \"License\"); you may not use this file except in compliance\r\n       with the License.  You may obtain a copy of the License at\r\n\r\n         http://www.apache.org/licenses/LICENSE-2.0\r\n\r\n       Unless required by applicable law or agreed to in writing,\r\n       software distributed under the License is distributed on an\r\n       \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\r\n       KIND, either express or implied.  See the License for the\r\n       specific language governing permissions and limitations\r\n       under the License.\r\n*/\r\npackage org.apache.cordova.file;\r\n\r\nimport android.util.SparseArray;\r\n\r\nimport org.apache.cordova.CallbackContext;\r\n\r\n/**\r\n * Holds pending runtime permission requests\r\n */\r\nclass PendingRequests {\r\n    private int currentReqId = 0;\r\n    private SparseArray<Request> requests = new SparseArray<Request>();\r\n\r\n    /**\r\n     * Creates a request and adds it to the array of pending requests. Each created request gets a\r\n     * unique result code for use with requestPermission()\r\n     * @param rawArgs           The raw arguments passed to the plugin\r\n     * @param action            The action this request corresponds to (get file, etc.)\r\n     * @param callbackContext   The CallbackContext for this plugin call\r\n     * @return                  The request code that can be used to retrieve the Request object\r\n     */\r\n    public synchronized int createRequest(String rawArgs, int action, CallbackContext callbackContext)  {\r\n        Request req = new Request(rawArgs, action, callbackContext);\r\n        requests.put(req.requestCode, req);\r\n        return req.requestCode;\r\n    }\r\n\r\n    /**\r\n     * Gets the request corresponding to this request code and removes it from the pending requests\r\n     * @param requestCode   The request code for the desired request\r\n     * @return              The request corresponding to the given request code or null if such a\r\n     *                      request is not found\r\n     */\r\n    public synchronized Request getAndRemove(int requestCode) {\r\n        Request result = requests.get(requestCode);\r\n        requests.remove(requestCode);\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * Holds the options and CallbackContext for a call made to the plugin.\r\n     */\r\n    public class Request {\r\n\r\n        // Unique int used to identify this request in any Android permission callback\r\n        private int requestCode;\r\n\r\n        // Action to be performed after permission request result\r\n        private int action;\r\n\r\n        // Raw arguments passed to plugin\r\n        private String rawArgs;\r\n\r\n        // The callback context for this plugin request\r\n        private CallbackContext callbackContext;\r\n\r\n        private Request(String rawArgs, int action, CallbackContext callbackContext) {\r\n            this.rawArgs = rawArgs;\r\n            this.action = action;\r\n            this.callbackContext = callbackContext;\r\n            this.requestCode = currentReqId ++;\r\n        }\r\n\r\n        public int getAction() {\r\n            return this.action;\r\n        }\r\n\r\n        public String getRawArgs() {\r\n            return rawArgs;\r\n        }\r\n\r\n        public CallbackContext getCallbackContext() {\r\n            return callbackContext;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "plugins/cordova-plugin-file/src/android/TypeMismatchException.java",
    "content": "/*\n       Licensed to the Apache Software Foundation (ASF) under one\n       or more contributor license agreements.  See the NOTICE file\n       distributed with this work for additional information\n       regarding copyright ownership.  The ASF licenses this file\n       to you under the Apache License, Version 2.0 (the\n       \"License\"); you may not use this file except in compliance\n       with the License.  You may obtain a copy of the License at\n\n         http://www.apache.org/licenses/LICENSE-2.0\n\n       Unless required by applicable law or agreed to in writing,\n       software distributed under the License is distributed on an\n       \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n       KIND, either express or implied.  See the License for the\n       specific language governing permissions and limitations\n       under the License.\n*/\n\n\npackage org.apache.cordova.file;\n\n@SuppressWarnings(\"serial\")\npublic class TypeMismatchException extends Exception {\n\n    public TypeMismatchException(String message) {\n        super(message);\n    }\n\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-file/src/android/build-extras.gradle",
    "content": "/*\n       Licensed to the Apache Software Foundation (ASF) under one\n       or more contributor license agreements.  See the NOTICE file\n       distributed with this work for additional information\n       regarding copyright ownership.  The ASF licenses this file\n       to you under the Apache License, Version 2.0 (the\n       \"License\"); you may not use this file except in compliance\n       with the License.  You may obtain a copy of the License at\n\n         http://www.apache.org/licenses/LICENSE-2.0\n\n       Unless required by applicable law or agreed to in writing,\n       software distributed under the License is distributed on an\n       \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n       KIND, either express or implied.  See the License for the\n       specific language governing permissions and limitations\n       under the License.\n */\next.postBuildExtras = {\n    def inAssetsDir = file(\"assets\")\n    def outAssetsDir = inAssetsDir\n    def outFile = new File(outAssetsDir, \"cdvasset.manifest\")\n\n    def newTask = task(\"cdvCreateAssetManifest\") << {\n        def contents = new HashMap()\n        def sizes = new HashMap()\n        contents[\"\"] = inAssetsDir.list()\n        def tree = fileTree(dir: inAssetsDir)\n        tree.visit { fileDetails ->\n            if (fileDetails.isDirectory()) {\n                contents[fileDetails.relativePath.toString()] = fileDetails.file.list()\n            } else {\n                sizes[fileDetails.relativePath.toString()] = fileDetails.file.length()\n            }\n        }\n\n        outAssetsDir.mkdirs()\n        outFile.withObjectOutputStream { oos ->\n            oos.writeObject(contents)\n            oos.writeObject(sizes)\n        }\n    }\n    newTask.inputs.dir inAssetsDir\n    newTask.outputs.file outFile\n    def preBuildTask = tasks[\"preBuild\"]\n    preBuildTask.dependsOn(newTask)\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-file/src/blackberry10/index.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/* global PluginResult */\n\nmodule.exports = {\n    setSandbox : function (success, fail, args, env) {\n        require(\"lib/webview\").setSandbox(JSON.parse(decodeURIComponent(args[0])));\n        new PluginResult(args, env).ok();\n    },\n\n    getHomePath: function (success, fail, args, env) {\n        var homeDir = window.qnx.webplatform.getApplication().getEnv(\"HOME\");\n        new PluginResult(args, env).ok(homeDir);\n    },\n\n    requestAllPaths: function (success, fail, args, env) {\n        var homeDir = 'file://' + window.qnx.webplatform.getApplication().getEnv(\"HOME\").replace('/data', ''),\n            paths = {\n                applicationDirectory: homeDir + '/app/native/',\n                applicationStorageDirectory: homeDir + '/',\n                dataDirectory: homeDir + '/data/webviews/webfs/persistent/local__0/',\n                cacheDirectory: homeDir + '/data/webviews/webfs/temporary/local__0/',\n                externalRootDirectory: 'file:///accounts/1000/removable/sdcard/',\n                sharedDirectory: homeDir + '/shared/'\n            };\n        success(paths);\n    }\n};\n"
  },
  {
    "path": "plugins/cordova-plugin-file/src/browser/FileProxy.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n */\n(function() {\n    /*global require, exports, module*/\n    /*global FILESYSTEM_PREFIX*/\n    /*global IDBKeyRange*/\n\n    /* Heavily based on https://github.com/ebidel/idb.filesystem.js */\n\n    // For chrome we don't need to implement proxy methods\n    // All functionality can be accessed natively.\n    if (require('./isChrome')()) {\n        var pathsPrefix = {\n            // Read-only directory where the application is installed.\n            applicationDirectory: location.origin + \"/\",\n            // Where to put app-specific data files.\n            dataDirectory: 'filesystem:file:///persistent/',\n            // Cached files that should survive app restarts.\n            // Apps should not rely on the OS to delete files in here.\n            cacheDirectory: 'filesystem:file:///temporary/',\n        };\n\n        exports.requestAllPaths = function(successCallback) {\n            successCallback(pathsPrefix);\n        };\n\n        require(\"cordova/exec/proxy\").add(\"File\", module.exports);\n        return;\n    }\n\n    var LocalFileSystem = require('./LocalFileSystem'),\n        FileSystem = require('./FileSystem'),\n        FileEntry = require('./FileEntry'),\n        FileError = require('./FileError'),\n        DirectoryEntry = require('./DirectoryEntry'),\n        File = require('./File');\n\n    (function(exports, global) {\n        var indexedDB = global.indexedDB || global.mozIndexedDB;\n        if (!indexedDB) {\n            throw \"Firefox OS File plugin: indexedDB not supported\";\n        }\n\n        var fs_ = null;\n\n        var idb_ = {};\n        idb_.db = null;\n        var FILE_STORE_ = 'entries';\n\n        var DIR_SEPARATOR = '/';\n\n        var pathsPrefix = {\n            // Read-only directory where the application is installed.\n            applicationDirectory: location.origin + \"/\",\n            // Where to put app-specific data files.\n            dataDirectory: 'file:///persistent/',\n            // Cached files that should survive app restarts.\n            // Apps should not rely on the OS to delete files in here.\n            cacheDirectory: 'file:///temporary/',\n        };\n\n        var unicodeLastChar = 65535;\n\n    /*** Exported functionality ***/\n\n        exports.requestFileSystem = function(successCallback, errorCallback, args) {\n            var type = args[0];\n            // Size is ignored since IDB filesystem size depends\n            // on browser implementation and can't be set up by user\n            var size = args[1]; // jshint ignore: line\n\n            if (type !== LocalFileSystem.TEMPORARY && type !== LocalFileSystem.PERSISTENT) {\n                if (errorCallback) {\n                    errorCallback(FileError.INVALID_MODIFICATION_ERR);\n                }\n                return;\n            }\n\n            var name = type === LocalFileSystem.TEMPORARY ? 'temporary' : 'persistent';\n            var storageName = (location.protocol + location.host).replace(/:/g, '_');\n\n            var root = new DirectoryEntry('', DIR_SEPARATOR);\n            fs_ = new FileSystem(name, root);\n\n            idb_.open(storageName, function() {\n                successCallback(fs_);\n            }, errorCallback);\n        };\n\n        // Overridden by Android, BlackBerry 10 and iOS to populate fsMap\n        require('./fileSystems').getFs = function(name, callback) {\n            callback(new FileSystem(name, fs_.root));\n        };\n\n        // list a directory's contents (files and folders).\n        exports.readEntries = function(successCallback, errorCallback, args) {\n            var fullPath = args[0];\n\n            if (typeof successCallback !== 'function') {\n                throw Error('Expected successCallback argument.');\n            }\n\n            var path = resolveToFullPath_(fullPath);\n\n            exports.getDirectory(function() {\n                idb_.getAllEntries(path.fullPath + DIR_SEPARATOR, path.storagePath, function(entries) {\n                    successCallback(entries);\n                }, errorCallback);\n            }, function() {\n                if (errorCallback) {\n                    errorCallback(FileError.NOT_FOUND_ERR);\n                }\n            }, [path.storagePath, path.fullPath, {create: false}]);\n        };\n\n        exports.getFile = function(successCallback, errorCallback, args) {\n            var fullPath = args[0];\n            var path = args[1];\n            var options = args[2] || {};\n\n            // Create an absolute path if we were handed a relative one.\n            path = resolveToFullPath_(fullPath, path);\n\n            idb_.get(path.storagePath, function(fileEntry) {\n                if (options.create === true && options.exclusive === true && fileEntry) {\n                    // If create and exclusive are both true, and the path already exists,\n                    // getFile must fail.\n\n                    if (errorCallback) {\n                        errorCallback(FileError.PATH_EXISTS_ERR);\n                    }\n                } else if (options.create === true && !fileEntry) {\n                    // If create is true, the path doesn't exist, and no other error occurs,\n                    // getFile must create it as a zero-length file and return a corresponding\n                    // FileEntry.\n                    var newFileEntry = new FileEntry(path.fileName, path.fullPath, new FileSystem(path.fsName, fs_.root));\n\n                    newFileEntry.file_ = new MyFile({\n                        size: 0,\n                        name: newFileEntry.name,\n                        lastModifiedDate: new Date(),\n                        storagePath: path.storagePath\n                    });\n\n                    idb_.put(newFileEntry, path.storagePath, successCallback, errorCallback);\n                } else if (options.create === true && fileEntry) {\n                    if (fileEntry.isFile) {\n                        // Overwrite file, delete then create new.\n                        idb_['delete'](path.storagePath, function() {\n                            var newFileEntry = new FileEntry(path.fileName, path.fullPath, new FileSystem(path.fsName, fs_.root));\n\n                            newFileEntry.file_ = new MyFile({\n                                size: 0,\n                                name: newFileEntry.name,\n                                lastModifiedDate: new Date(),\n                                storagePath: path.storagePath\n                            });\n\n                            idb_.put(newFileEntry, path.storagePath, successCallback, errorCallback);\n                        }, errorCallback);\n                    } else {\n                        if (errorCallback) {\n                            errorCallback(FileError.INVALID_MODIFICATION_ERR);\n                        }\n                    }\n                } else if ((!options.create || options.create === false) && !fileEntry) {\n                    // If create is not true and the path doesn't exist, getFile must fail.\n                    if (errorCallback) {\n                        errorCallback(FileError.NOT_FOUND_ERR);\n                    }\n                } else if ((!options.create || options.create === false) && fileEntry &&\n                    fileEntry.isDirectory) {\n                    // If create is not true and the path exists, but is a directory, getFile\n                    // must fail.\n                    if (errorCallback) {\n                        errorCallback(FileError.TYPE_MISMATCH_ERR);\n                    }\n                } else {\n                    // Otherwise, if no other error occurs, getFile must return a FileEntry\n                    // corresponding to path.\n\n                    successCallback(fileEntryFromIdbEntry(fileEntry));\n                }\n            }, errorCallback);\n        };\n\n        exports.getFileMetadata = function(successCallback, errorCallback, args) {\n            var fullPath = args[0];\n\n            exports.getFile(function(fileEntry) {\n                successCallback(new File(fileEntry.file_.name, fileEntry.fullPath, '', fileEntry.file_.lastModifiedDate,\n                    fileEntry.file_.size));\n            }, errorCallback, [fullPath, null]);\n        };\n\n        exports.getMetadata = function(successCallback, errorCallback, args) {\n            exports.getFile(function (fileEntry) {\n                successCallback(\n                    {\n                        modificationTime: fileEntry.file_.lastModifiedDate,\n                        size: fileEntry.file_.lastModifiedDate\n                    });\n            }, errorCallback, args);\n        };\n\n        exports.setMetadata = function(successCallback, errorCallback, args) {\n            var fullPath = args[0];\n            var metadataObject = args[1];\n\n            exports.getFile(function (fileEntry) {\n                  fileEntry.file_.lastModifiedDate = metadataObject.modificationTime;\n                  idb_.put(fileEntry, fileEntry.file_.storagePath, successCallback, errorCallback);\n            }, errorCallback, [fullPath, null]);\n        };\n\n        exports.write = function(successCallback, errorCallback, args) {\n            var fileName = args[0],\n                data = args[1],\n                position = args[2],\n                isBinary = args[3]; // jshint ignore: line\n\n            if (!data) {\n                if (errorCallback) {\n                    errorCallback(FileError.INVALID_MODIFICATION_ERR);\n                }\n                return;\n            }\n\n            if (typeof data === 'string' || data instanceof String) {\n                data = new Blob([data]);\n            }\n\n            exports.getFile(function(fileEntry) {\n                var blob_ = fileEntry.file_.blob_;\n\n                if (!blob_) {\n                    blob_ = new Blob([data], {type: data.type});\n                } else {\n                    // Calc the head and tail fragments\n                    var head = blob_.slice(0, position);\n                    var tail = blob_.slice(position + (data.size || data.byteLength));\n\n                    // Calc the padding\n                    var padding = position - head.size;\n                    if (padding < 0) {\n                        padding = 0;\n                    }\n\n                    // Do the \"write\". In fact, a full overwrite of the Blob.\n                    blob_ = new Blob([head, new Uint8Array(padding), data, tail],\n                        {type: data.type});\n                }\n\n                // Set the blob we're writing on this file entry so we can recall it later.\n                fileEntry.file_.blob_ = blob_;\n                fileEntry.file_.lastModifiedDate = new Date() || null;\n                fileEntry.file_.size = blob_.size;\n                fileEntry.file_.name = blob_.name;\n                fileEntry.file_.type = blob_.type;\n\n                idb_.put(fileEntry, fileEntry.file_.storagePath, function() {\n                    successCallback(data.size || data.byteLength);\n                }, errorCallback);\n            }, errorCallback, [fileName, null]);\n        };\n\n        exports.readAsText = function(successCallback, errorCallback, args) {\n            var fileName = args[0],\n                enc = args[1],\n                startPos = args[2],\n                endPos = args[3];\n\n            readAs('text', fileName, enc, startPos, endPos, successCallback, errorCallback);\n        };\n\n        exports.readAsDataURL = function(successCallback, errorCallback, args) {\n            var fileName = args[0],\n                startPos = args[1],\n                endPos = args[2];\n\n            readAs('dataURL', fileName, null, startPos, endPos, successCallback, errorCallback);\n        };\n\n        exports.readAsBinaryString = function(successCallback, errorCallback, args) {\n            var fileName = args[0],\n                startPos = args[1],\n                endPos = args[2];\n\n            readAs('binaryString', fileName, null, startPos, endPos, successCallback, errorCallback);\n        };\n\n        exports.readAsArrayBuffer = function(successCallback, errorCallback, args) {\n            var fileName = args[0],\n                startPos = args[1],\n                endPos = args[2];\n\n            readAs('arrayBuffer', fileName, null, startPos, endPos, successCallback, errorCallback);\n        };\n\n        exports.removeRecursively = exports.remove = function(successCallback, errorCallback, args) {\n            if (typeof successCallback !== 'function') {\n                throw Error('Expected successCallback argument.');\n            }\n\n            var fullPath = resolveToFullPath_(args[0]).storagePath;\n            if (fullPath === pathsPrefix.cacheDirectory || fullPath === pathsPrefix.dataDirectory) {\n                errorCallback(FileError.NO_MODIFICATION_ALLOWED_ERR);\n                return;\n            }\n\n            function deleteEntry(isDirectory) {\n                // TODO: This doesn't protect against directories that have content in it.\n                // Should throw an error instead if the dirEntry is not empty.\n                idb_['delete'](fullPath, function() {\n                    successCallback();\n                }, function() {\n                        if (errorCallback) { errorCallback(); }\n                }, isDirectory);\n            }\n\n            // We need to to understand what we are deleting:\n            exports.getDirectory(function(entry) {\n                deleteEntry(entry.isDirectory);\n            }, function(){\n                //DirectoryEntry was already deleted or entry is FileEntry\n                deleteEntry(false);\n            }, [fullPath, null, {create: false}]);\n        };\n\n        exports.getDirectory = function(successCallback, errorCallback, args) {\n            var fullPath = args[0];\n            var path = args[1];\n            var options = args[2];\n\n            // Create an absolute path if we were handed a relative one.\n            path = resolveToFullPath_(fullPath, path);\n\n            idb_.get(path.storagePath, function(folderEntry) {\n                if (!options) {\n                    options = {};\n                }\n\n                if (options.create === true && options.exclusive === true && folderEntry) {\n                    // If create and exclusive are both true, and the path already exists,\n                    // getDirectory must fail.\n                    if (errorCallback) {\n                        errorCallback(FileError.PATH_EXISTS_ERR);\n                    }\n                    // There is a strange bug in mobilespec + FF, which results in coming to multiple else-if's\n                    // so we are shielding from it with returns.\n                    return;\n                }\n\n                if (options.create === true && !folderEntry) {\n                    // If create is true, the path doesn't exist, and no other error occurs,\n                    // getDirectory must create it as a zero-length file and return a corresponding\n                    // MyDirectoryEntry.\n                    var dirEntry = new DirectoryEntry(path.fileName, path.fullPath, new FileSystem(path.fsName, fs_.root));\n\n                    idb_.put(dirEntry, path.storagePath, successCallback, errorCallback);\n                    return;\n                }\n\n                if (options.create === true && folderEntry) {\n\n                    if (folderEntry.isDirectory) {\n                        // IDB won't save methods, so we need re-create the MyDirectoryEntry.\n                        successCallback(new DirectoryEntry(folderEntry.name, folderEntry.fullPath, folderEntry.filesystem));\n                    } else {\n                        if (errorCallback) {\n                            errorCallback(FileError.INVALID_MODIFICATION_ERR);\n                        }\n                    }\n                    return;\n                }\n\n                if ((!options.create || options.create === false) && !folderEntry) {\n                    // Handle root special. It should always exist.\n                    if (path.fullPath === DIR_SEPARATOR) {\n                        successCallback(fs_.root);\n                        return;\n                    }\n\n                    // If create is not true and the path doesn't exist, getDirectory must fail.\n                    if (errorCallback) {\n                        errorCallback(FileError.NOT_FOUND_ERR);\n                    }\n\n                    return;\n                }\n                if ((!options.create || options.create === false) && folderEntry && folderEntry.isFile) {\n                    // If create is not true and the path exists, but is a file, getDirectory\n                    // must fail.\n                    if (errorCallback) {\n                        errorCallback(FileError.TYPE_MISMATCH_ERR);\n                    }\n                    return;\n                }\n\n                // Otherwise, if no other error occurs, getDirectory must return a\n                // MyDirectoryEntry corresponding to path.\n\n                // IDB won't' save methods, so we need re-create MyDirectoryEntry.\n                successCallback(new DirectoryEntry(folderEntry.name, folderEntry.fullPath, folderEntry.filesystem));\n            }, errorCallback);\n        };\n\n        exports.getParent = function(successCallback, errorCallback, args) {\n            if (typeof successCallback !== 'function') {\n                throw Error('Expected successCallback argument.');\n            }\n\n            var fullPath = args[0];\n            //fullPath is like this:\n            //file:///persistent/path/to/file or\n            //file:///persistent/path/to/directory/\n\n            if (fullPath === DIR_SEPARATOR || fullPath === pathsPrefix.cacheDirectory ||\n                fullPath === pathsPrefix.dataDirectory) {\n                successCallback(fs_.root);\n                return;\n            }\n\n            //To delete all slashes at the end\n            while (fullPath[fullPath.length - 1] === '/') {\n                fullPath = fullPath.substr(0, fullPath.length - 1);\n            }\n\n            var pathArr = fullPath.split(DIR_SEPARATOR);\n            pathArr.pop();\n            var parentName = pathArr.pop();\n            var path = pathArr.join(DIR_SEPARATOR) + DIR_SEPARATOR;\n\n            //To get parent of root files\n            var joined = path + parentName + DIR_SEPARATOR;//is like this: file:///persistent/\n            if (joined === pathsPrefix.cacheDirectory || joined === pathsPrefix.dataDirectory) {\n                exports.getDirectory(successCallback, errorCallback, [joined, DIR_SEPARATOR, {create: false}]);\n                return;\n            }\n\n            exports.getDirectory(successCallback, errorCallback, [path, parentName, {create: false}]);\n        };\n\n        exports.copyTo = function(successCallback, errorCallback, args) {\n            var srcPath = args[0];\n            var parentFullPath = args[1];\n            var name = args[2];\n\n            if (name.indexOf('/') !== -1 || srcPath === parentFullPath + name) {\n                if (errorCallback) {\n                    errorCallback(FileError.INVALID_MODIFICATION_ERR);\n                }\n\n                return;\n            }\n\n            // Read src file\n            exports.getFile(function(srcFileEntry) {\n\n                var path = resolveToFullPath_(parentFullPath);\n                //Check directory\n                exports.getDirectory(function() {\n\n                    // Create dest file\n                    exports.getFile(function(dstFileEntry) {\n\n                        exports.write(function() {\n                            successCallback(dstFileEntry);\n                        }, errorCallback, [dstFileEntry.file_.storagePath, srcFileEntry.file_.blob_, 0]);\n\n                    }, errorCallback, [parentFullPath, name, {create: true}]);\n\n                }, function() { if (errorCallback) { errorCallback(FileError.NOT_FOUND_ERR); }},\n                [path.storagePath, null, {create:false}]);\n\n            }, errorCallback, [srcPath, null]);\n        };\n\n        exports.moveTo = function(successCallback, errorCallback, args) {\n            var srcPath = args[0];\n            // parentFullPath and name parameters is ignored because\n            // args is being passed downstream to exports.copyTo method\n            var parentFullPath = args[1]; // jshint ignore: line\n            var name = args[2]; // jshint ignore: line\n\n            exports.copyTo(function (fileEntry) {\n\n                exports.remove(function () {\n                    successCallback(fileEntry);\n                }, errorCallback, [srcPath]);\n\n            }, errorCallback, args);\n        };\n\n        exports.resolveLocalFileSystemURI = function(successCallback, errorCallback, args) {\n            var path = args[0];\n\n            // Ignore parameters\n            if (path.indexOf('?') !== -1) {\n                path = String(path).split(\"?\")[0];\n            }\n\n            // support for encodeURI\n            if (/\\%5/g.test(path) || /\\%20/g.test(path)) {\n                path = decodeURI(path);\n            }\n\n            if (path.trim()[0] === '/') {\n                if (errorCallback) {\n                    errorCallback(FileError.ENCODING_ERR);\n                }\n                return;\n            }\n\n            //support for cdvfile\n            if (path.trim().substr(0,7) === \"cdvfile\") {\n                if (path.indexOf(\"cdvfile://localhost\") === -1) {\n                    if (errorCallback) {\n                        errorCallback(FileError.ENCODING_ERR);\n                    }\n                    return;\n                }\n\n                var indexPersistent = path.indexOf(\"persistent\");\n                var indexTemporary = path.indexOf(\"temporary\");\n\n                //cdvfile://localhost/persistent/path/to/file\n                if (indexPersistent !== -1) {\n                    path =  \"file:///persistent\" + path.substr(indexPersistent + 10);\n                } else if (indexTemporary !== -1) {\n                    path = \"file:///temporary\" + path.substr(indexTemporary + 9);\n                } else {\n                    if (errorCallback) {\n                        errorCallback(FileError.ENCODING_ERR);\n                    }\n                    return;\n                }\n            }\n\n            // to avoid path form of '///path/to/file'\n            function handlePathSlashes(path) {\n                var cutIndex  = 0;\n                for (var i = 0; i < path.length - 1; i++) {\n                    if (path[i] === DIR_SEPARATOR && path[i + 1] === DIR_SEPARATOR) {\n                        cutIndex = i + 1;\n                    } else break;\n                }\n\n                return path.substr(cutIndex);\n            }\n\n            // Handle localhost containing paths (see specs )\n            if (path.indexOf('file://localhost/') === 0) {\n                path = path.replace('file://localhost/', 'file:///');\n            }\n\n            if (path.indexOf(pathsPrefix.dataDirectory) === 0) {\n                path = path.substring(pathsPrefix.dataDirectory.length - 1);\n                path = handlePathSlashes(path);\n\n                exports.requestFileSystem(function() {\n                    exports.getFile(successCallback, function() {\n                        exports.getDirectory(successCallback, errorCallback, [pathsPrefix.dataDirectory, path,\n                        {create: false}]);\n                    }, [pathsPrefix.dataDirectory, path, {create: false}]);\n                }, errorCallback, [LocalFileSystem.PERSISTENT]);\n            } else if (path.indexOf(pathsPrefix.cacheDirectory) === 0) {\n                path = path.substring(pathsPrefix.cacheDirectory.length - 1);\n                path = handlePathSlashes(path);\n\n                exports.requestFileSystem(function() {\n                    exports.getFile(successCallback, function() {\n                        exports.getDirectory(successCallback, errorCallback, [pathsPrefix.cacheDirectory, path,\n                        {create: false}]);\n                    }, [pathsPrefix.cacheDirectory, path, {create: false}]);\n                }, errorCallback, [LocalFileSystem.TEMPORARY]);\n            } else if (path.indexOf(pathsPrefix.applicationDirectory) === 0) {\n                path = path.substring(pathsPrefix.applicationDirectory.length);\n                //TODO: need to cut out redundant slashes?\n\n                var xhr = new XMLHttpRequest();\n                xhr.open(\"GET\", path, true);\n                xhr.onreadystatechange = function () {\n                    if (xhr.status === 200 && xhr.readyState === 4) {\n                        exports.requestFileSystem(function(fs) {\n                            fs.name = location.hostname;\n\n                            //TODO: need to call exports.getFile(...) to handle errors correct\n                            fs.root.getFile(path, {create: true}, writeFile, errorCallback);\n                        }, errorCallback, [LocalFileSystem.PERSISTENT]);\n                    }\n                };\n\n                xhr.onerror = function () {\n                    if(errorCallback) {\n                        errorCallback(FileError.NOT_READABLE_ERR);\n                    }\n                };\n\n                xhr.send();\n            } else {\n                if(errorCallback) {\n                    errorCallback(FileError.NOT_FOUND_ERR);\n                }\n            }\n\n            function writeFile(entry) {\n                entry.createWriter(function (fileWriter) {\n                    fileWriter.onwriteend = function (evt) {\n                        if (!evt.target.error) {\n                            entry.filesystemName = location.hostname;\n                            successCallback(entry);\n                        }\n                    };\n                    fileWriter.onerror = function () {\n                        if (errorCallback) {\n                            errorCallback(FileError.NOT_READABLE_ERR);\n                        }\n                    };\n                    fileWriter.write(new Blob([xhr.response]));\n                }, errorCallback);\n            }\n        };\n\n        exports.requestAllPaths = function(successCallback) {\n            successCallback(pathsPrefix);\n        };\n\n    /*** Helpers ***/\n\n        /**\n         * Interface to wrap the native File interface.\n         *\n         * This interface is necessary for creating zero-length (empty) files,\n         * something the Filesystem API allows you to do. Unfortunately, File's\n         * constructor cannot be called directly, making it impossible to instantiate\n         * an empty File in JS.\n         *\n         * @param {Object} opts Initial values.\n         * @constructor\n         */\n        function MyFile(opts) {\n            var blob_ = new Blob();\n\n            this.size = opts.size || 0;\n            this.name = opts.name || '';\n            this.type = opts.type || '';\n            this.lastModifiedDate = opts.lastModifiedDate || null;\n            this.storagePath = opts.storagePath || '';\n\n            // Need some black magic to correct the object's size/name/type based on the\n            // blob that is saved.\n            Object.defineProperty(this, 'blob_', {\n                enumerable: true,\n                get: function() {\n                    return blob_;\n                },\n                set: function(val) {\n                    blob_ = val;\n                    this.size = blob_.size;\n                    this.name = blob_.name;\n                    this.type = blob_.type;\n                    this.lastModifiedDate = blob_.lastModifiedDate;\n                }.bind(this)\n            });\n        }\n\n        MyFile.prototype.constructor = MyFile;\n\n        // When saving an entry, the fullPath should always lead with a slash and never\n        // end with one (e.g. a directory). Also, resolve '.' and '..' to an absolute\n        // one. This method ensures path is legit!\n        function resolveToFullPath_(cwdFullPath, path) {\n            path = path || '';\n            var fullPath = path;\n            var prefix = '';\n\n            cwdFullPath = cwdFullPath || DIR_SEPARATOR;\n            if (cwdFullPath.indexOf(FILESYSTEM_PREFIX) === 0) {\n                prefix = cwdFullPath.substring(0, cwdFullPath.indexOf(DIR_SEPARATOR, FILESYSTEM_PREFIX.length));\n                cwdFullPath = cwdFullPath.substring(cwdFullPath.indexOf(DIR_SEPARATOR, FILESYSTEM_PREFIX.length));\n            }\n\n            var relativePath = path[0] !== DIR_SEPARATOR;\n            if (relativePath) {\n                fullPath = cwdFullPath;\n                if (cwdFullPath !== DIR_SEPARATOR) {\n                    fullPath += DIR_SEPARATOR + path;\n                } else {\n                    fullPath += path;\n                }\n            }\n\n            // Remove doubled separator substrings\n            var re = new RegExp(DIR_SEPARATOR + DIR_SEPARATOR, 'g');\n            fullPath = fullPath.replace(re, DIR_SEPARATOR);\n\n            // Adjust '..'s by removing parent directories when '..' flows in path.\n            var parts = fullPath.split(DIR_SEPARATOR);\n            for (var i = 0; i < parts.length; ++i) {\n                var part = parts[i];\n                if (part === '..') {\n                    parts[i - 1] = '';\n                    parts[i] = '';\n                }\n            }\n            fullPath = parts.filter(function(el) {\n                return el;\n            }).join(DIR_SEPARATOR);\n\n            // Add back in leading slash.\n            if (fullPath[0] !== DIR_SEPARATOR) {\n                fullPath = DIR_SEPARATOR + fullPath;\n            }\n\n            // Replace './' by current dir. ('./one/./two' -> one/two)\n            fullPath = fullPath.replace(/\\.\\//g, DIR_SEPARATOR);\n\n            // Replace '//' with '/'.\n            fullPath = fullPath.replace(/\\/\\//g, DIR_SEPARATOR);\n\n            // Replace '/.' with '/'.\n            fullPath = fullPath.replace(/\\/\\./g, DIR_SEPARATOR);\n\n            // Remove '/' if it appears on the end.\n            if (fullPath[fullPath.length - 1] === DIR_SEPARATOR &&\n                fullPath !== DIR_SEPARATOR) {\n                fullPath = fullPath.substring(0, fullPath.length - 1);\n            }\n\n            var storagePath = prefix + fullPath;\n            storagePath = decodeURI(storagePath);\n            fullPath = decodeURI(fullPath);\n\n            return {\n                storagePath: storagePath,\n                fullPath: fullPath,\n                fileName: fullPath.split(DIR_SEPARATOR).pop(),\n                fsName: prefix.split(DIR_SEPARATOR).pop()\n            };\n        }\n\n        function fileEntryFromIdbEntry(fileEntry) {\n            // IDB won't save methods, so we need re-create the FileEntry.\n            var clonedFileEntry = new FileEntry(fileEntry.name, fileEntry.fullPath, fileEntry.filesystem);\n            clonedFileEntry.file_ = fileEntry.file_;\n\n            return clonedFileEntry;\n        }\n\n        function readAs(what, fullPath, encoding, startPos, endPos, successCallback, errorCallback) {\n            exports.getFile(function(fileEntry) {\n                var fileReader = new FileReader(),\n                    blob = fileEntry.file_.blob_.slice(startPos, endPos);\n\n                fileReader.onload = function(e) {\n                    successCallback(e.target.result);\n                };\n\n                fileReader.onerror = errorCallback;\n\n                switch (what) {\n                    case 'text':\n                        fileReader.readAsText(blob, encoding);\n                        break;\n                    case 'dataURL':\n                        fileReader.readAsDataURL(blob);\n                        break;\n                    case 'arrayBuffer':\n                        fileReader.readAsArrayBuffer(blob);\n                        break;\n                    case 'binaryString':\n                        fileReader.readAsBinaryString(blob);\n                        break;\n                }\n\n            }, errorCallback, [fullPath, null]);\n        }\n\n    /*** Core logic to handle IDB operations ***/\n\n        idb_.open = function(dbName, successCallback, errorCallback) {\n            var self = this;\n\n            // TODO: FF 12.0a1 isn't liking a db name with : in it.\n            var request = indexedDB.open(dbName.replace(':', '_')/*, 1 /*version*/);\n\n            request.onerror = errorCallback || onError;\n\n            request.onupgradeneeded = function(e) {\n                // First open was called or higher db version was used.\n\n                // console.log('onupgradeneeded: oldVersion:' + e.oldVersion,\n                //           'newVersion:' + e.newVersion);\n\n                self.db = e.target.result;\n                self.db.onerror = onError;\n\n                if (!self.db.objectStoreNames.contains(FILE_STORE_)) {\n                    self.db.createObjectStore(FILE_STORE_/*,{keyPath: 'id', autoIncrement: true}*/);\n                }\n            };\n\n            request.onsuccess = function(e) {\n                self.db = e.target.result;\n                self.db.onerror = onError;\n                successCallback(e);\n            };\n\n            request.onblocked = errorCallback || onError;\n        };\n\n        idb_.close = function() {\n            this.db.close();\n            this.db = null;\n        };\n\n        idb_.get = function(fullPath, successCallback, errorCallback) {\n            if (!this.db) {\n                if (errorCallback) {\n                    errorCallback(FileError.INVALID_MODIFICATION_ERR);\n                }\n                return;\n            }\n\n            var tx = this.db.transaction([FILE_STORE_], 'readonly');\n\n            var request = tx.objectStore(FILE_STORE_).get(fullPath);\n\n            tx.onabort = errorCallback || onError;\n            tx.oncomplete = function() {\n                successCallback(request.result);\n            };\n        };\n\n        idb_.getAllEntries = function(fullPath, storagePath, successCallback, errorCallback) {\n            if (!this.db) {\n                if (errorCallback) {\n                    errorCallback(FileError.INVALID_MODIFICATION_ERR);\n                }\n                return;\n            }\n\n            var results = [];\n\n            if (storagePath[storagePath.length - 1] === DIR_SEPARATOR) {\n                storagePath = storagePath.substring(0, storagePath.length - 1);\n            }\n\n            var range = IDBKeyRange.bound(storagePath + DIR_SEPARATOR + ' ',\n                storagePath + DIR_SEPARATOR + String.fromCharCode(unicodeLastChar));\n\n            var tx = this.db.transaction([FILE_STORE_], 'readonly');\n            tx.onabort = errorCallback || onError;\n            tx.oncomplete = function() {\n                results = results.filter(function(val) {\n                    var pathWithoutSlash = val.fullPath;\n\n                    if (val.fullPath[val.fullPath.length - 1] === DIR_SEPARATOR) {\n                        pathWithoutSlash = pathWithoutSlash.substr(0, pathWithoutSlash.length - 1);\n                    }\n\n                    var valPartsLen = pathWithoutSlash.split(DIR_SEPARATOR).length;\n                    var fullPathPartsLen = fullPath.split(DIR_SEPARATOR).length;\n\n                    /* Input fullPath parameter  equals '//' for root folder */\n                    /* Entries in root folder has valPartsLen equals 2 (see below) */\n                    if (fullPath[fullPath.length -1] === DIR_SEPARATOR && fullPath.trim().length === 2) {\n                        fullPathPartsLen = 1;\n                    } else if (fullPath[fullPath.length -1] === DIR_SEPARATOR) {\n                        fullPathPartsLen = fullPath.substr(0, fullPath.length - 1).split(DIR_SEPARATOR).length;\n                    } else {\n                        fullPathPartsLen = fullPath.split(DIR_SEPARATOR).length;\n                    }\n\n                    if (valPartsLen === fullPathPartsLen + 1) {\n                        // If this a subfolder and entry is a direct child, include it in\n                        // the results. Otherwise, it's not an entry of this folder.\n                        return val;\n                    } else return false;\n                });\n\n                successCallback(results);\n            };\n\n            var request = tx.objectStore(FILE_STORE_).openCursor(range);\n\n            request.onsuccess = function(e) {\n                var cursor = e.target.result;\n                if (cursor) {\n                    var val = cursor.value;\n\n                    results.push(val.isFile ? fileEntryFromIdbEntry(val) : new DirectoryEntry(val.name, val.fullPath, val.filesystem));\n                    cursor['continue']();\n                }\n            };\n        };\n\n        idb_['delete'] = function(fullPath, successCallback, errorCallback, isDirectory) {\n            if (!idb_.db) {\n                if (errorCallback) {\n                    errorCallback(FileError.INVALID_MODIFICATION_ERR);\n                }\n                return;\n            }\n\n            var tx = this.db.transaction([FILE_STORE_], 'readwrite');\n            tx.oncomplete = successCallback;\n            tx.onabort = errorCallback || onError;\n            tx.oncomplete = function() {\n                if (isDirectory) {\n                    //We delete nested files and folders after deleting parent folder\n                    //We use ranges: https://developer.mozilla.org/en-US/docs/Web/API/IDBKeyRange\n                    fullPath = fullPath + DIR_SEPARATOR;\n\n                    //Range contains all entries in the form fullPath<symbol> where\n                    //symbol in the range from ' ' to symbol which has code `unicodeLastChar`\n                    var range = IDBKeyRange.bound(fullPath + ' ', fullPath + String.fromCharCode(unicodeLastChar));\n\n                    var newTx = this.db.transaction([FILE_STORE_], 'readwrite');\n                    newTx.oncomplete = successCallback;\n                    newTx.onabort = errorCallback || onError;\n                    newTx.objectStore(FILE_STORE_)['delete'](range);\n                } else {\n                    successCallback();\n                }\n            };\n            tx.objectStore(FILE_STORE_)['delete'](fullPath);\n        };\n\n        idb_.put = function(entry, storagePath, successCallback, errorCallback) {\n            if (!this.db) {\n                if (errorCallback) {\n                    errorCallback(FileError.INVALID_MODIFICATION_ERR);\n                }\n                return;\n            }\n\n            var tx = this.db.transaction([FILE_STORE_], 'readwrite');\n            tx.onabort = errorCallback || onError;\n            tx.oncomplete = function() {\n                // TODO: Error is thrown if we pass the request event back instead.\n                successCallback(entry);\n            };\n\n            tx.objectStore(FILE_STORE_).put(entry, storagePath);\n        };\n\n        // Global error handler. Errors bubble from request, to transaction, to db.\n        function onError(e) {\n            switch (e.target.errorCode) {\n                case 12:\n                    console.log('Error - Attempt to open db with a lower version than the ' +\n                        'current one.');\n                    break;\n                default:\n                    console.log('errorCode: ' + e.target.errorCode);\n            }\n\n            console.log(e, e.code, e.message);\n        }\n\n    })(module.exports, window);\n\n    require(\"cordova/exec/proxy\").add(\"File\", module.exports);\n})();\n"
  },
  {
    "path": "plugins/cordova-plugin-file/src/firefoxos/FileProxy.js",
    "content": "﻿/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n */\n\n/* global IDBKeyRange */\n\nvar LocalFileSystem = require('./LocalFileSystem'),\n    FileSystem = require('./FileSystem'),\n    FileEntry = require('./FileEntry'),\n    FileError = require('./FileError'),\n    DirectoryEntry = require('./DirectoryEntry'),\n    File = require('./File');\n\n/*\nQUIRKS:\n    Does not fail when removing non-empty directories\n    Does not support metadata for directories\n    Does not support requestAllFileSystems\n    Does not support resolveLocalFileSystemURI\n    Methods copyTo and moveTo do not support directories\n\n    Heavily based on https://github.com/ebidel/idb.filesystem.js\n */\n\n\n(function(exports, global) {\n    var indexedDB = global.indexedDB || global.mozIndexedDB;\n    if (!indexedDB) {\n        throw \"Firefox OS File plugin: indexedDB not supported\";\n    }\n\n    var fs_ = null;\n\n    var idb_ = {};\n    idb_.db = null;\n    var FILE_STORE_ = 'entries';\n\n    var DIR_SEPARATOR = '/';\n    var DIR_OPEN_BOUND = String.fromCharCode(DIR_SEPARATOR.charCodeAt(0) + 1);\n\n    var pathsPrefix = {\n        // Read-only directory where the application is installed.\n        applicationDirectory: location.origin + \"/\",\n        // Where to put app-specific data files.\n        dataDirectory: 'file:///persistent/',\n        // Cached files that should survive app restarts.\n        // Apps should not rely on the OS to delete files in here.\n        cacheDirectory: 'file:///temporary/',\n    };\n\n/*** Exported functionality ***/\n\n    exports.requestFileSystem = function(successCallback, errorCallback, args) {\n        var type = args[0];\n        //var size = args[1];\n\n        if (type !== LocalFileSystem.TEMPORARY && type !== LocalFileSystem.PERSISTENT) {\n            if (errorCallback) {\n                errorCallback(FileError.INVALID_MODIFICATION_ERR);\n            }\n            return;\n        }\n\n        var name = type === LocalFileSystem.TEMPORARY ? 'temporary' : 'persistent';\n        var storageName = (location.protocol + location.host).replace(/:/g, '_');\n\n        var root = new DirectoryEntry('', DIR_SEPARATOR);\n        fs_ = new FileSystem(name, root);\n\n        idb_.open(storageName, function() {\n            successCallback(fs_);\n        }, errorCallback);\n    };\n\n    require('./fileSystems').getFs = function(name, callback) {\n        callback(new FileSystem(name, fs_.root));\n    };\n\n    // list a directory's contents (files and folders).\n    exports.readEntries = function(successCallback, errorCallback, args) {\n        var fullPath = args[0];\n\n        if (!successCallback) {\n            throw Error('Expected successCallback argument.');\n        }\n\n        var path = resolveToFullPath_(fullPath);\n\n        idb_.getAllEntries(path.fullPath, path.storagePath, function(entries) {\n            successCallback(entries);\n        }, errorCallback);\n    };\n\n    exports.getFile = function(successCallback, errorCallback, args) {\n        var fullPath = args[0];\n        var path = args[1];\n        var options = args[2] || {};\n\n        // Create an absolute path if we were handed a relative one.\n        path = resolveToFullPath_(fullPath, path);\n\n        idb_.get(path.storagePath, function(fileEntry) {\n            if (options.create === true && options.exclusive === true && fileEntry) {\n                // If create and exclusive are both true, and the path already exists,\n                // getFile must fail.\n\n                if (errorCallback) {\n                    errorCallback(FileError.PATH_EXISTS_ERR);\n                }\n            } else if (options.create === true && !fileEntry) {\n                // If create is true, the path doesn't exist, and no other error occurs,\n                // getFile must create it as a zero-length file and return a corresponding\n                // FileEntry.\n                var newFileEntry = new FileEntry(path.fileName, path.fullPath, new FileSystem(path.fsName, fs_.root));\n\n                newFileEntry.file_ = new MyFile({\n                    size: 0,\n                    name: newFileEntry.name,\n                    lastModifiedDate: new Date(),\n                    storagePath: path.storagePath\n                });\n\n                idb_.put(newFileEntry, path.storagePath, successCallback, errorCallback);\n            } else if (options.create === true && fileEntry) {\n                if (fileEntry.isFile) {\n                    // Overwrite file, delete then create new.\n                    idb_['delete'](path.storagePath, function() {\n                        var newFileEntry = new FileEntry(path.fileName, path.fullPath, new FileSystem(path.fsName, fs_.root));\n\n                        newFileEntry.file_ = new MyFile({\n                            size: 0,\n                            name: newFileEntry.name,\n                            lastModifiedDate: new Date(),\n                            storagePath: path.storagePath\n                        });\n\n                        idb_.put(newFileEntry, path.storagePath, successCallback, errorCallback);\n                    }, errorCallback);\n                } else {\n                    if (errorCallback) {\n                        errorCallback(FileError.INVALID_MODIFICATION_ERR);\n                    }\n                }\n            } else if ((!options.create || options.create === false) && !fileEntry) {\n                // If create is not true and the path doesn't exist, getFile must fail.\n                if (errorCallback) {\n                    errorCallback(FileError.NOT_FOUND_ERR);\n                }\n            } else if ((!options.create || options.create === false) && fileEntry &&\n                fileEntry.isDirectory) {\n                // If create is not true and the path exists, but is a directory, getFile\n                // must fail.\n                if (errorCallback) {\n                    errorCallback(FileError.INVALID_MODIFICATION_ERR);\n                }\n            } else {\n                // Otherwise, if no other error occurs, getFile must return a FileEntry\n                // corresponding to path.\n\n                successCallback(fileEntryFromIdbEntry(fileEntry));\n            }\n        }, errorCallback);\n    };\n\n    exports.getFileMetadata = function(successCallback, errorCallback, args) {\n        var fullPath = args[0];\n\n        exports.getFile(function(fileEntry) {\n            successCallback(new File(fileEntry.file_.name, fileEntry.fullPath, '', fileEntry.file_.lastModifiedDate,\n                fileEntry.file_.size));\n        }, errorCallback, [fullPath, null]);\n    };\n\n    exports.getMetadata = function(successCallback, errorCallback, args) {\n        exports.getFile(function (fileEntry) {\n            successCallback(\n                {\n                    modificationTime: fileEntry.file_.lastModifiedDate,\n                    size: fileEntry.file_.lastModifiedDate\n                });\n        }, errorCallback, args);\n    };\n\n    exports.setMetadata = function(successCallback, errorCallback, args) {\n        var fullPath = args[0];\n        var metadataObject = args[1];\n\n        exports.getFile(function (fileEntry) {\n              fileEntry.file_.lastModifiedDate = metadataObject.modificationTime;\n        }, errorCallback, [fullPath, null]);\n    };\n\n    exports.write = function(successCallback, errorCallback, args) {\n        var fileName = args[0],\n            data = args[1],\n            position = args[2];\n            //isBinary = args[3];\n\n        if (!data) {\n            if (errorCallback) {\n                errorCallback(FileError.INVALID_MODIFICATION_ERR);\n            }\n            return;\n        }\n\n        exports.getFile(function(fileEntry) {\n            var blob_ = fileEntry.file_.blob_;\n\n            if (!blob_) {\n                blob_ = new Blob([data], {type: data.type});\n            } else {\n                // Calc the head and tail fragments\n                var head = blob_.slice(0, position);\n                var tail = blob_.slice(position + data.byteLength);\n\n                // Calc the padding\n                var padding = position - head.size;\n                if (padding < 0) {\n                    padding = 0;\n                }\n\n                // Do the \"write\". In fact, a full overwrite of the Blob.\n                blob_ = new Blob([head, new Uint8Array(padding), data, tail],\n                    {type: data.type});\n            }\n\n            // Set the blob we're writing on this file entry so we can recall it later.\n            fileEntry.file_.blob_ = blob_;\n            fileEntry.file_.lastModifiedDate = data.lastModifiedDate || null;\n            fileEntry.file_.size = blob_.size;\n            fileEntry.file_.name = blob_.name;\n            fileEntry.file_.type = blob_.type;\n\n            idb_.put(fileEntry, fileEntry.file_.storagePath, function() {\n                successCallback(data.byteLength);\n            }, errorCallback);\n        }, errorCallback, [fileName, null]);\n    };\n\n    exports.readAsText = function(successCallback, errorCallback, args) {\n        var fileName = args[0],\n            enc = args[1],\n            startPos = args[2],\n            endPos = args[3];\n\n        readAs('text', fileName, enc, startPos, endPos, successCallback, errorCallback);\n    };\n\n    exports.readAsDataURL = function(successCallback, errorCallback, args) {\n        var fileName = args[0],\n            startPos = args[1],\n            endPos = args[2];\n\n        readAs('dataURL', fileName, null, startPos, endPos, successCallback, errorCallback);\n    };\n\n    exports.readAsBinaryString = function(successCallback, errorCallback, args) {\n        var fileName = args[0],\n            startPos = args[1],\n            endPos = args[2];\n\n        readAs('binaryString', fileName, null, startPos, endPos, successCallback, errorCallback);\n    };\n\n    exports.readAsArrayBuffer = function(successCallback, errorCallback, args) {\n        var fileName = args[0],\n            startPos = args[1],\n            endPos = args[2];\n\n        readAs('arrayBuffer', fileName, null, startPos, endPos, successCallback, errorCallback);\n    };\n\n    exports.removeRecursively = exports.remove = function(successCallback, errorCallback, args) {\n        var fullPath = args[0];\n\n        // TODO: This doesn't protect against directories that have content in it.\n        // Should throw an error instead if the dirEntry is not empty.\n        idb_['delete'](fullPath, function() {\n            successCallback();\n        }, errorCallback);\n    };\n\n    exports.getDirectory = function(successCallback, errorCallback, args) {\n        var fullPath = args[0];\n        var path = args[1];\n        var options = args[2];\n\n        // Create an absolute path if we were handed a relative one.\n        path = resolveToFullPath_(fullPath, path);\n\n        idb_.get(path.storagePath, function(folderEntry) {\n            if (!options) {\n                options = {};\n            }\n\n            if (options.create === true && options.exclusive === true && folderEntry) {\n                // If create and exclusive are both true, and the path already exists,\n                // getDirectory must fail.\n                if (errorCallback) {\n                    errorCallback(FileError.INVALID_MODIFICATION_ERR);\n                }\n            } else if (options.create === true && !folderEntry) {\n                // If create is true, the path doesn't exist, and no other error occurs,\n                // getDirectory must create it as a zero-length file and return a corresponding\n                // MyDirectoryEntry.\n                var dirEntry = new DirectoryEntry(path.fileName, path.fullPath, new FileSystem(path.fsName, fs_.root));\n\n                idb_.put(dirEntry, path.storagePath, successCallback, errorCallback);\n            } else if (options.create === true && folderEntry) {\n\n                if (folderEntry.isDirectory) {\n                    // IDB won't save methods, so we need re-create the MyDirectoryEntry.\n                    successCallback(new DirectoryEntry(folderEntry.name, folderEntry.fullPath, folderEntry.fileSystem));\n                } else {\n                    if (errorCallback) {\n                        errorCallback(FileError.INVALID_MODIFICATION_ERR);\n                    }\n                }\n            } else if ((!options.create || options.create === false) && !folderEntry) {\n                // Handle root special. It should always exist.\n                if (path.fullPath === DIR_SEPARATOR) {\n                    successCallback(fs_.root);\n                    return;\n                }\n\n                // If create is not true and the path doesn't exist, getDirectory must fail.\n                if (errorCallback) {\n                    errorCallback(FileError.NOT_FOUND_ERR);\n                }\n            } else if ((!options.create || options.create === false) && folderEntry &&\n                folderEntry.isFile) {\n                // If create is not true and the path exists, but is a file, getDirectory\n                // must fail.\n                if (errorCallback) {\n                    errorCallback(FileError.INVALID_MODIFICATION_ERR);\n                }\n            } else {\n                // Otherwise, if no other error occurs, getDirectory must return a\n                // MyDirectoryEntry corresponding to path.\n\n                // IDB won't' save methods, so we need re-create MyDirectoryEntry.\n                successCallback(new DirectoryEntry(folderEntry.name, folderEntry.fullPath, folderEntry.fileSystem));\n            }\n        }, errorCallback);\n    };\n\n    exports.getParent = function(successCallback, errorCallback, args) {\n        var fullPath = args[0];\n\n        if (fullPath === DIR_SEPARATOR) {\n            successCallback(fs_.root);\n            return;\n        }\n\n        var pathArr = fullPath.split(DIR_SEPARATOR);\n        pathArr.pop();\n        var namesa = pathArr.pop();\n        var path = pathArr.join(DIR_SEPARATOR);\n\n        exports.getDirectory(successCallback, errorCallback, [path, namesa, {create: false}]);\n    };\n\n    exports.copyTo = function(successCallback, errorCallback, args) {\n        var srcPath = args[0];\n        var parentFullPath = args[1];\n        var name = args[2];\n\n        // Read src file\n        exports.getFile(function(srcFileEntry) {\n\n            // Create dest file\n            exports.getFile(function(dstFileEntry) {\n\n                exports.write(function() {\n                    successCallback(dstFileEntry);\n                }, errorCallback, [dstFileEntry.file_.storagePath, srcFileEntry.file_.blob_, 0]);\n\n            }, errorCallback, [parentFullPath, name, {create: true}]);\n\n        }, errorCallback, [srcPath, null]);\n    };\n\n    exports.moveTo = function(successCallback, errorCallback, args) {\n        var srcPath = args[0];\n        //var parentFullPath = args[1];\n        //var name = args[2];\n\n        exports.copyTo(function (fileEntry) {\n\n            exports.remove(function () {\n                successCallback(fileEntry);\n            }, errorCallback, [srcPath]);\n\n        }, errorCallback, args);\n    };\n\n    exports.resolveLocalFileSystemURI = function(successCallback, errorCallback, args) {\n        var path = args[0];\n\n        // Ignore parameters\n        if (path.indexOf('?') !== -1) {\n            path = String(path).split(\"?\")[0];\n        }\n\n        // support for encodeURI\n        if (/\\%5/g.test(path)) {\n            path = decodeURI(path);\n        }\n\n        if (path.indexOf(pathsPrefix.dataDirectory) === 0) {\n            path = path.substring(pathsPrefix.dataDirectory.length - 1);\n\n            exports.requestFileSystem(function(fs) {\n                fs.root.getFile(path, {create: false}, successCallback, function() {\n                    fs.root.getDirectory(path, {create: false}, successCallback, errorCallback);\n                });\n            }, errorCallback, [LocalFileSystem.PERSISTENT]);\n        } else if (path.indexOf(pathsPrefix.cacheDirectory) === 0) {\n            path = path.substring(pathsPrefix.cacheDirectory.length - 1);\n\n            exports.requestFileSystem(function(fs) {\n                fs.root.getFile(path, {create: false}, successCallback, function() {\n                    fs.root.getDirectory(path, {create: false}, successCallback, errorCallback);\n                });\n            }, errorCallback, [LocalFileSystem.TEMPORARY]);\n        } else if (path.indexOf(pathsPrefix.applicationDirectory) === 0) {\n            path = path.substring(pathsPrefix.applicationDirectory.length);\n\n            var xhr = new XMLHttpRequest();\n            xhr.open(\"GET\", path, true);\n            xhr.onreadystatechange = function () {\n                if (xhr.status === 200 && xhr.readyState === 4) {\n                    exports.requestFileSystem(function(fs) {\n                        fs.name = location.hostname;\n                        fs.root.getFile(path, {create: true}, writeFile, errorCallback);\n                    }, errorCallback, [LocalFileSystem.PERSISTENT]);\n                }\n            };\n\n            xhr.onerror = function () {\n                if (errorCallback) {\n                    errorCallback(FileError.NOT_READABLE_ERR);\n                }\n            };\n\n            xhr.send();\n        } else {\n            if (errorCallback) {\n                errorCallback(FileError.NOT_FOUND_ERR);\n            }\n        }\n\n        function writeFile(entry) {\n            entry.createWriter(function (fileWriter) {\n                fileWriter.onwriteend = function (evt) {\n                    if (!evt.target.error) {\n                        entry.filesystemName = location.hostname;\n                        successCallback(entry);\n                    }\n                };\n                fileWriter.onerror = function () {\n                    if (errorCallback) {\n                        errorCallback(FileError.NOT_READABLE_ERR);\n                    }\n                };\n                fileWriter.write(new Blob([xhr.response]));\n            }, errorCallback);\n        }\n    };\n\n    exports.requestAllPaths = function(successCallback) {\n        successCallback(pathsPrefix);\n    };\n\n/*** Helpers ***/\n\n    /**\n     * Interface to wrap the native File interface.\n     *\n     * This interface is necessary for creating zero-length (empty) files,\n     * something the Filesystem API allows you to do. Unfortunately, File's\n     * constructor cannot be called directly, making it impossible to instantiate\n     * an empty File in JS.\n     *\n     * @param {Object} opts Initial values.\n     * @constructor\n     */\n    function MyFile(opts) {\n        var blob_ = new Blob();\n\n        this.size = opts.size || 0;\n        this.name = opts.name || '';\n        this.type = opts.type || '';\n        this.lastModifiedDate = opts.lastModifiedDate || null;\n        this.storagePath = opts.storagePath || '';\n\n        // Need some black magic to correct the object's size/name/type based on the\n        // blob that is saved.\n        Object.defineProperty(this, 'blob_', {\n            enumerable: true,\n            get: function() {\n                return blob_;\n            },\n            set: function(val) {\n                blob_ = val;\n                this.size = blob_.size;\n                this.name = blob_.name;\n                this.type = blob_.type;\n                this.lastModifiedDate = blob_.lastModifiedDate;\n            }.bind(this)\n        });\n    }\n\n    MyFile.prototype.constructor = MyFile;\n\n    // When saving an entry, the fullPath should always lead with a slash and never\n    // end with one (e.g. a directory). Also, resolve '.' and '..' to an absolute\n    // one. This method ensures path is legit!\n    function resolveToFullPath_(cwdFullPath, path) {\n        path = path || '';\n        var fullPath = path;\n        var prefix = '';\n\n        cwdFullPath = cwdFullPath || DIR_SEPARATOR;\n        if (cwdFullPath.indexOf(FILESYSTEM_PREFIX) === 0) {\n            prefix = cwdFullPath.substring(0, cwdFullPath.indexOf(DIR_SEPARATOR, FILESYSTEM_PREFIX.length));\n            cwdFullPath = cwdFullPath.substring(cwdFullPath.indexOf(DIR_SEPARATOR, FILESYSTEM_PREFIX.length));\n        }\n\n        var relativePath = path[0] !== DIR_SEPARATOR;\n        if (relativePath) {\n            fullPath = cwdFullPath;\n            if (cwdFullPath != DIR_SEPARATOR) {\n                fullPath += DIR_SEPARATOR + path;\n            } else {\n                fullPath += path;\n            }\n        }\n\n        // Adjust '..'s by removing parent directories when '..' flows in path.\n        var parts = fullPath.split(DIR_SEPARATOR);\n        for (var i = 0; i < parts.length; ++i) {\n            var part = parts[i];\n            if (part == '..') {\n                parts[i - 1] = '';\n                parts[i] = '';\n            }\n        }\n        fullPath = parts.filter(function(el) {\n            return el;\n        }).join(DIR_SEPARATOR);\n\n        // Add back in leading slash.\n        if (fullPath[0] !== DIR_SEPARATOR) {\n            fullPath = DIR_SEPARATOR + fullPath;\n        }\n\n        // Replace './' by current dir. ('./one/./two' -> one/two)\n        fullPath = fullPath.replace(/\\.\\//g, DIR_SEPARATOR);\n\n        // Replace '//' with '/'.\n        fullPath = fullPath.replace(/\\/\\//g, DIR_SEPARATOR);\n\n        // Replace '/.' with '/'.\n        fullPath = fullPath.replace(/\\/\\./g, DIR_SEPARATOR);\n\n        // Remove '/' if it appears on the end.\n        if (fullPath[fullPath.length - 1] == DIR_SEPARATOR &&\n            fullPath != DIR_SEPARATOR) {\n            fullPath = fullPath.substring(0, fullPath.length - 1);\n        }\n\n        return {\n            storagePath: prefix + fullPath,\n            fullPath: fullPath,\n            fileName: fullPath.split(DIR_SEPARATOR).pop(),\n            fsName: prefix.split(DIR_SEPARATOR).pop()\n        };\n    }\n\n    function fileEntryFromIdbEntry(fileEntry) {\n        // IDB won't save methods, so we need re-create the FileEntry.\n        var clonedFileEntry = new FileEntry(fileEntry.name, fileEntry.fullPath, fileEntry.fileSystem);\n        clonedFileEntry.file_ = fileEntry.file_;\n\n        return clonedFileEntry;\n    }\n\n    function readAs(what, fullPath, encoding, startPos, endPos, successCallback, errorCallback) {\n        exports.getFile(function(fileEntry) {\n            var fileReader = new FileReader(),\n                blob = fileEntry.file_.blob_.slice(startPos, endPos);\n\n            fileReader.onload = function(e) {\n                successCallback(e.target.result);\n            };\n\n            fileReader.onerror = errorCallback;\n\n            switch (what) {\n                case 'text':\n                    fileReader.readAsText(blob, encoding);\n                    break;\n                case 'dataURL':\n                    fileReader.readAsDataURL(blob);\n                    break;\n                case 'arrayBuffer':\n                    fileReader.readAsArrayBuffer(blob);\n                    break;\n                case 'binaryString':\n                    fileReader.readAsBinaryString(blob);\n                    break;\n            }\n\n        }, errorCallback, [fullPath, null]);\n    }\n\n/*** Core logic to handle IDB operations ***/\n\n    idb_.open = function(dbName, successCallback, errorCallback) {\n        var self = this;\n\n        // TODO: FF 12.0a1 isn't liking a db name with : in it.\n        var request = indexedDB.open(dbName.replace(':', '_')/*, 1 /*version*/);\n\n        request.onerror = errorCallback || onError;\n\n        request.onupgradeneeded = function(e) {\n            // First open was called or higher db version was used.\n\n            // console.log('onupgradeneeded: oldVersion:' + e.oldVersion,\n            //           'newVersion:' + e.newVersion);\n\n            self.db = e.target.result;\n            self.db.onerror = onError;\n\n            if (!self.db.objectStoreNames.contains(FILE_STORE_)) {\n                self.db.createObjectStore(FILE_STORE_/*,{keyPath: 'id', autoIncrement: true}*/);\n            }\n        };\n\n        request.onsuccess = function(e) {\n            self.db = e.target.result;\n            self.db.onerror = onError;\n            successCallback(e);\n        };\n\n        request.onblocked = errorCallback || onError;\n    };\n\n    idb_.close = function() {\n        this.db.close();\n        this.db = null;\n    };\n\n    idb_.get = function(fullPath, successCallback, errorCallback) {\n        if (!this.db) {\n            if (errorCallback) {\n                errorCallback(FileError.INVALID_MODIFICATION_ERR);\n            }\n            return;\n        }\n\n        var tx = this.db.transaction([FILE_STORE_], 'readonly');\n\n        //var request = tx.objectStore(FILE_STORE_).get(fullPath);\n        var range = IDBKeyRange.bound(fullPath, fullPath + DIR_OPEN_BOUND,\n            false, true);\n        var request = tx.objectStore(FILE_STORE_).get(range);\n\n        tx.onabort = errorCallback || onError;\n        tx.oncomplete = function(e) {\n            successCallback(request.result);\n        };\n    };\n\n    idb_.getAllEntries = function(fullPath, storagePath, successCallback, errorCallback) {\n        if (!this.db) {\n            if (errorCallback) {\n                errorCallback(FileError.INVALID_MODIFICATION_ERR);\n            }\n            return;\n        }\n\n        var results = [];\n\n        if (storagePath[storagePath.length - 1] === DIR_SEPARATOR) {\n            storagePath = storagePath.substring(0, storagePath.length - 1);\n        }\n\n        var range = IDBKeyRange.bound(\n                storagePath + DIR_SEPARATOR, storagePath + DIR_OPEN_BOUND, false, true);\n\n        var tx = this.db.transaction([FILE_STORE_], 'readonly');\n        tx.onabort = errorCallback || onError;\n        tx.oncomplete = function(e) {\n            results = results.filter(function(val) {\n                var valPartsLen = val.fullPath.split(DIR_SEPARATOR).length;\n                var fullPathPartsLen = fullPath.split(DIR_SEPARATOR).length;\n\n                if (fullPath === DIR_SEPARATOR && valPartsLen < fullPathPartsLen + 1) {\n                    // Hack to filter out entries in the root folder. This is inefficient\n                    // because reading the entires of fs.root (e.g. '/') returns ALL\n                    // results in the database, then filters out the entries not in '/'.\n                    return val;\n                } else if (fullPath !== DIR_SEPARATOR &&\n                    valPartsLen === fullPathPartsLen + 1) {\n                    // If this a subfolder and entry is a direct child, include it in\n                    // the results. Otherwise, it's not an entry of this folder.\n                    return val;\n                }\n            });\n\n            successCallback(results);\n        };\n\n        var request = tx.objectStore(FILE_STORE_).openCursor(range);\n\n        request.onsuccess = function(e) {\n            var cursor = e.target.result;\n            if (cursor) {\n                var val = cursor.value;\n\n                results.push(val.isFile ? fileEntryFromIdbEntry(val) : new DirectoryEntry(val.name, val.fullPath, val.fileSystem));\n                cursor['continue']();\n            }\n        };\n    };\n\n    idb_['delete'] = function(fullPath, successCallback, errorCallback) {\n        if (!this.db) {\n            if (errorCallback) {\n                errorCallback(FileError.INVALID_MODIFICATION_ERR);\n            }\n            return;\n        }\n\n        var tx = this.db.transaction([FILE_STORE_], 'readwrite');\n        tx.oncomplete = successCallback;\n        tx.onabort = errorCallback || onError;\n\n        //var request = tx.objectStore(FILE_STORE_).delete(fullPath);\n        var range = IDBKeyRange.bound(\n            fullPath, fullPath + DIR_OPEN_BOUND, false, true);\n        tx.objectStore(FILE_STORE_)['delete'](range);\n    };\n\n    idb_.put = function(entry, storagePath, successCallback, errorCallback) {\n        if (!this.db) {\n            if (errorCallback) {\n                errorCallback(FileError.INVALID_MODIFICATION_ERR);\n            }\n            return;\n        }\n\n        var tx = this.db.transaction([FILE_STORE_], 'readwrite');\n        tx.onabort = errorCallback || onError;\n        tx.oncomplete = function(e) {\n            // TODO: Error is thrown if we pass the request event back instead.\n            successCallback(entry);\n        };\n\n        tx.objectStore(FILE_STORE_).put(entry, storagePath);\n    };\n\n    // Global error handler. Errors bubble from request, to transaction, to db.\n    function onError(e) {\n        switch (e.target.errorCode) {\n            case 12:\n                console.log('Error - Attempt to open db with a lower version than the ' +\n                    'current one.');\n                break;\n            default:\n                console.log('errorCode: ' + e.target.errorCode);\n        }\n\n        console.log(e, e.code, e.message);\n    }\n\n// Clean up.\n// TODO: Is there a place for this?\n//    global.addEventListener('beforeunload', function(e) {\n//        idb_.db && idb_.db.close();\n//    }, false);\n\n})(module.exports, window);\n\nrequire(\"cordova/exec/proxy\").add(\"File\", module.exports);\n"
  },
  {
    "path": "plugins/cordova-plugin-file/src/ios/CDVAssetLibraryFilesystem.h",
    "content": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements.  See the NOTICE file\n distributed with this work for additional information\n regarding copyright ownership.  The ASF licenses this file\n to you under the Apache License, Version 2.0 (the\n \"License\"); you may not use this file except in compliance\n with the License.  You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an\n \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n KIND, either express or implied.  See the License for the\n specific language governing permissions and limitations\n under the License.\n */\n\n#import \"CDVFile.h\"\n\nextern NSString* const kCDVAssetsLibraryPrefix;\nextern NSString* const kCDVAssetsLibraryScheme;\n\n@interface CDVAssetLibraryFilesystem : NSObject<CDVFileSystem> {\n}\n\n- (id) initWithName:(NSString *)name;\n\n@end\n"
  },
  {
    "path": "plugins/cordova-plugin-file/src/ios/CDVAssetLibraryFilesystem.m",
    "content": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements.  See the NOTICE file\n distributed with this work for additional information\n regarding copyright ownership.  The ASF licenses this file\n to you under the Apache License, Version 2.0 (the\n \"License\"); you may not use this file except in compliance\n with the License.  You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an\n \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n KIND, either express or implied.  See the License for the\n specific language governing permissions and limitations\n under the License.\n */\n\n#import \"CDVFile.h\"\n#import \"CDVAssetLibraryFilesystem.h\"\n#import <Cordova/CDV.h>\n#import <AssetsLibrary/ALAsset.h>\n#import <AssetsLibrary/ALAssetRepresentation.h>\n#import <AssetsLibrary/ALAssetsLibrary.h>\n#import <MobileCoreServices/MobileCoreServices.h>\n\nNSString* const kCDVAssetsLibraryPrefix = @\"assets-library://\";\nNSString* const kCDVAssetsLibraryScheme = @\"assets-library\";\n\n@implementation CDVAssetLibraryFilesystem\n@synthesize name=_name, urlTransformer;\n\n\n/*\n The CDVAssetLibraryFilesystem works with resources which are identified\n by iOS as\n   asset-library://<path>\n and represents them internally as URLs of the form\n   cdvfile://localhost/assets-library/<path>\n */\n\n- (NSURL *)assetLibraryURLForLocalURL:(CDVFilesystemURL *)url\n{\n    if ([url.url.scheme isEqualToString:kCDVFilesystemURLPrefix]) {\n        NSString *path = [[url.url absoluteString] substringFromIndex:[@\"cdvfile://localhost/assets-library\" length]];\n        return [NSURL URLWithString:[NSString stringWithFormat:@\"assets-library:/%@\", path]];\n    }\n    return url.url;\n}\n\n- (CDVPluginResult *)entryForLocalURI:(CDVFilesystemURL *)url\n{\n    NSDictionary* entry = [self makeEntryForLocalURL:url];\n    return [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:entry];\n}\n\n- (NSDictionary *)makeEntryForLocalURL:(CDVFilesystemURL *)url {\n    return [self makeEntryForPath:url.fullPath isDirectory:NO];\n}\n\n- (NSDictionary*)makeEntryForPath:(NSString*)fullPath isDirectory:(BOOL)isDir\n{\n    NSMutableDictionary* dirEntry = [NSMutableDictionary dictionaryWithCapacity:5];\n    NSString* lastPart = [fullPath lastPathComponent];\n    if (isDir && ![fullPath hasSuffix:@\"/\"]) {\n        fullPath = [fullPath stringByAppendingString:@\"/\"];\n    }\n    [dirEntry setObject:[NSNumber numberWithBool:!isDir]  forKey:@\"isFile\"];\n    [dirEntry setObject:[NSNumber numberWithBool:isDir]  forKey:@\"isDirectory\"];\n    [dirEntry setObject:fullPath forKey:@\"fullPath\"];\n    [dirEntry setObject:lastPart forKey:@\"name\"];\n    [dirEntry setObject:self.name forKey: @\"filesystemName\"];\n\n    NSURL* nativeURL = [NSURL URLWithString:[NSString stringWithFormat:@\"assets-library:/%@\",fullPath]];\n    if (self.urlTransformer) {\n        nativeURL = self.urlTransformer(nativeURL);\n    }\n    dirEntry[@\"nativeURL\"] = [nativeURL absoluteString];\n\n    return dirEntry;\n}\n\n/* helper function to get the mimeType from the file extension\n * IN:\n *\tNSString* fullPath - filename (may include path)\n * OUT:\n *\tNSString* the mime type as type/subtype.  nil if not able to determine\n */\n+ (NSString*)getMimeTypeFromPath:(NSString*)fullPath\n{\n    NSString* mimeType = nil;\n\n    if (fullPath) {\n        CFStringRef typeId = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)[fullPath pathExtension], NULL);\n        if (typeId) {\n            mimeType = (__bridge_transfer NSString*)UTTypeCopyPreferredTagWithClass(typeId, kUTTagClassMIMEType);\n            if (!mimeType) {\n                // special case for m4a\n                if ([(__bridge NSString*)typeId rangeOfString : @\"m4a-audio\"].location != NSNotFound) {\n                    mimeType = @\"audio/mp4\";\n                } else if ([[fullPath pathExtension] rangeOfString:@\"wav\"].location != NSNotFound) {\n                    mimeType = @\"audio/wav\";\n                } else if ([[fullPath pathExtension] rangeOfString:@\"css\"].location != NSNotFound) {\n                    mimeType = @\"text/css\";\n                }\n            }\n            CFRelease(typeId);\n        }\n    }\n    return mimeType;\n}\n\n- (id)initWithName:(NSString *)name\n{\n    if (self) {\n        self.name = name;\n    }\n    return self;\n}\n\n- (CDVPluginResult *)getFileForURL:(CDVFilesystemURL *)baseURI requestedPath:(NSString *)requestedPath options:(NSDictionary *)options\n{\n    // return unsupported result for assets-library URLs\n   return [CDVPluginResult resultWithStatus:CDVCommandStatus_MALFORMED_URL_EXCEPTION messageAsString:@\"getFile not supported for assets-library URLs.\"];\n}\n\n- (CDVPluginResult*)getParentForURL:(CDVFilesystemURL *)localURI\n{\n    // we don't (yet?) support getting the parent of an asset\n    return [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_READABLE_ERR];\n}\n\n- (CDVPluginResult*)setMetadataForURL:(CDVFilesystemURL *)localURI withObject:(NSDictionary *)options\n{\n    // setMetadata doesn't make sense for asset library files\n    return [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];\n}\n\n- (CDVPluginResult *)removeFileAtURL:(CDVFilesystemURL *)localURI\n{\n    // return error for assets-library URLs\n    return [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:INVALID_MODIFICATION_ERR];\n}\n\n- (CDVPluginResult *)recursiveRemoveFileAtURL:(CDVFilesystemURL *)localURI\n{\n    // return error for assets-library URLs\n    return [CDVPluginResult resultWithStatus:CDVCommandStatus_MALFORMED_URL_EXCEPTION messageAsString:@\"removeRecursively not supported for assets-library URLs.\"];\n}\n\n- (CDVPluginResult *)readEntriesAtURL:(CDVFilesystemURL *)localURI\n{\n    // return unsupported result for assets-library URLs\n    return [CDVPluginResult resultWithStatus:CDVCommandStatus_MALFORMED_URL_EXCEPTION messageAsString:@\"readEntries not supported for assets-library URLs.\"];\n}\n\n- (CDVPluginResult *)truncateFileAtURL:(CDVFilesystemURL *)localURI atPosition:(unsigned long long)pos\n{\n    // assets-library files can't be truncated\n    return [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NO_MODIFICATION_ALLOWED_ERR];\n}\n\n- (CDVPluginResult *)writeToFileAtURL:(CDVFilesystemURL *)localURL withData:(NSData*)encData append:(BOOL)shouldAppend\n{\n    // text can't be written into assets-library files\n    return [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NO_MODIFICATION_ALLOWED_ERR];\n}\n\n- (void)copyFileToURL:(CDVFilesystemURL *)destURL withName:(NSString *)newName fromFileSystem:(NSObject<CDVFileSystem> *)srcFs atURL:(CDVFilesystemURL *)srcURL copy:(BOOL)bCopy callback:(void (^)(CDVPluginResult *))callback\n{\n    // Copying to an assets library file is not doable, since we can't write it.\n    CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:INVALID_MODIFICATION_ERR];\n    callback(result);\n}\n\n- (NSString *)filesystemPathForURL:(CDVFilesystemURL *)url\n{\n    NSString *path = nil;\n    if ([[url.url scheme] isEqualToString:kCDVAssetsLibraryScheme]) {\n        path = [url.url path];\n    } else {\n       path = url.fullPath;\n    }\n    if ([path hasSuffix:@\"/\"]) {\n      path = [path substringToIndex:([path length]-1)];\n    }\n    return path;\n}\n\n- (void)readFileAtURL:(CDVFilesystemURL *)localURL start:(NSInteger)start end:(NSInteger)end callback:(void (^)(NSData*, NSString* mimeType, CDVFileError))callback\n{\n    ALAssetsLibraryAssetForURLResultBlock resultBlock = ^(ALAsset* asset) {\n        if (asset) {\n            // We have the asset!  Get the data and send it off.\n            ALAssetRepresentation* assetRepresentation = [asset defaultRepresentation];\n            NSUInteger size = (end > start) ? (end - start) : [assetRepresentation size];\n            Byte* buffer = (Byte*)malloc(size);\n            NSUInteger bufferSize = [assetRepresentation getBytes:buffer fromOffset:start length:size error:nil];\n            NSData* data = [NSData dataWithBytesNoCopy:buffer length:bufferSize freeWhenDone:YES];\n            NSString* MIMEType = (__bridge_transfer NSString*)UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)[assetRepresentation UTI], kUTTagClassMIMEType);\n\n            callback(data, MIMEType, NO_ERROR);\n        } else {\n            callback(nil, nil, NOT_FOUND_ERR);\n        }\n    };\n\n    ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError* error) {\n        // Retrieving the asset failed for some reason.  Send the appropriate error.\n        NSLog(@\"Error: %@\", error);\n        callback(nil, nil, SECURITY_ERR);\n    };\n\n    ALAssetsLibrary* assetsLibrary = [[ALAssetsLibrary alloc] init];\n    [assetsLibrary assetForURL:[self assetLibraryURLForLocalURL:localURL] resultBlock:resultBlock failureBlock:failureBlock];\n}\n\n- (void)getFileMetadataForURL:(CDVFilesystemURL *)localURL callback:(void (^)(CDVPluginResult *))callback\n{\n    // In this case, we need to use an asynchronous method to retrieve the file.\n    // Because of this, we can't just assign to `result` and send it at the end of the method.\n    // Instead, we return after calling the asynchronous method and send `result` in each of the blocks.\n    ALAssetsLibraryAssetForURLResultBlock resultBlock = ^(ALAsset* asset) {\n        if (asset) {\n            // We have the asset!  Populate the dictionary and send it off.\n            NSMutableDictionary* fileInfo = [NSMutableDictionary dictionaryWithCapacity:5];\n            ALAssetRepresentation* assetRepresentation = [asset defaultRepresentation];\n            [fileInfo setObject:[NSNumber numberWithUnsignedLongLong:[assetRepresentation size]] forKey:@\"size\"];\n            [fileInfo setObject:localURL.fullPath forKey:@\"fullPath\"];\n            NSString* filename = [assetRepresentation filename];\n            [fileInfo setObject:filename forKey:@\"name\"];\n            [fileInfo setObject:[CDVAssetLibraryFilesystem getMimeTypeFromPath:filename] forKey:@\"type\"];\n            NSDate* creationDate = [asset valueForProperty:ALAssetPropertyDate];\n            NSNumber* msDate = [NSNumber numberWithDouble:[creationDate timeIntervalSince1970] * 1000];\n            [fileInfo setObject:msDate forKey:@\"lastModifiedDate\"];\n\n            callback([CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:fileInfo]);\n        } else {\n            // We couldn't find the asset.  Send the appropriate error.\n            callback([CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_FOUND_ERR]);\n        }\n    };\n    ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError* error) {\n        // Retrieving the asset failed for some reason.  Send the appropriate error.\n        callback([CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsString:[error localizedDescription]]);\n    };\n\n    ALAssetsLibrary* assetsLibrary = [[ALAssetsLibrary alloc] init];\n    [assetsLibrary assetForURL:[self assetLibraryURLForLocalURL:localURL] resultBlock:resultBlock failureBlock:failureBlock];\n    return;\n}\n@end\n"
  },
  {
    "path": "plugins/cordova-plugin-file/src/ios/CDVFile.h",
    "content": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements.  See the NOTICE file\n distributed with this work for additional information\n regarding copyright ownership.  The ASF licenses this file\n to you under the Apache License, Version 2.0 (the\n \"License\"); you may not use this file except in compliance\n with the License.  You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an\n \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n KIND, either express or implied.  See the License for the\n specific language governing permissions and limitations\n under the License.\n */\n\n#import <Foundation/Foundation.h>\n#import <Cordova/CDVPlugin.h>\n\nNSString* const kCDVAssetsLibraryPrefix;\nNSString* const kCDVFilesystemURLPrefix;\n\nenum CDVFileError {\n    NO_ERROR = 0,\n    NOT_FOUND_ERR = 1,\n    SECURITY_ERR = 2,\n    ABORT_ERR = 3,\n    NOT_READABLE_ERR = 4,\n    ENCODING_ERR = 5,\n    NO_MODIFICATION_ALLOWED_ERR = 6,\n    INVALID_STATE_ERR = 7,\n    SYNTAX_ERR = 8,\n    INVALID_MODIFICATION_ERR = 9,\n    QUOTA_EXCEEDED_ERR = 10,\n    TYPE_MISMATCH_ERR = 11,\n    PATH_EXISTS_ERR = 12\n};\ntypedef int CDVFileError;\n\n@interface CDVFilesystemURL : NSObject  {\n    NSURL *_url;\n    NSString *_fileSystemName;\n    NSString *_fullPath;\n}\n\n- (id) initWithString:(NSString*)strURL;\n- (id) initWithURL:(NSURL*)URL;\n+ (CDVFilesystemURL *)fileSystemURLWithString:(NSString *)strURL;\n+ (CDVFilesystemURL *)fileSystemURLWithURL:(NSURL *)URL;\n\n- (NSString *)absoluteURL;\n\n@property (atomic) NSURL *url;\n@property (atomic) NSString *fileSystemName;\n@property (atomic) NSString *fullPath;\n\n@end\n\n@interface CDVFilesystemURLProtocol : NSURLProtocol\n@end\n\n@protocol CDVFileSystem\n- (CDVPluginResult *)entryForLocalURI:(CDVFilesystemURL *)url;\n- (CDVPluginResult *)getFileForURL:(CDVFilesystemURL *)baseURI requestedPath:(NSString *)requestedPath options:(NSDictionary *)options;\n- (CDVPluginResult *)getParentForURL:(CDVFilesystemURL *)localURI;\n- (CDVPluginResult *)setMetadataForURL:(CDVFilesystemURL *)localURI withObject:(NSDictionary *)options;\n- (CDVPluginResult *)removeFileAtURL:(CDVFilesystemURL *)localURI;\n- (CDVPluginResult *)recursiveRemoveFileAtURL:(CDVFilesystemURL *)localURI;\n- (CDVPluginResult *)readEntriesAtURL:(CDVFilesystemURL *)localURI;\n- (CDVPluginResult *)truncateFileAtURL:(CDVFilesystemURL *)localURI atPosition:(unsigned long long)pos;\n- (CDVPluginResult *)writeToFileAtURL:(CDVFilesystemURL *)localURL withData:(NSData*)encData append:(BOOL)shouldAppend;\n- (void)copyFileToURL:(CDVFilesystemURL *)destURL withName:(NSString *)newName fromFileSystem:(NSObject<CDVFileSystem> *)srcFs atURL:(CDVFilesystemURL *)srcURL copy:(BOOL)bCopy callback:(void (^)(CDVPluginResult *))callback;\n- (void)readFileAtURL:(CDVFilesystemURL *)localURL start:(NSInteger)start end:(NSInteger)end callback:(void (^)(NSData*, NSString* mimeType, CDVFileError))callback;\n- (void)getFileMetadataForURL:(CDVFilesystemURL *)localURL callback:(void (^)(CDVPluginResult *))callback;\n\n- (NSDictionary *)makeEntryForLocalURL:(CDVFilesystemURL *)url;\n- (NSDictionary*)makeEntryForPath:(NSString*)fullPath isDirectory:(BOOL)isDir;\n\n@property (nonatomic,strong) NSString *name;\n@property (nonatomic, copy) NSURL*(^urlTransformer)(NSURL*);\n\n@optional\n- (NSString *)filesystemPathForURL:(CDVFilesystemURL *)localURI;\n- (CDVFilesystemURL *)URLforFilesystemPath:(NSString *)path;\n\n@end\n\n@interface CDVFile : CDVPlugin {\n    NSString* rootDocsPath;\n    NSString* appDocsPath;\n    NSString* appLibraryPath;\n    NSString* appTempPath;\n\n    NSMutableArray* fileSystems_;\n    BOOL userHasAllowed;\n}\n\n- (NSNumber*)checkFreeDiskSpace:(NSString*)appPath;\n- (NSDictionary*)makeEntryForPath:(NSString*)fullPath fileSystemName:(NSString *)fsName isDirectory:(BOOL)isDir;\n- (NSDictionary *)makeEntryForURL:(NSURL *)URL;\n- (CDVFilesystemURL *)fileSystemURLforLocalPath:(NSString *)localPath;\n\n- (NSObject<CDVFileSystem> *)filesystemForURL:(CDVFilesystemURL *)localURL;\n\n/* Native Registration API */\n- (void)registerFilesystem:(NSObject<CDVFileSystem> *)fs;\n- (NSObject<CDVFileSystem> *)fileSystemByName:(NSString *)fsName;\n\n/* Exec API */\n- (void)requestFileSystem:(CDVInvokedUrlCommand*)command;\n- (void)resolveLocalFileSystemURI:(CDVInvokedUrlCommand*)command;\n- (void)getDirectory:(CDVInvokedUrlCommand*)command;\n- (void)getFile:(CDVInvokedUrlCommand*)command;\n- (void)getParent:(CDVInvokedUrlCommand*)command;\n- (void)removeRecursively:(CDVInvokedUrlCommand*)command;\n- (void)remove:(CDVInvokedUrlCommand*)command;\n- (void)copyTo:(CDVInvokedUrlCommand*)command;\n- (void)moveTo:(CDVInvokedUrlCommand*)command;\n- (void)getFileMetadata:(CDVInvokedUrlCommand*)command;\n- (void)readEntries:(CDVInvokedUrlCommand*)command;\n- (void)readAsText:(CDVInvokedUrlCommand*)command;\n- (void)readAsDataURL:(CDVInvokedUrlCommand*)command;\n- (void)readAsArrayBuffer:(CDVInvokedUrlCommand*)command;\n- (void)write:(CDVInvokedUrlCommand*)command;\n- (void)testFileExists:(CDVInvokedUrlCommand*)command;\n- (void)testDirectoryExists:(CDVInvokedUrlCommand*)command;\n- (void)getFreeDiskSpace:(CDVInvokedUrlCommand*)command;\n- (void)truncate:(CDVInvokedUrlCommand*)command;\n- (void)doCopyMove:(CDVInvokedUrlCommand*)command isCopy:(BOOL)bCopy;\n\n/* Compatibilty with older File API */\n- (NSString*)getMimeTypeFromPath:(NSString*)fullPath;\n- (NSDictionary *)getDirectoryEntry:(NSString *)target isDirectory:(BOOL)bDirRequest;\n\n/* Conversion between filesystem paths and URLs */\n- (NSString *)filesystemPathForURL:(CDVFilesystemURL *)URL;\n\n/* Internal methods for testing */\n- (void)_getLocalFilesystemPath:(CDVInvokedUrlCommand*)command;\n\n@property (nonatomic, strong) NSString* rootDocsPath;\n@property (nonatomic, strong) NSString* appDocsPath;\n@property (nonatomic, strong) NSString* appLibraryPath;\n@property (nonatomic, strong) NSString* appTempPath;\n@property (nonatomic, strong) NSString* persistentPath;\n@property (nonatomic, strong) NSString* temporaryPath;\n@property (nonatomic, strong) NSMutableArray* fileSystems;\n\n@property BOOL userHasAllowed;\n\n@end\n\n#define kW3FileTemporary @\"temporary\"\n#define kW3FilePersistent @\"persistent\"\n"
  },
  {
    "path": "plugins/cordova-plugin-file/src/ios/CDVFile.m",
    "content": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements.  See the NOTICE file\n distributed with this work for additional information\n regarding copyright ownership.  The ASF licenses this file\n to you under the Apache License, Version 2.0 (the\n \"License\"); you may not use this file except in compliance\n with the License.  You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an\n \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n KIND, either express or implied.  See the License for the\n specific language governing permissions and limitations\n under the License.\n */\n\n#import <Cordova/CDV.h>\n#import \"CDVFile.h\"\n#import \"CDVLocalFilesystem.h\"\n#import \"CDVAssetLibraryFilesystem.h\"\n#import <objc/message.h>\n\nstatic NSString* toBase64(NSData* data) {\n    SEL s1 = NSSelectorFromString(@\"cdv_base64EncodedString\");\n    SEL s2 = NSSelectorFromString(@\"base64EncodedString\");\n    SEL s3 = NSSelectorFromString(@\"base64EncodedStringWithOptions:\");\n    \n    if ([data respondsToSelector:s1]) {\n        NSString* (*func)(id, SEL) = (void *)[data methodForSelector:s1];\n        return func(data, s1);\n    } else if ([data respondsToSelector:s2]) {\n        NSString* (*func)(id, SEL) = (void *)[data methodForSelector:s2];\n        return func(data, s2);\n    } else if ([data respondsToSelector:s3]) {\n        NSString* (*func)(id, SEL, NSUInteger) = (void *)[data methodForSelector:s3];\n        return func(data, s3, 0);\n    } else {\n        return nil;\n    }\n}\n\nCDVFile *filePlugin = nil;\n\nextern NSString * const NSURLIsExcludedFromBackupKey __attribute__((weak_import));\n\n#ifndef __IPHONE_5_1\n    NSString* const NSURLIsExcludedFromBackupKey = @\"NSURLIsExcludedFromBackupKey\";\n#endif\n\nNSString* const kCDVFilesystemURLPrefix = @\"cdvfile\";\n\n@implementation CDVFilesystemURL\n@synthesize url=_url;\n@synthesize fileSystemName=_fileSystemName;\n@synthesize fullPath=_fullPath;\n\n- (id) initWithString:(NSString *)strURL\n{\n    if ( self = [super init] ) {\n        NSURL *decodedURL = [NSURL URLWithString:strURL];\n        return [self initWithURL:decodedURL];\n    }\n    return nil;\n}\n\n-(id) initWithURL:(NSURL *)URL\n{\n    if ( self = [super init] ) {\n        self.url = URL;\n        self.fileSystemName = [self filesystemNameForLocalURI:URL];\n        self.fullPath = [self fullPathForLocalURI:URL];\n    }\n    return self;\n}\n\n/*\n * IN\n *  NSString localURI\n * OUT\n *  NSString FileSystem Name for this URI, or nil if it is not recognized.\n */\n- (NSString *)filesystemNameForLocalURI:(NSURL *)uri\n{\n    if ([[uri scheme] isEqualToString:kCDVFilesystemURLPrefix] && [[uri host] isEqualToString:@\"localhost\"]) {\n        NSArray *pathComponents = [uri pathComponents];\n        if (pathComponents != nil && pathComponents.count > 1) {\n            return [pathComponents objectAtIndex:1];\n        }\n    } else if ([[uri scheme] isEqualToString:kCDVAssetsLibraryScheme]) {\n        return @\"assets-library\";\n    }\n    return nil;\n}\n\n/*\n * IN\n *  NSString localURI\n * OUT\n *  NSString fullPath component suitable for an Entry object.\n * The incoming URI should be properly escaped. The returned fullPath is unescaped.\n */\n- (NSString *)fullPathForLocalURI:(NSURL *)uri\n{\n    if ([[uri scheme] isEqualToString:kCDVFilesystemURLPrefix] && [[uri host] isEqualToString:@\"localhost\"]) {\n        NSString *path = [uri path];\n        if ([uri query]) {\n            path = [NSString stringWithFormat:@\"%@?%@\", path, [uri query]];\n        }\n        NSRange slashRange = [path rangeOfString:@\"/\" options:0 range:NSMakeRange(1, path.length-1)];\n        if (slashRange.location == NSNotFound) {\n            return @\"\";\n        }\n        return [path substringFromIndex:slashRange.location];\n    } else if ([[uri scheme] isEqualToString:kCDVAssetsLibraryScheme]) {\n        return [[uri absoluteString] substringFromIndex:[kCDVAssetsLibraryScheme length]+2];\n    }\n    return nil;\n}\n\n+ (CDVFilesystemURL *)fileSystemURLWithString:(NSString *)strURL\n{\n    return [[CDVFilesystemURL alloc] initWithString:strURL];\n}\n\n+ (CDVFilesystemURL *)fileSystemURLWithURL:(NSURL *)URL\n{\n    return [[CDVFilesystemURL alloc] initWithURL:URL];\n}\n\n- (NSString *)absoluteURL\n{\n    return [NSString stringWithFormat:@\"cdvfile://localhost/%@%@\", self.fileSystemName, self.fullPath];\n}\n\n@end\n\n@implementation CDVFilesystemURLProtocol\n\n+ (BOOL)canInitWithRequest:(NSURLRequest*)request\n{\n    NSURL* url = [request URL];\n    return [[url scheme] isEqualToString:kCDVFilesystemURLPrefix];\n}\n\n+ (NSURLRequest*)canonicalRequestForRequest:(NSURLRequest*)request\n{\n    return request;\n}\n\n+ (BOOL)requestIsCacheEquivalent:(NSURLRequest*)requestA toRequest:(NSURLRequest*)requestB\n{\n    return [[[requestA URL] resourceSpecifier] isEqualToString:[[requestB URL] resourceSpecifier]];\n}\n\n- (void)startLoading\n{\n    CDVFilesystemURL* url = [CDVFilesystemURL fileSystemURLWithURL:[[self request] URL]];\n    NSObject<CDVFileSystem> *fs = [filePlugin filesystemForURL:url];\n    __weak CDVFilesystemURLProtocol* weakSelf = self;\n    \n    [fs readFileAtURL:url start:0 end:-1 callback:^void(NSData *data, NSString *mimetype, CDVFileError error) {\n        NSMutableDictionary* responseHeaders = [[NSMutableDictionary alloc] init];\n        responseHeaders[@\"Cache-Control\"] = @\"no-cache\";\n\n        if (!error) {\n            responseHeaders[@\"Content-Type\"] = mimetype;\n            NSURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:url.url statusCode:200 HTTPVersion:@\"HTTP/1.1\"headerFields:responseHeaders];\n            [[weakSelf client] URLProtocol:weakSelf didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];\n            [[weakSelf client] URLProtocol:weakSelf didLoadData:data];\n            [[weakSelf client] URLProtocolDidFinishLoading:weakSelf];\n        } else {\n            NSURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:url.url statusCode:404 HTTPVersion:@\"HTTP/1.1\"headerFields:responseHeaders];\n            [[weakSelf client] URLProtocol:weakSelf didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];\n            [[weakSelf client] URLProtocolDidFinishLoading:weakSelf];\n        }\n    }];\n}\n\n- (void)stopLoading\n{}\n\n- (NSCachedURLResponse *)connection:(NSURLConnection *)connection\n                  willCacheResponse:(NSCachedURLResponse*)cachedResponse {\n    return nil;\n}\n\n@end\n\n\n@implementation CDVFile\n\n@synthesize rootDocsPath, appDocsPath, appLibraryPath, appTempPath, userHasAllowed, fileSystems=fileSystems_;\n\n- (void)registerFilesystem:(NSObject<CDVFileSystem> *)fs {\n    __weak CDVFile* weakSelf = self;\n    SEL sel = NSSelectorFromString(@\"urlTransformer\");\n    // for backwards compatibility - we check if this property is there\n    // we create a wrapper block because the urlTransformer property\n    // on the commandDelegate might be set dynamically at a future time\n    // (and not dependent on plugin loading order)\n    if ([self.commandDelegate respondsToSelector:sel]) {\n        fs.urlTransformer = ^NSURL*(NSURL* urlToTransform) {\n            // grab the block from the commandDelegate\n            NSURL* (^urlTransformer)(NSURL*) = ((id(*)(id, SEL))objc_msgSend)(weakSelf.commandDelegate, sel);\n            // if block is not null, we call it\n            if (urlTransformer) {\n                return urlTransformer(urlToTransform);\n            } else { // else we return the same url\n                return urlToTransform;\n            }\n        };\n    }\n    [fileSystems_ addObject:fs];\n}\n\n- (NSObject<CDVFileSystem> *)fileSystemByName:(NSString *)fsName\n{\n    if (self.fileSystems != nil) {\n        for (NSObject<CDVFileSystem> *fs in self.fileSystems) {\n            if ([fs.name isEqualToString:fsName]) {\n                return fs;\n            }\n        }\n    }\n    return nil;\n}\n\n- (NSObject<CDVFileSystem> *)filesystemForURL:(CDVFilesystemURL *)localURL {\n    if (localURL.fileSystemName == nil) return nil;\n    @try {\n        return [self fileSystemByName:localURL.fileSystemName];\n    }\n    @catch (NSException *e) {\n        return nil;\n    }\n}\n\n- (NSArray *)getExtraFileSystemsPreference:(UIViewController *)vc\n{\n    NSString *filesystemsStr = nil;\n    if([self.viewController isKindOfClass:[CDVViewController class]]) {\n        CDVViewController *vc = (CDVViewController *)self.viewController;\n        NSDictionary *settings = [vc settings];\n        filesystemsStr = [settings[@\"iosextrafilesystems\"] lowercaseString];\n    }\n    if (!filesystemsStr) {\n        filesystemsStr = @\"library,library-nosync,documents,documents-nosync,cache,bundle,root\";\n    }\n    return [filesystemsStr componentsSeparatedByString:@\",\"];\n}\n\n- (void)makeNonSyncable:(NSString*)path {\n    [[NSFileManager defaultManager] createDirectoryAtPath:path\n              withIntermediateDirectories:YES\n                               attributes:nil\n                                    error:nil];\n    NSURL* url = [NSURL fileURLWithPath:path];\n    [url setResourceValue: [NSNumber numberWithBool: YES]\n                   forKey: NSURLIsExcludedFromBackupKey error:nil];\n\n}\n\n- (void)registerExtraFileSystems:(NSArray *)filesystems fromAvailableSet:(NSDictionary *)availableFileSystems\n{\n    NSMutableSet *installedFilesystems = [[NSMutableSet alloc] initWithCapacity:7];\n\n    /* Build non-syncable directories as necessary */\n    for (NSString *nonSyncFS in @[@\"library-nosync\", @\"documents-nosync\"]) {\n        if ([filesystems containsObject:nonSyncFS]) {\n            [self makeNonSyncable:availableFileSystems[nonSyncFS]];\n        }\n    }\n\n    /* Register filesystems in order */\n    for (NSString *fsName in filesystems) {\n        if (![installedFilesystems containsObject:fsName]) {\n            NSString *fsRoot = availableFileSystems[fsName];\n            if (fsRoot) {\n                [filePlugin registerFilesystem:[[CDVLocalFilesystem alloc] initWithName:fsName root:fsRoot]];\n                [installedFilesystems addObject:fsName];\n            } else {\n                NSLog(@\"Unrecognized extra filesystem identifier: %@\", fsName);\n            }\n        }\n    }\n}\n\n- (NSDictionary *)getAvailableFileSystems\n{\n    NSString *libPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0];\n    NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];\n    return @{\n        @\"library\": libPath,\n        @\"library-nosync\": [libPath stringByAppendingPathComponent:@\"NoCloud\"],\n        @\"documents\": docPath,\n        @\"documents-nosync\": [docPath stringByAppendingPathComponent:@\"NoCloud\"],\n        @\"cache\": [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0],\n        @\"bundle\": [[NSBundle mainBundle] bundlePath],\n        @\"root\": @\"/\"\n    };\n}\n\n- (void)pluginInitialize\n{\n    filePlugin = self;\n    [NSURLProtocol registerClass:[CDVFilesystemURLProtocol class]];\n\n    fileSystems_ = [[NSMutableArray alloc] initWithCapacity:3];\n\n    // Get the Library directory path\n    NSArray* paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);\n    self.appLibraryPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@\"files\"];\n\n    // Get the Temporary directory path\n    self.appTempPath = [NSTemporaryDirectory()stringByStandardizingPath];   // remove trailing slash from NSTemporaryDirectory()\n\n    // Get the Documents directory path\n    paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);\n    self.rootDocsPath = [paths objectAtIndex:0];\n    self.appDocsPath = [self.rootDocsPath stringByAppendingPathComponent:@\"files\"];\n\n\n    NSString *location = nil;\n    if([self.viewController isKindOfClass:[CDVViewController class]]) {\n        CDVViewController *vc = (CDVViewController *)self.viewController;\n        NSMutableDictionary *settings = vc.settings;\n        location = [[settings objectForKey:@\"iospersistentfilelocation\"] lowercaseString];\n    }\n    if (location == nil) {\n        // Compatibilty by default (if the config preference is not set, or\n        // if we're not embedded in a CDVViewController somehow.)\n        location = @\"compatibility\";\n    }\n\n    NSError *error;\n    if ([[NSFileManager defaultManager] createDirectoryAtPath:self.appTempPath\n                                  withIntermediateDirectories:YES\n                                                   attributes:nil\n                                                        error:&error]) {\n        [self registerFilesystem:[[CDVLocalFilesystem alloc] initWithName:@\"temporary\" root:self.appTempPath]];\n    } else {\n        NSLog(@\"Unable to create temporary directory: %@\", error);\n    }\n    if ([location isEqualToString:@\"library\"]) {\n        if ([[NSFileManager defaultManager] createDirectoryAtPath:self.appLibraryPath\n                                      withIntermediateDirectories:YES\n                                                       attributes:nil\n                                                            error:&error]) {\n            [self registerFilesystem:[[CDVLocalFilesystem alloc] initWithName:@\"persistent\" root:self.appLibraryPath]];\n        } else {\n            NSLog(@\"Unable to create library directory: %@\", error);\n        }\n    } else if ([location isEqualToString:@\"compatibility\"]) {\n        /*\n         *  Fall-back to compatibility mode -- this is the logic implemented in\n         *  earlier versions of this plugin, and should be maintained here so\n         *  that apps which were originally deployed with older versions of the\n         *  plugin can continue to provide access to files stored under those\n         *  versions.\n         */\n        [self registerFilesystem:[[CDVLocalFilesystem alloc] initWithName:@\"persistent\" root:self.rootDocsPath]];\n    } else {\n        NSAssert(false,\n            @\"File plugin configuration error: Please set iosPersistentFileLocation in config.xml to one of \\\"library\\\" (for new applications) or \\\"compatibility\\\" (for compatibility with previous versions)\");\n    }\n    [self registerFilesystem:[[CDVAssetLibraryFilesystem alloc] initWithName:@\"assets-library\"]];\n\n    [self registerExtraFileSystems:[self getExtraFileSystemsPreference:self.viewController]\n                  fromAvailableSet:[self getAvailableFileSystems]];\n\n}\n\n- (CDVFilesystemURL *)fileSystemURLforArg:(NSString *)urlArg\n{\n    CDVFilesystemURL* ret = nil;\n    if ([urlArg hasPrefix:@\"file://\"]) {\n        /* This looks like a file url. Get the path, and see if any handlers recognize it. */\n        NSURL *fileURL = [NSURL URLWithString:urlArg];\n        NSURL *resolvedFileURL = [fileURL URLByResolvingSymlinksInPath];\n        NSString *path = [resolvedFileURL path];\n        ret = [self fileSystemURLforLocalPath:path];\n    } else {\n        ret = [CDVFilesystemURL fileSystemURLWithString:urlArg];\n    }\n    return ret;\n}\n\n- (CDVFilesystemURL *)fileSystemURLforLocalPath:(NSString *)localPath\n{\n    CDVFilesystemURL *localURL = nil;\n    NSUInteger shortestFullPath = 0;\n\n    // Try all installed filesystems, in order. Return the most match url.\n    for (id object in self.fileSystems) {\n        if ([object respondsToSelector:@selector(URLforFilesystemPath:)]) {\n            CDVFilesystemURL *url = [object URLforFilesystemPath:localPath];\n            if (url){\n                // A shorter fullPath would imply that the filesystem is a better match for the local path\n                if (!localURL || ([[url fullPath] length] < shortestFullPath)) {\n                    localURL = url;\n                    shortestFullPath = [[url fullPath] length];\n                }\n            }\n        }\n    }\n    return localURL;\n}\n\n- (NSNumber*)checkFreeDiskSpace:(NSString*)appPath\n{\n    NSFileManager* fMgr = [[NSFileManager alloc] init];\n\n    NSError* __autoreleasing pError = nil;\n\n    NSDictionary* pDict = [fMgr attributesOfFileSystemForPath:appPath error:&pError];\n    NSNumber* pNumAvail = (NSNumber*)[pDict objectForKey:NSFileSystemFreeSize];\n\n    return pNumAvail;\n}\n\n/* Request the File System info\n *\n * IN:\n * arguments[0] - type (number as string)\n *\tTEMPORARY = 0, PERSISTENT = 1;\n * arguments[1] - size\n *\n * OUT:\n *\tDictionary representing FileSystem object\n *\t\tname - the human readable directory name\n *\t\troot = DirectoryEntry object\n *\t\t\tbool isDirectory\n *\t\t\tbool isFile\n *\t\t\tstring name\n *\t\t\tstring fullPath\n *\t\t\tfileSystem = FileSystem object - !! ignored because creates circular reference !!\n */\n\n- (void)requestFileSystem:(CDVInvokedUrlCommand*)command\n{\n    // arguments\n    NSString* strType = [command argumentAtIndex:0];\n    unsigned long long size = [[command argumentAtIndex:1] longLongValue];\n\n    int type = [strType intValue];\n    CDVPluginResult* result = nil;\n\n    if (type >= self.fileSystems.count) {\n        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:NOT_FOUND_ERR];\n        NSLog(@\"No filesystem of type requested\");\n    } else {\n        NSString* fullPath = @\"/\";\n        // check for avail space for size request\n        NSNumber* pNumAvail = [self checkFreeDiskSpace:self.rootDocsPath];\n        // NSLog(@\"Free space: %@\", [NSString stringWithFormat:@\"%qu\", [ pNumAvail unsignedLongLongValue ]]);\n        if (pNumAvail && ([pNumAvail unsignedLongLongValue] < size)) {\n            result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:QUOTA_EXCEEDED_ERR];\n        } else {\n            NSObject<CDVFileSystem> *rootFs = [self.fileSystems objectAtIndex:type];\n            if (rootFs == nil) {\n                result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:NOT_FOUND_ERR];\n                NSLog(@\"No filesystem of type requested\");\n            } else {\n                NSMutableDictionary* fileSystem = [NSMutableDictionary dictionaryWithCapacity:2];\n                [fileSystem setObject:rootFs.name forKey:@\"name\"];\n                NSDictionary* dirEntry = [self makeEntryForPath:fullPath fileSystemName:rootFs.name isDirectory:YES];\n                [fileSystem setObject:dirEntry forKey:@\"root\"];\n                result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:fileSystem];\n            }\n        }\n    }\n    [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n}\n\n\n- (void)requestAllFileSystems:(CDVInvokedUrlCommand*)command\n{\n    NSMutableArray* ret = [[NSMutableArray alloc] init];\n    for (NSObject<CDVFileSystem>* root in fileSystems_) {\n        [ret addObject:[self makeEntryForPath:@\"/\" fileSystemName:root.name isDirectory:YES]];\n    }\n    CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsArray:ret];\n    [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n}\n\n- (void)requestAllPaths:(CDVInvokedUrlCommand*)command\n{\n    NSString* libPath = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES)[0];\n    NSString* libPathSync = [libPath stringByAppendingPathComponent:@\"Cloud\"];\n    NSString* libPathNoSync = [libPath stringByAppendingPathComponent:@\"NoCloud\"];\n    NSString* docPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];\n    NSString* storagePath = [libPath stringByDeletingLastPathComponent];\n    NSString* cachePath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0];\n\n    // Create the directories if necessary.\n    [[NSFileManager defaultManager] createDirectoryAtPath:libPathSync withIntermediateDirectories:YES attributes:nil error:nil];\n    [[NSFileManager defaultManager] createDirectoryAtPath:libPathNoSync withIntermediateDirectories:YES attributes:nil error:nil];\n    // Mark NoSync as non-iCloud.\n    [[NSURL fileURLWithPath:libPathNoSync] setResourceValue: [NSNumber numberWithBool: YES]\n                                                     forKey: NSURLIsExcludedFromBackupKey error:nil];\n\n    NSDictionary* ret = @{\n        @\"applicationDirectory\": [[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]] absoluteString],\n        @\"applicationStorageDirectory\": [[NSURL fileURLWithPath:storagePath] absoluteString],\n        @\"dataDirectory\": [[NSURL fileURLWithPath:libPathNoSync] absoluteString],\n        @\"syncedDataDirectory\": [[NSURL fileURLWithPath:libPathSync] absoluteString],\n        @\"documentsDirectory\": [[NSURL fileURLWithPath:docPath] absoluteString],\n        @\"cacheDirectory\": [[NSURL fileURLWithPath:cachePath] absoluteString],\n        @\"tempDirectory\": [[NSURL fileURLWithPath:NSTemporaryDirectory()] absoluteString]\n    };\n\n    CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:ret];\n    [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n}\n\n/* Creates and returns a dictionary representing an Entry Object\n *\n * IN:\n * NSString* fullPath of the entry\n * int fsType - FileSystem type\n * BOOL isDirectory - YES if this is a directory, NO if is a file\n * OUT:\n * NSDictionary* Entry object\n *\t\tbool as NSNumber isDirectory\n *\t\tbool as NSNumber isFile\n *\t\tNSString*  name - last part of path\n *\t\tNSString* fullPath\n *\t\tNSString* filesystemName - FileSystem name -- actual filesystem will be created on the JS side if necessary, to avoid\n *         creating circular reference (FileSystem contains DirectoryEntry which contains FileSystem.....!!)\n */\n- (NSDictionary*)makeEntryForPath:(NSString*)fullPath fileSystemName:(NSString *)fsName isDirectory:(BOOL)isDir\n{\n    NSObject<CDVFileSystem> *fs = [self fileSystemByName:fsName];\n    return [fs makeEntryForPath:fullPath isDirectory:isDir];\n}\n\n- (NSDictionary *)makeEntryForLocalURL:(CDVFilesystemURL *)localURL\n{\n    NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURL];\n    return [fs makeEntryForLocalURL:localURL];\n}\n\n- (NSDictionary *)makeEntryForURL:(NSURL *)URL\n{\n    CDVFilesystemURL* fsURL = [self fileSystemURLforArg:[URL absoluteString]];\n    return [self makeEntryForLocalURL:fsURL];\n}\n\n/*\n * Given a URI determine the File System information associated with it and return an appropriate W3C entry object\n * IN\n *\tNSString* localURI: Should be an escaped local filesystem URI\n * OUT\n *\tEntry object\n *\t\tbool isDirectory\n *\t\tbool isFile\n *\t\tstring name\n *\t\tstring fullPath\n *\t\tfileSystem = FileSystem object - !! ignored because creates circular reference FileSystem contains DirectoryEntry which contains FileSystem.....!!\n */\n- (void)resolveLocalFileSystemURI:(CDVInvokedUrlCommand*)command\n{\n    // arguments\n    NSString* localURIstr = [command argumentAtIndex:0];\n    CDVPluginResult* result;\n\n    localURIstr = [self encodePath:localURIstr]; //encode path before resolving\n    CDVFilesystemURL* inputURI = [self fileSystemURLforArg:localURIstr];\n\n    if (inputURI == nil || inputURI.fileSystemName == nil) {\n        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:ENCODING_ERR];\n    } else {\n        NSObject<CDVFileSystem> *fs = [self filesystemForURL:inputURI];\n        if (fs == nil) {\n            result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:ENCODING_ERR];\n        } else {\n            result = [fs entryForLocalURI:inputURI];\n        }\n    }\n    [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n}\n\n//encode path with percent escapes\n-(NSString *)encodePath:(NSString *)path\n{\n    NSString *decodedPath = [path stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; //decode incase it's already encoded to avoid encoding twice\n    return [decodedPath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];\n}\n\n\n/* Part of DirectoryEntry interface,  creates or returns the specified directory\n * IN:\n *\tNSString* localURI - local filesystem URI for this directory\n *\tNSString* path - directory to be created/returned; may be full path or relative path\n *\tNSDictionary* - Flags object\n *\t\tboolean as NSNumber create -\n *\t\t\tif create is true and directory does not exist, create dir and return directory entry\n *\t\t\tif create is true and exclusive is true and directory does exist, return error\n *\t\t\tif create is false and directory does not exist, return error\n *\t\t\tif create is false and the path represents a file, return error\n *\t\tboolean as NSNumber exclusive - used in conjunction with create\n *\t\t\tif exclusive is true and create is true - specifies failure if directory already exists\n *\n *\n */\n- (void)getDirectory:(CDVInvokedUrlCommand*)command\n{\n    NSMutableArray* arguments = [NSMutableArray arrayWithArray:command.arguments];\n    NSMutableDictionary* options = nil;\n\n    if ([arguments count] >= 3) {\n        options = [command argumentAtIndex:2 withDefault:nil];\n    }\n    // add getDir to options and call getFile()\n    if (options != nil) {\n        options = [NSMutableDictionary dictionaryWithDictionary:options];\n    } else {\n        options = [NSMutableDictionary dictionaryWithCapacity:1];\n    }\n    [options setObject:[NSNumber numberWithInt:1] forKey:@\"getDir\"];\n    if ([arguments count] >= 3) {\n        [arguments replaceObjectAtIndex:2 withObject:options];\n    } else {\n        [arguments addObject:options];\n    }\n    CDVInvokedUrlCommand* subCommand =\n        [[CDVInvokedUrlCommand alloc] initWithArguments:arguments\n                                             callbackId:command.callbackId\n                                              className:command.className\n                                             methodName:command.methodName];\n\n    [self getFile:subCommand];\n}\n\n/* Part of DirectoryEntry interface,  creates or returns the specified file\n * IN:\n *\tNSString* baseURI - local filesytem URI for the base directory to search\n *\tNSString* requestedPath - file to be created/returned; may be absolute path or relative path\n *\tNSDictionary* options - Flags object\n *\t\tboolean as NSNumber create -\n *\t\t\tif create is true and file does not exist, create file and return File entry\n *\t\t\tif create is true and exclusive is true and file does exist, return error\n *\t\t\tif create is false and file does not exist, return error\n *\t\t\tif create is false and the path represents a directory, return error\n *\t\tboolean as NSNumber exclusive - used in conjunction with create\n *\t\t\tif exclusive is true and create is true - specifies failure if file already exists\n */\n- (void)getFile:(CDVInvokedUrlCommand*)command\n{\n    NSString* baseURIstr = [command argumentAtIndex:0];\n    CDVFilesystemURL* baseURI = [self fileSystemURLforArg:baseURIstr];\n    NSString* requestedPath = [command argumentAtIndex:1];\n    NSDictionary* options = [command argumentAtIndex:2 withDefault:nil];\n\n    NSObject<CDVFileSystem> *fs = [self filesystemForURL:baseURI];\n    CDVPluginResult* result = [fs getFileForURL:baseURI requestedPath:requestedPath options:options];\n\n\n    [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n}\n\n/*\n * Look up the parent Entry containing this Entry.\n * If this Entry is the root of its filesystem, its parent is itself.\n * IN:\n * NSArray* arguments\n *\t0 - NSString* localURI\n * NSMutableDictionary* options\n *\tempty\n */\n- (void)getParent:(CDVInvokedUrlCommand*)command\n{\n    // arguments are URL encoded\n    CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]];\n\n    NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI];\n    CDVPluginResult* result = [fs getParentForURL:localURI];\n\n    [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n}\n\n/*\n * set MetaData of entry\n * Currently we only support \"com.apple.MobileBackup\" (boolean)\n */\n- (void)setMetadata:(CDVInvokedUrlCommand*)command\n{\n    // arguments\n    CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]];\n    NSDictionary* options = [command argumentAtIndex:1 withDefault:nil];\n    NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI];\n    CDVPluginResult* result = [fs setMetadataForURL:localURI withObject:options];\n\n    [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n}\n\n/* removes the directory or file entry\n * IN:\n * NSArray* arguments\n *\t0 - NSString* localURI\n *\n * returns NO_MODIFICATION_ALLOWED_ERR  if is top level directory or no permission to delete dir\n * returns INVALID_MODIFICATION_ERR if is non-empty dir or asset library file\n * returns NOT_FOUND_ERR if file or dir is not found\n*/\n- (void)remove:(CDVInvokedUrlCommand*)command\n{\n    // arguments\n    CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]];\n    CDVPluginResult* result = nil;\n\n    if ([localURI.fullPath isEqualToString:@\"\"]) {\n        // error if try to remove top level (documents or tmp) dir\n        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NO_MODIFICATION_ALLOWED_ERR];\n    } else {\n        NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI];\n        result = [fs removeFileAtURL:localURI];\n    }\n    [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n}\n\n/* recursively removes the directory\n * IN:\n * NSArray* arguments\n *\t0 - NSString* localURI\n *\n * returns NO_MODIFICATION_ALLOWED_ERR  if is top level directory or no permission to delete dir\n * returns NOT_FOUND_ERR if file or dir is not found\n */\n- (void)removeRecursively:(CDVInvokedUrlCommand*)command\n{\n    // arguments\n    CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]];\n    CDVPluginResult* result = nil;\n\n    if ([localURI.fullPath isEqualToString:@\"\"]) {\n        // error if try to remove top level (documents or tmp) dir\n        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NO_MODIFICATION_ALLOWED_ERR];\n    } else {\n        NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI];\n        result = [fs recursiveRemoveFileAtURL:localURI];\n    }\n    [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n}\n\n- (void)copyTo:(CDVInvokedUrlCommand*)command\n{\n    [self doCopyMove:command isCopy:YES];\n}\n\n- (void)moveTo:(CDVInvokedUrlCommand*)command\n{\n    [self doCopyMove:command isCopy:NO];\n}\n\n/* Copy/move a file or directory to a new location\n * IN:\n * NSArray* arguments\n *\t0 - NSString* URL of entry to copy\n *  1 - NSString* URL of the directory into which to copy/move the entry\n *  2 - Optionally, the new name of the entry, defaults to the current name\n *\tBOOL - bCopy YES if copy, NO if move\n */\n- (void)doCopyMove:(CDVInvokedUrlCommand*)command isCopy:(BOOL)bCopy\n{\n    NSArray* arguments = command.arguments;\n\n    // arguments\n    NSString* srcURLstr = [command argumentAtIndex:0];\n    NSString* destURLstr = [command argumentAtIndex:1];\n\n    CDVPluginResult *result;\n\n    if (!srcURLstr || !destURLstr) {\n        // either no source or no destination provided\n        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_FOUND_ERR];\n        [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n        return;\n    }\n\n    CDVFilesystemURL* srcURL = [self fileSystemURLforArg:srcURLstr];\n    CDVFilesystemURL* destURL = [self fileSystemURLforArg:destURLstr];\n\n    NSObject<CDVFileSystem> *srcFs = [self filesystemForURL:srcURL];\n    NSObject<CDVFileSystem> *destFs = [self filesystemForURL:destURL];\n\n    // optional argument; use last component from srcFullPath if new name not provided\n    NSString* newName = ([arguments count] > 2) ? [command argumentAtIndex:2] : [srcURL.url lastPathComponent];\n    if ([newName rangeOfString:@\":\"].location != NSNotFound) {\n        // invalid chars in new name\n        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:ENCODING_ERR];\n        [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n        return;\n    }\n\n    __weak CDVFile* weakSelf = self;\n    [destFs copyFileToURL:destURL withName:newName fromFileSystem:srcFs atURL:srcURL copy:bCopy callback:^(CDVPluginResult* result) {\n        [weakSelf.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n    }];\n\n}\n\n- (void)getFileMetadata:(CDVInvokedUrlCommand*)command\n{\n    // arguments\n    CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]];\n    NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI];\n    __weak CDVFile* weakSelf = self;\n    [fs getFileMetadataForURL:localURI callback:^(CDVPluginResult* result) {\n        [weakSelf.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n    }];\n}\n\n- (void)readEntries:(CDVInvokedUrlCommand*)command\n{\n    CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]];\n    NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI];\n    CDVPluginResult *result = [fs readEntriesAtURL:localURI];\n\n    [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n}\n\n/* read and return file data\n * IN:\n * NSArray* arguments\n *\t0 - NSString* fullPath\n *\t1 - NSString* encoding\n *\t2 - NSString* start\n *\t3 - NSString* end\n */\n- (void)readAsText:(CDVInvokedUrlCommand*)command\n{\n    // arguments\n    CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]];\n    NSString* encoding = [command argumentAtIndex:1];\n    NSInteger start = [[command argumentAtIndex:2] integerValue];\n    NSInteger end = [[command argumentAtIndex:3] integerValue];\n\n    NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI];\n\n    if (fs == nil) {\n        CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_FOUND_ERR];\n        [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n        return;\n    }\n\n    // TODO: implement\n    if ([@\"UTF-8\" caseInsensitiveCompare : encoding] != NSOrderedSame) {\n        NSLog(@\"Only UTF-8 encodings are currently supported by readAsText\");\n        CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:ENCODING_ERR];\n        [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n        return;\n    }\n\n    __weak CDVFile* weakSelf = self;\n\n    [self.commandDelegate runInBackground:^ {\n        [fs readFileAtURL:localURI start:start end:end callback:^(NSData* data, NSString* mimeType, CDVFileError errorCode) {\n            CDVPluginResult* result = nil;\n            if (data != nil) {\n                NSString* str = [[NSString alloc] initWithBytesNoCopy:(void*)[data bytes] length:[data length] encoding:NSUTF8StringEncoding freeWhenDone:NO];\n                // Check that UTF8 conversion did not fail.\n                if (str != nil) {\n                    result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:str];\n                    result.associatedObject = data;\n                } else {\n                    errorCode = ENCODING_ERR;\n                }\n            }\n            if (result == nil) {\n                result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:errorCode];\n            }\n\n            [weakSelf.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n        }];\n    }];\n}\n\n/* Read content of text file and return as base64 encoded data url.\n * IN:\n * NSArray* arguments\n *\t0 - NSString* fullPath\n *\t1 - NSString* start\n *\t2 - NSString* end\n *\n * Determines the mime type from the file extension, returns ENCODING_ERR if mimetype can not be determined.\n */\n\n- (void)readAsDataURL:(CDVInvokedUrlCommand*)command\n{\n    CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]];\n    NSInteger start = [[command argumentAtIndex:1] integerValue];\n    NSInteger end = [[command argumentAtIndex:2] integerValue];\n\n    NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI];\n\n    __weak CDVFile* weakSelf = self;\n    [self.commandDelegate runInBackground:^ {\n        [fs readFileAtURL:localURI start:start end:end callback:^(NSData* data, NSString* mimeType, CDVFileError errorCode) {\n            CDVPluginResult* result = nil;\n            if (data != nil) {\n                NSString* b64Str = toBase64(data);\n                NSString* output = [NSString stringWithFormat:@\"data:%@;base64,%@\", mimeType, b64Str];\n                result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:output];\n            } else {\n                result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:errorCode];\n            }\n\n            [weakSelf.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n        }];\n    }];\n}\n\n/* Read content of text file and return as an arraybuffer\n * IN:\n * NSArray* arguments\n *\t0 - NSString* fullPath\n *\t1 - NSString* start\n *\t2 - NSString* end\n */\n\n- (void)readAsArrayBuffer:(CDVInvokedUrlCommand*)command\n{\n    CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]];\n    NSInteger start = [[command argumentAtIndex:1] integerValue];\n    NSInteger end = [[command argumentAtIndex:2] integerValue];\n\n    NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI];\n\n    __weak CDVFile* weakSelf = self;\n\n    [self.commandDelegate runInBackground:^ {\n        [fs readFileAtURL:localURI start:start end:end callback:^(NSData* data, NSString* mimeType, CDVFileError errorCode) {\n            CDVPluginResult* result = nil;\n            if (data != nil) {\n                result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsArrayBuffer:data];\n            } else {\n                result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:errorCode];\n            }\n\n            [weakSelf.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n        }];\n    }];\n}\n\n- (void)readAsBinaryString:(CDVInvokedUrlCommand*)command\n{\n    CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]];\n    NSInteger start = [[command argumentAtIndex:1] integerValue];\n    NSInteger end = [[command argumentAtIndex:2] integerValue];\n\n    NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI];\n\n    __weak CDVFile* weakSelf = self;\n\n    [self.commandDelegate runInBackground:^ {\n        [fs readFileAtURL:localURI start:start end:end callback:^(NSData* data, NSString* mimeType, CDVFileError errorCode) {\n            CDVPluginResult* result = nil;\n            if (data != nil) {\n                NSString* payload = [[NSString alloc] initWithBytesNoCopy:(void*)[data bytes] length:[data length] encoding:NSASCIIStringEncoding freeWhenDone:NO];\n                result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:payload];\n                result.associatedObject = data;\n            } else {\n                result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:errorCode];\n            }\n\n            [weakSelf.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n        }];\n    }];\n}\n\n\n- (void)truncate:(CDVInvokedUrlCommand*)command\n{\n    // arguments\n    CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]];\n    unsigned long long pos = (unsigned long long)[[command argumentAtIndex:1] longLongValue];\n\n    NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI];\n    CDVPluginResult *result = [fs truncateFileAtURL:localURI atPosition:pos];\n\n    [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n}\n\n/* write\n * IN:\n * NSArray* arguments\n *  0 - NSString* localURI of file to write to\n *  1 - NSString* or NSData* data to write\n *  2 - NSNumber* position to begin writing\n */\n- (void)write:(CDVInvokedUrlCommand*)command\n{\n    __weak CDVFile* weakSelf = self;\n\n    [self.commandDelegate runInBackground:^ {\n        NSString* callbackId = command.callbackId;\n\n        // arguments\n        CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]];\n        id argData = [command argumentAtIndex:1];\n        unsigned long long pos = (unsigned long long)[[command argumentAtIndex:2] longLongValue];\n\n        NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI];\n\n\n        [fs truncateFileAtURL:localURI atPosition:pos];\n        CDVPluginResult *result;\n        if ([argData isKindOfClass:[NSString class]]) {\n            NSData *encData = [argData dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];\n            result = [fs writeToFileAtURL:localURI withData:encData append:YES];\n        } else if ([argData isKindOfClass:[NSData class]]) {\n            result = [fs writeToFileAtURL:localURI withData:argData append:YES];\n        } else {\n            result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@\"Invalid parameter type\"];\n        }\n        [weakSelf.commandDelegate sendPluginResult:result callbackId:callbackId];\n    }];\n}\n\n#pragma mark Methods for converting between URLs and paths\n\n- (NSString *)filesystemPathForURL:(CDVFilesystemURL *)localURL\n{\n    for (NSObject<CDVFileSystem> *fs in self.fileSystems) {\n        if ([fs.name isEqualToString:localURL.fileSystemName]) {\n            if ([fs respondsToSelector:@selector(filesystemPathForURL:)]) {\n                return [fs filesystemPathForURL:localURL];\n            }\n        }\n    }\n    return nil;\n}\n\n#pragma mark Undocumented Filesystem API\n\n- (void)testFileExists:(CDVInvokedUrlCommand*)command\n{\n    // arguments\n    NSString* argPath = [command argumentAtIndex:0];\n\n    // Get the file manager\n    NSFileManager* fMgr = [NSFileManager defaultManager];\n    NSString* appFile = argPath; // [ self getFullPath: argPath];\n\n    BOOL bExists = [fMgr fileExistsAtPath:appFile];\n    CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:(bExists ? 1 : 0)];\n\n    [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n}\n\n- (void)testDirectoryExists:(CDVInvokedUrlCommand*)command\n{\n    // arguments\n    NSString* argPath = [command argumentAtIndex:0];\n\n    // Get the file manager\n    NSFileManager* fMgr = [[NSFileManager alloc] init];\n    NSString* appFile = argPath; // [self getFullPath: argPath];\n    BOOL bIsDir = NO;\n    BOOL bExists = [fMgr fileExistsAtPath:appFile isDirectory:&bIsDir];\n\n    CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:((bExists && bIsDir) ? 1 : 0)];\n\n    [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n}\n\n// Returns number of bytes available via callback\n- (void)getFreeDiskSpace:(CDVInvokedUrlCommand*)command\n{\n    // no arguments\n    \n    NSNumber* pNumAvail = [self checkFreeDiskSpace:self.rootDocsPath];\n\n    NSString* strFreeSpace = [NSString stringWithFormat:@\"%qu\", [pNumAvail unsignedLongLongValue]];\n    // NSLog(@\"Free space is %@\", strFreeSpace );\n\n    CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:strFreeSpace];\n\n    [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n}\n\n#pragma mark Compatibility with older File API\n\n- (NSString*)getMimeTypeFromPath:(NSString*)fullPath\n{\n    return [CDVLocalFilesystem getMimeTypeFromPath:fullPath];\n}\n\n- (NSDictionary *)getDirectoryEntry:(NSString *)localPath isDirectory:(BOOL)bDirRequest\n{\n    CDVFilesystemURL *localURL = [self fileSystemURLforLocalPath:localPath];\n    return [self makeEntryForPath:localURL.fullPath fileSystemName:localURL.fileSystemName isDirectory:bDirRequest];\n}\n\n#pragma mark Internal methods for testing\n// Internal methods for testing: Get the on-disk location of a local filesystem url.\n// [Currently used for testing file-transfer]\n\n- (void)_getLocalFilesystemPath:(CDVInvokedUrlCommand*)command\n{\n    CDVFilesystemURL* localURL = [self fileSystemURLforArg:command.arguments[0]];\n\n    NSString* fsPath = [self filesystemPathForURL:localURL];\n    CDVPluginResult* result;\n    if (fsPath) {\n        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:fsPath];\n    } else {\n        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@\"Cannot resolve URL to a file\"];\n    }\n    [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n}\n\n@end\n"
  },
  {
    "path": "plugins/cordova-plugin-file/src/ios/CDVLocalFilesystem.h",
    "content": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements.  See the NOTICE file\n distributed with this work for additional information\n regarding copyright ownership.  The ASF licenses this file\n to you under the Apache License, Version 2.0 (the\n \"License\"); you may not use this file except in compliance\n with the License.  You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an\n \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n KIND, either express or implied.  See the License for the\n specific language governing permissions and limitations\n under the License.\n */\n\n#import \"CDVFile.h\"\n\n@interface CDVLocalFilesystem : NSObject<CDVFileSystem> {\n    NSString *_name;\n    NSString *_fsRoot;\n}\n\n- (id) initWithName:(NSString *)name root:(NSString *)fsRoot;\n+ (NSString*)getMimeTypeFromPath:(NSString*)fullPath;\n\n@property (nonatomic,strong) NSString *fsRoot;\n\n@end\n"
  },
  {
    "path": "plugins/cordova-plugin-file/src/ios/CDVLocalFilesystem.m",
    "content": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements.  See the NOTICE file\n distributed with this work for additional information\n regarding copyright ownership.  The ASF licenses this file\n to you under the Apache License, Version 2.0 (the\n \"License\"); you may not use this file except in compliance\n with the License.  You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an\n \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n KIND, either express or implied.  See the License for the\n specific language governing permissions and limitations\n under the License.\n */\n\n#import \"CDVFile.h\"\n#import \"CDVLocalFilesystem.h\"\n#import <Cordova/CDV.h>\n#import <MobileCoreServices/MobileCoreServices.h>\n#import <sys/xattr.h>\n\n@implementation CDVLocalFilesystem\n@synthesize name=_name, fsRoot=_fsRoot, urlTransformer;\n\n- (id) initWithName:(NSString *)name root:(NSString *)fsRoot\n{\n    if (self) {\n        self.name = name;\n        self.fsRoot = fsRoot;\n    }\n    return self;\n}\n\n/*\n * IN\n *  NSString localURI\n * OUT\n *  CDVPluginResult result containing a file or directoryEntry for the localURI, or an error if the\n *   URI represents a non-existent path, or is unrecognized or otherwise malformed.\n */\n- (CDVPluginResult *)entryForLocalURI:(CDVFilesystemURL *)url\n{\n    CDVPluginResult* result = nil;\n    NSDictionary* entry = [self makeEntryForLocalURL:url];\n    if (entry) {\n        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:entry];\n    } else {\n        // return NOT_FOUND_ERR\n        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_FOUND_ERR];\n    }\n    return result;\n}\n- (NSDictionary *)makeEntryForLocalURL:(CDVFilesystemURL *)url {\n    NSString *path = [self filesystemPathForURL:url];\n    NSFileManager* fileMgr = [[NSFileManager alloc] init];\n    BOOL isDir = NO;\n    // see if exists and is file or dir\n    BOOL bExists = [fileMgr fileExistsAtPath:path isDirectory:&isDir];\n    if (bExists) {\n        return [self makeEntryForPath:url.fullPath isDirectory:isDir];\n    } else {\n        return nil;\n    }\n}\n- (NSDictionary*)makeEntryForPath:(NSString*)fullPath isDirectory:(BOOL)isDir\n{\n    NSMutableDictionary* dirEntry = [NSMutableDictionary dictionaryWithCapacity:5];\n    NSString* lastPart = [[self stripQueryParametersFromPath:fullPath] lastPathComponent];\n    if (isDir && ![fullPath hasSuffix:@\"/\"]) {\n        fullPath = [fullPath stringByAppendingString:@\"/\"];\n    }\n    [dirEntry setObject:[NSNumber numberWithBool:!isDir]  forKey:@\"isFile\"];\n    [dirEntry setObject:[NSNumber numberWithBool:isDir]  forKey:@\"isDirectory\"];\n    [dirEntry setObject:fullPath forKey:@\"fullPath\"];\n    [dirEntry setObject:lastPart forKey:@\"name\"];\n    [dirEntry setObject:self.name forKey: @\"filesystemName\"];\n\n    NSURL* nativeURL = [NSURL fileURLWithPath:[self filesystemPathForFullPath:fullPath]];\n    if (self.urlTransformer) {\n        nativeURL = self.urlTransformer(nativeURL);\n    }\n\n    dirEntry[@\"nativeURL\"] = [nativeURL absoluteString];\n\n    return dirEntry;\n}\n\n- (NSString *)stripQueryParametersFromPath:(NSString *)fullPath\n{\n    NSRange questionMark = [fullPath rangeOfString:@\"?\"];\n    if (questionMark.location != NSNotFound) {\n        return [fullPath substringWithRange:NSMakeRange(0,questionMark.location)];\n    }\n    return fullPath;\n}\n\n- (NSString *)filesystemPathForFullPath:(NSString *)fullPath\n{\n    NSString *path = nil;\n    NSString *strippedFullPath = [self stripQueryParametersFromPath:fullPath];\n    path = [NSString stringWithFormat:@\"%@%@\", self.fsRoot, strippedFullPath];\n    if ([path length] > 1 && [path hasSuffix:@\"/\"]) {\n      path = [path substringToIndex:([path length]-1)];\n    }\n    return path;\n}\n/*\n * IN\n *  NSString localURI\n * OUT\n *  NSString full local filesystem path for the represented file or directory, or nil if no such path is possible\n *  The file or directory does not necessarily have to exist. nil is returned if the filesystem type is not recognized,\n *  or if the URL is malformed.\n * The incoming URI should be properly escaped (no raw spaces, etc. URI percent-encoding is expected).\n */\n- (NSString *)filesystemPathForURL:(CDVFilesystemURL *)url\n{\n    return [self filesystemPathForFullPath:url.fullPath];\n}\n\n- (CDVFilesystemURL *)URLforFullPath:(NSString *)fullPath\n{\n    if (fullPath) {\n        NSString* escapedPath = [fullPath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];\n        if ([fullPath hasPrefix:@\"/\"]) {\n            return [CDVFilesystemURL fileSystemURLWithString:[NSString stringWithFormat:@\"%@://localhost/%@%@\", kCDVFilesystemURLPrefix, self.name, escapedPath]];\n        }\n        return [CDVFilesystemURL fileSystemURLWithString:[NSString stringWithFormat:@\"%@://localhost/%@/%@\", kCDVFilesystemURLPrefix, self.name, escapedPath]];\n    }\n    return nil;\n}\n\n- (CDVFilesystemURL *)URLforFilesystemPath:(NSString *)path\n{\n    return [self URLforFullPath:[self fullPathForFileSystemPath:path]];\n\n}\n\n- (NSString *)normalizePath:(NSString *)rawPath\n{\n    // If this is an absolute path, the first path component will be '/'. Skip it if that's the case\n    BOOL isAbsolutePath = [rawPath hasPrefix:@\"/\"];\n    if (isAbsolutePath) {\n        rawPath = [rawPath substringFromIndex:1];\n    }\n    NSMutableArray *components = [NSMutableArray arrayWithArray:[rawPath pathComponents]];\n    for (int index = 0; index < [components count]; ++index) {\n        if ([[components objectAtIndex:index] isEqualToString:@\"..\"]) {\n            [components removeObjectAtIndex:index];\n            if (index > 0) {\n                [components removeObjectAtIndex:index-1];\n                --index;\n            }\n        }\n    }\n\n    if (isAbsolutePath) {\n        return [NSString stringWithFormat:@\"/%@\", [components componentsJoinedByString:@\"/\"]];\n    } else {\n        return [components componentsJoinedByString:@\"/\"];\n    }\n\n\n}\n\n- (BOOL)valueForKeyIsNumber:(NSDictionary*)dict key:(NSString*)key\n{\n    BOOL bNumber = NO;\n    NSObject* value = dict[key];\n    if (value) {\n        bNumber = [value isKindOfClass:[NSNumber class]];\n    }\n    return bNumber;\n}\n\n- (CDVPluginResult *)getFileForURL:(CDVFilesystemURL *)baseURI requestedPath:(NSString *)requestedPath options:(NSDictionary *)options\n{\n    CDVPluginResult* result = nil;\n    BOOL bDirRequest = NO;\n    BOOL create = NO;\n    BOOL exclusive = NO;\n    int errorCode = 0;  // !!! risky - no error code currently defined for 0\n\n    if ([self valueForKeyIsNumber:options key:@\"create\"]) {\n        create = [(NSNumber*)[options valueForKey:@\"create\"] boolValue];\n    }\n    if ([self valueForKeyIsNumber:options key:@\"exclusive\"]) {\n        exclusive = [(NSNumber*)[options valueForKey:@\"exclusive\"] boolValue];\n    }\n    if ([self valueForKeyIsNumber:options key:@\"getDir\"]) {\n        // this will not exist for calls directly to getFile but will have been set by getDirectory before calling this method\n        bDirRequest = [(NSNumber*)[options valueForKey:@\"getDir\"] boolValue];\n    }\n    // see if the requested path has invalid characters - should we be checking for  more than just \":\"?\n    if ([requestedPath rangeOfString:@\":\"].location != NSNotFound) {\n        errorCode = ENCODING_ERR;\n    } else {\n        // Build new fullPath for the requested resource.\n        // We concatenate the two paths together, and then scan the resulting string to remove\n        // parent (\"..\") references. Any parent references at the beginning of the string are\n        // silently removed.\n        NSString *combinedPath = [baseURI.fullPath stringByAppendingPathComponent:requestedPath];\n        combinedPath = [self normalizePath:combinedPath];\n        CDVFilesystemURL* requestedURL = [self URLforFullPath:combinedPath];\n\n        NSFileManager* fileMgr = [[NSFileManager alloc] init];\n        BOOL bIsDir;\n        BOOL bExists = [fileMgr fileExistsAtPath:[self filesystemPathForURL:requestedURL] isDirectory:&bIsDir];\n        if (bExists && (create == NO) && (bIsDir == !bDirRequest)) {\n            // path exists and is not of requested type  - return TYPE_MISMATCH_ERR\n            errorCode = TYPE_MISMATCH_ERR;\n        } else if (!bExists && (create == NO)) {\n            // path does not exist and create is false - return NOT_FOUND_ERR\n            errorCode = NOT_FOUND_ERR;\n        } else if (bExists && (create == YES) && (exclusive == YES)) {\n            // file/dir already exists and exclusive and create are both true - return PATH_EXISTS_ERR\n            errorCode = PATH_EXISTS_ERR;\n        } else {\n            // if bExists and create == YES - just return data\n            // if bExists and create == NO  - just return data\n            // if !bExists and create == YES - create and return data\n            BOOL bSuccess = YES;\n            NSError __autoreleasing* pError = nil;\n            if (!bExists && (create == YES)) {\n                if (bDirRequest) {\n                    // create the dir\n                    bSuccess = [fileMgr createDirectoryAtPath:[self filesystemPathForURL:requestedURL] withIntermediateDirectories:NO attributes:nil error:&pError];\n                } else {\n                    // create the empty file\n                    bSuccess = [fileMgr createFileAtPath:[self filesystemPathForURL:requestedURL] contents:nil attributes:nil];\n                }\n            }\n            if (!bSuccess) {\n                errorCode = ABORT_ERR;\n                if (pError) {\n                    NSLog(@\"error creating directory: %@\", [pError localizedDescription]);\n                }\n            } else {\n                // NSLog(@\"newly created file/dir (%@) exists: %d\", reqFullPath, [fileMgr fileExistsAtPath:reqFullPath]);\n                // file existed or was created\n                result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:[self makeEntryForPath:requestedURL.fullPath isDirectory:bDirRequest]];\n            }\n        } // are all possible conditions met?\n    }\n\n    if (errorCode > 0) {\n        // create error callback\n        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:errorCode];\n    }\n    return result;\n\n}\n\n- (CDVPluginResult*)getParentForURL:(CDVFilesystemURL *)localURI\n{\n    CDVPluginResult* result = nil;\n    CDVFilesystemURL *newURI = nil;\n    if ([localURI.fullPath isEqualToString:@\"\"]) {\n        // return self\n        newURI = localURI;\n    } else {\n        newURI = [CDVFilesystemURL fileSystemURLWithURL:[localURI.url URLByDeletingLastPathComponent]]; /* TODO: UGLY - FIX */\n    }\n    NSFileManager* fileMgr = [[NSFileManager alloc] init];\n    BOOL bIsDir;\n    BOOL bExists = [fileMgr fileExistsAtPath:[self filesystemPathForURL:newURI] isDirectory:&bIsDir];\n    if (bExists) {\n        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:[self makeEntryForPath:newURI.fullPath isDirectory:bIsDir]];\n    } else {\n        // invalid path or file does not exist\n        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_FOUND_ERR];\n    }\n    return result;\n}\n\n- (CDVPluginResult*)setMetadataForURL:(CDVFilesystemURL *)localURI withObject:(NSDictionary *)options\n{\n    BOOL ok = NO;\n\n    NSString* filePath = [self filesystemPathForURL:localURI];\n    // we only care about this iCloud key for now.\n    // set to 1/true to skip backup, set to 0/false to back it up (effectively removing the attribute)\n    NSString* iCloudBackupExtendedAttributeKey = @\"com.apple.MobileBackup\";\n    id iCloudBackupExtendedAttributeValue = [options objectForKey:iCloudBackupExtendedAttributeKey];\n\n    if ((iCloudBackupExtendedAttributeValue != nil) && [iCloudBackupExtendedAttributeValue isKindOfClass:[NSNumber class]]) {\n        if (IsAtLeastiOSVersion(@\"5.1\")) {\n            NSURL* url = [NSURL fileURLWithPath:filePath];\n            NSError* __autoreleasing error = nil;\n\n            ok = [url setResourceValue:[NSNumber numberWithBool:[iCloudBackupExtendedAttributeValue boolValue]] forKey:NSURLIsExcludedFromBackupKey error:&error];\n        } else { // below 5.1 (deprecated - only really supported in 5.01)\n            u_int8_t value = [iCloudBackupExtendedAttributeValue intValue];\n            if (value == 0) { // remove the attribute (allow backup, the default)\n                ok = (removexattr([filePath fileSystemRepresentation], [iCloudBackupExtendedAttributeKey cStringUsingEncoding:NSUTF8StringEncoding], 0) == 0);\n            } else { // set the attribute (skip backup)\n                ok = (setxattr([filePath fileSystemRepresentation], [iCloudBackupExtendedAttributeKey cStringUsingEncoding:NSUTF8StringEncoding], &value, sizeof(value), 0, 0) == 0);\n            }\n        }\n    }\n\n    if (ok) {\n        return [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];\n    } else {\n        return [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];\n    }\n}\n\n/* remove the file or directory (recursively)\n * IN:\n * NSString* fullPath - the full path to the file or directory to be removed\n * NSString* callbackId\n * called from remove and removeRecursively - check all pubic api specific error conditions (dir not empty, etc) before calling\n */\n\n- (CDVPluginResult*)doRemove:(NSString*)fullPath\n{\n    CDVPluginResult* result = nil;\n    BOOL bSuccess = NO;\n    NSError* __autoreleasing pError = nil;\n    NSFileManager* fileMgr = [[NSFileManager alloc] init];\n\n    @try {\n        bSuccess = [fileMgr removeItemAtPath:fullPath error:&pError];\n        if (bSuccess) {\n            result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];\n        } else {\n            // see if we can give a useful error\n            CDVFileError errorCode = ABORT_ERR;\n            NSLog(@\"error removing filesystem entry at %@: %@\", fullPath, [pError localizedDescription]);\n            if ([pError code] == NSFileNoSuchFileError) {\n                errorCode = NOT_FOUND_ERR;\n            } else if ([pError code] == NSFileWriteNoPermissionError) {\n                errorCode = NO_MODIFICATION_ALLOWED_ERR;\n            }\n\n            result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:errorCode];\n        }\n    } @catch(NSException* e) {  // NSInvalidArgumentException if path is . or ..\n        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:SYNTAX_ERR];\n    }\n\n    return result;\n}\n\n- (CDVPluginResult *)removeFileAtURL:(CDVFilesystemURL *)localURI\n{\n    NSString *fileSystemPath = [self filesystemPathForURL:localURI];\n\n    NSFileManager* fileMgr = [[NSFileManager alloc] init];\n    BOOL bIsDir = NO;\n    BOOL bExists = [fileMgr fileExistsAtPath:fileSystemPath isDirectory:&bIsDir];\n    if (!bExists) {\n        return [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_FOUND_ERR];\n    }\n    if (bIsDir && ([[fileMgr contentsOfDirectoryAtPath:fileSystemPath error:nil] count] != 0)) {\n        // dir is not empty\n        return [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:INVALID_MODIFICATION_ERR];\n    }\n    return [self doRemove:fileSystemPath];\n}\n\n- (CDVPluginResult *)recursiveRemoveFileAtURL:(CDVFilesystemURL *)localURI\n{\n    NSString *fileSystemPath = [self filesystemPathForURL:localURI];\n    return [self doRemove:fileSystemPath];\n}\n\n/*\n * IN\n *  NSString localURI\n * OUT\n *  NSString full local filesystem path for the represented file or directory, or nil if no such path is possible\n *  The file or directory does not necessarily have to exist. nil is returned if the filesystem type is not recognized,\n *  or if the URL is malformed.\n * The incoming URI should be properly escaped (no raw spaces, etc. URI percent-encoding is expected).\n */\n- (NSString *)fullPathForFileSystemPath:(NSString *)fsPath\n{\n    if ([fsPath hasPrefix:self.fsRoot]) {\n        return [fsPath substringFromIndex:[self.fsRoot length]];\n    }\n    return nil;\n}\n\n\n- (CDVPluginResult *)readEntriesAtURL:(CDVFilesystemURL *)localURI\n{\n    NSFileManager* fileMgr = [[NSFileManager alloc] init];\n    NSError* __autoreleasing error = nil;\n    NSString *fileSystemPath = [self filesystemPathForURL:localURI];\n\n    NSArray* contents = [fileMgr contentsOfDirectoryAtPath:fileSystemPath error:&error];\n\n    if (contents) {\n        NSMutableArray* entries = [NSMutableArray arrayWithCapacity:1];\n        if ([contents count] > 0) {\n            // create an Entry (as JSON) for each file/dir\n            for (NSString* name in contents) {\n                // see if is dir or file\n                NSString* entryPath = [fileSystemPath stringByAppendingPathComponent:name];\n                BOOL bIsDir = NO;\n                [fileMgr fileExistsAtPath:entryPath isDirectory:&bIsDir];\n                NSDictionary* entryDict = [self makeEntryForPath:[self fullPathForFileSystemPath:entryPath] isDirectory:bIsDir];\n                [entries addObject:entryDict];\n            }\n        }\n        return [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsArray:entries];\n    } else {\n        // assume not found but could check error for more specific error conditions\n        return [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_FOUND_ERR];\n    }\n}\n\n- (unsigned long long)truncateFile:(NSString*)filePath atPosition:(unsigned long long)pos\n{\n    unsigned long long newPos = 0UL;\n\n    NSFileHandle* file = [NSFileHandle fileHandleForWritingAtPath:filePath];\n\n    if (file) {\n        [file truncateFileAtOffset:(unsigned long long)pos];\n        newPos = [file offsetInFile];\n        [file synchronizeFile];\n        [file closeFile];\n    }\n    return newPos;\n}\n\n- (CDVPluginResult *)truncateFileAtURL:(CDVFilesystemURL *)localURI atPosition:(unsigned long long)pos\n{\n    unsigned long long newPos = [self truncateFile:[self filesystemPathForURL:localURI] atPosition:pos];\n    return [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:(int)newPos];\n}\n\n- (CDVPluginResult *)writeToFileAtURL:(CDVFilesystemURL *)localURL withData:(NSData*)encData append:(BOOL)shouldAppend\n{\n    NSString *filePath = [self filesystemPathForURL:localURL];\n\n    CDVPluginResult* result = nil;\n    CDVFileError errCode = INVALID_MODIFICATION_ERR;\n    int bytesWritten = 0;\n\n    if (filePath) {\n        NSOutputStream* fileStream = [NSOutputStream outputStreamToFileAtPath:filePath append:shouldAppend];\n        if (fileStream) {\n            NSUInteger len = [encData length];\n            if (len == 0) {\n                result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDouble:(double)len];\n            } else {\n                [fileStream open];\n\n                bytesWritten = (int)[fileStream write:[encData bytes] maxLength:len];\n\n                [fileStream close];\n                if (bytesWritten > 0) {\n                    result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:bytesWritten];\n                    // } else {\n                    // can probably get more detailed error info via [fileStream streamError]\n                    // errCode already set to INVALID_MODIFICATION_ERR;\n                    // bytesWritten = 0; // may be set to -1 on error\n                }\n            }\n        } // else fileStream not created return INVALID_MODIFICATION_ERR\n    } else {\n        // invalid filePath\n        errCode = NOT_FOUND_ERR;\n    }\n    if (!result) {\n        // was an error\n        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:errCode];\n    }\n    return result;\n}\n\n/**\n * Helper function to check to see if the user attempted to copy an entry into its parent without changing its name,\n * or attempted to copy a directory into a directory that it contains directly or indirectly.\n *\n * IN:\n *  NSString* srcDir\n *  NSString* destinationDir\n * OUT:\n *  YES copy/ move is allows\n *  NO move is onto itself\n */\n- (BOOL)canCopyMoveSrc:(NSString*)src ToDestination:(NSString*)dest\n{\n    // This weird test is to determine if we are copying or moving a directory into itself.\n    // Copy /Documents/myDir to /Documents/myDir-backup is okay but\n    // Copy /Documents/myDir to /Documents/myDir/backup not okay\n    BOOL copyOK = YES;\n    NSRange range = [dest rangeOfString:src];\n\n    if (range.location != NSNotFound) {\n        NSRange testRange = {range.length - 1, ([dest length] - range.length)};\n        NSRange resultRange = [dest rangeOfString:@\"/\" options:0 range:testRange];\n        if (resultRange.location != NSNotFound) {\n            copyOK = NO;\n        }\n    }\n    return copyOK;\n}\n\n- (void)copyFileToURL:(CDVFilesystemURL *)destURL withName:(NSString *)newName fromFileSystem:(NSObject<CDVFileSystem> *)srcFs atURL:(CDVFilesystemURL *)srcURL copy:(BOOL)bCopy callback:(void (^)(CDVPluginResult *))callback\n{\n    NSFileManager *fileMgr = [[NSFileManager alloc] init];\n    NSString *destRootPath = [self filesystemPathForURL:destURL];\n    BOOL bDestIsDir = NO;\n    BOOL bDestExists = [fileMgr fileExistsAtPath:destRootPath isDirectory:&bDestIsDir];\n\n    NSString *newFileSystemPath = [destRootPath stringByAppendingPathComponent:newName];\n    NSString *newFullPath = [self fullPathForFileSystemPath:newFileSystemPath];\n\n    BOOL bNewIsDir = NO;\n    BOOL bNewExists = [fileMgr fileExistsAtPath:newFileSystemPath isDirectory:&bNewIsDir];\n\n    CDVPluginResult *result = nil;\n    int errCode = 0;\n\n    if (!bDestExists) {\n        // the destination root does not exist\n        errCode = NOT_FOUND_ERR;\n    }\n\n    else if ([srcFs isKindOfClass:[CDVLocalFilesystem class]]) {\n        /* Same FS, we can shortcut with NSFileManager operations */\n        NSString *srcFullPath = [srcFs filesystemPathForURL:srcURL];\n\n        BOOL bSrcIsDir = NO;\n        BOOL bSrcExists = [fileMgr fileExistsAtPath:srcFullPath isDirectory:&bSrcIsDir];\n\n        if (!bSrcExists) {\n            // the source does not exist\n            errCode = NOT_FOUND_ERR;\n        } else if ([newFileSystemPath isEqualToString:srcFullPath]) {\n            // source and destination can not be the same\n            errCode = INVALID_MODIFICATION_ERR;\n        } else if (bSrcIsDir && (bNewExists && !bNewIsDir)) {\n            // can't copy/move dir to file\n            errCode = INVALID_MODIFICATION_ERR;\n        } else { // no errors yet\n            NSError* __autoreleasing error = nil;\n            BOOL bSuccess = NO;\n            if (bCopy) {\n                if (bSrcIsDir && ![self canCopyMoveSrc:srcFullPath ToDestination:newFileSystemPath]) {\n                    // can't copy dir into self\n                    errCode = INVALID_MODIFICATION_ERR;\n                } else if (bNewExists) {\n                    // the full destination should NOT already exist if a copy\n                    errCode = PATH_EXISTS_ERR;\n                } else {\n                    bSuccess = [fileMgr copyItemAtPath:srcFullPath toPath:newFileSystemPath error:&error];\n                }\n            } else { // move\n                // iOS requires that destination must not exist before calling moveTo\n                // is W3C INVALID_MODIFICATION_ERR error if destination dir exists and has contents\n                //\n                if (!bSrcIsDir && (bNewExists && bNewIsDir)) {\n                    // can't move a file to directory\n                    errCode = INVALID_MODIFICATION_ERR;\n                } else if (bSrcIsDir && ![self canCopyMoveSrc:srcFullPath ToDestination:newFileSystemPath]) {\n                    // can't move a dir into itself\n                    errCode = INVALID_MODIFICATION_ERR;\n                } else if (bNewExists) {\n                    if (bNewIsDir && ([[fileMgr contentsOfDirectoryAtPath:newFileSystemPath error:NULL] count] != 0)) {\n                        // can't move dir to a dir that is not empty\n                        errCode = INVALID_MODIFICATION_ERR;\n                        newFileSystemPath = nil;  // so we won't try to move\n                    } else {\n                        // remove destination so can perform the moveItemAtPath\n                        bSuccess = [fileMgr removeItemAtPath:newFileSystemPath error:NULL];\n                        if (!bSuccess) {\n                            errCode = INVALID_MODIFICATION_ERR; // is this the correct error?\n                            newFileSystemPath = nil;\n                        }\n                    }\n                } else if (bNewIsDir && [newFileSystemPath hasPrefix:srcFullPath]) {\n                    // can't move a directory inside itself or to any child at any depth;\n                    errCode = INVALID_MODIFICATION_ERR;\n                    newFileSystemPath = nil;\n                }\n\n                if (newFileSystemPath != nil) {\n                    bSuccess = [fileMgr moveItemAtPath:srcFullPath toPath:newFileSystemPath error:&error];\n                }\n            }\n            if (bSuccess) {\n                // should verify it is there and of the correct type???\n                NSDictionary* newEntry = [self makeEntryForPath:newFullPath isDirectory:bSrcIsDir];\n                result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:newEntry];\n            } else {\n                if (error) {\n                    if (([error code] == NSFileReadUnknownError) || ([error code] == NSFileReadTooLargeError)) {\n                        errCode = NOT_READABLE_ERR;\n                    } else if ([error code] == NSFileWriteOutOfSpaceError) {\n                        errCode = QUOTA_EXCEEDED_ERR;\n                    } else if ([error code] == NSFileWriteNoPermissionError) {\n                        errCode = NO_MODIFICATION_ALLOWED_ERR;\n                    }\n                }\n            }\n        }\n    } else {\n        // Need to copy the hard way\n        [srcFs readFileAtURL:srcURL start:0 end:-1 callback:^(NSData* data, NSString* mimeType, CDVFileError errorCode) {\n            CDVPluginResult* result = nil;\n            if (data != nil) {\n                BOOL bSuccess = [data writeToFile:newFileSystemPath atomically:YES];\n                if (bSuccess) {\n                    // should verify it is there and of the correct type???\n                    NSDictionary* newEntry = [self makeEntryForPath:newFullPath isDirectory:NO];\n                    result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:newEntry];\n                } else {\n                    result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:ABORT_ERR];\n                }\n            } else {\n                result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:errorCode];\n            }\n            callback(result);\n        }];\n        return; // Async IO; return without callback.\n    }\n    if (result == nil) {\n        if (!errCode) {\n            errCode = INVALID_MODIFICATION_ERR; // Catch-all default\n        }\n        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:errCode];\n    }\n    callback(result);\n}\n\n/* helper function to get the mimeType from the file extension\n * IN:\n *\tNSString* fullPath - filename (may include path)\n * OUT:\n *\tNSString* the mime type as type/subtype.  nil if not able to determine\n */\n+ (NSString*)getMimeTypeFromPath:(NSString*)fullPath\n{\n    NSString* mimeType = nil;\n\n    if (fullPath) {\n        CFStringRef typeId = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)[fullPath pathExtension], NULL);\n        if (typeId) {\n            mimeType = (__bridge_transfer NSString*)UTTypeCopyPreferredTagWithClass(typeId, kUTTagClassMIMEType);\n            if (!mimeType) {\n                // special case for m4a\n                if ([(__bridge NSString*)typeId rangeOfString : @\"m4a-audio\"].location != NSNotFound) {\n                    mimeType = @\"audio/mp4\";\n                } else if ([[fullPath pathExtension] rangeOfString:@\"wav\"].location != NSNotFound) {\n                    mimeType = @\"audio/wav\";\n                } else if ([[fullPath pathExtension] rangeOfString:@\"css\"].location != NSNotFound) {\n                    mimeType = @\"text/css\";\n                }\n            }\n            CFRelease(typeId);\n        }\n    }\n    return mimeType;\n}\n\n- (void)readFileAtURL:(CDVFilesystemURL *)localURL start:(NSInteger)start end:(NSInteger)end callback:(void (^)(NSData*, NSString* mimeType, CDVFileError))callback\n{\n    NSString *path = [self filesystemPathForURL:localURL];\n\n    NSString* mimeType = [CDVLocalFilesystem getMimeTypeFromPath:path];\n    if (mimeType == nil) {\n        mimeType = @\"*/*\";\n    }\n    NSFileHandle* file = [NSFileHandle fileHandleForReadingAtPath:path];\n    if (start > 0) {\n        [file seekToFileOffset:start];\n    }\n\n    NSData* readData;\n    if (end < 0) {\n        readData = [file readDataToEndOfFile];\n    } else {\n        readData = [file readDataOfLength:(end - start)];\n    }\n    [file closeFile];\n\n    callback(readData, mimeType, readData != nil ? NO_ERROR : NOT_FOUND_ERR);\n}\n\n- (void)getFileMetadataForURL:(CDVFilesystemURL *)localURL callback:(void (^)(CDVPluginResult *))callback\n{\n    NSString *path = [self filesystemPathForURL:localURL];\n    CDVPluginResult *result;\n    NSFileManager* fileMgr = [[NSFileManager alloc] init];\n\n    NSError* __autoreleasing error = nil;\n    NSDictionary* fileAttrs = [fileMgr attributesOfItemAtPath:path error:&error];\n\n    if (fileAttrs) {\n\n        // create dictionary of file info\n        NSMutableDictionary* fileInfo = [NSMutableDictionary dictionaryWithCapacity:5];\n\n        [fileInfo setObject:localURL.fullPath forKey:@\"fullPath\"];\n        [fileInfo setObject:@\"\" forKey:@\"type\"];  // can't easily get the mimetype unless create URL, send request and read response so skipping\n        [fileInfo setObject:[path lastPathComponent] forKey:@\"name\"];\n\n        // Ensure that directories (and other non-regular files) report size of 0\n        unsigned long long size = ([fileAttrs fileType] == NSFileTypeRegular ? [fileAttrs fileSize] : 0);\n        [fileInfo setObject:[NSNumber numberWithUnsignedLongLong:size] forKey:@\"size\"];\n\n        NSDate* modDate = [fileAttrs fileModificationDate];\n        if (modDate) {\n            [fileInfo setObject:[NSNumber numberWithDouble:[modDate timeIntervalSince1970] * 1000] forKey:@\"lastModifiedDate\"];\n        }\n\n        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:fileInfo];\n\n    } else {\n        // didn't get fileAttribs\n        CDVFileError errorCode = ABORT_ERR;\n        NSLog(@\"error getting metadata: %@\", [error localizedDescription]);\n        if ([error code] == NSFileNoSuchFileError || [error code] == NSFileReadNoSuchFileError) {\n            errorCode = NOT_FOUND_ERR;\n        }\n        // log [NSNumber numberWithDouble: theMessage] objCtype to see what it returns\n        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:errorCode];\n    }\n\n    callback(result);\n}\n\n@end\n"
  },
  {
    "path": "plugins/cordova-plugin-file/src/osx/CDVFile.h",
    "content": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements.  See the NOTICE file\n distributed with this work for additional information\n regarding copyright ownership.  The ASF licenses this file\n to you under the Apache License, Version 2.0 (the\n \"License\"); you may not use this file except in compliance\n with the License.  You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an\n \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n KIND, either express or implied.  See the License for the\n specific language governing permissions and limitations\n under the License.\n */\n\n#import <Foundation/Foundation.h>\n#import <Cordova/CDVPlugin.h>\n\nNSString* const kCDVFilesystemURLPrefix;\n\n/**\n* The default filesystems if non are specified.\n*/\n#define CDV_FILESYSTEMS_DEFAULT @\"documents,cache,bundle,root\"\n\n/**\n* Preference name of the extra filesystems to be \"mounted\". the following are supported:\n* 'bundle'    - mounts the application directory\n* 'documents' - mounts the users Documents directory (~/Documents)\n* 'root'      - mounts the root file system\n* 'cache'     - mounts the caches directory (~/Library/Caches/<bundle-id/)\n*/\n#define CDV_PREF_EXTRA_FILESYSTEM @\"osxextrafilesystems\"\n\nenum CDVFileError {\n    NO_ERROR = 0,\n    NOT_FOUND_ERR = 1,\n    SECURITY_ERR = 2,\n    ABORT_ERR = 3,\n    NOT_READABLE_ERR = 4,\n    ENCODING_ERR = 5,\n    NO_MODIFICATION_ALLOWED_ERR = 6,\n    INVALID_STATE_ERR = 7,\n    SYNTAX_ERR = 8,\n    INVALID_MODIFICATION_ERR = 9,\n    QUOTA_EXCEEDED_ERR = 10,\n    TYPE_MISMATCH_ERR = 11,\n    PATH_EXISTS_ERR = 12\n};\ntypedef int CDVFileError;\n\n@interface CDVFilesystemURL : NSObject  {\n    NSURL *_url;\n    NSString *_fileSystemName;\n    NSString *_fullPath;\n}\n\n- (id) initWithString:(NSString*)strURL;\n- (id) initWithURL:(NSURL*)URL;\n+ (CDVFilesystemURL *)fileSystemURLWithString:(NSString *)strURL;\n+ (CDVFilesystemURL *)fileSystemURLWithURL:(NSURL *)URL;\n\n- (NSString *)absoluteURL;\n\n@property (atomic) NSURL *url;\n@property (atomic) NSString *fileSystemName;\n@property (atomic) NSString *fullPath;\n\n@end\n\n@interface CDVFilesystemURLProtocol : NSURLProtocol\n@end\n\n@protocol CDVFileSystem\n- (CDVPluginResult *)entryForLocalURI:(CDVFilesystemURL *)url;\n- (CDVPluginResult *)getFileForURL:(CDVFilesystemURL *)baseURI requestedPath:(NSString *)requestedPath options:(NSDictionary *)options;\n- (CDVPluginResult *)getParentForURL:(CDVFilesystemURL *)localURI;\n- (CDVPluginResult *)setMetadataForURL:(CDVFilesystemURL *)localURI withObject:(NSDictionary *)options;\n- (CDVPluginResult *)removeFileAtURL:(CDVFilesystemURL *)localURI;\n- (CDVPluginResult *)recursiveRemoveFileAtURL:(CDVFilesystemURL *)localURI;\n- (CDVPluginResult *)readEntriesAtURL:(CDVFilesystemURL *)localURI;\n- (CDVPluginResult *)truncateFileAtURL:(CDVFilesystemURL *)localURI atPosition:(unsigned long long)pos;\n- (CDVPluginResult *)writeToFileAtURL:(CDVFilesystemURL *)localURL withData:(NSData*)encData append:(BOOL)shouldAppend;\n- (void)copyFileToURL:(CDVFilesystemURL *)destURL withName:(NSString *)newName fromFileSystem:(NSObject<CDVFileSystem> *)srcFs atURL:(CDVFilesystemURL *)srcURL copy:(BOOL)bCopy callback:(void (^)(CDVPluginResult *))callback;\n- (void)readFileAtURL:(CDVFilesystemURL *)localURL start:(NSInteger)start end:(NSInteger)end callback:(void (^)(NSData*, NSString* mimeType, CDVFileError))callback;\n- (void)getFileMetadataForURL:(CDVFilesystemURL *)localURL callback:(void (^)(CDVPluginResult *))callback;\n\n- (NSDictionary *)makeEntryForLocalURL:(CDVFilesystemURL *)url;\n- (NSDictionary*)makeEntryForPath:(NSString*)fullPath isDirectory:(BOOL)isDir;\n\n@property (nonatomic,strong) NSString *name;\n@property (nonatomic, copy) NSURL*(^urlTransformer)(NSURL*);\n\n@optional\n- (NSString *)filesystemPathForURL:(CDVFilesystemURL *)localURI;\n- (CDVFilesystemURL *)URLforFilesystemPath:(NSString *)path;\n\n@end\n\n@interface CDVFile : CDVPlugin {\n    NSString* rootDocsPath;\n    NSString* appDocsPath;\n    NSString* appLibraryPath;\n    NSString* appTempPath;\n\n    NSMutableArray* fileSystems_;\n    BOOL userHasAllowed;\n}\n\n- (NSNumber*)checkFreeDiskSpace:(NSString*)appPath;\n- (NSDictionary*)makeEntryForPath:(NSString*)fullPath fileSystemName:(NSString *)fsName isDirectory:(BOOL)isDir;\n- (NSDictionary *)makeEntryForURL:(NSURL *)URL;\n- (CDVFilesystemURL *)fileSystemURLforLocalPath:(NSString *)localPath;\n\n- (NSObject<CDVFileSystem> *)filesystemForURL:(CDVFilesystemURL *)localURL;\n\n/* Native Registration API */\n- (void)registerFilesystem:(NSObject<CDVFileSystem> *)fs;\n- (NSObject<CDVFileSystem> *)fileSystemByName:(NSString *)fsName;\n\n/* Exec API */\n- (void)requestFileSystem:(CDVInvokedUrlCommand*)command;\n- (void)resolveLocalFileSystemURI:(CDVInvokedUrlCommand*)command;\n- (void)getDirectory:(CDVInvokedUrlCommand*)command;\n- (void)getFile:(CDVInvokedUrlCommand*)command;\n- (void)getParent:(CDVInvokedUrlCommand*)command;\n- (void)removeRecursively:(CDVInvokedUrlCommand*)command;\n- (void)remove:(CDVInvokedUrlCommand*)command;\n- (void)copyTo:(CDVInvokedUrlCommand*)command;\n- (void)moveTo:(CDVInvokedUrlCommand*)command;\n- (void)getFileMetadata:(CDVInvokedUrlCommand*)command;\n- (void)readEntries:(CDVInvokedUrlCommand*)command;\n- (void)readAsText:(CDVInvokedUrlCommand*)command;\n- (void)readAsDataURL:(CDVInvokedUrlCommand*)command;\n- (void)readAsArrayBuffer:(CDVInvokedUrlCommand*)command;\n- (void)write:(CDVInvokedUrlCommand*)command;\n- (void)testFileExists:(CDVInvokedUrlCommand*)command;\n- (void)testDirectoryExists:(CDVInvokedUrlCommand*)command;\n- (void)getFreeDiskSpace:(CDVInvokedUrlCommand*)command;\n- (void)truncate:(CDVInvokedUrlCommand*)command;\n- (void)doCopyMove:(CDVInvokedUrlCommand*)command isCopy:(BOOL)bCopy;\n\n/* Compatibilty with older File API */\n- (NSString*)getMimeTypeFromPath:(NSString*)fullPath;\n- (NSDictionary *)getDirectoryEntry:(NSString *)target isDirectory:(BOOL)bDirRequest;\n\n/* Conversion between filesystem paths and URLs */\n- (NSString *)filesystemPathForURL:(CDVFilesystemURL *)URL;\n\n/* Internal methods for testing */\n- (void)_getLocalFilesystemPath:(CDVInvokedUrlCommand*)command;\n\n/**\n * local path of the 'documents' file system (~/Documents)\n */\n@property (nonatomic, strong) NSString* appDocsPath;\n\n/**\n* local path of the 'applicationStorageDirectory' file system (~/Library/Application Support/<bundle-id>)\n*/\n@property (nonatomic, strong) NSString* appSupportPath;\n\n/**\n* local path of the 'persistent' file system (~/Library/Application Support/<bundle-id>/files)\n*/\n@property (nonatomic, strong) NSString* appDataPath;\n\n/**\n* local path of the 'documents' file system (~/Documents)\n*/\n@property (nonatomic, strong) NSString* appTempPath;\n\n/**\n* local path of the 'cache' file system (~/Library/Caches/<bundle-id>)\n*/\n@property (nonatomic, strong) NSString* appCachePath;\n\n/**\n * registered file systems\n */\n@property (nonatomic, strong) NSMutableArray* fileSystems;\n\n@property BOOL userHasAllowed;\n\n@end\n"
  },
  {
    "path": "plugins/cordova-plugin-file/src/osx/CDVFile.m",
    "content": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements.  See the NOTICE file\n distributed with this work for additional information\n regarding copyright ownership.  The ASF licenses this file\n to you under the Apache License, Version 2.0 (the\n \"License\"); you may not use this file except in compliance\n with the License.  You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an\n \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n KIND, either express or implied.  See the License for the\n specific language governing permissions and limitations\n under the License.\n */\n\n#import \"CDVFile.h\"\n#import \"CDVLocalFilesystem.h\"\n#import <objc/message.h>\n\nstatic NSString* toBase64(NSData* data) {\n    SEL s1 = NSSelectorFromString(@\"cdv_base64EncodedString\");\n    SEL s2 = NSSelectorFromString(@\"base64EncodedString\");\n    SEL s3 = NSSelectorFromString(@\"base64EncodedStringWithOptions:\");\n\n    if ([data respondsToSelector:s1]) {\n        NSString* (*func)(id, SEL) = (void *)[data methodForSelector:s1];\n        return func(data, s1);\n    } else if ([data respondsToSelector:s2]) {\n        NSString* (*func)(id, SEL) = (void *)[data methodForSelector:s2];\n        return func(data, s2);\n    } else if ([data respondsToSelector:s3]) {\n        NSString* (*func)(id, SEL, NSUInteger) = (void *)[data methodForSelector:s3];\n        return func(data, s3, 0);\n    } else {\n        return nil;\n    }\n}\n\nCDVFile *filePlugin = nil;\n\nextern NSString * const NSURLIsExcludedFromBackupKey __attribute__((weak_import));\n\n#ifndef __IPHONE_5_1\n    NSString* const NSURLIsExcludedFromBackupKey = @\"NSURLIsExcludedFromBackupKey\";\n#endif\n\nNSString* const kCDVFilesystemURLPrefix = @\"cdvfile\";\n\n@implementation CDVFilesystemURL\n@synthesize url=_url;\n@synthesize fileSystemName=_fileSystemName;\n@synthesize fullPath=_fullPath;\n\n- (id) initWithString:(NSString *)strURL\n{\n    if ( self = [super init] ) {\n        NSURL *decodedURL = [NSURL URLWithString:strURL];\n        return [self initWithURL:decodedURL];\n    }\n    return nil;\n}\n\n-(id) initWithURL:(NSURL *)URL\n{\n    if ( self = [super init] ) {\n        _url = URL;\n        _fileSystemName = [self filesystemNameForLocalURI:URL];\n        _fullPath = [self fullPathForLocalURI:URL];\n    }\n    return self;\n}\n\n/*\n * IN\n *  NSString localURI\n * OUT\n *  NSString FileSystem Name for this URI, or nil if it is not recognized.\n */\n- (NSString *)filesystemNameForLocalURI:(NSURL *)uri\n{\n    if ([[uri scheme] isEqualToString:kCDVFilesystemURLPrefix] && [[uri host] isEqualToString:@\"localhost\"]) {\n        NSArray *pathComponents = [uri pathComponents];\n        if (pathComponents != nil && pathComponents.count > 1) {\n            return [pathComponents objectAtIndex:1];\n        }\n    }\n    return nil;\n}\n\n/*\n * IN\n *  NSString localURI\n * OUT\n *  NSString fullPath component suitable for an Entry object.\n * The incoming URI should be properly escaped. The returned fullPath is unescaped.\n */\n- (NSString *)fullPathForLocalURI:(NSURL *)uri\n{\n    if ([[uri scheme] isEqualToString:kCDVFilesystemURLPrefix] && [[uri host] isEqualToString:@\"localhost\"]) {\n        NSString *path = [uri path];\n        if ([uri query]) {\n            path = [NSString stringWithFormat:@\"%@?%@\", path, [uri query]];\n        }\n        NSRange slashRange = [path rangeOfString:@\"/\" options:0 range:NSMakeRange(1, path.length-1)];\n        if (slashRange.location == NSNotFound) {\n            return @\"\";\n        }\n        return [path substringFromIndex:slashRange.location];\n    }\n    return nil;\n}\n\n+ (CDVFilesystemURL *)fileSystemURLWithString:(NSString *)strURL\n{\n    return [[CDVFilesystemURL alloc] initWithString:strURL];\n}\n\n+ (CDVFilesystemURL *)fileSystemURLWithURL:(NSURL *)URL\n{\n    return [[CDVFilesystemURL alloc] initWithURL:URL];\n}\n\n- (NSString *)absoluteURL\n{\n    return [NSString stringWithFormat:@\"cdvfile://localhost/%@%@\", self.fileSystemName, self.fullPath];\n}\n\n@end\n\n@implementation CDVFilesystemURLProtocol\n\n+ (BOOL)canInitWithRequest:(NSURLRequest*)request\n{\n    NSURL* url = [request URL];\n    return [[url scheme] isEqualToString:kCDVFilesystemURLPrefix];\n}\n\n+ (NSURLRequest*)canonicalRequestForRequest:(NSURLRequest*)request\n{\n    return request;\n}\n\n+ (BOOL)requestIsCacheEquivalent:(NSURLRequest*)requestA toRequest:(NSURLRequest*)requestB\n{\n    return [[[requestA URL] resourceSpecifier] isEqualToString:[[requestB URL] resourceSpecifier]];\n}\n\n- (void)startLoading\n{\n    CDVFilesystemURL* url = [CDVFilesystemURL fileSystemURLWithURL:[[self request] URL]];\n    NSObject<CDVFileSystem> *fs = [filePlugin filesystemForURL:url];\n    [fs readFileAtURL:url start:0 end:-1 callback:^void(NSData *data, NSString *mimetype, CDVFileError error) {\n        NSMutableDictionary* responseHeaders = [[NSMutableDictionary alloc] init];\n        responseHeaders[@\"Cache-Control\"] = @\"no-cache\";\n\n        if (!error) {\n            responseHeaders[@\"Content-Type\"] = mimetype;\n            NSURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:url.url statusCode:200 HTTPVersion:@\"HTTP/1.1\"headerFields:responseHeaders];\n            [[self client] URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];\n            [[self client] URLProtocol:self didLoadData:data];\n            [[self client] URLProtocolDidFinishLoading:self];\n        } else {\n            NSURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:url.url statusCode:404 HTTPVersion:@\"HTTP/1.1\"headerFields:responseHeaders];\n            [[self client] URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];\n            [[self client] URLProtocolDidFinishLoading:self];\n        }\n    }];\n}\n\n- (void)stopLoading\n{}\n\n- (NSCachedURLResponse *)connection:(NSURLConnection *)connection\n                  willCacheResponse:(NSCachedURLResponse*)cachedResponse {\n    return nil;\n}\n\n@end\n\n\n@implementation CDVFile\n\n@synthesize appDocsPath, appDataPath, appSupportPath, appTempPath, appCachePath, userHasAllowed, fileSystems=fileSystems_;\n\n- (void)registerFilesystem:(NSObject<CDVFileSystem> *)fs {\n    __weak CDVFile* weakSelf = self;\n    SEL sel = NSSelectorFromString(@\"urlTransformer\");\n    // for backwards compatibility - we check if this property is there\n    // we create a wrapper block because the urlTransformer property\n    // on the commandDelegate might be set dynamically at a future time\n    // (and not dependent on plugin loading order)\n    if ([self.commandDelegate respondsToSelector:sel]) {\n        fs.urlTransformer = ^NSURL*(NSURL* urlToTransform) {\n            // grab the block from the commandDelegate\n            NSURL* (^urlTransformer)(NSURL*) = ((id(*)(id, SEL))objc_msgSend)(weakSelf.commandDelegate, sel);\n            // if block is not null, we call it\n            if (urlTransformer) {\n                return urlTransformer(urlToTransform);\n            } else { // else we return the same url\n                return urlToTransform;\n            }\n        };\n    }\n    [fileSystems_ addObject:fs];\n}\n\n- (NSObject<CDVFileSystem> *)fileSystemByName:(NSString *)fsName\n{\n    if (self.fileSystems != nil) {\n        for (NSObject<CDVFileSystem> *fs in self.fileSystems) {\n            if ([fs.name isEqualToString:fsName]) {\n                return fs;\n            }\n        }\n    }\n    return nil;\n\n}\n\n- (NSObject<CDVFileSystem> *)filesystemForURL:(CDVFilesystemURL *)localURL {\n    if (localURL.fileSystemName == nil) return nil;\n    @try {\n        return [self fileSystemByName:localURL.fileSystemName];\n    }\n    @catch (NSException *e) {\n        return nil;\n    }\n}\n\n- (NSArray *)getExtraFileSystemsPreference:(NSWindowController *)vc\n{\n    NSString *filesystemsStr = nil;\n    if([self.viewController isKindOfClass:[CDVViewController class]]) {\n        CDVViewController *vc = self.viewController;\n        NSDictionary *settings = [vc settings];\n        filesystemsStr = [settings[CDV_PREF_EXTRA_FILESYSTEM] lowercaseString];\n    }\n    if (!filesystemsStr) {\n        filesystemsStr = CDV_FILESYSTEMS_DEFAULT;\n    }\n    return [filesystemsStr componentsSeparatedByString:@\",\"];\n}\n\n- (void)makeNonSyncable:(NSString*)path {\n    [[NSFileManager defaultManager] createDirectoryAtPath:path\n              withIntermediateDirectories:YES\n                               attributes:nil\n                                    error:nil];\n    NSURL* url = [NSURL fileURLWithPath:path];\n    [url setResourceValue: [NSNumber numberWithBool: YES]\n                   forKey: NSURLIsExcludedFromBackupKey error:nil];\n\n}\n\n- (void)registerExtraFileSystems:(NSArray *)filesystems fromAvailableSet:(NSDictionary *)availableFileSystems\n{\n    NSMutableSet *installedFilesystems = [[NSMutableSet alloc] initWithCapacity:7];\n\n    /* Register filesystems in order */\n    for (NSString *fsName in filesystems) {\n        if (![installedFilesystems containsObject:fsName]) {\n            NSString *fsRoot = availableFileSystems[fsName];\n            if (fsRoot) {\n                [filePlugin registerFilesystem:[[CDVLocalFilesystem alloc] initWithName:fsName root:fsRoot]];\n                [installedFilesystems addObject:fsName];\n            } else {\n                NSLog(@\"Unrecognized extra filesystem identifier: %@\", fsName);\n            }\n        }\n    }\n}\n\n- (NSDictionary *)getAvailableFileSystems\n{\n    return @{\n        @\"documents\": self.appDocsPath,\n        @\"cache\": self.appCachePath,\n        @\"bundle\": [[NSBundle mainBundle] bundlePath],\n        @\"root\": @\"/\"\n    };\n}\n\n- (void)pluginInitialize\n{   filePlugin = self;\n    [NSURLProtocol registerClass:[CDVFilesystemURLProtocol class]];\n\n    fileSystems_ = [[NSMutableArray alloc] initWithCapacity:3];\n\n    // Get the Temporary directory path\n    self.appTempPath = [NSTemporaryDirectory()stringByStandardizingPath];   // remove trailing slash from NSTemporaryDirectory()\n    [self registerFilesystem:[[CDVLocalFilesystem alloc] initWithName:@\"temporary\" root:self.appTempPath]];\n\n    // ~/Library/Application Support/<bundle-id>\n    self.appSupportPath = [self getSupportDirectoryFor:NSApplicationSupportDirectory pathComponents:nil];\n\n    // ~/Library/Application Support/<bundle-id>/files\n    self.appDataPath = [self getSupportDirectoryFor:NSApplicationSupportDirectory pathComponents:@[@\"files\"]];\n    [self registerFilesystem:[[CDVLocalFilesystem alloc] initWithName:@\"persistent\" root:self.appDataPath]];\n\n    // ~/Documents/\n    self.appDocsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];\n\n    // ~/Library/Caches/<bundle-id>/files\n    self.appCachePath = [self getSupportDirectoryFor:NSCachesDirectory pathComponents:nil];\n\n    [self registerExtraFileSystems:[self getExtraFileSystemsPreference:self.viewController]\n                  fromAvailableSet:[self getAvailableFileSystems]];\n}\n\n- (NSString*) getSupportDirectoryFor: (NSSearchPathDirectory) directory pathComponents: (NSArray*) components  {\n    NSError* error;\n    NSFileManager* fm = [NSFileManager defaultManager];\n    NSURL* supportDir = [fm URLForDirectory:directory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:&error];\n    if (supportDir == nil) {\n        NSLog(@\"unable to get support directory: %@\", error);\n        return nil;\n    }\n\n    NSString* bundleID = [[NSBundle mainBundle] bundleIdentifier];\n    NSURL *dirPath = [supportDir URLByAppendingPathComponent:bundleID];\n    for (NSString* pathComponent in components) {\n        dirPath = [dirPath URLByAppendingPathComponent:pathComponent];\n    }\n\n    if (![fm fileExistsAtPath:dirPath.path]) {\n        if (![fm createDirectoryAtURL:dirPath withIntermediateDirectories:YES attributes:nil error:&error]) {\n            NSLog(@\"unable to create support directory: %@\", error);\n            return nil;\n        }\n    }\n    return dirPath.path;\n}\n\n\n- (CDVFilesystemURL *)fileSystemURLforArg:(NSString *)urlArg\n{\n    CDVFilesystemURL* ret = nil;\n    if ([urlArg hasPrefix:@\"file://\"]) {\n        /* This looks like a file url. Get the path, and see if any handlers recognize it. */\n        NSURL *fileURL = [NSURL URLWithString:urlArg];\n        NSURL *resolvedFileURL = [fileURL URLByResolvingSymlinksInPath];\n        NSString *path = [resolvedFileURL path];\n        ret = [self fileSystemURLforLocalPath:path];\n    } else {\n        ret = [CDVFilesystemURL fileSystemURLWithString:urlArg];\n    }\n    return ret;\n}\n\n- (CDVFilesystemURL *)fileSystemURLforLocalPath:(NSString *)localPath\n{\n    CDVFilesystemURL *localURL = nil;\n    NSUInteger shortestFullPath = 0;\n\n    // Try all installed filesystems, in order. Return the most match url.\n    for (id object in self.fileSystems) {\n        if ([object respondsToSelector:@selector(URLforFilesystemPath:)]) {\n            CDVFilesystemURL *url = [object URLforFilesystemPath:localPath];\n            if (url){\n                // A shorter fullPath would imply that the filesystem is a better match for the local path\n                if (!localURL || ([[url fullPath] length] < shortestFullPath)) {\n                    localURL = url;\n                    shortestFullPath = [[url fullPath] length];\n                }\n            }\n        }\n    }\n    return localURL;\n}\n\n- (NSNumber*)checkFreeDiskSpace:(NSString*)appPath\n{\n    NSFileManager* fMgr = [[NSFileManager alloc] init];\n\n    NSError* __autoreleasing pError = nil;\n\n    NSDictionary* pDict = [fMgr attributesOfFileSystemForPath:appPath error:&pError];\n    NSNumber* pNumAvail = (NSNumber*)[pDict objectForKey:NSFileSystemFreeSize];\n\n    return pNumAvail;\n}\n\n/* Request the File System info\n *\n * IN:\n * arguments[0] - type (number as string)\n *\tTEMPORARY = 0, PERSISTENT = 1;\n * arguments[1] - size\n *\n * OUT:\n *\tDictionary representing FileSystem object\n *\t\tname - the human readable directory name\n *\t\troot = DirectoryEntry object\n *\t\t\tbool isDirectory\n *\t\t\tbool isFile\n *\t\t\tstring name\n *\t\t\tstring fullPath\n *\t\t\tfileSystem = FileSystem object - !! ignored because creates circular reference !!\n */\n\n- (void)requestFileSystem:(CDVInvokedUrlCommand*)command\n{\n    // arguments\n    NSString* strType = [command argumentAtIndex:0];\n    unsigned long long size = [[command argumentAtIndex:1] longLongValue];\n\n    int type = [strType intValue];\n    CDVPluginResult* result = nil;\n\n    if (type > self.fileSystems.count) {\n        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:NOT_FOUND_ERR];\n        NSLog(@\"No filesystem of type requested\");\n    } else {\n        NSString* fullPath = @\"/\";\n        // check for avail space for size request\n        NSNumber* pNumAvail = [self checkFreeDiskSpace:self.appSupportPath];\n        // NSLog(@\"Free space: %@\", [NSString stringWithFormat:@\"%qu\", [ pNumAvail unsignedLongLongValue ]]);\n        if (pNumAvail && ([pNumAvail unsignedLongLongValue] < size)) {\n            result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:QUOTA_EXCEEDED_ERR];\n        } else {\n            NSObject<CDVFileSystem> *rootFs = [self.fileSystems objectAtIndex:type];\n            if (rootFs == nil) {\n                result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:NOT_FOUND_ERR];\n                NSLog(@\"No filesystem of type requested\");\n            } else {\n                NSMutableDictionary* fileSystem = [NSMutableDictionary dictionaryWithCapacity:2];\n                [fileSystem setObject:rootFs.name forKey:@\"name\"];\n                NSDictionary* dirEntry = [self makeEntryForPath:fullPath fileSystemName:rootFs.name isDirectory:YES];\n                [fileSystem setObject:dirEntry forKey:@\"root\"];\n                result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:fileSystem];\n            }\n        }\n    }\n    [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n}\n\n\n- (void)requestAllFileSystems:(CDVInvokedUrlCommand*)command\n{\n    NSMutableArray* ret = [[NSMutableArray alloc] init];\n    for (NSObject<CDVFileSystem>* root in fileSystems_) {\n        [ret addObject:[self makeEntryForPath:@\"/\" fileSystemName:root.name isDirectory:YES]];\n    }\n    CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsArray:ret];\n    [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n}\n\n- (void)requestAllPaths:(CDVInvokedUrlCommand*)command\n{\n    NSDictionary* ret = @{\n        @\"applicationDirectory\": [[NSURL fileURLWithPath:[[NSBundle mainBundle] resourcePath]] absoluteString],\n        @\"applicationStorageDirectory\": [[NSURL fileURLWithPath:self.appSupportPath] absoluteString],\n        @\"dataDirectory\": [[NSURL fileURLWithPath:self.appDataPath] absoluteString],\n        @\"documentsDirectory\": [[NSURL fileURLWithPath:self.appDocsPath] absoluteString],\n        @\"cacheDirectory\": [[NSURL fileURLWithPath:self.appCachePath] absoluteString],\n        @\"tempDirectory\":[[NSURL fileURLWithPath:self.appTempPath] absoluteString],\n        @\"rootDirectory\": @\"file:///\",\n    };\n\n    CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:ret];\n    [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n}\n\n/* Creates and returns a dictionary representing an Entry Object\n *\n * IN:\n * NSString* fullPath of the entry\n * int fsType - FileSystem type\n * BOOL isDirectory - YES if this is a directory, NO if is a file\n * OUT:\n * NSDictionary* Entry object\n *\t\tbool as NSNumber isDirectory\n *\t\tbool as NSNumber isFile\n *\t\tNSString*  name - last part of path\n *\t\tNSString* fullPath\n *\t\tNSString* filesystemName - FileSystem name -- actual filesystem will be created on the JS side if necessary, to avoid\n *         creating circular reference (FileSystem contains DirectoryEntry which contains FileSystem.....!!)\n */\n- (NSDictionary*)makeEntryForPath:(NSString*)fullPath fileSystemName:(NSString *)fsName isDirectory:(BOOL)isDir\n{\n    NSObject<CDVFileSystem> *fs = [self fileSystemByName:fsName];\n    return [fs makeEntryForPath:fullPath isDirectory:isDir];\n}\n\n- (NSDictionary *)makeEntryForLocalURL:(CDVFilesystemURL *)localURL\n{\n    NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURL];\n    return [fs makeEntryForLocalURL:localURL];\n}\n\n- (NSDictionary *)makeEntryForURL:(NSURL *)URL\n{\n    CDVFilesystemURL* fsURL = [self fileSystemURLforArg:[URL absoluteString]];\n    return [self makeEntryForLocalURL:fsURL];\n}\n\n/*\n * Given a URI determine the File System information associated with it and return an appropriate W3C entry object\n * IN\n *\tNSString* localURI: Should be an escaped local filesystem URI\n * OUT\n *\tEntry object\n *\t\tbool isDirectory\n *\t\tbool isFile\n *\t\tstring name\n *\t\tstring fullPath\n *\t\tfileSystem = FileSystem object - !! ignored because creates circular reference FileSystem contains DirectoryEntry which contains FileSystem.....!!\n */\n- (void)resolveLocalFileSystemURI:(CDVInvokedUrlCommand*)command\n{\n    // arguments\n    NSString* localURIstr = [command argumentAtIndex:0];\n    CDVPluginResult* result;\n\n    localURIstr = [self encodePath:localURIstr]; //encode path before resolving\n    CDVFilesystemURL* inputURI = [self fileSystemURLforArg:localURIstr];\n\n    if (inputURI == nil || inputURI.fileSystemName == nil) {\n        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:ENCODING_ERR];\n    } else {\n        NSObject<CDVFileSystem> *fs = [self filesystemForURL:inputURI];\n        if (fs == nil) {\n            result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:ENCODING_ERR];\n        } else {\n            result = [fs entryForLocalURI:inputURI];\n        }\n    }\n    [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n}\n\n//encode path with percent escapes\n-(NSString *)encodePath:(NSString *)path\n{\n    NSString *decodedPath = [path stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; //decode incase it's already encoded to avoid encoding twice\n    return [decodedPath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];\n}\n\n\n/* Part of DirectoryEntry interface,  creates or returns the specified directory\n * IN:\n *\tNSString* localURI - local filesystem URI for this directory\n *\tNSString* path - directory to be created/returned; may be full path or relative path\n *\tNSDictionary* - Flags object\n *\t\tboolean as NSNumber create -\n *\t\t\tif create is true and directory does not exist, create dir and return directory entry\n *\t\t\tif create is true and exclusive is true and directory does exist, return error\n *\t\t\tif create is false and directory does not exist, return error\n *\t\t\tif create is false and the path represents a file, return error\n *\t\tboolean as NSNumber exclusive - used in conjunction with create\n *\t\t\tif exclusive is true and create is true - specifies failure if directory already exists\n *\n *\n */\n- (void)getDirectory:(CDVInvokedUrlCommand*)command\n{\n    NSMutableArray* arguments = [NSMutableArray arrayWithArray:command.arguments];\n    NSMutableDictionary* options = nil;\n\n    if ([arguments count] >= 3) {\n        options = [command argumentAtIndex:2 withDefault:nil];\n    }\n    // add getDir to options and call getFile()\n    if (options != nil) {\n        options = [NSMutableDictionary dictionaryWithDictionary:options];\n    } else {\n        options = [NSMutableDictionary dictionaryWithCapacity:1];\n    }\n    [options setObject:[NSNumber numberWithInt:1] forKey:@\"getDir\"];\n    if ([arguments count] >= 3) {\n        [arguments replaceObjectAtIndex:2 withObject:options];\n    } else {\n        [arguments addObject:options];\n    }\n    CDVInvokedUrlCommand* subCommand =\n        [[CDVInvokedUrlCommand alloc] initWithArguments:arguments\n                                             callbackId:command.callbackId\n                                              className:command.className\n                                             methodName:command.methodName];\n\n    [self getFile:subCommand];\n}\n\n/* Part of DirectoryEntry interface,  creates or returns the specified file\n * IN:\n *\tNSString* baseURI - local filesytem URI for the base directory to search\n *\tNSString* requestedPath - file to be created/returned; may be absolute path or relative path\n *\tNSDictionary* options - Flags object\n *\t\tboolean as NSNumber create -\n *\t\t\tif create is true and file does not exist, create file and return File entry\n *\t\t\tif create is true and exclusive is true and file does exist, return error\n *\t\t\tif create is false and file does not exist, return error\n *\t\t\tif create is false and the path represents a directory, return error\n *\t\tboolean as NSNumber exclusive - used in conjunction with create\n *\t\t\tif exclusive is true and create is true - specifies failure if file already exists\n */\n- (void)getFile:(CDVInvokedUrlCommand*)command\n{\n    NSString* baseURIstr = [command argumentAtIndex:0];\n    CDVFilesystemURL* baseURI = [self fileSystemURLforArg:baseURIstr];\n    NSString* requestedPath = [command argumentAtIndex:1];\n    NSDictionary* options = [command argumentAtIndex:2 withDefault:nil];\n\n    NSObject<CDVFileSystem> *fs = [self filesystemForURL:baseURI];\n    CDVPluginResult* result = [fs getFileForURL:baseURI requestedPath:requestedPath options:options];\n\n\n    [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n}\n\n/*\n * Look up the parent Entry containing this Entry.\n * If this Entry is the root of its filesystem, its parent is itself.\n * IN:\n * NSArray* arguments\n *\t0 - NSString* localURI\n * NSMutableDictionary* options\n *\tempty\n */\n- (void)getParent:(CDVInvokedUrlCommand*)command\n{\n    // arguments are URL encoded\n    CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]];\n\n    NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI];\n    CDVPluginResult* result = [fs getParentForURL:localURI];\n\n    [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n}\n\n/*\n * set MetaData of entry\n * Currently we only support \"com.apple.MobileBackup\" (boolean)\n */\n- (void)setMetadata:(CDVInvokedUrlCommand*)command\n{\n    // arguments\n    CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]];\n    NSDictionary* options = [command argumentAtIndex:1 withDefault:nil];\n    NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI];\n    CDVPluginResult* result = [fs setMetadataForURL:localURI withObject:options];\n\n    [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n}\n\n/* removes the directory or file entry\n * IN:\n * NSArray* arguments\n *\t0 - NSString* localURI\n *\n * returns NO_MODIFICATION_ALLOWED_ERR  if is top level directory or no permission to delete dir\n * returns INVALID_MODIFICATION_ERR if is non-empty dir or asset library file\n * returns NOT_FOUND_ERR if file or dir is not found\n*/\n- (void)remove:(CDVInvokedUrlCommand*)command\n{\n    // arguments\n    CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]];\n    CDVPluginResult* result = nil;\n\n    if ([localURI.fullPath isEqualToString:@\"\"]) {\n        // error if try to remove top level (documents or tmp) dir\n        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NO_MODIFICATION_ALLOWED_ERR];\n    } else {\n        NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI];\n        result = [fs removeFileAtURL:localURI];\n    }\n    [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n}\n\n/* recursively removes the directory\n * IN:\n * NSArray* arguments\n *\t0 - NSString* localURI\n *\n * returns NO_MODIFICATION_ALLOWED_ERR  if is top level directory or no permission to delete dir\n * returns NOT_FOUND_ERR if file or dir is not found\n */\n- (void)removeRecursively:(CDVInvokedUrlCommand*)command\n{\n    // arguments\n    CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]];\n    CDVPluginResult* result = nil;\n\n    if ([localURI.fullPath isEqualToString:@\"\"]) {\n        // error if try to remove top level (documents or tmp) dir\n        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NO_MODIFICATION_ALLOWED_ERR];\n    } else {\n        NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI];\n        result = [fs recursiveRemoveFileAtURL:localURI];\n    }\n    [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n}\n\n- (void)copyTo:(CDVInvokedUrlCommand*)command\n{\n    [self doCopyMove:command isCopy:YES];\n}\n\n- (void)moveTo:(CDVInvokedUrlCommand*)command\n{\n    [self doCopyMove:command isCopy:NO];\n}\n\n/* Copy/move a file or directory to a new location\n * IN:\n * NSArray* arguments\n *\t0 - NSString* URL of entry to copy\n *  1 - NSString* URL of the directory into which to copy/move the entry\n *  2 - Optionally, the new name of the entry, defaults to the current name\n *\tBOOL - bCopy YES if copy, NO if move\n */\n- (void)doCopyMove:(CDVInvokedUrlCommand*)command isCopy:(BOOL)bCopy\n{\n    NSArray* arguments = command.arguments;\n\n    // arguments\n    NSString* srcURLstr = [command argumentAtIndex:0];\n    NSString* destURLstr = [command argumentAtIndex:1];\n\n    CDVPluginResult *result;\n\n    if (!srcURLstr || !destURLstr) {\n        // either no source or no destination provided\n        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_FOUND_ERR];\n        [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n        return;\n    }\n\n    CDVFilesystemURL* srcURL = [self fileSystemURLforArg:srcURLstr];\n    CDVFilesystemURL* destURL = [self fileSystemURLforArg:destURLstr];\n\n    NSObject<CDVFileSystem> *srcFs = [self filesystemForURL:srcURL];\n    NSObject<CDVFileSystem> *destFs = [self filesystemForURL:destURL];\n\n    // optional argument; use last component from srcFullPath if new name not provided\n    NSString* newName = ([arguments count] > 2) ? [command argumentAtIndex:2] : [srcURL.url lastPathComponent];\n    if ([newName rangeOfString:@\":\"].location != NSNotFound) {\n        // invalid chars in new name\n        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:ENCODING_ERR];\n        [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n        return;\n    }\n\n    [destFs copyFileToURL:destURL withName:newName fromFileSystem:srcFs atURL:srcURL copy:bCopy callback:^(CDVPluginResult* result) {\n        [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n    }];\n\n}\n\n- (void)getFileMetadata:(CDVInvokedUrlCommand*)command\n{\n    // arguments\n    CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]];\n    NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI];\n\n    [fs getFileMetadataForURL:localURI callback:^(CDVPluginResult* result) {\n        [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n    }];\n}\n\n- (void)readEntries:(CDVInvokedUrlCommand*)command\n{\n    CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]];\n    NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI];\n    CDVPluginResult *result = [fs readEntriesAtURL:localURI];\n\n    [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n}\n\n/* read and return file data\n * IN:\n * NSArray* arguments\n *\t0 - NSString* fullPath\n *\t1 - NSString* encoding\n *\t2 - NSString* start\n *\t3 - NSString* end\n */\n- (void)readAsText:(CDVInvokedUrlCommand*)command\n{\n    // arguments\n    CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]];\n    NSString* encoding = [command argumentAtIndex:1];\n    NSInteger start = [[command argumentAtIndex:2] integerValue];\n    NSInteger end = [[command argumentAtIndex:3] integerValue];\n\n    NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI];\n\n    if (fs == nil) {\n        CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_FOUND_ERR];\n        [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n        return;\n    }\n\n    // TODO: implement\n    if ([@\"UTF-8\" caseInsensitiveCompare : encoding] != NSOrderedSame) {\n        NSLog(@\"Only UTF-8 encodings are currently supported by readAsText\");\n        CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:ENCODING_ERR];\n        [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n        return;\n    }\n\n    [self.commandDelegate runInBackground:^ {\n        [fs readFileAtURL:localURI start:start end:end callback:^(NSData* data, NSString* mimeType, CDVFileError errorCode) {\n            CDVPluginResult* result = nil;\n            if (data != nil) {\n                NSString* str = [[NSString alloc] initWithBytesNoCopy:(void*)[data bytes] length:[data length] encoding:NSUTF8StringEncoding freeWhenDone:NO];\n                // Check that UTF8 conversion did not fail.\n                if (str != nil) {\n                    result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:str];\n                    result.associatedObject = data;\n                } else {\n                    errorCode = ENCODING_ERR;\n                }\n            }\n            if (result == nil) {\n                result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:errorCode];\n            }\n\n            [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n        }];\n    }];\n}\n\n/* Read content of text file and return as base64 encoded data url.\n * IN:\n * NSArray* arguments\n *\t0 - NSString* fullPath\n *\t1 - NSString* start\n *\t2 - NSString* end\n *\n * Determines the mime type from the file extension, returns ENCODING_ERR if mimetype can not be determined.\n */\n\n- (void)readAsDataURL:(CDVInvokedUrlCommand*)command\n{\n    CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]];\n    NSInteger start = [[command argumentAtIndex:1] integerValue];\n    NSInteger end = [[command argumentAtIndex:2] integerValue];\n\n    NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI];\n\n    [self.commandDelegate runInBackground:^ {\n        [fs readFileAtURL:localURI start:start end:end callback:^(NSData* data, NSString* mimeType, CDVFileError errorCode) {\n            CDVPluginResult* result = nil;\n            if (data != nil) {\n                NSString* b64Str = toBase64(data);\n                NSString* output = [NSString stringWithFormat:@\"data:%@;base64,%@\", mimeType, b64Str];\n                result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:output];\n            } else {\n                result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:errorCode];\n            }\n\n            [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n        }];\n    }];\n}\n\n/* Read content of text file and return as an arraybuffer\n * IN:\n * NSArray* arguments\n *\t0 - NSString* fullPath\n *\t1 - NSString* start\n *\t2 - NSString* end\n */\n\n- (void)readAsArrayBuffer:(CDVInvokedUrlCommand*)command\n{\n    CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]];\n    NSInteger start = [[command argumentAtIndex:1] integerValue];\n    NSInteger end = [[command argumentAtIndex:2] integerValue];\n\n    NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI];\n\n    [self.commandDelegate runInBackground:^ {\n        [fs readFileAtURL:localURI start:start end:end callback:^(NSData* data, NSString* mimeType, CDVFileError errorCode) {\n            CDVPluginResult* result = nil;\n            if (data != nil) {\n                result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsArrayBuffer:data];\n            } else {\n                result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:errorCode];\n            }\n\n            [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n        }];\n    }];\n}\n\n- (void)readAsBinaryString:(CDVInvokedUrlCommand*)command\n{\n    CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]];\n    NSInteger start = [[command argumentAtIndex:1] integerValue];\n    NSInteger end = [[command argumentAtIndex:2] integerValue];\n\n    NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI];\n\n    [self.commandDelegate runInBackground:^ {\n        [fs readFileAtURL:localURI start:start end:end callback:^(NSData* data, NSString* mimeType, CDVFileError errorCode) {\n            CDVPluginResult* result = nil;\n            if (data != nil) {\n                NSString* payload = [[NSString alloc] initWithBytesNoCopy:(void*)[data bytes] length:[data length] encoding:NSASCIIStringEncoding freeWhenDone:NO];\n                result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:payload];\n                result.associatedObject = data;\n            } else {\n                result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:errorCode];\n            }\n\n            [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n        }];\n    }];\n}\n\n\n- (void)truncate:(CDVInvokedUrlCommand*)command\n{\n    // arguments\n    CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]];\n    unsigned long long pos = (unsigned long long)[[command argumentAtIndex:1] longLongValue];\n\n    NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI];\n    CDVPluginResult *result = [fs truncateFileAtURL:localURI atPosition:pos];\n\n    [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n}\n\n/* write\n * IN:\n * NSArray* arguments\n *  0 - NSString* localURI of file to write to\n *  1 - NSString* or NSData* data to write\n *  2 - NSNumber* position to begin writing\n */\n- (void)write:(CDVInvokedUrlCommand*)command\n{\n    [self.commandDelegate runInBackground:^ {\n        NSString* callbackId = command.callbackId;\n\n        // arguments\n        CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]];\n        id argData = [command argumentAtIndex:1];\n        unsigned long long pos = (unsigned long long)[[command argumentAtIndex:2] longLongValue];\n\n        NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI];\n\n\n        [fs truncateFileAtURL:localURI atPosition:pos];\n        CDVPluginResult *result;\n        if ([argData isKindOfClass:[NSString class]]) {\n            NSData *encData = [argData dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];\n            result = [fs writeToFileAtURL:localURI withData:encData append:YES];\n        } else if ([argData isKindOfClass:[NSData class]]) {\n            result = [fs writeToFileAtURL:localURI withData:argData append:YES];\n        } else {\n            result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@\"Invalid parameter type\"];\n        }\n        [self.commandDelegate sendPluginResult:result callbackId:callbackId];\n    }];\n}\n\n#pragma mark Methods for converting between URLs and paths\n\n- (NSString *)filesystemPathForURL:(CDVFilesystemURL *)localURL\n{\n    for (NSObject<CDVFileSystem> *fs in self.fileSystems) {\n        if ([fs.name isEqualToString:localURL.fileSystemName]) {\n            if ([fs respondsToSelector:@selector(filesystemPathForURL:)]) {\n                return [fs filesystemPathForURL:localURL];\n            }\n        }\n    }\n    return nil;\n}\n\n#pragma mark Undocumented Filesystem API\n\n- (void)testFileExists:(CDVInvokedUrlCommand*)command\n{\n    // arguments\n    NSString* argPath = [command argumentAtIndex:0];\n\n    // Get the file manager\n    NSFileManager* fMgr = [NSFileManager defaultManager];\n    NSString* appFile = argPath; // [ self getFullPath: argPath];\n\n    BOOL bExists = [fMgr fileExistsAtPath:appFile];\n    CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:(bExists ? 1 : 0)];\n\n    [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n}\n\n- (void)testDirectoryExists:(CDVInvokedUrlCommand*)command\n{\n    // arguments\n    NSString* argPath = [command argumentAtIndex:0];\n\n    // Get the file manager\n    NSFileManager* fMgr = [[NSFileManager alloc] init];\n    NSString* appFile = argPath; // [self getFullPath: argPath];\n    BOOL bIsDir = NO;\n    BOOL bExists = [fMgr fileExistsAtPath:appFile isDirectory:&bIsDir];\n\n    CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:((bExists && bIsDir) ? 1 : 0)];\n\n    [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n}\n\n// Returns number of bytes available via callback\n- (void)getFreeDiskSpace:(CDVInvokedUrlCommand*)command\n{\n    // no arguments\n\n    NSNumber* pNumAvail = [self checkFreeDiskSpace:self.appDocsPath];\n\n    NSString* strFreeSpace = [NSString stringWithFormat:@\"%qu\", [pNumAvail unsignedLongLongValue]];\n    // NSLog(@\"Free space is %@\", strFreeSpace );\n\n    CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:strFreeSpace];\n\n    [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n}\n\n#pragma mark Compatibility with older File API\n\n- (NSString*)getMimeTypeFromPath:(NSString*)fullPath\n{\n    return [CDVLocalFilesystem getMimeTypeFromPath:fullPath];\n}\n\n- (NSDictionary *)getDirectoryEntry:(NSString *)localPath isDirectory:(BOOL)bDirRequest\n{\n    CDVFilesystemURL *localURL = [self fileSystemURLforLocalPath:localPath];\n    return [self makeEntryForPath:localURL.fullPath fileSystemName:localURL.fileSystemName isDirectory:bDirRequest];\n}\n\n#pragma mark Internal methods for testing\n// Internal methods for testing: Get the on-disk location of a local filesystem url.\n// [Currently used for testing file-transfer]\n\n- (void)_getLocalFilesystemPath:(CDVInvokedUrlCommand*)command\n{\n    CDVFilesystemURL* localURL = [self fileSystemURLforArg:command.arguments[0]];\n\n    NSString* fsPath = [self filesystemPathForURL:localURL];\n    CDVPluginResult* result;\n    if (fsPath) {\n        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:fsPath];\n    } else {\n        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@\"Cannot resolve URL to a file\"];\n    }\n    [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n}\n\n@end\n"
  },
  {
    "path": "plugins/cordova-plugin-file/src/osx/CDVLocalFilesystem.h",
    "content": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements.  See the NOTICE file\n distributed with this work for additional information\n regarding copyright ownership.  The ASF licenses this file\n to you under the Apache License, Version 2.0 (the\n \"License\"); you may not use this file except in compliance\n with the License.  You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an\n \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n KIND, either express or implied.  See the License for the\n specific language governing permissions and limitations\n under the License.\n */\n\n#import \"CDVFile.h\"\n\n@interface CDVLocalFilesystem : NSObject<CDVFileSystem> {\n    NSString *_name;\n    NSString *_fsRoot;\n}\n\n- (id) initWithName:(NSString *)name root:(NSString *)fsRoot;\n+ (NSString*)getMimeTypeFromPath:(NSString*)fullPath;\n\n@property (nonatomic,strong) NSString *fsRoot;\n\n@end\n"
  },
  {
    "path": "plugins/cordova-plugin-file/src/osx/CDVLocalFilesystem.m",
    "content": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements.  See the NOTICE file\n distributed with this work for additional information\n regarding copyright ownership.  The ASF licenses this file\n to you under the Apache License, Version 2.0 (the\n \"License\"); you may not use this file except in compliance\n with the License.  You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an\n \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n KIND, either express or implied.  See the License for the\n specific language governing permissions and limitations\n under the License.\n */\n\n#import \"CDVFile.h\"\n#import \"CDVLocalFilesystem.h\"\n#import <sys/xattr.h>\n\n@implementation CDVLocalFilesystem\n@synthesize name=_name, fsRoot=_fsRoot, urlTransformer;\n\n- (id) initWithName:(NSString *)name root:(NSString *)fsRoot\n{\n    if (self) {\n        _name = name;\n        _fsRoot = fsRoot;\n    }\n    return self;\n}\n\n/*\n * IN\n *  NSString localURI\n * OUT\n *  CDVPluginResult result containing a file or directoryEntry for the localURI, or an error if the\n *   URI represents a non-existent path, or is unrecognized or otherwise malformed.\n */\n- (CDVPluginResult *)entryForLocalURI:(CDVFilesystemURL *)url\n{\n    CDVPluginResult* result = nil;\n    NSDictionary* entry = [self makeEntryForLocalURL:url];\n    if (entry) {\n        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:entry];\n    } else {\n        // return NOT_FOUND_ERR\n        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_FOUND_ERR];\n    }\n    return result;\n}\n- (NSDictionary *)makeEntryForLocalURL:(CDVFilesystemURL *)url {\n    NSString *path = [self filesystemPathForURL:url];\n    NSFileManager* fileMgr = [[NSFileManager alloc] init];\n    BOOL isDir = NO;\n    // see if exists and is file or dir\n    BOOL bExists = [fileMgr fileExistsAtPath:path isDirectory:&isDir];\n    if (bExists) {\n        return [self makeEntryForPath:url.fullPath isDirectory:isDir];\n    } else {\n        return nil;\n    }\n}\n- (NSDictionary*)makeEntryForPath:(NSString*)fullPath isDirectory:(BOOL)isDir\n{\n    NSMutableDictionary* dirEntry = [NSMutableDictionary dictionaryWithCapacity:5];\n    NSString* lastPart = [[self stripQueryParametersFromPath:fullPath] lastPathComponent];\n    if (isDir && ![fullPath hasSuffix:@\"/\"]) {\n        fullPath = [fullPath stringByAppendingString:@\"/\"];\n    }\n    [dirEntry setObject:[NSNumber numberWithBool:!isDir]  forKey:@\"isFile\"];\n    [dirEntry setObject:[NSNumber numberWithBool:isDir]  forKey:@\"isDirectory\"];\n    [dirEntry setObject:fullPath forKey:@\"fullPath\"];\n    [dirEntry setObject:lastPart forKey:@\"name\"];\n    [dirEntry setObject:self.name forKey: @\"filesystemName\"];\n\n    NSURL* nativeURL = [NSURL fileURLWithPath:[self filesystemPathForFullPath:fullPath]];\n    if (self.urlTransformer) {\n        nativeURL = self.urlTransformer(nativeURL);\n    }\n\n    dirEntry[@\"nativeURL\"] = [nativeURL absoluteString];\n\n    return dirEntry;\n}\n\n- (NSString *)stripQueryParametersFromPath:(NSString *)fullPath\n{\n    NSRange questionMark = [fullPath rangeOfString:@\"?\"];\n    if (questionMark.location != NSNotFound) {\n        return [fullPath substringWithRange:NSMakeRange(0,questionMark.location)];\n    }\n    return fullPath;\n}\n\n- (NSString *)filesystemPathForFullPath:(NSString *)fullPath\n{\n    NSString *path = nil;\n    NSString *strippedFullPath = [self stripQueryParametersFromPath:fullPath];\n    path = [NSString stringWithFormat:@\"%@%@\", self.fsRoot, strippedFullPath];\n    if ([path length] > 1 && [path hasSuffix:@\"/\"]) {\n      path = [path substringToIndex:([path length]-1)];\n    }\n    return path;\n}\n/*\n * IN\n *  NSString localURI\n * OUT\n *  NSString full local filesystem path for the represented file or directory, or nil if no such path is possible\n *  The file or directory does not necessarily have to exist. nil is returned if the filesystem type is not recognized,\n *  or if the URL is malformed.\n * The incoming URI should be properly escaped (no raw spaces, etc. URI percent-encoding is expected).\n */\n- (NSString *)filesystemPathForURL:(CDVFilesystemURL *)url\n{\n    return [self filesystemPathForFullPath:url.fullPath];\n}\n\n- (CDVFilesystemURL *)URLforFullPath:(NSString *)fullPath\n{\n    if (fullPath) {\n        NSString* escapedPath = [fullPath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];\n        if ([fullPath hasPrefix:@\"/\"]) {\n            return [CDVFilesystemURL fileSystemURLWithString:[NSString stringWithFormat:@\"%@://localhost/%@%@\", kCDVFilesystemURLPrefix, self.name, escapedPath]];\n        }\n        return [CDVFilesystemURL fileSystemURLWithString:[NSString stringWithFormat:@\"%@://localhost/%@/%@\", kCDVFilesystemURLPrefix, self.name, escapedPath]];\n    }\n    return nil;\n}\n\n- (CDVFilesystemURL *)URLforFilesystemPath:(NSString *)path\n{\n    return [self URLforFullPath:[self fullPathForFileSystemPath:path]];\n\n}\n\n- (NSString *)normalizePath:(NSString *)rawPath\n{\n    // If this is an absolute path, the first path component will be '/'. Skip it if that's the case\n    BOOL isAbsolutePath = [rawPath hasPrefix:@\"/\"];\n    if (isAbsolutePath) {\n        rawPath = [rawPath substringFromIndex:1];\n    }\n    NSMutableArray *components = [NSMutableArray arrayWithArray:[rawPath pathComponents]];\n    for (int index = 0; index < [components count]; ++index) {\n        if ([[components objectAtIndex:index] isEqualToString:@\"..\"]) {\n            [components removeObjectAtIndex:index];\n            if (index > 0) {\n                [components removeObjectAtIndex:index-1];\n                --index;\n            }\n        }\n    }\n\n    if (isAbsolutePath) {\n        return [NSString stringWithFormat:@\"/%@\", [components componentsJoinedByString:@\"/\"]];\n    } else {\n        return [components componentsJoinedByString:@\"/\"];\n    }\n\n\n}\n\n- (BOOL)valueForKeyIsNumber:(NSDictionary*)dict key:(NSString*)key\n{\n    BOOL bNumber = NO;\n    NSObject* value = dict[key];\n    if (value) {\n        bNumber = [value isKindOfClass:[NSNumber class]];\n    }\n    return bNumber;\n}\n\n- (CDVPluginResult *)getFileForURL:(CDVFilesystemURL *)baseURI requestedPath:(NSString *)requestedPath options:(NSDictionary *)options\n{\n    CDVPluginResult* result = nil;\n    BOOL bDirRequest = NO;\n    BOOL create = NO;\n    BOOL exclusive = NO;\n    int errorCode = 0;  // !!! risky - no error code currently defined for 0\n\n    if ([self valueForKeyIsNumber:options key:@\"create\"]) {\n        create = [(NSNumber*)[options valueForKey:@\"create\"] boolValue];\n    }\n    if ([self valueForKeyIsNumber:options key:@\"exclusive\"]) {\n        exclusive = [(NSNumber*)[options valueForKey:@\"exclusive\"] boolValue];\n    }\n    if ([self valueForKeyIsNumber:options key:@\"getDir\"]) {\n        // this will not exist for calls directly to getFile but will have been set by getDirectory before calling this method\n        bDirRequest = [(NSNumber*)[options valueForKey:@\"getDir\"] boolValue];\n    }\n    // see if the requested path has invalid characters - should we be checking for  more than just \":\"?\n    if ([requestedPath rangeOfString:@\":\"].location != NSNotFound) {\n        errorCode = ENCODING_ERR;\n    } else {\n        // Build new fullPath for the requested resource.\n        // We concatenate the two paths together, and then scan the resulting string to remove\n        // parent (\"..\") references. Any parent references at the beginning of the string are\n        // silently removed.\n        NSString *combinedPath = [baseURI.fullPath stringByAppendingPathComponent:requestedPath];\n        combinedPath = [self normalizePath:combinedPath];\n        CDVFilesystemURL* requestedURL = [self URLforFullPath:combinedPath];\n\n        NSFileManager* fileMgr = [[NSFileManager alloc] init];\n        BOOL bIsDir;\n        BOOL bExists = [fileMgr fileExistsAtPath:[self filesystemPathForURL:requestedURL] isDirectory:&bIsDir];\n        if (bExists && (create == NO) && (bIsDir == !bDirRequest)) {\n            // path exists and is not of requested type  - return TYPE_MISMATCH_ERR\n            errorCode = TYPE_MISMATCH_ERR;\n        } else if (!bExists && (create == NO)) {\n            // path does not exist and create is false - return NOT_FOUND_ERR\n            errorCode = NOT_FOUND_ERR;\n        } else if (bExists && (create == YES) && (exclusive == YES)) {\n            // file/dir already exists and exclusive and create are both true - return PATH_EXISTS_ERR\n            errorCode = PATH_EXISTS_ERR;\n        } else {\n            // if bExists and create == YES - just return data\n            // if bExists and create == NO  - just return data\n            // if !bExists and create == YES - create and return data\n            BOOL bSuccess = YES;\n            NSError __autoreleasing* pError = nil;\n            if (!bExists && (create == YES)) {\n                if (bDirRequest) {\n                    // create the dir\n                    bSuccess = [fileMgr createDirectoryAtPath:[self filesystemPathForURL:requestedURL] withIntermediateDirectories:NO attributes:nil error:&pError];\n                } else {\n                    // create the empty file\n                    bSuccess = [fileMgr createFileAtPath:[self filesystemPathForURL:requestedURL] contents:nil attributes:nil];\n                }\n            }\n            if (!bSuccess) {\n                errorCode = ABORT_ERR;\n                if (pError) {\n                    NSLog(@\"error creating directory: %@\", [pError localizedDescription]);\n                }\n            } else {\n                // NSLog(@\"newly created file/dir (%@) exists: %d\", reqFullPath, [fileMgr fileExistsAtPath:reqFullPath]);\n                // file existed or was created\n                result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:[self makeEntryForPath:requestedURL.fullPath isDirectory:bDirRequest]];\n            }\n        } // are all possible conditions met?\n    }\n\n    if (errorCode > 0) {\n        // create error callback\n        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:errorCode];\n    }\n    return result;\n\n}\n\n- (CDVPluginResult*)getParentForURL:(CDVFilesystemURL *)localURI\n{\n    CDVPluginResult* result = nil;\n    CDVFilesystemURL *newURI = nil;\n    if ([localURI.fullPath isEqualToString:@\"\"]) {\n        // return self\n        newURI = localURI;\n    } else {\n        newURI = [CDVFilesystemURL fileSystemURLWithURL:[localURI.url URLByDeletingLastPathComponent]]; /* TODO: UGLY - FIX */\n    }\n    NSFileManager* fileMgr = [[NSFileManager alloc] init];\n    BOOL bIsDir;\n    BOOL bExists = [fileMgr fileExistsAtPath:[self filesystemPathForURL:newURI] isDirectory:&bIsDir];\n    if (bExists) {\n        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:[self makeEntryForPath:newURI.fullPath isDirectory:bIsDir]];\n    } else {\n        // invalid path or file does not exist\n        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_FOUND_ERR];\n    }\n    return result;\n}\n\n- (CDVPluginResult*)setMetadataForURL:(CDVFilesystemURL *)localURI withObject:(NSDictionary *)options\n{\n    BOOL ok = NO;\n\n    NSString* filePath = [self filesystemPathForURL:localURI];\n    // we only care about this iCloud key for now.\n    // set to 1/true to skip backup, set to 0/false to back it up (effectively removing the attribute)\n    NSString* iCloudBackupExtendedAttributeKey = @\"com.apple.MobileBackup\";\n    id iCloudBackupExtendedAttributeValue = [options objectForKey:iCloudBackupExtendedAttributeKey];\n\n    if ((iCloudBackupExtendedAttributeValue != nil) && [iCloudBackupExtendedAttributeValue isKindOfClass:[NSNumber class]]) {\n// todo: fix me\n//        if (IsAtLeastiOSVersion(@\"5.1\")) {\n//            NSURL* url = [NSURL fileURLWithPath:filePath];\n//            NSError* __autoreleasing error = nil;\n//\n//            ok = [url setResourceValue:[NSNumber numberWithBool:[iCloudBackupExtendedAttributeValue boolValue]] forKey:NSURLIsExcludedFromBackupKey error:&error];\n//        } else { // below 5.1 (deprecated - only really supported in 5.01)\n//            u_int8_t value = [iCloudBackupExtendedAttributeValue intValue];\n//            if (value == 0) { // remove the attribute (allow backup, the default)\n//                ok = (removexattr([filePath fileSystemRepresentation], [iCloudBackupExtendedAttributeKey cStringUsingEncoding:NSUTF8StringEncoding], 0) == 0);\n//            } else { // set the attribute (skip backup)\n//                ok = (setxattr([filePath fileSystemRepresentation], [iCloudBackupExtendedAttributeKey cStringUsingEncoding:NSUTF8StringEncoding], &value, sizeof(value), 0, 0) == 0);\n//            }\n//        }\n    }\n\n    if (ok) {\n        return [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];\n    } else {\n        return [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];\n    }\n}\n\n/* remove the file or directory (recursively)\n * IN:\n * NSString* fullPath - the full path to the file or directory to be removed\n * NSString* callbackId\n * called from remove and removeRecursively - check all pubic api specific error conditions (dir not empty, etc) before calling\n */\n\n- (CDVPluginResult*)doRemove:(NSString*)fullPath\n{\n    CDVPluginResult* result = nil;\n    BOOL bSuccess = NO;\n    NSError* __autoreleasing pError = nil;\n    NSFileManager* fileMgr = [[NSFileManager alloc] init];\n\n    @try {\n        bSuccess = [fileMgr removeItemAtPath:fullPath error:&pError];\n        if (bSuccess) {\n            result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];\n        } else {\n            // see if we can give a useful error\n            CDVFileError errorCode = ABORT_ERR;\n            NSLog(@\"error removing filesystem entry at %@: %@\", fullPath, [pError localizedDescription]);\n            if ([pError code] == NSFileNoSuchFileError) {\n                errorCode = NOT_FOUND_ERR;\n            } else if ([pError code] == NSFileWriteNoPermissionError) {\n                errorCode = NO_MODIFICATION_ALLOWED_ERR;\n            }\n\n            result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:errorCode];\n        }\n    } @catch(NSException* e) {  // NSInvalidArgumentException if path is . or ..\n        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:SYNTAX_ERR];\n    }\n\n    return result;\n}\n\n- (CDVPluginResult *)removeFileAtURL:(CDVFilesystemURL *)localURI\n{\n    NSString *fileSystemPath = [self filesystemPathForURL:localURI];\n\n    NSFileManager* fileMgr = [[NSFileManager alloc] init];\n    BOOL bIsDir = NO;\n    BOOL bExists = [fileMgr fileExistsAtPath:fileSystemPath isDirectory:&bIsDir];\n    if (!bExists) {\n        return [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_FOUND_ERR];\n    }\n    if (bIsDir && ([[fileMgr contentsOfDirectoryAtPath:fileSystemPath error:nil] count] != 0)) {\n        // dir is not empty\n        return [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:INVALID_MODIFICATION_ERR];\n    }\n    return [self doRemove:fileSystemPath];\n}\n\n- (CDVPluginResult *)recursiveRemoveFileAtURL:(CDVFilesystemURL *)localURI\n{\n    NSString *fileSystemPath = [self filesystemPathForURL:localURI];\n    return [self doRemove:fileSystemPath];\n}\n\n/*\n * IN\n *  NSString localURI\n * OUT\n *  NSString full local filesystem path for the represented file or directory, or nil if no such path is possible\n *  The file or directory does not necessarily have to exist. nil is returned if the filesystem type is not recognized,\n *  or if the URL is malformed.\n * The incoming URI should be properly escaped (no raw spaces, etc. URI percent-encoding is expected).\n */\n- (NSString *)fullPathForFileSystemPath:(NSString *)fsPath\n{\n    if ([fsPath hasPrefix:self.fsRoot]) {\n        return [fsPath substringFromIndex:[self.fsRoot length]];\n    }\n    return nil;\n}\n\n\n- (CDVPluginResult *)readEntriesAtURL:(CDVFilesystemURL *)localURI\n{\n    NSFileManager* fileMgr = [[NSFileManager alloc] init];\n    NSError* __autoreleasing error = nil;\n    NSString *fileSystemPath = [self filesystemPathForURL:localURI];\n\n    NSArray* contents = [fileMgr contentsOfDirectoryAtPath:fileSystemPath error:&error];\n\n    if (contents) {\n        NSMutableArray* entries = [NSMutableArray arrayWithCapacity:1];\n        if ([contents count] > 0) {\n            // create an Entry (as JSON) for each file/dir\n            for (NSString* name in contents) {\n                // see if is dir or file\n                NSString* entryPath = [fileSystemPath stringByAppendingPathComponent:name];\n                BOOL bIsDir = NO;\n                [fileMgr fileExistsAtPath:entryPath isDirectory:&bIsDir];\n                NSDictionary* entryDict = [self makeEntryForPath:[self fullPathForFileSystemPath:entryPath] isDirectory:bIsDir];\n                [entries addObject:entryDict];\n            }\n        }\n        return [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsArray:entries];\n    } else {\n        // assume not found but could check error for more specific error conditions\n        return [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_FOUND_ERR];\n    }\n}\n\n- (unsigned long long)truncateFile:(NSString*)filePath atPosition:(unsigned long long)pos\n{\n    unsigned long long newPos = 0UL;\n\n    NSFileHandle* file = [NSFileHandle fileHandleForWritingAtPath:filePath];\n\n    if (file) {\n        [file truncateFileAtOffset:(unsigned long long)pos];\n        newPos = [file offsetInFile];\n        [file synchronizeFile];\n        [file closeFile];\n    }\n    return newPos;\n}\n\n- (CDVPluginResult *)truncateFileAtURL:(CDVFilesystemURL *)localURI atPosition:(unsigned long long)pos\n{\n    unsigned long long newPos = [self truncateFile:[self filesystemPathForURL:localURI] atPosition:pos];\n    return [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:(int)newPos];\n}\n\n- (CDVPluginResult *)writeToFileAtURL:(CDVFilesystemURL *)localURL withData:(NSData*)encData append:(BOOL)shouldAppend\n{\n    NSString *filePath = [self filesystemPathForURL:localURL];\n\n    CDVPluginResult* result = nil;\n    CDVFileError errCode = INVALID_MODIFICATION_ERR;\n    int bytesWritten = 0;\n\n    if (filePath) {\n        NSOutputStream* fileStream = [NSOutputStream outputStreamToFileAtPath:filePath append:shouldAppend];\n        if (fileStream) {\n            NSUInteger len = [encData length];\n            if (len == 0) {\n                result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDouble:(double)len];\n            } else {\n                [fileStream open];\n\n                bytesWritten = (int)[fileStream write:[encData bytes] maxLength:len];\n\n                [fileStream close];\n                if (bytesWritten > 0) {\n                    result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:bytesWritten];\n                    // } else {\n                    // can probably get more detailed error info via [fileStream streamError]\n                    // errCode already set to INVALID_MODIFICATION_ERR;\n                    // bytesWritten = 0; // may be set to -1 on error\n                }\n            }\n        } // else fileStream not created return INVALID_MODIFICATION_ERR\n    } else {\n        // invalid filePath\n        errCode = NOT_FOUND_ERR;\n    }\n    if (!result) {\n        // was an error\n        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:errCode];\n    }\n    return result;\n}\n\n/**\n * Helper function to check to see if the user attempted to copy an entry into its parent without changing its name,\n * or attempted to copy a directory into a directory that it contains directly or indirectly.\n *\n * IN:\n *  NSString* srcDir\n *  NSString* destinationDir\n * OUT:\n *  YES copy/ move is allows\n *  NO move is onto itself\n */\n- (BOOL)canCopyMoveSrc:(NSString*)src ToDestination:(NSString*)dest\n{\n    // This weird test is to determine if we are copying or moving a directory into itself.\n    // Copy /Documents/myDir to /Documents/myDir-backup is okay but\n    // Copy /Documents/myDir to /Documents/myDir/backup not okay\n    BOOL copyOK = YES;\n    NSRange range = [dest rangeOfString:src];\n\n    if (range.location != NSNotFound) {\n        NSRange testRange = {range.length - 1, ([dest length] - range.length)};\n        NSRange resultRange = [dest rangeOfString:@\"/\" options:0 range:testRange];\n        if (resultRange.location != NSNotFound) {\n            copyOK = NO;\n        }\n    }\n    return copyOK;\n}\n\n- (void)copyFileToURL:(CDVFilesystemURL *)destURL withName:(NSString *)newName fromFileSystem:(NSObject<CDVFileSystem> *)srcFs atURL:(CDVFilesystemURL *)srcURL copy:(BOOL)bCopy callback:(void (^)(CDVPluginResult *))callback\n{\n    NSFileManager *fileMgr = [[NSFileManager alloc] init];\n    NSString *destRootPath = [self filesystemPathForURL:destURL];\n    BOOL bDestIsDir = NO;\n    BOOL bDestExists = [fileMgr fileExistsAtPath:destRootPath isDirectory:&bDestIsDir];\n\n    NSString *newFileSystemPath = [destRootPath stringByAppendingPathComponent:newName];\n    NSString *newFullPath = [self fullPathForFileSystemPath:newFileSystemPath];\n\n    BOOL bNewIsDir = NO;\n    BOOL bNewExists = [fileMgr fileExistsAtPath:newFileSystemPath isDirectory:&bNewIsDir];\n\n    CDVPluginResult *result = nil;\n    int errCode = 0;\n\n    if (!bDestExists) {\n        // the destination root does not exist\n        errCode = NOT_FOUND_ERR;\n    }\n\n    else if ([srcFs isKindOfClass:[CDVLocalFilesystem class]]) {\n        /* Same FS, we can shortcut with NSFileManager operations */\n        NSString *srcFullPath = [srcFs filesystemPathForURL:srcURL];\n\n        BOOL bSrcIsDir = NO;\n        BOOL bSrcExists = [fileMgr fileExistsAtPath:srcFullPath isDirectory:&bSrcIsDir];\n\n        if (!bSrcExists) {\n            // the source does not exist\n            errCode = NOT_FOUND_ERR;\n        } else if ([newFileSystemPath isEqualToString:srcFullPath]) {\n            // source and destination can not be the same\n            errCode = INVALID_MODIFICATION_ERR;\n        } else if (bSrcIsDir && (bNewExists && !bNewIsDir)) {\n            // can't copy/move dir to file\n            errCode = INVALID_MODIFICATION_ERR;\n        } else { // no errors yet\n            NSError* __autoreleasing error = nil;\n            BOOL bSuccess = NO;\n            if (bCopy) {\n                if (bSrcIsDir && ![self canCopyMoveSrc:srcFullPath ToDestination:newFileSystemPath]) {\n                    // can't copy dir into self\n                    errCode = INVALID_MODIFICATION_ERR;\n                } else if (bNewExists) {\n                    // the full destination should NOT already exist if a copy\n                    errCode = PATH_EXISTS_ERR;\n                } else {\n                    bSuccess = [fileMgr copyItemAtPath:srcFullPath toPath:newFileSystemPath error:&error];\n                }\n            } else { // move\n                // iOS requires that destination must not exist before calling moveTo\n                // is W3C INVALID_MODIFICATION_ERR error if destination dir exists and has contents\n                //\n                if (!bSrcIsDir && (bNewExists && bNewIsDir)) {\n                    // can't move a file to directory\n                    errCode = INVALID_MODIFICATION_ERR;\n                } else if (bSrcIsDir && ![self canCopyMoveSrc:srcFullPath ToDestination:newFileSystemPath]) {\n                    // can't move a dir into itself\n                    errCode = INVALID_MODIFICATION_ERR;\n                } else if (bNewExists) {\n                    if (bNewIsDir && ([[fileMgr contentsOfDirectoryAtPath:newFileSystemPath error:NULL] count] != 0)) {\n                        // can't move dir to a dir that is not empty\n                        errCode = INVALID_MODIFICATION_ERR;\n                        newFileSystemPath = nil;  // so we won't try to move\n                    } else {\n                        // remove destination so can perform the moveItemAtPath\n                        bSuccess = [fileMgr removeItemAtPath:newFileSystemPath error:NULL];\n                        if (!bSuccess) {\n                            errCode = INVALID_MODIFICATION_ERR; // is this the correct error?\n                            newFileSystemPath = nil;\n                        }\n                    }\n                } else if (bNewIsDir && [newFileSystemPath hasPrefix:srcFullPath]) {\n                    // can't move a directory inside itself or to any child at any depth;\n                    errCode = INVALID_MODIFICATION_ERR;\n                    newFileSystemPath = nil;\n                }\n\n                if (newFileSystemPath != nil) {\n                    bSuccess = [fileMgr moveItemAtPath:srcFullPath toPath:newFileSystemPath error:&error];\n                }\n            }\n            if (bSuccess) {\n                // should verify it is there and of the correct type???\n                NSDictionary* newEntry = [self makeEntryForPath:newFullPath isDirectory:bSrcIsDir];\n                result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:newEntry];\n            } else {\n                if (error) {\n                    if (([error code] == NSFileReadUnknownError) || ([error code] == NSFileReadTooLargeError)) {\n                        errCode = NOT_READABLE_ERR;\n                    } else if ([error code] == NSFileWriteOutOfSpaceError) {\n                        errCode = QUOTA_EXCEEDED_ERR;\n                    } else if ([error code] == NSFileWriteNoPermissionError) {\n                        errCode = NO_MODIFICATION_ALLOWED_ERR;\n                    }\n                }\n            }\n        }\n    } else {\n        // Need to copy the hard way\n        [srcFs readFileAtURL:srcURL start:0 end:-1 callback:^(NSData* data, NSString* mimeType, CDVFileError errorCode) {\n            CDVPluginResult* result = nil;\n            if (data != nil) {\n                BOOL bSuccess = [data writeToFile:newFileSystemPath atomically:YES];\n                if (bSuccess) {\n                    // should verify it is there and of the correct type???\n                    NSDictionary* newEntry = [self makeEntryForPath:newFullPath isDirectory:NO];\n                    result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:newEntry];\n                } else {\n                    result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:ABORT_ERR];\n                }\n            } else {\n                result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:errorCode];\n            }\n            callback(result);\n        }];\n        return; // Async IO; return without callback.\n    }\n    if (result == nil) {\n        if (!errCode) {\n            errCode = INVALID_MODIFICATION_ERR; // Catch-all default\n        }\n        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:errCode];\n    }\n    callback(result);\n}\n\n/* helper function to get the mimeType from the file extension\n * IN:\n *\tNSString* fullPath - filename (may include path)\n * OUT:\n *\tNSString* the mime type as type/subtype.  nil if not able to determine\n */\n+ (NSString*)getMimeTypeFromPath:(NSString*)fullPath\n{\n    NSString* mimeType = nil;\n\n    if (fullPath) {\n        CFStringRef typeId = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)[fullPath pathExtension], NULL);\n        if (typeId) {\n            mimeType = (__bridge_transfer NSString*)UTTypeCopyPreferredTagWithClass(typeId, kUTTagClassMIMEType);\n            if (!mimeType) {\n                // special case for m4a\n                if ([(__bridge NSString*)typeId rangeOfString : @\"m4a-audio\"].location != NSNotFound) {\n                    mimeType = @\"audio/mp4\";\n                } else if ([[fullPath pathExtension] rangeOfString:@\"wav\"].location != NSNotFound) {\n                    mimeType = @\"audio/wav\";\n                } else if ([[fullPath pathExtension] rangeOfString:@\"css\"].location != NSNotFound) {\n                    mimeType = @\"text/css\";\n                }\n            }\n            CFRelease(typeId);\n        }\n    }\n    return mimeType;\n}\n\n- (void)readFileAtURL:(CDVFilesystemURL *)localURL start:(NSInteger)start end:(NSInteger)end callback:(void (^)(NSData*, NSString* mimeType, CDVFileError))callback\n{\n    NSString *path = [self filesystemPathForURL:localURL];\n\n    NSString* mimeType = [CDVLocalFilesystem getMimeTypeFromPath:path];\n    if (mimeType == nil) {\n        mimeType = @\"*/*\";\n    }\n    NSFileHandle* file = [NSFileHandle fileHandleForReadingAtPath:path];\n    if (start > 0) {\n        [file seekToFileOffset:start];\n    }\n\n    NSData* readData;\n    if (end < 0) {\n        readData = [file readDataToEndOfFile];\n    } else {\n        readData = [file readDataOfLength:(end - start)];\n    }\n    [file closeFile];\n\n    callback(readData, mimeType, readData != nil ? NO_ERROR : NOT_FOUND_ERR);\n}\n\n- (void)getFileMetadataForURL:(CDVFilesystemURL *)localURL callback:(void (^)(CDVPluginResult *))callback\n{\n    NSString *path = [self filesystemPathForURL:localURL];\n    CDVPluginResult *result;\n    NSFileManager* fileMgr = [[NSFileManager alloc] init];\n\n    NSError* __autoreleasing error = nil;\n    NSDictionary* fileAttrs = [fileMgr attributesOfItemAtPath:path error:&error];\n\n    if (fileAttrs) {\n\n        // create dictionary of file info\n        NSMutableDictionary* fileInfo = [NSMutableDictionary dictionaryWithCapacity:5];\n\n        [fileInfo setObject:localURL.fullPath forKey:@\"fullPath\"];\n        [fileInfo setObject:@\"\" forKey:@\"type\"];  // can't easily get the mimetype unless create URL, send request and read response so skipping\n        [fileInfo setObject:[path lastPathComponent] forKey:@\"name\"];\n\n        // Ensure that directories (and other non-regular files) report size of 0\n        unsigned long long size = ([fileAttrs fileType] == NSFileTypeRegular ? [fileAttrs fileSize] : 0);\n        [fileInfo setObject:[NSNumber numberWithUnsignedLongLong:size] forKey:@\"size\"];\n\n        NSDate* modDate = [fileAttrs fileModificationDate];\n        if (modDate) {\n            [fileInfo setObject:[NSNumber numberWithDouble:[modDate timeIntervalSince1970] * 1000] forKey:@\"lastModifiedDate\"];\n        }\n\n        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:fileInfo];\n\n    } else {\n        // didn't get fileAttribs\n        CDVFileError errorCode = ABORT_ERR;\n        NSLog(@\"error getting metadata: %@\", [error localizedDescription]);\n        if ([error code] == NSFileNoSuchFileError || [error code] == NSFileReadNoSuchFileError) {\n            errorCode = NOT_FOUND_ERR;\n        }\n        // log [NSNumber numberWithDouble: theMessage] objCtype to see what it returns\n        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:errorCode];\n    }\n\n    callback(result);\n}\n\n@end\n"
  },
  {
    "path": "plugins/cordova-plugin-file/src/ubuntu/file.cpp",
    "content": "/*\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n */\n\n#include \"file.h\"\n\n#include <QApplication>\n\nnamespace {\n    class FileError {\n    public:\n        static const QString kEncodingErr;\n        static const QString kTypeMismatchErr;\n        static const QString kNotFoundErr;\n        static const QString kSecurityErr;\n        static const QString kAbortErr;\n        static const QString kNotReadableErr;\n        static const QString kNoModificationAllowedErr;\n        static const QString kInvalidStateErr;\n        static const QString kSyntaxErr;\n        static const QString kInvalidModificationErr;\n        static const QString kQuotaExceededErr;\n        static const QString kPathExistsErr;\n    };\n\n    bool checkFileName(const QString &name) {\n        if (name.contains(\":\")){\n            return false;\n        }\n        return true;\n    }\n};\n\nconst QString FileError::kEncodingErr(\"FileError.ENCODING_ERR\");\nconst QString FileError::kTypeMismatchErr(\"FileError.TYPE_MISMATCH_ERR\");\nconst QString FileError::kNotFoundErr(\"FileError.NOT_FOUND_ERR\");\nconst QString FileError::kSecurityErr(\"FileError.SECURITY_ERR\");\nconst QString FileError::kAbortErr(\"FileError.ABORT_ERR\");\nconst QString FileError::kNotReadableErr(\"FileError.NOT_READABLE_ERR\");\nconst QString FileError::kNoModificationAllowedErr(\"FileError.NO_MODIFICATION_ALLOWED_ERR\");\nconst QString FileError::kInvalidStateErr(\"FileError.INVALID_STATE_ERR\");\nconst QString FileError::kSyntaxErr(\"FileError.SYNTAX_ERR\");\nconst QString FileError::kInvalidModificationErr(\"FileError.INVALID_MODIFICATION_ERR\");\nconst QString FileError::kQuotaExceededErr(\"FileError.QUOTA_EXCEEDED_ERR\");\nconst QString FileError::kPathExistsErr(\"FileError.PATH_EXISTS_ERR\");\n\nFile::File(Cordova *cordova) :\n    CPlugin(cordova),\n    _persistentDir(QString(\"%1/.local/share/%2/persistent\").arg(QDir::homePath()).arg(QCoreApplication::applicationName())) {\n    QDir::root().mkpath(_persistentDir.absolutePath());\n}\n\nQVariantMap File::file2map(const QFileInfo &fileInfo) {\n    QVariantMap res;\n\n    res.insert(\"name\", fileInfo.fileName());\n    QPair<QString, QString> r = GetRelativePath(fileInfo);\n    res.insert(\"fullPath\", QString(\"/\") + r.second);\n    res.insert(\"filesystemName\", r.first);\n\n    res.insert(\"nativeURL\", QString(\"file://localhost\") + fileInfo.absoluteFilePath());\n    res.insert(\"isDirectory\", (int)fileInfo.isDir());\n    res.insert(\"isFile\", (int)fileInfo.isFile());\n\n    return res;\n}\n\nQVariantMap File::dir2map(const QDir &dir) {\n    return file2map(QFileInfo(dir.absolutePath()));\n}\n\nQPair<QString, QString> File::GetRelativePath(const QFileInfo &fileInfo) {\n    QString fullPath = fileInfo.isDir() ? QDir::cleanPath(fileInfo.absoluteFilePath()) : fileInfo.absoluteFilePath();\n\n    QString relativePath1 = _persistentDir.relativeFilePath(fullPath);\n    QString relativePath2 = QDir::temp().relativeFilePath(fullPath);\n\n    if (!(relativePath1[0] != '.' || relativePath2[0] != '.')) {\n        if (relativePath1.size() > relativePath2.size()) {\n            return QPair<QString, QString>(\"temporary\", relativePath2);\n        } else {\n            return QPair<QString, QString>(\"persistent\", relativePath1);\n        }\n    }\n\n    if (relativePath1[0] != '.')\n        return QPair<QString, QString>(\"persistent\", relativePath1);\n    return QPair<QString, QString>(\"temporary\", relativePath2);\n}\n\nvoid File::requestFileSystem(int scId, int ecId, unsigned short type, unsigned long long size) {\n    QDir dir;\n\n    if (size >= 1000485760){\n        this->callback(ecId, FileError::kQuotaExceededErr);\n        return;\n    }\n\n    if (type == 0)\n        dir = QDir::temp();\n    else\n        dir = _persistentDir;\n\n    if (type > 1) {\n        this->callback(ecId, FileError::kSyntaxErr);\n        return;\n    } else {\n        QVariantMap res;\n        res.insert(\"root\", dir2map(dir));\n        if (type == 0)\n            res.insert(\"name\", \"temporary\");\n        else\n            res.insert(\"name\", \"persistent\");\n\n        this->cb(scId, res);\n    }\n}\n\nQPair<bool, QFileInfo> File::resolveURI(int ecId, const QString &uri) {\n    QPair<bool, QFileInfo> result;\n\n    result.first = false;\n\n    QUrl url = QUrl::fromUserInput(uri);\n\n    if (url.scheme() == \"file\" && url.isValid()) {\n        result.first = true;\n        result.second = QFileInfo(url.path());\n        return result;\n    }\n\n    if (url.scheme() != \"cdvfile\") {\n        if (ecId)\n            this->callback(ecId, FileError::kTypeMismatchErr);\n        return result;\n    }\n\n    QString path = url.path().replace(\"//\", \"/\");\n    //NOTE: colon is not safe in url, it is not a valid path in Win and Mac, simple disable it here.\n    if (path.contains(\":\") || !url.isValid()){\n        if (ecId)\n            this->callback(ecId, FileError::kEncodingErr);\n        return result;\n    }\n    if (!path.startsWith(\"/persistent/\") && !path.startsWith(\"/temporary/\")) {\n        if (ecId)\n            this->callback(ecId, FileError::kEncodingErr);\n        return result;\n    }\n\n    result.first = true;\n    if (path.startsWith(\"/persistent/\")) {\n        QString relativePath = path.mid(QString(\"/persistent/\").size());\n        result.second = QFileInfo(_persistentDir.filePath(relativePath));\n    } else {\n        QString relativePath = path.mid(QString(\"/temporary/\").size());\n        result.second = QFileInfo(QDir::temp().filePath(relativePath));\n    }\n    return result;\n}\n\nQPair<bool, QFileInfo> File::resolveURI(const QString &uri) {\n    return resolveURI(0, uri);\n}\n\n\nvoid File::_getLocalFilesystemPath(int scId, int ecId, const QString& uri) {\n    QPair<bool, QFileInfo> f1 = resolveURI(ecId, uri);\n\n    if (!f1.first)\n        return;\n\n    this->cb(scId, f1.second.absoluteFilePath());\n}\n\nvoid File::resolveLocalFileSystemURI(int scId, int ecId, const QString &uri) {\n    if (uri[0] == '/' || uri[0] == '.') {\n        this->callback(ecId, FileError::kEncodingErr);\n        return;\n    }\n\n    QPair<bool, QFileInfo> f1 = resolveURI(ecId, uri);\n\n    if (!f1.first)\n        return;\n\n    QFileInfo fileInfo = f1.second;\n    if (!fileInfo.exists()) {\n        this->callback(ecId, FileError::kNotFoundErr);\n        return;\n    }\n\n    this->cb(scId, file2map(fileInfo));\n}\n\nvoid File::getFile(int scId, int ecId, const QString &parentPath, const QString &rpath, const QVariantMap &options) {\n    QPair<bool, QFileInfo> f1 = resolveURI(ecId, parentPath + \"/\" + rpath);\n    if (!f1.first)\n        return;\n\n    bool create = options.value(\"create\").toBool();\n    bool exclusive = options.value(\"exclusive\").toBool();\n    QFile file(f1.second.absoluteFilePath());\n\n    // if create is false and the path represents a directory, return error\n    QFileInfo fileInfo = f1.second;\n    if ((!create) && fileInfo.isDir()) {\n        this->callback(ecId, FileError::kTypeMismatchErr);\n        return;\n    }\n\n    // if file does exist, and create is true and exclusive is true, return error\n    if (file.exists()) {\n        if (create && exclusive) {\n            this->callback(ecId, FileError::kPathExistsErr);\n            return;\n        }\n    }\n    else {\n        // if file does not exist and create is false, return error\n        if (!create) {\n            this->callback(ecId, FileError::kNotFoundErr);\n            return;\n        }\n\n        file.open(QIODevice::WriteOnly);\n        file.close();\n\n        // Check if creation was successfull\n        if (!file.exists()) {\n            this->callback(ecId, FileError::kNoModificationAllowedErr);\n            return;\n        }\n    }\n\n    this->cb(scId, file2map(QFileInfo(file)));\n}\n\nvoid File::getDirectory(int scId, int ecId, const QString &parentPath, const QString &rpath, const QVariantMap &options) {\n    QPair<bool, QFileInfo> f1 = resolveURI(ecId, parentPath + \"/\" + rpath);\n    if (!f1.first)\n        return;\n\n    bool create = options.value(\"create\").toBool();\n    bool exclusive = options.value(\"exclusive\").toBool();\n    QDir dir(f1.second.absoluteFilePath());\n\n    QFileInfo &fileInfo = f1.second;\n    if ((!create) && fileInfo.isFile()) {\n        this->callback(ecId, FileError::kTypeMismatchErr);\n        return;\n    }\n\n    if (dir.exists()) {\n        if (create && exclusive) {\n            this->callback(ecId, FileError::kPathExistsErr);\n            return;\n        }\n    }\n    else {\n        if (!create) {\n            this->callback(ecId, FileError::kNotFoundErr);\n            return;\n        }\n\n        QString folderName = dir.dirName();\n        dir.cdUp();\n        dir.mkdir(folderName);\n        dir.cd(folderName);\n\n        if (!dir.exists()) {\n            this->callback(ecId, FileError::kNoModificationAllowedErr);\n            return;\n        }\n    }\n\n    this->cb(scId, dir2map(dir));\n}\n\nvoid File::removeRecursively(int scId, int ecId, const QString &uri) {\n    QPair<bool, QFileInfo> f1 = resolveURI(ecId, uri);\n\n    if (!f1.first)\n        return;\n\n    QDir dir(f1.second.absoluteFilePath());\n    if (File::rmDir(dir))\n        this->cb(scId);\n    else\n        this->callback(ecId, FileError::kNoModificationAllowedErr);\n}\n\nvoid File::write(int scId, int ecId, const QString &uri, const QString &_data, unsigned long long position, bool binary) {\n    QPair<bool, QFileInfo> f1 = resolveURI(ecId, uri);\n\n    if (!f1.first)\n        return;\n\n    QFile file(f1.second.absoluteFilePath());\n\n    file.open(QIODevice::WriteOnly);\n    file.close();\n\n    if (!file.exists()) {\n        this->callback(ecId, FileError::kNotFoundErr);\n        return;\n    }\n\n    QFileInfo fileInfo(file);\n    if (!file.open(QIODevice::ReadWrite)) {\n        this->callback(ecId, FileError::kNoModificationAllowedErr);\n        return;\n    }\n\n    if (!binary) {\n        QTextStream textStream(&file);\n        textStream.setCodec(\"UTF-8\");\n        textStream.setAutoDetectUnicode(true);\n\n        if (!textStream.seek(position)) {\n            file.close();\n            fileInfo.refresh();\n\n            this->callback(ecId, FileError::kInvalidModificationErr);\n            return;\n        }\n\n        textStream << _data;\n        textStream.flush();\n    } else {\n        QByteArray data(_data.toUtf8());\n        if (!file.seek(position)) {\n            file.close();\n            fileInfo.refresh();\n\n            this->callback(ecId, FileError::kInvalidModificationErr);\n            return;\n        }\n\n        file.write(data.data(), data.length());\n    }\n\n    file.flush();\n    file.close();\n    fileInfo.refresh();\n\n    this->cb(scId, fileInfo.size() - position);\n}\n\nvoid File::truncate(int scId, int ecId, const QString &uri, unsigned long long size) {\n    QPair<bool, QFileInfo> f1 = resolveURI(ecId, uri);\n\n    if (!f1.first)\n        return;\n\n    QFile file(f1.second.absoluteFilePath());\n\n    if (!file.exists()) {\n        this->callback(ecId, FileError::kNotFoundErr);\n        return;\n    }\n\n    if (!file.resize(size)) {\n        this->callback(ecId, FileError::kNoModificationAllowedErr);\n        return;\n    }\n\n    this->cb(scId, size);\n}\n\nvoid File::getParent(int scId, int ecId, const QString &uri) {\n    QPair<bool, QFileInfo> f1 = resolveURI(ecId, uri);\n\n    if (!f1.first)\n        return;\n    QDir dir(f1.second.absoluteFilePath());\n\n    //can't cdup more than app's root\n    // Try to change into upper directory\n    if (dir != _persistentDir && dir != QDir::temp()){\n        if (!dir.cdUp()) {\n            this->callback(ecId, FileError::kNotFoundErr);\n            return;\n        }\n\n    }\n    this->cb(scId, dir2map(dir));\n}\n\nvoid File::remove(int scId, int ecId, const QString &uri) {\n    QPair<bool, QFileInfo> f1 = resolveURI(ecId, uri);\n    if (!f1.first)\n        return;\n\n    QFileInfo &fileInfo = f1.second;\n    //TODO: fix\n    if (!fileInfo.exists() || (fileInfo.absoluteFilePath() == _persistentDir.absolutePath()) || (QDir::temp() == fileInfo.absoluteFilePath())) {\n        this->callback(ecId, FileError::kNoModificationAllowedErr);\n        return;\n    }\n\n    if (fileInfo.isDir()) {\n        QDir dir(fileInfo.absoluteFilePath());\n        if (dir.rmdir(dir.absolutePath())) {\n            this->cb(scId);\n            return;\n        }\n    } else {\n        QFile file(fileInfo.absoluteFilePath());\n        if (file.remove()) {\n            this->cb(scId);\n            return;\n        }\n    }\n\n    this->callback(ecId, FileError::kInvalidModificationErr);\n}\n\nvoid File::getFileMetadata(int scId, int ecId, const QString &uri) {\n    QPair<bool, QFileInfo> f1 = resolveURI(ecId, uri);\n\n    if (!f1.first)\n        return;\n    QFileInfo &fileInfo = f1.second;\n\n    if (!fileInfo.exists()) {\n        this->callback(ecId, FileError::kNotFoundErr);\n    } else {\n        QMimeType mime = _db.mimeTypeForFile(fileInfo.fileName());\n\n        QString args = QString(\"{name: %1, fullPath: %2, type: %3, lastModifiedDate: new Date(%4), size: %5}\")\n            .arg(CordovaInternal::format(fileInfo.fileName())).arg(CordovaInternal::format(fileInfo.absoluteFilePath()))\n            .arg(CordovaInternal::format(mime.name())).arg(fileInfo.lastModified().toMSecsSinceEpoch())\n            .arg(fileInfo.size());\n\n        this->callback(scId, args);\n    }\n}\n\nvoid File::getMetadata(int scId, int ecId, const QString &uri) {\n    QPair<bool, QFileInfo> f1 = resolveURI(ecId, uri);\n\n    if (!f1.first)\n        return;\n    QFileInfo &fileInfo = f1.second;\n\n    if (!fileInfo.exists())\n        this->callback(ecId, FileError::kNotFoundErr);\n    else {\n        QVariantMap obj;\n        obj.insert(\"modificationTime\", fileInfo.lastModified().toMSecsSinceEpoch());\n        obj.insert(\"size\", fileInfo.isDir() ? 0 : fileInfo.size());\n        this->cb(scId, obj);\n    }\n}\n\nvoid File::readEntries(int scId, int ecId, const QString &uri) {\n    QPair<bool, QFileInfo> f1 = resolveURI(ecId, uri);\n\n    if (!f1.first)\n        return;\n    QDir dir(f1.second.absoluteFilePath());\n    QString entriesList;\n\n    if (!dir.exists()) {\n        this->callback(ecId, FileError::kNotFoundErr);\n        return;\n    }\n\n    for (const QFileInfo &fileInfo: dir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot)) {\n        entriesList += CordovaInternal::format(file2map(fileInfo)) + \",\";\n    }\n    // Remove trailing comma\n    if (entriesList.size() > 0)\n        entriesList.remove(entriesList.size() - 1, 1);\n\n    entriesList = \"new Array(\" + entriesList + \")\";\n\n    this->callback(scId, entriesList);\n}\n\nvoid File::readAsText(int scId, int ecId, const QString &uri, const QString &/*encoding*/, int sliceStart, int sliceEnd) {\n    QPair<bool, QFileInfo> f1 = resolveURI(ecId, uri);\n\n    if (!f1.first)\n        return;\n\n    QFile file(f1.second.absoluteFilePath());\n\n    if (!file.exists()) {\n        this->callback(ecId, FileError::kNotFoundErr);\n        return;\n    }\n\n    if (!file.open(QIODevice::ReadOnly)) {\n        this->callback(ecId, FileError::kNotReadableErr);\n        return;\n    }\n\n    QByteArray content = file.readAll();\n\n    if (sliceEnd == -1)\n        sliceEnd = content.size();\n    if (sliceEnd < 0) {\n        sliceEnd++;\n        sliceEnd = std::max(0, content.size() + sliceEnd);\n    }\n    if (sliceEnd > content.size())\n        sliceEnd = content.size();\n\n    if (sliceStart < 0)\n        sliceStart = std::max(0, content.size() + sliceStart);\n    if (sliceStart > content.size())\n        sliceStart = content.size();\n\n    if (sliceStart > sliceEnd)\n        sliceEnd = sliceStart;\n\n    //FIXME: encoding\n    content = content.mid(sliceStart, sliceEnd - sliceStart);\n\n    this->cb(scId, content);\n}\n\nvoid File::readAsArrayBuffer(int scId, int ecId, const QString &uri, int sliceStart, int sliceEnd) {\n    const QString str2array(\"\\\n    (function strToArray(str) {                 \\\n        var res = new Uint8Array(str.length);   \\\n        for (var i = 0; i < str.length; i++) {  \\\n            res[i] = str.charCodeAt(i);         \\\n        }                                       \\\n        return res;                             \\\n    })(\\\"%1\\\")\");\n\n    QPair<bool, QFileInfo> f1 = resolveURI(ecId, uri);\n\n    if (!f1.first)\n        return;\n\n    QFile file(f1.second.absoluteFilePath());\n\n    if (!file.exists()) {\n        this->callback(ecId, FileError::kNotFoundErr);\n        return;\n    }\n\n    if (!file.open(QIODevice::ReadOnly)) {\n        this->callback(ecId, FileError::kNotReadableErr);\n        return;\n    }\n    QString res;\n    QByteArray content = file.readAll();\n\n    if (sliceEnd == -1)\n        sliceEnd = content.size();\n    if (sliceEnd < 0) {\n        sliceEnd++;\n        sliceEnd = std::max(0, content.size() + sliceEnd);\n    }\n    if (sliceEnd > content.size())\n        sliceEnd = content.size();\n\n    if (sliceStart < 0)\n        sliceStart = std::max(0, content.size() + sliceStart);\n    if (sliceStart > content.size())\n        sliceStart = content.size();\n\n    if (sliceStart > sliceEnd)\n        sliceEnd = sliceStart;\n\n    content = content.mid(sliceStart, sliceEnd - sliceStart);\n\n    res.reserve(content.length() * 6);\n    for (uchar c: content) {\n        res += \"\\\\x\";\n        res += QString::number(c, 16).rightJustified(2, '0').toUpper();\n    }\n\n    this->callback(scId, str2array.arg(res));\n}\n\nvoid File::readAsBinaryString(int scId, int ecId, const QString &uri, int sliceStart, int sliceEnd) {\n    QPair<bool, QFileInfo> f1 = resolveURI(ecId, uri);\n\n    if (!f1.first)\n        return;\n\n    QFile file(f1.second.absoluteFilePath());\n\n    if (!file.exists()) {\n        this->callback(ecId, FileError::kNotFoundErr);\n        return;\n    }\n\n    if (!file.open(QIODevice::ReadOnly)) {\n        this->callback(ecId, FileError::kNotReadableErr);\n        return;\n    }\n    QString res;\n    QByteArray content = file.readAll();\n\n    if (sliceEnd == -1)\n        sliceEnd = content.size();\n    if (sliceEnd < 0) {\n        sliceEnd++;\n        sliceEnd = std::max(0, content.size() + sliceEnd);\n    }\n    if (sliceEnd > content.size())\n        sliceEnd = content.size();\n\n    if (sliceStart < 0)\n        sliceStart = std::max(0, content.size() + sliceStart);\n    if (sliceStart > content.size())\n        sliceStart = content.size();\n\n    if (sliceStart > sliceEnd)\n        sliceEnd = sliceStart;\n\n    content = content.mid(sliceStart, sliceEnd - sliceStart);\n\n    res.reserve(content.length() * 6);\n    for (uchar c: content) {\n        res += \"\\\\x\";\n        res += QString::number(c, 16).rightJustified(2, '0').toUpper();\n    }\n    this->callback(scId, \"\\\"\" + res + \"\\\"\");\n}\n\nvoid File::readAsDataURL(int scId, int ecId, const QString &uri, int sliceStart, int sliceEnd) {\n    QPair<bool, QFileInfo> f1 = resolveURI(ecId, uri);\n\n    if (!f1.first)\n        return;\n\n    QFile file(f1.second.absoluteFilePath());\n    QFileInfo &fileInfo = f1.second;\n\n    if (!file.exists()) {\n        this->callback(ecId, FileError::kNotReadableErr);\n        return;\n    }\n\n    if (!file.open(QIODevice::ReadOnly)) {\n        this->callback(ecId, FileError::kNotReadableErr);\n        return;\n    }\n\n    QByteArray content = file.readAll();\n    QString contentType(_db.mimeTypeForFile(fileInfo.fileName()).name());\n\n    if (sliceEnd == -1)\n        sliceEnd = content.size();\n    if (sliceEnd < 0) {\n        sliceEnd++;\n        sliceEnd = std::max(0, content.size() + sliceEnd);\n    }\n    if (sliceEnd > content.size())\n        sliceEnd = content.size();\n\n    if (sliceStart < 0)\n        sliceStart = std::max(0, content.size() + sliceStart);\n    if (sliceStart > content.size())\n        sliceStart = content.size();\n\n    if (sliceStart > sliceEnd)\n        sliceEnd = sliceStart;\n\n    content = content.mid(sliceStart, sliceEnd - sliceStart);\n\n    this->cb(scId, QString(\"data:%1;base64,\").arg(contentType) + content.toBase64());\n}\n\nbool File::rmDir(const QDir &dir) {\n    if (dir == _persistentDir || dir == QDir::temp()) {//can't remove root dir\n        return false;\n    }\n    bool result = true;\n    if (dir.exists()) {\n        // Iterate over entries and remove them\n        Q_FOREACH(const QFileInfo &fileInfo, dir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot)) {\n            if (fileInfo.isDir()) {\n                result = rmDir(fileInfo.absoluteFilePath());\n            }\n            else {\n                result = QFile::remove(fileInfo.absoluteFilePath());\n            }\n\n            if (!result) {\n                return result;\n            }\n        }\n\n        // Finally remove the current dir\n        return dir.rmdir(dir.absolutePath());\n    }\n    return result;\n}\n\nbool File::copyFile(int scId, int ecId,const QString& sourceUri, const QString& destinationUri, const QString& newName) {\n    QPair<bool, QFileInfo> destDir = resolveURI(ecId, destinationUri);\n    QPair<bool, QFileInfo> sourceFile = resolveURI(ecId, sourceUri);\n\n    if (!destDir.first || !sourceFile.first)\n        return false;\n\n    if (!checkFileName(newName)) {\n        this->callback(ecId, FileError::kEncodingErr);\n        return false;\n    }\n\n    if (destDir.second.isFile()) {\n        this->callback(ecId, FileError::kInvalidModificationErr);\n        return false;\n    }\n\n    if (!destDir.second.isDir()) {\n        this->callback(ecId, FileError::kNotFoundErr);\n        return false;\n    }\n\n    QFileInfo &fileInfo = sourceFile.second;\n    QString fileName((newName.isEmpty()) ? fileInfo.fileName() : newName);\n    QString destinationFile(QDir(destDir.second.absoluteFilePath()).filePath(fileName));\n    if (QFile::copy(fileInfo.absoluteFilePath(), destinationFile)){\n        this->cb(scId, file2map(QFileInfo(destinationFile)));\n        return true;\n    }\n    this->callback(ecId, FileError::kInvalidModificationErr);\n    return false;\n}\n\nvoid File::copyDir(int scId, int ecId,const QString& sourceUri, const QString& destinationUri, const QString& newName) {\n    QPair<bool, QFileInfo> destDir = resolveURI(ecId, destinationUri);\n    QPair<bool, QFileInfo> sourceDir = resolveURI(ecId, sourceUri);\n\n    if (!destDir.first || !sourceDir.first)\n        return;\n    if (!checkFileName(newName)) {\n        this->callback(ecId, FileError::kEncodingErr);\n        return;\n    }\n\n    QString targetName = ((newName.isEmpty()) ? sourceDir.second.fileName() : newName);\n    QString target(QDir(destDir.second.absoluteFilePath()).filePath(targetName));\n\n    if (QFileInfo(target).isFile()){\n        this->callback(ecId, FileError::kInvalidModificationErr);\n        return;\n    }\n\n    // check: copy directory into itself\n    if (QDir(sourceDir.second.absoluteFilePath()).relativeFilePath(target)[0] != '.'){\n        this->callback(ecId, FileError::kInvalidModificationErr);\n        return;\n    }\n\n    if (!QDir(target).exists()){\n        QDir(destDir.second.absoluteFilePath()).mkdir(target);;\n    } else{\n        this->callback(ecId, FileError::kInvalidModificationErr);\n        return;\n    }\n\n    if (copyFolder(sourceDir.second.absoluteFilePath(), target)){\n        this->cb(scId, dir2map(QDir(target)));\n        return;\n    }\n    this->callback(ecId, FileError::kInvalidModificationErr);\n    return;\n}\n\nvoid File::copyTo(int scId, int ecId, const QString& source, const QString& destinationDir, const QString& newName) {\n    QPair<bool, QFileInfo> f1 = resolveURI(ecId, source);\n\n    if (!f1.first)\n        return;\n\n    if (f1.second.isDir())\n        copyDir(scId, ecId, source, destinationDir, newName);\n    else\n        copyFile(scId, ecId, source, destinationDir, newName);\n}\n\nvoid File::moveFile(int scId, int ecId,const QString& sourceUri, const QString& destinationUri, const QString& newName) {\n    QPair<bool, QFileInfo> sourceFile = resolveURI(ecId, sourceUri);\n    QPair<bool, QFileInfo> destDir = resolveURI(ecId, destinationUri);\n\n    if (!destDir.first || !sourceFile.first)\n        return;\n    if (!checkFileName(newName)) {\n        this->callback(ecId, FileError::kEncodingErr);\n        return;\n    }\n\n    QString fileName = ((newName.isEmpty()) ? sourceFile.second.fileName() : newName);\n    QString target = QDir(destDir.second.absoluteFilePath()).filePath(fileName);\n\n    if (sourceFile.second == QFileInfo(target)) {\n        this->callback(ecId, FileError::kInvalidModificationErr);\n        return;\n    }\n\n    if (!destDir.second.exists()) {\n        this->callback(ecId, FileError::kNotFoundErr);\n        return;\n    }\n    if (!destDir.second.isDir()){\n        this->callback(ecId, FileError::kInvalidModificationErr);\n        return;\n    }\n\n    if (QFileInfo(target).exists()) {\n        if (!QFile::remove(target)) {\n            this->callback(ecId, FileError::kInvalidModificationErr);\n            return;\n        }\n    }\n\n    QFile::rename(sourceFile.second.absoluteFilePath(), target);\n    this->cb(scId, file2map(QFileInfo(target)));\n}\n\nvoid File::moveDir(int scId, int ecId,const QString& sourceUri, const QString& destinationUri, const QString& newName){\n    QPair<bool, QFileInfo> sourceDir = resolveURI(ecId, sourceUri);\n    QPair<bool, QFileInfo> destDir = resolveURI(ecId, destinationUri);\n\n    if (!destDir.first || !sourceDir.first)\n        return;\n    if (!checkFileName(newName)) {\n        this->callback(ecId, FileError::kEncodingErr);\n        return;\n    }\n\n    QString fileName = ((newName.isEmpty()) ? sourceDir.second.fileName() : newName);\n    QString target = QDir(destDir.second.absoluteFilePath()).filePath(fileName);\n\n    if (!destDir.second.exists()){\n        this->callback(ecId, FileError::kNotFoundErr);\n        return;\n    }\n\n    if (destDir.second.isFile()){\n        this->callback(ecId, FileError::kInvalidModificationErr);\n        return;\n    }\n\n    // check: copy directory into itself\n    if (QDir(sourceDir.second.absoluteFilePath()).relativeFilePath(target)[0] != '.'){\n        this->callback(ecId, FileError::kInvalidModificationErr);\n        return;\n    }\n\n    if (QFileInfo(target).exists() && !QDir(destDir.second.absoluteFilePath()).rmdir(fileName)) {\n        this->callback(ecId, FileError::kInvalidModificationErr);\n        return;\n    }\n\n    if (copyFolder(sourceDir.second.absoluteFilePath(), target)) {\n        rmDir(sourceDir.second.absoluteFilePath());\n        this->cb(scId, file2map(QFileInfo(target)));\n    } else {\n        this->callback(ecId, FileError::kNoModificationAllowedErr);\n    }\n}\n\nvoid File::moveTo(int scId, int ecId, const QString& source, const QString& destinationDir, const QString& newName) {\n    QPair<bool, QFileInfo> f1 = resolveURI(ecId, source);\n\n    if (!f1.first)\n        return;\n\n    if (f1.second.isDir())\n        moveDir(scId, ecId, source, destinationDir, newName);\n    else\n        moveFile(scId, ecId, source, destinationDir, newName);\n}\n\nbool File::copyFolder(const QString& sourceFolder, const QString& destFolder) {\n    QDir sourceDir(sourceFolder);\n    if (!sourceDir.exists())\n        return false;\n    QDir destDir(destFolder);\n    if (!destDir.exists()){\n        destDir.mkdir(destFolder);\n    }\n    QStringList files = sourceDir.entryList(QDir::Files);\n    for (int i = 0; i< files.count(); i++)\n    {\n        QString srcName = sourceFolder + \"/\" + files[i];\n        QString destName = destFolder + \"/\" + files[i];\n        QFile::copy(srcName, destName);\n    }\n    files.clear();\n    files = sourceDir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot);\n    for (int i = 0; i< files.count(); i++)\n    {\n        QString srcName = sourceFolder + \"/\" + files[i];\n        QString destName = destFolder + \"/\" + files[i];\n        copyFolder(srcName, destName);\n    }\n    return true;\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-file/src/ubuntu/file.h",
    "content": "/*\n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the License.\n *  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n *  Unless required by applicable law or agreed to in writing, software\n *  distributed under the License is distributed on an \"AS IS\" BASIS,\n *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n *  See the License for the specific language governing permissions and\n *  limitations under the License.\n */\n\n#ifndef FILEAPI_H_SDASDASDAS\n#define FILEAPI_H_SDASDASDAS\n\n#include <QNetworkReply>\n#include <QtCore>\n\n#include <cplugin.h>\n#include <cordova.h>\n\nclass File: public CPlugin {\n    Q_OBJECT\npublic:\n    explicit File(Cordova *cordova);\n\n    virtual const QString fullName() override {\n        return File::fullID();\n    }\n\n    virtual const QString shortName() override {\n        return \"File\";\n    }\n\n    static const QString fullID() {\n        return \"File\";\n    }\n    QPair<bool, QFileInfo> resolveURI(const QString &uri);\n    QPair<bool, QFileInfo> resolveURI(int ecId, const QString &uri);\n    QVariantMap file2map(const QFileInfo &dir);\n\npublic slots:\n    void requestFileSystem(int scId, int ecId, unsigned short type, unsigned long long size);\n    void resolveLocalFileSystemURI(int scId, int ecId, const QString&);\n    void getDirectory(int scId, int ecId, const QString&, const QString&, const QVariantMap&);\n    void getFile(int scId, int ecId, const QString &parentPath, const QString &rpath, const QVariantMap &options);\n    void readEntries(int scId, int ecId, const QString &uri);\n    void getParent(int scId, int ecId, const QString &uri);\n    void copyTo(int scId, int ecId, const QString& source, const QString& destinationDir, const QString& newName);\n    void moveTo(int scId, int ecId, const QString& source, const QString& destinationDir, const QString& newName);\n    void getFileMetadata(int scId, int ecId, const QString &);\n    void getMetadata(int scId, int ecId, const QString &);\n    void remove(int scId, int ecId, const QString &);\n    void removeRecursively(int scId, int ecId, const QString&);\n    void write(int scId, int ecId, const QString&, const QString&, unsigned long long position, bool binary);\n    void readAsText(int scId, int ecId, const QString&, const QString &encoding, int sliceStart, int sliceEnd);\n    void readAsDataURL(int scId, int ecId, const QString&, int sliceStart, int sliceEnd);\n    void readAsArrayBuffer(int scId, int ecId, const QString&, int sliceStart, int sliceEnd);\n    void readAsBinaryString(int scId, int ecId, const QString&, int sliceStart, int sliceEnd);\n    void truncate(int scId, int ecId, const QString&, unsigned long long size);\n\n    void _getLocalFilesystemPath(int scId, int ecId, const QString&);\nprivate:\n    void moveFile(int scId, int ecId,const QString&, const QString&, const QString&);\n    void moveDir(int scId, int ecId,const QString&, const QString&, const QString&);\n    bool copyFile(int scId, int ecId, const QString&, const QString&, const QString&);\n    void copyDir(int scId, int ecId, const QString&, const QString&, const QString&);\n    bool rmDir(const QDir &dir);\n    bool copyFolder(const QString&, const QString&);\n\n    QPair<QString, QString> GetRelativePath(const QFileInfo &fileInfo);\n    QVariantMap dir2map(const QDir &dir);\n\n    QMimeDatabase _db;\n    const QDir _persistentDir;\n    QNetworkAccessManager _manager;\n};\n\n#endif\n"
  },
  {
    "path": "plugins/cordova-plugin-file/src/windows/FileProxy.js",
    "content": "﻿/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/* global Windows, WinJS, MSApp */\n\nvar File = require('./File'),\n    FileError = require('./FileError'),\n    Flags = require('./Flags'),\n    FileSystem = require('./FileSystem'),\n    LocalFileSystem = require('./LocalFileSystem'),\n    utils = require('cordova/utils');\n\nfunction Entry(isFile, isDirectory, name, fullPath, filesystemName, nativeURL) {\n    this.isFile = !!isFile;\n    this.isDirectory = !!isDirectory;\n    this.name = name || '';\n    this.fullPath = fullPath || '';\n    this.filesystemName = filesystemName || null;\n    this.nativeURL = nativeURL || null;\n}\n\nvar FileEntry = function(name, fullPath, filesystemName, nativeURL) {\n     FileEntry.__super__.constructor.apply(this, [true, false, name, fullPath, filesystemName, nativeURL]);\n};\n\nutils.extend(FileEntry, Entry);\n\nvar DirectoryEntry = function(name, fullPath, filesystemName, nativeURL) {\n    DirectoryEntry.__super__.constructor.call(this, false, true, name, fullPath, filesystemName, nativeURL);\n};\n\nutils.extend(DirectoryEntry, Entry);\n\n  \nvar getFolderFromPathAsync = Windows.Storage.StorageFolder.getFolderFromPathAsync;\nvar getFileFromPathAsync = Windows.Storage.StorageFile.getFileFromPathAsync;\n\nfunction  writeBytesAsync(storageFile, data, position) {\n    return storageFile.openAsync(Windows.Storage.FileAccessMode.readWrite)\n    .then(function (output) {\n        output.seek(position);\n        var dataWriter = new Windows.Storage.Streams.DataWriter(output);\n        dataWriter.writeBytes(data);\n        return dataWriter.storeAsync().then(function (size) {\n            output.size = position+size;\n            return dataWriter.flushAsync().then(function() {\n                output.close();\n                return size;\n            });\n        });\n    });\n}\n\nfunction writeTextAsync(storageFile, data, position) {\n    return storageFile.openAsync(Windows.Storage.FileAccessMode.readWrite)\n    .then(function (output) {\n        output.seek(position);\n        var dataWriter = new Windows.Storage.Streams.DataWriter(output);\n        dataWriter.writeString(data);\n        return dataWriter.storeAsync().then(function (size) {\n            output.size = position+size;\n            return dataWriter.flushAsync().then(function() {\n                output.close();\n                return size;\n            });\n        });\n    });\n}\n\nfunction writeBlobAsync(storageFile, data, position) {\n    return storageFile.openAsync(Windows.Storage.FileAccessMode.readWrite)\n    .then(function (output) {\n        output.seek(position);\n        var dataSize = data.size;\n        var input = (data.detachStream || data.msDetachStream).call(data);\n\n        // Copy the stream from the blob to the File stream \n        return Windows.Storage.Streams.RandomAccessStream.copyAsync(input, output)\n        .then(function () {\n\t\t\toutput.size = position+dataSize;\n            return output.flushAsync().then(function () {\n                input.close();\n                output.close();\n\n                return dataSize;\n            });\n        });\n    });\n}\n\nfunction writeArrayBufferAsync(storageFile, data, position) {\n    return writeBlobAsync(storageFile, new Blob([data]), position);\n}\n\nfunction cordovaPathToNative(path) {\n    // turn / into \\\\\n    var cleanPath = path.replace(/\\//g, '\\\\');\n    // turn  \\\\ into \\\n    cleanPath = cleanPath.replace(/\\\\+/g, '\\\\');\n    return cleanPath;\n}\n\nfunction nativePathToCordova(path) {\n    var cleanPath = path.replace(/\\\\/g, '/');\n    return cleanPath;\n}\n\nvar driveRE = new RegExp(\"^[/]*([A-Z]:)\");\nvar invalidNameRE = /[\\\\?*|\"<>:]/;\nfunction validName(name) {\n    return !invalidNameRE.test(name.replace(driveRE,''));\n}\n\nfunction sanitize(path) {\n    var slashesRE = new RegExp('/{2,}','g');\n    var components = path.replace(slashesRE, '/').split(/\\/+/);\n    // Remove double dots, use old school array iteration instead of RegExp\n    // since it is impossible to debug them\n    for (var index = 0; index < components.length; ++index) {\n        if (components[index] === \"..\") {\n            components.splice(index, 1);\n            if (index > 0) {\n                // if we're not in the start of array then remove preceeding path component,\n                // In case if relative path points above the root directory, just ignore double dots\n                // See file.spec.111 should not traverse above above the root directory for test case\n                components.splice(index-1, 1);\n                --index;\n            }\n        }\n    }\n    return components.join('/');\n}\n\nvar WinFS = function(name, root) {\n    this.winpath = root.winpath;\n    if (this.winpath && !/\\/$/.test(this.winpath)) {\n        this.winpath += \"/\";\n    }\n    this.makeNativeURL = function(path) {\n        return FileSystem.encodeURIPath(this.root.nativeURL + sanitize(path.replace(':','%3A')));};\n    root.fullPath = '/';\n    if (!root.nativeURL)\n            root.nativeURL = 'file://'+sanitize(this.winpath + root.fullPath).replace(':','%3A');\n    WinFS.__super__.constructor.call(this, name, root);\n};\n\nutils.extend(WinFS, FileSystem);\n\nWinFS.prototype.__format__ = function(fullPath) {\n    var path = sanitize('/'+this.name+(fullPath[0]==='/'?'':'/')+FileSystem.encodeURIPath(fullPath));\n    return 'cdvfile://localhost' + path;\n};\n\nvar windowsPaths = {\n    dataDirectory: \"ms-appdata:///local/\",\n    cacheDirectory: \"ms-appdata:///temp/\",\n    tempDirectory: \"ms-appdata:///temp/\",\n    syncedDataDirectory: \"ms-appdata:///roaming/\",\n    applicationDirectory: \"ms-appx:///\",\n    applicationStorageDirectory: \"ms-appx:///\"\n};\n\nvar AllFileSystems; \n\nfunction getAllFS() {\n    if (!AllFileSystems) {\n        AllFileSystems = {\n            'persistent':\n            Object.freeze(new WinFS('persistent', { \n                name: 'persistent', \n                nativeURL: 'ms-appdata:///local',\n                winpath: nativePathToCordova(Windows.Storage.ApplicationData.current.localFolder.path)  \n            })),\n            'temporary':\n            Object.freeze(new WinFS('temporary', { \n                name: 'temporary', \n                nativeURL: 'ms-appdata:///temp',\n                winpath: nativePathToCordova(Windows.Storage.ApplicationData.current.temporaryFolder.path)\n            })),\n            'root':\n            Object.freeze(new WinFS('root', { \n                name: 'root', \n                //nativeURL: 'file:///'\n                winpath: ''\n            }))\n        };\n    }\n    return AllFileSystems;\n}\n\nfunction getFS(name) {\n    return getAllFS()[name];\n}\n\nFileSystem.prototype.__format__ = function(fullPath) {\n    return getFS(this.name).__format__(fullPath);\n};\n\nrequire('./fileSystems').getFs = function(name, callback) {\n    setTimeout(function(){callback(getFS(name));});\n};\n\nfunction getFilesystemFromPath(path) {\n    var res;\n    var allfs = getAllFS();\n    Object.keys(allfs).some(function(fsn) {\n        var fs = allfs[fsn];\n        if (path.indexOf(fs.winpath) === 0)\n            res = fs;\n        return res;\n    });\n    return res;\n}\n\nvar msapplhRE = new RegExp('^ms-appdata://localhost/');\nfunction pathFromURL(url) {\n    url=url.replace(msapplhRE,'ms-appdata:///');\n    var path = decodeURIComponent(url);\n    // support for file name with parameters\n    if (/\\?/g.test(path)) {\n        path = String(path).split(\"?\")[0];\n    }\n    if (path.indexOf(\"file:/\")===0) {\n        if (path.indexOf(\"file://\") !== 0) {\n            url = \"file:///\" + url.substr(6);\n        }\n    }\n    \n    ['file://','ms-appdata:///','cdvfile://localhost/'].every(function(p) {\n        if (path.indexOf(p)!==0)\n            return true;\n        var thirdSlash = path.indexOf(\"/\", p.length);\n        if (thirdSlash < 0) {\n            path = \"\";\n        } else {\n            path = sanitize(path.substr(thirdSlash));\n        }\n    });\n    \n    return path.replace(driveRE,'$1');\n}\n\nfunction getFilesystemFromURL(url) {\n    url=url.replace(msapplhRE,'ms-appdata:///');\n    var res;\n    if (url.indexOf(\"file:/\")===0)\n        res = getFilesystemFromPath(pathFromURL(url));\n    else {\n        var allfs = getAllFS();\n        Object.keys(allfs).every(function(fsn) {\n            var fs = allfs[fsn];\n            if (url.indexOf(fs.root.nativeURL) === 0 || \n                url.indexOf('cdvfile://localhost/'+fs.name+'/') === 0) \n            {\n                res = fs;\n                return false;\n            }\n            return true;\n        });\n    }\n    return res;\n}\n\nfunction getFsPathForWinPath(fs, wpath) {\n    var path = nativePathToCordova(wpath);\n    if (path.indexOf(fs.winpath) !== 0)\n        return null;\n    return path.replace(fs.winpath,'/');\n}\n\nvar WinError = {\n    invalidArgument: -2147024809,\n    fileNotFound: -2147024894,\n    accessDenied: -2147024891\n};\n\nfunction openPath(path, ops) {\n    ops=ops?ops:{};\n    return new WinJS.Promise(function (complete,failed) {\n        getFileFromPathAsync(path).done(\n            function(file) {\n                complete({file:file});\n            },\n            function(err) {\n                if (err.number != WinError.fileNotFound && err.number != WinError.invalidArgument)\n                    failed(FileError.NOT_READABLE_ERR);\n                getFolderFromPathAsync(path)\n                .done(\n                    function(dir) {\n                        if (!ops.getContent)\n                            complete({folder:dir});\n                        else\n                            WinJS.Promise.join({\n                                files:dir.getFilesAsync(),\n                                folders:dir.getFoldersAsync()\n                            }).done(\n                                function(a) {\n                                    complete({\n                                        folder:dir,\n                                        files:a.files,\n                                        folders:a.folders\n                                    });\n                                },\n                                function(err) {\n                                    failed(FileError.NOT_READABLE_ERR);\n                                }\n                            );\n                    },\n                    function(err) {\n                        if (err.number == WinError.fileNotFound || err.number == WinError.invalidArgument)\n                            complete({});\n                        else\n                            failed(FileError.NOT_READABLE_ERR);\n                    }\n                );\n            }\n        );\n    });\n}\n\nfunction copyFolder(src,dst,name) {\n    name = name?name:src.name;\n    return new WinJS.Promise(function (complete,failed) {\n        WinJS.Promise.join({\n            fld:dst.createFolderAsync(name, Windows.Storage.CreationCollisionOption.openIfExists),\n            files:src.getFilesAsync(),\n            folders:src.getFoldersAsync()\n        }).done(\n            function(the) {\n                if (!(the.files.length || the.folders.length)) {\n                    complete();\n                    return;\n                }\n                var todo = the.files.length;\n                var copyfolders = function() {\n                    if (!(todo--)) {\n                        complete();\n                        return;\n                    }\n                    copyFolder(the.folders[todo],dst)\n                    .done(function() { copyfolders(); }, failed);\n                };\n                var copyfiles = function() {\n                    if (!(todo--)) {\n                        todo = the.folders.length;\n                        copyfolders();\n                        return;\n                    }\n                    the.files[todo].copyAsync(the.fld)\n                    .done(function() { copyfiles(); }, failed);\n                };\n                copyfiles();\n            },\n            failed\n        );\n    });\n}\n\nfunction moveFolder(src,dst,name) {\n    name = name?name:src.name;\n    return new WinJS.Promise(function (complete,failed) {\n        WinJS.Promise.join({\n            fld: dst.createFolderAsync(name, Windows.Storage.CreationCollisionOption.openIfExists),\n            files: src.getFilesAsync(),\n            folders: src.getFoldersAsync()\n        }).done(\n            function(the) {\n                if (!(the.files.length || the.folders.length)) {\n                    complete();\n                    return;\n                }\n                var todo = the.files.length;\n                var movefolders = function() {\n                    if (!(todo--)) {\n                        src.deleteAsync().done(complete,failed);\n                        return;\n                    }\n                    moveFolder(the.folders[todo],dst)\n                    .done(movefolders,failed); \n                };\n                var movefiles = function() {\n                    if (!(todo--)) {\n                        todo = the.folders.length;\n                        movefolders();\n                        return;\n                    }\n                    the.files[todo].moveAsync(the.fld)\n                    .done(function() { movefiles(); }, failed);\n                };\n                movefiles();\n            },\n            failed\n        );\n    });\n}\n\nfunction transport(success, fail, args, ops) { // [\"fullPath\",\"parent\", \"newName\"]\n    var src = args[0];\n    var parent = args[1];\n    var name = args[2];\n\n    var srcFS = getFilesystemFromURL(src);\n    var dstFS = getFilesystemFromURL(parent);\n    var srcPath = pathFromURL(src);\n    var dstPath = pathFromURL(parent);\n    if (!(srcFS && dstFS && validName(name))){\n        fail(FileError.ENCODING_ERR);\n        return;\n    }\n    \n    var srcWinPath = cordovaPathToNative(sanitize(srcFS.winpath + srcPath));\n    var dstWinPath = cordovaPathToNative(sanitize(dstFS.winpath + dstPath));\n    var tgtFsPath = sanitize(dstPath+'/'+name);\n    var tgtWinPath = cordovaPathToNative(sanitize(dstFS.winpath + dstPath+'/'+name));\n    if (srcWinPath == dstWinPath || srcWinPath == tgtWinPath) {\n        fail(FileError.INVALID_MODIFICATION_ERR);\n        return;\n    }\n    \n    \n    WinJS.Promise.join({\n        src:openPath(srcWinPath),\n        dst:openPath(dstWinPath),\n        tgt:openPath(tgtWinPath,{getContent:true})\n    })\n    .done(\n        function (the) {\n            if ((!the.dst.folder) || !(the.src.folder || the.src.file)) {\n                fail(FileError.NOT_FOUND_ERR);\n                return;\n            }\n            if ((the.src.folder && the.tgt.file) ||\n                (the.src.file && the.tgt.folder) ||\n                (the.tgt.folder && (the.tgt.files.length || the.tgt.folders.length))) {\n                fail(FileError.INVALID_MODIFICATION_ERR);\n                return;\n            }\n            if (the.src.file)\n                ops.fileOp(the.src.file,the.dst.folder, name, Windows.Storage.NameCollisionOption.replaceExisting)\n                .done(\n                    function (storageFile) {\n                        success(new FileEntry(\n                            name,\n                            tgtFsPath,\n                            dstFS.name,\n                            dstFS.makeNativeURL(tgtFsPath)\n                        ));\n                    },\n                    function (err) {\n                        fail(FileError.INVALID_MODIFICATION_ERR);\n                    }\n                );\n            else\n                ops.folderOp(the.src.folder, the.dst.folder, name).done(\n                    function () {\n                        success(new DirectoryEntry(\n                            name, \n                            tgtFsPath, \n                            dstFS.name, \n                            dstFS.makeNativeURL(tgtFsPath)\n                        ));\n                    },\n                    function() {\n                        fail(FileError.INVALID_MODIFICATION_ERR);\n                    }\n                );\n        },\n        function(err) {\n            fail(FileError.INVALID_MODIFICATION_ERR);\n        }\n    );\n}\n\nmodule.exports = {\n    requestAllFileSystems: function() {\n        return getAllFS();\n    },\n    requestAllPaths: function(success){\n        success(windowsPaths);\n    },\n    getFileMetadata: function (success, fail, args) {\n        module.exports.getMetadata(success, fail, args);\n    },\n\n    getMetadata: function (success, fail, args) {\n        var fs = getFilesystemFromURL(args[0]);\n        var path = pathFromURL(args[0]);\n        if (!fs || !validName(path)){\n            fail(FileError.ENCODING_ERR);\n            return;\n        }\n        var fullPath = cordovaPathToNative(fs.winpath + path);\n\n        var getMetadataForFile = function (storageFile) {\n            storageFile.getBasicPropertiesAsync().then(\n                function (basicProperties) {\n                    success(new File(storageFile.name, storageFile.path, storageFile.fileType, basicProperties.dateModified, basicProperties.size));\n                }, function () {\n                    fail(FileError.NOT_READABLE_ERR);\n                }\n            );\n        };\n\n        var getMetadataForFolder = function (storageFolder) {\n            storageFolder.getBasicPropertiesAsync().then(\n                function (basicProperties) {\n                    var metadata = {\n                        size: basicProperties.size,\n                        lastModifiedDate: basicProperties.dateModified\n                    };\n                    success(metadata);\n                },\n                function () {\n                    fail(FileError.NOT_READABLE_ERR);\n                }\n            );\n        };\n\n        getFileFromPathAsync(fullPath).then(getMetadataForFile,\n            function () {\n                getFolderFromPathAsync(fullPath).then(getMetadataForFolder,\n                    function () {\n                        fail(FileError.NOT_FOUND_ERR);\n                    }\n                );\n            }\n        );\n    },\n\n    getParent: function (win, fail, args) { // [\"fullPath\"]\n        var fs = getFilesystemFromURL(args[0]);\n        var path = pathFromURL(args[0]);\n        if (!fs || !validName(path)){\n            fail(FileError.ENCODING_ERR);\n            return;\n        }\n        if (!path || (new RegExp('/[^/]*/?$')).test(path)) {\n            win(new DirectoryEntry(fs.root.name, fs.root.fullPath, fs.name, fs.makeNativeURL(fs.root.fullPath)));\n            return;\n        }\n        \n        var parpath = path.replace(new RegExp('/[^/]+/?$','g'),'');\n        var parname = path.substr(parpath.length);\n        var fullPath = cordovaPathToNative(fs.winpath + parpath);\n        \n        var result = new DirectoryEntry(parname, parpath, fs.name, fs.makeNativeURL(parpath));\n        getFolderFromPathAsync(fullPath).done(\n            function () { win(result); },\n            function () { fail(FileError.INVALID_STATE_ERR); }\n        );\n    },\n\n    readAsText: function (win, fail, args) {\n\n        var url = args[0],\n            enc = args[1],\n            startPos = args[2],\n            endPos = args[3];\n        \n        var fs = getFilesystemFromURL(url);\n        var path = pathFromURL(url);\n        if (!fs){\n            fail(FileError.ENCODING_ERR);\n            return;\n        }\n        var wpath = cordovaPathToNative(sanitize(fs.winpath + path));\n        \n        var encoding = Windows.Storage.Streams.UnicodeEncoding.utf8;\n        if (enc == 'Utf16LE' || enc == 'utf16LE') {\n            encoding = Windows.Storage.Streams.UnicodeEncoding.utf16LE;\n        } else if (enc == 'Utf16BE' || enc == 'utf16BE') {\n            encoding = Windows.Storage.Streams.UnicodeEncoding.utf16BE;\n        }\n\n        getFileFromPathAsync(wpath).then(function(file) {\n                return file.openReadAsync();\n            }).then(function (stream) {\n                startPos = (startPos < 0) ? Math.max(stream.size + startPos, 0) : Math.min(stream.size, startPos);\n                endPos = (endPos < 0) ? Math.max(endPos + stream.size, 0) : Math.min(stream.size, endPos);\n                stream.seek(startPos);\n                \n                var readSize = endPos - startPos,\n                    buffer = new Windows.Storage.Streams.Buffer(readSize);\n\n                return stream.readAsync(buffer, readSize, Windows.Storage.Streams.InputStreamOptions.none);\n            }).done(function(buffer) {\n            \ttry {\n            \t\twin(Windows.Security.Cryptography.CryptographicBuffer.convertBinaryToString(encoding, buffer));\n                }\n                catch (e) {\n                \tfail(FileError.ENCODING_ERR);\n                }\n            },function() {\n                fail(FileError.NOT_FOUND_ERR);\n            });\n    },\n\n    readAsBinaryString:function(win,fail,args) {\n        var url = args[0],\n            startPos = args[1],\n            endPos = args[2];\n\n        var fs = getFilesystemFromURL(url);\n        var path = pathFromURL(url);\n        if (!fs){\n            fail(FileError.ENCODING_ERR);\n            return;\n        }\n        var wpath = cordovaPathToNative(sanitize(fs.winpath + path));\n\n        getFileFromPathAsync(wpath).then(\n            function (storageFile) {\n                Windows.Storage.FileIO.readBufferAsync(storageFile).done(\n                    function (buffer) {\n                        var dataReader = Windows.Storage.Streams.DataReader.fromBuffer(buffer);\n                        // var fileContent = dataReader.readString(buffer.length);\n                        var byteArray = new Uint8Array(buffer.length),\n                            byteString = \"\";\n                        dataReader.readBytes(byteArray);\n                        dataReader.close();\n                        for (var i = 0; i < byteArray.length; i++) {\n                            var charByte = byteArray[i];\n                            // var charRepresentation = charByte <= 127 ? String.fromCharCode(charByte) : charByte.toString(16);\n                            var charRepresentation = String.fromCharCode(charByte);\n                            byteString += charRepresentation;\n                        }\n                        win(byteString.slice(startPos, endPos));\n                    }\n                );\n            }, function () {\n                fail(FileError.NOT_FOUND_ERR);\n            }\n        );\n    },\n\n    readAsArrayBuffer:function(win,fail,args) {\n        var url = args[0];\n        var fs = getFilesystemFromURL(url);\n        var path = pathFromURL(url);\n        if (!fs){\n            fail(FileError.ENCODING_ERR);\n            return;\n        }\n        var wpath = cordovaPathToNative(sanitize(fs.winpath + path));\n\n        getFileFromPathAsync(wpath).then(\n            function (storageFile) {\n                var blob = MSApp.createFileFromStorageFile(storageFile);\n                var url = URL.createObjectURL(blob, { oneTimeOnly: true });\n                var xhr = new XMLHttpRequest();\n                xhr.open(\"GET\", url, true);\n                xhr.responseType = 'arraybuffer';\n                xhr.onload = function () {\n                    var resultArrayBuffer = xhr.response;\n                    // get start and end position of bytes in buffer to be returned\n                    var startPos = args[1] || 0,\n                        endPos = args[2] || resultArrayBuffer.length;\n                    // if any of them is specified, we'll slice output array\n                    if (startPos !== 0 || endPos !== resultArrayBuffer.length) {\n                        // slice method supported only on Windows 8.1, so we need to check if it's available \n                        // see http://msdn.microsoft.com/en-us/library/ie/dn641192(v=vs.94).aspx\n                        if (resultArrayBuffer.slice) {\n                            resultArrayBuffer = resultArrayBuffer.slice(startPos, endPos);\n                        } else {\n                            // if slice isn't available, we'll use workaround method\n                            var tempArray = new Uint8Array(resultArrayBuffer),\n                                resBuffer = new ArrayBuffer(endPos - startPos),\n                                resArray = new Uint8Array(resBuffer);\n\n                            for (var i = 0; i < resArray.length; i++) {\n                                resArray[i] = tempArray[i + startPos];\n                            }\n                            resultArrayBuffer = resBuffer;\n                        }\n                    }\n                    win(resultArrayBuffer);\n                };\n                xhr.send();\n            }, function () {\n                fail(FileError.NOT_FOUND_ERR);\n            }\n        );\n    },\n\n    readAsDataURL: function (win, fail, args) {\n        var url = args[0];\n        var fs = getFilesystemFromURL(url);\n        var path = pathFromURL(url);\n        if (!fs){\n            fail(FileError.ENCODING_ERR);\n            return;\n        }\n        var wpath = cordovaPathToNative(sanitize(fs.winpath + path));\n\n        getFileFromPathAsync(wpath).then(\n            function (storageFile) {\n                Windows.Storage.FileIO.readBufferAsync(storageFile).done(\n                    function (buffer) {\n                        var strBase64 = Windows.Security.Cryptography.CryptographicBuffer.encodeToBase64String(buffer);\n                        //the method encodeToBase64String will add \"77u/\" as a prefix, so we should remove it\n                        if(String(strBase64).substr(0,4) == \"77u/\") {\n                            strBase64 = strBase64.substr(4);\n                        }\n                        var mediaType = storageFile.contentType;\n                        var result = \"data:\" + mediaType + \";base64,\" + strBase64;\n                        win(result);\n                    }\n                );\n            }, function () {\n                fail(FileError.NOT_FOUND_ERR);\n            }\n        );\n    },\n\n    getDirectory: function (win, fail, args) {\n        var dirurl = args[0];\n        var path = args[1];\n        var options = args[2];\n\n        var fs = getFilesystemFromURL(dirurl);\n        var dirpath = pathFromURL(dirurl);\n        if (!fs || !validName(path)){\n            fail(FileError.ENCODING_ERR);\n            return;\n        }           \n        var fspath = sanitize(dirpath +'/'+ path);\n        var completePath = sanitize(fs.winpath + fspath);\n\n        var name = completePath.substring(completePath.lastIndexOf('/')+1);\n        \n        var wpath = cordovaPathToNative(completePath.substring(0, completePath.lastIndexOf('/')));\n\n        var flag = \"\";\n        if (options) {\n            flag = new Flags(options.create, options.exclusive);\n        } else {\n            flag = new Flags(false, false);\n        }\n\n        getFolderFromPathAsync(wpath).done(\n            function (storageFolder) {\n                if (flag.create === true && flag.exclusive === true) {\n                    storageFolder.createFolderAsync(name, Windows.Storage.CreationCollisionOption.failIfExists).done(\n                        function (storageFolder) {\n                            win(new DirectoryEntry(storageFolder.name, fspath, fs.name, fs.makeNativeURL(fspath)));\n                        }, function (err) {\n                            fail(FileError.PATH_EXISTS_ERR);\n                        }\n                    );\n                } else if (flag.create === true && flag.exclusive === false) {\n                    storageFolder.createFolderAsync(name, Windows.Storage.CreationCollisionOption.openIfExists).done(\n                        function (storageFolder) {\n                            win(new DirectoryEntry(storageFolder.name, fspath, fs.name, fs.makeNativeURL(fspath)));\n                        }, function () {\n                            fail(FileError.INVALID_MODIFICATION_ERR);\n                        }\n                    );\n                } else if (flag.create === false) {\n                    storageFolder.getFolderAsync(name).done(\n                        function (storageFolder) {\n                            win(new DirectoryEntry(storageFolder.name, fspath, fs.name, fs.makeNativeURL(fspath)));\n                        }, \n                        function () {\n                            // check if path actually points to a file\n                            storageFolder.getFileAsync(name).done(\n                                function () {\n                                    fail(FileError.TYPE_MISMATCH_ERR);\n                                }, function() {\n                                    fail(FileError.NOT_FOUND_ERR);\n                                }\n                            );\n                        }\n                    );\n                }\n            }, function () {\n                fail(FileError.NOT_FOUND_ERR);\n            }\n        );\n    },\n\n    remove: function (win, fail, args) {\n        var fs = getFilesystemFromURL(args[0]);\n        var path = pathFromURL(args[0]);\n        if (!fs || !validName(path)){\n            fail(FileError.ENCODING_ERR);\n            return;\n        }\n\n        // FileSystem root can't be removed!\n        if (!path || path=='/'){\n            fail(FileError.NO_MODIFICATION_ALLOWED_ERR);\n            return;\n        }\n        var fullPath = cordovaPathToNative(fs.winpath + path);\n\n        getFileFromPathAsync(fullPath).then(\n            function (storageFile) {\n                    storageFile.deleteAsync().done(win, function () {\n                        fail(FileError.INVALID_MODIFICATION_ERR);\n                });\n            },\n            function () {\n                getFolderFromPathAsync(fullPath).done(\n                    function (sFolder) {\n                        sFolder.getFilesAsync()\n                        // check for files\n                        .then(function(fileList) {\n                            if (fileList) {\n                                if (fileList.length === 0) {\n                                    return sFolder.getFoldersAsync();\n                                } else {\n                                    fail(FileError.INVALID_MODIFICATION_ERR);\n                                }\n                            }\n                        })\n                        // check for folders\n                        .done(function (folderList) {\n                            if (folderList) {\n                                if (folderList.length === 0) {\n                                    sFolder.deleteAsync().done(\n                                        win, \n                                        function () {\n                                            fail(FileError.INVALID_MODIFICATION_ERR);\n                                        }\n                                    );\n                                } else {\n                                    fail(FileError.INVALID_MODIFICATION_ERR);\n                                }\n                            }\n                        });\n                    }, \n                    function () {\n                        fail(FileError.NOT_FOUND_ERR);\n                    }\n                );\n            }\n        );\n    },\n\n    removeRecursively: function (successCallback, fail, args) {\n\n        var fs = getFilesystemFromURL(args[0]);\n        var path = pathFromURL(args[0]);\n        if (!fs || !validName(path)){\n            fail(FileError.ENCODING_ERR);\n            return;\n        }\n\n        // FileSystem root can't be removed!\n        if (!path || path=='/'){\n            fail(FileError.NO_MODIFICATION_ALLOWED_ERR);\n            return;\n        }\n        var fullPath = cordovaPathToNative(fs.winpath + path);\n\n        getFolderFromPathAsync(fullPath).done(function (storageFolder) {\n            storageFolder.deleteAsync().done(function (res) {\n                successCallback(res);\n            }, function (err) {\n                fail(err);\n            });\n\n        }, function () {\n            fail(FileError.FILE_NOT_FOUND_ERR);\n        });\n    },\n\n    getFile: function (win, fail, args) {\n\n        var dirurl = args[0];\n        var path = args[1];\n        var options = args[2];\n\n        var fs = getFilesystemFromURL(dirurl);\n        var dirpath = pathFromURL(dirurl);\n        if (!fs || !validName(path)){\n            fail(FileError.ENCODING_ERR);\n            return;\n        }\n        var fspath = sanitize(dirpath +'/'+ path);\n        var completePath = sanitize(fs.winpath + fspath);\n\n        var fileName = completePath.substring(completePath.lastIndexOf('/')+1);\n        \n        var wpath = cordovaPathToNative(completePath.substring(0, completePath.lastIndexOf('/')));\n\n        var flag = \"\";\n        if (options !== null) {\n            flag = new Flags(options.create, options.exclusive);\n        } else {\n            flag = new Flags(false, false);\n        }\n\n        getFolderFromPathAsync(wpath).done(\n            function (storageFolder) {\n                if (flag.create === true && flag.exclusive === true) {\n                    storageFolder.createFileAsync(fileName, Windows.Storage.CreationCollisionOption.failIfExists).done(\n                        function (storageFile) {\n                            win(new FileEntry(storageFile.name, fspath, fs.name, fs.makeNativeURL(fspath)));\n                        }, function () {\n                            fail(FileError.PATH_EXISTS_ERR);\n                        }\n                    );\n                } else if (flag.create === true && flag.exclusive === false) {\n                    storageFolder.createFileAsync(fileName, Windows.Storage.CreationCollisionOption.openIfExists).done(\n                        function (storageFile) {\n                            win(new FileEntry(storageFile.name, fspath, fs.name, fs.makeNativeURL(fspath)));\n                        }, function () {\n                            fail(FileError.INVALID_MODIFICATION_ERR);\n                        }\n                    );\n                } else if (flag.create === false) {\n                    storageFolder.getFileAsync(fileName).done(\n                        function (storageFile) {\n                            win(new FileEntry(storageFile.name, fspath, fs.name, fs.makeNativeURL(fspath)));\n                        }, function () {\n                            // check if path actually points to a folder\n                            storageFolder.getFolderAsync(fileName).done(\n                                function () {\n                                    fail(FileError.TYPE_MISMATCH_ERR);\n                                }, function () {\n                                    fail(FileError.NOT_FOUND_ERR);\n                                });\n                        }\n                    );\n                }\n            }, function (err) {\n                fail(\n                    err.number == WinError.accessDenied?\n                    FileError.SECURITY_ERR:\n                    FileError.NOT_FOUND_ERR\n                );\n            }\n        );\n    },\n\n    readEntries: function (win, fail, args) { // [\"fullPath\"]\n        var fs = getFilesystemFromURL(args[0]);\n        var path = pathFromURL(args[0]);\n        if (!fs || !validName(path)){\n            fail(FileError.ENCODING_ERR);\n            return;\n        }\n        var fullPath = cordovaPathToNative(fs.winpath + path);\n\n        var result = [];\n\n        getFolderFromPathAsync(fullPath).done(function (storageFolder) {\n            var promiseArr = [];\n            var index = 0;\n            promiseArr[index++] = storageFolder.getFilesAsync().then(function (fileList) {\n                if (fileList !== null) {\n                    for (var i = 0; i < fileList.length; i++) {\n                        var fspath = getFsPathForWinPath(fs, fileList[i].path);\n                        if (!fspath) {\n                            fail(FileError.NOT_FOUND_ERR);\n                            return;\n                        }\n                        result.push(new FileEntry(fileList[i].name, fspath, fs.name, fs.makeNativeURL(fspath)));\n                    }\n                }\n            });\n            promiseArr[index++] = storageFolder.getFoldersAsync().then(function (folderList) {\n                if (folderList !== null) {\n                    for (var j = 0; j < folderList.length; j++) {\n                        var fspath = getFsPathForWinPath(fs, folderList[j].path);\n                        if (!fspath) {\n                            fail(FileError.NOT_FOUND_ERR);\n                            return;\n                        }\n                        result.push(new DirectoryEntry(folderList[j].name, fspath, fs.name, fs.makeNativeURL(fspath)));\n                    }\n                }\n            });\n            WinJS.Promise.join(promiseArr).then(function () {\n                win(result);\n            });\n\n        }, function () { fail(FileError.NOT_FOUND_ERR); });\n    },\n\n    write: function (win, fail, args) {\n\n        var url = args[0],\n            data = args[1],\n            position = args[2],\n            isBinary = args[3];\n\n        var fs = getFilesystemFromURL(url);\n        var path = pathFromURL(url);\n        if (!fs){\n            fail(FileError.ENCODING_ERR);\n            return;\n        }\n        var completePath = sanitize(fs.winpath + path);\n        var fileName = completePath.substring(completePath.lastIndexOf('/')+1);\n        var dirpath = completePath.substring(0,completePath.lastIndexOf('/'));\n        var wpath = cordovaPathToNative(dirpath);\n        \n        function getWriteMethodForData(data, isBinary) {\n            \n            if (data instanceof Blob) {\n                return writeBlobAsync;\n            }\n\n            if (data instanceof ArrayBuffer) {\n                return writeArrayBufferAsync;\n            }\n\n            if (isBinary) {\n                return writeBytesAsync;\n            }\n\n            if (typeof data === 'string') {\n                return writeTextAsync;\n            }\n\n            throw new Error('Unsupported data type for write method');          \n        }\n\n        var writePromise = getWriteMethodForData(data, isBinary);\n\n        getFolderFromPathAsync(wpath).done(\n            function (storageFolder) {\n                storageFolder.createFileAsync(fileName, Windows.Storage.CreationCollisionOption.openIfExists).done(\n                    function (storageFile) {\n                        writePromise(storageFile, data, position).done(\n                            function (bytesWritten) {\n                                var written = bytesWritten || data.length;\n                                win(written);\n                            },\n                            function () {\n                                fail(FileError.INVALID_MODIFICATION_ERR);\n                            }\n                        );\n                    },\n                    function () {\n                        fail(FileError.INVALID_MODIFICATION_ERR);\n                    }\n                );\n\n            },\n            function () {\n                fail(FileError.NOT_FOUND_ERR);\n            }\n        );\n    },\n\n    truncate: function (win, fail, args) { // [\"fileName\",\"size\"]\n        var url = args[0];\n        var size = args[1];\n        \n        var fs = getFilesystemFromURL(url);\n        var path = pathFromURL(url);\n        if (!fs){\n            fail(FileError.ENCODING_ERR);\n            return;\n        }\n        var completePath = sanitize(fs.winpath + path);\n        var wpath = cordovaPathToNative(completePath);\n        var dirwpath = cordovaPathToNative(completePath.substring(0,completePath.lastIndexOf('/')));\n\n        getFileFromPathAsync(wpath).done(function(storageFile){\n            //the current length of the file.\n            var leng = 0;\n\n            storageFile.getBasicPropertiesAsync().then(function (basicProperties) {\n                leng = basicProperties.size;\n                if (Number(size) >= leng) {\n                    win(this.length);\n                    return;\n                }\n                if (Number(size) >= 0) {\n                    Windows.Storage.FileIO.readTextAsync(storageFile, Windows.Storage.Streams.UnicodeEncoding.utf8).then(function (fileContent) {\n                        fileContent = fileContent.substr(0, size);\n                        var name = storageFile.name;\n                        storageFile.deleteAsync().then(function () {\n                            return getFolderFromPathAsync(dirwpath);\n                        }).done(function (storageFolder) {\n                            storageFolder.createFileAsync(name).then(function (newStorageFile) {\n                                Windows.Storage.FileIO.writeTextAsync(newStorageFile, fileContent).done(function () {\n                                    win(String(fileContent).length);\n                                }, function () {\n                                    fail(FileError.NO_MODIFICATION_ALLOWED_ERR);\n                                });\n                            }, function() {\n                                fail(FileError.NO_MODIFICATION_ALLOWED_ERR);\n                            });\n                        });\n                    }, function () { fail(FileError.NOT_FOUND_ERR); });\n                }\n            });\n        }, function () { fail(FileError.NOT_FOUND_ERR); });\n    },\n\n    copyTo: function (success, fail, args) { // [\"fullPath\",\"parent\", \"newName\"]\n        transport(success, fail, args,\n            {\n                fileOp:function(file,folder,name,coll) {\n                    return file.copyAsync(folder,name,coll);\n                },\n                folderOp:function(src,dst,name) {\n                    return copyFolder(src,dst,name);\n            }}\n        );\n    },\n\n    moveTo: function (success, fail, args) {\n        transport(success, fail, args,\n            {\n                fileOp:function(file,folder,name,coll) {\n                    return file.moveAsync(folder,name,coll);\n                },\n                folderOp:function(src,dst,name) {\n                    return moveFolder(src,dst,name);\n            }}\n        );\n    },\n    tempFileSystem:null,\n\n    persistentFileSystem:null,\n\n    requestFileSystem: function (win, fail, args) {\n\n        var type = args[0];\n        var size = args[1];\n        var MAX_SIZE = 10000000000;\n        if (size > MAX_SIZE) {\n            fail(FileError.QUOTA_EXCEEDED_ERR);\n            return;\n        }\n        \n        var fs;\n        switch (type) {\n            case LocalFileSystem.TEMPORARY:\n                fs = getFS('temporary');\n                break;\n            case LocalFileSystem.PERSISTENT:\n                fs = getFS('persistent');\n                break;\n        }\n        if (fs)\n            win(fs);\n        else\n            fail(FileError.NOT_FOUND_ERR);\n    },\n\n    resolveLocalFileSystemURI: function (success, fail, args) {\n\n        var uri = args[0];\n\n        var path = pathFromURL(uri);\n        var fs = getFilesystemFromURL(uri);\n        if (!fs || !validName(path)) {\n            fail(FileError.ENCODING_ERR);\n            return;\n        }\n        if (path.indexOf(fs.winpath) === 0)\n            path=path.substr(fs.winpath.length);\n        var abspath = cordovaPathToNative(fs.winpath+path);\n        \n        getFileFromPathAsync(abspath).done(\n            function (storageFile) {\n                success(new FileEntry(storageFile.name, path, fs.name, fs.makeNativeURL(path)));\n            }, function () {\n                getFolderFromPathAsync(abspath).done(\n                    function (storageFolder) {\n                        success(new DirectoryEntry(storageFolder.name, path, fs.name,fs.makeNativeURL(path)));\n                    }, function () {\n                        fail(FileError.NOT_FOUND_ERR);\n                    }\n                );\n            }\n        );\n    }\n    \n\n};\n\nrequire(\"cordova/exec/proxy\").add(\"File\",module.exports);\n"
  },
  {
    "path": "plugins/cordova-plugin-file/src/wp/File.cs",
    "content": "/*  \n    Licensed under the Apache License, Version 2.0 (the \"License\");\n    you may not use this file except in compliance with the License.\n    You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing, software\n    distributed under the License is distributed on an \"AS IS\" BASIS,\n    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n    See the License for the specific language governing permissions and\n    limitations under the License.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.IO;\nusing System.IO.IsolatedStorage;\nusing System.Runtime.Serialization;\nusing System.Security;\nusing System.Text;\nusing System.Windows;\nusing System.Windows.Resources;\nusing WPCordovaClassLib.Cordova.JSON;\n\nnamespace WPCordovaClassLib.Cordova.Commands\n{\n    /// <summary>\n    /// Provides access to isolated storage\n    /// </summary>\n    public class File : BaseCommand\n    {\n        // Error codes\n        public const int NOT_FOUND_ERR = 1;\n        public const int SECURITY_ERR = 2;\n        public const int ABORT_ERR = 3;\n        public const int NOT_READABLE_ERR = 4;\n        public const int ENCODING_ERR = 5;\n        public const int NO_MODIFICATION_ALLOWED_ERR = 6;\n        public const int INVALID_STATE_ERR = 7;\n        public const int SYNTAX_ERR = 8;\n        public const int INVALID_MODIFICATION_ERR = 9;\n        public const int QUOTA_EXCEEDED_ERR = 10;\n        public const int TYPE_MISMATCH_ERR = 11;\n        public const int PATH_EXISTS_ERR = 12;\n\n        // File system options\n        public const int TEMPORARY = 0;\n        public const int PERSISTENT = 1;\n        public const int RESOURCE = 2;\n        public const int APPLICATION = 3;\n\n        /// <summary>\n        /// Temporary directory name\n        /// </summary>\n        private readonly string TMP_DIRECTORY_NAME = \"tmp\";\n\n        /// <summary>\n        /// Represents error code for callback\n        /// </summary>\n        [DataContract]\n        public class ErrorCode\n        {\n            /// <summary>\n            /// Error code\n            /// </summary>\n            [DataMember(IsRequired = true, Name = \"code\")]\n            public int Code { get; set; }\n\n            /// <summary>\n            /// Creates ErrorCode object\n            /// </summary>\n            public ErrorCode(int code)\n            {\n                this.Code = code;\n            }\n        }\n\n        /// <summary>\n        /// Represents File action options.\n        /// </summary>\n        [DataContract]\n        public class FileOptions\n        {\n            /// <summary>\n            /// File path\n            /// </summary>\n            /// \n            private string _fileName;\n            [DataMember(Name = \"fileName\")]\n            public string FilePath\n            {\n                get\n                {\n                    return this._fileName;\n                }\n\n                set\n                {\n                    int index = value.IndexOfAny(new char[] { '#', '?' });\n                    this._fileName = index > -1 ? value.Substring(0, index) : value;\n                }\n            }\n\n            /// <summary>\n            /// Full entryPath\n            /// </summary>\n            [DataMember(Name = \"fullPath\")]\n            public string FullPath { get; set; }\n\n            /// <summary>\n            /// Directory name\n            /// </summary>\n            [DataMember(Name = \"dirName\")]\n            public string DirectoryName { get; set; }\n\n            /// <summary>\n            /// Path to create file/directory\n            /// </summary>\n            [DataMember(Name = \"path\")]\n            public string Path { get; set; }\n\n            /// <summary>\n            /// The encoding to use to encode the file's content. Default is UTF8.\n            /// </summary>\n            [DataMember(Name = \"encoding\")]\n            public string Encoding { get; set; }\n\n            /// <summary>\n            /// Uri to get file\n            /// </summary>\n            /// \n            private string _uri;\n            [DataMember(Name = \"uri\")]\n            public string Uri\n            {\n                get\n                {\n                    return this._uri;\n                }\n\n                set\n                {\n                    int index = value.IndexOfAny(new char[] { '#', '?' });\n                    this._uri = index > -1 ? value.Substring(0, index) : value;\n                }\n            }\n\n            /// <summary>\n            /// Size to truncate file\n            /// </summary>\n            [DataMember(Name = \"size\")]\n            public long Size { get; set; }\n\n            /// <summary>\n            /// Data to write in file\n            /// </summary>\n            [DataMember(Name = \"data\")]\n            public string Data { get; set; }\n\n            /// <summary>\n            /// Position the writing starts with\n            /// </summary>\n            [DataMember(Name = \"position\")]\n            public int Position { get; set; }\n\n            /// <summary>\n            /// Type of file system requested\n            /// </summary>\n            [DataMember(Name = \"type\")]\n            public int FileSystemType { get; set; }\n\n            /// <summary>\n            /// New file/directory name\n            /// </summary>\n            [DataMember(Name = \"newName\")]\n            public string NewName { get; set; }\n\n            /// <summary>\n            /// Destination directory to copy/move file/directory\n            /// </summary>\n            [DataMember(Name = \"parent\")]\n            public string Parent { get; set; }\n\n            /// <summary>\n            /// Options for getFile/getDirectory methods\n            /// </summary>\n            [DataMember(Name = \"options\")]\n            public CreatingOptions CreatingOpt { get; set; }\n\n            /// <summary>\n            /// Creates options object with default parameters\n            /// </summary>\n            public FileOptions()\n            {\n                this.SetDefaultValues(new StreamingContext());\n            }\n\n            /// <summary>\n            /// Initializes default values for class fields.\n            /// Implemented in separate method because default constructor is not invoked during deserialization.\n            /// </summary>\n            /// <param name=\"context\"></param>\n            [OnDeserializing()]\n            public void SetDefaultValues(StreamingContext context)\n            {\n                this.Encoding = \"UTF-8\";\n                this.FilePath = \"\";\n                this.FileSystemType = -1; \n            }\n        }\n\n        /// <summary>\n        /// Stores image info\n        /// </summary>\n        [DataContract]\n        public class FileMetadata\n        {\n            [DataMember(Name = \"fileName\")]\n            public string FileName { get; set; }\n\n            [DataMember(Name = \"fullPath\")]\n            public string FullPath { get; set; }\n\n            [DataMember(Name = \"type\")]\n            public string Type { get; set; }\n\n            [DataMember(Name = \"lastModifiedDate\")]\n            public string LastModifiedDate { get; set; }\n\n            [DataMember(Name = \"size\")]\n            public long Size { get; set; }\n\n            public FileMetadata(string filePath)\n            {\n                if (string.IsNullOrEmpty(filePath))\n                {\n                    throw new FileNotFoundException(\"File doesn't exist\");\n                }\n\n                this.FullPath = filePath;\n                this.Size = 0;\n                this.FileName = string.Empty;\n\n                using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())\n                {\n                    bool IsFile = isoFile.FileExists(filePath);\n                    bool IsDirectory = isoFile.DirectoryExists(filePath);\n\n                        if (!IsDirectory)\n                        {\n                            if (!IsFile)      // special case, if isoFile cannot find it, it might still be part of the app-package\n                            {\n                                // attempt to get it from the resources\n\n                                Uri fileUri = new Uri(filePath, UriKind.Relative);\n                                StreamResourceInfo streamInfo = Application.GetResourceStream(fileUri);\n                                if (streamInfo != null)\n                                {\n                                    this.Size = streamInfo.Stream.Length;\n                                    this.FileName = filePath.Substring(filePath.LastIndexOf(\"/\") + 1);\n                                }\n                                else\n                                {\n                                    throw new FileNotFoundException(\"File doesn't exist\");\n                                }\n                            }\n                            else\n                            {\n                                using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, FileAccess.Read, isoFile))\n                                {\n                                    this.Size = stream.Length;\n                                }\n\n                                this.FileName = System.IO.Path.GetFileName(filePath);\n                                this.LastModifiedDate = isoFile.GetLastWriteTime(filePath).DateTime.ToString();\n                            }\n                        }\n\n                    this.Type = MimeTypeMapper.GetMimeType(this.FileName);\n                }\n            }\n        }\n\n        /// <summary>\n        /// Represents file or directory modification metadata\n        /// </summary>\n        [DataContract]\n        public class ModificationMetadata\n        {\n            /// <summary>\n            /// Modification time\n            /// </summary>\n            [DataMember]\n            public string modificationTime { get; set; }\n        }\n\n        /// <summary>\n        /// Represents file or directory entry\n        /// </summary>\n        [DataContract]\n        public class FileEntry\n        {\n\n            /// <summary>\n            /// File type\n            /// </summary>\n            [DataMember(Name = \"isFile\")]\n            public bool IsFile { get; set; }\n\n            /// <summary>\n            /// Directory type\n            /// </summary>\n            [DataMember(Name = \"isDirectory\")]\n            public bool IsDirectory { get; set; }\n\n            /// <summary>\n            /// File/directory name\n            /// </summary>\n            [DataMember(Name = \"name\")]\n            public string Name { get; set; }\n\n            /// <summary>\n            /// Full path to file/directory\n            /// </summary>\n            [DataMember(Name = \"fullPath\")]\n            public string FullPath { get; set; }\n\n            /// <summary>\n            /// URI encoded fullpath\n            /// </summary>\n            [DataMember(Name = \"nativeURL\")]\n            public string NativeURL\n            {\n                set { }\n                get\n                {\n                    string escaped = Uri.EscapeUriString(this.FullPath);\n                    escaped = escaped.Replace(\"//\", \"/\");\n                    if (escaped.StartsWith(\"/\"))\n                    {\n                        escaped = escaped.Insert(0, \"/\");\n                    }\n                    return escaped;\n                }\n            }\n\n            public bool IsResource { get; set; }\n\n            public static FileEntry GetEntry(string filePath, bool bIsRes=false)\n            {\n                FileEntry entry = null;\n                try\n                {\n                    entry = new FileEntry(filePath, bIsRes);\n\n                }\n                catch (Exception ex)\n                {\n                    Debug.WriteLine(\"Exception in GetEntry for filePath :: \" + filePath + \" \" + ex.Message);\n                }\n                return entry;\n            }\n\n            /// <summary>\n            /// Creates object and sets necessary properties\n            /// </summary>\n            /// <param name=\"filePath\"></param>\n            public FileEntry(string filePath, bool bIsRes = false)\n            {\n                if (string.IsNullOrEmpty(filePath))\n                {\n                    throw new ArgumentException();\n                }\n\n                if(filePath.Contains(\" \")) \n                {\n                    Debug.WriteLine(\"FilePath with spaces :: \" +  filePath);\n                }\n\n                using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())\n                {\n                    IsResource = bIsRes;\n                    IsFile = isoFile.FileExists(filePath);\n                    IsDirectory = isoFile.DirectoryExists(filePath);\n                    if (IsFile)\n                    {\n                        this.Name = Path.GetFileName(filePath);\n                    }\n                    else if (IsDirectory)\n                    {\n                        this.Name = this.GetDirectoryName(filePath);\n                        if (string.IsNullOrEmpty(Name))\n                        {\n                            this.Name = \"/\";\n                        }\n                    }\n                    else\n                    {\n                        if (IsResource)\n                        {\n                            this.Name = Path.GetFileName(filePath);\n                        }\n                        else\n                        {\n                            throw new FileNotFoundException();\n                        }\n                    }\n\n                    try\n                    {\n                        this.FullPath = filePath.Replace('\\\\', '/'); // new Uri(filePath).LocalPath;\n                    }\n                    catch (Exception)\n                    {\n                        this.FullPath = filePath;\n                    }\n                }\n            }\n\n            /// <summary>\n            /// Extracts directory name from path string\n            /// Path should refer to a directory, for example \\foo\\ or /foo.\n            /// </summary>\n            /// <param name=\"path\"></param>\n            /// <returns></returns>\n            private string GetDirectoryName(string path)\n            {\n                if (String.IsNullOrEmpty(path))\n                {\n                    return path;\n                }\n\n                string[] split = path.Split(new char[] { '/', '\\\\' }, StringSplitOptions.RemoveEmptyEntries);\n                if (split.Length < 1)\n                {\n                    return null;\n                }\n                else\n                {\n                    return split[split.Length - 1];\n                }\n            }\n        }\n\n\n        /// <summary>\n        /// Represents info about requested file system\n        /// </summary>\n        [DataContract]\n        public class FileSystemInfo\n        {\n            /// <summary>\n            /// file system type\n            /// </summary>\n            [DataMember(Name = \"name\", IsRequired = true)]\n            public string Name { get; set; }\n\n            /// <summary>\n            /// Root directory entry\n            /// </summary>\n            [DataMember(Name = \"root\", EmitDefaultValue = false)]\n            public FileEntry Root { get; set; }\n\n            /// <summary>\n            /// Creates class instance\n            /// </summary>\n            /// <param name=\"name\"></param>\n            /// <param name=\"rootEntry\"> Root directory</param>\n            public FileSystemInfo(string name, FileEntry rootEntry = null)\n            {\n                Name = name;\n                Root = rootEntry;\n            }\n        }\n\n        [DataContract]\n        public class CreatingOptions\n        {\n            /// <summary>\n            /// Create file/directory if is doesn't exist\n            /// </summary>\n            [DataMember(Name = \"create\")]\n            public bool Create { get; set; }\n\n            /// <summary>\n            /// Generate an exception if create=true and file/directory already exists\n            /// </summary>\n            [DataMember(Name = \"exclusive\")]\n            public bool Exclusive { get; set; }\n\n\n        }\n\n        // returns null value if it fails.\n        private string[] getOptionStrings(string options)\n        {\n            string[] optStings = null;\n            try\n            {\n                optStings = JSON.JsonHelper.Deserialize<string[]>(options);\n            }\n            catch (Exception)\n            {\n                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), CurrentCommandCallbackId);\n            }\n            return optStings;\n        }\n\n        /// <summary>\n        /// Gets amount of free space available for Isolated Storage\n        /// </summary>\n        /// <param name=\"options\">No options is needed for this method</param>\n        public void getFreeDiskSpace(string options)\n        {\n            string callbackId = getOptionStrings(options)[0];\n\n            try\n            {\n                using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())\n                {\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.OK, isoFile.AvailableFreeSpace), callbackId);\n                }\n            }\n            catch (IsolatedStorageException)\n            {\n                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);\n            }\n            catch (Exception ex)\n            {\n                if (!this.HandleException(ex))\n                {\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);\n                }\n            }\n        }\n\n        /// <summary>\n        /// Check if file exists\n        /// </summary>\n        /// <param name=\"options\">File path</param>\n        public void testFileExists(string options)\n        {\n            IsDirectoryOrFileExist(options, false);\n        }\n\n        /// <summary>\n        /// Check if directory exists\n        /// </summary>\n        /// <param name=\"options\">directory name</param>\n        public void testDirectoryExists(string options)\n        {\n            IsDirectoryOrFileExist(options, true);\n        }\n\n        /// <summary>\n        /// Check if file or directory exist\n        /// </summary>\n        /// <param name=\"options\">File path/Directory name</param>\n        /// <param name=\"isDirectory\">Flag to recognize what we should check</param>\n        public void IsDirectoryOrFileExist(string options, bool isDirectory)\n        {\n            string[] args = getOptionStrings(options);\n            string callbackId = args[1];\n            FileOptions fileOptions = JSON.JsonHelper.Deserialize<FileOptions>(args[0]);\n            string filePath = args[0];\n\n            if (fileOptions == null)\n            {\n                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);\n            }\n\n            try\n            {\n                using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())\n                {\n                    bool isExist;\n                    if (isDirectory)\n                    {\n                        isExist = isoFile.DirectoryExists(fileOptions.DirectoryName);\n                    }\n                    else\n                    {\n                        isExist = isoFile.FileExists(fileOptions.FilePath);\n                    }\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.OK, isExist), callbackId);\n                }\n            }\n            catch (IsolatedStorageException) // default handler throws INVALID_MODIFICATION_ERR\n            {\n                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);\n            }\n            catch (Exception ex)\n            {\n                if (!this.HandleException(ex))\n                {\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);\n                }\n            }\n\n        }\n\n        public void readAsDataURL(string options)\n        {\n            string[] optStrings = getOptionStrings(options);\n            string filePath = optStrings[0];\n            int startPos = int.Parse(optStrings[1]);\n            int endPos = int.Parse(optStrings[2]);\n            string callbackId = optStrings[3];\n\n            if (filePath != null)\n            {\n                try\n                {\n                    string base64URL = null;\n\n                    using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())\n                    {\n                        if (!isoFile.FileExists(filePath))\n                        {\n                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);\n                            return;\n                        }\n                        string mimeType = MimeTypeMapper.GetMimeType(filePath);\n\n                        using (IsolatedStorageFileStream stream = isoFile.OpenFile(filePath, FileMode.Open, FileAccess.Read))\n                        {\n                            string base64String = GetFileContent(stream);\n                            base64URL = \"data:\" + mimeType + \";base64,\" + base64String;\n                        }\n                    }\n\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.OK, base64URL), callbackId);\n                }\n                catch (Exception ex)\n                {\n                    if (!this.HandleException(ex))\n                    {\n                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);\n                    }\n                }\n            }\n        }\n\n        private byte[] readFileBytes(string filePath,int startPos,int endPos, IsolatedStorageFile isoFile)\n        {\n            byte[] buffer;\n            using (IsolatedStorageFileStream reader = isoFile.OpenFile(filePath, FileMode.Open, FileAccess.Read))\n            {\n                if (startPos < 0)\n                {\n                    startPos = Math.Max((int)reader.Length + startPos, 0);\n                }\n                else if (startPos > 0)\n                {\n                    startPos = Math.Min((int)reader.Length, startPos);\n                }\n                if (endPos > 0)\n                {\n                    endPos = Math.Min((int)reader.Length, endPos);\n                }\n                else if (endPos < 0)\n                {\n                    endPos = Math.Max(endPos + (int)reader.Length, 0);\n                }\n\n                buffer = new byte[endPos - startPos];\n                reader.Seek(startPos, SeekOrigin.Begin);\n                reader.Read(buffer, 0, buffer.Length);\n            }\n\n            return buffer;\n        }\n\n        public void readAsArrayBuffer(string options)\n        {\n            string[] optStrings = getOptionStrings(options);\n            string filePath = optStrings[0];\n            int startPos = int.Parse(optStrings[1]);\n            int endPos = int.Parse(optStrings[2]);\n            string callbackId = optStrings[3];\n\n            try\n            {\n                byte[] buffer;\n\n                using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())\n                {\n                    if (!isoFile.FileExists(filePath))\n                    {\n                        readResourceAsText(options);\n                        return;\n                    }\n                    buffer = readFileBytes(filePath, startPos, endPos, isoFile);\n                }\n\n                DispatchCommandResult(new PluginResult(PluginResult.Status.OK, buffer), callbackId);\n            }\n            catch (Exception ex)\n            {\n                if (!this.HandleException(ex, callbackId))\n                {\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);\n                }\n            }\n        }\n\n        public void readAsBinaryString(string options)\n        {\n            string[] optStrings = getOptionStrings(options);\n            string filePath = optStrings[0];\n            int startPos = int.Parse(optStrings[1]);\n            int endPos = int.Parse(optStrings[2]);\n            string callbackId = optStrings[3];\n\n            try\n            {\n                string result;\n\n                using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())\n                {\n                    if (!isoFile.FileExists(filePath))\n                    {\n                        readResourceAsText(options);\n                        return;\n                    }\n\n                    byte[] buffer = readFileBytes(filePath, startPos, endPos, isoFile);\n                    result = System.Text.Encoding.GetEncoding(\"iso-8859-1\").GetString(buffer, 0, buffer.Length);\n\n                }\n\n                DispatchCommandResult(new PluginResult(PluginResult.Status.OK, result), callbackId);\n            }\n            catch (Exception ex)\n            {\n                if (!this.HandleException(ex, callbackId))\n                {\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);\n                }\n            }\n        }\n\n        public void readAsText(string options)\n        {\n            string[] optStrings = getOptionStrings(options);\n            string filePath = optStrings[0];\n            string encStr = optStrings[1];\n            int startPos = int.Parse(optStrings[2]);\n            int endPos = int.Parse(optStrings[3]);\n            string callbackId = optStrings[4];\n\n            try\n            {\n                string text = \"\";\n\n                using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())\n                {\n                    if (!isoFile.FileExists(filePath))\n                    {\n                        readResourceAsText(options);\n                        return;\n                    }\n                    Encoding encoding = Encoding.GetEncoding(encStr);\n\n                    byte[] buffer = this.readFileBytes(filePath, startPos, endPos, isoFile);\n                    text = encoding.GetString(buffer, 0, buffer.Length);\n                }\n\n                // JIRA: https://issues.apache.org/jira/browse/CB-8792\n                // Need to perform additional serialization here because NativeExecution is always trying\n                // to do JSON.parse() on command result. This leads to issue when trying to read JSON files\n                var resultText = JsonHelper.Serialize(text);\n                DispatchCommandResult(new PluginResult(PluginResult.Status.OK, resultText), callbackId);\n            }\n            catch (Exception ex)\n            {\n                if (!this.HandleException(ex, callbackId))\n                {\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);\n                }\n            }\n        }\n\n        /// <summary>\n        /// Reads application resource as a text\n        /// </summary>\n        /// <param name=\"options\">Path to a resource</param>\n        public void readResourceAsText(string options)\n        {\n            string[] optStrings = getOptionStrings(options);\n            string pathToResource = optStrings[0];\n            string encStr = optStrings[1];\n            int start = int.Parse(optStrings[2]);\n            int endMarker = int.Parse(optStrings[3]);\n            string callbackId = optStrings[4];\n\n            try\n            {\n                if (pathToResource.StartsWith(\"/\"))\n                {\n                    pathToResource = pathToResource.Remove(0, 1);\n                }\n                \n                var resource = Application.GetResourceStream(new Uri(pathToResource, UriKind.Relative));\n                \n                if (resource == null)\n                {\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);\n                    return;\n                }\n\n                string text;\n                StreamReader streamReader = new StreamReader(resource.Stream);\n                text = streamReader.ReadToEnd();\n\n                DispatchCommandResult(new PluginResult(PluginResult.Status.OK, text), callbackId);\n            }\n            catch (Exception ex)\n            {\n                if (!this.HandleException(ex, callbackId))\n                {\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);\n                }\n            }\n        }\n\n        public void truncate(string options)\n        {\n            string[] optStrings = getOptionStrings(options);\n\n            string filePath = optStrings[0];\n            int size = int.Parse(optStrings[1]);\n            string callbackId = optStrings[2];\n\n            try\n            {\n                long streamLength = 0;\n\n                using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())\n                {\n                    if (!isoFile.FileExists(filePath))\n                    {\n                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);\n                        return;\n                    }\n\n                    using (FileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, FileAccess.ReadWrite, isoFile))\n                    {\n                        if (0 <= size && size <= stream.Length)\n                        {\n                            stream.SetLength(size);\n                        }\n                        streamLength = stream.Length;\n                    }\n                }\n\n                DispatchCommandResult(new PluginResult(PluginResult.Status.OK, streamLength), callbackId);\n            }\n            catch (Exception ex)\n            {\n                if (!this.HandleException(ex, callbackId))\n                {\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);\n                }\n            }\n        }\n\n        //write:[filePath,data,position,isBinary,callbackId]\n        public void write(string options)\n        {\n            string[] optStrings = getOptionStrings(options);\n\n            string filePath = optStrings[0];\n            string data = optStrings[1];\n            int position = int.Parse(optStrings[2]);\n            bool isBinary = bool.Parse(optStrings[3]);\n            string callbackId = optStrings[4];\n\n            try\n            {\n                if (string.IsNullOrEmpty(data))\n                {\n                    Debug.WriteLine(\"Expected some data to be send in the write command to {0}\", filePath);\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);\n                    return;\n                }\n\n                byte[] dataToWrite = isBinary ? JSON.JsonHelper.Deserialize<byte[]>(data) :\n                                     System.Text.Encoding.UTF8.GetBytes(data);\n\n                using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())\n                {\n                    // create the file if not exists\n                    if (!isoFile.FileExists(filePath))\n                    {\n                        var file = isoFile.CreateFile(filePath);\n                        file.Close();\n                    }\n\n                    using (FileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, FileAccess.ReadWrite, isoFile))\n                    {\n                        if (0 <= position && position <= stream.Length)\n                        {\n                            stream.SetLength(position);\n                        }\n                        using (BinaryWriter writer = new BinaryWriter(stream))\n                        {\n                            writer.Seek(0, SeekOrigin.End);\n                            writer.Write(dataToWrite);\n                        }\n                    }\n                }\n\n                DispatchCommandResult(new PluginResult(PluginResult.Status.OK, dataToWrite.Length), callbackId);\n            }\n            catch (Exception ex)\n            {\n                if (!this.HandleException(ex, callbackId))\n                {\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);\n                }\n            }\n        }\n\n        /// <summary>\n        /// Look up metadata about this entry.\n        /// </summary>\n        /// <param name=\"options\">filePath to entry</param>   \n        public void getMetadata(string options)\n        {\n            string[] optStings = getOptionStrings(options);\n            string filePath = optStings[0];\n            string callbackId = optStings[1];\n\n            if (filePath != null)\n            {\n                try\n                {\n                    using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())\n                    {\n                        if (isoFile.FileExists(filePath))\n                        {\n                            DispatchCommandResult(new PluginResult(PluginResult.Status.OK,\n                                new ModificationMetadata() { modificationTime = isoFile.GetLastWriteTime(filePath).DateTime.ToString() }), callbackId);\n                        }\n                        else if (isoFile.DirectoryExists(filePath))\n                        {\n                            string modTime = isoFile.GetLastWriteTime(filePath).DateTime.ToString();\n                            DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new ModificationMetadata() { modificationTime = modTime }), callbackId);\n                        }\n                        else\n                        {\n                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);\n                        }\n\n                    }\n                }\n                catch (IsolatedStorageException)\n                {\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);\n                }\n                catch (Exception ex)\n                {\n                    if (!this.HandleException(ex))\n                    {\n                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);\n                    }\n                }\n            }\n\n        }\n\n\n        /// <summary>\n        /// Returns a File that represents the current state of the file that this FileEntry represents.\n        /// </summary>\n        /// <param name=\"filePath\">filePath to entry</param>\n        /// <returns></returns>\n        public void getFileMetadata(string options)\n        {\n            string[] optStings = getOptionStrings(options);\n            string filePath = optStings[0];\n            string callbackId = optStings[1];\n\n            if (!string.IsNullOrEmpty(filePath))\n            {\n                try\n                {\n                    FileMetadata metaData = new FileMetadata(filePath);\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.OK, metaData), callbackId);\n                }\n                catch (IsolatedStorageException)\n                {\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);\n                }\n                catch (Exception ex)\n                {\n                    if (!this.HandleException(ex))\n                    {\n                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);\n                    }\n                }\n            }\n            else\n            {\n                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);\n            }\n        }\n\n        /// <summary>\n        /// Look up the parent DirectoryEntry containing this Entry. \n        /// If this Entry is the root of IsolatedStorage, its parent is itself.\n        /// </summary>\n        /// <param name=\"options\"></param>\n        public void getParent(string options)\n        {\n            string[] optStings = getOptionStrings(options);\n            string filePath = optStings[0];\n            string callbackId = optStings[1];\n\n            if (filePath != null)\n            {\n                try\n                {\n                    if (string.IsNullOrEmpty(filePath))\n                    {\n                        DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION),callbackId);\n                        return;\n                    }\n\n                    using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())\n                    {\n                        FileEntry entry;\n\n                        if (isoFile.FileExists(filePath) || isoFile.DirectoryExists(filePath))\n                        {\n                           \n                             \n                            string path = this.GetParentDirectory(filePath);\n                            entry = FileEntry.GetEntry(path);\n                            DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry),callbackId);\n                        }\n                        else\n                        {\n                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);\n                        }\n\n                    }\n                }\n                catch (Exception ex)\n                {\n                    if (!this.HandleException(ex))\n                    {\n                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);\n                    }\n                }\n            }\n        }\n\n        public void remove(string options)\n        {\n            string[] args = getOptionStrings(options);\n            string filePath = args[0];\n            string callbackId = args[1];\n\n            if (filePath != null)\n            {\n                try\n                {\n                    if (filePath == \"/\" || filePath == \"\" || filePath == @\"\\\")\n                    {\n                        throw new Exception(\"Cannot delete root file system\") ;\n                    }\n                    using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())\n                    {\n                        if (isoFile.FileExists(filePath))\n                        {\n                            isoFile.DeleteFile(filePath);\n                        }\n                        else\n                        {\n                            if (isoFile.DirectoryExists(filePath))\n                            {\n                                isoFile.DeleteDirectory(filePath);\n                            }\n                            else\n                            {\n                                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);\n                                return;\n                            }\n                        }\n                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK),callbackId);\n                    }\n                }\n                catch (Exception ex)\n                {\n                    if (!this.HandleException(ex))\n                    {\n                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR),callbackId);\n                    }\n                }\n            }\n        }\n\n        public void removeRecursively(string options)\n        {\n            string[] args = getOptionStrings(options);\n            string filePath = args[0];\n            string callbackId = args[1];\n\n            if (filePath != null)\n            {\n                if (string.IsNullOrEmpty(filePath))\n                {\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION),callbackId);\n                }\n                else\n                {\n                    if (removeDirRecursively(filePath, callbackId))\n                    {\n                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK), callbackId);\n                    }\n                }\n            }\n        }\n\n        public void readEntries(string options)\n        {\n            string[] args = getOptionStrings(options);\n            string filePath = args[0];\n            string callbackId = args[1];\n\n            if (filePath != null)\n            {\n                try\n                {\n                    if (string.IsNullOrEmpty(filePath))\n                    {\n                        DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION),callbackId);\n                        return;\n                    }\n\n                    using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())\n                    {\n                        if (isoFile.DirectoryExists(filePath))\n                        {\n                            string path = File.AddSlashToDirectory(filePath);\n                            List<FileEntry> entries = new List<FileEntry>();\n                            string[] files = isoFile.GetFileNames(path + \"*\");\n                            string[] dirs = isoFile.GetDirectoryNames(path + \"*\");\n                            foreach (string file in files)\n                            {\n                                entries.Add(FileEntry.GetEntry(path + file));\n                            }\n                            foreach (string dir in dirs)\n                            {\n                                entries.Add(FileEntry.GetEntry(path + dir + \"/\"));\n                            }\n                            DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entries),callbackId);\n                        }\n                        else\n                        {\n                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);\n                        }\n                    }\n                }\n                catch (Exception ex)\n                {\n                    if (!this.HandleException(ex))\n                    {\n                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR),callbackId);\n                    }\n                }\n            }\n        }\n\n        public void requestFileSystem(string options)\n        {\n            // TODO: try/catch\n            string[] optVals = getOptionStrings(options);\n            //FileOptions fileOptions = new FileOptions();\n            int fileSystemType = int.Parse(optVals[0]);\n            double size = double.Parse(optVals[1]);\n            string callbackId = optVals[2];\n\n\n            IsolatedStorageFile.GetUserStoreForApplication();\n\n            if (size > (10 * 1024 * 1024)) // 10 MB, compier will clean this up!\n            {\n                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, QUOTA_EXCEEDED_ERR), callbackId);\n                return;\n            }\n\n            try\n            {\n                if (size != 0)\n                {\n                    using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())\n                    {\n                        long availableSize = isoFile.AvailableFreeSpace;\n                        if (size > availableSize)\n                        {\n                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, QUOTA_EXCEEDED_ERR), callbackId);\n                            return;\n                        }\n                    }\n                }\n\n                if (fileSystemType == PERSISTENT)\n                {\n                    // TODO: this should be in it's own folder to prevent overwriting of the app assets, which are also in ISO\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo(\"persistent\", FileEntry.GetEntry(\"/\"))), callbackId);\n                }\n                else if (fileSystemType == TEMPORARY)\n                {\n                    using (IsolatedStorageFile isoStorage = IsolatedStorageFile.GetUserStoreForApplication())\n                    {\n                        if (!isoStorage.FileExists(TMP_DIRECTORY_NAME))\n                        {\n                            isoStorage.CreateDirectory(TMP_DIRECTORY_NAME);\n                        }\n                    }\n\n                    string tmpFolder = \"/\" + TMP_DIRECTORY_NAME + \"/\";\n\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo(\"temporary\", FileEntry.GetEntry(tmpFolder))), callbackId);\n                }\n                else if (fileSystemType == RESOURCE)\n                {\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo(\"resource\")), callbackId);\n                }\n                else if (fileSystemType == APPLICATION)\n                {\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo(\"application\")), callbackId);\n                }\n                else\n                {\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);\n                }\n\n            }\n            catch (Exception ex)\n            {\n                if (!this.HandleException(ex))\n                {\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);\n                }\n            }\n        }\n\n        public void resolveLocalFileSystemURI(string options)\n        {\n\n            string[] optVals = getOptionStrings(options);\n            string uri = optVals[0].Split('?')[0];\n            string callbackId = optVals[1];\n\n            if (uri != null)\n            {\n                // a single '/' is valid, however, '/someDir' is not, but '/tmp//somedir' and '///someDir' are valid\n                if (uri.StartsWith(\"/\") && uri.IndexOf(\"//\") < 0 && uri != \"/\")\n                {\n                     DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);\n                     return;\n                }\n                try\n                {\n                    // fix encoded spaces\n                    string path = Uri.UnescapeDataString(uri);\n\n                    FileEntry uriEntry = FileEntry.GetEntry(path);\n                    if (uriEntry != null)\n                    {\n                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK, uriEntry), callbackId);\n                    }\n                    else\n                    {\n                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);\n                    }\n                }\n                catch (Exception ex)\n                {\n                    if (!this.HandleException(ex, callbackId))\n                    {\n                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);\n                    }\n                }\n            }\n        }\n\n        public void copyTo(string options)\n        {\n            TransferTo(options, false);\n        }\n\n        public void moveTo(string options)\n        {\n            TransferTo(options, true);\n        }\n\n        public void getFile(string options)\n        {\n            GetFileOrDirectory(options, false);\n        }\n\n        public void getDirectory(string options)\n        {\n            GetFileOrDirectory(options, true);\n        }\n\n        #region internal functionality\n\n        /// <summary>\n        /// Retrieves the parent directory name of the specified path,\n        /// </summary>\n        /// <param name=\"path\">Path</param>\n        /// <returns>Parent directory name</returns>\n        private string GetParentDirectory(string path)\n        {\n            if (String.IsNullOrEmpty(path) || path == \"/\")\n            {\n                return \"/\";\n            }\n\n            if (path.EndsWith(@\"/\") || path.EndsWith(@\"\\\"))\n            {\n                return this.GetParentDirectory(Path.GetDirectoryName(path));\n            }\n\n            string result = Path.GetDirectoryName(path);\n            if (result == null)\n            {\n                result = \"/\";\n            }\n\n            return result;\n        }\n\n        private bool removeDirRecursively(string fullPath,string callbackId)\n        {\n            try\n            {\n                if (fullPath == \"/\")\n                {\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR),callbackId);\n                    return false;\n                }\n\n                using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())\n                {\n                    if (isoFile.DirectoryExists(fullPath))\n                    {\n                        string tempPath = File.AddSlashToDirectory(fullPath);\n                        string[] files = isoFile.GetFileNames(tempPath + \"*\");\n                        if (files.Length > 0)\n                        {\n                            foreach (string file in files)\n                            {\n                                isoFile.DeleteFile(tempPath + file);\n                            }\n                        }\n                        string[] dirs = isoFile.GetDirectoryNames(tempPath + \"*\");\n                        if (dirs.Length > 0)\n                        {\n                            foreach (string dir in dirs)\n                            {\n                                if (!removeDirRecursively(tempPath + dir, callbackId))\n                                {\n                                    return false;\n                                }\n                            }\n                        }\n                        isoFile.DeleteDirectory(fullPath);\n                    }\n                    else\n                    {\n                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);\n                    }\n                }\n            }\n            catch (Exception ex)\n            {\n                if (!this.HandleException(ex))\n                {\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR),callbackId);\n                    return false;\n                }\n            }\n            return true;\n        }\n\n        private bool CanonicalCompare(string pathA, string pathB)\n        {\n            string a = pathA.Replace(\"//\", \"/\");\n            string b = pathB.Replace(\"//\", \"/\");\n\n            return a.Equals(b, StringComparison.OrdinalIgnoreCase);\n        }\n\n        /*\n         *  copyTo:[\"fullPath\",\"parent\", \"newName\"],\n         *  moveTo:[\"fullPath\",\"parent\", \"newName\"],\n         */\n        private void TransferTo(string options, bool move)\n        {\n            // TODO: try/catch\n            string[] optStrings = getOptionStrings(options);\n            string fullPath = optStrings[0];\n            string parent = optStrings[1];\n            string newFileName = optStrings[2];\n            string callbackId = optStrings[3];\n\n            char[] invalids = Path.GetInvalidPathChars();\n            \n            if (newFileName.IndexOfAny(invalids) > -1 || newFileName.IndexOf(\":\") > -1 )\n            {\n                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);\n                return;\n            }\n\n            try\n            {\n                if ((parent == null) || (string.IsNullOrEmpty(parent)) || (string.IsNullOrEmpty(fullPath)))\n                {\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);\n                    return;\n                }\n\n                string parentPath = File.AddSlashToDirectory(parent);\n                string currentPath = fullPath;\n\n                using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())\n                {\n                    bool isFileExist = isoFile.FileExists(currentPath);\n                    bool isDirectoryExist = isoFile.DirectoryExists(currentPath);\n                    bool isParentExist = isoFile.DirectoryExists(parentPath);\n\n                    if ( ( !isFileExist && !isDirectoryExist ) || !isParentExist )\n                    {\n                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);\n                        return;\n                    }\n                    string newName;\n                    string newPath;\n                    if (isFileExist)\n                    {\n                        newName = (string.IsNullOrEmpty(newFileName))\n                                    ? Path.GetFileName(currentPath)\n                                    : newFileName;\n\n                        newPath = Path.Combine(parentPath, newName);\n                        \n                        // sanity check ..\n                        // cannot copy file onto itself\n                        if (CanonicalCompare(newPath,currentPath)) //(parent + newFileName))\n                        {\n                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, INVALID_MODIFICATION_ERR), callbackId);\n                            return;\n                        }\n                        else if (isoFile.DirectoryExists(newPath)) \n                        {\n                            // there is already a folder with the same name, operation is not allowed\n                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, INVALID_MODIFICATION_ERR), callbackId);\n                            return;\n                        }\n                        else if (isoFile.FileExists(newPath))\n                        {   // remove destination file if exists, in other case there will be exception\n                            isoFile.DeleteFile(newPath);\n                        }\n\n                        if (move)\n                        {\n                            isoFile.MoveFile(currentPath, newPath);\n                        }\n                        else\n                        {\n                            isoFile.CopyFile(currentPath, newPath, true);\n                        }\n                    }\n                    else\n                    {\n                        newName = (string.IsNullOrEmpty(newFileName))\n                                    ? currentPath\n                                    : newFileName;\n\n                        newPath = Path.Combine(parentPath, newName);\n\n                        if (move)\n                        {\n                            // remove destination directory if exists, in other case there will be exception\n                            // target directory should be empty\n                            if (!newPath.Equals(currentPath) && isoFile.DirectoryExists(newPath))\n                            {\n                                isoFile.DeleteDirectory(newPath);\n                            }\n\n                            isoFile.MoveDirectory(currentPath, newPath);\n                        }\n                        else\n                        {\n                            CopyDirectory(currentPath, newPath, isoFile);\n                        }\n                    }\n                    FileEntry entry = FileEntry.GetEntry(newPath);\n                    if (entry != null)\n                    {\n                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry), callbackId);\n                    }\n                    else\n                    {\n                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);\n                    }\n                }\n\n            }\n            catch (Exception ex)\n            {\n                if (!this.HandleException(ex, callbackId))\n                {\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);\n                }\n            }\n        }\n\n        private bool HandleException(Exception ex, string cbId=\"\")\n        {\n            bool handled = false;\n            string callbackId = String.IsNullOrEmpty(cbId) ? this.CurrentCommandCallbackId : cbId;\n            if (ex is SecurityException)\n            {\n                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, SECURITY_ERR), callbackId);\n                handled = true;\n            }\n            else if (ex is FileNotFoundException)\n            {\n                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);\n                handled = true;\n            }\n            else if (ex is ArgumentException)\n            {\n                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);\n                handled = true;\n            }\n            else if (ex is IsolatedStorageException)\n            {\n                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, INVALID_MODIFICATION_ERR), callbackId);\n                handled = true;\n            }\n            else if (ex is DirectoryNotFoundException)\n            {\n                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);\n                handled = true;\n            }\n            return handled;\n        }\n\n        private void CopyDirectory(string sourceDir, string destDir, IsolatedStorageFile isoFile)\n        {\n            string path = File.AddSlashToDirectory(sourceDir);\n\n            bool bExists = isoFile.DirectoryExists(destDir);\n\n            if (!bExists)\n            {\n                isoFile.CreateDirectory(destDir);\n            }\n\n            destDir = File.AddSlashToDirectory(destDir);\n               \n            string[] files = isoFile.GetFileNames(path + \"*\");\n                \n            if (files.Length > 0)\n            {\n                foreach (string file in files)\n                {\n                    isoFile.CopyFile(path + file, destDir + file,true);\n                }\n            }\n            string[] dirs = isoFile.GetDirectoryNames(path + \"*\");\n            if (dirs.Length > 0)\n            {\n                foreach (string dir in dirs)\n                {\n                    CopyDirectory(path + dir, destDir + dir, isoFile);\n                }\n            }\n        }\n\n        private string RemoveExtraSlash(string path) {\n            if (path.StartsWith(\"//\")) {\n                path = path.Remove(0, 1);\n                path = RemoveExtraSlash(path);\n            }\n            return path;\n        }\n\n        private string ResolvePath(string parentPath, string path)\n        {   \n            string absolutePath = null;\n            \n            if (path.Contains(\"..\"))\n            {\n                if (parentPath.Length > 1 && parentPath.StartsWith(\"/\") && parentPath !=\"/\")\n                {\n                    parentPath = RemoveExtraSlash(parentPath);\n                }\n                \n                string fullPath = Path.GetFullPath(Path.Combine(parentPath, path));\n                absolutePath = fullPath.Replace(Path.GetPathRoot(fullPath), @\"//\");\n            }\n            else\n            {\n                absolutePath = Path.Combine(parentPath + \"/\", path);\n            }\n            return absolutePath;\n        }\n\n        private void GetFileOrDirectory(string options, bool getDirectory)\n        {\n            FileOptions fOptions = new FileOptions();\n            string[] args = getOptionStrings(options);\n\n            fOptions.FullPath = args[0];\n            fOptions.Path = args[1];\n\n            string callbackId = args[3];\n\n            try\n            {\n                fOptions.CreatingOpt = JSON.JsonHelper.Deserialize<CreatingOptions>(args[2]);\n            }\n            catch (Exception)\n            {\n                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);\n                return;\n            }\n\n            try\n            {\n                if ((string.IsNullOrEmpty(fOptions.Path)) || (string.IsNullOrEmpty(fOptions.FullPath)))\n                {\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);\n                    return;\n                }\n\n                string path;\n\n                if (fOptions.Path.Split(':').Length > 2)\n                {\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);\n                    return;\n                }\n\n                try\n                {\n                    path = ResolvePath(fOptions.FullPath, fOptions.Path);\n                }\n                catch (Exception)\n                {\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);\n                    return;\n                }\n\n                using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())\n                {\n                    bool isFile = isoFile.FileExists(path);\n                    bool isDirectory = isoFile.DirectoryExists(path);\n                    bool create = (fOptions.CreatingOpt == null) ? false : fOptions.CreatingOpt.Create;\n                    bool exclusive = (fOptions.CreatingOpt == null) ? false : fOptions.CreatingOpt.Exclusive;\n                    if (create)\n                    {\n                        if (exclusive && (isoFile.FileExists(path) || isoFile.DirectoryExists(path)))\n                        {\n                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, PATH_EXISTS_ERR), callbackId);\n                            return;\n                        }\n\n                        // need to make sure the parent exists\n                        // it is an error to create a directory whose immediate parent does not yet exist\n                        // see issue: https://issues.apache.org/jira/browse/CB-339\n                        string[] pathParts = path.Split('/');\n                        string builtPath = pathParts[0];\n                        for (int n = 1; n < pathParts.Length - 1; n++)\n                        {\n                            builtPath += \"/\" + pathParts[n];\n                            if (!isoFile.DirectoryExists(builtPath))\n                            {\n                                Debug.WriteLine(String.Format(\"Error :: Parent folder \\\"{0}\\\" does not exist, when attempting to create \\\"{1}\\\"\",builtPath,path));\n                                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);\n                                return;\n                            }\n                        }\n\n                        if ((getDirectory) && (!isDirectory))\n                        {\n                            isoFile.CreateDirectory(path);\n                        }\n                        else\n                        {\n                            if ((!getDirectory) && (!isFile))\n                            {\n\n                                IsolatedStorageFileStream fileStream = isoFile.CreateFile(path);\n                                fileStream.Close();\n                            }\n                        }\n                    }\n                    else // (not create)\n                    {\n                        if ((!isFile) && (!isDirectory))\n                        {\n                            if (path.IndexOf(\"//www\") == 0)\n                            {\n                                Uri fileUri = new Uri(path.Remove(0,2), UriKind.Relative);\n                                StreamResourceInfo streamInfo = Application.GetResourceStream(fileUri);\n                                if (streamInfo != null)\n                                {\n                                    FileEntry _entry = FileEntry.GetEntry(fileUri.OriginalString,true);\n\n                                    DispatchCommandResult(new PluginResult(PluginResult.Status.OK, _entry), callbackId);\n\n                                    //using (BinaryReader br = new BinaryReader(streamInfo.Stream))\n                                    //{\n                                    //    byte[] data = br.ReadBytes((int)streamInfo.Stream.Length);\n                                   \n                                    //}\n\n                                }\n                                else\n                                {\n                                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);\n                                }\n\n\n                            }\n                            else\n                            {\n                                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);\n                            }\n                            return;\n                        }\n                        if (((getDirectory) && (!isDirectory)) || ((!getDirectory) && (!isFile)))\n                        {\n                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, TYPE_MISMATCH_ERR), callbackId);\n                            return;\n                        }\n                    }\n                    FileEntry entry = FileEntry.GetEntry(path);\n                    if (entry != null)\n                    {\n                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry), callbackId);\n                    }\n                    else\n                    {\n                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);\n                    }\n                }\n            }\n            catch (Exception ex)\n            {\n                if (!this.HandleException(ex))\n                {\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);\n                }\n            }\n        }\n\n        private static string AddSlashToDirectory(string dirPath)\n        {\n            if (dirPath.EndsWith(\"/\"))\n            {\n                return dirPath;\n            }\n            else\n            {\n                return dirPath + \"/\";\n            }\n        }\n\n        /// <summary>\n        /// Returns file content in a form of base64 string\n        /// </summary>\n        /// <param name=\"stream\">File stream</param>\n        /// <returns>Base64 representation of the file</returns>\n        private string GetFileContent(Stream stream)\n        {\n            int streamLength = (int)stream.Length;\n            byte[] fileData = new byte[streamLength + 1];\n            stream.Read(fileData, 0, streamLength);\n            stream.Close();\n            return Convert.ToBase64String(fileData);\n        }\n\n        #endregion\n\n    }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-file/tests/plugin.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  Licensed to the Apache Software Foundation (ASF) under one\n  or more contributor license agreements.  See the NOTICE file\n  distributed with this work for additional information\n  regarding copyright ownership.  The ASF licenses this file\n  to you under the Apache License, Version 2.0 (the\n  \"License\"); you may not use this file except in compliance\n  with the License.  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing,\n  software distributed under the License is distributed on an\n  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n  KIND, either express or implied.  See the License for the\n  specific language governing permissions and limitations\n  under the License.\n-->\n\n<plugin xmlns=\"http://apache.org/cordova/ns/plugins/1.0\"\n    xmlns:rim=\"http://www.blackberry.com/ns/widgets\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    id=\"cordova-plugin-file-tests\"\n    version=\"4.2.0\">\n\n    <name>Cordova File Plugin Tests</name>\n    <license>Apache 2.0</license>\n\n    <js-module src=\"tests.js\" name=\"tests\">\n    </js-module>\n\n    <platform name=\"android\">\n        <source-file src=\"src/android/TestContentProvider.java\" target-dir=\"src/org/apache/cordova/file/test\" />\n        <config-file target=\"AndroidManifest.xml\" parent=\"/*/application\">\n            <provider\n                android:name=\"org.apache.cordova.file.test.TestContentProvider\"\n                android:authorities=\"org.apache.cordova.file.testprovider\"\n                android:exported=\"false\" />\n        </config-file>\n        <asset src=\"www/fixtures/asset-test\" target=\"fixtures/asset-test\" />\n    </platform>\n</plugin>\n"
  },
  {
    "path": "plugins/cordova-plugin-file/tests/src/android/TestContentProvider.java",
    "content": "/*\n       Licensed to the Apache Software Foundation (ASF) under one\n       or more contributor license agreements.  See the NOTICE file\n       distributed with this work for additional information\n       regarding copyright ownership.  The ASF licenses this file\n       to you under the Apache License, Version 2.0 (the\n       \"License\"); you may not use this file except in compliance\n       with the License.  You may obtain a copy of the License at\n\n         http://www.apache.org/licenses/LICENSE-2.0\n\n       Unless required by applicable law or agreed to in writing,\n       software distributed under the License is distributed on an\n       \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n       KIND, either express or implied.  See the License for the\n       specific language governing permissions and limitations\n       under the License.\n */\npackage org.apache.cordova.file.test;\n\nimport android.content.ContentProvider;\nimport android.net.Uri;\nimport android.content.res.AssetFileDescriptor;\nimport android.content.res.AssetManager;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileNotFoundException;\nimport android.content.ContentValues;\nimport android.database.Cursor;\nimport android.os.ParcelFileDescriptor;\n\nimport org.apache.cordova.CordovaResourceApi;\n\nimport java.io.IOException;\nimport java.util.HashMap;\n\npublic class TestContentProvider extends ContentProvider {\n\n    @Override\n    public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {\n        String fileName = uri.getQueryParameter(\"realPath\");\n        if (fileName == null) {\n            fileName = uri.getPath();\n        }\n        if (fileName == null || fileName.length() < 1) {\n            throw new FileNotFoundException();\n        }\n        CordovaResourceApi resourceApi = new CordovaResourceApi(getContext(), null);\n        try {\n            File f = File.createTempFile(\"test-content-provider\", \".tmp\");\n            resourceApi.copyResource(Uri.parse(\"file:///android_asset\" + fileName), Uri.fromFile(f));\n            FileInputStream fis = new FileInputStream(f);\n            String thisIsDumb = fis.getFD().toString();\n            int fd = Integer.parseInt(thisIsDumb.substring(\"FileDescriptor[\".length(), thisIsDumb.length() - 1));\n            return ParcelFileDescriptor.adoptFd(fd);\n        } catch (FileNotFoundException e) {\n            throw e;\n        } catch (IOException e) {\n            e.printStackTrace();\n            throw new FileNotFoundException(\"IO error: \" + e.toString());\n        }\n    }\n\n    @Override\n    public boolean onCreate() {\n        return false;\n    }\n\n    @Override\n    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public String getType(Uri uri) {\n        return \"text/html\";\n    }\n\n    @Override\n    public Uri insert(Uri uri, ContentValues values) {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public int delete(Uri uri, String selection, String[] selectionArgs) {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {\n        throw new UnsupportedOperationException();\n    }\n\n\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-file/tests/tests.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements. See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership. The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied. See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n */\n\n/* jshint jasmine: true */\n/* global WebKitBlobBuilder */\n\nexports.defineAutoTests = function () {\n    var isBrowser = (cordova.platformId === \"browser\");\n    // Use feature detection to determine current browser instead of checking user-agent\n    var isChrome = isBrowser && window.webkitRequestFileSystem && window.webkitResolveLocalFileSystemURL;\n    var isIE = isBrowser && (window.msIndexedDB);\n    var isIndexedDBShim = isBrowser && !isChrome;   // Firefox and IE for example\n\n    var isWindows = (cordova.platformId === \"windows\" || cordova.platformId === \"windows8\");\n\n    var MEDIUM_TIMEOUT = 15000;\n\n    describe('File API', function () {\n        // Adding a Jasmine helper matcher, to report errors when comparing to FileError better.\n        var fileErrorMap = {\n            1 : 'NOT_FOUND_ERR',\n            2 : 'SECURITY_ERR',\n            3 : 'ABORT_ERR',\n            4 : 'NOT_READABLE_ERR',\n            5 : 'ENCODING_ERR',\n            6 : 'NO_MODIFICATION_ALLOWED_ERR',\n            7 : 'INVALID_STATE_ERR',\n            8 : 'SYNTAX_ERR',\n            9 : 'INVALID_MODIFICATION_ERR',\n            10 : 'QUOTA_EXCEEDED_ERR',\n            11 : 'TYPE_MISMATCH_ERR',\n            12 : 'PATH_EXISTS_ERR'\n        },\n        root,\n        temp_root,\n        persistent_root;\n        beforeEach(function (done) {\n            // Custom Matchers\n            jasmine.Expectation.addMatchers({\n                toBeFileError : function () {\n                    return {\n                        compare : function (error, code) {\n                            var pass = error.code === code;\n                            return {\n                                pass : pass,\n                                message : 'Expected FileError with code ' + fileErrorMap[error.code] + ' (' + error.code + ') to be ' + fileErrorMap[code] + '(' + code + ')'\n                            };\n                        }\n                    };\n                },\n                toCanonicallyMatch : function () {\n                    return {\n                        compare : function (currentPath, path) {\n                            var a = path.split(\"/\").join(\"\").split(\"\\\\\").join(\"\"),\n                            b = currentPath.split(\"/\").join(\"\").split(\"\\\\\").join(\"\"),\n                            pass = a === b;\n                            return {\n                                pass : pass,\n                                message : 'Expected paths to match : ' + path + ' should be ' + currentPath\n                            };\n                        }\n                    };\n                },\n                toFailWithMessage : function () {\n                    return {\n                        compare : function (error, message) {\n                            var pass = false;\n                            return {\n                                pass : pass,\n                                message : message\n                            };\n                        }\n                    };\n                },\n                toBeDataUrl: function () {\n                    return {\n                        compare : function (url) {\n                            var pass = false;\n                            // \"data:application/octet-stream;base64,\"\n                            var header = url.substr(0, url.indexOf(','));\n                            var headerParts = header.split(/[:;]/);\n                            if (headerParts.length === 3 &&\n                                headerParts[0] === 'data' &&\n                                headerParts[2] === 'base64') {\n                                pass = true;\n                            }\n                            var message = 'Expected ' + url + ' to be a valid data url. ' + header + ' is not valid header for data uris';\n                            return {\n                                pass : pass,\n                                message : message\n                            };\n                        }\n                    };\n                }\n            });\n            //Define global variables\n            var onError = function (e) {\n                console.log('[ERROR] Problem setting up root filesystem for test running! Error to follow.');\n                console.log(JSON.stringify(e));\n            };\n            window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function (fileSystem) {\n                root = fileSystem.root;\n                // set in file.tests.js\n                persistent_root = root;\n                window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, function (fileSystem) {\n                    temp_root = fileSystem.root;\n                    // set in file.tests.js\n                    done();\n                }, onError);\n            }, onError);\n        });\n        // HELPER FUNCTIONS\n        // deletes specified file or directory\n        var deleteEntry = function (name, success, error) {\n            // deletes entry, if it exists\n            // entry.remove success callback is required: http://www.w3.org/TR/2011/WD-file-system-api-20110419/#the-entry-interface\n            success = success || function() {};\n            error = error || failed.bind(null, success, 'deleteEntry failed.');\n\n            window.resolveLocalFileSystemURL(root.toURL() + '/' + name, function (entry) {\n                if (entry.isDirectory === true) {\n                    entry.removeRecursively(success, error);\n                } else {\n                    entry.remove(success, error);\n                }\n            }, success);\n        };\n        // deletes file, if it exists, then invokes callback\n        var deleteFile = function (fileName, callback) {\n            // entry.remove success callback is required: http://www.w3.org/TR/2011/WD-file-system-api-20110419/#the-entry-interface\n            callback = callback || function() {};\n\n            root.getFile(fileName, null, // remove file system entry\n                function (entry) {\n                entry.remove(callback, function () {\n                    console.log('[ERROR] deleteFile cleanup method invoked fail callback.');\n                });\n            }, // doesn't exist\n                callback);\n        };\n        // deletes and re-creates the specified file\n        var createFile = function (fileName, success, error) {\n            deleteEntry(fileName, function () {\n                root.getFile(fileName, {\n                    create : true\n                }, success, error);\n            }, error);\n        };\n        // deletes and re-creates the specified directory\n        var createDirectory = function (dirName, success, error) {\n            deleteEntry(dirName, function () {\n                root.getDirectory(dirName, {\n                    create : true\n                }, success, error);\n            }, error);\n        };\n        function failed(done, msg, error) {\n            var info = typeof msg == 'undefined' ? 'Unexpected error callback' : msg;\n            var codeMsg = (error && error.code) ? (': ' + fileErrorMap[error.code]) : '';\n            expect(true).toFailWithMessage(info + '\\n' + JSON.stringify(error) + codeMsg);\n            done();\n        }\n        var succeed = function (done, msg) {\n            var info = typeof msg == 'undefined' ? 'Unexpected success callback' : msg;\n            expect(true).toFailWithMessage(info);\n            done();\n        };\n        var joinURL = function (base, extension) {\n            if (base.charAt(base.length - 1) !== '/' && extension.charAt(0) !== '/') {\n                return base + '/' + extension;\n            }\n            if (base.charAt(base.length - 1) === '/' && extension.charAt(0) === '/') {\n                return base + extension.substring(1);\n            }\n            return base + extension;\n        };\n        describe('FileError object', function () {\n            it(\"file.spec.1 should define FileError constants\", function () {\n                expect(FileError.NOT_FOUND_ERR).toBe(1);\n                expect(FileError.SECURITY_ERR).toBe(2);\n                expect(FileError.ABORT_ERR).toBe(3);\n                expect(FileError.NOT_READABLE_ERR).toBe(4);\n                expect(FileError.ENCODING_ERR).toBe(5);\n                expect(FileError.NO_MODIFICATION_ALLOWED_ERR).toBe(6);\n                expect(FileError.INVALID_STATE_ERR).toBe(7);\n                expect(FileError.SYNTAX_ERR).toBe(8);\n                expect(FileError.INVALID_MODIFICATION_ERR).toBe(9);\n                expect(FileError.QUOTA_EXCEEDED_ERR).toBe(10);\n                expect(FileError.TYPE_MISMATCH_ERR).toBe(11);\n                expect(FileError.PATH_EXISTS_ERR).toBe(12);\n            });\n        });\n        describe('LocalFileSystem', function () {\n            it(\"file.spec.2 should define LocalFileSystem constants\", function () {\n                expect(LocalFileSystem.TEMPORARY).toBe(0);\n                expect(LocalFileSystem.PERSISTENT).toBe(1);\n            });\n            describe('window.requestFileSystem', function () {\n                it(\"file.spec.3 should be defined\", function () {\n                    expect(window.requestFileSystem).toBeDefined();\n                });\n                it(\"file.spec.4 should be able to retrieve a PERSISTENT file system\", function (done) {\n                    var win = function (fileSystem) {\n                        expect(fileSystem).toBeDefined();\n                        expect(fileSystem.name).toBeDefined();\n                        if (isChrome) {\n                            expect(fileSystem.name).toContain(\"Persistent\");\n                        } else {\n                            expect(fileSystem.name).toBe(\"persistent\");\n                        }\n                        expect(fileSystem.root).toBeDefined();\n                        expect(fileSystem.root.filesystem).toBeDefined();\n                        // Shouldn't use cdvfile by default.\n                        expect(fileSystem.root.toURL()).not.toMatch(/^cdvfile:/);\n                        // All DirectoryEntry URLs should always have a trailing slash.\n                        expect(fileSystem.root.toURL()).toMatch(/\\/$/);\n                        done();\n                    };\n\n                    // Request a little bit of space on the filesystem, unless we're running in a browser where that could cause a prompt.\n                    var spaceRequired = isBrowser ? 0 : 1024;\n\n                    // retrieve PERSISTENT file system\n                    window.requestFileSystem(LocalFileSystem.PERSISTENT, spaceRequired, win, failed.bind(null, done, 'window.requestFileSystem - Error retrieving PERSISTENT file system'));\n                });\n                it(\"file.spec.5 should be able to retrieve a TEMPORARY file system\", function (done) {\n                    var win = function (fileSystem) {\n                        expect(fileSystem).toBeDefined();\n                        if (isChrome) {\n                            expect(fileSystem.name).toContain(\"Temporary\");\n                        } else {\n                            expect(fileSystem.name).toBe(\"temporary\");\n                        }\n                        expect(fileSystem.root).toBeDefined();\n                        expect(fileSystem.root.filesystem).toBeDefined();\n                        expect(fileSystem.root.filesystem).toBe(fileSystem);\n                        done();\n                    };\n                    //retrieve TEMPORARY file system\n                    window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, win, failed.bind(null, done, 'window.requestFileSystem - Error retrieving TEMPORARY file system'));\n                });\n                it(\"file.spec.6 should error if you request a file system that is too large\", function (done) {\n                    if (isBrowser) {\n                        /*window.requestFileSystem TEMPORARY and PERSISTENT filesystem quota is not limited in Chrome.\n                        Firefox filesystem size is not limited but every 50MB request user permission.\n                        IE10 allows up to 10mb of combined AppCache and IndexedDB used in implementation\n                        of filesystem without prompting, once you hit that level you will be asked if you\n                        want to allow it to be increased up to a max of 250mb per site.\n                        So `size` parameter for `requestFileSystem` function does not affect on filesystem in Firefox and IE.*/\n                        pending();\n                    }\n\n                    var fail = function (error) {\n                        expect(error).toBeDefined();\n                        expect(error).toBeFileError(FileError.QUOTA_EXCEEDED_ERR);\n                        done();\n                    };\n                    //win = createWin('window.requestFileSystem');\n                    // Request the file system\n                    window.requestFileSystem(LocalFileSystem.TEMPORARY, 1000000000000000, failed.bind(null, done, 'window.requestFileSystem - Error retrieving TEMPORARY file system'), fail);\n                });\n                it(\"file.spec.7 should error out if you request a file system that does not exist\", function (done) {\n\n                    var fail = function (error) {\n                        expect(error).toBeDefined();\n                        if (isChrome) {\n                            /*INVALID_MODIFICATION_ERR (code: 9) is thrown instead of SYNTAX_ERR(code: 8)\n                            on requesting of a non-existant filesystem.*/\n                            expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR);\n                        } else {\n                            expect(error).toBeFileError(FileError.SYNTAX_ERR);\n                        }\n                        done();\n                    };\n                    // Request the file system\n                    window.requestFileSystem(-1, 0, succeed.bind(null, done, 'window.requestFileSystem'), fail);\n                });\n            });\n            describe('window.resolveLocalFileSystemURL', function () {\n                it(\"file.spec.8 should be defined\", function () {\n                    expect(window.resolveLocalFileSystemURL).toBeDefined();\n                });\n                it(\"file.spec.9 should resolve a valid file name\", function (done) {\n                    var fileName = 'file.spec.9';\n                    var win = function (fileEntry) {\n                        expect(fileEntry).toBeDefined();\n                        expect(fileEntry.isFile).toBe(true);\n                        expect(fileEntry.isDirectory).toBe(false);\n                        expect(fileEntry.name).toCanonicallyMatch(fileName);\n                        expect(fileEntry.toURL()).not.toMatch(/^cdvfile:/, 'should not use cdvfile URL');\n                        expect(fileEntry.toURL()).not.toMatch(/\\/$/, 'URL should not end with a slash');\n                        // Clean-up\n                        deleteEntry(fileName, done);\n                    };\n                    createFile(fileName, function (entry) {\n                        window.resolveLocalFileSystemURL(entry.toURL(), win, failed.bind(null, done, 'window.resolveLocalFileSystemURL - Error resolving file URL: ' + entry.toURL()));\n                    }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName), failed.bind(null, done, 'createFile - Error creating file: ' + fileName));\n                });\n                it(\"file.spec.9.1 should resolve a file even with a terminating slash\", function (done) {\n                    var fileName = 'file.spec.9.1';\n                    var win = function (fileEntry) {\n                        expect(fileEntry).toBeDefined();\n                        expect(fileEntry.isFile).toBe(true);\n                        expect(fileEntry.isDirectory).toBe(false);\n                        expect(fileEntry.name).toCanonicallyMatch(fileName);\n                        expect(fileEntry.toURL()).not.toMatch(/^cdvfile:/, 'should not use cdvfile URL');\n                        expect(fileEntry.toURL()).not.toMatch(/\\/$/, 'URL should not end with a slash');\n                        // Clean-up\n                        deleteEntry(fileName, done);\n                    };\n                    createFile(fileName, function (entry) {\n                        var entryURL = entry.toURL() + '/';\n                        window.resolveLocalFileSystemURL(entryURL, win, failed.bind(null, done, 'window.resolveLocalFileSystemURL - Error resolving file URL: ' + entryURL));\n                    }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName), failed.bind(null, done, 'createFile - Error creating file: ' + fileName));\n                });\n                it(\"file.spec.9.5 should resolve a directory\", function (done) {\n                    var fileName = 'file.spec.9.5';\n                    var win = function (fileEntry) {\n                        expect(fileEntry).toBeDefined();\n                        expect(fileEntry.isFile).toBe(false);\n                        expect(fileEntry.isDirectory).toBe(true);\n                        expect(fileEntry.name).toCanonicallyMatch(fileName);\n                        expect(fileEntry.toURL()).not.toMatch(/^cdvfile:/, 'should not use cdvfile URL');\n                        expect(fileEntry.toURL()).toMatch(/\\/$/, 'URL end with a slash');\n                        // cleanup\n                        deleteEntry(fileName, done);\n                    };\n                    function gotDirectory(entry) {\n                        // lookup file system entry\n                        window.resolveLocalFileSystemURL(entry.toURL(), win, failed.bind(null, done, 'window.resolveLocalFileSystemURL - Error resolving directory URL: ' + entry.toURL()));\n                    }\n                    createDirectory(fileName, gotDirectory, failed.bind(null, done, 'createDirectory - Error creating directory: ' + fileName), failed.bind(null, done, 'createDirectory - Error creating directory: ' + fileName));\n                });\n                it(\"file.spec.9.6 should resolve a directory even without a terminating slash\", function (done) {\n                    var fileName = 'file.spec.9.6';\n                    var win = function (fileEntry) {\n                        expect(fileEntry).toBeDefined();\n                        expect(fileEntry.isFile).toBe(false);\n                        expect(fileEntry.isDirectory).toBe(true);\n                        expect(fileEntry.name).toCanonicallyMatch(fileName);\n                        expect(fileEntry.toURL()).not.toMatch(/^cdvfile:/, 'should not use cdvfile URL');\n                        expect(fileEntry.toURL()).toMatch(/\\/$/, 'URL end with a slash');\n                        // cleanup\n                        deleteEntry(fileName, done);\n                    };\n                    function gotDirectory(entry) {\n                        // lookup file system entry\n                        var entryURL = entry.toURL();\n                        entryURL = entryURL.substring(0, entryURL.length - 1);\n                        window.resolveLocalFileSystemURL(entryURL, win, failed.bind(null, done, 'window.resolveLocalFileSystemURL - Error resolving directory URL: ' + entryURL));\n                    }\n                    createDirectory(fileName, gotDirectory, failed.bind(null, done, 'createDirectory - Error creating directory: ' + fileName), failed.bind(null, done, 'createDirectory - Error creating directory: ' + fileName));\n                });\n                it(\"file.spec.10 resolve valid file name with parameters\", function (done) {\n                    var fileName = \"resolve.file.uri.params\",\n                    win = function (fileEntry) {\n                        expect(fileEntry).toBeDefined();\n                        if (fileEntry.toURL().toLowerCase().substring(0, 10) === \"cdvfile://\") {\n                            expect(fileEntry.fullPath).toBe(\"/\" + fileName + \"?1234567890\");\n                        }\n                        expect(fileEntry.name).toBe(fileName);\n                        // cleanup\n                        deleteEntry(fileName, done);\n                    };\n                    // create a new file entry\n                    createFile(fileName, function (entry) {\n                        window.resolveLocalFileSystemURL(entry.toURL() + \"?1234567890\", win, failed.bind(null, done, 'window.resolveLocalFileSystemURL - Error resolving file URI: ' + entry.toURL()));\n                    }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName));\n                });\n                it(\"file.spec.11 should error (NOT_FOUND_ERR) when resolving (non-existent) invalid file name\", function (done) {\n                    var fileName = cordova.platformId === 'windowsphone' ? root.toURL() + \"/\" + \"this.is.not.a.valid.file.txt\" : joinURL(root.toURL(), \"this.is.not.a.valid.file.txt\"),\n                        fail = function (error) {\n                        expect(error).toBeDefined();\n                        expect(error).toBeFileError(FileError.NOT_FOUND_ERR);\n                        done();\n                    };\n                    // lookup file system entry\n                    window.resolveLocalFileSystemURL(fileName, succeed.bind(null, done, 'window.resolveLocalFileSystemURL - Error unexpected callback resolving file URI: ' + fileName), fail);\n                });\n                it(\"file.spec.12 should error (ENCODING_ERR) when resolving invalid URI with leading /\", function (done) {\n                    var fileName = \"/this.is.not.a.valid.url\",\n                        fail = function (error) {\n                        expect(error).toBeDefined();\n                        expect(error).toBeFileError(FileError.ENCODING_ERR);\n                        done();\n                    };\n                    // lookup file system entry\n                    window.resolveLocalFileSystemURL(fileName, succeed.bind(null, done, 'window.resolveLocalFileSystemURL - Error unexpected callback resolving file URI: ' + fileName), fail);\n                });\n            });\n        });\n        //LocalFileSystem\n        describe('Metadata interface', function () {\n            it(\"file.spec.13 should exist and have the right properties\", function () {\n                var metadata = new Metadata();\n                expect(metadata).toBeDefined();\n                expect(metadata.modificationTime).toBeDefined();\n            });\n        });\n        describe('Flags interface', function () {\n            it(\"file.spec.14 should exist and have the right properties\", function () {\n                var flags = new Flags(false, true);\n                expect(flags).toBeDefined();\n                expect(flags.create).toBeDefined();\n                expect(flags.create).toBe(false);\n                expect(flags.exclusive).toBeDefined();\n                expect(flags.exclusive).toBe(true);\n            });\n        });\n        describe('FileSystem interface', function () {\n            it(\"file.spec.15 should have a root that is a DirectoryEntry\", function (done) {\n                var win = function (entry) {\n                    expect(entry).toBeDefined();\n                    expect(entry.isFile).toBe(false);\n                    expect(entry.isDirectory).toBe(true);\n                    expect(entry.name).toBeDefined();\n                    expect(entry.fullPath).toBeDefined();\n                    expect(entry.getMetadata).toBeDefined();\n                    expect(entry.moveTo).toBeDefined();\n                    expect(entry.copyTo).toBeDefined();\n                    expect(entry.toURL).toBeDefined();\n                    expect(entry.remove).toBeDefined();\n                    expect(entry.getParent).toBeDefined();\n                    expect(entry.createReader).toBeDefined();\n                    expect(entry.getFile).toBeDefined();\n                    expect(entry.getDirectory).toBeDefined();\n                    expect(entry.removeRecursively).toBeDefined();\n                    done();\n                };\n                window.resolveLocalFileSystemURL(root.toURL(), win, failed.bind(null, done, 'window.resolveLocalFileSystemURL - Error resolving file URI: ' + root.toURL()));\n            });\n        });\n        describe('DirectoryEntry', function () {\n            it(\"file.spec.16 getFile: get Entry for file that does not exist\", function (done) {\n                var fileName = \"de.no.file\",\n                fail = function (error) {\n                    expect(error).toBeDefined();\n                    expect(error).toBeFileError(FileError.NOT_FOUND_ERR);\n                    done();\n                };\n                // create:false, exclusive:false, file does not exist\n                root.getFile(fileName, {\n                    create : false\n                }, succeed.bind(null, done, 'root.getFile - Error unexpected callback, file should not exists: ' + fileName), fail);\n            });\n            it(\"file.spec.17 getFile: create new file\", function (done) {\n                var fileName = \"de.create.file\",\n                filePath = joinURL(root.fullPath, fileName),\n                win = function (entry) {\n                    expect(entry).toBeDefined();\n                    expect(entry.isFile).toBe(true);\n                    expect(entry.isDirectory).toBe(false);\n                    expect(entry.name).toCanonicallyMatch(fileName);\n                    expect(entry.fullPath).toCanonicallyMatch(filePath);\n                    // cleanup\n                    deleteEntry(entry.name, done);\n                };\n                // create:true, exclusive:false, file does not exist\n                root.getFile(fileName, {\n                    create : true\n                }, win, succeed.bind(null, done, 'root.getFile - Error unexpected callback, file should not exists: ' + fileName));\n            });\n            it(\"file.spec.18 getFile: create new file (exclusive)\", function (done) {\n                var fileName = \"de.create.exclusive.file\",\n                filePath = joinURL(root.fullPath, fileName),\n                win = function (entry) {\n                    expect(entry).toBeDefined();\n                    expect(entry.isFile).toBe(true);\n                    expect(entry.isDirectory).toBe(false);\n                    expect(entry.name).toBe(fileName);\n                    expect(entry.fullPath).toCanonicallyMatch(filePath);\n                    // cleanup\n                    deleteEntry(entry.name, done);\n                };\n                // create:true, exclusive:true, file does not exist\n                root.getFile(fileName, {\n                    create : true,\n                    exclusive : true\n                }, win, failed.bind(null, done, 'root.getFile - Error creating file: ' + fileName));\n            });\n            it(\"file.spec.19 getFile: create file that already exists\", function (done) {\n                var fileName = \"de.create.existing.file\",\n                filePath = joinURL(root.fullPath, fileName);\n\n                function win(entry) {\n                    expect(entry).toBeDefined();\n                    expect(entry.isFile).toBe(true);\n                    expect(entry.isDirectory).toBe(false);\n                    expect(entry.name).toCanonicallyMatch(fileName);\n                    expect(entry.fullPath).toCanonicallyMatch(filePath);\n                    // cleanup\n                    deleteEntry(entry.name, done);\n                }\n\n                function getFile(file) {\n                    // create:true, exclusive:false, file exists\n                    root.getFile(fileName, {\n                        create : true\n                    }, win, failed.bind(null, done, 'root.getFile - Error creating file: ' + fileName));\n                }\n\n                // create file to kick off it\n                root.getFile(fileName, {\n                    create : true\n                }, getFile, failed.bind(null, done, 'root.getFile - Error on initial creating file: ' + fileName));\n            });\n            it(\"file.spec.20 getFile: create file that already exists (exclusive)\", function (done) {\n                var fileName = \"de.create.exclusive.existing.file\",\n                existingFile;\n\n                function fail(error) {\n                    expect(error).toBeDefined();\n                    if (isChrome) {\n                        /*INVALID_MODIFICATION_ERR (code: 9) is thrown instead of PATH_EXISTS_ERR(code: 12)\n                        on trying to exclusively create a file, which already exists in Chrome.*/\n                        expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR);\n                    } else {\n                        expect(error).toBeFileError(FileError.PATH_EXISTS_ERR);\n                    }\n                    // cleanup\n                    deleteEntry(existingFile.name, done);\n                }\n\n                function getFile(file) {\n                    existingFile = file;\n                    // create:true, exclusive:true, file exists\n                    root.getFile(fileName, {\n                        create : true,\n                        exclusive : true\n                    }, succeed.bind(null, done, 'root.getFile - getFile function - Error unexpected callback, file should exists: ' + fileName), fail);\n                }\n\n                // create file to kick off it\n                root.getFile(fileName, {\n                    create : true\n                }, getFile, failed.bind(null, done, 'root.getFile - Error creating file: ' + fileName));\n            });\n            it(\"file.spec.21 DirectoryEntry.getFile: get Entry for existing file\", function (done) {\n                var fileName = \"de.get.file\",\n                filePath = joinURL(root.fullPath, fileName),\n                win = function (entry) {\n                    expect(entry).toBeDefined();\n                    expect(entry.isFile).toBe(true);\n                    expect(entry.isDirectory).toBe(false);\n                    expect(entry.name).toCanonicallyMatch(fileName);\n                    expect(entry.fullPath).toCanonicallyMatch(filePath);\n                    expect(entry.filesystem).toBeDefined();\n                    expect(entry.filesystem).toBe(root.filesystem);\n                    //clean up\n                    deleteEntry(entry.name, done);\n                },\n                getFile = function (file) {\n                    // create:false, exclusive:false, file exists\n                    root.getFile(fileName, {\n                        create : false\n                    }, win, failed.bind(null, done, 'root.getFile - Error getting file entry: ' + fileName));\n                };\n                // create file to kick off it\n                root.getFile(fileName, {\n                    create : true\n                }, getFile, failed.bind(null, done, 'root.getFile - Error creating file: ' + fileName));\n            });\n            it(\"file.spec.22 DirectoryEntry.getFile: get FileEntry for invalid path\", function (done) {\n                if (isBrowser) {\n                    /*The plugin does not follow to [\"8.3 Naming restrictions\"]\n                    (http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions).*/\n                    pending();\n                }\n\n                var fileName = \"de:invalid:path\",\n                fail = function (error) {\n                    expect(error).toBeDefined();\n                    expect(error).toBeFileError(FileError.ENCODING_ERR);\n                    done();\n                };\n                // create:false, exclusive:false, invalid path\n                root.getFile(fileName, {\n                    create : false\n                }, succeed.bind(null, done, 'root.getFile - Error unexpected callback, file should not exists: ' + fileName), fail);\n            });\n            it(\"file.spec.23 DirectoryEntry.getDirectory: get Entry for directory that does not exist\", function (done) {\n                var dirName = \"de.no.dir\",\n                fail = function (error) {\n                    expect(error).toBeDefined();\n                    expect(error).toBeFileError(FileError.NOT_FOUND_ERR);\n                    done();\n                };\n                // create:false, exclusive:false, directory does not exist\n                root.getDirectory(dirName, {\n                    create : false\n                }, succeed.bind(null, done, 'root.getDirectory - Error unexpected callback, directory should not exists: ' + dirName), fail);\n            });\n            it(\"file.spec.24 DirectoryEntry.getDirectory: create new dir with space then resolveLocalFileSystemURL\", function (done) {\n                var dirName = \"de create dir\";\n\n                function win(directory) {\n                    expect(directory).toBeDefined();\n                    expect(directory.isFile).toBe(false);\n                    expect(directory.isDirectory).toBe(true);\n                    expect(directory.name).toCanonicallyMatch(dirName);\n                    expect(directory.fullPath).toCanonicallyMatch(joinURL(root.fullPath, dirName));\n                    // cleanup\n                    deleteEntry(directory.name, done);\n                }\n\n                function getDir(dirEntry) {\n                    expect(dirEntry.filesystem).toBeDefined();\n                    expect(dirEntry.filesystem).toBe(root.filesystem);\n                    var dirURI = dirEntry.toURL();\n                    // now encode URI and try to resolve\n                    window.resolveLocalFileSystemURL(dirURI, win, failed.bind(null, done, 'window.resolveLocalFileSystemURL - getDir function - Error resolving directory: ' + dirURI));\n                }\n\n                // create:true, exclusive:false, directory does not exist\n                root.getDirectory(dirName, {\n                    create : true\n                }, getDir, failed.bind(null, done, 'root.getDirectory - Error creating directory : ' + dirName));\n            });\n            // This test is excluded, and should probably be removed. Filesystem\n            // should always be properly encoded URLs, and *not* raw paths, and it\n            // doesn't make sense to double-encode the URLs and expect that to be\n            // handled by the implementation.\n            // If a particular platform uses paths internally rather than URLs, // then that platform should careful to pass them correctly to its\n            // backend.\n            xit(\"file.spec.25 DirectoryEntry.getDirectory: create new dir with space resolveLocalFileSystemURL with encoded URI\", function (done) {\n                var dirName = \"de create dir2\",\n                dirPath = joinURL(root.fullPath, dirName);\n\n                function win(directory) {\n                    expect(directory).toBeDefined();\n                    expect(directory.isFile).toBe(false);\n                    expect(directory.isDirectory).toBe(true);\n                    expect(directory.name).toCanonicallyMatch(dirName);\n                    expect(directory.fullPath).toCanonicallyMatch(dirPath);\n                    // cleanup\n                    deleteEntry(directory.name, done);\n                }\n\n                function getDir(dirEntry) {\n                    var dirURI = dirEntry.toURL();\n                    // now encode URI and try to resolve\n                    window.resolveLocalFileSystemURL(encodeURI(dirURI), win, failed.bind(null, done, 'window.resolveLocalFileSystemURL - getDir function - Error resolving directory: ' + dirURI));\n                }\n\n                // create:true, exclusive:false, directory does not exist\n                root.getDirectory(dirName, {\n                    create : true\n                }, getDir, failed.bind(null, done, 'root.getDirectory - Error creating directory : ' + dirName));\n            });\n            it(\"file.spec.26 DirectoryEntry.getDirectory: create new directory\", function (done) {\n                var dirName = \"de.create.dir\",\n                dirPath = joinURL(root.fullPath, dirName),\n                win = function (directory) {\n                    expect(directory).toBeDefined();\n                    expect(directory.isFile).toBe(false);\n                    expect(directory.isDirectory).toBe(true);\n                    expect(directory.name).toCanonicallyMatch(dirName);\n                    expect(directory.fullPath).toCanonicallyMatch(dirPath);\n                    expect(directory.filesystem).toBeDefined();\n                    expect(directory.filesystem).toBe(root.filesystem);\n                    // cleanup\n                    deleteEntry(directory.name, done);\n                };\n                // create:true, exclusive:false, directory does not exist\n                root.getDirectory(dirName, {\n                    create : true\n                }, win, failed.bind(null, done, 'root.getDirectory - Error creating directory : ' + dirName));\n            });\n            it(\"file.spec.27 DirectoryEntry.getDirectory: create new directory (exclusive)\", function (done) {\n                var dirName = \"de.create.exclusive.dir\",\n                dirPath = joinURL(root.fullPath, dirName),\n                win = function (directory) {\n                    expect(directory).toBeDefined();\n                    expect(directory.isFile).toBe(false);\n                    expect(directory.isDirectory).toBe(true);\n                    expect(directory.name).toCanonicallyMatch(dirName);\n                    expect(directory.fullPath).toCanonicallyMatch(dirPath);\n                    expect(directory.filesystem).toBeDefined();\n                    expect(directory.filesystem).toBe(root.filesystem);\n                    // cleanup\n                    deleteEntry(directory.name, done);\n                };\n                // create:true, exclusive:true, directory does not exist\n                root.getDirectory(dirName, {\n                    create : true,\n                    exclusive : true\n                }, win, failed.bind(null, done, 'root.getDirectory - Error creating directory : ' + dirName));\n            });\n            it(\"file.spec.28 DirectoryEntry.getDirectory: create directory that already exists\", function (done) {\n                var dirName = \"de.create.existing.dir\",\n                dirPath = joinURL(root.fullPath, dirName),\n                win = function (directory) {\n                    expect(directory).toBeDefined();\n                    expect(directory.isFile).toBe(false);\n                    expect(directory.isDirectory).toBe(true);\n                    expect(directory.name).toCanonicallyMatch(dirName);\n                    expect(directory.fullPath).toCanonicallyMatch(dirPath);\n                    // cleanup\n                    deleteEntry(directory.name, done);\n                };\n                // create directory to kick off it\n                root.getDirectory(dirName, {\n                    create : true\n                }, function () {\n                    root.getDirectory(dirName, {\n                        create : true\n                    }, win, failed.bind(null, done, 'root.getDirectory - Error creating existent second directory : ' + dirName));\n                }, failed.bind(null, done, 'root.getDirectory - Error creating directory : ' + dirName));\n            });\n            it(\"file.spec.29 DirectoryEntry.getDirectory: create directory that already exists (exclusive)\", function (done) {\n\n                var dirName = \"de.create.exclusive.existing.dir\",\n                existingDir,\n                fail = function (error) {\n                    expect(error).toBeDefined();\n                    if (isChrome) {\n                        /*INVALID_MODIFICATION_ERR (code: 9) is thrown instead of PATH_EXISTS_ERR(code: 12)\n                        on trying to exclusively create a file or directory, which already exists (Chrome).*/\n                        expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR);\n                    } else {\n                        expect(error).toBeFileError(FileError.PATH_EXISTS_ERR);\n                    }\n                    // cleanup\n                    deleteEntry(existingDir.name, done);\n                };\n                // create directory to kick off it\n                root.getDirectory(dirName, {\n                    create : true\n                }, function (directory) {\n                    existingDir = directory;\n                    // create:true, exclusive:true, directory exists\n                    root.getDirectory(dirName, {\n                        create : true,\n                        exclusive : true\n                    }, failed.bind(null, done, 'root.getDirectory - Unexpected success callback, second directory should not be created : ' + dirName), fail);\n                }, failed.bind(null, done, 'root.getDirectory - Error creating directory : ' + dirName));\n            });\n            it(\"file.spec.30 DirectoryEntry.getDirectory: get Entry for existing directory\", function (done) {\n                var dirName = \"de.get.dir\",\n                dirPath = joinURL(root.fullPath, dirName),\n                win = function (directory) {\n                    expect(directory).toBeDefined();\n                    expect(directory.isFile).toBe(false);\n                    expect(directory.isDirectory).toBe(true);\n                    expect(directory.name).toCanonicallyMatch(dirName);\n                    expect(directory.fullPath).toCanonicallyMatch(dirPath);\n                    // cleanup\n                    deleteEntry(directory.name, done);\n                };\n                // create directory to kick it off\n                root.getDirectory(dirName, {\n                    create : true\n                }, function () {\n                    root.getDirectory(dirName, {\n                        create : false\n                    }, win, failed.bind(null, done, 'root.getDirectory - Error getting directory entry : ' + dirName));\n                }, failed.bind(null, done, 'root.getDirectory - Error creating directory : ' + dirName));\n            });\n            it(\"file.spec.31 DirectoryEntry.getDirectory: get DirectoryEntry for invalid path\", function (done) {\n                if (isBrowser) {\n                    /*The plugin does not follow to [\"8.3 Naming restrictions\"]\n                    (http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions).*/\n                    pending();\n                }\n\n                var dirName = \"de:invalid:path\",\n                fail = function (error) {\n                    expect(error).toBeDefined();\n                    expect(error).toBeFileError(FileError.ENCODING_ERR);\n                    done();\n                };\n                // create:false, exclusive:false, invalid path\n                root.getDirectory(dirName, {\n                    create : false\n                }, succeed.bind(null, done, 'root.getDirectory - Unexpected success callback, directory should not exists: ' + dirName), fail);\n            });\n            it(\"file.spec.32 DirectoryEntry.getDirectory: get DirectoryEntry for existing file\", function (done) {\n                var fileName = \"de.existing.file\",\n                existingFile,\n                fail = function (error) {\n                    expect(error).toBeDefined();\n                    expect(error).toBeFileError(FileError.TYPE_MISMATCH_ERR);\n                    // cleanup\n                    deleteEntry(existingFile.name, done);\n                };\n                // create file to kick off it\n                root.getFile(fileName, {\n                    create : true\n                }, function (file) {\n                    existingFile = file;\n                    root.getDirectory(fileName, {\n                        create : false\n                    }, succeed.bind(null, done, 'root.getDirectory - Unexpected success callback, directory should not exists: ' + fileName), fail);\n                }, failed.bind(null, done, 'root.getFile - Error creating file : ' + fileName));\n            });\n            it(\"file.spec.33 DirectoryEntry.getFile: get FileEntry for existing directory\", function (done) {\n                var dirName = \"de.existing.dir\",\n                existingDir,\n                fail = function (error) {\n                    expect(error).toBeDefined();\n                    expect(error).toBeFileError(FileError.TYPE_MISMATCH_ERR);\n                    // cleanup\n                    deleteEntry(existingDir.name, done);\n                };\n                // create directory to kick off it\n                root.getDirectory(dirName, {\n                    create : true\n                }, function (directory) {\n                    existingDir = directory;\n                    root.getFile(dirName, {\n                        create : false\n                    }, succeed.bind(null, done, 'root.getFile - Unexpected success callback, file should not exists: ' + dirName), fail);\n                }, failed.bind(null, done, 'root.getDirectory - Error creating directory : ' + dirName));\n            });\n            it(\"file.spec.34 DirectoryEntry.removeRecursively on directory\", function (done) {\n                var dirName = \"de.removeRecursively\",\n                subDirName = \"dir\",\n                dirExists = function (error) {\n                    expect(error).toBeDefined();\n                    expect(error).toBeFileError(FileError.NOT_FOUND_ERR);\n                    done();\n                };\n                // create a new directory entry to kick off it\n                root.getDirectory(dirName, {\n                    create : true\n                }, function (entry) {\n                    entry.getDirectory(subDirName, {\n                        create : true\n                    }, function (dir) {\n                        entry.removeRecursively(function () {\n                            root.getDirectory(dirName, {\n                                create : false\n                            }, succeed.bind(null, done, 'root.getDirectory - Unexpected success callback, directory should not exists: ' + dirName), dirExists);\n                        }, failed.bind(null, done, 'entry.removeRecursively - Error removing directory recursively : ' + dirName));\n                    }, failed.bind(null, done, 'root.getDirectory - Error creating directory : ' + subDirName));\n                }, failed.bind(null, done, 'root.getDirectory - Error creating directory : ' + dirName));\n            });\n            it(\"file.spec.35 createReader: create reader on existing directory\", function () {\n                // create reader for root directory\n                var reader = root.createReader();\n                expect(reader).toBeDefined();\n                expect(typeof reader.readEntries).toBe('function');\n            });\n            it(\"file.spec.36 removeRecursively on root file system\", function (done) {\n\n                var remove = function (error) {\n                    expect(error).toBeDefined();\n                    if (isChrome) {\n                        /*INVALID_MODIFICATION_ERR (code: 9) is thrown instead of\n                        NO_MODIFICATION_ALLOWED_ERR(code: 6) on trying to call removeRecursively\n                        on the root file system (Chrome).*/\n                        expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR);\n                    } else {\n                        expect(error).toBeFileError(FileError.NO_MODIFICATION_ALLOWED_ERR);\n                    }\n                    done();\n                };\n                // remove root file system\n                root.removeRecursively(succeed.bind(null, done, 'root.removeRecursively - Unexpected success callback, root cannot be removed'), remove);\n            });\n        });\n        describe('DirectoryReader interface', function () {\n            describe(\"readEntries\", function () {\n                it(\"file.spec.37 should read contents of existing directory\", function (done) {\n                    var reader,\n                    win = function (entries) {\n                        expect(entries).toBeDefined();\n                        expect(entries instanceof Array).toBe(true);\n                        done();\n                    };\n                    // create reader for root directory\n                    reader = root.createReader();\n                    // read entries\n                    reader.readEntries(win, failed.bind(null, done, 'reader.readEntries - Error reading entries'));\n                });\n                it(\"file.spec.37.1 should read contents of existing directory\", function (done) {\n                    var dirName = 'readEntries.dir',\n                    fileName = 'readeEntries.file';\n                    root.getDirectory(dirName, {\n                        create : true\n                    }, function (directory) {\n                        directory.getFile(fileName, {\n                            create : true\n                        }, function (fileEntry) {\n                            var reader = directory.createReader();\n                            reader.readEntries(function (entries) {\n                                expect(entries).toBeDefined();\n                                expect(entries instanceof Array).toBe(true);\n                                expect(entries.length).toBe(1);\n                                expect(entries[0].fullPath).toCanonicallyMatch(fileEntry.fullPath);\n                                expect(entries[0].filesystem).not.toBe(null);\n                                if (isChrome) {\n                                    // Slicing '[object {type}]' -> '{type}'\n                                    expect(entries[0].filesystem.toString().slice(8, -1)).toEqual(\"DOMFileSystem\");\n                                }\n                                else {\n                                    expect(entries[0].filesystem instanceof FileSystem).toBe(true);\n                                }\n\n                                // cleanup\n                                deleteEntry(directory.name, done);\n                            }, failed.bind(null, done, 'reader.readEntries - Error reading entries from directory: ' + dirName));\n                        }, failed.bind(null, done, 'directory.getFile - Error creating file : ' + fileName));\n                    }, failed.bind(null, done, 'root.getDirectory - Error creating directory : ' + dirName));\n                });\n                it(\"file.spec.109 should return an empty entry list on the second call\", function (done) {\n                    var reader,\n                    fileName = 'test109.txt';\n                    // Add a file to ensure the root directory is non-empty and then read the contents of the directory.\n                    root.getFile(fileName, {\n                        create : true\n                    }, function (entry) {\n                        reader = root.createReader();\n                        //First read\n                        reader.readEntries(function (entries) {\n                            expect(entries).toBeDefined();\n                            expect(entries instanceof Array).toBe(true);\n                            expect(entries.length).not.toBe(0);\n                            //Second read\n                            reader.readEntries(function (entries_) {\n                                expect(entries_).toBeDefined();\n                                expect(entries_ instanceof Array).toBe(true);\n                                expect(entries_.length).toBe(0);\n                                //Clean up\n                                deleteEntry(entry.name, done);\n                            }, failed.bind(null, done, 'reader.readEntries - Error during SECOND reading of entries from [root] directory'));\n                        }, failed.bind(null, done, 'reader.readEntries - Error during FIRST reading of entries from [root] directory'));\n                    }, failed.bind(null, done, 'root.getFile - Error creating file : ' + fileName));\n                });\n            });\n            it(\"file.spec.38 should read contents of directory that has been removed\", function (done) {\n                var dirName = \"de.createReader.notfound\";\n                // create a new directory entry to kick off it\n                root.getDirectory(dirName, {\n                    create : true\n                }, function (directory) {\n                    directory.removeRecursively(function () {\n                        var reader = directory.createReader();\n                        reader.readEntries(succeed.bind(null, done, 'reader.readEntries - Unexpected success callback, it should not read entries from deleted dir: ' + dirName), function (error) {\n                            expect(error).toBeDefined();\n                            expect(error).toBeFileError(FileError.NOT_FOUND_ERR);\n                            root.getDirectory(dirName, {\n                                create : false\n                            }, succeed.bind(null, done, 'root.getDirectory - Unexpected success callback, it should not get deleted directory: ' + dirName), function (err) {\n                                expect(err).toBeDefined();\n                                expect(err).toBeFileError(FileError.NOT_FOUND_ERR);\n                                done();\n                            });\n                        });\n                    }, failed.bind(null, done, 'directory.removeRecursively - Error removing directory recursively : ' + dirName));\n                }, failed.bind(null, done, 'root.getDirectory - Error creating directory : ' + dirName));\n            });\n        });\n        //DirectoryReader interface\n        describe('File', function () {\n            it(\"file.spec.39 constructor should be defined\", function () {\n                expect(File).toBeDefined();\n                expect(typeof File).toBe('function');\n            });\n            it(\"file.spec.40 should be define File attributes\", function () {\n                var file = new File();\n                expect(file.name).toBeDefined();\n                expect(file.type).toBeDefined();\n                expect(file.lastModifiedDate).toBeDefined();\n                expect(file.size).toBeDefined();\n            });\n        });\n        //File\n        describe('FileEntry', function () {\n\n            it(\"file.spec.41 should be define FileEntry methods\", function (done) {\n                var fileName = \"fe.methods\",\n                testFileEntry = function (fileEntry) {\n                    expect(fileEntry).toBeDefined();\n                    expect(typeof fileEntry.createWriter).toBe('function');\n                    expect(typeof fileEntry.file).toBe('function');\n                    // cleanup\n                    deleteEntry(fileEntry.name, done);\n                };\n                // create a new file entry to kick off it\n                root.getFile(fileName, {\n                    create : true\n                }, testFileEntry, failed.bind(null, done, 'root.getFile - Error creating file : ' + fileName));\n            });\n            it(\"file.spec.42 createWriter should return a FileWriter object\", function (done) {\n                var fileName = \"fe.createWriter\",\n                testFile,\n                testWriter = function (writer) {\n                    expect(writer).toBeDefined();\n                    if (isChrome) {\n                        // Slicing '[object {type}]' -> '{type}'\n                        expect(writer.toString().slice(8, -1)).toEqual(\"FileWriter\");\n                    }\n                    else {\n                        expect(writer instanceof FileWriter).toBe(true);\n                    }\n\n                    // cleanup\n                    deleteEntry(testFile.name, done);\n                };\n                // create a new file entry to kick off it\n                root.getFile(fileName, {\n                    create : true\n                }, function (fileEntry) {\n                    testFile = fileEntry;\n                    fileEntry.createWriter(testWriter, failed.bind(null, done, 'fileEntry.createWriter - Error creating Writer from entry'));\n                }, failed.bind(null, done, 'root.getFile - Error creating file : ' + fileName));\n            });\n            it(\"file.spec.43 file should return a File object\", function (done) {\n                var fileName = \"fe.file\",\n                newFile,\n                testFile = function (file) {\n                    expect(file).toBeDefined();\n                    if (isChrome) {\n                        // Slicing '[object {type}]' -> '{type}'\n                        expect(file.toString().slice(8, -1)).toEqual(\"File\");\n                    }\n                    else {\n                        expect(file instanceof File).toBe(true);\n                    }\n\n                    // cleanup\n                    deleteEntry(newFile.name, done);\n                };\n                // create a new file entry to kick off it\n                root.getFile(fileName, {\n                    create : true\n                }, function (fileEntry) {\n                    newFile = fileEntry;\n                    fileEntry.file(testFile, failed.bind(null, done, 'fileEntry.file - Error reading file using fileEntry: ' + fileEntry.name));\n                }, failed.bind(null, done, 'root.getFile - Error creating file : ' + fileName));\n            });\n            it(\"file.spec.44 file: on File that has been removed\", function (done) {\n                var fileName = \"fe.no.file\";\n                // create a new file entry to kick off it\n                root.getFile(fileName, {\n                    create : true\n                }, function (fileEntry) {\n                    fileEntry.remove(function () {\n                        fileEntry.file(succeed.bind(null, done, 'fileEntry.file - Unexpected success callback, file it should not be created from removed entry'), function (error) {\n                            expect(error).toBeDefined();\n                            expect(error).toBeFileError(FileError.NOT_FOUND_ERR);\n                            done();\n                        });\n                    }, failed.bind(null, done, 'fileEntry.remove - Error removing entry : ' + fileName));\n                }, failed.bind(null, done, 'root.getFile - Error creating file : ' + fileName));\n            });\n        });\n        //FileEntry\n        describe('Entry', function () {\n            it(\"file.spec.45 Entry object\", function (done) {\n                var fileName = \"entry\",\n                fullPath = joinURL(root.fullPath, fileName),\n                winEntry = function (entry) {\n                    expect(entry).toBeDefined();\n                    expect(entry.isFile).toBe(true);\n                    expect(entry.isDirectory).toBe(false);\n                    expect(entry.name).toCanonicallyMatch(fileName);\n                    expect(entry.fullPath).toCanonicallyMatch(fullPath);\n                    expect(typeof entry.getMetadata).toBe('function');\n                    expect(typeof entry.setMetadata).toBe('function');\n                    expect(typeof entry.moveTo).toBe('function');\n                    expect(typeof entry.copyTo).toBe('function');\n                    expect(typeof entry.toURL).toBe('function');\n                    expect(typeof entry.remove).toBe('function');\n                    expect(typeof entry.getParent).toBe('function');\n                    expect(typeof entry.createWriter).toBe('function');\n                    expect(typeof entry.file).toBe('function');\n                    // Clean up\n                    deleteEntry(fileName, done);\n                };\n                // create a new file entry\n                createFile(fileName, winEntry, failed.bind(null, done, 'createFile - Error creating file : ' + fileName));\n            });\n            it(\"file.spec.46 Entry.getMetadata on file\", function (done) {\n                var fileName = \"entry.metadata.file\";\n                // create a new file entry\n                createFile(fileName, function (entry) {\n                    entry.getMetadata(function (metadata) {\n                        expect(metadata).toBeDefined();\n                        expect(metadata.modificationTime instanceof Date).toBe(true);\n                        expect(typeof metadata.size).toBe(\"number\");\n                        // cleanup\n                        deleteEntry(fileName, done);\n                    }, failed.bind(null, done, 'entry.getMetadata - Error getting metadata from entry : ' + fileName));\n                }, failed.bind(null, done, 'createFile - Error creating file : ' + fileName));\n            });\n            it(\"file.spec.47 Entry.getMetadata on directory\", function (done) {\n                if (isIndexedDBShim) {\n                    /* Does not support metadata for directories (Firefox, IE) */\n                    pending();\n                }\n\n                var dirName = \"entry.metadata.dir\";\n                // create a new directory entry\n                createDirectory(dirName, function (entry) {\n                    entry.getMetadata(function (metadata) {\n                        expect(metadata).toBeDefined();\n                        expect(metadata.modificationTime instanceof Date).toBe(true);\n                        expect(typeof metadata.size).toBe(\"number\");\n                        expect(metadata.size).toBe(0);\n                        // cleanup\n                        deleteEntry(dirName, done);\n                    }, failed.bind(null, done, 'entry.getMetadata - Error getting metadata from entry : ' + dirName));\n                }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + dirName));\n            });\n            it(\"file.spec.48 Entry.getParent on file in root file system\", function (done) {\n                var fileName = \"entry.parent.file\",\n                rootPath = root.fullPath;\n                // create a new file entry\n                createFile(fileName, function (entry) {\n                    entry.getParent(function (parent) {\n                        expect(parent).toBeDefined();\n                        expect(parent.fullPath).toCanonicallyMatch(rootPath);\n                        // cleanup\n                        deleteEntry(fileName, done);\n                    }, failed.bind(null, done, 'entry.getParent - Error getting parent directory of file : ' + fileName));\n                }, failed.bind(null, done, 'createFile - Error creating file : ' + fileName));\n            });\n            it(\"file.spec.49 Entry.getParent on directory in root file system\", function (done) {\n                var dirName = \"entry.parent.dir\",\n                rootPath = root.fullPath;\n                // create a new directory entry\n                createDirectory(dirName, function (entry) {\n                    entry.getParent(function (parent) {\n                        expect(parent).toBeDefined();\n                        expect(parent.fullPath).toCanonicallyMatch(rootPath);\n                        // cleanup\n                        deleteEntry(dirName, done);\n                    }, failed.bind(null, done, 'entry.getParent - Error getting parent directory of directory : ' + dirName));\n                }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + dirName));\n            });\n            it(\"file.spec.50 Entry.getParent on root file system\", function (done) {\n                var rootPath = root.fullPath,\n                winParent = function (parent) {\n                    expect(parent).toBeDefined();\n                    expect(parent.fullPath).toCanonicallyMatch(rootPath);\n                    done();\n                };\n                // create a new directory entry\n                root.getParent(winParent, failed.bind(null, done, 'root.getParent - Error getting parent directory of root'));\n            });\n            it(\"file.spec.51 Entry.toURL on file\", function (done) {\n                var fileName = \"entry.uri.file\",\n                rootPath = root.fullPath,\n                winURI = function (entry) {\n                    var uri = entry.toURL();\n                    expect(uri).toBeDefined();\n                    expect(uri.indexOf(rootPath)).not.toBe(-1);\n                    // cleanup\n                    deleteEntry(fileName, done);\n                };\n                // create a new file entry\n                createFile(fileName, winURI, failed.bind(null, done, 'createFile - Error creating file : ' + fileName));\n            });\n            it(\"file.spec.52 Entry.toURL on directory\", function (done) {\n                var dirName_1 = \"num 1\",\n                dirName_2 = \"num 2\",\n                rootPath = root.fullPath;\n                createDirectory(dirName_1, function (entry) {\n                    entry.getDirectory(dirName_2, {\n                        create : true\n                    }, function (entryFile) {\n                        var uri = entryFile.toURL();\n                        expect(uri).toBeDefined();\n                        expect(uri).toContain('/num%201/num%202/');\n                        expect(uri.indexOf(rootPath)).not.toBe(-1);\n                        // cleanup\n                        deleteEntry(dirName_1, done);\n                    }, failed.bind(null, done, 'entry.getDirectory - Error creating directory : ' + dirName_2));\n                }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + dirName_1));\n            });\n            it(\"file.spec.53 Entry.remove on file\", function (done) {\n                var fileName = \"entr .rm.file\";\n                // create a new file entry\n                createFile(fileName, function (entry) {\n                    expect(entry).toBeDefined();\n                    entry.remove(function () {\n                        root.getFile(fileName, null, succeed.bind(null, done, 'root.getFile - Unexpected success callback, it should not get deleted file : ' + fileName), function (error) {\n                            expect(error).toBeDefined();\n                            expect(error).toBeFileError(FileError.NOT_FOUND_ERR);\n                            // cleanup\n                            deleteEntry(fileName, done);\n                        });\n                    }, failed.bind(null, done, 'entry.remove - Error removing entry : ' + fileName));\n                }, failed.bind(null, done, 'createFile - Error creating file : ' + fileName));\n            });\n            it(\"file.spec.53.1 Entry.remove on filename with #s\", function (done) {\n                var fileName = \"entry.#rm#.file\";\n                // create a new file entry\n                createFile(fileName, function (entry) {\n                    expect(entry).toBeDefined();\n                    entry.remove(function () {\n                        root.getFile(fileName, null, succeed.bind(null, done, 'root.getFile - Unexpected success callback, it should not get deleted file : ' + fileName), function (error) {\n                            expect(error).toBeDefined();\n                            expect(error).toBeFileError(FileError.NOT_FOUND_ERR);\n                            // cleanup\n                            deleteEntry(fileName, done);\n                        });\n                    }, failed.bind(null, done, 'entry.remove - Error removing entry : ' + fileName));\n                }, failed.bind(null, done, 'createFile - Error creating file : ' + fileName));\n            });\n            it(\"file.spec.54 remove on empty directory\", function (done) {\n                var dirName = \"entry.rm.dir\";\n                // create a new directory entry\n                createDirectory(dirName, function (entry) {\n                    expect(entry).toBeDefined();\n                    entry.remove(function () {\n                        root.getDirectory(dirName, null, succeed.bind(null, done, 'root.getDirectory - Unexpected success callback, it should not get deleted directory : ' + dirName), function (error) {\n                            expect(error).toBeDefined();\n                            expect(error).toBeFileError(FileError.NOT_FOUND_ERR);\n                            // cleanup\n                            deleteEntry(dirName, done);\n                        });\n                    }, failed.bind(null, done, 'entry.remove - Error removing entry : ' + dirName));\n                }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + dirName));\n            });\n            it(\"file.spec.55 remove on non-empty directory\", function (done) {\n                if (isIndexedDBShim) {\n                    /* Both Entry.remove and directoryEntry.removeRecursively don't fail when removing\n                    non-empty directories - directories being removed are cleaned\n                    along with contents instead (Firefox, IE)*/\n                    pending();\n                }\n\n                var dirName = \"ent y.rm.dir.not.empty\",\n                fileName = \"re ove.txt\",\n                fullPath = joinURL(root.fullPath, dirName);\n                // create a new directory entry\n                createDirectory(dirName, function (entry) {\n                    entry.getFile(fileName, {\n                        create : true\n                    }, function (fileEntry) {\n                        entry.remove(succeed.bind(null, done, 'entry.remove - Unexpected success callback, it should not remove a directory that contains files : ' + dirName), function (error) {\n                            expect(error).toBeDefined();\n                            expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR);\n                            root.getDirectory(dirName, null, function (entry) {\n                                expect(entry).toBeDefined();\n                                expect(entry.fullPath).toCanonicallyMatch(fullPath);\n                                // cleanup\n                                deleteEntry(dirName, done);\n                            }, failed.bind(null, done, 'root.getDirectory - Error getting directory : ' + dirName));\n                        });\n                    }, failed.bind(null, done, 'entry.getFile - Error creating file : ' + fileName + ' inside of ' + dirName));\n                }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + dirName));\n            });\n            it(\"file.spec.56 remove on root file system\", function (done) {\n\n                // remove entry that doesn't exist\n                root.remove(succeed.bind(null, done, 'entry.remove - Unexpected success callback, it should not remove entry that it does not exists'), function (error) {\n                    expect(error).toBeDefined();\n                    if (isChrome) {\n                        /*INVALID_MODIFICATION_ERR (code: 9) is thrown instead of\n                        NO_MODIFICATION_ALLOWED_ERR(code: 6) on trying to call removeRecursively\n                        on the root file system.*/\n                        expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR);\n                    } else {\n                        expect(error).toBeFileError(FileError.NO_MODIFICATION_ALLOWED_ERR);\n                    }\n                    done();\n                });\n            });\n            it(\"file.spec.57 copyTo: file\", function (done) {\n                var file1 = \"entry copy.file1\",\n                file2 = \"entry copy.file2\",\n                fullPath = joinURL(root.fullPath, file2);\n                // create a new file entry to kick off it\n                deleteEntry(file2, function () {\n                    createFile(file1, function (fileEntry) {\n                        // copy file1 to file2\n                        fileEntry.copyTo(root, file2, function (entry) {\n                            expect(entry).toBeDefined();\n                            expect(entry.isFile).toBe(true);\n                            expect(entry.isDirectory).toBe(false);\n                            expect(entry.fullPath).toCanonicallyMatch(fullPath);\n                            expect(entry.name).toCanonicallyMatch(file2);\n                            root.getFile(file2, {\n                                create : false\n                            }, function (entry2) {\n                                expect(entry2).toBeDefined();\n                                expect(entry2.isFile).toBe(true);\n                                expect(entry2.isDirectory).toBe(false);\n                                expect(entry2.fullPath).toCanonicallyMatch(fullPath);\n                                expect(entry2.name).toCanonicallyMatch(file2);\n                                // cleanup\n                                deleteEntry(file1, function () {\n                                    deleteEntry(file2, done);\n                                });\n                            }, failed.bind(null, done, 'root.getFile - Error getting copied file : ' + file2));\n                        }, failed.bind(null, done, 'fileEntry.copyTo - Error copying file : ' + file2));\n                    }, failed.bind(null, done, 'createFile - Error creating file : ' + file1));\n                }, failed.bind(null, done, 'deleteEntry - Error removing file : ' + file2));\n            });\n            it(\"file.spec.58 copyTo: file onto itself\", function (done) {\n                var file1 = \"entry.copy.fos.file1\";\n                // create a new file entry to kick off it\n                createFile(file1, function (entry) {\n                    // copy file1 onto itself\n                    entry.copyTo(root, null, succeed.bind(null, done, 'entry.copyTo - Unexpected success callback, it should not copy a null file'), function (error) {\n                        expect(error).toBeDefined();\n                        expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR);\n                        // cleanup\n                        deleteEntry(file1, done);\n                    });\n                }, failed.bind(null, done, 'createFile - Error creating file : ' + file1));\n            });\n            it(\"file.spec.59 copyTo: directory\", function (done) {\n                if (isIndexedDBShim) {\n                    /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */\n                    pending();\n                }\n\n                var file1 = \"file1\",\n                srcDir = \"entry.copy.srcDir\",\n                dstDir = \"entry.copy.dstDir\",\n                dstPath = joinURL(root.fullPath, dstDir),\n                filePath = joinURL(dstPath, file1);\n                // create a new directory entry to kick off it\n                deleteEntry(dstDir, function () {\n                    createDirectory(srcDir, function (directory) {\n                        // create a file within new directory\n                        directory.getFile(file1, {\n                            create : true\n                        }, function () {\n                            directory.copyTo(root, dstDir, function (directory) {\n                                expect(directory).toBeDefined();\n                                expect(directory.isFile).toBe(false);\n                                expect(directory.isDirectory).toBe(true);\n                                expect(directory.fullPath).toCanonicallyMatch(dstPath);\n                                expect(directory.name).toCanonicallyMatch(dstDir);\n                                root.getDirectory(dstDir, {\n                                    create : false\n                                }, function (dirEntry) {\n                                    expect(dirEntry).toBeDefined();\n                                    expect(dirEntry.isFile).toBe(false);\n                                    expect(dirEntry.isDirectory).toBe(true);\n                                    expect(dirEntry.fullPath).toCanonicallyMatch(dstPath);\n                                    expect(dirEntry.name).toCanonicallyMatch(dstDir);\n                                    dirEntry.getFile(file1, {\n                                        create : false\n                                    }, function (fileEntry) {\n                                        expect(fileEntry).toBeDefined();\n                                        expect(fileEntry.isFile).toBe(true);\n                                        expect(fileEntry.isDirectory).toBe(false);\n                                        expect(fileEntry.fullPath).toCanonicallyMatch(filePath);\n                                        expect(fileEntry.name).toCanonicallyMatch(file1);\n                                        // cleanup\n                                        deleteEntry(srcDir, function () {\n                                            deleteEntry(dstDir, done);\n                                        });\n                                    }, failed.bind(null, done, 'dirEntry.getFile - Error getting file : ' + file1));\n                                }, failed.bind(null, done, 'root.getDirectory - Error getting copied directory : ' + dstDir));\n                            }, failed.bind(null, done, 'directory.copyTo - Error copying directory : ' + srcDir + ' to :' + dstDir));\n                        }, failed.bind(null, done, 'directory.getFile - Error creating file : ' + file1));\n                    }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + srcDir));\n                }, failed.bind(null, done, 'deleteEntry - Error removing directory : ' + dstDir));\n            });\n            it(\"file.spec.60 copyTo: directory to backup at same root directory\", function (done) {\n                if (isIndexedDBShim) {\n                    /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */\n                    pending();\n                }\n\n                var file1 = \"file1\",\n                srcDir = \"entry.copy srcDirSame\",\n                dstDir = \"entry.copy srcDirSame-backup\",\n                dstPath = joinURL(root.fullPath, dstDir),\n                filePath = joinURL(dstPath, file1);\n                // create a new directory entry to kick off it\n                deleteEntry(dstDir, function () {\n                    createDirectory(srcDir, function (directory) {\n                        directory.getFile(file1, {\n                            create : true\n                        }, function () {\n                            directory.copyTo(root, dstDir, function (directory) {\n                                expect(directory).toBeDefined();\n                                expect(directory.isFile).toBe(false);\n                                expect(directory.isDirectory).toBe(true);\n                                expect(directory.fullPath).toCanonicallyMatch(dstPath);\n                                expect(directory.name).toCanonicallyMatch(dstDir);\n                                root.getDirectory(dstDir, {\n                                    create : false\n                                }, function (dirEntry) {\n                                    expect(dirEntry).toBeDefined();\n                                    expect(dirEntry.isFile).toBe(false);\n                                    expect(dirEntry.isDirectory).toBe(true);\n                                    expect(dirEntry.fullPath).toCanonicallyMatch(dstPath);\n                                    expect(dirEntry.name).toCanonicallyMatch(dstDir);\n                                    dirEntry.getFile(file1, {\n                                        create : false\n                                    }, function (fileEntry) {\n                                        expect(fileEntry).toBeDefined();\n                                        expect(fileEntry.isFile).toBe(true);\n                                        expect(fileEntry.isDirectory).toBe(false);\n                                        expect(fileEntry.fullPath).toCanonicallyMatch(filePath);\n                                        expect(fileEntry.name).toCanonicallyMatch(file1);\n                                        // cleanup\n                                        deleteEntry(srcDir, function () {\n                                            deleteEntry(dstDir, done);\n                                        });\n                                    }, failed.bind(null, done, 'dirEntry.getFile - Error getting file : ' + file1));\n                                }, failed.bind(null, done, 'root.getDirectory - Error getting copied directory : ' + dstDir));\n                            }, failed.bind(null, done, 'directory.copyTo - Error copying directory : ' + srcDir + ' to :' + dstDir));\n                        }, failed.bind(null, done, 'directory.getFile - Error creating file : ' + file1));\n                    }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + srcDir));\n                }, failed.bind(null, done, 'deleteEntry - Error removing directory : ' + dstDir));\n            });\n            it(\"file.spec.61 copyTo: directory onto itself\", function (done) {\n                if (isIndexedDBShim) {\n                    /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */\n                    pending();\n                }\n\n                var file1 = \"file1\",\n                srcDir = \"entry.copy.dos.srcDir\",\n                srcPath = joinURL(root.fullPath, srcDir),\n                filePath = joinURL(srcPath, file1);\n                // create a new directory entry to kick off it\n                createDirectory(srcDir, function (directory) {\n                    // create a file within new directory\n                    directory.getFile(file1, {\n                        create : true\n                    }, function (fileEntry) {\n                        // copy srcDir onto itself\n                        directory.copyTo(root, null, succeed.bind(null, done, 'directory.copyTo - Unexpected success callback, it should not copy file: ' + srcDir + ' to a null destination'), function (error) {\n                            expect(error).toBeDefined();\n                            expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR);\n                            root.getDirectory(srcDir, {\n                                create : false\n                            }, function (dirEntry) {\n                                expect(dirEntry).toBeDefined();\n                                expect(dirEntry.fullPath).toCanonicallyMatch(srcPath);\n                                dirEntry.getFile(file1, {\n                                    create : false\n                                }, function (fileEntry) {\n                                    expect(fileEntry).toBeDefined();\n                                    expect(fileEntry.fullPath).toCanonicallyMatch(filePath);\n                                    // cleanup\n                                    deleteEntry(srcDir, done);\n                                }, failed.bind(null, done, 'dirEntry.getFile - Error getting file : ' + file1));\n                            }, failed.bind(null, done, 'root.getDirectory - Error getting directory : ' + srcDir));\n                        });\n                    }, failed.bind(null, done, 'directory.getFile - Error creating file : ' + file1));\n                }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + srcDir));\n            });\n            it(\"file.spec.62 copyTo: directory into itself\", function (done) {\n                if (isIndexedDBShim) {\n                    /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */\n                    pending();\n                }\n\n                var srcDir = \"entry.copy.dis.srcDir\",\n                dstDir = \"entry.copy.dis.dstDir\",\n                srcPath = joinURL(root.fullPath, srcDir);\n                // create a new directory entry to kick off it\n                createDirectory(srcDir, function (directory) {\n                    // copy source directory into itself\n                    directory.copyTo(directory, dstDir, succeed.bind(null, done, 'directory.copyTo - Unexpected success callback, it should not copy a directory ' + srcDir + ' into itself'), function (error) {\n                        expect(error).toBeDefined();\n                        expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR);\n                        root.getDirectory(srcDir, {\n                            create : false\n                        }, function (dirEntry) {\n                            // returning confirms existence so just check fullPath entry\n                            expect(dirEntry).toBeDefined();\n                            expect(dirEntry.fullPath).toCanonicallyMatch(srcPath);\n                            // cleanup\n                            deleteEntry(srcDir, done);\n                        }, failed.bind(null, done, 'root.getDirectory - Error getting directory : ' + srcDir));\n                    });\n                }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + srcDir));\n            });\n            it(\"file.spec.63 copyTo: directory that does not exist\", function (done) {\n                var file1 = \"entry.copy.dnf.file1\",\n                dirName = 'dir-foo';\n                createFile(file1, function (fileEntry) {\n                    createDirectory(dirName, function (dirEntry) {\n                        dirEntry.remove(function () {\n                            fileEntry.copyTo(dirEntry, null, succeed.bind(null, done, 'fileEntry.copyTo - Unexpected success callback, it should not copy a file ' + file1 + ' into a removed directory'), function (error) {\n                                expect(error).toBeDefined();\n                                expect(error).toBeFileError(FileError.NOT_FOUND_ERR);\n                                done();\n                            });\n                        }, failed.bind(null, done, 'dirEntry.remove - Error removing directory : ' + dirName));\n                    }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + dirName));\n                }, failed.bind(null, done, 'createFile - Error creating file : ' + file1));\n            });\n            it(\"file.spec.64 copyTo: invalid target name\", function (done) {\n                if (isBrowser) {\n                    /*The plugin does not follow [\"8.3 Naming restrictions\"]\n                    (http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions*/\n                    pending();\n                }\n\n                var file1 = \"entry.copy.itn.file1\",\n                file2 = \"bad:file:name\";\n                // create a new file entry\n                createFile(file1, function (entry) {\n                    // copy file1 to file2\n                    entry.copyTo(root, file2, succeed.bind(null, done, 'entry.copyTo - Unexpected success callback, it should not copy a file ' + file1 + ' to an invalid file name: ' + file2), function (error) {\n                        expect(error).toBeDefined();\n                        expect(error).toBeFileError(FileError.ENCODING_ERR);\n                        // cleanup\n                        deleteEntry(file1, done);\n                    });\n                }, failed.bind(null, done, 'createFile - Error creating file : ' + file1));\n            });\n            it(\"file.spec.65 moveTo: file to same parent\", function (done) {\n                var file1 = \"entry.move.fsp.file1\",\n                file2 = \"entry.move.fsp.file2\",\n                dstPath = joinURL(root.fullPath, file2);\n                // create a new file entry to kick off it\n                createFile(file1, function (entry) {\n                    // move file1 to file2\n                    entry.moveTo(root, file2, function (entry) {\n                        expect(entry).toBeDefined();\n                        expect(entry.isFile).toBe(true);\n                        expect(entry.isDirectory).toBe(false);\n                        expect(entry.fullPath).toCanonicallyMatch(dstPath);\n                        expect(entry.name).toCanonicallyMatch(file2);\n                        root.getFile(file2, {\n                            create : false\n                        }, function (fileEntry) {\n                            expect(fileEntry).toBeDefined();\n                            expect(fileEntry.fullPath).toCanonicallyMatch(dstPath);\n                            root.getFile(file1, {\n                                create : false\n                            }, succeed.bind(null, done, 'root.getFile - Unexpected success callback, it should not get invalid or moved file: ' + file1), function (error) {\n                                //expect(navigator.fileMgr.testFileExists(srcPath) === false, \"original file should not exist.\");\n                                expect(error).toBeDefined();\n                                expect(error).toBeFileError(FileError.NOT_FOUND_ERR);\n                                // cleanup\n                                deleteEntry(file1, function () {\n                                    deleteEntry(file2, done);\n                                });\n                            });\n                        }, failed.bind(null, done, 'root.getFile - Error getting file : ' + file2));\n                    }, failed.bind(null, done, 'entry.moveTo - Error moving file : ' + file1 + ' to root as: ' + file2));\n                }, failed.bind(null, done, 'createFile - Error creating file : ' + file1));\n            });\n            it(\"file.spec.66 moveTo: file to new parent\", function (done) {\n                var file1 = \"entry.move.fnp.file1\",\n                dir = \"entry.move.fnp.dir\",\n                dstPath = joinURL(joinURL(root.fullPath, dir), file1);\n                // ensure destination directory is cleaned up first\n                deleteEntry(dir, function () {\n                    // create a new file entry to kick off it\n                    createFile(file1, function (entry) {\n                        // create a parent directory to move file to\n                        root.getDirectory(dir, {\n                            create : true\n                        }, function (directory) {\n                            // move file1 to new directory\n                            // move the file\n                            entry.moveTo(directory, null, function (entry) {\n                                expect(entry).toBeDefined();\n                                expect(entry.isFile).toBe(true);\n                                expect(entry.isDirectory).toBe(false);\n                                expect(entry.fullPath).toCanonicallyMatch(dstPath);\n                                expect(entry.name).toCanonicallyMatch(file1);\n                                // test the moved file exists\n                                directory.getFile(file1, {\n                                    create : false\n                                }, function (fileEntry) {\n                                    expect(fileEntry).toBeDefined();\n                                    expect(fileEntry.fullPath).toCanonicallyMatch(dstPath);\n                                    root.getFile(file1, {\n                                        create : false\n                                    }, succeed.bind(null, done, 'root.getFile - Unexpected success callback, it should not get invalid or moved file: ' + file1), function (error) {\n                                        expect(error).toBeDefined();\n                                        expect(error).toBeFileError(FileError.NOT_FOUND_ERR);\n                                        // cleanup\n                                        deleteEntry(file1, function () {\n                                            deleteEntry(dir, done);\n                                        });\n                                    });\n                                }, failed.bind(null, done, 'directory.getFile - Error getting file : ' + file1 + ' from: ' + dir));\n                            }, failed.bind(null, done, 'entry.moveTo - Error moving file : ' + file1 + ' to: ' + dir + ' with the same name'));\n                        }, failed.bind(null, done, 'root.getDirectory - Error creating directory : ' + dir));\n                    }, failed.bind(null, done, 'createFile - Error creating file : ' + file1));\n                }, failed.bind(null, done, 'deleteEntry - Error removing directory : ' + dir));\n            });\n            it(\"file.spec.67 moveTo: directory to same parent\", function (done) {\n                if (isIndexedDBShim) {\n                    /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */\n                    pending();\n                }\n\n                var file1 = \"file1\",\n                srcDir = \"entry.move.dsp.srcDir\",\n                dstDir = \"entry.move.dsp.dstDir\",\n                dstPath = joinURL(root.fullPath, dstDir),\n                filePath = joinURL(dstPath, file1);\n                // ensure destination directory is cleaned up before it\n                deleteEntry(dstDir, function () {\n                    // create a new directory entry to kick off it\n                    createDirectory(srcDir, function (directory) {\n                        // create a file within directory\n                        directory.getFile(file1, {\n                            create : true\n                        }, function () {\n                            // move srcDir to dstDir\n                            directory.moveTo(root, dstDir, function (directory) {\n                                expect(directory).toBeDefined();\n                                expect(directory.isFile).toBe(false);\n                                expect(directory.isDirectory).toBe(true);\n                                expect(directory.fullPath).toCanonicallyMatch(dstPath);\n                                expect(directory.name).toCanonicallyMatch(dstDir);\n                                // test that moved file exists in destination dir\n                                directory.getFile(file1, {\n                                    create : false\n                                }, function (fileEntry) {\n                                    expect(fileEntry).toBeDefined();\n                                    expect(fileEntry.fullPath).toCanonicallyMatch(filePath);\n                                    // check that the moved file no longer exists in original dir\n                                    root.getFile(file1, {\n                                        create : false\n                                    }, succeed.bind(null, done, 'directory.getFile - Unexpected success callback, it should not get invalid or moved file: ' + file1), function (error) {\n                                        expect(error).toBeDefined();\n                                        expect(error).toBeFileError(FileError.NOT_FOUND_ERR);\n                                        // cleanup\n                                        deleteEntry(srcDir, function() {\n                                            deleteEntry(dstDir, done);\n                                        });\n                                    });\n                                }, failed.bind(null, done, 'directory.getFile - Error getting file : ' + file1 + ' from: ' + srcDir));\n                            }, failed.bind(null, done, 'entry.moveTo - Error moving directory : ' + srcDir + ' to root as: ' + dstDir));\n                        }, failed.bind(null, done, 'directory.getFile - Error creating file : ' + file1));\n                    }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + srcDir));\n                }, failed.bind(null, done, 'deleteEntry - Error removing directory : ' + dstDir));\n            });\n            it(\"file.spec.68 moveTo: directory to same parent with same name\", function (done) {\n                if (isIndexedDBShim) {\n                    /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */\n                    pending();\n                }\n\n                var file1 = \"file1\",\n                srcDir = \"entry.move.dsp.srcDir\",\n                dstDir = \"entry.move.dsp.srcDir-backup\",\n                dstPath = joinURL(root.fullPath, dstDir),\n                filePath = joinURL(dstPath, file1);\n                // ensure destination directory is cleaned up before it\n                deleteEntry(dstDir, function () {\n                    // create a new directory entry to kick off it\n                    createDirectory(srcDir, function (directory) {\n                        // create a file within directory\n                        directory.getFile(file1, {\n                            create : true\n                        }, function () {\n                            // move srcDir to dstDir\n                            directory.moveTo(root, dstDir, function (directory) {\n                                expect(directory).toBeDefined();\n                                expect(directory.isFile).toBe(false);\n                                expect(directory.isDirectory).toBe(true);\n                                expect(directory.fullPath).toCanonicallyMatch(dstPath);\n                                expect(directory.name).toCanonicallyMatch(dstDir);\n                                // check that moved file exists in destination dir\n                                directory.getFile(file1, {\n                                    create : false\n                                }, function (fileEntry) {\n                                    expect(fileEntry).toBeDefined();\n                                    expect(fileEntry.fullPath).toCanonicallyMatch(filePath);\n                                    // check that the moved file no longer exists in original dir\n                                    root.getFile(file1, {\n                                        create : false\n                                    }, succeed.bind(null, done, 'directory.getFile - Unexpected success callback, it should not get invalid or moved file: ' + file1), function (error) {\n                                        expect(error).toBeDefined();\n                                        expect(error).toBeFileError(FileError.NOT_FOUND_ERR);\n                                        // cleanup\n                                        deleteEntry(srcDir, function() {\n                                            deleteEntry(dstDir, done);\n                                        });\n                                    });\n                                }, failed.bind(null, done, 'directory.getFile - Error getting file : ' + file1 + ' from: ' + srcDir));\n                            }, failed.bind(null, done, 'entry.moveTo - Error moving directory : ' + srcDir + ' to root as: ' + dstDir));\n                        }, failed.bind(null, done, 'directory.getFile - Error creating file : ' + file1));\n                    }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + srcDir));\n                }, failed.bind(null, done, 'deleteEntry - Error removing directory : ' + dstDir));\n            });\n            it(\"file.spec.69 moveTo: directory to new parent\", function (done) {\n                if (isIndexedDBShim) {\n                    /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */\n                    pending();\n                }\n\n                var file1 = \"file1\",\n                srcDir = \"entry.move.dnp.srcDir\",\n                dstDir = \"entry.move.dnp.dstDir\",\n                dstPath = joinURL(root.fullPath, dstDir),\n                filePath = joinURL(dstPath, file1);\n                // ensure destination directory is cleaned up before it\n                deleteEntry(dstDir, function () {\n                    // create a new directory entry to kick off it\n                    createDirectory(srcDir, function (directory) {\n                        // create a file within directory\n                        directory.getFile(file1, {\n                            create : true\n                        }, function () {\n                            // move srcDir to dstDir\n                            directory.moveTo(root, dstDir, function (dirEntry) {\n                                expect(dirEntry).toBeDefined();\n                                expect(dirEntry.isFile).toBe(false);\n                                expect(dirEntry.isDirectory).toBe(true);\n                                expect(dirEntry.fullPath).toCanonicallyMatch(dstPath);\n                                expect(dirEntry.name).toCanonicallyMatch(dstDir);\n                                // test that moved file exists in destination dir\n                                dirEntry.getFile(file1, {\n                                    create : false\n                                }, function (fileEntry) {\n                                    expect(fileEntry).toBeDefined();\n                                    expect(fileEntry.fullPath).toCanonicallyMatch(filePath);\n                                    // test that the moved file no longer exists in original dir\n                                    root.getFile(file1, {\n                                        create : false\n                                    }, succeed.bind(null, done, 'root.getFile - Unexpected success callback, it should not get invalid or moved file: ' + file1), function (error) {\n                                        expect(error).toBeDefined();\n                                        expect(error).toBeFileError(FileError.NOT_FOUND_ERR);\n                                        // cleanup\n                                        deleteEntry(srcDir, function() {\n                                            deleteEntry(dstDir, done);\n                                        });\n                                    });\n                                }, failed.bind(null, done, 'directory.getFile - Error getting file : ' + file1 + ' from: ' + dstDir));\n                            }, failed.bind(null, done, 'directory.moveTo - Error moving directory : ' + srcDir + ' to root as: ' + dstDir));\n                        }, failed.bind(null, done, 'directory.getFile - Error creating file : ' + file1));\n                    }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + srcDir));\n                }, failed.bind(null, done, 'deleteEntry - Error removing directory : ' + dstDir));\n            });\n            it(\"file.spec.70 moveTo: directory onto itself\", function (done) {\n                if (isIndexedDBShim) {\n                    /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */\n                    pending();\n                }\n\n                var file1 = \"file1\",\n                srcDir = \"entry.move.dos.srcDir\",\n                srcPath = joinURL(root.fullPath, srcDir),\n                filePath = joinURL(srcPath, file1);\n                // create a new directory entry to kick off it\n                createDirectory(srcDir, function (directory) {\n                    // create a file within new directory\n                    directory.getFile(file1, {\n                        create : true\n                    }, function () {\n                        // move srcDir onto itself\n                        directory.moveTo(root, null, succeed.bind(null, done, 'directory.moveTo - Unexpected success callback, it should not move directory to invalid path'), function (error) {\n                            expect(error).toBeDefined();\n                            expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR);\n                            // test that original dir still exists\n                            root.getDirectory(srcDir, {\n                                create : false\n                            }, function (dirEntry) {\n                                // returning confirms existence so just check fullPath entry\n                                expect(dirEntry).toBeDefined();\n                                expect(dirEntry.fullPath).toCanonicallyMatch(srcPath);\n                                dirEntry.getFile(file1, {\n                                    create : false\n                                }, function (fileEntry) {\n                                    expect(fileEntry).toBeDefined();\n                                    expect(fileEntry.fullPath).toCanonicallyMatch(filePath);\n                                    // cleanup\n                                    deleteEntry(srcDir, done);\n                                }, failed.bind(null, done, 'dirEntry.getFile - Error getting file : ' + file1 + ' from: ' + srcDir));\n                            }, failed.bind(null, done, 'root.getDirectory - Error getting directory : ' + srcDir));\n                        });\n                    }, failed.bind(null, done, 'directory.getFile - Error creating file : ' + file1));\n                }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + srcDir));\n            });\n            it(\"file.spec.71 moveTo: directory into itself\", function (done) {\n                if (isIndexedDBShim) {\n                    /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */\n                    pending();\n                }\n\n                var srcDir = \"entry.move.dis.srcDir\",\n                dstDir = \"entry.move.dis.dstDir\",\n                srcPath = joinURL(root.fullPath, srcDir);\n                // create a new directory entry to kick off it\n                createDirectory(srcDir, function (directory) {\n                    // move source directory into itself\n                    directory.moveTo(directory, dstDir, succeed.bind(null, done, 'directory.moveTo - Unexpected success callback, it should not move a directory into itself: ' + srcDir), function (error) {\n                        expect(error).toBeDefined();\n                        expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR);\n                        // make sure original directory still exists\n                        root.getDirectory(srcDir, {\n                            create : false\n                        }, function (entry) {\n                            expect(entry).toBeDefined();\n                            expect(entry.fullPath).toCanonicallyMatch(srcPath);\n                            // cleanup\n                            deleteEntry(srcDir, done);\n                        }, failed.bind(null, done, 'root.getDirectory - Error getting directory, making sure that original directory still exists: ' + srcDir));\n                    });\n                }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + srcDir));\n            });\n            it(\"file.spec.130 moveTo: directory into similar directory\", function (done) {\n                if (isIndexedDBShim) {\n                    /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */\n                    pending();\n                }\n\n                var srcDir = \"entry.move.dis.srcDir\",\n                dstDir = \"entry.move.dis.srcDir-backup\";\n                // create a new directory entry to kick off it\n                createDirectory(srcDir, function (srcDirEntry) {\n                deleteEntry(dstDir, function () {\n                createDirectory(dstDir, function (dstDirEntry) {\n                    // move source directory into itself\n                    srcDirEntry.moveTo(dstDirEntry, 'file', function (newDirEntry) {\n                        expect(newDirEntry).toBeDefined();\n                        deleteEntry(dstDir, done);\n                    }, failed.bind(null, done, 'directory.moveTo - Error moving a directory into a similarly-named directory: ' + srcDir));\n                }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + dstDir));\n                }, failed.bind(null, done, 'deleteEntry - Error deleting directory : ' + dstDir));\n                }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + srcDir));\n            });\n            it(\"file.spec.72 moveTo: file onto itself\", function (done) {\n                var file1 = \"entry.move.fos.file1\",\n                filePath = joinURL(root.fullPath, file1);\n                // create a new file entry to kick off it\n                createFile(file1, function (entry) {\n                    // move file1 onto itself\n                    entry.moveTo(root, null, succeed.bind(null, done, 'entry.moveTo - Unexpected success callback, it should not move a file: ' + file1 + ' into the same parent'), function (error) {\n                        expect(error).toBeDefined();\n                        expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR);\n                        //test that original file still exists\n                        root.getFile(file1, {\n                            create : false\n                        }, function (fileEntry) {\n                            expect(fileEntry).toBeDefined();\n                            expect(fileEntry.fullPath).toCanonicallyMatch(filePath);\n                            // cleanup\n                            deleteEntry(file1, done);\n                        }, failed.bind(null, done, 'root.getFile - Error getting file, making sure that original file still exists: ' + file1));\n                    });\n                }, failed.bind(null, done, 'createFile - Error creating file : ' + file1));\n            });\n            it(\"file.spec.73 moveTo: file onto existing directory\", function (done) {\n                var file1 = \"entry.move.fod.file1\",\n                dstDir = \"entry.move.fod.dstDir\",\n                subDir = \"subDir\",\n                dirPath = joinURL(joinURL(root.fullPath, dstDir), subDir),\n                filePath = joinURL(root.fullPath, file1);\n                // ensure destination directory is cleaned up before it\n                deleteEntry(dstDir, function () {\n                    // create a new file entry to kick off it\n                    createFile(file1, function (entry) {\n                        // create top level directory\n                        root.getDirectory(dstDir, {\n                            create : true\n                        }, function (directory) {\n                            // create sub-directory\n                            directory.getDirectory(subDir, {\n                                create : true\n                            }, function (subDirectory) {\n                                // move file1 onto sub-directory\n                                entry.moveTo(directory, subDir, succeed.bind(null, done, 'entry.moveTo - Unexpected success callback, it should not move a file: ' + file1 + ' into directory: ' + dstDir + '\\n' + subDir + ' directory already exists'), function (error) {\n                                    expect(error).toBeDefined();\n                                    expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR);\n                                    // check that original dir still exists\n                                    directory.getDirectory(subDir, {\n                                        create : false\n                                    }, function (dirEntry) {\n                                        expect(dirEntry).toBeDefined();\n                                        expect(dirEntry.fullPath).toCanonicallyMatch(dirPath);\n                                        // check that original file still exists\n                                        root.getFile(file1, {\n                                            create : false\n                                        }, function (fileEntry) {\n                                            expect(fileEntry).toBeDefined();\n                                            expect(fileEntry.fullPath).toCanonicallyMatch(filePath);\n                                            // cleanup\n                                            deleteEntry(file1, function () {\n                                                deleteEntry(dstDir, done);\n                                            });\n                                        }, failed.bind(null, done, 'root.getFile - Error getting file, making sure that original file still exists: ' + file1));\n                                    }, failed.bind(null, done, 'directory.getDirectory - Error getting directory, making sure that original directory still exists: ' + subDir));\n                                });\n                            }, failed.bind(null, done, 'directory.getDirectory - Error creating directory : ' + subDir));\n                        }, failed.bind(null, done, 'root.getDirectory - Error creating directory : ' + dstDir));\n                    }, failed.bind(null, done, 'createFile - Error creating file : ' + file1));\n                }, failed.bind(null, done, 'deleteEntry - Error removing directory : ' + dstDir));\n            });\n            it(\"file.spec.74 moveTo: directory onto existing file\", function (done) {\n                if (isIndexedDBShim) {\n                    /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */\n                    pending();\n                }\n\n                var file1 = \"entry.move.dof.file1\",\n                srcDir = \"entry.move.dof.srcDir\",\n                dirPath = joinURL(root.fullPath, srcDir),\n                filePath = joinURL(root.fullPath, file1);\n                // create a new directory entry to kick off it\n                createDirectory(srcDir, function (entry) {\n                    // create file\n                    root.getFile(file1, {\n                        create : true\n                    }, function (fileEntry) {\n                        // move directory onto file\n                        entry.moveTo(root, file1, succeed.bind(null, done, 'entry.moveTo - Unexpected success callback, it should not move : \\n' + srcDir + ' into root directory renamed as ' + file1 + '\\n' + file1 + ' file already exists'), function (error) {\n                            expect(error).toBeDefined();\n                            expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR);\n                            // test that original directory exists\n                            root.getDirectory(srcDir, {\n                                create : false\n                            }, function (dirEntry) {\n                                // returning confirms existence so just check fullPath entry\n                                expect(dirEntry).toBeDefined();\n                                expect(dirEntry.fullPath).toCanonicallyMatch(dirPath);\n                                // test that original file exists\n                                root.getFile(file1, {\n                                    create : false\n                                }, function (fileEntry) {\n                                    expect(fileEntry).toBeDefined();\n                                    expect(fileEntry.fullPath).toCanonicallyMatch(filePath);\n                                    // cleanup\n                                    deleteEntry(file1, function () {\n                                        deleteEntry(srcDir, done);\n                                    });\n                                }, failed.bind(null, done, 'root.getFile - Error getting file, making sure that original file still exists: ' + file1));\n                            }, failed.bind(null, done, 'directory.getDirectory - Error getting directory, making sure that original directory still exists: ' + srcDir));\n                        });\n                    }, failed.bind(null, done, 'root.getFile - Error creating file : ' + file1));\n                }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + srcDir));\n            });\n            it(\"file.spec.75 copyTo: directory onto existing file\", function (done) {\n                if (isIndexedDBShim) {\n                    /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */\n                    pending();\n                }\n\n                var file1 = \"entry.copy.dof.file1\",\n                srcDir = \"entry.copy.dof.srcDir\",\n                dirPath = joinURL(root.fullPath, srcDir),\n                filePath = joinURL(root.fullPath, file1);\n                // create a new directory entry to kick off it\n                createDirectory(srcDir, function (entry) {\n                    // create file\n                    root.getFile(file1, {\n                        create : true\n                    }, function () {\n                        // copy directory onto file\n                        entry.copyTo(root, file1, succeed.bind(null, done, 'entry.copyTo - Unexpected success callback, it should not copy : \\n' + srcDir + ' into root directory renamed as ' + file1 + '\\n' + file1 + ' file already exists'), function (error) {\n                            expect(error).toBeDefined();\n                            expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR);\n                            //check that original dir still exists\n                            root.getDirectory(srcDir, {\n                                create : false\n                            }, function (dirEntry) {\n                                // returning confirms existence so just check fullPath entry\n                                expect(dirEntry).toBeDefined();\n                                expect(dirEntry.fullPath).toCanonicallyMatch(dirPath);\n                                // test that original file still exists\n                                root.getFile(file1, {\n                                    create : false\n                                }, function (fileEntry) {\n                                    expect(fileEntry).toBeDefined();\n                                    expect(fileEntry.fullPath).toCanonicallyMatch(filePath);\n                                    // cleanup\n                                    deleteEntry(file1, function () {\n                                        deleteEntry(srcDir, done);\n                                    });\n                                }, failed.bind(null, done, 'root.getFile - Error getting file, making sure that original file still exists: ' + file1));\n                            }, failed.bind(null, done, 'root.getDirectory - Error getting directory, making sure that original directory still exists: ' + srcDir));\n                        });\n                    }, failed.bind(null, done, 'root.getFile - Error creating file : ' + file1));\n                }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + srcDir));\n            });\n            it(\"file.spec.76 moveTo: directory onto directory that is not empty\", function (done) {\n                if (isIndexedDBShim) {\n                    /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */\n                    pending();\n                }\n\n                var srcDir = \"entry.move.dod.srcDir\",\n                dstDir = \"entry.move.dod.dstDir\",\n                subDir = \"subDir\",\n                srcPath = joinURL(root.fullPath, srcDir),\n                dstPath = joinURL(joinURL(root.fullPath, dstDir), subDir);\n                // ensure destination directory is cleaned up before it\n                deleteEntry(dstDir, function () {\n                    // create a new file entry to kick off it\n                    createDirectory(srcDir, function (entry) {\n                        // create top level directory\n                        root.getDirectory(dstDir, {\n                            create : true\n                        }, function (directory) {\n                            // create sub-directory\n                            directory.getDirectory(subDir, {\n                                create : true\n                            }, function () {\n                                // move srcDir onto dstDir (not empty)\n                                entry.moveTo(root, dstDir, succeed.bind(null, done, 'entry.moveTo - Unexpected success callback, it should not copy : \\n' + srcDir + ' into root directory renamed as ' + dstDir + '\\n' + dstDir + ' directory already exists'), function (error) {\n                                    expect(error).toBeDefined();\n                                    expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR);\n                                    // making sure destination directory still exists\n                                    directory.getDirectory(subDir, {\n                                        create : false\n                                    }, function (dirEntry) {\n                                        // returning confirms existence so just check fullPath entry\n                                        expect(dirEntry).toBeDefined();\n                                        expect(dirEntry.fullPath).toCanonicallyMatch(dstPath);\n                                        // making sure source directory exists\n                                        root.getDirectory(srcDir, {\n                                            create : false\n                                        }, function (srcEntry) {\n                                            expect(srcEntry).toBeDefined();\n                                            expect(srcEntry.fullPath).toCanonicallyMatch(srcPath);\n                                            // cleanup\n                                            deleteEntry(srcDir, function () {\n                                                deleteEntry(dstDir, done);\n                                            });\n                                        }, failed.bind(null, done, 'root.getDirectory - Error getting directory, making sure that original directory still exists: ' + srcDir));\n                                    }, failed.bind(null, done, 'directory.getDirectory - Error getting directory, making sure that original directory still exists: ' + subDir));\n                                });\n                            }, failed.bind(null, done, 'directory.getDirectory - Error creating directory : ' + subDir));\n                        }, failed.bind(null, done, 'directory.getDirectory - Error creating directory : ' + subDir));\n                    }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + srcDir));\n                }, failed.bind(null, done, 'deleteEntry - Error removing directory : ' + dstDir));\n            });\n            it(\"file.spec.77 moveTo: file replace existing file\", function (done) {\n                var file1 = \"entry.move.frf.file1\",\n                file2 = \"entry.move.frf.file2\",\n                file2Path = joinURL(root.fullPath, file2);\n                // create a new directory entry to kick off it\n                createFile(file1, function (entry) {\n                    // create file\n                    root.getFile(file2, {\n                        create : true\n                    }, function () {\n                        // replace file2 with file1\n                        entry.moveTo(root, file2, function (entry2) {\n                            expect(entry2).toBeDefined();\n                            expect(entry2.isFile).toBe(true);\n                            expect(entry2.isDirectory).toBe(false);\n                            expect(entry2.fullPath).toCanonicallyMatch(file2Path);\n                            expect(entry2.name).toCanonicallyMatch(file2);\n                            // old file should not exists\n                            root.getFile(file1, {\n                                create : false\n                            }, succeed.bind(null, done, 'root.getFile - Unexpected success callback, file: ' + file1 + ' should not exists'), function (error) {\n                                expect(error).toBeDefined();\n                                expect(error).toBeFileError(FileError.NOT_FOUND_ERR);\n                                // test that new file exists\n                                root.getFile(file2, {\n                                    create : false\n                                }, function (fileEntry) {\n                                    expect(fileEntry).toBeDefined();\n                                    expect(fileEntry.fullPath).toCanonicallyMatch(file2Path);\n                                    // cleanup\n                                    deleteEntry(file1, function () {\n                                        deleteEntry(file2, done);\n                                    });\n                                }, failed.bind(null, done, 'root.getFile - Error getting moved file: ' + file2));\n                            });\n                        }, failed.bind(null, done, 'entry.moveTo - Error moving file : ' + file1 + ' to root as: ' + file2));\n                    }, failed.bind(null, done, 'root.getFile - Error creating file: ' + file2));\n                }, failed.bind(null, done, 'createFile - Error creating file: ' + file1));\n            });\n            it(\"file.spec.78 moveTo: directory replace empty directory\", function (done) {\n                if (isIndexedDBShim) {\n                    /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */\n                    pending();\n                }\n\n                var file1 = \"file1\",\n                srcDir = \"entry.move.drd.srcDir\",\n                dstDir = \"entry.move.drd.dstDir\",\n                dstPath = joinURL(root.fullPath, dstDir),\n                filePath = dstPath + '/' + file1;\n                // ensure destination directory is cleaned up before it\n                deleteEntry(dstDir, function () {\n                    // create a new directory entry to kick off it\n                    createDirectory(srcDir, function (directory) {\n                        // create a file within source directory\n                        directory.getFile(file1, {\n                            create : true\n                        }, function () {\n                            // create destination directory\n                            root.getDirectory(dstDir, {\n                                create : true\n                            }, function () {\n                                // move srcDir to dstDir\n                                directory.moveTo(root, dstDir, function (dirEntry) {\n                                    expect(dirEntry).toBeDefined();\n                                    expect(dirEntry.isFile).toBe(false);\n                                    expect(dirEntry.isDirectory).toBe(true);\n                                    expect(dirEntry.fullPath).toCanonicallyMatch(dstPath);\n                                    expect(dirEntry.name).toCanonicallyMatch(dstDir);\n                                    // check that old directory contents have been moved\n                                    dirEntry.getFile(file1, {\n                                        create : false\n                                    }, function (fileEntry) {\n                                        expect(fileEntry).toBeDefined();\n                                        expect(fileEntry.fullPath).toCanonicallyMatch(filePath);\n                                        // check that old directory no longer exists\n                                        root.getDirectory(srcDir, {\n                                            create : false\n                                        }, succeed.bind(null, done, 'root.getDirectory - Unexpected success callback, directory: ' + srcDir + ' should not exists'), function (error) {\n                                            expect(error).toBeDefined();\n                                            expect(error).toBeFileError(FileError.NOT_FOUND_ERR);\n                                            // cleanup\n                                            deleteEntry(srcDir, function () {\n                                                deleteEntry(dstDir, done);\n                                            });\n                                        });\n                                    }, failed.bind(null, done, 'dirEntry.getFile - Error getting moved file: ' + file1));\n                                }, failed.bind(null, done, 'entry.moveTo - Error moving directory : ' + srcDir + ' to root as: ' + dstDir));\n                            }, failed.bind(null, done, 'root.getDirectory - Error creating directory: ' + dstDir));\n                        }, failed.bind(null, done, 'root.getFile - Error creating file: ' + file1));\n                    }, failed.bind(null, done, 'createDirectory - Error creating directory: ' + srcDir));\n                }, failed.bind(null, done, 'deleteEntry - Error removing directory : ' + dstDir));\n            });\n            it(\"file.spec.79 moveTo: directory that does not exist\", function (done) {\n\n                var file1 = \"entry.move.dnf.file1\",\n                dstDir = \"entry.move.dnf.dstDir\",\n                dstPath = joinURL(root.fullPath, dstDir);\n                // create a new file entry to kick off it\n                createFile(file1, function (entry) {\n                    // move file to directory that does not exist\n                    var directory = new DirectoryEntry();\n                    directory.filesystem = root.filesystem;\n                    directory.fullPath = dstPath;\n                    entry.moveTo(directory, null, succeed.bind(null, done, 'entry.moveTo - Unexpected success callback, parent directory: ' + dstPath + ' should not exists'), function (error) {\n                        expect(error).toBeDefined();\n                        if (isChrome) {\n                            /*INVALID_MODIFICATION_ERR (code: 9) is thrown instead of NOT_FOUND_ERR(code: 1)\n                            on trying to moveTo directory that does not exist.*/\n                            expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR);\n                        } else {\n                            expect(error).toBeFileError(FileError.NOT_FOUND_ERR);\n                        }\n                        // cleanup\n                        deleteEntry(file1, done);\n                    });\n                }, failed.bind(null, done, 'createFile - Error creating file: ' + file1));\n            });\n            it(\"file.spec.80 moveTo: invalid target name\", function (done) {\n                if (isBrowser) {\n                    /*The plugin does not follow [\"8.3 Naming restrictions\"]\n                    (http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions*/\n                    pending();\n                }\n\n                var file1 = \"entry.move.itn.file1\",\n                file2 = \"bad:file:name\";\n                // create a new file entry to kick off it\n                createFile(file1, function (entry) {\n                    // move file1 to file2\n                    entry.moveTo(root, file2, succeed.bind(null, done, 'entry.moveTo - Unexpected success callback, : ' + file1 + ' to root as: ' + file2), function (error) {\n                        expect(error).toBeDefined();\n                        expect(error).toBeFileError(FileError.ENCODING_ERR);\n                        // cleanup\n                        deleteEntry(file1, done);\n                    });\n                }, failed.bind(null, done, 'createFile - Error creating file: ' + file1));\n            });\n        });\n        //Entry\n        describe('FileReader', function () {\n            it(\"file.spec.81 should have correct methods\", function () {\n                var reader = new FileReader();\n                expect(reader).toBeDefined();\n                expect(typeof reader.readAsBinaryString).toBe('function');\n                expect(typeof reader.readAsDataURL).toBe('function');\n                expect(typeof reader.readAsText).toBe('function');\n                expect(typeof reader.readAsArrayBuffer).toBe('function');\n                expect(typeof reader.abort).toBe('function');\n                expect(reader.result).toBe(null);\n            });\n        });\n        //FileReader\n        describe('Read method', function () {\n            it(\"file.spec.82 should error out on non-existent file\", function (done) {\n                var fileName = cordova.platformId === 'windowsphone' ? root.toURL() + \"/\" + \"somefile.txt\" : \"somefile.txt\",\n                verifier = function (evt) {\n                    expect(evt).toBeDefined();\n                    expect(evt.target.error).toBeFileError(FileError.NOT_FOUND_ERR);\n                    done();\n                };\n                root.getFile(fileName, {\n                    create : true\n                }, function (entry) {\n                    entry.file(function (file) {\n                        deleteEntry(fileName, function () {\n                            //Create FileReader\n                            var reader = new FileReader();\n                            reader.onerror = verifier;\n                            reader.onload = succeed.bind(null, done, 'reader.onload - Unexpected success callback, file: ' + fileName + ' it should not exists');\n                            reader.readAsText(file);\n                        }, failed.bind(null, done, 'deleteEntry - Error removing file: ' + fileName));\n                    }, failed.bind(null, done, 'entry.file - Error reading file: ' + fileName));\n                }, failed.bind(null, done, 'root.getFile - Error creating file: ' + fileName));\n            });\n            it(\"file.spec.83 should be able to read native blob objects\", function (done) {\n                // Skip test if blobs are not supported (e.g.: Android 2.3).\n                if (typeof window.Blob == 'undefined' || typeof window.Uint8Array == 'undefined') {\n                    expect(true).toFailWithMessage('Platform does not supported this feature');\n                    done();\n                }\n                var contents = 'asdf';\n                var uint8Array = new Uint8Array(contents.length);\n                for (var i = 0; i < contents.length; ++i) {\n                    uint8Array[i] = contents.charCodeAt(i);\n                }\n                var Builder = window.BlobBuilder || window.WebKitBlobBuilder;\n                var blob;\n                if (Builder) {\n                    var builder = new Builder();\n                    builder.append(uint8Array.buffer);\n                    builder.append(contents);\n                    blob = builder.getBlob(\"text/plain\");\n                } else {\n                    try {\n                        // iOS 6 does not support Views, so pass in the buffer.\n                        blob = new Blob([uint8Array.buffer, contents]);\n                    } catch (e) {\n                        // Skip the test if we can't create a blob (e.g.: iOS 5).\n                        if (e instanceof TypeError) {\n                            expect(true).toFailWithMessage('Platform does not supported this feature');\n                            done();\n                        }\n                        throw e;\n                    }\n                }\n                var verifier = function (evt) {\n                    expect(evt).toBeDefined();\n                    expect(evt.target.result).toBe('asdfasdf');\n                    done();\n                };\n                var reader = new FileReader();\n                reader.onloadend = verifier;\n                reader.readAsText(blob);\n            });\n            function writeDummyFile(writeBinary, callback, done, fileContents) {\n                var fileName = \"dummy.txt\",\n                fileEntry = null,\n                // use default string if file data is not provided\n                fileData = fileContents !== undefined ? fileContents :\n                    '\\u20AC\\xEB - There is an exception to every rule. Except this one.',\n                fileDataAsBinaryString = fileContents !== undefined ? fileContents :\n                    '\\xe2\\x82\\xac\\xc3\\xab - There is an exception to every rule. Except this one.';\n\n                function createWriter(fe) {\n                    fileEntry = fe;\n                    fileEntry.createWriter(writeFile, failed.bind(null, done, 'fileEntry.createWriter - Error reading file: ' + fileName));\n                }\n\n                // writes file and reads it back in\n                function writeFile(writer) {\n                    writer.onwriteend = function () {\n                        fileEntry.file(function (f) {\n                            callback(fileEntry, f, fileData, fileDataAsBinaryString);\n                        }, failed.bind(null, done, 'writer.onwriteend - Error writing data on file: ' + fileName));\n                    };\n                    writer.write(fileData);\n                }\n\n                fileData += writeBinary ? 'bin:\\x01\\x00' : '';\n                fileDataAsBinaryString += writeBinary ? 'bin:\\x01\\x00' : '';\n                // create a file, write to it, and read it in again\n                createFile(fileName, createWriter, failed.bind(null, done, 'createFile - Error creating file: ' + fileName));\n            }\n            function runReaderTest(funcName, writeBinary, done, progressFunc, verifierFunc, sliceStart, sliceEnd, fileContents) {\n                writeDummyFile(writeBinary, function (fileEntry, file, fileData, fileDataAsBinaryString) {\n                    var verifier = function (evt) {\n                        expect(evt).toBeDefined();\n                        verifierFunc(evt, fileData, fileDataAsBinaryString);\n                    };\n                    var reader = new FileReader();\n                    reader.onprogress = progressFunc;\n                    reader.onload = verifier;\n                    reader.onerror = failed.bind(null, done, 'reader.onerror - Error reading file: ' + file + ' using function: ' + funcName);\n                    if (sliceEnd !== undefined) {\n                        // 'type' is specified so that is will be preserved in the resulting file:\n                        // http://www.w3.org/TR/FileAPI/#slice-method-algo -> \"6.4.1. The slice method\" -> 4. A), 6. c)\n                        file = file.slice(sliceStart, sliceEnd, file.type);\n                    } else if (sliceStart !== undefined) {\n                        file = file.slice(sliceStart, file.size, file.type);\n                    }\n                    reader[funcName](file);\n                }, done, fileContents);\n            }\n            function arrayBufferEqualsString(ab, str) {\n                var buf = new Uint8Array(ab);\n                var match = buf.length == str.length;\n                for (var i = 0; match && i < buf.length; i++) {\n                    match = buf[i] == str.charCodeAt(i);\n                }\n                return match;\n            }\n            it(\"file.spec.84 should read file properly, readAsText\", function (done) {\n                runReaderTest('readAsText', false, done, null, function (evt, fileData, fileDataAsBinaryString) {\n                    expect(evt.target.result).toBe(fileData);\n                    done();\n                });\n            });\n            it(\"file.spec.84.1 should read JSON file properly, readAsText\", function (done) {\n                var testObject = {key1: \"value1\", key2: 2};\n                runReaderTest('readAsText', false, done, null, function (evt, fileData, fileDataAsBinaryString) {\n                    expect(evt.target.result).toEqual(JSON.stringify(testObject));\n                    done();\n                }, undefined, undefined, JSON.stringify(testObject));\n            });\n            it(\"file.spec.85 should read file properly, Data URI\", function (done) {\n                runReaderTest('readAsDataURL', true, done, null, function (evt, fileData, fileDataAsBinaryString) {\n                    /* `readAsDataURL` function is supported, but the mediatype in Chrome depends on entry name extension,\n                        mediatype in IE is always empty (which is the same as `text-plain` according the specification),\n                        the mediatype in Firefox is always `application/octet-stream`.\n                        For example, if the content is `abcdefg` then Firefox returns `data:application/octet-stream;base64,YWJjZGVmZw==`,\n                        IE returns `data:;base64,YWJjZGVmZw==`, Chrome returns `data:<mediatype depending on extension of entry name>;base64,YWJjZGVmZw==`. */\n                    expect(evt.target.result).toBeDataUrl();\n\n                    //The atob function it is completely ignored during mobilespec execution, besides the returned object: evt\n                    //it is encoded and the atob function is aimed to decode a string. Even with btoa (encode) the function it gets stucked\n                    //because of the Unicode characters that contains the fileData object.\n                    //Issue reported at JIRA with all the details: CB-7095\n\n                    //expect(evt.target.result.slice(23)).toBe(atob(fileData));\n\n                    done();\n                });\n            });\n            it(\"file.spec.86 should read file properly, readAsBinaryString\", function (done) {\n                if (isIE) {\n                    /*`readAsBinaryString` function is not supported by IE and has not the stub.*/\n                    pending();\n                }\n\n                runReaderTest('readAsBinaryString', true, done, null, function (evt, fileData, fileDataAsBinaryString) {\n                    expect(evt.target.result).toBe(fileDataAsBinaryString);\n                    done();\n                });\n            });\n            it(\"file.spec.87 should read file properly, readAsArrayBuffer\", function (done) {\n                // Skip test if ArrayBuffers are not supported (e.g.: Android 2.3).\n                if (typeof window.ArrayBuffer == 'undefined') {\n                    expect(true).toFailWithMessage('Platform does not supported this feature');\n                    done();\n                }\n                runReaderTest('readAsArrayBuffer', true, done, null, function (evt, fileData, fileDataAsBinaryString) {\n                    expect(arrayBufferEqualsString(evt.target.result, fileDataAsBinaryString)).toBe(true);\n                    done();\n                });\n            });\n            it(\"file.spec.88 should read sliced file: readAsText\", function (done) {\n                runReaderTest('readAsText', false, done, null, function (evt, fileData, fileDataAsBinaryString) {\n                    expect(evt.target.result).toBe(fileDataAsBinaryString.slice(10, 40));\n                    done();\n                }, 10, 40);\n            });\n            it(\"file.spec.89 should read sliced file: slice past eof\", function (done) {\n                runReaderTest('readAsText', false, done, null, function (evt, fileData, fileDataAsBinaryString) {\n                    expect(evt.target.result).toBe(fileData.slice(-5, 9999));\n                    done();\n                }, -5, 9999);\n            });\n            it(\"file.spec.90 should read sliced file: slice to eof\", function (done) {\n                runReaderTest('readAsText', false, done, null, function (evt, fileData, fileDataAsBinaryString) {\n                    expect(evt.target.result).toBe(fileData.slice(-5));\n                    done();\n                }, -5);\n            });\n            it(\"file.spec.91 should read empty slice\", function (done) {\n                runReaderTest('readAsText', false, done, null, function (evt, fileData, fileDataAsBinaryString) {\n                    expect(evt.target.result).toBe('');\n                    done();\n                }, 0, 0);\n            });\n            it(\"file.spec.92 should read sliced file properly, readAsDataURL\", function (done) {\n                runReaderTest('readAsDataURL', true, done, null, function (evt, fileData, fileDataAsBinaryString) {\n                    /* `readAsDataURL` function is supported, but the mediatype in Chrome depends on entry name extension,\n                        mediatype in IE is always empty (which is the same as `text-plain` according the specification),\n                        the mediatype in Firefox is always `application/octet-stream`.\n                        For example, if the content is `abcdefg` then Firefox returns `data:application/octet-stream;base64,YWJjZGVmZw==`,\n                        IE returns `data:;base64,YWJjZGVmZw==`, Chrome returns `data:<mediatype depending on extension of entry name>;base64,YWJjZGVmZw==`. */\n                    expect(evt.target.result).toBeDataUrl();\n\n                    //The atob function it is completely ignored during mobilespec execution, besides the returned object: evt\n                    //it is encoded and the atob function is aimed to decode a string. Even with btoa (encode) the function it gets stucked\n                    //because of the Unicode characters that contains the fileData object.\n                    //Issue reported at JIRA with all the details: CB-7095\n\n                    //expect(evt.target.result.slice(23)).toBe(atob(fileDataAsBinaryString.slice(10, -3)));\n\n                    done();\n                }, 10, -3);\n            });\n            it(\"file.spec.93 should read sliced file properly, readAsBinaryString\", function (done) {\n                if (isIE) {\n                    /*`readAsBinaryString` function is not supported by IE and has not the stub.*/\n                    pending();\n                }\n\n                runReaderTest('readAsBinaryString', true, done, null, function (evt, fileData, fileDataAsBinaryString) {\n                    expect(evt.target.result).toBe(fileDataAsBinaryString.slice(-10, -5));\n                    done();\n                }, -10, -5);\n            });\n            it(\"file.spec.94 should read sliced file properly, readAsArrayBuffer\", function (done) {\n                // Skip test if ArrayBuffers are not supported (e.g.: Android 2.3).\n                if (typeof window.ArrayBuffer == 'undefined') {\n                    expect(true).toFailWithMessage('Platform does not supported this feature');\n                    done();\n                }\n                runReaderTest('readAsArrayBuffer', true, done, null, function (evt, fileData, fileDataAsBinaryString) {\n                    expect(arrayBufferEqualsString(evt.target.result, fileDataAsBinaryString.slice(0, -1))).toBe(true);\n                    done();\n                }, 0, -1);\n            });\n            it(\"file.spec.94.5 should read large file in multiple chunks, readAsArrayBuffer\", function (done) {\n                // Skip test if ArrayBuffers are not supported (e.g.: Android 2.3).\n                if (typeof window.ArrayBuffer == 'undefined') {\n                    expect(true).toFailWithMessage('Platform does not supported this feature');\n                    done();\n                }\n\n                var largeText = \"\";\n                for (var i = 0; i < 1000; i++) {\n                    largeText += \"Test \" + i + \"\\n\";\n                }\n\n                // Set the chunk size so that the read will take 5 chunks\n                FileReader.READ_CHUNK_SIZE = Math.floor(largeText.length / 4) + 1;\n\n                var chunkCount = 0;\n                var lastProgressValue = -1;\n                var progressFunc = function (evt) {\n                    expect(evt.loaded).toBeDefined();\n                    expect(evt.total).toBeDefined();\n\n                    expect(evt.total >= largeText.length).toBe(true);\n                    expect(evt.total <= largeText.length + 5).toBe(true);\n                    expect(evt.loaded > lastProgressValue).toBe(true);\n                    expect(evt.loaded <= evt.total).toBe(true);\n\n                    lastProgressValue = evt.loaded;\n                    chunkCount++;\n                };\n\n                runReaderTest(\n                    'readAsArrayBuffer', true, done, progressFunc,\n                    function (evt, fileData, fileDataAsBinaryString) {\n                        expect(arrayBufferEqualsString(evt.target.result, fileDataAsBinaryString.slice(0, -1))).toBe(true);\n                        expect(lastProgressValue >= largeText.length).toBe(true);\n                        expect(lastProgressValue <= largeText.length + 5).toBe(true);\n                        expect(chunkCount).toBe(5);\n                        done();\n                    },\n                    0, -1, largeText);\n            });\n       });\n        //Read method\n        describe('FileWriter', function () {\n            it(\"file.spec.95 should have correct methods\", function (done) {\n                // retrieve a FileWriter object\n                var fileName = \"writer.methods\";\n                // FileWriter\n                root.getFile(fileName, {\n                    create : true\n                }, function (fileEntry) {\n                    fileEntry.createWriter(function (writer) {\n                        expect(writer).toBeDefined();\n                        expect(typeof writer.write).toBe('function');\n                        expect(typeof writer.seek).toBe('function');\n                        expect(typeof writer.truncate).toBe('function');\n                        expect(typeof writer.abort).toBe('function');\n                        // cleanup\n                        deleteFile(fileName, done);\n                    }, failed.bind(null, done, 'fileEntry.createWriter - Error creating writer using fileEntry: ' + fileEntry.name));\n                }, failed.bind(null, done, 'root.getFile - Error creating file: ' + fileName));\n            });\n            it(\"file.spec.96 should be able to write and append to file, createWriter\", function (done) {\n                var fileName = \"writer.append.createWriter\", // file content\n                content = \"There is an exception to every rule.\", // for checkin file length\n                exception = \" Except this one.\",\n                length = content.length;\n                // create file, then write and append to it\n                createFile(fileName, function (fileEntry) {\n                    // writes initial file content\n                    fileEntry.createWriter(function (writer) {\n                        //Verifiers declaration\n                        function verifier(evt) {\n                            expect(writer.length).toBe(length);\n                            expect(writer.position).toBe(length);\n                            // Append some more data\n                            writer.onwriteend = secondVerifier;\n                            length += exception.length;\n                            writer.seek(writer.length);\n                            writer.write(exception);\n                        }\n                        function secondVerifier(evt) {\n                            expect(writer.length).toBe(length);\n                            expect(writer.position).toBe(length);\n                            var reader = new FileReader();\n                            reader.onloadend = thirdVerifier;\n                            reader.onerror = failed.bind(null, done, 'reader.onerror - Error reading file: ' + fileName);\n                            fileEntry.file(function(f){reader.readAsText(f);});\n                        }\n                        function thirdVerifier(evt) {\n                            expect(evt.target.result).toBe(content+exception);\n                            // cleanup\n                            deleteFile(fileName, done);\n                        }\n\n                        //Write process\n                        writer.onwriteend = verifier;\n                        writer.write(content);\n                    }, failed.bind(null, done, 'fileEntry.createWriter - Error creating writer using fileEntry: ' + fileEntry.name));\n                }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName));\n            });\n            it(\"file.spec.97 should be able to write and append to file, File object\", function (done) {\n                var fileName = \"writer.append.File\", // file content\n                content = \"There is an exception to every rule.\", // for checkin file length\n                exception = \" Except this one.\",\n                length = content.length;\n                root.getFile(fileName, {\n                    create : true\n                }, function (fileEntry) {\n                    fileEntry.createWriter(function (writer) {\n                        //Verifiers declaration\n                        function verifier() {\n                            expect(writer.length).toBe(length);\n                            expect(writer.position).toBe(length);\n                            // Append some more data\n                            writer.onwriteend = secondVerifier;\n                            length += exception.length;\n                            writer.seek(writer.length);\n                            writer.write(exception);\n                        }\n                        function secondVerifier() {\n                            expect(writer.length).toBe(length);\n                            expect(writer.position).toBe(length);\n                            var reader = new FileReader();\n                            reader.onloadend = thirdVerifier;\n                            reader.onerror = failed.bind(null, done, 'reader.onerror - Error reading file: ' + fileName);\n                            fileEntry.file(function(f){reader.readAsText(f);});\n                        }\n                        function thirdVerifier(evt) {\n                            expect(evt.target.result).toBe(content+exception);\n                            // cleanup\n                            deleteFile(fileName, done);\n                        }\n\n                        //Write process\n                        writer.onwriteend = verifier;\n                        writer.write(content);\n                    }, failed.bind(null, done, 'fileEntry.createWriter - Error creating writer using fileEntry: ' + fileEntry.name));\n                }, failed.bind(null, done, 'root.getFile - Error creating file: ' + fileName));\n            });\n            it(\"file.spec.98 should be able to seek to the middle of the file and write more data than file.length\", function (done) {\n                var fileName = \"writer.seek.write\", // file content\n                content = \"This is our sentence.\", // for checking file length\n                exception = \"newer sentence.\",\n                length = content.length;\n                // create file, then write and append to it\n                createFile(fileName, function (fileEntry) {\n                    fileEntry.createWriter(function (writer) {\n                        //Verifiers declaration\n                        function verifier(evt) {\n                            expect(writer.length).toBe(length);\n                            expect(writer.position).toBe(length);\n                            // Append some more data\n                            writer.onwriteend = secondVerifier;\n                            length = 12 + exception.length;\n                            writer.seek(12);\n                            writer.write(exception);\n                        }\n                        function secondVerifier(evt) {\n                            expect(writer.length).toBe(length);\n                            expect(writer.position).toBe(length);\n                            var reader = new FileReader();\n                            reader.onloadend = thirdVerifier;\n                            reader.onerror = failed.bind(null, done, 'reader.onerror - Error reading file: ' + fileName);\n                            fileEntry.file(function(f){reader.readAsText(f);});\n                        }\n                        function thirdVerifier(evt) {\n                            expect(evt.target.result).toBe(content.substr(0,12)+exception);\n                            // cleanup\n                            deleteFile(fileName, done);\n                        }\n\n                        //Write process\n                        writer.onwriteend = verifier;\n                        writer.write(content);\n                    }, failed.bind(null, done, 'fileEntry.createWriter - Error creating writer using fileEntry: ' + fileEntry.name));\n                }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName));\n            });\n            it(\"file.spec.99 should be able to seek to the middle of the file and write less data than file.length\", function (done) {\n                if (isChrome) {\n                    /* Chrome (re)writes as follows: \"This is our sentence.\" -> \"This is new.sentence.\",\n                       i.e. the length is not being changed from content.length and writer length will be equal 21 */\n                    pending();\n                }\n\n                var fileName = \"writer.seek.write2\", // file content\n                content = \"This is our sentence.\", // for checking file length\n                exception = \"new.\",\n                length = content.length;\n                // create file, then write and append to it\n                createFile(fileName, function (fileEntry) {\n                    fileEntry.createWriter(function (writer) {\n                        // Verifiers declaration\n                        function verifier(evt) {\n                            expect(writer.length).toBe(length);\n                            expect(writer.position).toBe(length);\n                            // Append some more data\n                            writer.onwriteend = secondVerifier;\n                            length = 8 + exception.length;\n                            writer.seek(8);\n                            writer.write(exception);\n                        }\n                        function secondVerifier(evt) {\n                            expect(writer.length).toBe(length);\n                            expect(writer.position).toBe(length);\n                            var reader = new FileReader();\n                            reader.onloadend = thirdVerifier;\n                            reader.onerror = failed.bind(null, done, 'reader.onerror - Error reading file: ' + fileName);\n                            fileEntry.file(function(f){reader.readAsText(f);});\n                        }\n                        function thirdVerifier(evt) {\n                            expect(evt.target.result).toBe(content.substr(0,8)+exception);\n                            // cleanup\n                            deleteFile(fileName, done);\n                        }\n\n                        //Write process\n                        writer.onwriteend = verifier;\n                        writer.write(content);\n                    }, failed.bind(null, done, 'fileEntry.createWriter - Error creating writer using fileEntry: ' + fileEntry.name));\n                }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName));\n            });\n            it(\"file.spec.100 should be able to write XML data\", function (done) {\n                var fileName = \"writer.xml\", // file content\n                content = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n<test prop=\"ack\">\\nData\\n</test>\\n', // for testing file length\n                length = content.length;\n                // creates file, then write XML data\n                createFile(fileName, function (fileEntry) {\n                    fileEntry.createWriter(function (writer) {\n                        //Verifier content\n                        var verifier = function (evt) {\n                            expect(writer.length).toBe(length);\n                            expect(writer.position).toBe(length);\n                            // cleanup\n                            deleteFile(fileName, done);\n                        };\n                        //Write process\n                        writer.onwriteend = verifier;\n                        writer.write(content);\n                    }, failed.bind(null, done, 'fileEntry.createWriter - Error creating writer using fileEntry: ' + fileEntry.name));\n                }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName));\n            });\n            it(\"file.spec.101 should be able to write JSON data\", function (done) {\n                var fileName = \"writer.json\", // file content\n                content = '{ \"name\": \"Guy Incognito\", \"email\": \"here@there.com\" }', // for testing file length\n                length = content.length;\n                // creates file, then write JSON content\n                createFile(fileName, function (fileEntry) {\n                    fileEntry.createWriter(function (writer) {\n                        //Verifier declaration\n                        var verifier = function (evt) {\n                            expect(writer.length).toBe(length);\n                            expect(writer.position).toBe(length);\n                            // cleanup\n                            deleteFile(fileName, done);\n                        };\n                        //Write process\n                        writer.onwriteend = verifier;\n                        writer.write(content);\n                    }, failed.bind(null, done, 'fileEntry.createWriter - Error creating writer using fileEntry: ' + fileEntry.name));\n                }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName));\n            });\n            it(\"file.spec.102 should be able to seek\", function (done) {\n                var fileName = \"writer.seek\", // file content\n                content = \"There is an exception to every rule. Except this one.\", // for testing file length\n                length = content.length;\n                // creates file, then write JSON content\n                createFile(fileName, function (fileEntry) {\n                    // writes file content and tests writer.seek\n                    fileEntry.createWriter(function (writer) {\n                        //Verifier declaration\n                        var verifier = function () {\n                            expect(writer.position).toBe(length);\n                            writer.seek(-5);\n                            expect(writer.position).toBe(length - 5);\n                            writer.seek(length + 100);\n                            expect(writer.position).toBe(length);\n                            writer.seek(10);\n                            expect(writer.position).toBe(10);\n                            // cleanup\n                            deleteFile(fileName, done);\n                        };\n                        //Write process\n                        writer.onwriteend = verifier;\n                        writer.seek(-100);\n                        expect(writer.position).toBe(0);\n                        writer.write(content);\n                    }, failed.bind(null, done, 'fileEntry.createWriter - Error creating writer using fileEntry: ' + fileEntry.name));\n                }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName));\n            });\n            it(\"file.spec.103 should be able to truncate\", function (done) {\n                if (isIndexedDBShim) {\n                    /* `abort` and `truncate` functions are not supported (Firefox, IE) */\n                    pending();\n                }\n\n                var fileName = \"writer.truncate\",\n                content = \"There is an exception to every rule. Except this one.\";\n                // creates file, writes to it, then truncates it\n                createFile(fileName, function (fileEntry) {\n                    fileEntry.createWriter(function (writer) {\n                        // Verifier declaration\n                        var verifier = function () {\n                            expect(writer.length).toBe(36);\n                            expect(writer.position).toBe(36);\n                            // cleanup\n                            deleteFile(fileName, done);\n                        };\n                        //Write process\n                        writer.onwriteend = function () {\n                            //Truncate process after write\n                            writer.onwriteend = verifier;\n                            writer.truncate(36);\n                        };\n                        writer.write(content);\n                    }, failed.bind(null, done, 'fileEntry.createWriter - Error creating writer using fileEntry: ' + fileEntry.name));\n                }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName));\n            });\n            it(\"file.spec.104 should be able to write binary data from an ArrayBuffer\", function (done) {\n                // Skip test if ArrayBuffers are not supported (e.g.: Android 2.3).\n                if (typeof window.ArrayBuffer == 'undefined') {\n                    expect(true).toFailWithMessage('Platform does not supported this feature');\n                    done();\n                    return;\n                }\n                var fileName = \"bufferwriter.bin\", // file content\n                data = new ArrayBuffer(32),\n                dataView = new Int8Array(data), // for verifying file length\n                length = 32;\n                for (var i = 0; i < dataView.length; i++) {\n                    dataView[i] = i;\n                }\n                // creates file, then write content\n                createFile(fileName, function (fileEntry) {\n                    // writes file content\n                    fileEntry.createWriter(function (writer) {\n                        //Verifier declaration\n                        var verifier = function () {\n                            expect(writer.length).toBe(length);\n                            expect(writer.position).toBe(length);\n                            // cleanup\n                            deleteFile(fileName, done);\n                        };\n                        //Write process\n                        writer.onwriteend = verifier;\n                        writer.write(data);\n                    }, failed.bind(null, done, 'fileEntry.createWriter - Error creating writer using fileEntry: ' + fileEntry.name));\n                }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName));\n            });\n            it(\"file.spec.105 should be able to write binary data from a Blob\", function (done) {\n                // Skip test if Blobs are not supported (e.g.: Android 2.3).\n                if ((typeof window.Blob == 'undefined' && typeof window.WebKitBlobBuilder == 'undefined') || typeof window.ArrayBuffer == 'undefined') {\n                    expect(true).toFailWithMessage('Platform does not supported this feature');\n                    done();\n                    return;\n                }\n                var fileName = \"blobwriter.bin\", // file content\n                data = new ArrayBuffer(32),\n                dataView = new Int8Array(data),\n                blob, // for verifying file length\n                length = 32;\n                for (var i = 0; i < dataView.length; i++) {\n                    dataView[i] = i;\n                }\n                try {\n                    // Mobile Safari: Use Blob constructor\n                    blob = new Blob([data], {\n                            \"type\" : \"application/octet-stream\"\n                        });\n                } catch (e) {\n                    if (window.WebKitBlobBuilder) {\n                        // Android Browser: Use deprecated BlobBuilder\n                        var builder = new WebKitBlobBuilder();\n                        builder.append(data);\n                        blob = builder.getBlob('application/octet-stream');\n                    } else {\n                        // We have no way defined to create a Blob, so fail\n                        fail();\n                    }\n                }\n                if (typeof blob !== 'undefined') {\n                    // creates file, then write content\n                    createFile(fileName, function (fileEntry) {\n                        fileEntry.createWriter(function (writer) {\n                            //Verifier declaration\n                            var verifier = function () {\n                                expect(writer.length).toBe(length);\n                                expect(writer.position).toBe(length);\n                                // cleanup\n                                deleteFile(fileName, done);\n                            };\n                            //Write process\n                            writer.onwriteend = verifier;\n                            writer.write(blob);\n                        }, failed.bind(null, done, 'fileEntry.createWriter - Error creating writer using fileEntry: ' + fileEntry.name));\n                    }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName));\n                }\n            });\n            it(\"file.spec.106 should be able to write a File to a FileWriter\", function (done) {\n                var dummyFileName = 'dummy.txt',\n                outputFileName = 'verify.txt',\n                dummyFileText = 'This text should be written to two files',\n                verifier = function (outputFileWriter) {\n                    expect(outputFileWriter.length).toBe(dummyFileText.length);\n                    expect(outputFileWriter.position).toBe(dummyFileText.length);\n                    deleteFile(outputFileName, done);\n                },\n                writeFile = function (fileName, fileData, win) {\n                    var theWriter,\n                    write_file = function (fileEntry) {\n                        // writes file content to new file\n                        fileEntry.createWriter(function (writer) {\n                            theWriter = writer;\n                            writer.onwriteend = function (ev) {\n                                if (typeof fileData.length !== \"undefined\") {\n                                    expect(theWriter.length).toBe(fileData.length);\n                                    expect(theWriter.position).toBe(fileData.length);\n                                }\n                                win(theWriter);\n                            };\n                            writer.onerror = failed.bind(null, done, 'writer.onerror - Error writing content on file: ' + fileName);\n                            writer.write(fileData);\n                        }, failed.bind(null, done, 'fileEntry.createWriter - Error creating writer using fileEntry: ' + fileEntry.name));\n                    };\n                    createFile(fileName, write_file, failed.bind(null, done, 'createFile - Error creating file: ' + fileName));\n                },\n                openFile = function (fileName, callback) {\n                    root.getFile(fileName, {\n                        create : false\n                    }, function (fileEntry) {\n                        fileEntry.file(callback, failed.bind(null, done, 'fileEntry.file - Error reading file using fileEntry: ' + fileEntry.name));\n                    }, failed.bind(null, done, 'root.getFile - Error getting file: ' + fileName));\n                };\n                writeFile(dummyFileName, dummyFileText, function (dummyFileWriter) {\n                    openFile(dummyFileName, function (file) {\n                        writeFile(outputFileName, file, verifier);\n                    });\n                });\n            });\n            it(\"file.spec.107 should be able to write a sliced File to a FileWriter\", function (done) {\n                var dummyFileName = 'dummy2.txt',\n                outputFileName = 'verify2.txt',\n                dummyFileText = 'This text should be written to two files',\n                verifier = function (outputFileWriter) {\n                    expect(outputFileWriter.length).toBe(10);\n                    expect(outputFileWriter.position).toBe(10);\n                    deleteFile(outputFileName, done);\n                },\n                writeFile = function (fileName, fileData, win) {\n                    var theWriter,\n                    write_file = function (fileEntry) {\n                        // writes file content to new file\n                        fileEntry.createWriter(function (writer) {\n                            theWriter = writer;\n                            writer.onwriteend = function (ev) {\n                                if (typeof fileData.length !== \"undefined\") {\n                                    expect(theWriter.length).toBe(fileData.length);\n                                    expect(theWriter.position).toBe(fileData.length);\n                                }\n                                win(theWriter);\n                            };\n                            writer.onerror = failed.bind(null, done, 'writer.onerror - Error writing content on file: ' + fileName);\n                            writer.write(fileData);\n                        }, failed.bind(null, done, 'fileEntry.createWriter - Error creating writer using fileEntry: ' + fileEntry.name));\n                    };\n                    createFile(fileName, write_file, failed.bind(null, done, 'createFile - Error creating file: ' + fileName));\n                },\n                openFile = function (fileName, callback) {\n                    root.getFile(fileName, {\n                        create : false\n                    }, function (fileEntry) {\n                        fileEntry.file(callback, failed.bind(null, done, 'fileEntry.file - Error reading file using fileEntry: ' + fileEntry.name));\n                    }, failed.bind(null, done, 'root.getFile - Error getting file: ' + fileName));\n                };\n                writeFile(dummyFileName, dummyFileText, function (dummyFileWriter) {\n                    openFile(dummyFileName, function (file) {\n                        writeFile(outputFileName, file.slice(10, 20), verifier);\n                    });\n                });\n            });\n            it(\"file.spec.108 should be able to write binary data from a File\", function (done) {\n                // Skip test if Blobs are not supported (e.g.: Android 2.3).\n                if (typeof window.Blob == 'undefined' && typeof window.WebKitBlobBuilder == 'undefined') {\n                    expect(true).toFailWithMessage('Platform does not supported this feature');\n                    done();\n                }\n                var dummyFileName = \"blobwriter.bin\",\n                outputFileName = 'verify.bin', // file content\n                data = new ArrayBuffer(32),\n                dataView = new Int8Array(data),\n                blob, // for verifying file length\n                length = 32,\n                verifier = function (outputFileWriter) {\n                    expect(outputFileWriter.length).toBe(length);\n                    expect(outputFileWriter.position).toBe(length);\n                    // cleanup\n                    deleteFile(outputFileName);\n                    done();\n                },\n                writeFile = function (fileName, fileData, win) {\n                    var theWriter,\n                    write_file = function (fileEntry) {\n                        // writes file content to new file\n                        fileEntry.createWriter(function (writer) {\n                            theWriter = writer;\n                            writer.onwriteend = function (ev) {\n                                if (typeof fileData.length !== \"undefined\") {\n                                    expect(theWriter.length).toBe(fileData.length);\n                                    expect(theWriter.position).toBe(fileData.length);\n                                }\n                                win(theWriter);\n                            };\n                            writer.onerror = failed.bind(null, done, 'writer.onerror - Error writing content on file: ' + fileName);\n                            writer.write(fileData);\n                        }, failed.bind(null, done, 'fileEntry.createWriter - Error creating writer using fileEntry: ' + fileEntry.name));\n                    };\n                    createFile(fileName, write_file, failed.bind(null, done, 'createFile - Error creating file: ' + fileName));\n                },\n                openFile = function (fileName, callback) {\n                    root.getFile(fileName, {\n                        create : false\n                    }, function (fileEntry) {\n                        fileEntry.file(callback, failed.bind(null, done, 'fileEntry.file - Error reading file using fileEntry: ' + fileEntry.name));\n                    }, failed.bind(null, done, 'root.getFile - Error getting file: ' + fileName));\n                };\n                for (var i = 0; i < dataView.length; i++) {\n                    dataView[i] = i;\n                }\n                try {\n                    // Mobile Safari: Use Blob constructor\n                    blob = new Blob([data], {\n                            \"type\" : \"application/octet-stream\"\n                        });\n                } catch (e) {\n                    if (window.WebKitBlobBuilder) {\n                        // Android Browser: Use deprecated BlobBuilder\n                        var builder = new WebKitBlobBuilder();\n                        builder.append(data);\n                        blob = builder.getBlob('application/octet-stream');\n                    } else {\n                        // We have no way defined to create a Blob, so fail\n                        fail();\n                    }\n                }\n                if (typeof blob !== 'undefined') {\n                    // creates file, then write content\n                    writeFile(dummyFileName, blob, function (dummyFileWriter) {\n                        openFile(dummyFileName, function (file) {\n                            writeFile(outputFileName, file, verifier);\n                        });\n                    });\n                }\n            });\n        });\n        //FileWritter\n        describe('Backwards compatibility', function () {\n            /* These specs exist to test that the File plugin can still recognize file:///\n             * URLs, and can resolve them to FileEntry and DirectoryEntry objects.\n             * They rely on an undocumented interface to File which provides absolute file\n             * paths, which are not used internally anymore.\n             * If that interface is not present, then these tests will silently succeed.\n             */\n            it(\"file.spec.109 should be able to resolve a file:/// URL\", function (done) {\n                var localFilename = 'file.txt';\n                var originalEntry;\n                root.getFile(localFilename, {\n                    create : true\n                }, function (entry) {\n                    originalEntry = entry;\n                    /* This is an undocumented interface to File which exists only for testing\n                     * backwards compatibilty. By obtaining the raw filesystem path of the download\n                     * location, we can pass that to ft.download() to make sure that previously-stored\n                     * paths are still valid.\n                     */\n                    cordova.exec(function (localPath) {\n                        window.resolveLocalFileSystemURL(\"file://\" + encodeURI(localPath), function (fileEntry) {\n                            expect(fileEntry.toURL()).toEqual(originalEntry.toURL());\n                            // cleanup\n                            deleteFile(localFilename);\n                            done();\n                        }, failed.bind(null, done, 'window.resolveLocalFileSystemURL - Error resolving URI: file://' + encodeURI(localPath)));\n                    }, done, 'File', '_getLocalFilesystemPath', [entry.toURL()]);\n                }, failed.bind(null, done, 'root.getFile - Error creating file: ' + localFilename));\n            });\n        });\n        //Backwards Compatibility\n        describe('Parent References', function () {\n            /* These specs verify that paths with parent references i(\"..\") in them\n             * work correctly, and do not cause the application to crash.\n             */\n            it(\"file.spec.110 should not throw exception resolving parent refefences\", function (done) {\n                /* This is a direct copy of file.spec.9, with the filename changed, * as reported in CB-5721.\n                 */\n                var fileName = \"resolve.file.uri\";\n                var dirName = \"resolve.dir.uri\";\n                // create a new file entry\n                createDirectory(dirName, function () {\n                    createFile(dirName+\"/../\" + fileName, function (entry) {\n                        // lookup file system entry\n                        window.resolveLocalFileSystemURL(entry.toURL(), function (fileEntry) {\n                            expect(fileEntry).toBeDefined();\n                            expect(fileEntry.name).toCanonicallyMatch(fileName);\n                            // cleanup\n                            deleteEntry(fileName, done);\n                        }, failed.bind(null, done, 'window.resolveLocalFileSystemURL - Error resolving URI: ' + entry.toURL()));\n                    }, failed.bind(null, done, 'createFile - Error creating file: ../' + fileName));\n                }, failed.bind(null, done, 'createDirectory - Error creating directory: ' + dirName));\n            });\n            it(\"file.spec.111 should not traverse above above the root directory\", function (done) {\n                var fileName = \"traverse.file.uri\";\n                // create a new file entry\n                createFile(fileName, function (entry) {\n                    // lookup file system entry\n                    root.getFile('../' + fileName, {\n                        create : false\n                    }, function (fileEntry) {\n                        // Note: we expect this to still resolve, as the correct behaviour is to ignore the ../, not to fail out.\n                        expect(fileEntry).toBeDefined();\n                        expect(fileEntry.name).toBe(fileName);\n                        expect(fileEntry.fullPath).toCanonicallyMatch(root.fullPath +'/' + fileName);\n                        // cleanup\n                        deleteEntry(fileName, done);\n                    }, failed.bind(null, done, 'root.getFile - Error getting file: ../' + fileName));\n                }, failed.bind(null, done, 'createFile - Error creating file: ../' + fileName));\n            });\n            it(\"file.spec.112 should traverse above above the current directory\", function (done) {\n                var fileName = \"traverse2.file.uri\",\n                dirName = \"traverse2.subdir\";\n                // create a new directory and a file entry\n                createFile(fileName, function () {\n                    createDirectory(dirName, function (entry) {\n                        // lookup file system entry\n                        entry.getFile('../' + fileName, {\n                            create : false\n                        }, function (fileEntry) {\n                            expect(fileEntry).toBeDefined();\n                            expect(fileEntry.name).toBe(fileName);\n                            expect(fileEntry.fullPath).toCanonicallyMatch('/' + fileName);\n                            // cleanup\n                            deleteEntry(fileName, function () {\n                                deleteEntry(dirName, done);\n                            });\n                        }, failed.bind(null, done, 'entry.getFile - Error getting file: ' + fileName + ' recently created above: ' + dirName));\n                    }, failed.bind(null, done, 'createDirectory - Error creating directory: ' + dirName));\n                }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName));\n            });\n            it(\"file.spec.113 getFile: get Entry should error for missing file above root directory\", function (done) {\n                var fileName = \"../missing.file\";\n                // create:false, exclusive:false, file does not exist\n                root.getFile(fileName, {\n                    create : false\n                }, succeed.bind(null, done, 'root.getFile - Unexpected success callback, it should not locate nonexistent file: ' + fileName), function (error) {\n                    expect(error).toBeDefined();\n                    expect(error).toBeFileError(FileError.NOT_FOUND_ERR);\n                    done();\n                });\n            });\n        });\n        //Parent References\n        describe('toNativeURL interface', function () {\n            /* These specs verify that FileEntries have a toNativeURL method\n             * which appears to be sane.\n             */\n            var pathExpect = cordova.platformId === 'windowsphone' ? \"//nativ\" : \"file://\";\n            if (isChrome) {\n                pathExpect = 'filesystem:file://';\n            }\n            it(\"file.spec.114 fileEntry should have a toNativeURL method\", function (done) {\n                var fileName = \"native.file.uri\";\n                if (isWindows) {\n                    var rootPath = root.fullPath;\n                    pathExpect = rootPath.substr(0, rootPath.indexOf(\":\"));\n                }\n                // create a new file entry\n                createFile(fileName, function (entry) {\n                    expect(entry.toNativeURL).toBeDefined();\n                    expect(entry.name).toCanonicallyMatch(fileName);\n                    expect(typeof entry.toNativeURL).toBe('function');\n                    var nativeURL = entry.toNativeURL();\n                    expect(typeof nativeURL).toBe(\"string\");\n                    expect(nativeURL.substring(0, pathExpect.length)).toEqual(pathExpect);\n                    expect(nativeURL.substring(nativeURL.length - fileName.length)).toEqual(fileName);\n                    // cleanup\n                    deleteEntry(fileName, done);\n                }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName));\n            });\n            it(\"file.spec.115 DirectoryReader should return entries with toNativeURL method\", function (done) {\n                var dirName = 'nativeEntries.dir',\n                fileName = 'nativeEntries.file',\n                directory,\n                checkEntries = function (entries) {\n                    expect(entries).toBeDefined();\n                    expect(entries instanceof Array).toBe(true);\n                    expect(entries.length).toBe(1);\n                    expect(entries[0].toNativeURL).toBeDefined();\n                    expect(typeof entries[0].toNativeURL).toBe('function');\n                    var nativeURL = entries[0].toNativeURL();\n                    expect(typeof nativeURL).toBe(\"string\");\n                    expect(nativeURL.substring(0, pathExpect.length)).toEqual(pathExpect);\n                    expect(nativeURL.substring(nativeURL.length - fileName.length)).toEqual(fileName);\n                    // cleanup\n                    directory.removeRecursively(null, null);\n                    done();\n                };\n                // create a new file entry\n                root.getDirectory(dirName, {\n                    create : true\n                }, function (dir) {\n                    directory = dir;\n                    directory.getFile(fileName, {\n                        create : true\n                    }, function (fileEntry) {\n                        var reader = directory.createReader();\n                        reader.readEntries(checkEntries, failed.bind(null, done, 'reader.readEntries - Error reading entries from directory: ' + dirName));\n                    }, failed.bind(null, done, 'directory.getFile - Error creating file: ' + fileName));\n                }, failed.bind(null, done, 'root.getDirectory - Error creating directory: ' + dirName));\n            });\n            it(\"file.spec.116 resolveLocalFileSystemURL should return entries with toNativeURL method\", function (done) {\n                var fileName = \"native.resolve.uri\";\n                // create a new file entry\n                createFile(fileName, function (entry) {\n                    resolveLocalFileSystemURL(entry.toURL(), function (entry) {\n                        expect(entry.toNativeURL).toBeDefined();\n                        expect(entry.name).toCanonicallyMatch(fileName);\n                        expect(typeof entry.toNativeURL).toBe('function');\n                        var nativeURL = entry.toNativeURL();\n                        expect(typeof nativeURL).toBe(\"string\");\n                        expect(nativeURL.substring(0, pathExpect.length)).toEqual(pathExpect);\n                        expect(nativeURL.substring(nativeURL.length - fileName.length)).toEqual(fileName);\n                        // cleanup\n                        deleteEntry(fileName, done);\n                    }, failed.bind(null, done, 'resolveLocalFileSystemURL - Error resolving file URL: ' + entry.toURL()));\n                }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName));\n            });\n        });\n        //toNativeURL interface\n        describe('resolveLocalFileSystemURL on file://', function () {\n            /* These specs verify that window.resolveLocalFileSystemURL works correctly on file:// URLs\n             */\n            it(\"file.spec.117 should not resolve native URLs outside of FS roots\", function (done) {\n                // lookup file system entry\n                window.resolveLocalFileSystemURL(\"file:///this.is.an.invalid.url\", succeed.bind(null, done, 'window.resolveLocalFileSystemURL - Unexpected success callback, it should not resolve invalid URL: file:///this.is.an.invalid.url'), function (error) {\n                    expect(error).toBeDefined();\n                    done();\n                });\n            });\n            it(\"file.spec.118 should not resolve native URLs outside of FS roots\", function (done) {\n                // lookup file system entry\n                window.resolveLocalFileSystemURL(\"file://localhost/this.is.an.invalid.url\", succeed.bind(null, done, 'window.resolveLocalFileSystemURL - Unexpected success callback, it should not resolve invalid URL: file://localhost/this.is.an.invalid.url'), function (error) {\n                    expect(error).toBeDefined();\n                    done();\n                });\n            });\n            it(\"file.spec.119 should not resolve invalid native URLs\", function (done) {\n                // lookup file system entry\n                window.resolveLocalFileSystemURL(\"file://localhost\", succeed.bind(null, done, 'window.resolveLocalFileSystemURL - Unexpected success callback, it should not resolve invalid URL: file://localhost'), function (error) {\n                    expect(error).toBeDefined();\n                    done();\n                });\n            });\n            it(\"file.spec.120 should not resolve invalid native URLs with query strings\", function (done) {\n                // lookup file system entry\n                window.resolveLocalFileSystemURL(\"file://localhost?test/test\", succeed.bind(null, done, 'window.resolveLocalFileSystemURL - Unexpected success callback, it should not resolve invalid URL: file://localhost?test/test'), function (error) {\n                    expect(error).toBeDefined();\n                    done();\n                });\n            });\n            it(\"file.spec.121 should resolve native URLs returned by API\", function (done) {\n                var fileName = \"native.resolve.uri1\";\n                // create a new file entry\n                createFile(fileName, function (entry) {\n                    resolveLocalFileSystemURL(entry.toNativeURL(), function (fileEntry) {\n                        expect(fileEntry.fullPath).toCanonicallyMatch(root.fullPath + \"/\" + fileName);\n                        // cleanup\n                        deleteEntry(fileName, done);\n                    }, failed.bind(null, done, 'resolveLocalFileSystemURL - Error resolving file URL: ' + entry.toNativeURL()));\n                }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName));\n            });\n            it(\"file.spec.122 should resolve native URLs returned by API with localhost\", function (done) {\n                var fileName = \"native.resolve.uri2\";\n                // create a new file entry\n                createFile(fileName, function (entry) {\n                    var url = entry.toNativeURL();\n                    url = url.replace(\"///\", \"//localhost/\");\n                    resolveLocalFileSystemURL(url, function (fileEntry) {\n                        expect(fileEntry.fullPath).toCanonicallyMatch(root.fullPath + \"/\" + fileName);\n                        // cleanup\n                        deleteEntry(fileName, done);\n                    }, failed.bind(null, done, 'resolveLocalFileSystemURL - Error resolving file URL: ' + url));\n                }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName));\n            });\n            it(\"file.spec.123 should resolve native URLs returned by API with query string\", function (done) {\n                var fileName = \"native.resolve.uri3\";\n                // create a new file entry\n                createFile(fileName, function (entry) {\n                    var url = entry.toNativeURL();\n                    url = url + \"?test/test\";\n                    resolveLocalFileSystemURL(url, function (fileEntry) {\n                        expect(fileEntry.fullPath).toCanonicallyMatch(root.fullPath + \"/\" + fileName);\n                        // cleanup\n                        deleteEntry(fileName, done);\n                    }, failed.bind(null, done, 'resolveLocalFileSystemURL - Error resolving file URL: ' + url));\n                }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName));\n            });\n            it(\"file.spec.124 should resolve native URLs returned by API with localhost and query string\", function (done) {\n                var fileName = \"native.resolve.uri4\";\n                // create a new file entry\n                createFile(fileName, function (entry) {\n                    var url = entry.toNativeURL();\n                    url = url.replace(\"///\", \"//localhost/\") + \"?test/test\";\n                    resolveLocalFileSystemURL(url, function (fileEntry) {\n                        expect(fileEntry.fullPath).toCanonicallyMatch(root.fullPath + \"/\" + fileName);\n                        // cleanup\n                        deleteEntry(fileName, done);\n                    }, failed.bind(null, done, 'resolveLocalFileSystemURL - Error resolving file URL: ' + url));\n                }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName));\n            });\n        });\n        //resolveLocalFileSystemURL on file://\n        describe('cross-file-system copy and move', function () {\n            /* These specs verify that Entry.copyTo and Entry.moveTo work correctly\n             * when crossing filesystem boundaries.\n             */\n            it(\"file.spec.125 copyTo: temporary -> persistent\", function (done) {\n                var file1 = \"entry.copy.file1a\",\n                file2 = \"entry.copy.file2a\",\n                sourceEntry,\n                fullPath = joinURL(root.fullPath, file2),\n                validateFile = function (entry) {\n                    // a bit redundant since copy returned this entry already\n                    expect(entry).toBeDefined();\n                    expect(entry.isFile).toBe(true);\n                    expect(entry.isDirectory).toBe(false);\n                    expect(entry.name).toCanonicallyMatch(file2);\n                    expect(entry.fullPath).toCanonicallyMatch(fullPath);\n                    expect(entry.filesystem).toBeDefined();\n                    if (isChrome) {\n                        expect(entry.filesystem.name).toContain(\"Persistent\");\n                    } else {\n                        expect(entry.filesystem.name).toEqual(\"persistent\");\n                    }\n                    // cleanup\n                    deleteEntry(entry.name);\n                    deleteEntry(sourceEntry.name, done);\n                },\n                createSourceAndTransfer = function () {\n                    temp_root.getFile(file1, {\n                        create : true\n                    }, function (entry) {\n                        expect(entry.filesystem).toBeDefined();\n                        if (isChrome) {\n                            expect(entry.filesystem.name).toContain(\"Temporary\");\n                        } else {\n                            expect(entry.filesystem.name).toEqual(\"temporary\");\n                        }\n                        sourceEntry = entry;\n                        // Save for later cleanup\n                        entry.copyTo(persistent_root, file2, validateFile, failed.bind(null, done, 'entry.copyTo - Error copying file: ' + file1 + ' to PERSISTENT root as: ' + file2));\n                    }, failed.bind(null, done, 'temp_root.getFile - Error creating file: ' + file1 + 'at TEMPORAL root'));\n                };\n                // Delete any existing file to start things off\n                persistent_root.getFile(file2, {}, function (entry) {\n                    entry.remove(createSourceAndTransfer, failed.bind(null, done, 'entry.remove - Error removing file: ' + file2));\n                }, createSourceAndTransfer);\n            });\n            it(\"file.spec.126 copyTo: persistent -> temporary\", function (done) {\n                var file1 = \"entry.copy.file1b\",\n                file2 = \"entry.copy.file2b\",\n                sourceEntry,\n                fullPath = joinURL(temp_root.fullPath, file2),\n                validateFile = function (entry) {\n                    expect(entry).toBeDefined();\n                    expect(entry.isFile).toBe(true);\n                    expect(entry.isDirectory).toBe(false);\n                    expect(entry.name).toCanonicallyMatch(file2);\n                    expect(entry.fullPath).toCanonicallyMatch(fullPath);\n                    if (isChrome) {\n                        expect(entry.filesystem.name).toContain(\"Temporary\");\n                    } else {\n                        expect(entry.filesystem.name).toEqual(\"temporary\");\n                    }\n                    // cleanup\n                    deleteEntry(entry.name);\n                    deleteEntry(sourceEntry.name, done);\n                },\n                createSourceAndTransfer = function () {\n                    persistent_root.getFile(file1, {\n                        create : true\n                    }, function (entry) {\n                        expect(entry).toBeDefined();\n                        expect(entry.filesystem).toBeDefined();\n                        if (isChrome) {\n                            expect(entry.filesystem.name).toContain(\"Persistent\");\n                        } else {\n                            expect(entry.filesystem.name).toEqual(\"persistent\");\n                        }\n                        sourceEntry = entry;\n                        // Save for later cleanup\n                        entry.copyTo(temp_root, file2, validateFile, failed.bind(null, done, 'entry.copyTo - Error copying file: ' + file1 + ' to TEMPORAL root as: ' + file2));\n                    }, failed.bind(null, done, 'persistent_root.getFile - Error creating file: ' + file1 + 'at PERSISTENT root'));\n                };\n                // Delete any existing file to start things off\n                temp_root.getFile(file2, {}, function (entry) {\n                    entry.remove(createSourceAndTransfer, failed.bind(null, done, 'entry.remove - Error removing file: ' + file2));\n                }, createSourceAndTransfer);\n            });\n            it(\"file.spec.127 moveTo: temporary -> persistent\", function (done) {\n                var file1 = \"entry.copy.file1a\",\n                file2 = \"entry.copy.file2a\",\n                sourceEntry,\n                fullPath = joinURL(root.fullPath, file2),\n                validateFile = function (entry) {\n                    // a bit redundant since copy returned this entry already\n                    expect(entry).toBeDefined();\n                    expect(entry.isFile).toBe(true);\n                    expect(entry.isDirectory).toBe(false);\n                    expect(entry.name).toCanonicallyMatch(file2);\n                    expect(entry.fullPath).toCanonicallyMatch(fullPath);\n                    expect(entry.filesystem).toBeDefined();\n                    if (isChrome) {\n                        expect(entry.filesystem.name).toContain(\"Persistent\");\n                    } else {\n                        expect(entry.filesystem.name).toEqual(\"persistent\");\n                    }\n                    // cleanup\n                    deleteEntry(entry.name);\n                    deleteEntry(sourceEntry.name, done);\n                },\n                createSourceAndTransfer = function () {\n                    temp_root.getFile(file1, {\n                        create : true\n                    }, function (entry) {\n                        expect(entry.filesystem).toBeDefined();\n                        if (isChrome) {\n                            expect(entry.filesystem.name).toContain(\"Temporary\");\n                        } else {\n                            expect(entry.filesystem.name).toEqual(\"temporary\");\n                        }\n                        sourceEntry = entry;\n                        // Save for later cleanup\n                        entry.moveTo(persistent_root, file2, validateFile, failed.bind(null, done, 'entry.moveTo - Error moving file: ' + file1 + ' to PERSISTENT root as: ' + file2));\n                    }, failed.bind(null, done, 'temp_root.getFile - Error creating file: ' + file1 + 'at TEMPORAL root'));\n                };\n                // Delete any existing file to start things off\n                persistent_root.getFile(file2, {}, function (entry) {\n                    entry.remove(createSourceAndTransfer, failed.bind(null, done, 'entry.remove - Error removing file: ' + file2));\n                }, createSourceAndTransfer);\n            });\n            it(\"file.spec.128 moveTo: persistent -> temporary\", function (done) {\n                var file1 = \"entry.copy.file1b\",\n                file2 = \"entry.copy.file2b\",\n                sourceEntry,\n                fullPath = joinURL(temp_root.fullPath, file2),\n                validateFile = function (entry) {\n                    expect(entry).toBeDefined();\n                    expect(entry.isFile).toBe(true);\n                    expect(entry.isDirectory).toBe(false);\n                    expect(entry.name).toCanonicallyMatch(file2);\n                    expect(entry.fullPath).toCanonicallyMatch(fullPath);\n                    if(isChrome) {\n                        expect(entry.filesystem.name).toContain(\"Temporary\");\n                    } else {\n                        expect(entry.filesystem.name).toEqual(\"temporary\");\n                    }\n                    // cleanup\n                    deleteEntry(entry.name);\n                    deleteEntry(sourceEntry.name, done);\n                },\n                createSourceAndTransfer = function () {\n                    persistent_root.getFile(file1, {\n                        create : true\n                    }, function (entry) {\n                        expect(entry).toBeDefined();\n                        expect(entry.filesystem).toBeDefined();\n                        if (isChrome) {\n                            expect(entry.filesystem.name).toContain(\"Persistent\");\n                        } else {\n                            expect(entry.filesystem.name).toEqual(\"persistent\");\n                        }\n                        sourceEntry = entry;\n                        // Save for later cleanup\n                        entry.moveTo(temp_root, file2, validateFile, failed.bind(null, done, 'entry.moveTo - Error moving file: ' + file1 + ' to TEMPORAL root as: ' + file2));\n                    }, failed.bind(null, done, 'persistent_root.getFile - Error creating file: ' + file1 + 'at PERSISTENT root'));\n                };\n                // Delete any existing file to start things off\n                temp_root.getFile(file2, {}, function (entry) {\n                    entry.remove(createSourceAndTransfer, failed.bind(null, done, 'entry.remove - Error removing file: ' + file2));\n                }, createSourceAndTransfer);\n            });\n            it(\"file.spec.129 cordova.file.*Directory are set\", function () {\n                var expectedPaths = ['applicationDirectory', 'applicationStorageDirectory', 'dataDirectory', 'cacheDirectory'];\n                if (cordova.platformId == 'android' || cordova.platformId == 'amazon-fireos') {\n                    if (cordova.file.externalApplicationStorageDirectory !== null) {\n                        // https://issues.apache.org/jira/browse/CB-10411\n                        // If external storage can't be mounted, the cordova.file.external* properties are null.\n                        expectedPaths.push('externalApplicationStorageDirectory', 'externalRootDirectory', 'externalCacheDirectory', 'externalDataDirectory');\n                    }\n                } else if (cordova.platformId == 'blackberry10') {\n                    expectedPaths.push('externalRootDirectory', 'sharedDirectory');\n                } else if (cordova.platformId == 'ios') {\n                    expectedPaths.push('syncedDataDirectory', 'documentsDirectory', 'tempDirectory');\n                } else if (cordova.platformId == 'osx') {\n                    expectedPaths.push('documentsDirectory', 'tempDirectory', 'rootDirectory');\n                } else {\n                    console.log('Skipping test due on unsupported platform.');\n                    return;\n                }\n                for (var i = 0; i < expectedPaths.length; ++i) {\n                    expect(typeof cordova.file[expectedPaths[i]]).toBe('string');\n                    expect(cordova.file[expectedPaths[i]]).toMatch(/\\/$/, 'Path should end with a slash');\n                }\n            });\n        });\n        //cross-file-system copy and move\n        describe('IndexedDB-based impl', function () {\n            it(\"file.spec.131 Nested file or nested directory should be removed when removing a parent directory\", function (done) {\n                var parentDirName = 'deletedDir131',\n                    nestedDirName = 'nestedDir131',\n                    nestedFileName = 'nestedFile131.txt';\n\n                createDirectory(parentDirName, function (parent) {\n                    parent.getDirectory(nestedDirName, { create: true}, function () {\n                        parent.getFile(nestedFileName, { create: true}, function () {\n                            parent.removeRecursively(function() {\n                                root.getDirectory(parentDirName,{ create: false}, failed.bind(this, done, 'root.getDirectory - unexpected success callback : ' + parentDirName), function(){\n                                    parent.getFile(nestedFileName,{ create: false}, failed.bind(this, done, 'getFile - unexpected success callback : ' + nestedFileName), function(){\n                                            parent.getDirectory(nestedDirName, { create: false}, failed.bind(this, done, 'getDirectory - unexpected success callback : ' + nestedDirName), done);\n                                        });\n                                    });\n                                }, failed.bind(this, done, 'removeRecursively - Error removing directory : ' + parentDirName));\n                        }, failed.bind(this, done, 'getFile - Error creating file : ' + nestedFileName));\n                    },failed.bind(this, done, 'getDirectory - Error creating directory : ' + nestedDirName));\n                }, failed.bind(this, done, 'root.getDirectory - Error creating directory : ' + parentDirName));\n            });\n            it(\"file.spec.132 Entry should be created succesfully when using relative paths if its parent directory exists\", function (done) {\n                /* Directory entries have to be created successively.\n                   For example, the call `fs.root.getDirectory('dir1/dir2', {create:true}, successCallback, errorCallback)`\n                   will fail if dir1 did not exist. */\n                var parentName = 'parentName132';\n                var nestedName = 'nestedName132';\n                var path = parentName + '/' + nestedName;\n\n                var win = function(directory){\n                    expect(directory).toBeDefined();\n                    expect(directory.isFile).toBe(false);\n                    expect(directory.isDirectory).toBe(true);\n                    expect(directory.name).toCanonicallyMatch(nestedName);\n                    expect(directory.fullPath).toCanonicallyMatch('/' + path + '/');\n                    deleteEntry(directory.name);\n                    deleteEntry(parentName, done);\n                };\n\n                createDirectory(parentName, function() {\n                    root.getDirectory(parentName + '/' + nestedName, {create:true}, win,\n                        failed.bind(this, done, 'root.getDirectory - Error getting directory : ' + path));\n                }, failed.bind(this, done, 'root.getDirectory - Error getting directory : ' + parentName));\n            });\n            it(\"file.spec.133 A file being removed should not affect another file with name being a prefix of the removed file name.\", function (done) {\n\n                // Names include special symbols so that we check the IndexedDB range used\n                var deletedFileName = 'deletedFile.0',\n                secondFileName = 'deletedFile.0.1';\n\n                var win = function(fileEntry){\n                    expect(fileEntry).toBeDefined();\n                    expect(fileEntry.isFile).toBe(true);\n                    expect(fileEntry.isDirectory).toBe(false);\n                    expect(fileEntry.name).toCanonicallyMatch(secondFileName);\n                    deleteEntry(fileEntry.name, done);\n                };\n\n                createFile(deletedFileName, function (deletedFile) {\n                    createFile(secondFileName, function () {\n                        deletedFile.remove(function() {\n                            root.getFile(deletedFileName, {create: false}, failed.bind(this, done, 'getFile - unexpected success callback getting deleted file : ' + deletedFileName), function(){\n                                root.getFile(secondFileName, {create: false}, win, failed.bind(this, done, 'getFile - Error getting file after deleting deletedFile : ' + secondFileName));\n                            });\n                        }, failed.bind(this, done, 'remove - Error removing file : ' + deletedFileName));\n                    }, failed.bind(this, done, 'getFile - Error creating file : ' + secondFileName));\n                }, failed.bind(this, done, 'getFile - Error creating file : ' + deletedFileName));\n            });\n            it(\"file.spec.134 A directory being removed should not affect another directory with name being a prefix of the removed directory name.\", function (done) {\n\n                // Names include special symbols so that we check the IndexedDB range used\n                var deletedDirName = 'deletedDir.0',\n                secondDirName = 'deletedDir.0.1';\n\n                var win = function(directory){\n                    expect(directory).toBeDefined();\n                    expect(directory.isFile).toBe(false);\n                    expect(directory.isDirectory).toBe(true);\n                    expect(directory.name).toCanonicallyMatch(secondDirName);\n                    deleteEntry(directory.name, done);\n                };\n\n                createDirectory(deletedDirName, function (deletedDir) {\n                    createDirectory(secondDirName, function () {\n                        deletedDir.remove(function() {\n                            root.getDirectory(deletedDirName, {create: false}, failed.bind(this, done, 'getDirectory - unexpected success callback getting deleted directory : ' + deletedDirName), function() {\n                                root.getDirectory(secondDirName, {create: false}, win, failed.bind(this, done, 'getDirectory - Error getting directory after deleting deletedDirectory : ' + secondDirName));\n                            });\n                        }, failed.bind(this, done, 'remove - Error removing directory : ' + deletedDirName));\n                    }, failed.bind(this, done, 'root.getDirectory - Error creating directory : ' + secondDirName));\n                }, failed.bind(this, done, 'root.getDirectory - Error creating directory : ' + deletedDirName));\n            });\n            it(\"file.spec.135 Deletion of a child directory should not affect the parent directory.\", function (done) {\n\n                var parentName = 'parentName135';\n                var childName = 'childName135';\n\n                var win = function(directory){\n                    expect(directory).toBeDefined();\n                    expect(directory.isFile).toBe(false);\n                    expect(directory.isDirectory).toBe(true);\n                    expect(directory.name).toCanonicallyMatch(parentName);\n                    deleteEntry(directory.name, done);\n                };\n\n                createDirectory(parentName, function(parent){\n                    parent.getDirectory(childName, {create: true}, function(child){\n                        child.removeRecursively(function(){\n                            root.getDirectory(parentName, {create: false}, win, failed.bind(this, done, 'root.getDirectory - Error getting parent directory : ' + parentName));\n                        },\n                        failed.bind(this, done, 'getDirectory - Error removing directory : ' + childName));\n                    }, failed.bind(this, done, 'getDirectory - Error creating directory : ' + childName));\n                }, failed.bind(this, done, 'root.getDirectory - Error creating directory : ' + parentName));\n            });\n            it(\"file.spec.136 Paths should support Unicode symbols.\", function (done) {\n\n                var dirName = '文件插件';\n\n                var win = function(directory){\n                    expect(directory).toBeDefined();\n                    expect(directory.isFile).toBe(false);\n                    expect(directory.isDirectory).toBe(true);\n                    expect(directory.name).toCanonicallyMatch(dirName);\n                    deleteEntry(directory.name, done);\n                };\n\n                createDirectory(dirName, function(){\n                    root.getDirectory(dirName, {create: false}, win,\n                        failed.bind(this, done, 'root.getDirectory - Error getting directory : ' + dirName));\n                }, failed.bind(this, done, 'root.getDirectory - Error creating directory : ' + dirName));\n            });\n        });\n        // Content and Asset URLs\n        if (cordova.platformId == 'android') {\n            describe('content: URLs', function() {\n                function testContentCopy(src, done) {\n                    var file2 = \"entry.copy.file2b\",\n                    fullPath = joinURL(temp_root.fullPath, file2),\n                    validateFile = function (entry) {\n                        expect(entry.isFile).toBe(true);\n                        expect(entry.isDirectory).toBe(false);\n                        expect(entry.name).toCanonicallyMatch(file2);\n                        expect(entry.fullPath).toCanonicallyMatch(fullPath);\n                        expect(entry.filesystem.name).toEqual(\"temporary\");\n                        // cleanup\n                        deleteEntry(entry.name, done);\n                    },\n                    transfer = function () {\n                        resolveLocalFileSystemURL(src, function(entry) {\n                            expect(entry).toBeDefined();\n                            expect(entry.filesystem.name).toEqual(\"content\");\n                            entry.copyTo(temp_root, file2, validateFile, failed.bind(null, done, 'entry.copyTo - Error copying file: ' + entry.toURL() + ' to TEMPORAL root as: ' + file2));\n                        }, failed.bind(null, done, 'resolveLocalFileSystemURL failed for content provider'));\n                    };\n                    // Delete any existing file to start things off\n                    temp_root.getFile(file2, {}, function (entry) {\n                        entry.remove(transfer, failed.bind(null, done, 'entry.remove - Error removing file: ' + file2));\n                    }, transfer);\n                }\n                it(\"file.spec.138 copyTo: content\", function(done) {\n                    testContentCopy('content://org.apache.cordova.file.testprovider/www/index.html', done);\n                });\n                it(\"file.spec.139 copyTo: content /w space and query\", function(done) {\n                    testContentCopy('content://org.apache.cordova.file.testprovider/?name=foo%20bar&realPath=%2Fwww%2Findex.html', done);\n                });\n                it(\"file.spec.140 delete: content should fail\", function(done) {\n                    resolveLocalFileSystemURL('content://org.apache.cordova.file.testprovider/www/index.html', function(entry) {\n                        entry.remove(failed.bind(null, done, 'expected delete to fail'), done);\n                    }, failed.bind(null, done, 'resolveLocalFileSystemURL failed for content provider'));\n                });\n            });\n\n            // these tests ensure that you can read and copy from android_asset folder\n            // for details see https://issues.apache.org/jira/browse/CB-6428\n            // and https://mail-archives.apache.org/mod_mbox/cordova-dev/201508.mbox/%3C782154441.8406572.1440182722528.JavaMail.yahoo%40mail.yahoo.com%3E\n            describe('asset: URLs', function() {\n                it(\"file.spec.141 filePaths.applicationStorage\", function() {\n                    expect(cordova.file.applicationDirectory).toEqual('file:///android_asset/');\n                }, MEDIUM_TIMEOUT);\n                it(\"file.spec.142 assets should be enumerable\", function(done) {\n                    resolveLocalFileSystemURL('file:///android_asset/www/fixtures/asset-test', function(entry) {\n                        var reader = entry.createReader();\n                        reader.readEntries(function (entries) {\n                            expect(entries.length).not.toBe(0);\n                            done();\n                        }, failed.bind(null, done, 'reader.readEntries - Error during reading of entries from assets directory'));\n                    }, failed.bind(null, done, 'resolveLocalFileSystemURL failed for assets'));\n                }, MEDIUM_TIMEOUT);\n                it(\"file.spec.145 asset subdirectories should be obtainable\", function(done) {\n                    resolveLocalFileSystemURL('file:///android_asset/www/fixtures', function(entry) {\n                        entry.getDirectory('asset-test', { create: false }, function (subDir) {\n                            expect(subDir).toBeDefined();\n                            expect(subDir.isFile).toBe(false);\n                            expect(subDir.isDirectory).toBe(true);\n                            expect(subDir.name).toCanonicallyMatch('asset-test');\n                            done();\n                        }, failed.bind(null, done, 'entry.getDirectory - Error getting asset subdirectory'));\n                    }, failed.bind(null, done, 'resolveLocalFileSystemURL failed for assets'));\n                }, MEDIUM_TIMEOUT);\n                it(\"file.spec.146 asset files should be readable\", function(done) {\n                    resolveLocalFileSystemURL('file:///android_asset/www/fixtures/asset-test/asset-test.txt', function(entry) {\n                        expect(entry.isFile).toBe(true);\n                        entry.file(function (file) {\n                            expect(file).toBeDefined();\n                            var reader = new FileReader();\n                            reader.onerror = failed.bind(null, done, 'reader.readAsText - Error reading asset text file');\n                            reader.onloadend = function () {\n                                expect(this.result).toBeDefined();\n                                expect(this.result.length).not.toBe(0);\n                                done();\n                            };\n                            reader.readAsText(file);\n                        }, failed.bind(null, done, 'entry.file - Error reading asset file'));\n                    }, failed.bind(null, done, 'resolveLocalFileSystemURL failed for assets'));\n                }, MEDIUM_TIMEOUT);\n                it(\"file.spec.143 copyTo: asset -> temporary\", function(done) {\n                    var file2 = \"entry.copy.file2b\",\n                    fullPath = joinURL(temp_root.fullPath, file2),\n                    validateFile = function (entry) {\n                        expect(entry.isFile).toBe(true);\n                        expect(entry.isDirectory).toBe(false);\n                        expect(entry.name).toCanonicallyMatch(file2);\n                        expect(entry.fullPath).toCanonicallyMatch(fullPath);\n                        expect(entry.filesystem.name).toEqual(\"temporary\");\n                        // cleanup\n                        deleteEntry(entry.name, done);\n                    },\n                    transfer = function () {\n                        resolveLocalFileSystemURL('file:///android_asset/www/index.html', function(entry) {\n                            expect(entry.filesystem.name).toEqual('assets');\n                            entry.copyTo(temp_root, file2, validateFile, failed.bind(null, done, 'entry.copyTo - Error copying file: ' + entry.toURL() + ' to TEMPORAL root as: ' + file2));\n                        }, failed.bind(null, done, 'resolveLocalFileSystemURL failed for assets'));\n                    };\n                    // Delete any existing file to start things off\n                    temp_root.getFile(file2, {}, function (entry) {\n                        entry.remove(transfer, failed.bind(null, done, 'entry.remove - Error removing file: ' + file2));\n                    }, transfer);\n                }, MEDIUM_TIMEOUT);\n            });\n            it(\"file.spec.144 copyTo: asset directory\", function (done) {\n                var srcUrl = 'file:///android_asset/www/fixtures/asset-test';\n                var dstDir = \"entry.copy.dstDir\";\n                var dstPath = joinURL(root.fullPath, dstDir);\n                // create a new directory entry to kick off it\n                deleteEntry(dstDir, function () {\n                    resolveLocalFileSystemURL(srcUrl, function(directory) {\n                        directory.copyTo(root, dstDir, function (directory) {\n                            expect(directory).toBeDefined();\n                            expect(directory.isFile).toBe(false);\n                            expect(directory.isDirectory).toBe(true);\n                            expect(directory.fullPath).toCanonicallyMatch(dstPath);\n                            expect(directory.name).toCanonicallyMatch(dstDir);\n                            root.getDirectory(dstDir, {\n                                create : false\n                            }, function (dirEntry) {\n                                expect(dirEntry).toBeDefined();\n                                expect(dirEntry.isFile).toBe(false);\n                                expect(dirEntry.isDirectory).toBe(true);\n                                expect(dirEntry.fullPath).toCanonicallyMatch(dstPath);\n                                expect(dirEntry.name).toCanonicallyMatch(dstDir);\n                                dirEntry.getFile('asset-test.txt', {\n                                    create : false\n                                }, function (fileEntry) {\n                                    expect(fileEntry).toBeDefined();\n                                    expect(fileEntry.isFile).toBe(true);\n                                    // cleanup\n                                    deleteEntry(dstDir, done);\n                                }, failed.bind(null, done, 'dirEntry.getFile - Error getting subfile'));\n                            }, failed.bind(null, done, 'root.getDirectory - Error getting copied directory'));\n                        }, failed.bind(null, done, 'directory.copyTo - Error copying directory'));\n                    }, failed.bind(null, done, 'resolving src dir'));\n                }, failed.bind(null, done, 'deleteEntry - Error removing directory : ' + dstDir));\n            }, MEDIUM_TIMEOUT);\n        }\n    });\n\n};\n//******************************************************************************************\n//***************************************Manual Tests***************************************\n//******************************************************************************************\n\nexports.defineManualTests = function (contentEl, createActionButton) {\n\n    function resolveFs(fsname) {\n        var fsURL = \"cdvfile://localhost/\" + fsname + \"/\";\n        logMessage(\"Resolving URL: \" + fsURL);\n        resolveLocalFileSystemURL(fsURL, function (entry) {\n            logMessage(\"Success\", 'green');\n            logMessage(entry.toURL(), 'blue');\n            logMessage(entry.toInternalURL(), 'blue');\n            logMessage(\"Resolving URL: \" + entry.toURL());\n            resolveLocalFileSystemURL(entry.toURL(), function (entry2) {\n                logMessage(\"Success\", 'green');\n                logMessage(entry2.toURL(), 'blue');\n                logMessage(entry2.toInternalURL(), 'blue');\n            }, logError(\"resolveLocalFileSystemURL\"));\n        }, logError(\"resolveLocalFileSystemURL\"));\n    }\n\n    function testPrivateURL() {\n        requestFileSystem(LocalFileSystem.TEMPORARY, 0, function (fileSystem) {\n            logMessage(\"Temporary root is at \" + fileSystem.root.toNativeURL());\n            fileSystem.root.getFile(\"testfile\", {\n                create : true\n            }, function (entry) {\n                logMessage(\"Temporary file is at \" + entry.toNativeURL());\n                if (entry.toNativeURL().substring(0, 12) == \"file:///var/\") {\n                    logMessage(\"File starts with /var/, trying /private/var\");\n                    var newURL = \"file://localhost/private/var/\" + entry.toNativeURL().substring(12) + \"?and=another_thing\";\n                    //var newURL = entry.toNativeURL();\n                    logMessage(newURL, 'blue');\n                    resolveLocalFileSystemURL(newURL, function (newEntry) {\n                        logMessage(\"Successfully resolved.\", 'green');\n                        logMessage(newEntry.toURL(), 'blue');\n                        logMessage(newEntry.toNativeURL(), 'blue');\n                    }, logError(\"resolveLocalFileSystemURL\"));\n                }\n            }, logError(\"getFile\"));\n        }, logError(\"requestFileSystem\"));\n    }\n\n    function clearLog() {\n        var log = document.getElementById(\"info\");\n        log.innerHTML = \"\";\n    }\n\n    function logMessage(message, color) {\n        var log = document.getElementById(\"info\");\n        var logLine = document.createElement('div');\n        if (color) {\n            logLine.style.color = color;\n        }\n        logLine.innerHTML = message;\n        log.appendChild(logLine);\n    }\n\n    function logError(serviceName) {\n        return function (err) {\n            logMessage(\"ERROR: \" + serviceName + \" \" + JSON.stringify(err), \"red\");\n        };\n    }\n\n    var fsRoots = {\n        \"ios\" : \"library,library-nosync,documents,documents-nosync,cache,bundle,root,private\",\n        \"osx\" : \"library,library-nosync,documents,documents-nosync,cache,bundle,root,private\",\n        \"android\" : \"files,files-external,documents,sdcard,cache,cache-external,root\",\n        \"amazon-fireos\" : \"files,files-external,documents,sdcard,cache,cache-external,root\",\n        \"windows\": \"temporary,persistent\"\n    };\n\n    //Add title and align to content\n    var div = document.createElement('h2');\n    div.appendChild(document.createTextNode('File Systems'));\n    div.setAttribute(\"align\", \"center\");\n    contentEl.appendChild(div);\n\n    div = document.createElement('h3');\n    div.appendChild(document.createTextNode('Results are displayed in yellow status box below with expected results noted under that'));\n    div.setAttribute(\"align\", \"center\");\n    contentEl.appendChild(div);\n\n    div = document.createElement('div');\n    div.setAttribute(\"id\", \"button\");\n    div.setAttribute(\"align\", \"center\");\n    contentEl.appendChild(div);\n    if (fsRoots.hasOwnProperty(cordova.platformId)) {\n        (fsRoots[cordova.platformId].split(',')).forEach(function (fs) {\n            if (cordova.platformId === 'ios' && fs === 'private') {\n                createActionButton(\"Test private URL (iOS)\", function () {\n                    clearLog();\n                    testPrivateURL();\n                }, 'button');\n            } else {\n                createActionButton(fs, function () {\n                    clearLog();\n                    resolveFs(fs);\n                }, 'button');\n            }\n        });\n    }\n\n\n    div = document.createElement('div');\n    div.setAttribute(\"id\", \"info\");\n    div.setAttribute(\"align\", \"center\");\n    contentEl.appendChild(div);\n\n    div = document.createElement('h3');\n    div.appendChild(document.createTextNode('For each test above, file or directory should be successfully found. ' +\n        'Status box should say Resolving URL was Success. The first URL resolved is the internal URL. ' +\n        'The second URL resolved is the absolute URL. Blue URLs must match.'));\n    contentEl.appendChild(div);\n\n    div = document.createElement('h3');\n    div.appendChild(document.createTextNode('For Test private URL (iOS), the private URL (first blue URL in status box) ' +\n        'should be successfully resolved. Status box should say Successfully resolved. Both blue URLs below ' +\n        'that should match.'));\n    contentEl.appendChild(div);\n};\n"
  },
  {
    "path": "plugins/cordova-plugin-file/tests/www/fixtures/asset-test/asset-test.txt",
    "content": "This file is here for testing purposes"
  },
  {
    "path": "plugins/cordova-plugin-file/www/DirectoryEntry.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\nvar argscheck = require('cordova/argscheck'),\n    utils = require('cordova/utils'),\n    exec = require('cordova/exec'),\n    Entry = require('./Entry'),\n    FileError = require('./FileError'),\n    DirectoryReader = require('./DirectoryReader');\n\n/**\n * An interface representing a directory on the file system.\n *\n * {boolean} isFile always false (readonly)\n * {boolean} isDirectory always true (readonly)\n * {DOMString} name of the directory, excluding the path leading to it (readonly)\n * {DOMString} fullPath the absolute full path to the directory (readonly)\n * {FileSystem} filesystem on which the directory resides (readonly)\n */\nvar DirectoryEntry = function(name, fullPath, fileSystem, nativeURL) {\n\n    // add trailing slash if it is missing\n    if ((fullPath) && !/\\/$/.test(fullPath)) {\n        fullPath += \"/\";\n    }\n    // add trailing slash if it is missing\n    if (nativeURL && !/\\/$/.test(nativeURL)) {\n        nativeURL += \"/\";\n    }\n    DirectoryEntry.__super__.constructor.call(this, false, true, name, fullPath, fileSystem, nativeURL);\n};\n\nutils.extend(DirectoryEntry, Entry);\n\n/**\n * Creates a new DirectoryReader to read entries from this directory\n */\nDirectoryEntry.prototype.createReader = function() {\n    return new DirectoryReader(this.toInternalURL());\n};\n\n/**\n * Creates or looks up a directory\n *\n * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a directory\n * @param {Flags} options to create or exclusively create the directory\n * @param {Function} successCallback is called with the new entry\n * @param {Function} errorCallback is called with a FileError\n */\nDirectoryEntry.prototype.getDirectory = function(path, options, successCallback, errorCallback) {\n    argscheck.checkArgs('sOFF', 'DirectoryEntry.getDirectory', arguments);\n    var fs = this.filesystem;\n    var win = successCallback && function(result) {\n        var entry = new DirectoryEntry(result.name, result.fullPath, fs, result.nativeURL);\n        successCallback(entry);\n    };\n    var fail = errorCallback && function(code) {\n        errorCallback(new FileError(code));\n    };\n    exec(win, fail, \"File\", \"getDirectory\", [this.toInternalURL(), path, options]);\n};\n\n/**\n * Deletes a directory and all of it's contents\n *\n * @param {Function} successCallback is called with no parameters\n * @param {Function} errorCallback is called with a FileError\n */\nDirectoryEntry.prototype.removeRecursively = function(successCallback, errorCallback) {\n    argscheck.checkArgs('FF', 'DirectoryEntry.removeRecursively', arguments);\n    var fail = errorCallback && function(code) {\n        errorCallback(new FileError(code));\n    };\n    exec(successCallback, fail, \"File\", \"removeRecursively\", [this.toInternalURL()]);\n};\n\n/**\n * Creates or looks up a file\n *\n * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a file\n * @param {Flags} options to create or exclusively create the file\n * @param {Function} successCallback is called with the new entry\n * @param {Function} errorCallback is called with a FileError\n */\nDirectoryEntry.prototype.getFile = function(path, options, successCallback, errorCallback) {\n    argscheck.checkArgs('sOFF', 'DirectoryEntry.getFile', arguments);\n    var fs = this.filesystem;\n    var win = successCallback && function(result) {\n        var FileEntry = require('./FileEntry');\n        var entry = new FileEntry(result.name, result.fullPath, fs, result.nativeURL);\n        successCallback(entry);\n    };\n    var fail = errorCallback && function(code) {\n        errorCallback(new FileError(code));\n    };\n    exec(win, fail, \"File\", \"getFile\", [this.toInternalURL(), path, options]);\n};\n\nmodule.exports = DirectoryEntry;\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/DirectoryReader.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\nvar exec = require('cordova/exec'),\n    FileError = require('./FileError') ;\n\n/**\n * An interface that lists the files and directories in a directory.\n */\nfunction DirectoryReader(localURL) {\n    this.localURL = localURL || null;\n    this.hasReadEntries = false;\n}\n\n/**\n * Returns a list of entries from a directory.\n *\n * @param {Function} successCallback is called with a list of entries\n * @param {Function} errorCallback is called with a FileError\n */\nDirectoryReader.prototype.readEntries = function(successCallback, errorCallback) {\n    // If we've already read and passed on this directory's entries, return an empty list.\n    if (this.hasReadEntries) {\n        successCallback([]);\n        return;\n    }\n    var reader = this;\n    var win = typeof successCallback !== 'function' ? null : function(result) {\n        var retVal = [];\n        for (var i=0; i<result.length; i++) {\n            var entry = null;\n            if (result[i].isDirectory) {\n                entry = new (require('./DirectoryEntry'))();\n            }\n            else if (result[i].isFile) {\n                entry = new (require('./FileEntry'))();\n            }\n            entry.isDirectory = result[i].isDirectory;\n            entry.isFile = result[i].isFile;\n            entry.name = result[i].name;\n            entry.fullPath = result[i].fullPath;\n            entry.filesystem = new (require('./FileSystem'))(result[i].filesystemName);\n            entry.nativeURL = result[i].nativeURL;\n            retVal.push(entry);\n        }\n        reader.hasReadEntries = true;\n        successCallback(retVal);\n    };\n    var fail = typeof errorCallback !== 'function' ? null : function(code) {\n        errorCallback(new FileError(code));\n    };\n    exec(win, fail, \"File\", \"readEntries\", [this.localURL]);\n};\n\nmodule.exports = DirectoryReader;\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/Entry.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\nvar argscheck = require('cordova/argscheck'),\n    exec = require('cordova/exec'),\n    FileError = require('./FileError'),\n    Metadata = require('./Metadata');\n\n/**\n * Represents a file or directory on the local file system.\n *\n * @param isFile\n *            {boolean} true if Entry is a file (readonly)\n * @param isDirectory\n *            {boolean} true if Entry is a directory (readonly)\n * @param name\n *            {DOMString} name of the file or directory, excluding the path\n *            leading to it (readonly)\n * @param fullPath\n *            {DOMString} the absolute full path to the file or directory\n *            (readonly)\n * @param fileSystem\n *            {FileSystem} the filesystem on which this entry resides\n *            (readonly)\n * @param nativeURL\n *            {DOMString} an alternate URL which can be used by native\n *            webview controls, for example media players.\n *            (optional, readonly)\n */\nfunction Entry(isFile, isDirectory, name, fullPath, fileSystem, nativeURL) {\n    this.isFile = !!isFile;\n    this.isDirectory = !!isDirectory;\n    this.name = name || '';\n    this.fullPath = fullPath || '';\n    this.filesystem = fileSystem || null;\n    this.nativeURL = nativeURL || null;\n}\n\n/**\n * Look up the metadata of the entry.\n *\n * @param successCallback\n *            {Function} is called with a Metadata object\n * @param errorCallback\n *            {Function} is called with a FileError\n */\nEntry.prototype.getMetadata = function(successCallback, errorCallback) {\n    argscheck.checkArgs('FF', 'Entry.getMetadata', arguments);\n    var success = successCallback && function(entryMetadata) {\n        var metadata = new Metadata({\n            size: entryMetadata.size,\n            modificationTime: entryMetadata.lastModifiedDate\n        });\n        successCallback(metadata);\n    };\n    var fail = errorCallback && function(code) {\n        errorCallback(new FileError(code));\n    };\n    exec(success, fail, \"File\", \"getFileMetadata\", [this.toInternalURL()]);\n};\n\n/**\n * Set the metadata of the entry.\n *\n * @param successCallback\n *            {Function} is called with a Metadata object\n * @param errorCallback\n *            {Function} is called with a FileError\n * @param metadataObject\n *            {Object} keys and values to set\n */\nEntry.prototype.setMetadata = function(successCallback, errorCallback, metadataObject) {\n    argscheck.checkArgs('FFO', 'Entry.setMetadata', arguments);\n    exec(successCallback, errorCallback, \"File\", \"setMetadata\", [this.toInternalURL(), metadataObject]);\n};\n\n/**\n * Move a file or directory to a new location.\n *\n * @param parent\n *            {DirectoryEntry} the directory to which to move this entry\n * @param newName\n *            {DOMString} new name of the entry, defaults to the current name\n * @param successCallback\n *            {Function} called with the new DirectoryEntry object\n * @param errorCallback\n *            {Function} called with a FileError\n */\nEntry.prototype.moveTo = function(parent, newName, successCallback, errorCallback) {\n    argscheck.checkArgs('oSFF', 'Entry.moveTo', arguments);\n    var fail = errorCallback && function(code) {\n        errorCallback(new FileError(code));\n    };\n    var srcURL = this.toInternalURL(),\n        // entry name\n        name = newName || this.name,\n        success = function(entry) {\n            if (entry) {\n                if (successCallback) {\n                    // create appropriate Entry object\n                    var newFSName = entry.filesystemName || (entry.filesystem && entry.filesystem.name);\n                    var fs = newFSName ? new FileSystem(newFSName, { name: \"\", fullPath: \"/\" }) : new FileSystem(parent.filesystem.name, { name: \"\", fullPath: \"/\" });\n                    var result = (entry.isDirectory) ? new (require('./DirectoryEntry'))(entry.name, entry.fullPath, fs, entry.nativeURL) : new (require('cordova-plugin-file.FileEntry'))(entry.name, entry.fullPath, fs, entry.nativeURL);\n                    successCallback(result);\n                }\n            }\n            else {\n                // no Entry object returned\n                if (fail) {\n                    fail(FileError.NOT_FOUND_ERR);\n                }\n            }\n        };\n\n    // copy\n    exec(success, fail, \"File\", \"moveTo\", [srcURL, parent.toInternalURL(), name]);\n};\n\n/**\n * Copy a directory to a different location.\n *\n * @param parent\n *            {DirectoryEntry} the directory to which to copy the entry\n * @param newName\n *            {DOMString} new name of the entry, defaults to the current name\n * @param successCallback\n *            {Function} called with the new Entry object\n * @param errorCallback\n *            {Function} called with a FileError\n */\nEntry.prototype.copyTo = function(parent, newName, successCallback, errorCallback) {\n    argscheck.checkArgs('oSFF', 'Entry.copyTo', arguments);\n    var fail = errorCallback && function(code) {\n        errorCallback(new FileError(code));\n    };\n    var srcURL = this.toInternalURL(),\n        // entry name\n        name = newName || this.name,\n        // success callback\n        success = function(entry) {\n            if (entry) {\n                if (successCallback) {\n                    // create appropriate Entry object\n                    var newFSName = entry.filesystemName || (entry.filesystem && entry.filesystem.name);\n                    var fs = newFSName ? new FileSystem(newFSName, { name: \"\", fullPath: \"/\" }) : new FileSystem(parent.filesystem.name, { name: \"\", fullPath: \"/\" });\n                    var result = (entry.isDirectory) ? new (require('./DirectoryEntry'))(entry.name, entry.fullPath, fs, entry.nativeURL) : new (require('cordova-plugin-file.FileEntry'))(entry.name, entry.fullPath, fs, entry.nativeURL);\n                    successCallback(result);\n                }\n            }\n            else {\n                // no Entry object returned\n                if (fail) {\n                    fail(FileError.NOT_FOUND_ERR);\n                }\n            }\n        };\n\n    // copy\n    exec(success, fail, \"File\", \"copyTo\", [srcURL, parent.toInternalURL(), name]);\n};\n\n/**\n * Return a URL that can be passed across the bridge to identify this entry.\n */\nEntry.prototype.toInternalURL = function() {\n    if (this.filesystem && this.filesystem.__format__) {\n      return this.filesystem.__format__(this.fullPath, this.nativeURL);\n    }\n};\n\n/**\n * Return a URL that can be used to identify this entry.\n * Use a URL that can be used to as the src attribute of a <video> or\n * <audio> tag. If that is not possible, construct a cdvfile:// URL.\n */\nEntry.prototype.toURL = function() {\n    if (this.nativeURL) {\n      return this.nativeURL;\n    }\n    // fullPath attribute may contain the full URL in the case that\n    // toInternalURL fails.\n    return this.toInternalURL() || \"file://localhost\" + this.fullPath;\n};\n\n/**\n * Backwards-compatibility: In v1.0.0 - 1.0.2, .toURL would only return a\n * cdvfile:// URL, and this method was necessary to obtain URLs usable by the\n * webview.\n * See CB-6051, CB-6106, CB-6117, CB-6152, CB-6199, CB-6201, CB-6243, CB-6249,\n * and CB-6300.\n */\nEntry.prototype.toNativeURL = function() {\n    console.log(\"DEPRECATED: Update your code to use 'toURL'\");\n    return this.toURL();\n};\n\n/**\n * Returns a URI that can be used to identify this entry.\n *\n * @param {DOMString} mimeType for a FileEntry, the mime type to be used to interpret the file, when loaded through this URI.\n * @return uri\n */\nEntry.prototype.toURI = function(mimeType) {\n    console.log(\"DEPRECATED: Update your code to use 'toURL'\");\n    return this.toURL();\n};\n\n/**\n * Remove a file or directory. It is an error to attempt to delete a\n * directory that is not empty. It is an error to attempt to delete a\n * root directory of a file system.\n *\n * @param successCallback {Function} called with no parameters\n * @param errorCallback {Function} called with a FileError\n */\nEntry.prototype.remove = function(successCallback, errorCallback) {\n    argscheck.checkArgs('FF', 'Entry.remove', arguments);\n    var fail = errorCallback && function(code) {\n        errorCallback(new FileError(code));\n    };\n    exec(successCallback, fail, \"File\", \"remove\", [this.toInternalURL()]);\n};\n\n/**\n * Look up the parent DirectoryEntry of this entry.\n *\n * @param successCallback {Function} called with the parent DirectoryEntry object\n * @param errorCallback {Function} called with a FileError\n */\nEntry.prototype.getParent = function(successCallback, errorCallback) {\n    argscheck.checkArgs('FF', 'Entry.getParent', arguments);\n    var fs = this.filesystem;\n    var win = successCallback && function(result) {\n        var DirectoryEntry = require('./DirectoryEntry');\n        var entry = new DirectoryEntry(result.name, result.fullPath, fs, result.nativeURL);\n        successCallback(entry);\n    };\n    var fail = errorCallback && function(code) {\n        errorCallback(new FileError(code));\n    };\n    exec(win, fail, \"File\", \"getParent\", [this.toInternalURL()]);\n};\n\nmodule.exports = Entry;\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/File.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/**\n * Constructor.\n * name {DOMString} name of the file, without path information\n * fullPath {DOMString} the full path of the file, including the name\n * type {DOMString} mime type\n * lastModifiedDate {Date} last modified date\n * size {Number} size of the file in bytes\n */\n\nvar File = function(name, localURL, type, lastModifiedDate, size){\n    this.name = name || '';\n    this.localURL = localURL || null;\n    this.type = type || null;\n    this.lastModified = lastModifiedDate || null;\n    // For backwards compatibility, store the timestamp in lastModifiedDate as well\n    this.lastModifiedDate = lastModifiedDate || null;\n    this.size = size || 0;\n\n    // These store the absolute start and end for slicing the file.\n    this.start = 0;\n    this.end = this.size;\n};\n\n/**\n * Returns a \"slice\" of the file. Since Cordova Files don't contain the actual\n * content, this really returns a File with adjusted start and end.\n * Slices of slices are supported.\n * start {Number} The index at which to start the slice (inclusive).\n * end {Number} The index at which to end the slice (exclusive).\n */\nFile.prototype.slice = function(start, end) {\n    var size = this.end - this.start;\n    var newStart = 0;\n    var newEnd = size;\n    if (arguments.length) {\n        if (start < 0) {\n            newStart = Math.max(size + start, 0);\n        } else {\n            newStart = Math.min(size, start);\n        }\n    }\n\n    if (arguments.length >= 2) {\n        if (end < 0) {\n            newEnd = Math.max(size + end, 0);\n        } else {\n            newEnd = Math.min(end, size);\n        }\n    }\n\n    var newFile = new File(this.name, this.localURL, this.type, this.lastModified, this.size);\n    newFile.start = this.start + newStart;\n    newFile.end = this.start + newEnd;\n    return newFile;\n};\n\n\nmodule.exports = File;\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/FileEntry.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\nvar utils = require('cordova/utils'),\n    exec = require('cordova/exec'),\n    Entry = require('./Entry'),\n    FileWriter = require('./FileWriter'),\n    File = require('./File'),\n    FileError = require('./FileError');\n\n/**\n * An interface representing a file on the file system.\n *\n * {boolean} isFile always true (readonly)\n * {boolean} isDirectory always false (readonly)\n * {DOMString} name of the file, excluding the path leading to it (readonly)\n * {DOMString} fullPath the absolute full path to the file (readonly)\n * {FileSystem} filesystem on which the file resides (readonly)\n */\nvar FileEntry = function(name, fullPath, fileSystem, nativeURL) {\n    // remove trailing slash if it is present\n    if (fullPath && /\\/$/.test(fullPath)) {\n        fullPath = fullPath.substring(0, fullPath.length - 1);\n    }\n    if (nativeURL && /\\/$/.test(nativeURL)) {\n        nativeURL = nativeURL.substring(0, nativeURL.length - 1);\n    }\n\n    FileEntry.__super__.constructor.apply(this, [true, false, name, fullPath, fileSystem, nativeURL]);\n};\n\nutils.extend(FileEntry, Entry);\n\n/**\n * Creates a new FileWriter associated with the file that this FileEntry represents.\n *\n * @param {Function} successCallback is called with the new FileWriter\n * @param {Function} errorCallback is called with a FileError\n */\nFileEntry.prototype.createWriter = function(successCallback, errorCallback) {\n    this.file(function(filePointer) {\n        var writer = new FileWriter(filePointer);\n\n        if (writer.localURL === null || writer.localURL === \"\") {\n            if (errorCallback) {\n                errorCallback(new FileError(FileError.INVALID_STATE_ERR));\n            }\n        } else {\n            if (successCallback) {\n                successCallback(writer);\n            }\n        }\n    }, errorCallback);\n};\n\n/**\n * Returns a File that represents the current state of the file that this FileEntry represents.\n *\n * @param {Function} successCallback is called with the new File object\n * @param {Function} errorCallback is called with a FileError\n */\nFileEntry.prototype.file = function(successCallback, errorCallback) {\n    var localURL = this.toInternalURL();\n    var win = successCallback && function(f) {\n        var file = new File(f.name, localURL, f.type, f.lastModifiedDate, f.size);\n        successCallback(file);\n    };\n    var fail = errorCallback && function(code) {\n        errorCallback(new FileError(code));\n    };\n    exec(win, fail, \"File\", \"getFileMetadata\", [localURL]);\n};\n\n\nmodule.exports = FileEntry;\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/FileError.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/**\n * FileError\n */\nfunction FileError(error) {\n  this.code = error || null;\n}\n\n// File error codes\n// Found in DOMException\nFileError.NOT_FOUND_ERR = 1;\nFileError.SECURITY_ERR = 2;\nFileError.ABORT_ERR = 3;\n\n// Added by File API specification\nFileError.NOT_READABLE_ERR = 4;\nFileError.ENCODING_ERR = 5;\nFileError.NO_MODIFICATION_ALLOWED_ERR = 6;\nFileError.INVALID_STATE_ERR = 7;\nFileError.SYNTAX_ERR = 8;\nFileError.INVALID_MODIFICATION_ERR = 9;\nFileError.QUOTA_EXCEEDED_ERR = 10;\nFileError.TYPE_MISMATCH_ERR = 11;\nFileError.PATH_EXISTS_ERR = 12;\n\nmodule.exports = FileError;\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/FileReader.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\nvar exec = require('cordova/exec'),\n    modulemapper = require('cordova/modulemapper'),\n    utils = require('cordova/utils'),\n    FileError = require('./FileError'),\n    ProgressEvent = require('./ProgressEvent'),\n    origFileReader = modulemapper.getOriginalSymbol(window, 'FileReader');\n\n/**\n * This class reads the mobile device file system.\n *\n * For Android:\n *      The root directory is the root of the file system.\n *      To read from the SD card, the file name is \"sdcard/my_file.txt\"\n * @constructor\n */\nvar FileReader = function() {\n    this._readyState = 0;\n    this._error = null;\n    this._result = null;\n    this._progress = null;\n    this._localURL = '';\n    this._realReader = origFileReader ? new origFileReader() : {};\n};\n\n/**\n * Defines the maximum size to read at a time via the native API. The default value is a compromise between\n * minimizing the overhead of many exec() calls while still reporting progress frequently enough for large files.\n * (Note attempts to allocate more than a few MB of contiguous memory on the native side are likely to cause\n * OOM exceptions, while the JS engine seems to have fewer problems managing large strings or ArrayBuffers.)\n */\nFileReader.READ_CHUNK_SIZE = 256*1024;\n\n// States\nFileReader.EMPTY = 0;\nFileReader.LOADING = 1;\nFileReader.DONE = 2;\n\nutils.defineGetter(FileReader.prototype, 'readyState', function() {\n    return this._localURL ? this._readyState : this._realReader.readyState;\n});\n\nutils.defineGetter(FileReader.prototype, 'error', function() {\n    return this._localURL ? this._error: this._realReader.error;\n});\n\nutils.defineGetter(FileReader.prototype, 'result', function() {\n    return this._localURL ? this._result: this._realReader.result;\n});\n\nfunction defineEvent(eventName) {\n    utils.defineGetterSetter(FileReader.prototype, eventName, function() {\n        return this._realReader[eventName] || null;\n    }, function(value) {\n        this._realReader[eventName] = value;\n    });\n}\ndefineEvent('onloadstart');    // When the read starts.\ndefineEvent('onprogress');     // While reading (and decoding) file or fileBlob data, and reporting partial file data (progress.loaded/progress.total)\ndefineEvent('onload');         // When the read has successfully completed.\ndefineEvent('onerror');        // When the read has failed (see errors).\ndefineEvent('onloadend');      // When the request has completed (either in success or failure).\ndefineEvent('onabort');        // When the read has been aborted. For instance, by invoking the abort() method.\n\nfunction initRead(reader, file) {\n    // Already loading something\n    if (reader.readyState == FileReader.LOADING) {\n      throw new FileError(FileError.INVALID_STATE_ERR);\n    }\n\n    reader._result = null;\n    reader._error = null;\n    reader._progress = 0;\n    reader._readyState = FileReader.LOADING;\n\n    if (typeof file.localURL == 'string') {\n        reader._localURL = file.localURL;\n    } else {\n        reader._localURL = '';\n        return true;\n    }\n\n    if (reader.onloadstart) {\n        reader.onloadstart(new ProgressEvent(\"loadstart\", {target:reader}));\n    }\n}\n\n/**\n * Callback used by the following read* functions to handle incremental or final success.\n * Must be bound to the FileReader's this along with all but the last parameter,\n * e.g. readSuccessCallback.bind(this, \"readAsText\", \"UTF-8\", offset, totalSize, accumulate)\n * @param readType The name of the read function to call.\n * @param encoding Text encoding, or null if this is not a text type read.\n * @param offset Starting offset of the read.\n * @param totalSize Total number of bytes or chars to read.\n * @param accumulate A function that takes the callback result and accumulates it in this._result.\n * @param r Callback result returned by the last read exec() call, or null to begin reading.\n */\nfunction readSuccessCallback(readType, encoding, offset, totalSize, accumulate, r) {\n    if (this._readyState === FileReader.DONE) {\n        return;\n    }\n\n    if (typeof r !== \"undefined\") {\n        accumulate(r);\n        this._progress = Math.min(this._progress + FileReader.READ_CHUNK_SIZE, totalSize);\n\n        if (typeof this.onprogress === \"function\") {\n            this.onprogress(new ProgressEvent(\"progress\", {loaded:this._progress, total:totalSize}));\n        }\n    }\n\n    if (typeof r === \"undefined\" || this._progress < totalSize) {\n        var execArgs = [\n            this._localURL,\n            offset + this._progress,\n            offset + this._progress + Math.min(totalSize - this._progress, FileReader.READ_CHUNK_SIZE)];\n        if (encoding) {\n            execArgs.splice(1, 0, encoding);\n        }\n        exec(\n            readSuccessCallback.bind(this, readType, encoding, offset, totalSize, accumulate),\n            readFailureCallback.bind(this),\n            \"File\", readType, execArgs);\n    } else {\n        this._readyState = FileReader.DONE;\n\n        if (typeof this.onload === \"function\") {\n            this.onload(new ProgressEvent(\"load\", {target:this}));\n        }\n\n        if (typeof this.onloadend === \"function\") {\n            this.onloadend(new ProgressEvent(\"loadend\", {target:this}));\n        }\n    }\n}\n\n/**\n * Callback used by the following read* functions to handle errors.\n * Must be bound to the FileReader's this, e.g. readFailureCallback.bind(this)\n */\nfunction readFailureCallback(e) {\n    if (this._readyState === FileReader.DONE) {\n        return;\n    }\n\n    this._readyState = FileReader.DONE;\n    this._result = null;\n    this._error = new FileError(e);\n\n    if (typeof this.onerror === \"function\") {\n        this.onerror(new ProgressEvent(\"error\", {target:this}));\n    }\n\n    if (typeof this.onloadend === \"function\") {\n        this.onloadend(new ProgressEvent(\"loadend\", {target:this}));\n    }\n}\n\n/**\n * Abort reading file.\n */\nFileReader.prototype.abort = function() {\n    if (origFileReader && !this._localURL) {\n        return this._realReader.abort();\n    }\n    this._result = null;\n\n    if (this._readyState == FileReader.DONE || this._readyState == FileReader.EMPTY) {\n      return;\n    }\n\n    this._readyState = FileReader.DONE;\n\n    // If abort callback\n    if (typeof this.onabort === 'function') {\n        this.onabort(new ProgressEvent('abort', {target:this}));\n    }\n    // If load end callback\n    if (typeof this.onloadend === 'function') {\n        this.onloadend(new ProgressEvent('loadend', {target:this}));\n    }\n};\n\n/**\n * Read text file.\n *\n * @param file          {File} File object containing file properties\n * @param encoding      [Optional] (see http://www.iana.org/assignments/character-sets)\n */\nFileReader.prototype.readAsText = function(file, encoding) {\n    if (initRead(this, file)) {\n        return this._realReader.readAsText(file, encoding);\n    }\n\n    // Default encoding is UTF-8\n    var enc = encoding ? encoding : \"UTF-8\";\n\n    var totalSize = file.end - file.start;\n    readSuccessCallback.bind(this)(\"readAsText\", enc, file.start, totalSize, function(r) {\n        if (this._progress === 0) {\n            this._result = \"\";\n        }\n        this._result += r;\n    }.bind(this));\n};\n\n\n/**\n * Read file and return data as a base64 encoded data url.\n * A data url is of the form:\n *      data:[<mediatype>][;base64],<data>\n *\n * @param file          {File} File object containing file properties\n */\nFileReader.prototype.readAsDataURL = function(file) {\n    if (initRead(this, file)) {\n        return this._realReader.readAsDataURL(file);\n    }\n\n    var totalSize = file.end - file.start;\n    readSuccessCallback.bind(this)(\"readAsDataURL\", null, file.start, totalSize, function(r) {\n        var commaIndex = r.indexOf(',');\n        if (this._progress === 0) {\n            this._result = r;\n        } else {\n            this._result += r.substring(commaIndex + 1);\n        }\n    }.bind(this));\n};\n\n/**\n * Read file and return data as a binary data.\n *\n * @param file          {File} File object containing file properties\n */\nFileReader.prototype.readAsBinaryString = function(file) {\n    if (initRead(this, file)) {\n        return this._realReader.readAsBinaryString(file);\n    }\n\n    var totalSize = file.end - file.start;\n    readSuccessCallback.bind(this)(\"readAsBinaryString\", null, file.start, totalSize, function(r) {\n        if (this._progress === 0) {\n            this._result = \"\";\n        }\n        this._result += r;\n    }.bind(this));\n};\n\n/**\n * Read file and return data as a binary data.\n *\n * @param file          {File} File object containing file properties\n */\nFileReader.prototype.readAsArrayBuffer = function(file) {\n    if (initRead(this, file)) {\n        return this._realReader.readAsArrayBuffer(file);\n    }\n\n    var totalSize = file.end - file.start;\n    readSuccessCallback.bind(this)(\"readAsArrayBuffer\", null, file.start, totalSize, function(r) {\n        var resultArray = (this._progress === 0 ? new Uint8Array(totalSize) : new Uint8Array(this._result));\n        resultArray.set(new Uint8Array(r), this._progress);\n        this._result = resultArray.buffer;\n    }.bind(this));\n};\n\nmodule.exports = FileReader;\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/FileSystem.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\nvar DirectoryEntry = require('./DirectoryEntry');\n\n/**\n * An interface representing a file system\n *\n * @constructor\n * {DOMString} name the unique name of the file system (readonly)\n * {DirectoryEntry} root directory of the file system (readonly)\n */\nvar FileSystem = function(name, root) {\n    this.name = name;\n    if (root) {\n        this.root = new DirectoryEntry(root.name, root.fullPath, this, root.nativeURL);\n    } else {\n        this.root = new DirectoryEntry(this.name, '/', this);\n    }\n};\n\nFileSystem.prototype.__format__ = function(fullPath, nativeUrl) {\n    return fullPath;\n};\n\nFileSystem.prototype.toJSON = function() {\n    return \"<FileSystem: \" + this.name + \">\";\n};\n\n// Use instead of encodeURI() when encoding just the path part of a URI rather than an entire URI.\nFileSystem.encodeURIPath = function(path) {\n    // Because # is a valid filename character, it must be encoded to prevent part of the\n    // path from being parsed as a URI fragment.\n    return encodeURI(path).replace(/#/g, '%23');\n};\n\nmodule.exports = FileSystem;\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/FileUploadOptions.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/**\n * Options to customize the HTTP request used to upload files.\n * @constructor\n * @param fileKey {String}   Name of file request parameter.\n * @param fileName {String}  Filename to be used by the server. Defaults to image.jpg.\n * @param mimeType {String}  Mimetype of the uploaded file. Defaults to image/jpeg.\n * @param params {Object}    Object with key: value params to send to the server.\n * @param headers {Object}   Keys are header names, values are header values. Multiple\n *                           headers of the same name are not supported.\n */\nvar FileUploadOptions = function(fileKey, fileName, mimeType, params, headers, httpMethod) {\n    this.fileKey = fileKey || null;\n    this.fileName = fileName || null;\n    this.mimeType = mimeType || null;\n    this.params = params || null;\n    this.headers = headers || null;\n    this.httpMethod = httpMethod || null;\n};\n\nmodule.exports = FileUploadOptions;\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/FileUploadResult.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/**\n * FileUploadResult\n * @constructor\n */\nmodule.exports = function FileUploadResult(size, code, content) {\n\tthis.bytesSent = size;\n\tthis.responseCode = code;\n\tthis.response = content;\n };"
  },
  {
    "path": "plugins/cordova-plugin-file/www/FileWriter.js",
    "content": "﻿/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\nvar exec = require('cordova/exec'),\n    FileError = require('./FileError'),\n    ProgressEvent = require('./ProgressEvent');\n\n/**\n * This class writes to the mobile device file system.\n *\n * For Android:\n *      The root directory is the root of the file system.\n *      To write to the SD card, the file name is \"sdcard/my_file.txt\"\n *\n * @constructor\n * @param file {File} File object containing file properties\n * @param append if true write to the end of the file, otherwise overwrite the file\n */\nvar FileWriter = function(file) {\n    this.fileName = \"\";\n    this.length = 0;\n    if (file) {\n        this.localURL = file.localURL || file;\n        this.length = file.size || 0;\n    }\n    // default is to write at the beginning of the file\n    this.position = 0;\n\n    this.readyState = 0; // EMPTY\n\n    this.result = null;\n\n    // Error\n    this.error = null;\n\n    // Event handlers\n    this.onwritestart = null;   // When writing starts\n    this.onprogress = null;     // While writing the file, and reporting partial file data\n    this.onwrite = null;        // When the write has successfully completed.\n    this.onwriteend = null;     // When the request has completed (either in success or failure).\n    this.onabort = null;        // When the write has been aborted. For instance, by invoking the abort() method.\n    this.onerror = null;        // When the write has failed (see errors).\n};\n\n// States\nFileWriter.INIT = 0;\nFileWriter.WRITING = 1;\nFileWriter.DONE = 2;\n\n/**\n * Abort writing file.\n */\nFileWriter.prototype.abort = function() {\n    // check for invalid state\n    if (this.readyState === FileWriter.DONE || this.readyState === FileWriter.INIT) {\n        throw new FileError(FileError.INVALID_STATE_ERR);\n    }\n\n    // set error\n    this.error = new FileError(FileError.ABORT_ERR);\n\n    this.readyState = FileWriter.DONE;\n\n    // If abort callback\n    if (typeof this.onabort === \"function\") {\n        this.onabort(new ProgressEvent(\"abort\", {\"target\":this}));\n    }\n\n    // If write end callback\n    if (typeof this.onwriteend === \"function\") {\n        this.onwriteend(new ProgressEvent(\"writeend\", {\"target\":this}));\n    }\n};\n\n/**\n * Writes data to the file\n *\n * @param data text or blob to be written\n * @param isPendingBlobReadResult {Boolean} true if the data is the pending blob read operation result\n */\nFileWriter.prototype.write = function(data, isPendingBlobReadResult) {\n\n    var that=this;\n    var supportsBinary = (typeof window.Blob !== 'undefined' && typeof window.ArrayBuffer !== 'undefined');\n    var isProxySupportBlobNatively = (cordova.platformId === \"windows8\" || cordova.platformId === \"windows\");\n    var isBinary;\n\n    // Check to see if the incoming data is a blob\n    if (data instanceof File || (!isProxySupportBlobNatively && supportsBinary && data instanceof Blob)) {\n        var fileReader = new FileReader();\n        fileReader.onload = function() {\n            // Call this method again, with the arraybuffer as argument\n            FileWriter.prototype.write.call(that, this.result, true /* isPendingBlobReadResult */);\n        };\n        fileReader.onerror = function () {\n            // DONE state\n            that.readyState = FileWriter.DONE;\n\n            // Save error\n            that.error = this.error;\n\n            // If onerror callback\n            if (typeof that.onerror === \"function\") {\n                that.onerror(new ProgressEvent(\"error\", {\"target\":that}));\n            }\n\n            // If onwriteend callback\n            if (typeof that.onwriteend === \"function\") {\n                that.onwriteend(new ProgressEvent(\"writeend\", {\"target\":that}));\n            }\n        };\n\n        // WRITING state\n        this.readyState = FileWriter.WRITING;\n\n        if (supportsBinary) {\n            fileReader.readAsArrayBuffer(data);\n        } else {\n            fileReader.readAsText(data);\n        }\n        return;\n    }\n\n    // Mark data type for safer transport over the binary bridge\n    isBinary = supportsBinary && (data instanceof ArrayBuffer);\n    if (isBinary && cordova.platformId === \"windowsphone\") {\n        // create a plain array, using the keys from the Uint8Array view so that we can serialize it\n        data = Array.apply(null, new Uint8Array(data));\n    }\n    \n    // Throw an exception if we are already writing a file\n    if (this.readyState === FileWriter.WRITING && !isPendingBlobReadResult) {\n        throw new FileError(FileError.INVALID_STATE_ERR);\n    }\n\n    // WRITING state\n    this.readyState = FileWriter.WRITING;\n\n    var me = this;\n\n    // If onwritestart callback\n    if (typeof me.onwritestart === \"function\") {\n        me.onwritestart(new ProgressEvent(\"writestart\", {\"target\":me}));\n    }\n\n    // Write file\n    exec(\n        // Success callback\n        function(r) {\n            // If DONE (cancelled), then don't do anything\n            if (me.readyState === FileWriter.DONE) {\n                return;\n            }\n\n            // position always increases by bytes written because file would be extended\n            me.position += r;\n            // The length of the file is now where we are done writing.\n\n            me.length = me.position;\n\n            // DONE state\n            me.readyState = FileWriter.DONE;\n\n            // If onwrite callback\n            if (typeof me.onwrite === \"function\") {\n                me.onwrite(new ProgressEvent(\"write\", {\"target\":me}));\n            }\n\n            // If onwriteend callback\n            if (typeof me.onwriteend === \"function\") {\n                me.onwriteend(new ProgressEvent(\"writeend\", {\"target\":me}));\n            }\n        },\n        // Error callback\n        function(e) {\n            // If DONE (cancelled), then don't do anything\n            if (me.readyState === FileWriter.DONE) {\n                return;\n            }\n\n            // DONE state\n            me.readyState = FileWriter.DONE;\n\n            // Save error\n            me.error = new FileError(e);\n\n            // If onerror callback\n            if (typeof me.onerror === \"function\") {\n                me.onerror(new ProgressEvent(\"error\", {\"target\":me}));\n            }\n\n            // If onwriteend callback\n            if (typeof me.onwriteend === \"function\") {\n                me.onwriteend(new ProgressEvent(\"writeend\", {\"target\":me}));\n            }\n        }, \"File\", \"write\", [this.localURL, data, this.position, isBinary]);\n};\n\n/**\n * Moves the file pointer to the location specified.\n *\n * If the offset is a negative number the position of the file\n * pointer is rewound.  If the offset is greater than the file\n * size the position is set to the end of the file.\n *\n * @param offset is the location to move the file pointer to.\n */\nFileWriter.prototype.seek = function(offset) {\n    // Throw an exception if we are already writing a file\n    if (this.readyState === FileWriter.WRITING) {\n        throw new FileError(FileError.INVALID_STATE_ERR);\n    }\n\n    if (!offset && offset !== 0) {\n        return;\n    }\n\n    // See back from end of file.\n    if (offset < 0) {\n        this.position = Math.max(offset + this.length, 0);\n    }\n    // Offset is bigger than file size so set position\n    // to the end of the file.\n    else if (offset > this.length) {\n        this.position = this.length;\n    }\n    // Offset is between 0 and file size so set the position\n    // to start writing.\n    else {\n        this.position = offset;\n    }\n};\n\n/**\n * Truncates the file to the size specified.\n *\n * @param size to chop the file at.\n */\nFileWriter.prototype.truncate = function(size) {\n    // Throw an exception if we are already writing a file\n    if (this.readyState === FileWriter.WRITING) {\n        throw new FileError(FileError.INVALID_STATE_ERR);\n    }\n\n    // WRITING state\n    this.readyState = FileWriter.WRITING;\n\n    var me = this;\n\n    // If onwritestart callback\n    if (typeof me.onwritestart === \"function\") {\n        me.onwritestart(new ProgressEvent(\"writestart\", {\"target\":this}));\n    }\n\n    // Write file\n    exec(\n        // Success callback\n        function(r) {\n            // If DONE (cancelled), then don't do anything\n            if (me.readyState === FileWriter.DONE) {\n                return;\n            }\n\n            // DONE state\n            me.readyState = FileWriter.DONE;\n\n            // Update the length of the file\n            me.length = r;\n            me.position = Math.min(me.position, r);\n\n            // If onwrite callback\n            if (typeof me.onwrite === \"function\") {\n                me.onwrite(new ProgressEvent(\"write\", {\"target\":me}));\n            }\n\n            // If onwriteend callback\n            if (typeof me.onwriteend === \"function\") {\n                me.onwriteend(new ProgressEvent(\"writeend\", {\"target\":me}));\n            }\n        },\n        // Error callback\n        function(e) {\n            // If DONE (cancelled), then don't do anything\n            if (me.readyState === FileWriter.DONE) {\n                return;\n            }\n\n            // DONE state\n            me.readyState = FileWriter.DONE;\n\n            // Save error\n            me.error = new FileError(e);\n\n            // If onerror callback\n            if (typeof me.onerror === \"function\") {\n                me.onerror(new ProgressEvent(\"error\", {\"target\":me}));\n            }\n\n            // If onwriteend callback\n            if (typeof me.onwriteend === \"function\") {\n                me.onwriteend(new ProgressEvent(\"writeend\", {\"target\":me}));\n            }\n        }, \"File\", \"truncate\", [this.localURL, size]);\n};\n\nmodule.exports = FileWriter;\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/Flags.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/**\n * Supplies arguments to methods that lookup or create files and directories.\n *\n * @param create\n *            {boolean} file or directory if it doesn't exist\n * @param exclusive\n *            {boolean} used with create; if true the command will fail if\n *            target path exists\n */\nfunction Flags(create, exclusive) {\n    this.create = create || false;\n    this.exclusive = exclusive || false;\n}\n\nmodule.exports = Flags;\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/LocalFileSystem.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\nexports.TEMPORARY = 0;\nexports.PERSISTENT = 1;\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/Metadata.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/**\n * Information about the state of the file or directory\n *\n * {Date} modificationTime (readonly)\n */\nvar Metadata = function(metadata) {\n    if (typeof metadata == \"object\") {\n        this.modificationTime = new Date(metadata.modificationTime);\n        this.size = metadata.size || 0;\n    } else if (typeof metadata == \"undefined\") {\n        this.modificationTime = null;\n        this.size = 0;\n    } else {\n        /* Backwards compatiblity with platforms that only return a timestamp */\n        this.modificationTime = new Date(metadata);\n    }\n};\n\nmodule.exports = Metadata;\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/ProgressEvent.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n// If ProgressEvent exists in global context, use it already, otherwise use our own polyfill\n// Feature test: See if we can instantiate a native ProgressEvent;\n// if so, use that approach,\n// otherwise fill-in with our own implementation.\n//\n// NOTE: right now we always fill in with our own. Down the road would be nice if we can use whatever is native in the webview.\nvar ProgressEvent = (function() {\n    /*\n    var createEvent = function(data) {\n        var event = document.createEvent('Events');\n        event.initEvent('ProgressEvent', false, false);\n        if (data) {\n            for (var i in data) {\n                if (data.hasOwnProperty(i)) {\n                    event[i] = data[i];\n                }\n            }\n            if (data.target) {\n                // TODO: cannot call <some_custom_object>.dispatchEvent\n                // need to first figure out how to implement EventTarget\n            }\n        }\n        return event;\n    };\n    try {\n        var ev = createEvent({type:\"abort\",target:document});\n        return function ProgressEvent(type, data) {\n            data.type = type;\n            return createEvent(data);\n        };\n    } catch(e){\n    */\n        return function ProgressEvent(type, dict) {\n            this.type = type;\n            this.bubbles = false;\n            this.cancelBubble = false;\n            this.cancelable = false;\n            this.lengthComputable = false;\n            this.loaded = dict && dict.loaded ? dict.loaded : 0;\n            this.total = dict && dict.total ? dict.total : 0;\n            this.target = dict && dict.target ? dict.target : null;\n        };\n    //}\n})();\n\nmodule.exports = ProgressEvent;\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/android/FileSystem.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\nFILESYSTEM_PROTOCOL = \"cdvfile\";\n\nmodule.exports = {\n    __format__: function(fullPath, nativeUrl) {\n        var path;\n        var contentUrlMatch = /^content:\\/\\//.exec(nativeUrl);\n        if (contentUrlMatch) {\n            // When available, use the path from a native content URL, which was already encoded by Android.\n            // This is necessary because JavaScript's encodeURI() does not encode as many characters as\n            // Android, which can result in permission exceptions when the encoding of a content URI\n            // doesn't match the string for which permission was originally granted.\n            path = nativeUrl.substring(contentUrlMatch[0].length - 1);\n        } else {\n            path = FileSystem.encodeURIPath(fullPath);\n            if (!/^\\//.test(path)) {\n                path = '/' + path;\n            }\n            \n            var m = /\\?.*/.exec(nativeUrl);\n            if (m) {\n                path += m[0];\n            }\n        }\n\n        return FILESYSTEM_PROTOCOL + '://localhost/' + this.name + path;\n    }\n};\n\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/blackberry10/.jshintrc",
    "content": "{\n    \"globals\": {\n        \"requestAnimationFrame\": true\n    }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/blackberry10/FileProxy.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/*\n * FileProxy\n *\n * Register all File exec calls to be handled by proxy\n */\n\nmodule.exports = {\n    copyTo: require('cordova-plugin-file.copyToProxy'),\n    getDirectory: require('cordova-plugin-file.getDirectoryProxy'),\n    getFile: require('cordova-plugin-file.getFileProxy'),\n    getFileMetadata: require('cordova-plugin-file.getFileMetadataProxy'),\n    getMetadata: require('cordova-plugin-file.getMetadataProxy'),\n    getParent: require('cordova-plugin-file.getParentProxy'),\n    moveTo: require('cordova-plugin-file.moveToProxy'),\n    readAsArrayBuffer: require('cordova-plugin-file.readAsArrayBufferProxy'),\n    readAsBinaryString: require('cordova-plugin-file.readAsBinaryStringProxy'),\n    readAsDataURL: require('cordova-plugin-file.readAsDataURLProxy'),\n    readAsText: require('cordova-plugin-file.readAsTextProxy'),\n    readEntries: require('cordova-plugin-file.readEntriesProxy'),\n    remove: require('cordova-plugin-file.removeProxy'),\n    removeRecursively: require('cordova-plugin-file.removeRecursivelyProxy'),\n    resolveLocalFileSystemURI: require('cordova-plugin-file.resolveLocalFileSystemURIProxy'),\n    requestAllFileSystems: require('cordova-plugin-file.requestAllFileSystemsProxy'),\n    requestFileSystem: require('cordova-plugin-file.requestFileSystemProxy'),\n    setMetadata: require('cordova-plugin-file.setMetadataProxy'),\n    truncate: require('cordova-plugin-file.truncateProxy'),\n    write: require('cordova-plugin-file.writeProxy')\n};\n\nrequire('cordova/exec/proxy').add('File', module.exports);\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/blackberry10/FileSystem.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/*\n * FileSystem\n * \n * Translate temporary / persistent / root file paths\n */\n\nvar info = require(\"cordova-plugin-file.bb10FileSystemInfo\");\n\nmodule.exports = {\n    __format__: function(fullPath) {\n        var path;\n        switch (this.name) {\n            case 'temporary':\n                path = info.temporaryPath + FileSystem.encodeURIPath(fullPath);\n                break;\n            case 'persistent':\n                path = info.persistentPath + FileSystem.encodeURIPath(fullPath);\n                break;\n            case 'root':\n                path = 'file://' + FileSystem.encodeURIPath(fullPath);\n                break;\n        }\n        return path;\n    }\n};\n\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/blackberry10/copyTo.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/* \n * copyTo\n * \n * IN:\n *  args\n *   0 - URL of entry to copy\n *   1 - URL of the directory into which to copy/move the entry\n *   2 - the new name of the entry, defaults to the current name\n *  move - if true, delete the entry which was copied\n * OUT:\n *  success - entry for the copied file or directory\n *  fail - FileError\n */\n\nvar resolve = cordova.require('cordova-plugin-file.resolveLocalFileSystemURIProxy'),\n    requestAnimationFrame = cordova.require('cordova-plugin-file.bb10RequestAnimationFrame');\n\nmodule.exports = function (success, fail, args, move) {\n    var uri = args[0],\n        destination = args[1],\n        fileName = args[2],\n        copiedEntry;\n\n    function onSuccess() {\n        resolve(\n            function (entry) {\n                if (typeof(success) === 'function') {\n                    success(entry);\n                }\n            },\n            onFail,\n            [destination + copiedEntry.name]\n        );\n    }\n    function onFail(error) {\n        if (typeof(fail) === 'function') {\n            if (error && error.code) {\n                //set error codes expected by mobile spec\n                if (uri === destination) {\n                    fail(FileError.INVALID_MODIFICATION_ERR);\n                } else if (error.code === FileError.SECURITY_ERR) {\n                    fail(FileError.INVALID_MODIFICATION_ERR);\n                } else {\n                    fail(error.code);\n                }\n            } else {\n                fail(error);\n            }\n        }\n    }\n    function writeFile(fileEntry, blob, entry) {\n        copiedEntry = fileEntry;\n        fileEntry.createWriter(function (fileWriter) {\n            fileWriter.onwriteend = function () {\n                if (move) {\n                    entry.nativeEntry.remove(onSuccess, function () {\n                        console.error(\"Move operation failed. Files may exist at both source and destination\");\n                    });\n                } else {\n                    onSuccess();\n                }\n            };\n            fileWriter.onerror = onFail;\n            fileWriter.write(blob);\n        }, onFail);\n    }\n    function copyFile(entry) {\n        if (entry.nativeEntry.file) {\n            entry.nativeEntry.file(function (file) {\n                var reader = new FileReader()._realReader;\n                reader.onloadend = function (e) {\n                    var contents = new Uint8Array(this.result),\n                        blob = new Blob([contents]);\n                    resolve(function (destEntry) {\n                        requestAnimationFrame(function () {\n                            destEntry.nativeEntry.getFile(fileName, {create: true}, function (fileEntry) {\n                                writeFile(fileEntry, blob, entry);\n                            }, onFail);\n                        });\n                    }, onFail, [destination]);   \n                };\n                reader.onerror = onFail;\n                reader.readAsArrayBuffer(file);\n            }, onFail);\n        } else {\n            onFail(FileError.INVALID_MODIFICATION_ERR);\n        }\n    }\n    function copyDirectory(entry) {\n        resolve(function (destEntry) {\n            if (entry.filesystemName !== destEntry.filesystemName) {\n                console.error(\"Copying directories between filesystems is not supported on BB10\");\n                onFail(FileError.INVALID_MODIFICATION_ERR);\n            } else {\n                entry.nativeEntry.copyTo(destEntry.nativeEntry, fileName, function () {\n                    resolve(function (copiedDir) {\n                        copiedEntry = copiedDir;\n                        if (move) {\n                            entry.nativeEntry.removeRecursively(onSuccess, onFail);\n                        } else {\n                            onSuccess();\n                        }\n                    }, onFail, [destination + fileName]);\n                }, onFail);\n            }\n        }, onFail, [destination]); \n    }\n\n    if (destination + fileName === uri) {\n        onFail(FileError.INVALID_MODIFICATION_ERR);\n    } else if (fileName.indexOf(':') > -1) {\n        onFail(FileError.ENCODING_ERR);\n    } else {\n        resolve(function (entry) {\n            if (entry.isDirectory) {\n                copyDirectory(entry);\n            } else {\n                copyFile(entry);\n            }\n        }, onFail, [uri]);\n    }\n};\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/blackberry10/createEntryFromNative.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/*\n * createEntryFromNative\n * \n * IN\n *  native - webkit Entry\n * OUT\n *  returns Cordova entry\n */\n\nvar info = require('cordova-plugin-file.bb10FileSystemInfo'),\n    fileSystems = require('cordova-plugin-file.fileSystems');\n\nmodule.exports = function (native) {\n    var entry = {\n            nativeEntry: native,\n            isDirectory: !!native.isDirectory,\n            isFile: !!native.isFile,\n            name: native.name,\n            fullPath: native.fullPath,\n            filesystemName: native.filesystem.name,\n            nativeURL: native.toURL()\n        },\n        persistentPath = info.persistentPath.substring(7),\n        temporaryPath = info.temporaryPath.substring(7);\n    //fix bb10 webkit incorrect nativeURL\n    if (native.filesystem.name === 'root') {\n        entry.nativeURL = 'file:///' + FileSystem.encodeURIPath(native.fullPath);\n    } else if (entry.nativeURL.indexOf('filesystem:local:///persistent/') === 0) {\n        entry.nativeURL = info.persistentPath + FileSystem.encodeURIPath(native.fullPath);\n    } else if (entry.nativeURL.indexOf('filesystem:local:///temporary') === 0) {\n        entry.nativeURL = info.temporaryPath + FileSystem.encodeURIPath(native.fullPath);\n    }\n    //translate file system name from bb10 webkit\n    if (entry.filesystemName === 'local__0:Persistent' || entry.fullPath.indexOf(persistentPath) !== -1) {\n        entry.filesystemName = 'persistent';\n    } else if (entry.filesystemName === 'local__0:Temporary' || entry.fullPath.indexOf(temporaryPath) !== -1) {\n        entry.filesystemName = 'temporary';\n    }\n    //add file system property (will be called sync)\n    fileSystems.getFs(entry.filesystemName, function (fs) {\n        entry.filesystem = fs;\n    });\n    //set root on fullPath for persistent / temporary locations\n    entry.fullPath = entry.fullPath.replace(persistentPath, \"\");\n    entry.fullPath = entry.fullPath.replace(temporaryPath, \"\");\n    //set trailing slash on directory\n    if (entry.isDirectory && entry.fullPath.substring(entry.fullPath.length - 1) !== '/') {\n        entry.fullPath += '/';\n    }\n    if (entry.isDirectory && entry.nativeURL.substring(entry.nativeURL.length - 1) !== '/') {\n        entry.nativeURL += '/';\n    }\n    return entry;\n};\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/blackberry10/getDirectory.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/* \n * getDirectory\n * \n * IN:\n *  args\n *   0 - local filesytem URI for the base directory to search\n *   1 - directory to be created/returned; may be absolute path or relative path\n *   2 - options object\n * OUT:\n *  success - DirectoryEntry\n *  fail - FileError code\n */\n\nvar resolve = cordova.require('cordova-plugin-file.resolveLocalFileSystemURIProxy'),\n    requestAnimationFrame = cordova.require('cordova-plugin-file.bb10RequestAnimationFrame');\n\nmodule.exports = function (success, fail, args) {\n    var uri = args[0] === \"/\" ? \"\" : args[0],\n        dir = args[1],\n        options = args[2],\n        onSuccess = function (entry) {\n            if (typeof(success) === 'function') {\n                success(entry);\n            }\n        },\n        onFail = function (error) {\n            if (typeof(fail) === 'function') {\n                if (error && error.code) {\n                    //set error codes expected by mobile-spec tests\n                    if (error.code === FileError.INVALID_MODIFICATION_ERR  && options.exclusive) {\n                        fail(FileError.PATH_EXISTS_ERR);\n                    } else if ( error.code === FileError.NOT_FOUND_ERR && dir.indexOf(':') > 0) {\n                        fail(FileError.ENCODING_ERR);\n                    } else {\n                        fail(error.code);\n                    }\n                } else {\n                    fail(error);\n                }\n            }\n        };\n    resolve(function (entry) {\n        requestAnimationFrame(function () {\n            entry.nativeEntry.getDirectory(dir, options, function (nativeEntry) {\n                resolve(function (entry) {\n                    onSuccess(entry);\n                }, onFail, [uri + \"/\" + dir]);\n            }, onFail);\n        });\n    }, onFail, [uri]);\n};\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/blackberry10/getFile.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/* \n * getFile\n *\n * IN:\n *  args\n *   0 - local filesytem URI for the base directory to search\n *   1 - file to be created/returned; may be absolute path or relative path\n *   2 - options object\n * OUT:\n *  success - FileEntry\n *  fail - FileError code\n */\n\nvar resolve = cordova.require('cordova-plugin-file.resolveLocalFileSystemURIProxy');\n\nmodule.exports = function (success, fail, args) {\n    var uri = args[0] === \"/\" ? \"\" : args[0] + \"/\" + args[1],\n        options = args[2],\n        onSuccess = function (entry) {\n            if (typeof(success) === 'function') {\n                success(entry);\n            }\n        },\n        onFail = function (code) {\n            if (typeof(fail) === 'function') {\n                fail(code);\n            }\n        };\n    resolve(function (entry) {\n        if (!entry.isFile) {\n            onFail(FileError.TYPE_MISMATCH_ERR);\n        } else {\n            onSuccess(entry);\n        }\n    }, onFail, [uri, options]);\n};\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/blackberry10/getFileMetadata.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/* \n * getFileMetadata\n *\n * IN:\n *  args\n *   0 - local filesytem URI\n * OUT:\n *  success - file\n *   - name\n *   - type\n *   - lastModifiedDate\n *   - size\n *  fail - FileError code\n */\n\nvar resolve = cordova.require('cordova-plugin-file.resolveLocalFileSystemURIProxy'),\n    requestAnimationFrame = cordova.require('cordova-plugin-file.bb10RequestAnimationFrame');\n\nmodule.exports = function (success, fail, args) {\n    var uri = args[0],\n        onSuccess = function (entry) {\n            if (typeof(success) === 'function') {\n                success(entry);\n            }\n        },\n        onFail = function (error) {\n            if (typeof(fail) === 'function') {\n                if (error.code) {\n                    fail(error.code);\n                } else {\n                    fail(error);\n                }\n            }\n        };\n    resolve(function (entry) {\n        requestAnimationFrame(function () {\n            if (entry.nativeEntry.file) {\n                entry.nativeEntry.file(onSuccess, onFail);\n            } else {\n                entry.nativeEntry.getMetadata(onSuccess, onFail);\n            }\n        });\n    }, onFail, [uri]);\n};\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/blackberry10/getMetadata.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/* \n * getMetadata\n *\n * IN:\n *  args\n *   0 - local filesytem URI\n * OUT:\n *  success - metadata\n *  fail - FileError code\n */\n\nvar resolve = cordova.require('cordova-plugin-file.resolveLocalFileSystemURIProxy');\n\nmodule.exports = function (success, fail, args) {\n    var uri = args[0],\n        onSuccess = function (entry) {\n            if (typeof(success) === 'function') {\n                success(entry);\n            }\n        },\n        onFail = function (error) {\n            if (typeof(fail) === 'function') {\n                if (error.code) {\n                    fail(error.code);\n                } else {\n                    fail(error);\n                }\n            }\n        };\n    resolve(function (entry) {\n        entry.nativeEntry.getMetadata(onSuccess, onFail);\n    }, onFail, [uri]);\n};\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/blackberry10/getParent.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/* \n * getParent\n *\n * IN:\n *  args\n *   0 - local filesytem URI\n * OUT:\n *  success - DirectoryEntry of parent\n *  fail - FileError code\n */\n\nvar resolve = cordova.require('cordova-plugin-file.resolveLocalFileSystemURIProxy'),\n    requestAnimationFrame = cordova.require('cordova-plugin-file.bb10RequestAnimationFrame');\n\nmodule.exports = function (success, fail, args) {\n    var uri = args[0],\n        onSuccess = function (entry) {\n            if (typeof(success) === 'function') {\n                success(entry);\n            }\n        },\n        onFail = function (error) {\n            if (typeof(fail) === 'function') {\n                if (error && error.code) {\n                    fail(error.code);\n                } else {\n                    fail(error);\n                }\n            }\n        };\n    resolve(function (entry) {\n        requestAnimationFrame(function () {\n            entry.nativeEntry.getParent(onSuccess, onFail);\n        });\n    }, onFail, [uri]);\n};\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/blackberry10/info.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/* \n * info\n *\n * persistentPath - full path to app sandboxed persistent storage\n * temporaryPath - full path to app sandboxed temporary storage\n * localPath - full path to app source (www dir)\n * MAX_SIZE - maximum size for filesystem request\n */\n\nvar info = {\n    persistentPath: \"\", \n    temporaryPath: \"\", \n    localPath: \"\",\n    MAX_SIZE: 64 * 1024 * 1024 * 1024\n};\n\ncordova.exec(\n    function (path) {\n        info.persistentPath = 'file://' + path + '/webviews/webfs/persistent/local__0';\n        info.temporaryPath = 'file://' + path + '/webviews/webfs/temporary/local__0';\n        info.localPath = path.replace('/data', '/app/native');\n    },\n    function () {\n        console.error('Unable to determine local storage file path');\n    },\n    'File',\n    'getHomePath',\n    false\n);\n\nmodule.exports = info;\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/blackberry10/moveTo.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/* \n * moveTo\n * \n * IN:\n *  args\n *   0 - URL of entry to move\n *   1 - URL of the directory into which to move the entry\n *   2 - the new name of the entry, defaults to the current name\n * OUT:\n *  success - entry for the copied file or directory\n *  fail - FileError\n */\n\nvar copy = cordova.require('cordova-plugin-file.copyToProxy');\n\nmodule.exports = function (success, fail, args) {\n    copy(success, fail, args, true);\n};\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/blackberry10/readAsArrayBuffer.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/* \n * readAsArrayBuffer\n * \n * IN:\n *  args\n *   0 - URL of file to read\n *   1 - start position\n *   2 - end position\n * OUT:\n *  success - ArrayBuffer of file\n *  fail - FileError\n */\n\nvar resolve = cordova.require('cordova-plugin-file.resolveLocalFileSystemURIProxy'),\n    requestAnimationFrame = cordova.require('cordova-plugin-file.bb10RequestAnimationFrame');\n\nmodule.exports = function (success, fail, args) {\n    var uri = args[0],\n        start = args[1],\n        end = args[2],\n        onSuccess = function (data) {\n            if (typeof success === 'function') {\n                success(data);\n            }\n        },\n        onFail = function (error) {\n            if (typeof fail === 'function') {\n                if (error && error.code) {\n                    fail(error.code);\n                } else {\n                    fail(error);\n                }\n            }\n        };\n    resolve(function (fs) {\n        requestAnimationFrame(function () {\n            fs.nativeEntry.file(function (file) {\n                var reader = new FileReader()._realReader;\n                reader.onloadend = function () {\n                    onSuccess(this.result.slice(start, end));\n                };\n                reader.onerror = onFail;\n                reader.readAsArrayBuffer(file); \n            }, onFail);\n        });\n    }, fail, [uri]);\n};\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/blackberry10/readAsBinaryString.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/* \n * readAsBinaryString\n * \n * IN:\n *  args\n *   0 - URL of file to read\n *   1 - start position\n *   2 - end position\n * OUT:\n *  success - BinaryString contents of file\n *  fail - FileError\n */\n\nvar resolve = cordova.require('cordova-plugin-file.resolveLocalFileSystemURIProxy'),\n    requestAnimationFrame = cordova.require('cordova-plugin-file.bb10RequestAnimationFrame');\n\nmodule.exports = function (success, fail, args) {\n    var uri = args[0],\n        start = args[1],\n        end = args[2],\n        onSuccess = function (data) {\n            if (typeof success === 'function') {\n                success(data);\n            }\n        },\n        onFail = function (error) {\n            if (typeof fail === 'function') {\n                if (error && error.code) {\n                    fail(error.code);\n                } else {\n                    fail(error);\n                }\n            }\n        };\n    resolve(function (fs) {\n        requestAnimationFrame(function () {\n            fs.nativeEntry.file(function (file) {\n                var reader = new FileReader()._realReader;\n                reader.onloadend = function () {\n                    onSuccess(this.result.substring(start, end));\n                };\n                reader.onerror = onFail;\n                reader.readAsBinaryString(file); \n            }, onFail);\n        });\n    }, fail, [uri]);\n};\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/blackberry10/readAsDataURL.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/* \n * readAsDataURL\n * \n * IN:\n *  args\n *   0 - URL of file to read\n * OUT:\n *  success - DataURL representation of file contents\n *  fail - FileError\n */\n\n\nvar resolve = cordova.require('cordova-plugin-file.resolveLocalFileSystemURIProxy'),\n    requestAnimationFrame = cordova.require('cordova-plugin-file.bb10RequestAnimationFrame');\n\nmodule.exports = function (success, fail, args) {\n    var uri = args[0],\n        onSuccess = function (data) {\n            if (typeof success === 'function') {\n                success(data);\n            }\n        },\n        onFail = function (error) {\n            if (typeof fail === 'function') {\n                if (error && error.code) {\n                    fail(error.code);\n                } else {\n                    fail(error);\n                }\n            }\n        };\n    resolve(function (fs) {\n        requestAnimationFrame(function () {\n            fs.nativeEntry.file(function (file) {\n                var reader = new FileReader()._realReader;\n                reader.onloadend = function () {\n                    onSuccess(this.result);\n                };\n                reader.onerror = onFail;\n                reader.readAsDataURL(file); \n            }, onFail);\n        });\n    }, fail, [uri]);\n};\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/blackberry10/readAsText.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/* \n * readAsText\n * \n * IN:\n *  args\n *   0 - URL of file to read\n *   1 - encoding\n *   2 - start position\n *   3 - end position\n * OUT:\n *  success - text contents of file\n *  fail - FileError\n */\n\n\nvar resolve = cordova.require('cordova-plugin-file.resolveLocalFileSystemURIProxy'),\n    requestAnimationFrame = cordova.require('cordova-plugin-file.bb10RequestAnimationFrame');\n\nmodule.exports = function (success, fail, args) {\n    var uri = args[0],\n        start = args[2],\n        end = args[3],\n        onSuccess = function (data) {\n            if (typeof success === 'function') {\n                success(data);\n            }\n        },\n        onFail = function (error) {\n            if (typeof fail === 'function') {\n                if (error && error.code) {\n                    fail(error.code);\n                } else {\n                    fail(error);\n                }\n            }\n        };\n    resolve(function (fs) {\n        requestAnimationFrame(function () {\n            fs.nativeEntry.file(function (file) {\n                var reader = new FileReader()._realReader;\n                reader.onloadend = function () {\n                    var contents = new Uint8Array(this.result).subarray(start, end),\n                        blob = new Blob([contents]),\n                        textReader = new FileReader()._realReader;\n                    textReader.onloadend = function () {\n                        onSuccess(this.result);\n                    };\n                    textReader.onerror = onFail;\n                    textReader.readAsText(blob);\n                };\n                reader.onerror = onFail;\n                reader.readAsArrayBuffer(file);\n            }, onFail);\n        });\n    }, fail, [uri]);\n};\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/blackberry10/readEntries.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/* \n * readEntries\n * \n * IN:\n *  args\n *   0 - URL of directory to list\n * OUT:\n *  success - Array of Entry objects\n *  fail - FileError\n */\n\nvar resolve = cordova.require('cordova-plugin-file.resolveLocalFileSystemURIProxy'),\n    requestAnimationFrame = cordova.require('cordova-plugin-file.bb10RequestAnimationFrame'),\n    createEntryFromNative = cordova.require('cordova-plugin-file.bb10CreateEntryFromNative');\n\nmodule.exports = function (success, fail, args) {\n    var uri = args[0],\n        onSuccess = function (data) {\n            if (typeof success === 'function') {\n                success(data);\n            }\n        },\n        onFail = function (error) {\n            if (typeof fail === 'function') {\n                if (error.code) {\n                    fail(error.code);\n                } else {\n                    fail(error);\n                }\n            }\n        };\n    resolve(function (fs) {\n        requestAnimationFrame(function () {\n            var reader = fs.nativeEntry.createReader(),\n                entries = [],\n                readEntries = function() {\n                    reader.readEntries(function (results) {\n                        if (!results.length) {\n                            onSuccess(entries.sort().map(createEntryFromNative));\n                        } else {\n                            entries = entries.concat(Array.prototype.slice.call(results || [], 0));\n                            readEntries();\n                        }\n                    }, onFail);\n                };\n            readEntries();\n        });\n    }, fail, [uri]);\n};\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/blackberry10/remove.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/* \n * remove\n * \n * IN:\n *  args\n *   0 - URL of Entry to remove\n * OUT:\n *  success - (no args)\n *  fail - FileError\n */\n\nvar resolve = cordova.require('cordova-plugin-file.resolveLocalFileSystemURIProxy'),\n    requestAnimationFrame = cordova.require('cordova-plugin-file.bb10RequestAnimationFrame');\n\nmodule.exports = function (success, fail, args) {\n    var uri = args[0],\n        onSuccess = function (data) {\n            if (typeof success === 'function') {\n                success(data);\n            }\n        },\n        onFail = function (error) {\n            if (typeof fail === 'function') {\n                if (error && error.code) {\n                    fail(error.code);\n                } else {\n                    fail(error);\n                }\n            }\n        };\n    resolve(function (fs) {\n        requestAnimationFrame(function () {\n            if (fs.fullPath === '/') {\n                onFail(FileError.NO_MODIFICATION_ALLOWED_ERR);\n            } else {\n                fs.nativeEntry.remove(onSuccess, onFail);\n            }\n        });\n    }, fail, [uri]);\n};\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/blackberry10/removeRecursively.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/* \n * removeRecursively\n * \n * IN:\n *  args\n *   0 - URL of DirectoryEntry to remove recursively\n * OUT:\n *  success - (no args)\n *  fail - FileError\n */\n\nvar resolve = cordova.require('cordova-plugin-file.resolveLocalFileSystemURIProxy'),\n    requestAnimationFrame = cordova.require('cordova-plugin-file.bb10RequestAnimationFrame');\n\nmodule.exports = function (success, fail, args) {\n    var uri = args[0],\n        onSuccess = function (data) {\n            if (typeof success === 'function') {\n                success(data);\n            }\n        },\n        onFail = function (error) {\n            if (typeof fail === 'function') {\n                if (error.code) {\n                    if (error.code === FileError.INVALID_MODIFICATION_ERR) {\n                        //mobile-spec expects this error code\n                        fail(FileError.NO_MODIFICATION_ALLOWED_ERR);\n                    } else {\n                        fail(error.code);\n                    }\n                } else {\n                    fail(error);\n                }\n            }\n        };\n    resolve(function (fs) {\n        requestAnimationFrame(function () {\n            fs.nativeEntry.removeRecursively(onSuccess, onFail);\n        }); \n    }, fail, [uri]);\n};\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/blackberry10/requestAllFileSystems.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/* \n * requestAllFileSystems\n * \n * IN - no arguments\n * OUT\n *  success - Array of FileSystems\n *   - filesystemName\n *   - fullPath\n *   - name\n *   - nativeURL\n */\n\nvar info = require('cordova-plugin-file.bb10FileSystemInfo');\n\nmodule.exports = function (success, fail, args) {\n    success([\n        { filesystemName: 'persistent', name: 'persistent', fullPath: '/', nativeURL: info.persistentPath + '/' },\n        { filesystemName: 'temporary', name: 'temporary', fullPath: '/', nativeURL: info.temporaryPath + '/' },\n        { filesystemName: 'root', name: 'root', fullPath: '/', nativeURL: 'file:///' }\n    ]);\n};\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/blackberry10/requestAnimationFrame.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/*\n * requestAnimationFrame\n * \n * This is used throughout the BB10 File implementation to wrap\n * native webkit calls. There is a bug in the webkit implementation\n * which causes callbacks to never return when multiple file system\n * APIs are called in sequence. This should also make the UI more\n * responsive during file operations.\n * \n * Supported on BB10 OS > 10.1\n */\n\nvar requestAnimationFrame = window.requestAnimationFrame;\nif (typeof(requestAnimationFrame) !== 'function') {\n    requestAnimationFrame = function (cb) { cb(); };\n}\nmodule.exports = requestAnimationFrame;\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/blackberry10/requestFileSystem.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/* \n * requestFileSystem\n *\n * IN:\n *  args \n *   0 - type (TEMPORARY = 0, PERSISTENT = 1)\n *   1 - size\n * OUT:\n *  success - FileSystem object\n *   - name - the human readable directory name\n *   - root - DirectoryEntry object\n *      - isDirectory\n *      - isFile\n *      - name\n *      - fullPath\n *  fail - FileError code\n */\n\nvar resolve = cordova.require('cordova-plugin-file.resolveLocalFileSystemURIProxy');\n\nmodule.exports = function (success, fail, args) {\n    var fsType = args[0] === 0 ? 'temporary' : 'persistent',\n        size = args[1],\n        onSuccess = function (fs) {\n            var directory = {\n                name: fsType,\n                root: fs\n            };\n            success(directory);\n        };\n    resolve(onSuccess, fail, ['cdvfile://localhost/' + fsType + '/', undefined, size]);\n};\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/blackberry10/resolveLocalFileSystemURI.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/*\n * resolveLocalFileSystemURI\n *\n * IN\n *  args\n *   0 - escaped local filesystem URI\n *   1 - options (standard HTML5 file system options)\n *   2 - size\n * OUT\n *  success - Entry object\n *   - isDirectory\n *   - isFile\n *   - name\n *   - fullPath\n *   - nativeURL\n *   - fileSystemName\n *  fail - FileError code\n */\n\nvar info = require('cordova-plugin-file.bb10FileSystemInfo'),\n    requestAnimationFrame = cordova.require('cordova-plugin-file.bb10RequestAnimationFrame'),\n    createEntryFromNative = require('cordova-plugin-file.bb10CreateEntryFromNative'),\n    SANDBOXED = true,\n    UNSANDBOXED = false;\n\nmodule.exports = function (success, fail, args) {\n    var request = args[0],\n        options = args[1],\n        size = args[2];\n    if (request) {\n        request = decodeURIComponent(request);\n        if (request.indexOf('?') > -1) {\n            //bb10 does not support params; strip them off\n            request = request.substring(0, request.indexOf('?'));\n        }\n        if (request.indexOf('file://localhost/') === 0) {\n            //remove localhost prefix\n            request = request.replace('file://localhost/', 'file:///');\n        }\n        //requests to sandboxed locations should use cdvfile\n        request = request.replace(info.persistentPath, 'cdvfile://localhost/persistent');\n        request = request.replace(info.temporaryPath, 'cdvfile://localhost/temporary');\n        //pick appropriate handler\n        if (request.indexOf('file:///') === 0) {\n            resolveFile(success, fail, request, options);\n        } else if (request.indexOf('cdvfile://localhost/') === 0) {\n            resolveCdvFile(success, fail, request, options, size);\n        } else if (request.indexOf('local:///') === 0) {\n            resolveLocal(success, fail, request, options);\n        } else {\n            fail(FileError.ENCODING_ERR);\n        }\n    } else {\n        fail(FileError.NOT_FOUND_ERR);\n    }\n};\n\n//resolve file:///\nfunction resolveFile(success, fail, request, options) {\n    var path = request.substring(7);\n    resolve(success, fail, path, window.PERSISTENT, UNSANDBOXED, options);\n}\n\n//resolve cdvfile://localhost/filesystemname/\nfunction resolveCdvFile(success, fail, request, options, size) {\n    var components = /cdvfile:\\/\\/localhost\\/([^\\/]+)\\/(.*)/.exec(request),\n        fsType = components[1],\n        path = components[2];\n    if (fsType === 'persistent') {\n        resolve(success, fail, path, window.PERSISTENT, SANDBOXED, options, size);\n    }\n    else if (fsType === 'temporary') {\n        resolve(success, fail, path, window.TEMPORARY, SANDBOXED, options, size);\n    }\n    else if (fsType === 'root') {\n        resolve(success, fail, path, window.PERSISTENT, UNSANDBOXED, options);\n    }\n    else {\n        fail(FileError.NOT_FOUND_ERR);\n    }\n}\n\n//resolve local:///\nfunction resolveLocal(success, fail, request, options) {\n    var path = localPath + request.substring(8);\n    resolve(success, fail, path, window.PERSISTENT, UNSANDBOXED, options);\n}\n\n//validate parameters and set sandbox\nfunction resolve(success, fail, path, fsType, sandbox, options, size) {\n    options = options || { create: false };\n    size = size || info.MAX_SIZE;\n    if (size > info.MAX_SIZE) {\n        //bb10 does not respect quota; fail at unreasonably large size\n        fail(FileError.QUOTA_EXCEEDED_ERR);\n    } else if (path.indexOf(':') > -1) {\n        //files with : character are not valid in Cordova apps \n        fail(FileError.ENCODING_ERR);\n    } else {\n        requestAnimationFrame(function () {\n            cordova.exec(function () {\n                requestAnimationFrame(function () {\n                    resolveNative(success, fail, path, fsType, options, size);\n                });\n            }, fail, 'File', 'setSandbox', [sandbox], false);\n        });\n    }\n}\n\n//find path using webkit file system\nfunction resolveNative(success, fail, path, fsType, options, size) {\n    window.webkitRequestFileSystem(\n        fsType,\n        size,\n        function (fs) {\n            if (path === '') {\n                //no path provided, call success with root file system\n                success(createEntryFromNative(fs.root));\n            } else {\n                //otherwise attempt to resolve as file\n                fs.root.getFile(\n                    path,\n                    options,\n                    function (entry) {\n                        success(createEntryFromNative(entry));\n                    },\n                    function (fileError) {\n                        //file not found, attempt to resolve as directory\n                        fs.root.getDirectory(\n                            path,\n                            options,\n                            function (entry) {\n                                success(createEntryFromNative(entry));\n                            },\n                            function (dirError) {\n                                //path cannot be resolved\n                                if (fileError.code === FileError.INVALID_MODIFICATION_ERR && \n                                    options.exclusive) {\n                                    //mobile-spec expects this error code\n                                    fail(FileError.PATH_EXISTS_ERR);\n                                } else {\n                                    fail(FileError.NOT_FOUND_ERR);\n                                }\n                            }\n                        );\n                    }\n                );\n            }\n        }\n    );\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/blackberry10/setMetadata.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/* \n * setMetadata\n * \n * BB10 OS does not support setting file metadata via HTML5 File System \n */\n\nmodule.exports = function (success, fail, args) {\n    console.error(\"setMetadata not supported on BB10\", arguments);\n    if (typeof(fail) === 'function') {\n        fail();\n    }\n};\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/blackberry10/truncate.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/* \n * truncate\n * \n * IN:\n *  args\n *   0 - URL of file to truncate\n *   1 - start position\n * OUT:\n *  success - new length of file\n *  fail - FileError\n */\n\nvar resolve = cordova.require('cordova-plugin-file.resolveLocalFileSystemURIProxy'),\n    requestAnimationFrame = cordova.require('cordova-plugin-file.bb10RequestAnimationFrame');\n\nmodule.exports = function (success, fail, args) {\n    var uri = args[0],\n        length = args[1],\n        onSuccess = function (data) {\n            if (typeof success === 'function') {\n                success(data.loaded);\n            }\n        },\n        onFail = function (error) {\n            if (typeof fail === 'function') {\n                if (error && error.code) {\n                    fail(error.code);\n                } else {\n                    fail(error);\n                }\n            }\n        };\n    resolve(function (fs) {\n        requestAnimationFrame(function () {\n            fs.nativeEntry.file(function (file) {\n                var reader = new FileReader()._realReader;\n                reader.onloadend = function () {\n                    var contents = new Uint8Array(this.result).subarray(0, length),\n                        blob = new Blob([contents]);\n                    window.requestAnimationFrame(function () {\n                        fs.nativeEntry.createWriter(function (fileWriter) {\n                            fileWriter.onwriteend = onSuccess;\n                            fileWriter.onerror = onFail;\n                            fileWriter.write(blob);\n                        }, onFail);\n                    });\n                };\n                reader.onerror = onFail;\n                reader.readAsArrayBuffer(file);\n            }, onFail);\n        });\n    }, onFail, [uri]);\n};\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/blackberry10/write.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/* \n * write\n * \n * IN:\n *  args\n *   0 - URL of file to write\n *   1 - data to write\n *   2 - offset\n *   3 - isBinary\n * OUT:\n *  success - bytes written\n *  fail - FileError\n */\n\nvar resolve = cordova.require('cordova-plugin-file.resolveLocalFileSystemURIProxy'),\n    requestAnimationFrame = cordova.require('cordova-plugin-file.bb10RequestAnimationFrame');\n\nmodule.exports = function (success, fail, args) {\n    var uri = args[0],\n        data = args[1],\n        offset = args[2],\n        //isBinary = args[3],\n        onSuccess = function (data) {\n            if (typeof success === 'function') {\n                success(data.loaded);\n            }\n        },\n        onFail = function (error) {\n            if (typeof fail === 'function') {\n                if (error && error.code) {\n                    fail(error.code);\n                } else if (error && error.target && error.target.code) {\n                    fail(error.target.code);\n                } else {\n                    fail(error);\n                }\n            }\n        };\n    resolve(function (fs) {\n        requestAnimationFrame(function () {\n            fs.nativeEntry.createWriter(function (writer) {\n                var blob = new Blob([data]);\n                if (offset) {\n                    writer.seek(offset);\n                }\n                writer.onwriteend = onSuccess;\n                writer.onerror = onFail;\n                writer.write(blob);\n            }, onFail);\n        });\n    }, fail, [uri, { create: true }]);\n};\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/browser/FileSystem.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/*global FILESYSTEM_PREFIX: true, module*/\n\nFILESYSTEM_PREFIX = \"file:///\";\n\nmodule.exports = {\n    __format__: function(fullPath) {\n        return (FILESYSTEM_PREFIX + this.name + (fullPath[0] === '/' ? '' : '/') + FileSystem.encodeURIPath(fullPath));\n    }\n};\n\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/browser/Preparing.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n(function () {\n    /*global require*/\n\n    //Only Chrome uses this file.\n    if (!require('./isChrome')()) {\n        return;\n    }\n\n    var channel = require('cordova/channel');\n    var FileError = require('./FileError');\n    var PERSISTENT_FS_QUOTA = 5 * 1024 * 1024;\n    var filePluginIsReadyEvent = new Event('filePluginIsReady');\n\n    var entryFunctionsCreated = false;\n    var quotaWasRequested = false;\n    var eventWasThrown = false;\n\n    if (!window.requestFileSystem) {\n        window.requestFileSystem = function(type, size, win, fail) {\n            if (fail) {\n                fail(\"Not supported\");\n            }\n        };\n    } else {\n        window.requestFileSystem(window.TEMPORARY, 1, createFileEntryFunctions, function() {});\n    }\n\n    if (!window.resolveLocalFileSystemURL) {\n        window.resolveLocalFileSystemURL = function(url, win, fail) {\n            if(fail) {\n                fail(\"Not supported\");\n            }\n        };\n    }\n\n    // Resolves a filesystem entry by its path - which is passed either in standard (filesystem:file://) or\n    // Cordova-specific (cdvfile://) universal way.\n    // Aligns with specification: http://www.w3.org/TR/2011/WD-file-system-api-20110419/#widl-LocalFileSystem-resolveLocalFileSystemURL\n    var nativeResolveLocalFileSystemURL = window.resolveLocalFileSystemURL || window.webkitResolveLocalFileSystemURL;\n    window.resolveLocalFileSystemURL = function(url, win, fail) {\n        /* If url starts with `cdvfile` then we need convert it to Chrome real url first:\n          cdvfile://localhost/persistent/path/to/file -> filesystem:file://persistent/path/to/file */\n        if (url.trim().substr(0,7) === \"cdvfile\") {\n            /* Quirk:\n            Plugin supports cdvfile://localhost (local resources) only.\n            I.e. external resources are not supported via cdvfile. */\n            if (url.indexOf(\"cdvfile://localhost\") !== -1) {\n                // Browser supports temporary and persistent only\n                var indexPersistent = url.indexOf('persistent');\n                var indexTemporary = url.indexOf('temporary');\n\n                /* Chrome urls start with 'filesystem:' prefix. See quirk:\n                   toURL function in Chrome returns filesystem:-prefixed path depending on application host.\n                   For example, filesystem:file:///persistent/somefile.txt,\n                   filesystem:http://localhost:8080/persistent/somefile.txt. */\n                var prefix = 'filesystem:file:///';\n                if (location.protocol !== 'file:') {\n                    prefix = 'filesystem:' + location.origin + '/';\n                }\n\n                var result;\n                if (indexPersistent !== -1) {\n                    // cdvfile://localhost/persistent/path/to/file -> filesystem:file://persistent/path/to/file\n                    // or filesystem:http://localhost:8080/persistent/path/to/file\n                    result =  prefix + 'persistent' + url.substr(indexPersistent + 10);\n                    nativeResolveLocalFileSystemURL(result, win, fail);\n                    return;\n                }\n\n                if (indexTemporary !== -1) {\n                    // cdvfile://localhost/temporary/path/to/file -> filesystem:file://temporary/path/to/file\n                    // or filesystem:http://localhost:8080/temporary/path/to/file\n                    result = prefix + 'temporary' + url.substr(indexTemporary + 9);\n                    nativeResolveLocalFileSystemURL(result, win, fail);\n                    return;\n                }\n            }\n\n            // cdvfile other than local file resource is not supported\n            if (fail) {\n                fail(new FileError(FileError.ENCODING_ERR));\n            }\n        } else {\n            nativeResolveLocalFileSystemURL(url, win, fail);\n        }\n    };\n\n    function createFileEntryFunctions(fs) {\n        fs.root.getFile('todelete_658674_833_4_cdv', {create: true}, function(fileEntry) {\n            var fileEntryType = Object.getPrototypeOf(fileEntry);\n            var entryType = Object.getPrototypeOf(fileEntryType);\n\n            // Save the original method\n            var origToURL = entryType.toURL;\n            entryType.toURL = function () {\n                var origURL = origToURL.call(this);\n                if (this.isDirectory && origURL.substr(-1) !== '/') {\n                    return origURL + '/';\n                }\n                return origURL;\n            };\n\n            entryType.toNativeURL = function () {\n                console.warn(\"DEPRECATED: Update your code to use 'toURL'\");\n                return this.toURL();\n            };\n\n            entryType.toInternalURL = function() {\n                if (this.toURL().indexOf(\"persistent\") > -1) {\n                    return \"cdvfile://localhost/persistent\" + this.fullPath;\n                }\n\n                if (this.toURL().indexOf(\"temporary\") > -1) {\n                    return \"cdvfile://localhost/temporary\" + this.fullPath;\n                }\n            };\n\n            entryType.setMetadata = function(win, fail /*, metadata*/) {\n                if (fail) {\n                    fail(\"Not supported\");\n                }\n            };\n\n            fileEntry.createWriter(function(writer) {\n                var originalWrite = writer.write;\n                var writerProto = Object.getPrototypeOf(writer);\n                writerProto.write = function(blob) {\n                    if(blob instanceof Blob) {\n                        originalWrite.apply(this, [blob]);\n                    } else {\n                        var realBlob = new Blob([blob]);\n                        originalWrite.apply(this, [realBlob]);\n                   }\n                };\n\n                fileEntry.remove(function(){ entryFunctionsCreated = true; }, function(){ /* empty callback */ });\n          });\n        });\n    }\n\n    window.initPersistentFileSystem = function(size, win, fail) {\n        if (navigator.webkitPersistentStorage) {\n            navigator.webkitPersistentStorage.requestQuota(size, win, fail);\n            return;\n        }\n\n        fail(\"This browser does not support this function\");\n    };\n\n    window.isFilePluginReadyRaised = function () { return eventWasThrown; };\n\n    window.initPersistentFileSystem(PERSISTENT_FS_QUOTA, function() {\n        console.log('Persistent fs quota granted');\n        quotaWasRequested = true;\n    }, function(e){\n        console.log('Error occured while trying to request Persistent fs quota: ' + JSON.stringify(e));\n    });\n\n    channel.onCordovaReady.subscribe(function () {\n        function dispatchEventIfReady() {\n            if (entryFunctionsCreated && quotaWasRequested) {\n                window.dispatchEvent(filePluginIsReadyEvent);\n                eventWasThrown = true;\n            } else {\n                setTimeout(dispatchEventIfReady, 100);\n            }\n        }\n\n        dispatchEventIfReady();\n    }, false);\n})();\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/browser/isChrome.js",
    "content": "/*\r\n *\r\n * Licensed to the Apache Software Foundation (ASF) under one\r\n * or more contributor license agreements.  See the NOTICE file\r\n * distributed with this work for additional information\r\n * regarding copyright ownership.  The ASF licenses this file\r\n * to you under the Apache License, Version 2.0 (the\r\n * \"License\"); you may not use this file except in compliance\r\n * with the License.  You may obtain a copy of the License at\r\n *\r\n *   http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing,\r\n * software distributed under the License is distributed on an\r\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\r\n * KIND, either express or implied.  See the License for the\r\n * specific language governing permissions and limitations\r\n * under the License.\r\n *\r\n */\r\n\r\nmodule.exports = function () {\r\n    // window.webkitRequestFileSystem and window.webkitResolveLocalFileSystemURL are available only in Chrome and\r\n    // possibly a good flag to indicate that we're running in Chrome\r\n    return window.webkitRequestFileSystem && window.webkitResolveLocalFileSystemURL;\r\n};\r\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/fileSystemPaths.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\nvar exec = require('cordova/exec');\nvar channel = require('cordova/channel');\n\nexports.file = {\n    // Read-only directory where the application is installed.\n    applicationDirectory: null,\n    // Root of app's private writable storage\n    applicationStorageDirectory: null,\n    // Where to put app-specific data files.\n    dataDirectory: null,\n    // Cached files that should survive app restarts.\n    // Apps should not rely on the OS to delete files in here.\n    cacheDirectory: null,\n    // Android: the application space on external storage.\n    externalApplicationStorageDirectory: null,\n    // Android: Where to put app-specific data files on external storage.\n    externalDataDirectory: null,\n    // Android: the application cache on external storage.\n    externalCacheDirectory: null,\n    // Android: the external storage (SD card) root.\n    externalRootDirectory: null,\n    // iOS: Temp directory that the OS can clear at will.\n    tempDirectory: null,\n    // iOS: Holds app-specific files that should be synced (e.g. to iCloud).\n    syncedDataDirectory: null,\n    // iOS: Files private to the app, but that are meaningful to other applications (e.g. Office files)\n    documentsDirectory: null,\n    // BlackBerry10: Files globally available to all apps\n    sharedDirectory: null\n};\n\nchannel.waitForInitialization('onFileSystemPathsReady');\nchannel.onCordovaReady.subscribe(function() {\n    function after(paths) {\n        for (var k in paths) {\n            exports.file[k] = paths[k];\n        }\n        channel.initializationComplete('onFileSystemPathsReady');\n    }\n    exec(after, null, 'File', 'requestAllPaths', []);\n});\n\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/fileSystems-roots.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n// Map of fsName -> FileSystem.\nvar fsMap = null;\nvar FileSystem = require('./FileSystem');\nvar exec = require('cordova/exec');\n\n// Overridden by Android, BlackBerry 10 and iOS to populate fsMap.\nrequire('./fileSystems').getFs = function(name, callback) {\n    function success(response) {\n        fsMap = {};\n        for (var i = 0; i < response.length; ++i) {\n            var fsRoot = response[i];\n            var fs = new FileSystem(fsRoot.filesystemName, fsRoot);\n            fsMap[fs.name] = fs;\n        }\n        callback(fsMap[name]);\n    }\n\n    if (fsMap) {\n        callback(fsMap[name]);\n    } else {\n        exec(success, null, \"File\", \"requestAllFileSystems\", []);\n    }\n};\n\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/fileSystems.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n// Overridden by Android, BlackBerry 10 and iOS to populate fsMap.\nmodule.exports.getFs = function(name, callback) {\n    callback(null);\n};\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/firefoxos/FileSystem.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\nFILESYSTEM_PREFIX = \"file:///\";\n\nmodule.exports = {\n    __format__: function(fullPath) {\n        return (FILESYSTEM_PREFIX + this.name + (fullPath[0] === '/' ? '' : '/') + FileSystem.encodeURIPath(fullPath));\n    }\n};\n\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/ios/FileSystem.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\nFILESYSTEM_PROTOCOL = \"cdvfile\";\n\nmodule.exports = {\n    __format__: function(fullPath) {\n        var path = ('/'+this.name+(fullPath[0]==='/'?'':'/')+FileSystem.encodeURIPath(fullPath)).replace('//','/');\n        return FILESYSTEM_PROTOCOL + '://localhost' + path;\n    }\n};\n\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/osx/FileSystem.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\nFILESYSTEM_PROTOCOL = \"cdvfile\";\n\nmodule.exports = {\n    __format__: function(fullPath) {\n        var path = ('/'+this.name+(fullPath[0]==='/'?'':'/')+FileSystem.encodeURIPath(fullPath)).replace('//','/');\n        return FILESYSTEM_PROTOCOL + '://localhost' + path;\n    }\n};\n\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/requestFileSystem.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n(function() {\n    //For browser platform: not all browsers use this file.\n    function checkBrowser() {\n        if (cordova.platformId === \"browser\" && require('./isChrome')()) {\n            module.exports = window.requestFileSystem || window.webkitRequestFileSystem;\n            return true;\n        }\n        return false;\n    }\n    if (checkBrowser()) {\n        return;\n    }\n\n    var argscheck = require('cordova/argscheck'),\n        FileError = require('./FileError'),\n        FileSystem = require('./FileSystem'),\n        exec = require('cordova/exec');\n    var fileSystems = require('./fileSystems');\n\n    /**\n     * Request a file system in which to store application data.\n     * @param type  local file system type\n     * @param size  indicates how much storage space, in bytes, the application expects to need\n     * @param successCallback  invoked with a FileSystem object\n     * @param errorCallback  invoked if error occurs retrieving file system\n     */\n    var requestFileSystem = function(type, size, successCallback, errorCallback) {\n        argscheck.checkArgs('nnFF', 'requestFileSystem', arguments);\n        var fail = function(code) {\n            if (errorCallback) {\n                errorCallback(new FileError(code));\n            }\n        };\n\n        if (type < 0) {\n            fail(FileError.SYNTAX_ERR);\n        } else {\n            // if successful, return a FileSystem object\n            var success = function(file_system) {\n                if (file_system) {\n                    if (successCallback) {\n                        fileSystems.getFs(file_system.name, function(fs) {\n                            // This should happen only on platforms that haven't implemented requestAllFileSystems (windows)\n                            if (!fs) {\n                                fs = new FileSystem(file_system.name, file_system.root);\n                            }\n                            successCallback(fs);\n                        });\n                    }\n                }\n                else {\n                    // no FileSystem object returned\n                    fail(FileError.NOT_FOUND_ERR);\n                }\n            };\n            exec(success, fail, \"File\", \"requestFileSystem\", [type, size]);\n        }\n    };\n\n    module.exports = requestFileSystem;\n})();\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/resolveLocalFileSystemURI.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n(function() {\n    //For browser platform: not all browsers use overrided `resolveLocalFileSystemURL`.\n    function checkBrowser() {\n        if (cordova.platformId === \"browser\" && require('./isChrome')()) {\n            module.exports.resolveLocalFileSystemURL = window.resolveLocalFileSystemURL || window.webkitResolveLocalFileSystemURL;\n            return true;\n        }\n        return false;\n    }\n    if (checkBrowser()) {\n        return;\n    }\n\n    var argscheck = require('cordova/argscheck'),\n        DirectoryEntry = require('./DirectoryEntry'),\n        FileEntry = require('./FileEntry'),\n        FileError = require('./FileError'),\n        exec = require('cordova/exec');\n    var fileSystems = require('./fileSystems');\n\n    /**\n     * Look up file system Entry referred to by local URI.\n     * @param {DOMString} uri  URI referring to a local file or directory\n     * @param successCallback  invoked with Entry object corresponding to URI\n     * @param errorCallback    invoked if error occurs retrieving file system entry\n     */\n    module.exports.resolveLocalFileSystemURL = module.exports.resolveLocalFileSystemURL || function(uri, successCallback, errorCallback) {\n        argscheck.checkArgs('sFF', 'resolveLocalFileSystemURI', arguments);\n        // error callback\n        var fail = function(error) {\n            if (errorCallback) {\n                errorCallback(new FileError(error));\n            }\n        };\n        // sanity check for 'not:valid:filename' or '/not:valid:filename'\n        // file.spec.12 window.resolveLocalFileSystemURI should error (ENCODING_ERR) when resolving invalid URI with leading /.\n        if(!uri || uri.split(\":\").length > 2) {\n            setTimeout( function() {\n                fail(FileError.ENCODING_ERR);\n            },0);\n            return;\n        }\n        // if successful, return either a file or directory entry\n        var success = function(entry) {\n            if (entry) {\n                if (successCallback) {\n                    // create appropriate Entry object\n                    var fsName = entry.filesystemName || (entry.filesystem && entry.filesystem.name) || (entry.filesystem == window.PERSISTENT ? 'persistent' : 'temporary');\n                    fileSystems.getFs(fsName, function(fs) {\n                        // This should happen only on platforms that haven't implemented requestAllFileSystems (windows)\n                        if (!fs) {\n                            fs = new FileSystem(fsName, {name:\"\", fullPath:\"/\"});\n                        }\n                        var result = (entry.isDirectory) ? new DirectoryEntry(entry.name, entry.fullPath, fs, entry.nativeURL) : new FileEntry(entry.name, entry.fullPath, fs, entry.nativeURL);\n                        successCallback(result);\n                    });\n                }\n            }\n            else {\n                // no Entry object returned\n                fail(FileError.NOT_FOUND_ERR);\n            }\n        };\n\n        exec(success, fail, \"File\", \"resolveLocalFileSystemURI\", [uri]);\n    };\n\n    module.exports.resolveLocalFileSystemURI = function() {\n        console.log(\"resolveLocalFileSystemURI is deprecated. Please call resolveLocalFileSystemURL instead.\");\n        module.exports.resolveLocalFileSystemURL.apply(this, arguments);\n    };\n})();\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/ubuntu/FileSystem.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\nFILESYSTEM_PROTOCOL = \"cdvfile\";\n\nmodule.exports = {\n    __format__: function(fullPath) {\n        if (this.name === 'content') {\n            return 'content:/' + fullPath;\n        }\n        var path = ('/' + this.name + (fullPath[0] === '/' ? '' : '/') + FileSystem.encodeURIPath(fullPath)).replace('//','/');\n\n        return FILESYSTEM_PROTOCOL + '://localhost' + path;\n    }\n};\n\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/ubuntu/FileWriter.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\nvar exec = require('cordova/exec'),\n    FileError = require('./FileError'),\n    ProgressEvent = require('./ProgressEvent');\n\nfunction write(data) {\n    var that=this;\n    var supportsBinary = (typeof window.Blob !== 'undefined' && typeof window.ArrayBuffer !== 'undefined');\n    var isBinary;\n\n    // Check to see if the incoming data is a blob\n    if (data instanceof File || (supportsBinary && data instanceof Blob)) {\n        var fileReader = new FileReader();\n        fileReader.onload = function() {\n            // Call this method again, with the arraybuffer as argument\n            FileWriter.prototype.write.call(that, this.result);\n        };\n        if (supportsBinary) {\n            fileReader.readAsArrayBuffer(data);\n        } else {\n            fileReader.readAsText(data);\n        }\n        return;\n    }\n\n    // Mark data type for safer transport over the binary bridge\n    isBinary = supportsBinary && (data instanceof ArrayBuffer);\n\n    // Throw an exception if we are already writing a file\n    if (this.readyState === FileWriter.WRITING) {\n        throw new FileError(FileError.INVALID_STATE_ERR);\n    }\n\n    // WRITING state\n    this.readyState = FileWriter.WRITING;\n\n    var me = this;\n\n    // If onwritestart callback\n    if (typeof me.onwritestart === \"function\") {\n        me.onwritestart(new ProgressEvent(\"writestart\", {\"target\":me}));\n    }\n\n    if (data instanceof ArrayBuffer || data.buffer instanceof ArrayBuffer) {\n        data = new Uint8Array(data);\n    var binary = \"\";\n    for (var i = 0; i < data.byteLength; i++) {\n            binary += String.fromCharCode(data[i]);\n    }\n        data = binary;\n    }\n\n    var prefix = \"file://localhost\";\n    var path = this.localURL;\n    if (path.substr(0, prefix.length) == prefix) {\n        path = path.substr(prefix.length);\n    }\n    // Write file\n    exec(\n        // Success callback\n        function(r) {\n            // If DONE (cancelled), then don't do anything\n            if (me.readyState === FileWriter.DONE) {\n                return;\n            }\n\n            // position always increases by bytes written because file would be extended\n            me.position += r;\n            // The length of the file is now where we are done writing.\n\n            me.length = me.position;\n\n            // DONE state\n            me.readyState = FileWriter.DONE;\n\n            // If onwrite callback\n            if (typeof me.onwrite === \"function\") {\n                me.onwrite(new ProgressEvent(\"write\", {\"target\":me}));\n            }\n\n            // If onwriteend callback\n            if (typeof me.onwriteend === \"function\") {\n                me.onwriteend(new ProgressEvent(\"writeend\", {\"target\":me}));\n            }\n        },\n        // Error callback\n        function(e) {\n            // If DONE (cancelled), then don't do anything\n            if (me.readyState === FileWriter.DONE) {\n                return;\n            }\n\n            // DONE state\n            me.readyState = FileWriter.DONE;\n\n            // Save error\n            me.error = new FileError(e);\n\n            // If onerror callback\n            if (typeof me.onerror === \"function\") {\n                me.onerror(new ProgressEvent(\"error\", {\"target\":me}));\n            }\n\n            // If onwriteend callback\n            if (typeof me.onwriteend === \"function\") {\n                me.onwriteend(new ProgressEvent(\"writeend\", {\"target\":me}));\n            }\n        }, \"File\", \"write\", [path, data, this.position, isBinary]);\n}\n\nmodule.exports = {\n    write: write\n};\n\nrequire(\"cordova/exec/proxy\").add(\"FileWriter\", module.exports);\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/ubuntu/fileSystems-roots.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\nvar fsMap = null;\nvar FileSystem = require('./FileSystem');\nvar LocalFileSystem = require('./LocalFileSystem');\nvar exec = require('cordova/exec');\n\nvar requestFileSystem = function(type, size, successCallback) {\n    var success = function(file_system) {\n        if (file_system) {\n            if (successCallback) {\n                var fs = new FileSystem(file_system.name, file_system.root);\n                successCallback(fs);\n            }\n        }\n    };\n    exec(success, null, \"File\", \"requestFileSystem\", [type, size]);\n};\n\nrequire('./fileSystems').getFs = function(name, callback) {\n    if (fsMap) {\n        callback(fsMap[name]);\n    } else {\n        requestFileSystem(LocalFileSystem.PERSISTENT, 1, function(fs) {\n            requestFileSystem(LocalFileSystem.TEMPORARY, 1, function(tmp) {\n                fsMap = {};\n                fsMap[tmp.name] = tmp;\n                fsMap[fs.name] = fs;\n                callback(fsMap[name]);\n            });\n        });\n    }\n};\n\n"
  },
  {
    "path": "plugins/cordova-plugin-file/www/wp/FileUploadOptions.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/**\n * Options to customize the HTTP request used to upload files.\n * @constructor\n * @param fileKey {String}   Name of file request parameter.\n * @param fileName {String}  Filename to be used by the server. Defaults to image.jpg.\n * @param mimeType {String}  Mimetype of the uploaded file. Defaults to image/jpeg.\n * @param params {Object}    Object with key: value params to send to the server.\n */\nvar FileUploadOptions = function(fileKey, fileName, mimeType, params, headers, httpMethod) {\n    this.fileKey = fileKey || null;\n    this.fileName = fileName || null;\n    this.mimeType = mimeType || null;\n    this.headers = headers || null;\n    this.httpMethod = httpMethod || null;\n\n    if(params && typeof params != typeof \"\") {\n        var arrParams = [];\n        for(var v in params) {\n            arrParams.push(v + \"=\" + params[v]);\n        }\n        this.params = encodeURIComponent(arrParams.join(\"&\"));\n    }\n    else {\n        this.params = params || null;\n    }\n};\n\nmodule.exports = FileUploadOptions;\n"
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/CONTRIBUTING.md",
    "content": "<!--\n#\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#  KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n#\n-->\n\n# Contributing to Apache Cordova\n\nAnyone can contribute to Cordova. And we need your contributions.\n\nThere are multiple ways to contribute: report bugs, improve the docs, and\ncontribute code.\n\nFor instructions on this, start with the \n[contribution overview](http://cordova.apache.org/contribute/).\n\nThe details are explained there, but the important items are:\n - Sign and submit an Apache ICLA (Contributor License Agreement).\n - Have a Jira issue open that corresponds to your contribution.\n - Run the tests so your patch doesn't break existing functionality.\n\nWe look forward to your contributions!\n"
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License."
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/NOTICE",
    "content": "Apache Cordova\nCopyright 2012 The Apache Software Foundation\n\nThis product includes software developed at\nThe Apache Software Foundation (http://www.apache.org/).\n\nThis product includes a copy of OkHttp from:\nhttps://github.com/square/okhttp\n"
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-file-transfer.svg?branch=master)](https://travis-ci.org/apache/cordova-plugin-file-transfer)\n\n# cordova-plugin-file-transfer\n\nThis plugin allows you to upload and download files.\n\nThis plugin defines global `FileTransfer`, `FileUploadOptions` constructors. Although in the global scope, they are not available until after the `deviceready` event.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(FileTransfer);\n    }\n\nReport issues with this plugin on the [Apache Cordova issue tracker](https://issues.apache.org/jira/issues/?jql=project%20%3D%20CB%20AND%20status%20in%20%28Open%2C%20%22In%20Progress%22%2C%20Reopened%29%20AND%20resolution%20%3D%20Unresolved%20AND%20component%20%3D%20%22Plugin%20File%20Transfer%22%20ORDER%20BY%20priority%20DESC%2C%20summary%20ASC%2C%20updatedDate%20DESC)\n\n## Installation\n\n    cordova plugin add cordova-plugin-file-transfer\n\n## Supported Platforms\n\n- Amazon Fire OS\n- Android\n- BlackBerry 10\n- Browser\n- Firefox OS**\n- iOS\n- Windows Phone 7 and 8*\n- Windows\n\n\\* _Do not support `onprogress` nor `abort()`_\n\n\\** _Do not support `onprogress`_\n\n# FileTransfer\n\nThe `FileTransfer` object provides a way to upload files using an HTTP\nmulti-part POST or PUT request, and to download files.\n\n## Properties\n\n- __onprogress__: Called with a `ProgressEvent` whenever a new chunk of data is transferred. _(Function)_\n\n## Methods\n\n- __upload__: Sends a file to a server.\n\n- __download__: Downloads a file from server.\n\n- __abort__: Aborts an in-progress transfer.\n\n\n## upload\n\n__Parameters__:\n\n- __fileURL__: Filesystem URL representing the file on the device or a [data URI](https://en.wikipedia.org/wiki/Data_URI_scheme). For backwards compatibility, this can also be the full path of the file on the device. (See [Backwards Compatibility Notes](#backwards-compatibility-notes) below)\n\n- __server__: URL of the server to receive the file, as encoded by `encodeURI()`.\n\n- __successCallback__: A callback that is passed a `FileUploadResult` object. _(Function)_\n\n- __errorCallback__: A callback that executes if an error occurs retrieving the `FileUploadResult`. Invoked with a `FileTransferError` object. _(Function)_\n\n- __options__: Optional parameters _(Object)_. Valid keys:\n  - __fileKey__: The name of the form element.  Defaults to `file`. (DOMString)\n  - __fileName__: The file name to use when saving the file on the server.  Defaults to `image.jpg`. (DOMString)\n  - __httpMethod__: The HTTP method to use - either `PUT` or `POST`. Defaults to `POST`. (DOMString)\n  - __mimeType__: The mime type of the data to upload.  Defaults to `image/jpeg`. (DOMString)\n  - __params__: A set of optional key/value pairs to pass in the HTTP request. (Object, key/value - DOMString)\n  - __chunkedMode__: Whether to upload the data in chunked streaming mode. Defaults to `true`. (Boolean)\n  - __headers__: A map of header name/header values. Use an array to specify more than one value.  On iOS, FireOS, and Android, if a header named Content-Type is present, multipart form data will NOT be used. (Object)\n\n- __trustAllHosts__: Optional parameter, defaults to `false`. If set to `true`, it accepts all security certificates. This is useful since Android rejects self-signed security certificates. Not recommended for production use. Supported on Android and iOS. _(boolean)_\n\n### Example\n\n    // !! Assumes variable fileURL contains a valid URL to a text file on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/file.txt\n\n    var win = function (r) {\n        console.log(\"Code = \" + r.responseCode);\n        console.log(\"Response = \" + r.response);\n        console.log(\"Sent = \" + r.bytesSent);\n    }\n\n    var fail = function (error) {\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n\n    var options = new FileUploadOptions();\n    options.fileKey = \"file\";\n    options.fileName = fileURL.substr(fileURL.lastIndexOf('/') + 1);\n    options.mimeType = \"text/plain\";\n\n    var params = {};\n    params.value1 = \"test\";\n    params.value2 = \"param\";\n\n    options.params = params;\n\n    var ft = new FileTransfer();\n    ft.upload(fileURL, encodeURI(\"http://some.server.com/upload.php\"), win, fail, options);\n\n### Example with Upload Headers and Progress Events (Android and iOS only)\n\n    function win(r) {\n        console.log(\"Code = \" + r.responseCode);\n        console.log(\"Response = \" + r.response);\n        console.log(\"Sent = \" + r.bytesSent);\n    }\n\n    function fail(error) {\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n\n    var uri = encodeURI(\"http://some.server.com/upload.php\");\n\n    var options = new FileUploadOptions();\n    options.fileKey=\"file\";\n    options.fileName=fileURL.substr(fileURL.lastIndexOf('/')+1);\n    options.mimeType=\"text/plain\";\n\n    var headers={'headerParam':'headerValue'};\n\n    options.headers = headers;\n\n    var ft = new FileTransfer();\n    ft.onprogress = function(progressEvent) {\n        if (progressEvent.lengthComputable) {\n          loadingStatus.setPercentage(progressEvent.loaded / progressEvent.total);\n        } else {\n          loadingStatus.increment();\n        }\n    };\n    ft.upload(fileURL, uri, win, fail, options);\n\n## FileUploadResult\n\nA `FileUploadResult` object is passed to the success callback of the\n`FileTransfer` object's `upload()` method.\n\n### Properties\n\n- __bytesSent__: The number of bytes sent to the server as part of the upload. (long)\n\n- __responseCode__: The HTTP response code returned by the server. (long)\n\n- __response__: The HTTP response returned by the server. (DOMString)\n\n- __headers__: The HTTP response headers by the server. (Object)\n  - Currently supported on iOS only.\n\n### iOS Quirks\n\n- Does not support `responseCode` or `bytesSent`.\n\n### Browser Quirks\n\n- __withCredentials__: _boolean_ that tells the browser to set the withCredentials flag on the XMLHttpRequest\n\n### Windows Quirks\n\n- An option parameter with empty/null value is excluded in the upload operation due to the Windows API design.\n\n## download\n\n__Parameters__:\n\n- __source__: URL of the server to download the file, as encoded by `encodeURI()`.\n\n- __target__: Filesystem url representing the file on the device. For backwards compatibility, this can also be the full path of the file on the device. (See [Backwards Compatibility Notes](#backwards-compatibility-notes) below)\n\n- __successCallback__: A callback that is passed  a `FileEntry` object. _(Function)_\n\n- __errorCallback__: A callback that executes if an error occurs when retrieving the `FileEntry`. Invoked with a `FileTransferError` object. _(Function)_\n\n- __trustAllHosts__: Optional parameter, defaults to `false`. If set to `true`, it accepts all security certificates. This is useful because Android rejects self-signed security certificates. Not recommended for production use. Supported on Android and iOS. _(boolean)_\n\n- __options__: Optional parameters, currently only supports headers (such as Authorization (Basic Authentication), etc).\n\n### Example\n\n    // !! Assumes variable fileURL contains a valid URL to a path on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/downloads/\n\n    var fileTransfer = new FileTransfer();\n    var uri = encodeURI(\"http://some.server.com/download.php\");\n\n    fileTransfer.download(\n        uri,\n        fileURL,\n        function(entry) {\n            console.log(\"download complete: \" + entry.toURL());\n        },\n        function(error) {\n            console.log(\"download error source \" + error.source);\n            console.log(\"download error target \" + error.target);\n            console.log(\"upload error code\" + error.code);\n        },\n        false,\n        {\n            headers: {\n                \"Authorization\": \"Basic dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA==\"\n            }\n        }\n    );\n\n### WP8 Quirks\n\n- Download requests is being cached by native implementation. To avoid caching, pass `if-Modified-Since` header to download method.\n\n### Browser Quirks\n\n- __withCredentials__: _boolean_ that tells the browser to set the withCredentials flag on the XMLHttpRequest\n\n## abort\n\nAborts an in-progress transfer. The onerror callback is passed a FileTransferError object which has an error code of `FileTransferError.ABORT_ERR`.\n\n### Example\n\n    // !! Assumes variable fileURL contains a valid URL to a text file on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/file.txt\n\n    var win = function(r) {\n        console.log(\"Should not be called.\");\n    }\n\n    var fail = function(error) {\n        // error.code == FileTransferError.ABORT_ERR\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n\n    var options = new FileUploadOptions();\n    options.fileKey=\"file\";\n    options.fileName=\"myphoto.jpg\";\n    options.mimeType=\"image/jpeg\";\n\n    var ft = new FileTransfer();\n    ft.upload(fileURL, encodeURI(\"http://some.server.com/upload.php\"), win, fail, options);\n    ft.abort();\n\n\n## FileTransferError\n\nA `FileTransferError` object is passed to an error callback when an error occurs.\n\n### Properties\n\n- __code__: One of the predefined error codes listed below. (Number)\n\n- __source__: URL to the source. (String)\n\n- __target__: URL to the target. (String)\n\n- __http_status__: HTTP status code.  This attribute is only available when a response code is received from the HTTP connection. (Number)\n\n- __body__ Response body. This attribute is only available when a response is received from the HTTP connection. (String)\n\n- __exception__: Either e.getMessage or e.toString (String)\n\n### Constants\n\n- 1 = `FileTransferError.FILE_NOT_FOUND_ERR`\n- 2 = `FileTransferError.INVALID_URL_ERR`\n- 3 = `FileTransferError.CONNECTION_ERR`\n- 4 = `FileTransferError.ABORT_ERR`\n- 5 = `FileTransferError.NOT_MODIFIED_ERR`\n\n## Windows Quirks\n\n- The plugin implementation is based on [BackgroundDownloader](https://msdn.microsoft.com/en-us/library/windows/apps/windows.networking.backgroundtransfer.backgrounddownloader.aspx)/[BackgroundUploader](https://msdn.microsoft.com/en-us/library/windows/apps/windows.networking.backgroundtransfer.backgrounduploader.aspx), which entails the latency issues on Windows devices (creation/starting of an operation can take up to a few seconds). You can use XHR or [HttpClient](https://msdn.microsoft.com/en-us/library/windows/apps/windows.web.http.httpclient.aspx) as a quicker alternative for small downloads.\n\n## Backwards Compatibility Notes\n\nPrevious versions of this plugin would only accept device-absolute-file-paths as the source for uploads, or as the target for downloads. These paths would typically be of the form:\n\n    /var/mobile/Applications/<application UUID>/Documents/path/to/file  (iOS)\n    /storage/emulated/0/path/to/file                                    (Android)\n\nFor backwards compatibility, these paths are still accepted, and if your application has recorded paths like these in persistent storage, then they can continue to be used.\n\nThese paths were previously exposed in the `fullPath` property of `FileEntry` and `DirectoryEntry` objects returned by the File plugin. New versions of the File plugin however, no longer expose these paths to JavaScript.\n\nIf you are upgrading to a new (1.0.0 or newer) version of File, and you have previously been using `entry.fullPath` as arguments to `download()` or `upload()`, then you will need to change your code to use filesystem URLs instead.\n\n`FileEntry.toURL()` and `DirectoryEntry.toURL()` return a filesystem URL of the form:\n\n    cdvfile://localhost/persistent/path/to/file\n\nwhich can be used in place of the absolute file path in both `download()` and `upload()` methods.\n"
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/RELEASENOTES.md",
    "content": "<!--\n#\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n# \n# http://www.apache.org/licenses/LICENSE-2.0\n# \n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#  KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n#\n-->\n# Release Notes\n                                              \n### 1.5.1 (Apr 15, 2016)\n* CB-10536 Removing flaky test assertions about abort callback latency\n* Removing the expectation in `spec.34` for the transfer method to be called.\n* CB-10978 Fix `file-transfer.tests` JSHint issues\n* CB-10782 Occasional failure in file transfer tests causing mobilespec crash\n* CB-10771 Fixing failure when empty string passed as a value for option parameter in upload function\n* CB-10636 Add `JSHint` for plugins\n\n### 1.5.0 (Jan 15, 2016)\n* CB-10208 Fix `file-transfer` multipart form data upload format on **Windows**\n* CB-9837 Add data `URI` support to `file-transfer` upload on **iOS**\n* CB-9600 `FileUploadOptions` params not posted on **iOS**\n* CB-9840 Fallback `file-transfer` `uploadResponse` encoding to `latin1` in case not encoded with `UTF-8` on **iOS**\n* CB-9840 Fallback `file-transfer` upload/download response encoding to `latin1` in case not encoded with `UTF-8` on **iOS**\n* CB-8641 **Windows Phone 8.1** Some `file-transfer` plugin tests occasionally fail in `mobilespec`\n* Adding linting and fixing linter warnings. Reducing timeouts to 7 seconds.\n* CB-10100 updated file dependency to not grab new majors\n* CB-7006 Empty file is created on file transfer if server response is 304\n* CB-10098 `filetransfer.spec.33` is faulty\n* CB-9969 Filetransfer upload error deletes original file\n* CB-10088 `filetransfer spec.10` and `spec.11` test is faulty\n* CB-9969 Filetransfer upload error deletes original file\n* CB-10086 There are two `spec.31` tests for `file-transfer` tests\n* CB-10037 Add progress indicator to file-transfer manual tests\n* CB-9563 Mulptipart form data is used even a header named `Content-Type` is present\n* CB-8863 fix block usage of self\n\n### 1.4.0 (Nov 18, 2015)\n* [CB-10035](https://issues.apache.org/jira/browse/CB-10035) Updated `RELEASENOTES` to be newest to oldest\n* [CB-9879](https://issues.apache.org/jira/browse/CB-9879) `getCookie`s can cause unhandled `NullPointerException`\n* [CB-6928](https://issues.apache.org/jira/browse/CB-6928) Wrong behaviour transferring cacheable content\n* [CB-51](https://issues.apache.org/jira/browse/CB-51) FileTransfer - Support `PUT` Method\n* [CB-9906](https://issues.apache.org/jira/browse/CB-9906) cleanup duplicate code, removed 2nd `isWP8` declaration.\n* [CB-9950](https://issues.apache.org/jira/browse/CB-9950) Unpend Filetransfer spec.27 on **wp8** as custom headers are now supported\n* [CB-9843](https://issues.apache.org/jira/browse/CB-9843) Added **wp8** quirk to test spec 12\n* Fixing contribute link.\n* [CB-8431](https://issues.apache.org/jira/browse/CB-8431) File Transfer tests crash on **Android Lolipop**\n* [CB-9790](https://issues.apache.org/jira/browse/CB-9790) Align `FileUploadOptions` `fileName` and `mimeType` default parameter values to the docs on **iOS**\n* [CB-9385](https://issues.apache.org/jira/browse/CB-9385) Return `FILE_NOT_FOUND_ERR` when receiving `404` code on **iOS**\n* [CB-9791](https://issues.apache.org/jira/browse/CB-9791) Decreased download and upload tests timeout\n\n### 1.3.0 (Sep 18, 2015)\n* Found issue where : is accepted as a valid header, this is obviously wrong\n* [CB-9562](https://issues.apache.org/jira/browse/CB-9562) Fixed incorrect headers handling on Android\n* Fixing headers so they don't accept non-ASCII\n* updated tests to use cordova apache vm\n* [CB-9493](https://issues.apache.org/jira/browse/CB-9493) Fix file paths in file-transfer manual tests\n* [CB-8816](https://issues.apache.org/jira/browse/CB-8816) Add cdvfile:// support on windows\n* [CB-9376](https://issues.apache.org/jira/browse/CB-9376) Fix FileTransfer plugin manual tests issue - 'undefined' in paths\n     \n### 1.2.1 (Jul 7, 2015)\n* [CB-9275](https://issues.apache.org/jira/browse/CB-9275) [WP8] Fix build failure on WP8 by using reflection to detect presence of JSON.NET based serialization        \n* Updated code per code review.                                                         \n* Updated documentation for browser                                                     \n* Added option to allow for passing cookies automatically in the browser \n\n### 1.2.0 (Jun 17, 2015)\n* [CB-9128](https://issues.apache.org/jira/browse/CB-9128) cordova-plugin-file-transfer documentation translation: cordova-plugin-file-transfer\n* [CB-6503](https://issues.apache.org/jira/browse/CB-6503): Null pointer check for headers in upload (This closes #27)\n* [CB-6503](https://issues.apache.org/jira/browse/CB-6503): Allow payload content-types other than multipart/form-data to be used for upload\n* Fix NoSuchMethodException looking up cookies.\n* fix npm md issue\n* [CB-8951](https://issues.apache.org/jira/browse/CB-8951) (wp8) Handle exceptions in download() and upload() again\n* [wp8] Relaxed engine version requirement, using reflection to see if methods are available\n* Check for the existence of Json.net assembly to determin how we deserialize our headers.\n* relax engine requirement to allow -dev versions\n* Remove verbose console log messages\n* fix bad commit (mine) for cordova-wp8@4.0.0 engine req\n* bump required cordova-wp8 version to 4.0.0\n* This closes #80, This closes #12\n* fix failing test resulting from overlapping async calls\n* [CB-8721](https://issues.apache.org/jira/browse/CB-8721) Fixes incorrect headers and upload params parsing on wp8\n* Replace all slashes in windows path\n\n### 1.1.0 (May 06, 2015)\n* [CB-8951](https://issues.apache.org/jira/browse/CB-8951) Fixed crash related to headers parsing on **wp8**\n* [CB-8933](https://issues.apache.org/jira/browse/CB-8933) Increased download and upload test timeout\n* [CB-6313](https://issues.apache.org/jira/browse/CB-6313) **wp8**: Extra boundary in upload\n* [CB-8761](https://issues.apache.org/jira/browse/CB-8761) **wp8**: Copy cookies from WebBrowser\n\n### 1.0.0 (Apr 15, 2015)\n* [CB-8746](https://issues.apache.org/jira/browse/CB-8746) bumped version of file dependency\n* [CB-8746](https://issues.apache.org/jira/browse/CB-8746) gave plugin major version bump\n* [CB-8641](https://issues.apache.org/jira/browse/CB-8641) Fixed tests to pass on windows and wp8\n* [CB-8583](https://issues.apache.org/jira/browse/CB-8583) Forces download to overwrite existing target file\n* [CB-8589](https://issues.apache.org/jira/browse/CB-8589) Fixes upload failure when server's response doesn't contain any data\n* [CB-8747](https://issues.apache.org/jira/browse/CB-8747) updated dependency, added peer dependency\n* [CB-8683](https://issues.apache.org/jira/browse/CB-8683) changed plugin-id to pacakge-name\n* [CB-8653](https://issues.apache.org/jira/browse/CB-8653) properly updated translated docs to use new id\n* [CB-8653](https://issues.apache.org/jira/browse/CB-8653) updated translated docs to use new id\n* Use TRAVIS_BUILD_DIR, install paramedic by npm\n* [CB-8653](https://issues.apache.org/jira/browse/CB-8653) Updated Readme\n* [CB-8654](https://issues.apache.org/jira/browse/CB-8654) Note WP8 download requests caching in docs\n* [CB-8590](https://issues.apache.org/jira/browse/CB-8590) (Windows) Fixed download.onprogress.lengthComputable\n* [CB-8566](https://issues.apache.org/jira/browse/CB-8566) Integrate TravisCI\n* [CB-8438](https://issues.apache.org/jira/browse/CB-8438) cordova-plugin-file-transfer documentation translation: cordova-plugin-file-transfer\n* [CB-8538](https://issues.apache.org/jira/browse/CB-8538) Added package.json file\n* [CB-8495](https://issues.apache.org/jira/browse/CB-8495) Fixed wp8 and wp81 test failures\n* [CB-7957](https://issues.apache.org/jira/browse/CB-7957) Adds support for `browser` platform\n* [CB-8429](https://issues.apache.org/jira/browse/CB-8429) Updated version and RELEASENOTES.md for release 0.5.0 (take 2)\n* Fixes typo, introduced in https://github.com/apache/cordova-plugin-file-transfer/commit/bc43b46\n* [CB-8407](https://issues.apache.org/jira/browse/CB-8407) Use File proxy to construct valid FileEntry for download success callback\n* [CB-8407](https://issues.apache.org/jira/browse/CB-8407) Removes excess path to native path conversion in download method\n* [CB-8429](https://issues.apache.org/jira/browse/CB-8429) Updated version and RELEASENOTES.md for release 0.5.0\n* [CB-7957](https://issues.apache.org/jira/browse/CB-7957) Adds support for `browser` platform\n* [CB-8095](https://issues.apache.org/jira/browse/CB-8095) Fixes JSHint and formatting issues\n* [CB-8095](https://issues.apache.org/jira/browse/CB-8095) Updates tests and documentation\n* [CB-8095](https://issues.apache.org/jira/browse/CB-8095) Rewrite upload method to support progress events properly\n* android: Fix error reporting for unknown uri type on sourceUri instead of targetUri\n\n### 0.5.0 (Feb 04, 2015)\n* [CB-8407](https://issues.apache.org/jira/browse/CB-8407) windows: Fix download of `ms-appdata:///` URIs\n* [CB-8095](https://issues.apache.org/jira/browse/CB-8095) windows: Rewrite upload method to support progress events properly\n* [CB-5059](https://issues.apache.org/jira/browse/CB-5059) android: Add a CookieManager abstraction for pluggable webviews\n* ios: Fix compile warning about implicity int conversion\n* [CB-8351](https://issues.apache.org/jira/browse/CB-8351) ios: Use argumentForIndex rather than NSArray extension\n* [CB-8351](https://issues.apache.org/jira/browse/CB-8351) ios: Use a local copy of DLog macro rather than CordovaLib version\n* [CB-8296](https://issues.apache.org/jira/browse/CB-8296) ios: Fix crash when upload fails and file is not yet created (close #57)\n* Document \"body\" property on FileTransferError\n* [CB-7912](https://issues.apache.org/jira/browse/CB-7912) ios, android: Update to work with whitelist plugins in Cordova 4.x\n* Error callback should always be called with the FileTransferError object, and not just the code\n* windows: alias appData to Windows.Storage.ApplicationData.current\n* [CB-8093](https://issues.apache.org/jira/browse/CB-8093) Fixes incorrect FileTransferError returned in case of download failure\n\n### 0.4.8 (Dec 02, 2014)\n* [CB-8021](https://issues.apache.org/jira/browse/CB-8021) - adds documentation for `httpMethod` to `doc/index.md`. However, translations still need to be addressed.\n* [CB-7223](https://issues.apache.org/jira/browse/CB-7223) spec.27 marked pending for **wp8**\n* [CB-6900](https://issues.apache.org/jira/browse/CB-6900) fixed `spec.7` for **wp8**\n* [CB-7944](https://issues.apache.org/jira/browse/CB-7944) Pended unsupported auto tests for *Windows*\n* [CB-7977](https://issues.apache.org/jira/browse/CB-7977) Mention `deviceready` in plugin docs\n* [CB-7700](https://issues.apache.org/jira/browse/CB-7700) cordova-plugin-file-transfer documentation translation: cordova-plugin-file-transfer\n\n### 0.4.7 (Oct 03, 2014)\n* Construct proper FileEntry with nativeURL property set\n* [CB-7532](https://issues.apache.org/jira/browse/CB-7532) Handle non-existent download dirs properly\n* [CB-7529](https://issues.apache.org/jira/browse/CB-7529) Adds support for 'ms-appdata' URIs for windows\n\n### 0.4.6 (Sep 17, 2014)\n* [CB-7471](https://issues.apache.org/jira/browse/CB-7471) cordova-plugin-file-transfer documentation translation\n* [CB-7249](https://issues.apache.org/jira/browse/CB-7249) cordova-plugin-file-transfer documentation translation\n* [CB-7423](https://issues.apache.org/jira/browse/CB-7423) fix spec28,29 lastProgressEvent not visible to afterEach function\n* Amazon related changes.\n* Remove dupe file windows+windows8 both use the same one\n* [CB-7316](https://issues.apache.org/jira/browse/CB-7316) Updates docs with actual information.\n* [CB-7316](https://issues.apache.org/jira/browse/CB-7316) Adds support for Windows platform, moves \\*Proxy files to proper directory.\n* [CB-7316](https://issues.apache.org/jira/browse/CB-7316) Improves current specs compatibility:\n* added documentation for new test\n* [CB-6466](https://issues.apache.org/jira/browse/CB-6466) Fix failing test due to recent url change\n* [CB-6466](https://issues.apache.org/jira/browse/CB-6466) created mobile-spec test\n* Renamed test dir, added nested plugin.xml and test\n* Fixed failing spec.19 on wp8\n* added documentation to manual tests\n* [CB-6961](https://issues.apache.org/jira/browse/CB-6961) port file-transfer tests to framework\n\n### 0.4.5 (Aug 06, 2014)\n* Upload parameters out of order\n* **FirefoxOS** initial implementation\n* [CB-6781](https://issues.apache.org/jira/browse/CB-6781): Expose FileTransferError.exception to application\n* [CB-6928](https://issues.apache.org/jira/browse/CB-6928): Add new error code to documentation\n* [CB-6928](https://issues.apache.org/jira/browse/CB-6928): Handle 304 status code\n* [CB-6928](https://issues.apache.org/jira/browse/CB-6928): Open output stream only if it's necessary.\n* [BlackBerry10] Minor doc correction\n* [CB-6127](https://issues.apache.org/jira/browse/CB-6127) Updated translations for docs\n* [Windows8] upload uses the provided fileName or the actual fileName\n* [CB-2420](https://issues.apache.org/jira/browse/CB-2420) [Windows8] honor fileKey and param options. This closes #15\n* [CB-6781](https://issues.apache.org/jira/browse/CB-6781): Update new docs to match AlexNennker's changes in PR30\n* [CB-6781](https://issues.apache.org/jira/browse/CB-6781): Continue previous commit with one new instance (This closes #30)\n* [CB-6781](https://issues.apache.org/jira/browse/CB-6781): add the exception text to the error object\n* [CB-6890](https://issues.apache.org/jira/browse/CB-6890): Fix pluginManager access for 4.0.x branch\n\n### 0.4.4 (Jun 05, 2014)\n* [CB-6127](https://issues.apache.org/jira/browse/CB-6127) Spanish and French Translations added. Github close #21\n* ubuntu: support 'cdvfile' URI\n* [CB-6802](https://issues.apache.org/jira/browse/CB-6802) Add license\n* Upload progress now works also for second file\n* [CB-6706](https://issues.apache.org/jira/browse/CB-6706): Relax dependency on file plugin\n* [CB-3440](https://issues.apache.org/jira/browse/CB-3440) [BlackBerry10] Update implementation to use modules from file plugin\n* [CB-6378](https://issues.apache.org/jira/browse/CB-6378) Use connection.disconnect() instead of stream.close() for thread-safety\n* [CB-6491](https://issues.apache.org/jira/browse/CB-6491) add CONTRIBUTING.md\n* [CB-6466](https://issues.apache.org/jira/browse/CB-6466) Auto-create directories in download\n* [CB-6494](https://issues.apache.org/jira/browse/CB-6494) android: Fix upload of KitKat content URIs\n* Upleveled from android port with following commits: 3c1ff16 Andrew Grieve - [CB-5762](https://issues.apache.org/jira/browse/CB-5762) android: Fix lengthComputable set wrong for gzip downloads 8374b3d Colin Mahoney - [CB-5631](https://issues.apache.org/jira/browse/CB-5631) Removed SimpleTrackingInputStream.read(byte[] buffer) 6f91ac3 Bas Bosman - [CB-4907](https://issues.apache.org/jira/browse/CB-4907) Close stream when we're finished with it 651460f Christoph Neumann - [CB-6000](https://issues.apache.org/jira/browse/CB-6000) Nginx rejects Content-Type without a space before \"boundary\". 35f80e4 Ian Clelland - [CB-6050](https://issues.apache.org/jira/browse/CB-6050): Use instance method on actual file plugin object to get FileEntry to return on download\n* [CB-5980](https://issues.apache.org/jira/browse/CB-5980) Updated version and RELEASENOTES.md for release 0.4.1\n\n### 0.4.3 (Apr 17, 2014)\n* [CB-6422](https://issues.apache.org/jira/browse/CB-6422) [windows8] use cordova/exec/proxy\n* iOS: Fix error where files were not removed on abort\n* [CB-5175](https://issues.apache.org/jira/browse/CB-5175): [ios] CDVFileTransfer asynchronous download (Fixes #24)\n* [ios] Cast id references to NSURL to avoid compiler warnings (Fixes: apache/cordova-plugin-file-transfer#18)\n* [CB-6212](https://issues.apache.org/jira/browse/CB-6212): [iOS] fix warnings compiled under arm64 64-bit\n* [CB-5762](https://issues.apache.org/jira/browse/CB-5762): [FireOS] android: Fix lengthComputable set wrong for gzip downloads\n* [CB-5631](https://issues.apache.org/jira/browse/CB-5631): [FireOS] Removed SimpleTrackingInputStream.read(byte[] buffer)\n* [CB-4907](https://issues.apache.org/jira/browse/CB-4907): [FireOS] Close stream when we're finished with it\n* [CB-6000](https://issues.apache.org/jira/browse/CB-6000): [FireOS] Nginx rejects Content-Type without a space before \"boundary\".\n* [CB-6050](https://issues.apache.org/jira/browse/CB-6050): [FireOS] Use instance method on actual file plugin object to get FileEntry to return on download\n* [CB-6460](https://issues.apache.org/jira/browse/CB-6460): Update license headers\n\n### 0.4.2 (Feb 28, 2014)\n* [CB-6106](https://issues.apache.org/jira/browse/CB-6106) Ensure that nativeURL is used by file transfer download\n* iOS: Fix default value for trustAllHosts on iOS (YES->NO)\n* [CB-6059](https://issues.apache.org/jira/browse/CB-6059) iOS: Stop FileTransfer.download doing IO on the UI thread.\n* [CB-5588](https://issues.apache.org/jira/browse/CB-5588) iOS: Add response headers to upload result\n* [CB-2190](https://issues.apache.org/jira/browse/CB-2190) iOS: Make backgroundTaskId apply to downloads as well. Move backgroundTaskId to the delegate.\n* [CB-6050](https://issues.apache.org/jira/browse/CB-6050) Android: Use instance method on actual file plugin object to get FileEntry to return on download\n* [CB-6000](https://issues.apache.org/jira/browse/CB-6000) Android: Nginx rejects Content-Type without a space before \"boundary\".\n* [CB-4907](https://issues.apache.org/jira/browse/CB-4907) Android: Close stream when we're finished with it\n* [CB-6022](https://issues.apache.org/jira/browse/CB-6022) Add backwards-compatibility notes to doc\n\n### 0.4.1 (Feb 05, 2014)\n* [CB-5365](https://issues.apache.org/jira/browse/CB-5365) Remove unused exception var to prevent warnings?\n* [CB-2421](https://issues.apache.org/jira/browse/CB-2421) explicitly write the bytesSent,responseCode,result to the FileUploadResult pending release of cordova-plugin-file dependency, added some sanity checks for callbacks\n* iOS: Update for new file plugin api\n* [CB-5631](https://issues.apache.org/jira/browse/CB-5631) Removed SimpleTrackingInputStream.read(byte[] buffer)\n* [CB-5762](https://issues.apache.org/jira/browse/CB-5762) android: Fix lengthComputable set wrong for gzip downloads\n* [CB-4899](https://issues.apache.org/jira/browse/CB-4899) [BlackBerry10] Improve binary file transfer download\n* Delete stale test/ directory\n* [CB-5722](https://issues.apache.org/jira/browse/CB-5722) [BlackBerry10] Update upload function to use native file object\n* [CB-5658](https://issues.apache.org/jira/browse/CB-5658) Delete stale snapshot of plugin docs\n* Remove @1 designation from file plugin dependency until pushed to npm\n* [CB-5466](https://issues.apache.org/jira/browse/CB-5466): Update to work with filesystem URLs\n\n### 0.4.0 (Dec 4, 2013)\n* [CB-5466](https://issues.apache.org/jira/browse/CB-5466): Partial revert; we're not ready yet for FS urls\n* add ubuntu platform\n* [CB-5466](https://issues.apache.org/jira/browse/CB-5466): Minor version bump\n* [CB-5466](https://issues.apache.org/jira/browse/CB-5466): Update FileTransfer plugin to accept filesystem urls\n* Added amazon-fireos platform. Change to use amazon-fireos as the platform if the user agen string contains 'cordova-amazon-fireos'\n\n### 0.3.4 (Oct 28, 2013)\n* [CB-5128](https://issues.apache.org/jira/browse/CB-5128): added repo + issue tag to plugin.xml for file transfer plugin\n* [CB-5010](https://issues.apache.org/jira/browse/CB-5010) Incremented plugin version on dev branch.\n\n### 0.3.3 (Oct 9, 2013)\n* removed un-needed undef check\n* Fix missing headers in Windows 8 upload proxy\n* Fix missing headers in Windows 8 Proxy\n* Fix Windows 8 HTMLAnchorElement return host:80 which force Basic Auth Header to replace options Auth Header\n* [CB-4915](https://issues.apache.org/jira/browse/CB-4915) Incremented plugin version on dev branch.\n\n### 0.3.2 (Sept 25, 2013)\n* [CB-4889](https://issues.apache.org/jira/browse/CB-4889) bumping&resetting version\n* [windows8] commandProxy was moved\n* [CB-4889](https://issues.apache.org/jira/browse/CB-4889) updating core references\n* [CB-4889](https://issues.apache.org/jira/browse/CB-4889) renaming org.apache.cordova.core.file-transfer to org.apache.cordova.file-transfer and updating dependency\n* Rename CHANGELOG.md -> RELEASENOTES.md\n"
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/doc/de/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-file-transfer\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-file-transfer.svg)](https://travis-ci.org/apache/cordova-plugin-file-transfer)\n\nPlugin-Dokumentation: <doc/index.md>\n\nDieses Plugin ermöglicht Ihnen zum Hochladen und Herunterladen von Dateien.\n\nDieses Plugin wird global `FileTransfer`, `FileUploadOptions` Konstruktoren definiert.\n\nObwohl im globalen Gültigkeitsbereich, sind sie nicht bis nach dem `deviceready`-Ereignis.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(FileTransfer);\n    }\n    \n\n## Installation\n\n    cordova plugin add cordova-plugin-file-transfer\n    \n\n## Unterstützte Plattformen\n\n  * Amazon Fire OS\n  * Android\n  * BlackBerry 10\n  * Browser\n  * Firefox OS **\n  * iOS\n  * Windows Phone 7 und 8 *\n  * Windows 8\n  * Windows\n\n\\ * *Unterstützen keine `Onprogress` noch `abort()` *\n\n\\ ** * `Onprogress` nicht unterstützt*\n\n# FileTransfer\n\nDas `FileTransfer` -Objekt stellt eine Möglichkeit zum Hochladen von Dateien, die mithilfe einer HTTP-mehrteiligen POST oder PUT-Anforderung, und auch Dateien herunterladen.\n\n## Eigenschaften\n\n  * **OnProgress**: aufgerufen, wobei ein `ProgressEvent` wann wird eine neue Datenmenge übertragen. *(Funktion)*\n\n## Methoden\n\n  * **Upload**: sendet eine Datei an einen Server.\n\n  * **Download**: lädt eine Datei vom Server.\n\n  * **abort**: Abbruch eine Übertragung in Bearbeitung.\n\n## Upload\n\n**Parameter**:\n\n  * **FileURL**: Dateisystem-URL, das die Datei auf dem Gerät. Für rückwärts Kompatibilität, dies kann auch der vollständige Pfad der Datei auf dem Gerät sein. (Siehe [rückwärts Kompatibilität Notes] unten)\n\n  * **Server**: URL des Servers, die Datei zu empfangen, wie kodiert`encodeURI()`.\n\n  * **successCallback**: ein Rückruf, der ein `FileUploadResult`-Objekt übergeben wird. *(Funktion)*\n\n  * **errorCallback**: ein Rückruf, der ausgeführt wird, tritt ein Fehler beim Abrufen der `FileUploadResult`. Mit einem `FileTransferError`-Objekt aufgerufen. *(Funktion)*\n\n  * **Optionen**: optionale Parameter *(Objekt)*. Gültige Schlüssel:\n    \n      * **FileKey**: der Name des Form-Elements. Wird standardmäßig auf `file` . (DOM-String und enthält)\n      * **Dateiname**: der Dateiname beim Speichern der Datei auf dem Server verwendet. Wird standardmäßig auf `image.jpg` . (DOM-String und enthält)\n      * **httpMethod**: die HTTP-Methode, die-entweder `PUT` oder `POST`. Der Standardwert ist `POST`. (DOM-String und enthält)\n      * **mimeType**: den Mime-Typ der Daten hochzuladen. Standardwerte auf `Image/Jpeg`. (DOM-String und enthält)\n      * **params**: eine Reihe von optionalen Schlüssel/Wert-Paaren in der HTTP-Anforderung übergeben. (Objekt)\n      * **chunkedMode**: ob die Daten in \"Chunked\" streaming-Modus hochladen. Der Standardwert ist `true`. (Boolean)\n      * **headers**: eine Karte von Header-Name-Header-Werte. Verwenden Sie ein Array, um mehr als einen Wert anzugeben. Auf iOS, FireOS und Android wenn ein Content-Type-Header vorhanden ist, werden mehrteilige Formulardaten nicht verwendet werden. (Object)\n      * **httpMethod**: die HTTP-Methode zu verwenden, z.B. POST oder PUT. Der Standardwert ist `POST`. (DOM-String enthält)\n\n  * **TrustAllHosts**: Optionaler Parameter, wird standardmäßig auf `false` . Wenn legen Sie auf `true` , es akzeptiert alle Sicherheitszertifikate. Dies ist nützlich, da Android selbstsignierte Zertifikate ablehnt. Nicht für den produktiven Einsatz empfohlen. Auf Android und iOS unterstützt. *(Boolean)*\n\n### Beispiel\n\n    // !! Assumes variable fileURL contains a valid URL to a text file on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/file.txt\n    \n    var win = function (r) {\n        console.log(\"Code = \" + r.responseCode);\n        console.log(\"Response = \" + r.response);\n        console.log(\"Sent = \" + r.bytesSent);\n    }\n    \n    var fail = function (error) {\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n    \n    var options = new FileUploadOptions();\n    options.fileKey = \"file\";\n    options.fileName = fileURL.substr(fileURL.lastIndexOf('/') + 1);\n    options.mimeType = \"text/plain\";\n    \n    var params = {};\n    params.value1 = \"test\";\n    params.value2 = \"param\";\n    \n    options.params = params;\n    \n    var ft = new FileTransfer();\n    ft.upload(fileURL, encodeURI(\"http://some.server.com/upload.php\"), win, fail, options);\n    \n\n### Beispiel mit hochladen Kopf- und Progress-Ereignisse (Android und iOS nur)\n\n    function win(r) {\n        console.log(\"Code = \" + r.responseCode);\n        console.log(\"Response = \" + r.response);\n        console.log(\"Sent = \" + r.bytesSent);\n    }\n    \n    function fail(error) {\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n    \n    var uri = encodeURI(\"http://some.server.com/upload.php\");\n    \n    var options = new FileUploadOptions();\n    options.fileKey=\"file\";\n    options.fileName=fileURL.substr(fileURL.lastIndexOf('/')+1);\n    options.mimeType=\"text/plain\";\n    \n    var headers={'headerParam':'headerValue'};\n    \n    options.headers = headers;\n    \n    var ft = new FileTransfer();\n    ft.onprogress = function(progressEvent) {\n        if (progressEvent.lengthComputable) {\n          loadingStatus.setPercentage(progressEvent.loaded / progressEvent.total);\n        } else {\n          loadingStatus.increment();\n        }\n    };\n    ft.upload(fileURL, uri, win, fail, options);\n    \n\n## FileUploadResult\n\nEin `FileUploadResult`-Objekt wird an den Erfolg-Rückruf des `Objekts <code>FileTransfer`-Upload()-Methode</code> übergeben.\n\n### Eigenschaften\n\n  * **BytesSent**: die Anzahl der Bytes, die als Teil des Uploads an den Server gesendet. (lange)\n\n  * **ResponseCode**: die HTTP-Response-Code vom Server zurückgegeben. (lange)\n\n  * **response**: der HTTP-Antwort vom Server zurückgegeben. (DOM-String und enthält)\n\n  * **Header**: die HTTP-Response-Header vom Server. (Objekt)\n    \n      * Derzeit unterstützt auf iOS nur.\n\n### iOS Macken\n\n  * Unterstützt keine `responseCode` oder`bytesSent`.\n\n## Download\n\n**Parameter**:\n\n  * **source**: URL des Servers, um die Datei herunterzuladen, wie kodiert`encodeURI()`.\n\n  * **target**: Dateisystem-Url, das die Datei auf dem Gerät. Für rückwärts Kompatibilität, dies kann auch der vollständige Pfad der Datei auf dem Gerät sein. (Siehe [rückwärts Kompatibilität Notes] unten)\n\n  * **SuccessCallback**: ein Rückruf, der übergeben wird ein `FileEntry` Objekt. *(Funktion)*\n\n  * **errorCallback**: ein Rückruf, der ausgeführt wird, tritt ein Fehler beim Abrufen der `FileEntry`. Mit einem `FileTransferError`-Objekt aufgerufen. *(Funktion)*\n\n  * **TrustAllHosts**: Optionaler Parameter, wird standardmäßig auf `false` . Wenn legen Sie auf `true` , es akzeptiert alle Sicherheitszertifikate. Dies ist nützlich, da Android selbstsignierte Zertifikate ablehnt. Nicht für den produktiven Einsatz empfohlen. Auf Android und iOS unterstützt. *(Boolean)*\n\n  * **Options**: optionale Parameter, derzeit nur unterstützt Kopfzeilen (z. B. Autorisierung (Standardauthentifizierung), etc.).\n\n### Beispiel\n\n    // !! Assumes variable fileURL contains a valid URL to a path on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/downloads/\n    \n    var fileTransfer = new FileTransfer();\n    var uri = encodeURI(\"http://some.server.com/download.php\");\n    \n    fileTransfer.download(\n        uri,\n        fileURL,\n        function(entry) {\n            console.log(\"download complete: \" + entry.toURL());\n        },\n        function(error) {\n            console.log(\"download error source \" + error.source);\n            console.log(\"download error target \" + error.target);\n            console.log(\"upload error code\" + error.code);\n        },\n        false,\n        {\n            headers: {\n                \"Authorization\": \"Basic dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA==\"\n            }\n        }\n    );\n    \n\n### WP8 Macken\n\n  * Downloaden anfordert, wird von native Implementierung zwischengespeichert wird. Um zu vermeiden, Zwischenspeicherung, übergeben `If-Modified-Since` Header Methode herunterladen.\n\n## abort\n\nBricht einen in-Progress-Transfer. Der Onerror-Rückruf wird ein FileTransferError-Objekt übergeben, die einen Fehlercode FileTransferError.ABORT_ERR hat.\n\n### Beispiel\n\n    // !! Assumes variable fileURL contains a valid URL to a text file on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/file.txt\n    \n    var win = function(r) {\n        console.log(\"Should not be called.\");\n    }\n    \n    var fail = function(error) {\n        // error.code == FileTransferError.ABORT_ERR\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n    \n    var options = new FileUploadOptions();\n    options.fileKey=\"file\";\n    options.fileName=\"myphoto.jpg\";\n    options.mimeType=\"image/jpeg\";\n    \n    var ft = new FileTransfer();\n    ft.upload(fileURL, encodeURI(\"http://some.server.com/upload.php\"), win, fail, options);\n    ft.abort();\n    \n\n## FileTransferError\n\nEin `FileTransferError`-Objekt wird an eine Fehler-Callback übergeben, wenn ein Fehler auftritt.\n\n### Eigenschaften\n\n  * **Code**: einer der vordefinierten Fehlercodes aufgeführt. (Anzahl)\n\n  * **Quelle**: URL der Quelle. (String)\n\n  * **Ziel**: URL zum Ziel. (String)\n\n  * **HTTP_STATUS**: HTTP-Statuscode. Dieses Attribut ist nur verfügbar, wenn ein Response-Code aus der HTTP-Verbindung eingeht. (Anzahl)\n\n  * **body** Antworttext. Dieses Attribut ist nur verfügbar, wenn eine Antwort von der HTTP-Verbindung eingeht. (String)\n\n  * **exception**: entweder e.getMessage oder e.toString (String)\n\n### Konstanten\n\n  * 1 = `FileTransferError.FILE_NOT_FOUND_ERR`\n  * 2 = `FileTransferError.INVALID_URL_ERR`\n  * 3 = `FileTransferError.CONNECTION_ERR`\n  * 4 = `FileTransferError.ABORT_ERR`\n  * 5 = `FileTransferError.NOT_MODIFIED_ERR`\n\n## Hinweise rückwärts Kompatibilität\n\nFrühere Versionen des Plugins würde nur Gerät-Absolute-Dateipfade als Quelle für Uploads oder als Ziel für Downloads übernehmen. Diese Pfade wäre in der Regel der form\n\n    /var/mobile/Applications/<application UUID>/Documents/path/to/file  (iOS)\n    /storage/emulated/0/path/to/file                                    (Android)\n    \n\nFür rückwärts Kompatibilität, diese Pfade noch akzeptiert werden, und wenn Ihre Anwendung Pfade wie diese im permanenten Speicher aufgezeichnet hat, dann sie können weiter verwendet werden.\n\nDiese Pfade waren zuvor in der Eigenschaft `fullPath` `FileEntry` und `DirectoryEntry`-Objekte, die durch das Plugin Datei zurückgegeben ausgesetzt. Neue Versionen der die Datei-Erweiterung, jedoch nicht länger werden diese Pfade zu JavaScript.\n\nWenn Sie ein auf eine neue Upgrade (1.0.0 oder neuere) Version der Datei, und Sie haben zuvor mit `entry.fullPath` als Argumente `download()` oder `upload()`, dann ändern Sie den Code, um die Dateisystem-URLs verwenden müssen.\n\n`FileEntry.toURL()` und `DirectoryEntry.toURL()` zurück, eine Dateisystem-URL in der form\n\n    cdvfile://localhost/persistent/path/to/file\n    \n\ndie anstelle der absoluten Dateipfad in `download()` und `upload()` Methode verwendet werden kann."
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/doc/de/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-file-transfer\n\nDieses Plugin ermöglicht Ihnen zum Hochladen und Herunterladen von Dateien.\n\nDieses Plugin wird global `FileTransfer`, `FileUploadOptions` Konstruktoren definiert.\n\nObwohl im globalen Gültigkeitsbereich, sind sie nicht bis nach dem `deviceready`-Ereignis.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(FileTransfer);\n    }\n    \n\n## Installation\n\n    cordova plugin add cordova-plugin-file-transfer\n    \n\n## Unterstützte Plattformen\n\n*   Amazon Fire OS\n*   Android\n*   BlackBerry 10\n*   Browser\n*   Firefox OS **\n*   iOS\n*   Windows Phone 7 und 8 *\n*   Windows 8\n*   Windows\n\n* *Unterstützen keine `onprogress` noch `abort()`*\n\n* * *`onprogress` nicht unterstützt*\n\n# FileTransfer\n\nDas `FileTransfer`-Objekt bietet eine Möglichkeit zum Hochladen von Dateien, die mithilfe einer HTTP-Anforderung für mehrteiligen POST sowie Informationen zum Herunterladen von Dateien sowie.\n\n## Eigenschaften\n\n*   **OnProgress**: aufgerufen, wobei ein `ProgressEvent` wann wird eine neue Datenmenge übertragen. *(Funktion)*\n\n## Methoden\n\n*   **Upload**: sendet eine Datei an einen Server.\n\n*   **Download**: lädt eine Datei vom Server.\n\n*   **abort**: Abbruch eine Übertragung in Bearbeitung.\n\n## Upload\n\n**Parameter**:\n\n*   **FileURL**: Dateisystem-URL, das die Datei auf dem Gerät. Für rückwärts Kompatibilität, dies kann auch der vollständige Pfad der Datei auf dem Gerät sein. (Siehe [rückwärts Kompatibilität Notes] unten)\n\n*   **Server**: URL des Servers, die Datei zu empfangen, wie kodiert`encodeURI()`.\n\n*   **successCallback**: ein Rückruf, der ein `FileUploadResult`-Objekt übergeben wird. *(Funktion)*\n\n*   **errorCallback**: ein Rückruf, der ausgeführt wird, tritt ein Fehler beim Abrufen der `FileUploadResult`. Mit einem `FileTransferError`-Objekt aufgerufen. *(Funktion)*\n\n*   **Optionen**: optionale Parameter *(Objekt)*. Gültige Schlüssel:\n    \n    *   **FileKey**: der Name des Form-Elements. Wird standardmäßig auf `file` . (DOM-String und enthält)\n    *   **Dateiname**: der Dateiname beim Speichern der Datei auf dem Server verwendet. Wird standardmäßig auf `image.jpg` . (DOM-String und enthält)\n    *   **httpMethod**: die HTTP-Methode, die-entweder `PUT` oder `POST`. Der Standardwert ist `POST`. (DOM-String und enthält)\n    *   **mimeType**: den Mime-Typ der Daten hochzuladen. Standardwerte auf `Image/Jpeg`. (DOM-String und enthält)\n    *   **params**: eine Reihe von optionalen Schlüssel/Wert-Paaren in der HTTP-Anforderung übergeben. (Objekt)\n    *   **chunkedMode**: ob die Daten in \"Chunked\" streaming-Modus hochladen. Der Standardwert ist `true`. (Boolean)\n    *   **headers**: eine Karte von Header-Name-Header-Werte. Verwenden Sie ein Array, um mehr als einen Wert anzugeben. (Objekt)\n\n*   **TrustAllHosts**: Optionaler Parameter, wird standardmäßig auf `false` . Wenn legen Sie auf `true` , es akzeptiert alle Sicherheitszertifikate. Dies ist nützlich, da Android selbstsignierte Zertifikate ablehnt. Nicht für den produktiven Einsatz empfohlen. Auf Android und iOS unterstützt. *(Boolean)*\n\n### Beispiel\n\n    // !! Assumes variable fileURL contains a valid URL to a text file on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/file.txt\n    \n    var win = function (r) {\n        console.log(\"Code = \" + r.responseCode);\n        console.log(\"Response = \" + r.response);\n        console.log(\"Sent = \" + r.bytesSent);\n    }\n    \n    var fail = function (error) {\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n    \n    var options = new FileUploadOptions();\n    options.fileKey = \"file\";\n    options.fileName = fileURL.substr(fileURL.lastIndexOf('/') + 1);\n    options.mimeType = \"text/plain\";\n    \n    var params = {};\n    params.value1 = \"test\";\n    params.value2 = \"param\";\n    \n    options.params = params;\n    \n    var ft = new FileTransfer();\n    ft.upload(fileURL, encodeURI(\"http://some.server.com/upload.php\"), win, fail, options);\n    \n\n### Beispiel mit hochladen Kopf- und Progress-Ereignisse (Android und iOS nur)\n\n    function win(r) {\n        console.log(\"Code = \" + r.responseCode);\n        console.log(\"Response = \" + r.response);\n        console.log(\"Sent = \" + r.bytesSent);\n    }\n    \n    function fail(error) {\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n    \n    var uri = encodeURI(\"http://some.server.com/upload.php\");\n    \n    var options = new FileUploadOptions();\n    options.fileKey=\"file\";\n    options.fileName=fileURL.substr(fileURL.lastIndexOf('/')+1);\n    options.mimeType=\"text/plain\";\n    \n    var headers={'headerParam':'headerValue'};\n    \n    options.headers = headers;\n    \n    var ft = new FileTransfer();\n    ft.onprogress = function(progressEvent) {\n        if (progressEvent.lengthComputable) {\n          loadingStatus.setPercentage(progressEvent.loaded / progressEvent.total);\n        } else {\n          loadingStatus.increment();\n        }\n    };\n    ft.upload(fileURL, uri, win, fail, options);\n    \n\n## FileUploadResult\n\nEin `FileUploadResult`-Objekt wird an den Erfolg-Rückruf des `Objekts <code>FileTransfer`-Upload()-Methode</code> übergeben.\n\n### Eigenschaften\n\n*   **BytesSent**: die Anzahl der Bytes, die als Teil des Uploads an den Server gesendet. (lange)\n\n*   **ResponseCode**: die HTTP-Response-Code vom Server zurückgegeben. (lange)\n\n*   **response**: der HTTP-Antwort vom Server zurückgegeben. (DOM-String und enthält)\n\n*   **Header**: die HTTP-Response-Header vom Server. (Objekt)\n    \n    *   Derzeit unterstützt auf iOS nur.\n\n### iOS Macken\n\n*   Unterstützt keine `responseCode` oder`bytesSent`.\n\n## Download\n\n**Parameter**:\n\n*   **source**: URL des Servers, um die Datei herunterzuladen, wie kodiert`encodeURI()`.\n\n*   **target**: Dateisystem-Url, das die Datei auf dem Gerät. Für rückwärts Kompatibilität, dies kann auch der vollständige Pfad der Datei auf dem Gerät sein. (Siehe [rückwärts Kompatibilität Notes] unten)\n\n*   **SuccessCallback**: ein Rückruf, der übergeben wird ein `FileEntry` Objekt. *(Funktion)*\n\n*   **errorCallback**: ein Rückruf, der ausgeführt wird, tritt ein Fehler beim Abrufen der `FileEntry`. Mit einem `FileTransferError`-Objekt aufgerufen. *(Funktion)*\n\n*   **TrustAllHosts**: Optionaler Parameter, wird standardmäßig auf `false` . Wenn legen Sie auf `true` , es akzeptiert alle Sicherheitszertifikate. Dies ist nützlich, da Android selbstsignierte Zertifikate ablehnt. Nicht für den produktiven Einsatz empfohlen. Auf Android und iOS unterstützt. *(Boolean)*\n\n*   **Options**: optionale Parameter, derzeit nur unterstützt Kopfzeilen (z. B. Autorisierung (Standardauthentifizierung), etc.).\n\n### Beispiel\n\n    // !! Assumes variable fileURL contains a valid URL to a path on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/downloads/\n    \n    var fileTransfer = new FileTransfer();\n    var uri = encodeURI(\"http://some.server.com/download.php\");\n    \n    fileTransfer.download(\n        uri,\n        fileURL,\n        function(entry) {\n            console.log(\"download complete: \" + entry.toURL());\n        },\n        function(error) {\n            console.log(\"download error source \" + error.source);\n            console.log(\"download error target \" + error.target);\n            console.log(\"upload error code\" + error.code);\n        },\n        false,\n        {\n            headers: {\n                \"Authorization\": \"Basic dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA==\"\n            }\n        }\n    );\n    \n\n## abort\n\nBricht einen in-Progress-Transfer. Der Onerror-Rückruf wird ein FileTransferError-Objekt übergeben, die einen Fehlercode FileTransferError.ABORT_ERR hat.\n\n### Beispiel\n\n    // !! Assumes variable fileURL contains a valid URL to a text file on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/file.txt\n    \n    var win = function(r) {\n        console.log(\"Should not be called.\");\n    }\n    \n    var fail = function(error) {\n        // error.code == FileTransferError.ABORT_ERR\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n    \n    var options = new FileUploadOptions();\n    options.fileKey=\"file\";\n    options.fileName=\"myphoto.jpg\";\n    options.mimeType=\"image/jpeg\";\n    \n    var ft = new FileTransfer();\n    ft.upload(fileURL, encodeURI(\"http://some.server.com/upload.php\"), win, fail, options);\n    ft.abort();\n    \n\n## FileTransferError\n\nEin `FileTransferError`-Objekt wird an eine Fehler-Callback übergeben, wenn ein Fehler auftritt.\n\n### Eigenschaften\n\n*   **Code**: einer der vordefinierten Fehlercodes aufgeführt. (Anzahl)\n\n*   **Quelle**: URL der Quelle. (String)\n\n*   **Ziel**: URL zum Ziel. (String)\n\n*   **HTTP_STATUS**: HTTP-Statuscode. Dieses Attribut ist nur verfügbar, wenn ein Response-Code aus der HTTP-Verbindung eingeht. (Anzahl)\n\n*   **body** Antworttext. Dieses Attribut ist nur verfügbar, wenn eine Antwort von der HTTP-Verbindung eingeht. (String)\n\n*   **exception**: entweder e.getMessage oder e.toString (String)\n\n### Konstanten\n\n*   1 = `FileTransferError.FILE_NOT_FOUND_ERR`\n*   2 = `FileTransferError.INVALID_URL_ERR`\n*   3 = `FileTransferError.CONNECTION_ERR`\n*   4 = `FileTransferError.ABORT_ERR`\n*   5 = `FileTransferError.NOT_MODIFIED_ERR`\n\n## Hinweise rückwärts Kompatibilität\n\nFrühere Versionen des Plugins würde nur Gerät-Absolute-Dateipfade als Quelle für Uploads oder als Ziel für Downloads übernehmen. Diese Pfade wäre in der Regel der form\n\n    /var/mobile/Applications/<application UUID>/Documents/path/to/file  (iOS)\n    /storage/emulated/0/path/to/file                                    (Android)\n    \n\nFür rückwärts Kompatibilität, diese Pfade noch akzeptiert werden, und wenn Ihre Anwendung Pfade wie diese im permanenten Speicher aufgezeichnet hat, dann sie können weiter verwendet werden.\n\nDiese Pfade waren zuvor in der Eigenschaft `fullPath` `FileEntry` und `DirectoryEntry`-Objekte, die durch das Plugin Datei zurückgegeben ausgesetzt. Neue Versionen der die Datei-Erweiterung, jedoch nicht länger werden diese Pfade zu JavaScript.\n\nWenn Sie ein auf eine neue Upgrade (1.0.0 oder neuere) Version der Datei, und Sie haben zuvor mit `entry.fullPath` als Argumente `download()` oder `upload()`, dann ändern Sie den Code, um die Dateisystem-URLs verwenden müssen.\n\n`FileEntry.toURL()` und `DirectoryEntry.toURL()` zurück, eine Dateisystem-URL in der form\n\n    cdvfile://localhost/persistent/path/to/file\n    \n\ndie anstelle der absoluten Dateipfad in `download()` und `upload()` Methode verwendet werden kann.\n"
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/doc/es/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-file-transfer\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-file-transfer.svg)](https://travis-ci.org/apache/cordova-plugin-file-transfer)\n\nDocumentación del plugin: <doc/index.md>\n\nEste plugin te permite cargar y descargar archivos.\n\nEste plugin define global `FileTransfer` , `FileUploadOptions` constructores.\n\nAunque en el ámbito global, no están disponibles hasta después de la `deviceready` evento.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(FileTransfer);\n    }\n    \n\n## Instalación\n\n    cordova plugin add cordova-plugin-file-transfer\n    \n\n## Plataformas soportadas\n\n  * Amazon fire OS\n  * Android\n  * BlackBerry 10\n  * Explorador\n  * Firefox OS **\n  * iOS\n  * Windows Phone 7 y 8 *\n  * Windows 8\n  * Windows\n\n\\ * *No soporta `onprogress` ni `abort()` *\n\n\\ ** *No soporta `onprogress` *\n\n# FileTransfer\n\nEl objeto `FileTransfer` proporciona una manera para subir archivos utilizando una varias parte solicitud HTTP POST o PUT y descargar archivos, así.\n\n## Propiedades\n\n  * **OnProgress**: llama con un `ProgressEvent` cuando se transfiere un nuevo paquete de datos. *(Función)*\n\n## Métodos\n\n  * **cargar**: envía un archivo a un servidor.\n\n  * **Descargar**: descarga un archivo del servidor.\n\n  * **abortar**: aborta una transferencia en curso.\n\n## subir\n\n**Parámetros**:\n\n  * **fileURL**: URL de Filesystem que representa el archivo en el dispositivo. Para atrás compatibilidad, esto también puede ser la ruta de acceso completa del archivo en el dispositivo. (Ver [hacia atrás compatibilidad notas] debajo)\n\n  * **servidor**: dirección URL del servidor para recibir el archivo, como codificada por`encodeURI()`.\n\n  * **successCallback**: una devolución de llamada que se pasa un `FileUploadResult` objeto. *(Función)*\n\n  * **errorCallback**: una devolución de llamada que se ejecuta si se produce un error recuperar la `FileUploadResult` . Invocado con un `FileTransferError` objeto. *(Función)*\n\n  * **Opciones**: parámetros opcionales *(objeto)*. Teclas válidas:\n    \n      * **fileKey**: el nombre del elemento de formulario. Por defecto es `file` . (DOMString)\n      * **nombre de archivo**: el nombre del archivo a utilizar al guardar el archivo en el servidor. Por defecto es `image.jpg` . (DOMString)\n      * **httpMethod**: método HTTP el utilizar - o `PUT` o `POST` . Por defecto es `POST` . (DOMString)\n      * **mimeType**: el tipo mime de los datos para cargar. Por defecto es `image/jpeg` . (DOMString)\n      * **params**: un conjunto de pares clave/valor opcional para pasar en la petición HTTP. (Objeto)\n      * **chunkedMode**: Si desea cargar los datos en modo de transmisión fragmentado. Por defecto es `true` . (Boolean)\n      * **headers**: un mapa de nombre de encabezado/valores de encabezado Utilice una matriz para especificar más de un valor. En iOS FireOS y Android, si existe un encabezado llamado Content-Type, datos de un formulario multipart no se utilizará. (Object)\n      * **httpMethod**: HTTP el método a utilizar por ejemplo POST o poner. Por defecto `el POST`. (DOMString)\n\n  * **trustAllHosts**: parámetro opcional, por defecto es `false` . Si establece en `true` , acepta todos los certificados de seguridad. Esto es útil ya que Android rechaza certificados autofirmados seguridad. No se recomienda para uso productivo. Compatible con iOS y Android. *(boolean)*\n\n### Ejemplo\n\n    // !! Assumes variable fileURL contains a valid URL to a text file on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/file.txt\n    \n    var win = function (r) {\n        console.log(\"Code = \" + r.responseCode);\n        console.log(\"Response = \" + r.response);\n        console.log(\"Sent = \" + r.bytesSent);\n    }\n    \n    var fail = function (error) {\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n    \n    var options = new FileUploadOptions();\n    options.fileKey = \"file\";\n    options.fileName = fileURL.substr(fileURL.lastIndexOf('/') + 1);\n    options.mimeType = \"text/plain\";\n    \n    var params = {};\n    params.value1 = \"test\";\n    params.value2 = \"param\";\n    \n    options.params = params;\n    \n    var ft = new FileTransfer();\n    ft.upload(fileURL, encodeURI(\"http://some.server.com/upload.php\"), win, fail, options);\n    \n\n### Ejemplo con cabeceras de subir y eventos de progreso (Android y iOS solamente)\n\n    function win(r) {\n        console.log(\"Code = \" + r.responseCode);\n        console.log(\"Response = \" + r.response);\n        console.log(\"Sent = \" + r.bytesSent);\n    }\n    \n    function fail(error) {\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n    \n    var uri = encodeURI(\"http://some.server.com/upload.php\");\n    \n    var options = new FileUploadOptions();\n    options.fileKey=\"file\";\n    options.fileName=fileURL.substr(fileURL.lastIndexOf('/')+1);\n    options.mimeType=\"text/plain\";\n    \n    var headers={'headerParam':'headerValue'};\n    \n    options.headers = headers;\n    \n    var ft = new FileTransfer();\n    ft.onprogress = function(progressEvent) {\n        if (progressEvent.lengthComputable) {\n          loadingStatus.setPercentage(progressEvent.loaded / progressEvent.total);\n        } else {\n          loadingStatus.increment();\n        }\n    };\n    ft.upload(fileURL, uri, win, fail, options);\n    \n\n## FileUploadResult\n\nA `FileUploadResult` objeto se pasa a la devolución del éxito de la `FileTransfer` del objeto `upload()` método.\n\n### Propiedades\n\n  * **bytesSent**: el número de bytes enviados al servidor como parte de la carga. (largo)\n\n  * **responseCode**: código de respuesta HTTP el devuelto por el servidor. (largo)\n\n  * **respuesta**: respuesta el HTTP devuelto por el servidor. (DOMString)\n\n  * **cabeceras**: cabeceras de respuesta HTTP el por el servidor. (Objeto)\n    \n      * Actualmente compatible con iOS solamente.\n\n### iOS rarezas\n\n  * No es compatible con `responseCode` o`bytesSent`.\n\n## descargar\n\n**Parámetros**:\n\n  * **fuente**: dirección URL del servidor para descargar el archivo, como codificada por`encodeURI()`.\n\n  * **objetivo**: Filesystem url que representa el archivo en el dispositivo. Para atrás compatibilidad, esto también puede ser la ruta de acceso completa del archivo en el dispositivo. (Ver [hacia atrás compatibilidad notas] debajo)\n\n  * **successCallback**: una devolución de llamada que se pasa un `FileEntry` objeto. *(Función)*\n\n  * **errorCallback**: una devolución de llamada que se ejecuta si se produce un error al recuperar los `FileEntry` . Invocado con un `FileTransferError` objeto. *(Función)*\n\n  * **trustAllHosts**: parámetro opcional, por defecto es `false` . Si establece en `true` , acepta todos los certificados de seguridad. Esto es útil porque Android rechaza certificados autofirmados seguridad. No se recomienda para uso productivo. Compatible con iOS y Android. *(boolean)*\n\n  * **Opciones**: parámetros opcionales, actualmente sólo soporta cabeceras (como autorización (autenticación básica), etc.).\n\n### Ejemplo\n\n    // !! Assumes variable fileURL contains a valid URL to a path on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/downloads/\n    \n    var fileTransfer = new FileTransfer();\n    var uri = encodeURI(\"http://some.server.com/download.php\");\n    \n    fileTransfer.download(\n        uri,\n        fileURL,\n        function(entry) {\n            console.log(\"download complete: \" + entry.toURL());\n        },\n        function(error) {\n            console.log(\"download error source \" + error.source);\n            console.log(\"download error target \" + error.target);\n            console.log(\"upload error code\" + error.code);\n        },\n        false,\n        {\n            headers: {\n                \"Authorization\": \"Basic dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA==\"\n            }\n        }\n    );\n    \n\n### Rarezas de WP8\n\n  * Descargar pide se almacena en caché por aplicación nativa. Para evitar el almacenamiento en caché, pasar `if-Modified-Since` encabezado para descargar el método.\n\n## abortar\n\nAborta a una transferencia en curso. El callback onerror se pasa un objeto FileTransferError que tiene un código de error de FileTransferError.ABORT_ERR.\n\n### Ejemplo\n\n    // !! Assumes variable fileURL contains a valid URL to a text file on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/file.txt\n    \n    var win = function(r) {\n        console.log(\"Should not be called.\");\n    }\n    \n    var fail = function(error) {\n        // error.code == FileTransferError.ABORT_ERR\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n    \n    var options = new FileUploadOptions();\n    options.fileKey=\"file\";\n    options.fileName=\"myphoto.jpg\";\n    options.mimeType=\"image/jpeg\";\n    \n    var ft = new FileTransfer();\n    ft.upload(fileURL, encodeURI(\"http://some.server.com/upload.php\"), win, fail, options);\n    ft.abort();\n    \n\n## FileTransferError\n\nA `FileTransferError` objeto se pasa a un callback de error cuando se produce un error.\n\n### Propiedades\n\n  * **código**: uno de los códigos de error predefinido enumerados a continuación. (Número)\n\n  * **fuente**: URL a la fuente. (String)\n\n  * **objetivo**: URL a la meta. (String)\n\n  * **HTTP_STATUS**: código de estado HTTP. Este atributo sólo está disponible cuando se recibe un código de respuesta de la conexión HTTP. (Número)\n\n  * **cuerpo** Cuerpo de la respuesta. Este atributo sólo está disponible cuando se recibe una respuesta de la conexión HTTP. (String)\n\n  * **excepción**: cualquier e.getMessage o e.toString (String)\n\n### Constantes\n\n  * 1 = `FileTransferError.FILE_NOT_FOUND_ERR`\n  * 2 = `FileTransferError.INVALID_URL_ERR`\n  * 3 = `FileTransferError.CONNECTION_ERR`\n  * 4 = `FileTransferError.ABORT_ERR`\n  * 5 = `FileTransferError.NOT_MODIFIED_ERR`\n\n## Al revés notas de compatibilidad\n\nVersiones anteriores de este plugin sólo aceptaría dispositivo-absoluto-archivo-rutas como la fuente de carga, o como destino para las descargas. Estos caminos normalmente sería de la forma\n\n    /var/mobile/Applications/<application UUID>/Documents/path/to/file  (iOS)\n    /storage/emulated/0/path/to/file                                    (Android)\n    \n\nPara atrás compatibilidad, estos caminos son aceptados todavía, y si su solicitud ha grabado caminos como éstos en almacenamiento persistente, entonces pueden seguir utilizarse.\n\nEstos caminos fueron expuestos anteriormente en el `fullPath` propiedad de `FileEntry` y `DirectoryEntry` objetos devueltos por el plugin de archivo. Las nuevas versiones del archivo plugin, sin embargo, ya no exponen estos caminos a JavaScript.\n\nSi va a actualizar a una nueva (1.0.0 o más reciente) versión del archivo y previamente han estado utilizando `entry.fullPath` como argumentos para `download()` o `upload()` , entonces tendrá que cambiar su código para usar URLs de sistema de archivos en su lugar.\n\n`FileEntry.toURL()`y `DirectoryEntry.toURL()` devolver un filesystem dirección URL de la forma\n\n    cdvfile://localhost/persistent/path/to/file\n    \n\nque puede ser utilizado en lugar de la ruta del archivo absoluta tanto en `download()` y `upload()` los métodos."
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/doc/es/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-file-transfer\n\nEste plugin te permite cargar y descargar archivos.\n\nEste plugin define global `FileTransfer` , `FileUploadOptions` constructores.\n\nAunque en el ámbito global, no están disponibles hasta después de la `deviceready` evento.\n\n    document.addEventListener (\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {console.log(FileTransfer)};\n    \n\n## Instalación\n\n    Cordova plugin añade cordova-plugin-file-transferencia\n    \n\n## Plataformas soportadas\n\n*   Amazon fire OS\n*   Android\n*   BlackBerry 10\n*   Explorador\n*   Firefox OS **\n*   iOS\n*   Windows Phone 7 y 8 *\n*   Windows 8\n*   Windows\n\n* *No son compatibles con `onprogress` ni `abort()` *\n\n** *No son compatibles con `onprogress` *\n\n# FileTransfer\n\nEl `FileTransfer` objeto proporciona una manera de subir archivos mediante una solicitud HTTP de POST varias parte y para descargar archivos.\n\n## Propiedades\n\n*   **OnProgress**: llama con un `ProgressEvent` cuando se transfiere un nuevo paquete de datos. *(Función)*\n\n## Métodos\n\n*   **cargar**: envía un archivo a un servidor.\n\n*   **Descargar**: descarga un archivo del servidor.\n\n*   **abortar**: aborta una transferencia en curso.\n\n## subir\n\n**Parámetros**:\n\n*   **fileURL**: URL de Filesystem que representa el archivo en el dispositivo. Para atrás compatibilidad, esto también puede ser la ruta de acceso completa del archivo en el dispositivo. (Ver [hacia atrás compatibilidad notas] debajo)\n\n*   **servidor**: dirección URL del servidor para recibir el archivo, como codificada por`encodeURI()`.\n\n*   **successCallback**: una devolución de llamada que se pasa un `FileUploadResult` objeto. *(Función)*\n\n*   **errorCallback**: una devolución de llamada que se ejecuta si se produce un error recuperar la `FileUploadResult` . Invocado con un `FileTransferError` objeto. *(Función)*\n\n*   **Opciones**: parámetros opcionales *(objeto)*. Teclas válidas:\n    \n    *   **fileKey**: el nombre del elemento de formulario. Por defecto es `file` . (DOMString)\n    *   **nombre de archivo**: el nombre del archivo a utilizar al guardar el archivo en el servidor. Por defecto es `image.jpg` . (DOMString)\n    *   **httpMethod**: método HTTP el utilizar - o `PUT` o `POST` . Por defecto es `POST` . (DOMString)\n    *   **mimeType**: el tipo mime de los datos para cargar. Por defecto es `image/jpeg` . (DOMString)\n    *   **params**: un conjunto de pares clave/valor opcional para pasar en la petición HTTP. (Objeto)\n    *   **chunkedMode**: Si desea cargar los datos en modo de transmisión fragmentado. Por defecto es `true` . (Boolean)\n    *   **cabeceras**: un mapa de valores de encabezado nombre/cabecera. Utilice una matriz para especificar más de un valor. (Objeto)\n\n*   **trustAllHosts**: parámetro opcional, por defecto es `false` . Si establece en `true` , acepta todos los certificados de seguridad. Esto es útil ya que Android rechaza certificados autofirmados seguridad. No se recomienda para uso productivo. Compatible con iOS y Android. *(boolean)*\n\n### Ejemplo\n\n    // !! Asume fileURL variable contiene una dirección URL válida a un archivo de texto en el dispositivo, / / por ejemplo, ganar var cdvfile://localhost/persistent/path/to/file.txt = function (r) {console.log (\"código =\" + r.responseCode);\n        Console.log (\"respuesta =\" + r.response);\n        Console.log (\"Sent =\" + r.bytesSent);}\n    \n    var fallar = function (error) {alert (\"ha ocurrido un error: código =\" + error.code);\n        Console.log (\"error al cargar el origen\" + error.source);\n        Console.log (\"upload error objetivo\" + error.target);}\n    \n    var opciones = new FileUploadOptions();\n    options.fileKey = \"file\";\n    options.fileName = fileURL.substr(fileURL.lastIndexOf('/') + 1);\n    options.mimeType = \"text/plain\";\n    \n    var params = {};\n    params.value1 = \"prueba\";\n    params.value2 = \"param\";\n    \n    options.params = params;\n    \n    var ft = new FileTransfer();\n    Ft.upload (fileURL, encodeURI (\"http://some.server.com/upload.php\"), win, fail, opciones);\n    \n\n### Ejemplo con cabeceras de subir y eventos de progreso (Android y iOS solamente)\n\n    function win(r) {console.log (\"código =\" + r.responseCode);\n        Console.log (\"respuesta =\" + r.response);\n        Console.log (\"Sent =\" + r.bytesSent);}\n    \n    function fail(error) {alert (\"ha ocurrido un error: código =\" + error.code);\n        Console.log (\"error al cargar el origen\" + error.source);\n        Console.log (\"upload error objetivo\" + error.target);}\n    \n    var uri = encodeURI (\"http://some.server.com/upload.php\");\n    \n    var opciones = new FileUploadOptions();\n    options.fileKey=\"file\";\n    options.fileName=fileURL.substr(fileURL.lastIndexOf('/')+1);\n    options.mimeType=\"text/plain\";\n    \n    cabeceras de var ={'headerParam':'headerValue'};\n    \n    options.headers = encabezados;\n    \n    var ft = new FileTransfer();\n    Ft.OnProgress = function(progressEvent) {si (progressEvent.lengthComputable) {loadingStatus.setPercentage(progressEvent.loaded / progressEvent.total);\n        } {loadingStatus.increment() más;\n        }\n    };\n    Ft.upload (fileURL, uri, win, fail, opciones);\n    \n\n## FileUploadResult\n\nA `FileUploadResult` objeto se pasa a la devolución del éxito de la `FileTransfer` del objeto `upload()` método.\n\n### Propiedades\n\n*   **bytesSent**: el número de bytes enviados al servidor como parte de la carga. (largo)\n\n*   **responseCode**: código de respuesta HTTP el devuelto por el servidor. (largo)\n\n*   **respuesta**: respuesta el HTTP devuelto por el servidor. (DOMString)\n\n*   **cabeceras**: cabeceras de respuesta HTTP el por el servidor. (Objeto)\n    \n    *   Actualmente compatible con iOS solamente.\n\n### iOS rarezas\n\n*   No es compatible con `responseCode` o`bytesSent`.\n\n## descargar\n\n**Parámetros**:\n\n*   **fuente**: dirección URL del servidor para descargar el archivo, como codificada por`encodeURI()`.\n\n*   **objetivo**: Filesystem url que representa el archivo en el dispositivo. Para atrás compatibilidad, esto también puede ser la ruta de acceso completa del archivo en el dispositivo. (Ver [hacia atrás compatibilidad notas] debajo)\n\n*   **successCallback**: una devolución de llamada que se pasa un `FileEntry` objeto. *(Función)*\n\n*   **errorCallback**: una devolución de llamada que se ejecuta si se produce un error al recuperar los `FileEntry` . Invocado con un `FileTransferError` objeto. *(Función)*\n\n*   **trustAllHosts**: parámetro opcional, por defecto es `false` . Si establece en `true` , acepta todos los certificados de seguridad. Esto es útil porque Android rechaza certificados autofirmados seguridad. No se recomienda para uso productivo. Compatible con iOS y Android. *(boolean)*\n\n*   **Opciones**: parámetros opcionales, actualmente sólo soporta cabeceras (como autorización (autenticación básica), etc.).\n\n### Ejemplo\n\n    // !! Asume fileURL variable contiene una dirección URL válida a un camino en el dispositivo, / / por ejemplo, File Transfer var cdvfile://localhost/persistent/path/to/downloads/ = new FileTransfer();\n    var uri = encodeURI (\"http://some.server.com/download.php\");\n    \n    fileTransfer.download (uri, fileURL, function(entry) {console.log (\"descarga completa:\" + entry.toURL());\n        }, function(error) {console.log (\"error al descargar el origen\" + error.source);\n            Console.log (\"descargar error objetivo\" + error.target);\n            Console.log (\"código de error de carga\" + error.code);\n        }, falso, {encabezados: {\"Autorización\": \"Basic dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA ==\"}});\n    \n\n## abortar\n\nAborta a una transferencia en curso. El callback onerror se pasa un objeto FileTransferError que tiene un código de error de FileTransferError.ABORT_ERR.\n\n### Ejemplo\n\n    // !! Asume fileURL variable contiene una dirección URL válida a un archivo de texto en el dispositivo, / / por ejemplo, ganar cdvfile://localhost/persistent/path/to/file.txt var function(r) = {console.log (\"no se debe llamar.\");}\n    \n    var fallar = function(error) {/ / error.code == FileTransferError.ABORT_ERR alert (\"ha ocurrido un error: código =\" + error.code);\n        Console.log (\"error al cargar el origen\" + error.source);\n        Console.log (\"upload error objetivo\" + error.target);}\n    \n    var opciones = new FileUploadOptions();\n    options.fileKey=\"file\";\n    options.fileName=\"myphoto.jpg\";\n    options.mimeType=\"image/jpeg\";\n    \n    var ft = new FileTransfer();\n    Ft.upload (fileURL, encodeURI (\"http://some.server.com/upload.php\"), win, fail, opciones);\n    Ft.Abort();\n    \n\n## FileTransferError\n\nA `FileTransferError` objeto se pasa a un callback de error cuando se produce un error.\n\n### Propiedades\n\n*   **código**: uno de los códigos de error predefinido enumerados a continuación. (Número)\n\n*   **fuente**: URL a la fuente. (String)\n\n*   **objetivo**: URL a la meta. (String)\n\n*   **HTTP_STATUS**: código de estado HTTP. Este atributo sólo está disponible cuando se recibe un código de respuesta de la conexión HTTP. (Número)\n\n*   **cuerpo** Cuerpo de la respuesta. Este atributo sólo está disponible cuando se recibe una respuesta de la conexión HTTP. (String)\n\n*   **excepción**: cualquier e.getMessage o e.toString (String)\n\n### Constantes\n\n*   1 = `FileTransferError.FILE_NOT_FOUND_ERR`\n*   2 = `FileTransferError.INVALID_URL_ERR`\n*   3 = `FileTransferError.CONNECTION_ERR`\n*   4 = `FileTransferError.ABORT_ERR`\n*   5 = `FileTransferError.NOT_MODIFIED_ERR`\n\n## Al revés notas de compatibilidad\n\nVersiones anteriores de este plugin sólo aceptaría dispositivo-absoluto-archivo-rutas como la fuente de carga, o como destino para las descargas. Estos caminos normalmente sería de la forma\n\n    /var/mobile/Applications/<application UUID>/Documents/path/to/file  (iOS)\n    /storage/emulated/0/path/to/file                                    (Android)\n    \n\nPara atrás compatibilidad, estos caminos son aceptados todavía, y si su solicitud ha grabado caminos como éstos en almacenamiento persistente, entonces pueden seguir utilizarse.\n\nEstos caminos fueron expuestos anteriormente en el `fullPath` propiedad de `FileEntry` y `DirectoryEntry` objetos devueltos por el plugin de archivo. Las nuevas versiones del archivo plugin, sin embargo, ya no exponen estos caminos a JavaScript.\n\nSi va a actualizar a una nueva (1.0.0 o más reciente) versión del archivo y previamente han estado utilizando `entry.fullPath` como argumentos para `download()` o `upload()` , entonces tendrá que cambiar su código para usar URLs de sistema de archivos en su lugar.\n\n`FileEntry.toURL()`y `DirectoryEntry.toURL()` devolver un filesystem dirección URL de la forma\n\n    cdvfile://localhost/persistent/path/to/file\n    \n\nque puede ser utilizado en lugar de la ruta del archivo absoluta tanto en `download()` y `upload()` los métodos.\n"
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/doc/fr/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-file-transfer\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-file-transfer.svg)](https://travis-ci.org/apache/cordova-plugin-file-transfer)\n\nDocumentation du plugin : <doc/index.md>\n\nCe plugin vous permet de télécharger des fichiers.\n\nCe plugin définit global `FileTransfer` , `FileUploadOptions` constructeurs.\n\nBien que dans la portée globale, ils ne sont pas disponibles jusqu'après la `deviceready` événement.\n\n    document.addEventListener (« deviceready », onDeviceReady, false) ;\n    function onDeviceReady() {console.log(FileTransfer);}\n    \n\n## Installation\n\n    cordova plugin add cordova-plugin-file-transfer\n    \n\n## Plates-formes supportées\n\n  * Amazon Fire OS\n  * Android\n  * BlackBerry 10\n  * Navigateur\n  * Firefox OS **\n  * iOS\n  * Windows Phone 7 et 8 *\n  * Windows 8\n  * Windows\n\n\\ * *Ne supportent pas `onprogress` ni `abort()` *\n\n\\ ** *Ne prennent pas en charge les `onprogress` *\n\n# Transfert de fichiers\n\nL'objet de `FileTransfer` fournit un moyen de télécharger des fichiers à l'aide d'une requête HTTP multi-part POST ou PUT et pour télécharger des fichiers.\n\n## Propriétés\n\n  * **onprogress** : fonction appelée avec un `ProgressEvent` à chaque fois qu'un nouveau segment de données est transféré. *(Function)*\n\n## Méthodes\n\n  * **upload** : envoie un fichier à un serveur.\n\n  * **download** : télécharge un fichier depuis un serveur.\n\n  * **abort** : annule le transfert en cours.\n\n## upload\n\n**Paramètres**:\n\n  * **fileURL** : système de fichiers URL représentant le fichier sur le périphérique. Pour la compatibilité ascendante, cela peut aussi être le chemin complet du fichier sur le périphérique. (Voir [Backwards Compatibility Notes] ci-dessous)\n\n  * **server** : l'URL du serveur destiné à recevoir le fichier, encodée via `encodeURI()`.\n\n  * **successCallback**: un rappel passé un `FileUploadResult` objet. *(Fonction)*\n\n  * **errorCallback**: un rappel qui s'exécute si une erreur survient récupérer la `FileUploadResult` . Appelée avec un `FileTransferError` objet. *(Fonction)*\n\n  * **options**: paramètres facultatifs *(objet)*. Clés valides :\n    \n      * **fileKey**: le nom de l'élément form. Valeur par défaut est `file` . (DOMString)\n      * **fileName**: le nom de fichier à utiliser lorsque vous enregistrez le fichier sur le serveur. Valeur par défaut est `image.jpg` . (DOMString)\n      * **httpMethod**: méthode de The HTTP à utiliser - soit `PUT` ou `POST` . Valeur par défaut est `POST` . (DOMString)\n      * **type MIME**: le type mime des données à télécharger. Valeur par défaut est `image/jpeg` . (DOMString)\n      * **params**: un ensemble de paires clé/valeur facultative pour passer dans la requête HTTP. (Objet)\n      * **chunkedMode**: s'il faut télécharger les données en mode streaming mémorisé en bloc. Valeur par défaut est `true` . (Boolean)\n      * **headers**: une carte des valeurs d'en-tête en-tête/nom. Un tableau permet de spécifier plusieurs valeurs. Sur iOS, FireOS et Android, si un en-tête nommé Content-Type n'est présent, les données de formulaire multipart servira pas. (Object)\n      * **httpMethod**: The HTTP méthode à utiliser par exemple poster ou mis. Par défaut, `message`. (DOMString)\n\n  * **trustAllHosts**: paramètre facultatif, valeur par défaut est `false` . Si la valeur est `true` , il accepte tous les certificats de sécurité. Ceci est utile car Android rejette des certificats auto-signés. N'est pas recommandé pour une utilisation en production. Supporté sur Android et iOS. *(booléen)*\n\n### Exemple\n\n    // !! Suppose fileURL variable contient une URL valide dans un fichier texte sur le périphérique, / / par exemple, cdvfile://localhost/persistent/path/to/file.txt var win = function (r) {console.log (\"Code =\" + r.responseCode) ;\n        Console.log (\"réponse =\" + r.response) ;\n        Console.log (\"envoyés =\" + r.bytesSent);}\n    \n    échouer var = function (erreur) {alert (\"une erreur est survenue : Code =\" + error.code) ;\n        Console.log (« source de l'erreur de téléchargement » + error.source) ;\n        Console.log (\"erreur de téléchargement cible\" + error.target);}\n    \n    options de var = new FileUploadOptions() ;\n    options.fileKey = « fichier » ;\n    options.fileName = fileURL.substr(fileURL.lastIndexOf('/') + 1) ;\n    options.mimeType = « text/plain » ;\n    \n    var params = {} ;\n    params.value1 = « test » ;\n    params.Value2 = « param » ;\n    \n    options.params = params ;\n    \n    ft var = new FileTransfer() ;\n    ft.upload (fileURL, encodeURI (\"http://some.server.com/upload.php\"), win, fail, options) ;\n    \n\n### Exemple avec téléchargement du Header et des Progress Events (Android et iOS uniquement)\n\n    function win(r) {console.log (\"Code =\" + r.responseCode) ;\n        Console.log (\"réponse =\" + r.response) ;\n        Console.log (\"envoyés =\" + r.bytesSent);}\n    \n    function fail(error) {alert (\"une erreur est survenue : Code =\" + error.code) ;\n        Console.log (« source de l'erreur de téléchargement » + error.source) ;\n        Console.log (\"erreur de téléchargement cible\" + error.target);}\n    \n    var uri = encodeURI (\"http://some.server.com/upload.php\") ;\n    \n    options de var = new FileUploadOptions() ;\n    options.fileKey=\"file\" ;\n    options.fileName=fileURL.substr(fileURL.lastIndexOf('/')+1) ;\n    options.mimeType=\"text/plain\" ;\n    \n    en-têtes var ={'headerParam':'headerValue'} ;\n    \n    options.Headers = en-têtes ;\n    \n    ft var = new FileTransfer() ;\n    ft.OnProgress = function(progressEvent) {si (progressEvent.lengthComputable) {loadingStatus.setPercentage(progressEvent.loaded / progressEvent.total) ;\n        } else {loadingStatus.increment() ;\n        }\n    };\n    ft.upload (fileURL, uri, win, fail, options) ;\n    \n\n## FileUploadResult\n\nA `FileUploadResult` objet est passé au rappel de succès la `FileTransfer` de l'objet `upload()` méthode.\n\n### Propriétés\n\n  * **bytesSent** : le nombre d'octets envoyés au serveur dans le cadre du téléchargement. (long)\n\n  * **responseCode** : le code de réponse HTTP retourné par le serveur. (long)\n\n  * **response** : la réponse HTTP renvoyée par le serveur. (DOMString)\n\n  * **en-têtes** : en-têtes de réponse HTTP par le serveur. (Objet)\n    \n      * Actuellement pris en charge sur iOS seulement.\n\n### Notes au sujet d'iOS\n\n  * Ne prend pas en charge les propriétés `responseCode` et `bytesSent`.\n\n## download\n\n**Paramètres**:\n\n  * **source** : l'URL du serveur depuis lequel télécharger le fichier, encodée via `encodeURI()`.\n\n  * **target** : système de fichiers url représentant le fichier sur le périphérique. Pour la compatibilité ascendante, cela peut aussi être le chemin complet du fichier sur le périphérique. (Voir [Backwards Compatibility Notes] ci-dessous)\n\n  * **successCallback** : une callback de succès à laquelle est passée un objet `FileEntry`. *(Function)*\n\n  * **errorCallback**: un rappel qui s'exécute si une erreur se produit lors de la récupération du `FileEntry` . Appelée avec un `FileTransferError` objet. *(Fonction)*\n\n  * **trustAllHosts**: paramètre facultatif, valeur par défaut est `false` . Si la valeur est `true` , il accepte tous les certificats de sécurité. Ceci peut être utile car Android rejette les certificats auto-signés. N'est pas recommandé pour une utilisation en production. Supporté sur Android et iOS. *(booléen)*\n\n  * **options** : paramètres facultatifs, seules les en-têtes sont actuellement supportées (par exemple l'autorisation (authentification basique), etc.).\n\n### Exemple\n\n    // !! Suppose fileURL variable contient une URL valide vers un chemin d'accès sur le périphérique, / / par exemple, transfert de fichiers var cdvfile://localhost/persistent/path/to/downloads/ = new FileTransfer() ;\n    var uri = encodeURI (\"http://some.server.com/download.php\") ;\n    \n    fileTransfer.download (uri, fileURL, function(entry) {console.log (\"téléchargement complet:\" + entry.toURL()) ;\n        }, function(error) {console.log (« source de l'erreur de téléchargement » + error.source) ;\n            Console.log (« erreur de téléchargement cible » + error.target) ;\n            Console.log (« code d'erreur de téléchargement » + error.code) ;\n        }, faux, {en-têtes: {« Autorisation »: « dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA base == \"}}) ;\n    \n\n### Quirks wp8\n\n  * Télécharger demande est mis en cache par l'implémentation native. Pour éviter la mise en cache, pass `if-Modified-Since` en-tête Télécharger méthode.\n\n## abort\n\nAbandonne un transfert en cours. Le rappel onerror est passé à un objet FileTransferError qui a un code d'erreur de FileTransferError.ABORT_ERR.\n\n### Exemple\n\n    // !! Suppose fileURL variable contient une URL valide dans un fichier texte sur le périphérique, / / par exemple, cdvfile://localhost/persistent/path/to/file.txt var win = function(r) {console.log (\"ne devrait pas être appelée.\");}\n    \n    var fail = function(error) {/ / error.code == FileTransferError.ABORT_ERR alert (\"une erreur est survenue : Code =\" + error.code) ;\n        Console.log (« source de l'erreur de téléchargement » + error.source) ;\n        Console.log (\"erreur de téléchargement cible\" + error.target);}\n    \n    options de var = new FileUploadOptions() ;\n    options.fileKey=\"file\" ;\n    options.fileName=\"myphoto.jpg\" ;\n    options.mimeType=\"image/jpeg\" ;\n    \n    ft var = new FileTransfer() ;\n    ft.upload (fileURL, encodeURI (\"http://some.server.com/upload.php\"), win, fail, options) ;\n    ft.Abort() ;\n    \n\n## FileTransferError\n\nA `FileTransferError` objet est passé à un rappel d'erreur lorsqu'une erreur survient.\n\n### Propriétés\n\n  * **code** : l'un des codes d'erreur prédéfinis énumérés ci-dessous. (Number)\n\n  * **source** : l'URI de la source. (String)\n\n  * **target**: l'URI de la destination. (String)\n\n  * **http_status** : code d'état HTTP. Cet attribut n'est disponible que lorsqu'un code de réponse est fourni via la connexion HTTP. (Number)\n\n  * **corps** Corps de réponse. Cet attribut n'est disponible que lorsqu'une réponse est reçue de la connexion HTTP. (String)\n\n  * **exception**: soit e.getMessage ou e.toString (String)\n\n### Constantes\n\n  * 1 = `FileTransferError.FILE_NOT_FOUND_ERR`\n  * 2 = `FileTransferError.INVALID_URL_ERR`\n  * 3 = `FileTransferError.CONNECTION_ERR`\n  * 4 = `FileTransferError.ABORT_ERR`\n  * 5 = `FileTransferError.NOT_MODIFIED_ERR`\n\n## Backwards Compatibility Notes\n\nLes versions précédentes de ce plugin n'accepterait périphérique--fichier-chemins d'accès absolus comme source pour les téléchargements, ou comme cible pour les téléchargements. Ces chemins seraient généralement de la forme\n\n    / var/mobile/Applications/< application UUID >/Documents/chemin/vers/fichier (iOS), /storage/emulated/0/path/to/file (Android)\n    \n\nPour vers l'arrière la compatibilité, ces chemins sont toujours acceptés, et si votre application a enregistré des chemins comme celles-ci dans un stockage persistant, alors ils peuvent continuer à être utilisé.\n\nCes chemins ont été précédemment exposés dans le `fullPath` propriété de `FileEntry` et `DirectoryEntry` les objets retournés par le fichier plugin. Nouvelles versions du fichier plugin, cependant, ne plus exposent ces chemins à JavaScript.\n\nSi vous migrez vers une nouvelle (1.0.0 ou plus récent) version de fichier et vous avez précédemment utilisé `entry.fullPath` comme arguments à `download()` ou `upload()` , alors vous aurez besoin de modifier votre code pour utiliser le système de fichiers URL au lieu de cela.\n\n`FileEntry.toURL()`et `DirectoryEntry.toURL()` retournent une URL de système de fichiers du formulaire\n\n    cdvfile://localhost/persistent/path/to/file\n    \n\nqui peut être utilisé à la place le chemin d'accès absolu au fichier dans les deux `download()` et `upload()` méthodes."
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/doc/fr/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-file-transfer\n\nCe plugin vous permet de télécharger des fichiers.\n\nCe plugin définit global `FileTransfer` , `FileUploadOptions` constructeurs.\n\nBien que dans la portée globale, ils ne sont pas disponibles jusqu'après la `deviceready` événement.\n\n    document.addEventListener (« deviceready », onDeviceReady, false) ;\n    function onDeviceReady() {console.log(FileTransfer);}\n    \n\n## Installation\n\n    Cordova plugin ajouter cordova-plugin-file-transfert\n    \n\n## Plates-formes prises en charge\n\n*   Amazon Fire OS\n*   Android\n*   BlackBerry 10\n*   Navigateur\n*   Firefox OS **\n*   iOS\n*   Windows Phone 7 et 8 *\n*   Windows 8\n*   Windows\n\n* *Ne supportent pas `onprogress` ni `abort()` *\n\n** *Ne prennent pas en charge `onprogress` *\n\n# Transfert de fichiers\n\nLe `FileTransfer` objet fournit un moyen de télécharger des fichiers à l'aide d'une requête HTTP de la poste plusieurs partie et pour télécharger des fichiers aussi bien.\n\n## Propriétés\n\n*   **onprogress** : fonction appelée avec un `ProgressEvent` à chaque fois qu'un nouveau segment de données est transféré. *(Function)*\n\n## Méthodes\n\n*   **upload** : envoie un fichier à un serveur.\n\n*   **download** : télécharge un fichier depuis un serveur.\n\n*   **abort** : annule le transfert en cours.\n\n## upload\n\n**Paramètres**:\n\n*   **fileURL** : système de fichiers URL représentant le fichier sur le périphérique. Pour la compatibilité ascendante, cela peut aussi être le chemin complet du fichier sur le périphérique. (Voir [Backwards Compatibility Notes] ci-dessous)\n\n*   **server** : l'URL du serveur destiné à recevoir le fichier, encodée via `encodeURI()`.\n\n*   **successCallback**: un rappel passé un `FileUploadResult` objet. *(Fonction)*\n\n*   **errorCallback**: un rappel qui s'exécute si une erreur survient récupérer la `FileUploadResult` . Appelée avec un `FileTransferError` objet. *(Fonction)*\n\n*   **options**: paramètres facultatifs *(objet)*. Clés valides :\n    \n    *   **fileKey**: le nom de l'élément form. Valeur par défaut est `file` . (DOMString)\n    *   **fileName**: le nom de fichier à utiliser lorsque vous enregistrez le fichier sur le serveur. Valeur par défaut est `image.jpg` . (DOMString)\n    *   **httpMethod**: méthode de The HTTP à utiliser - soit `PUT` ou `POST` . Valeur par défaut est `POST` . (DOMString)\n    *   **type MIME**: le type mime des données à télécharger. Valeur par défaut est `image/jpeg` . (DOMString)\n    *   **params**: un ensemble de paires clé/valeur facultative pour passer dans la requête HTTP. (Objet)\n    *   **chunkedMode**: s'il faut télécharger les données en mode streaming mémorisé en bloc. Valeur par défaut est `true` . (Boolean)\n    *   **en-têtes**: une carte des valeurs d'en-tête en-tête/nom. Un tableau permet de spécifier plusieurs valeurs. (Objet)\n\n*   **trustAllHosts**: paramètre facultatif, valeur par défaut est `false` . Si la valeur `true` , il accepte tous les certificats de sécurité. Ceci est utile car Android rejette des certificats auto-signés. Non recommandé pour une utilisation de production. Supporté sur Android et iOS. *(boolean)*\n\n### Exemple\n\n    // !! Suppose fileURL variable contient une URL valide dans un fichier texte sur le périphérique, / / par exemple, cdvfile://localhost/persistent/path/to/file.txt var win = function (r) {console.log (\"Code =\" + r.responseCode) ;\n        Console.log (\"réponse =\" + r.response) ;\n        Console.log (\"envoyés =\" + r.bytesSent);}\n    \n    échouer var = function (erreur) {alert (\"une erreur est survenue : Code =\" + error.code) ;\n        Console.log (« source de l'erreur de téléchargement » + error.source) ;\n        Console.log (\"erreur de téléchargement cible\" + error.target);}\n    \n    options de var = new FileUploadOptions() ;\n    options.fileKey = « fichier » ;\n    options.fileName = fileURL.substr(fileURL.lastIndexOf('/') + 1) ;\n    options.mimeType = « text/plain » ;\n    \n    var params = {} ;\n    params.value1 = « test » ;\n    params.Value2 = « param » ;\n    \n    options.params = params ;\n    \n    ft var = new FileTransfer() ;\n    ft.upload (fileURL, encodeURI (\"http://some.server.com/upload.php\"), win, fail, options) ;\n    \n\n### Exemple avec téléchargement du Header et des Progress Events (Android et iOS uniquement)\n\n    function win(r) {console.log (\"Code =\" + r.responseCode) ;\n        Console.log (\"réponse =\" + r.response) ;\n        Console.log (\"envoyés =\" + r.bytesSent);}\n    \n    function fail(error) {alert (\"une erreur est survenue : Code =\" + error.code) ;\n        Console.log (« source de l'erreur de téléchargement » + error.source) ;\n        Console.log (\"erreur de téléchargement cible\" + error.target);}\n    \n    var uri = encodeURI (\"http://some.server.com/upload.php\") ;\n    \n    options de var = new FileUploadOptions() ;\n    options.fileKey=\"file\" ;\n    options.fileName=fileURL.substr(fileURL.lastIndexOf('/')+1) ;\n    options.mimeType=\"text/plain\" ;\n    \n    en-têtes var ={'headerParam':'headerValue'} ;\n    \n    options.Headers = en-têtes ;\n    \n    ft var = new FileTransfer() ;\n    ft.OnProgress = function(progressEvent) {si (progressEvent.lengthComputable) {loadingStatus.setPercentage(progressEvent.loaded / progressEvent.total) ;\n        } else {loadingStatus.increment() ;\n        }\n    };\n    ft.upload (fileURL, uri, win, fail, options) ;\n    \n\n## FileUploadResult\n\nA `FileUploadResult` objet est passé au rappel de succès la `FileTransfer` de l'objet `upload()` méthode.\n\n### Propriétés\n\n*   **bytesSent** : le nombre d'octets envoyés au serveur dans le cadre du téléchargement. (long)\n\n*   **responseCode** : le code de réponse HTTP retourné par le serveur. (long)\n\n*   **response** : la réponse HTTP renvoyée par le serveur. (DOMString)\n\n*   **en-têtes** : en-têtes de réponse HTTP par le serveur. (Objet)\n    \n    *   Actuellement pris en charge sur iOS seulement.\n\n### iOS Remarques\n\n*   Ne prend pas en charge les propriétés `responseCode` et `bytesSent`.\n\n## download\n\n**Paramètres**:\n\n*   **source** : l'URL du serveur depuis lequel télécharger le fichier, encodée via `encodeURI()`.\n\n*   **target** : système de fichiers url représentant le fichier sur le périphérique. Pour vers l'arrière la compatibilité, cela peut aussi être le chemin d'accès complet du fichier sur le périphérique. (Voir [vers l'arrière compatibilité note] ci-dessous)\n\n*   **successCallback** : une callback de succès à laquelle est passée un objet `FileEntry`. *(Function)*\n\n*   **errorCallback**: un rappel qui s'exécute si une erreur se produit lors de la récupération du `FileEntry` . Appelée avec un `FileTransferError` objet. *(Fonction)*\n\n*   **trustAllHosts**: paramètre facultatif, valeur par défaut est `false` . Si la valeur est `true` , il accepte tous les certificats de sécurité. Ceci peut être utile car Android rejette les certificats auto-signés. N'est pas recommandé pour une utilisation en production. Supporté sur Android et iOS. *(booléen)*\n\n*   **options** : paramètres facultatifs, seules les en-têtes sont actuellement supportées (par exemple l'autorisation (authentification basique), etc.).\n\n### Exemple\n\n    // !! Suppose fileURL variable contient une URL valide vers un chemin d'accès sur le périphérique, / / par exemple, transfert de fichiers var cdvfile://localhost/persistent/path/to/downloads/ = new FileTransfer() ;\n    var uri = encodeURI (\"http://some.server.com/download.php\") ;\n    \n    fileTransfer.download (uri, fileURL, function(entry) {console.log (\"téléchargement complet:\" + entry.toURL()) ;\n        }, function(error) {console.log (« source de l'erreur de téléchargement » + error.source) ;\n            Console.log (« erreur de téléchargement cible » + error.target) ;\n            Console.log (« code d'erreur de téléchargement » + error.code) ;\n        }, faux, {en-têtes: {« Autorisation »: « dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA base == \"}}) ;\n    \n\n## abort\n\nAbandonne un transfert en cours. Le rappel onerror est passé à un objet FileTransferError qui a un code d'erreur de FileTransferError.ABORT_ERR.\n\n### Exemple\n\n    // !! Suppose fileURL variable contient une URL valide dans un fichier texte sur le périphérique, / / par exemple, cdvfile://localhost/persistent/path/to/file.txt var win = function(r) {console.log (\"ne devrait pas être appelée.\");}\n    \n    var fail = function(error) {/ / error.code == FileTransferError.ABORT_ERR alert (\"une erreur est survenue : Code =\" + error.code) ;\n        Console.log (« source de l'erreur de téléchargement » + error.source) ;\n        Console.log (\"erreur de téléchargement cible\" + error.target);}\n    \n    options de var = new FileUploadOptions() ;\n    options.fileKey=\"file\" ;\n    options.fileName=\"myphoto.jpg\" ;\n    options.mimeType=\"image/jpeg\" ;\n    \n    ft var = new FileTransfer() ;\n    ft.upload (fileURL, encodeURI (\"http://some.server.com/upload.php\"), win, fail, options) ;\n    ft.Abort() ;\n    \n\n## FileTransferError\n\nA `FileTransferError` objet est passé à un rappel d'erreur lorsqu'une erreur survient.\n\n### Propriétés\n\n*   **code** : l'un des codes d'erreur prédéfinis énumérés ci-dessous. (Number)\n\n*   **source** : l'URI de la source. (String)\n\n*   **target**: l'URI de la destination. (String)\n\n*   **http_status** : code d'état HTTP. Cet attribut n'est disponible que lorsqu'un code de réponse est fourni via la connexion HTTP. (Number)\n\n*   **corps** Corps de réponse. Cet attribut n'est disponible que lorsqu'une réponse est reçue de la connexion HTTP. (String)\n\n*   **exception**: soit e.getMessage ou e.toString (String)\n\n### Constantes\n\n*   1 = `FileTransferError.FILE_NOT_FOUND_ERR`\n*   2 = `FileTransferError.INVALID_URL_ERR`\n*   3 = `FileTransferError.CONNECTION_ERR`\n*   4 = `FileTransferError.ABORT_ERR`\n*   5 = `FileTransferError.NOT_MODIFIED_ERR`\n\n## Backwards Compatibility Notes\n\nLes versions précédentes de ce plugin n'accepterait périphérique--fichier-chemins d'accès absolus comme source pour les téléchargements, ou comme cible pour les téléchargements. Ces chemins seraient généralement de la forme\n\n    / var/mobile/Applications/< application UUID >/Documents/chemin/vers/fichier (iOS), /storage/emulated/0/path/to/file (Android)\n    \n\nPour vers l'arrière la compatibilité, ces chemins sont toujours acceptés, et si votre application a enregistré des chemins comme celles-ci dans un stockage persistant, alors ils peuvent continuer à être utilisé.\n\nCes chemins ont été précédemment exposés dans le `fullPath` propriété de `FileEntry` et `DirectoryEntry` les objets retournés par le fichier plugin. Nouvelles versions du fichier plugin, cependant, ne plus exposent ces chemins à JavaScript.\n\nSi vous migrez vers une nouvelle (1.0.0 ou plus récent) version de fichier et vous avez précédemment utilisé `entry.fullPath` comme arguments à `download()` ou `upload()` , alors vous aurez besoin de modifier votre code pour utiliser le système de fichiers URL au lieu de cela.\n\n`FileEntry.toURL()`et `DirectoryEntry.toURL()` retournent une URL de système de fichiers du formulaire\n\n    cdvfile://localhost/persistent/path/to/file\n    \n\nqui peut être utilisé à la place le chemin d'accès absolu au fichier dans les deux `download()` et `upload()` méthodes.\n"
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/doc/it/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-file-transfer\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-file-transfer.svg)](https://travis-ci.org/apache/cordova-plugin-file-transfer)\n\nDocumentazione plugin: <doc/index.md>\n\nQuesto plugin permette di caricare e scaricare file.\n\nQuesto plugin definisce globale `FileTransfer`, costruttori di `FileUploadOptions`.\n\nAnche se in ambito globale, non sono disponibili fino a dopo l'evento `deviceready`.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(FileTransfer);\n    }\n    \n\n## Installazione\n\n    cordova plugin add cordova-plugin-file-transfer\n    \n\n## Piattaforme supportate\n\n  * Amazon fuoco OS\n  * Android\n  * BlackBerry 10\n  * Browser\n  * Firefox OS**\n  * iOS\n  * Windows Phone 7 e 8 *\n  * Windows 8\n  * Windows\n\n\\ * *Non supportano `onprogress` né `abort()` *\n\n\\ * * *Non supportano `onprogress` *\n\n# FileTransfer\n\nL'oggetto `FileTransfer` fornisce un modo per caricare i file utilizzando una richiesta HTTP multiparte POST o PUT e scaricare file pure.\n\n## Proprietà\n\n  * **OnProgress**: chiamata con un `ProgressEvent` ogni volta che un nuovo blocco di dati viene trasferito. *(Funzione)*\n\n## Metodi\n\n  * **caricare**: invia un file a un server.\n\n  * **Scarica**: Scarica un file dal server.\n\n  * **Abort**: interrompe un trasferimento in corso.\n\n## upload\n\n**Parametri**:\n\n  * **fileURL**: Filesystem URL che rappresenta il file nel dispositivo. Per indietro la compatibilità, questo può anche essere il percorso completo del file sul dispositivo. (Vedere [indietro compatibilità rileva] qui sotto)\n\n  * **server**: URL del server per ricevere il file, come codificato dal`encodeURI()`.\n\n  * **successCallback**: un callback che viene passato un oggetto `FileUploadResult`. *(Funzione)*\n\n  * **errorCallback**: un callback che viene eseguito se si verifica un errore di recupero `FileUploadResult`. Richiamato con un oggetto `FileTransferError`. *(Funzione)*\n\n  * **opzioni**: parametri facoltativi *(oggetto)*. Chiavi valide:\n    \n      * **fileKey**: il nome dell'elemento form. Valore predefinito è `file` . (DOMString)\n      * **nome file**: il nome del file da utilizzare quando si salva il file sul server. Valore predefinito è `image.jpg` . (DOMString)\n      * **httpMethod**: metodo HTTP da utilizzare - `PUT` o `POST`. Impostazioni predefinite per `POST`. (DOMString)\n      * **mimeType**: il tipo mime dei dati da caricare. Impostazioni predefinite su `image/jpeg`. (DOMString)\n      * **params**: un insieme di coppie chiave/valore opzionale per passare nella richiesta HTTP. (Object)\n      * **chunkedMode**: se a caricare i dati in modalità streaming chunked. Impostazione predefinita è `true`. (Boolean)\n      * **headers**: una mappa di valori di intestazione e nome dell'intestazione. Utilizzare una matrice per specificare più di un valore. Su iOS, FireOS e Android, se è presente, un'intestazione Content-Type il nome dati form multipart non verranno utilizzati. (Object)\n      * **httpMethod**: metodo HTTP da utilizzare per esempio POST o PUT. Il valore predefinito è `POST`. (DOMString)\n\n  * **trustAllHosts**: parametro opzionale, valore predefinito è `false` . Se impostata su `true` , accetta tutti i certificati di sicurezza. Questo è utile poiché Android respinge i certificati autofirmati sicurezza. Non raccomandato per uso in produzione. Supportato su Android e iOS. *(boolean)*\n\n### Esempio\n\n    // !! Assumes variable fileURL contains a valid URL to a text file on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/file.txt\n    \n    var win = function (r) {\n        console.log(\"Code = \" + r.responseCode);\n        console.log(\"Response = \" + r.response);\n        console.log(\"Sent = \" + r.bytesSent);\n    }\n    \n    var fail = function (error) {\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n    \n    var options = new FileUploadOptions();\n    options.fileKey = \"file\";\n    options.fileName = fileURL.substr(fileURL.lastIndexOf('/') + 1);\n    options.mimeType = \"text/plain\";\n    \n    var params = {};\n    params.value1 = \"test\";\n    params.value2 = \"param\";\n    \n    options.params = params;\n    \n    var ft = new FileTransfer();\n    ft.upload(fileURL, encodeURI(\"http://some.server.com/upload.php\"), win, fail, options);\n    \n\n### Esempio con intestazioni di caricare ed eventi Progress (Android e iOS solo)\n\n    function win(r) {\n        console.log(\"Code = \" + r.responseCode);\n        console.log(\"Response = \" + r.response);\n        console.log(\"Sent = \" + r.bytesSent);\n    }\n    \n    function fail(error) {\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n    \n    var uri = encodeURI(\"http://some.server.com/upload.php\");\n    \n    var options = new FileUploadOptions();\n    options.fileKey=\"file\";\n    options.fileName=fileURL.substr(fileURL.lastIndexOf('/')+1);\n    options.mimeType=\"text/plain\";\n    \n    var headers={'headerParam':'headerValue'};\n    \n    options.headers = headers;\n    \n    var ft = new FileTransfer();\n    ft.onprogress = function(progressEvent) {\n        if (progressEvent.lengthComputable) {\n          loadingStatus.setPercentage(progressEvent.loaded / progressEvent.total);\n        } else {\n          loadingStatus.increment();\n        }\n    };\n    ft.upload(fileURL, uri, win, fail, options);\n    \n\n## FileUploadResult\n\nUn oggetto `FileUploadResult` viene passato al metodo di callback del metodo `upload()` dell'oggetto `FileTransfer` successo.\n\n### Proprietà\n\n  * **bytesSent**: il numero di byte inviati al server come parte dell'upload. (lungo)\n\n  * **responseCode**: codice di risposta HTTP restituito dal server. (lungo)\n\n  * **risposta**: risposta HTTP restituito dal server. (DOMString)\n\n  * **intestazioni**: intestazioni di risposta HTTP dal server. (Oggetto)\n    \n      * Attualmente supportato solo iOS.\n\n### iOS stranezze\n\n  * Non supporta `responseCode` o`bytesSent`.\n\n## Scarica\n\n**Parametri**:\n\n  * **fonte**: URL del server per scaricare il file, come codificato dal`encodeURI()`.\n\n  * **destinazione**: Filesystem url che rappresenta il file nel dispositivo. Per indietro la compatibilità, questo può anche essere il percorso completo del file sul dispositivo. (Vedere [indietro compatibilità rileva] qui sotto)\n\n  * **successCallback**: un callback passato un `FileEntry` oggetto. *(Funzione)*\n\n  * **errorCallback**: un callback che viene eseguito se si verifica un errore durante il recupero `FileEntry`. Richiamato con un oggetto `FileTransferError`. *(Function)*\n\n  * **trustAllHosts**: parametro opzionale, valore predefinito è `false` . Se impostata su `true` , accetta tutti i certificati di sicurezza. Questo è utile perché Android respinge i certificati autofirmati sicurezza. Non raccomandato per uso in produzione. Supportato su Android e iOS. *(boolean)*\n\n  * **opzioni**: parametri facoltativi, attualmente solo supporti intestazioni (ad esempio autorizzazione (autenticazione di base), ecc.).\n\n### Esempio\n\n    // !! Assumes variable fileURL contains a valid URL to a path on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/downloads/\n    \n    var fileTransfer = new FileTransfer();\n    var uri = encodeURI(\"http://some.server.com/download.php\");\n    \n    fileTransfer.download(\n        uri,\n        fileURL,\n        function(entry) {\n            console.log(\"download complete: \" + entry.toURL());\n        },\n        function(error) {\n            console.log(\"download error source \" + error.source);\n            console.log(\"download error target \" + error.target);\n            console.log(\"upload error code\" + error.code);\n        },\n        false,\n        {\n            headers: {\n                \"Authorization\": \"Basic dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA==\"\n            }\n        }\n    );\n    \n\n### WP8 stranezze\n\n  * Il download richiede è nella cache di implementazione nativa. Per evitare la memorizzazione nella cache, passare `if-Modified-Since` intestazione per metodo di download.\n\n## Abort\n\nInterrompe un trasferimento in corso. Il callback onerror viene passato un oggetto FileTransferError che presenta un codice di errore di FileTransferError.ABORT_ERR.\n\n### Esempio\n\n    // !! Assumes variable fileURL contains a valid URL to a text file on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/file.txt\n    \n    var win = function(r) {\n        console.log(\"Should not be called.\");\n    }\n    \n    var fail = function(error) {\n        // error.code == FileTransferError.ABORT_ERR\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n    \n    var options = new FileUploadOptions();\n    options.fileKey=\"file\";\n    options.fileName=\"myphoto.jpg\";\n    options.mimeType=\"image/jpeg\";\n    \n    var ft = new FileTransfer();\n    ft.upload(fileURL, encodeURI(\"http://some.server.com/upload.php\"), win, fail, options);\n    ft.abort();\n    \n\n## FileTransferError\n\nUn oggetto `FileTransferError` viene passato a un callback di errore quando si verifica un errore.\n\n### Proprietà\n\n  * **codice**: uno dei codici di errore predefiniti elencati di seguito. (Numero)\n\n  * **fonte**: URL all'origine. (String)\n\n  * **destinazione**: URL di destinazione. (String)\n\n  * **http_status**: codice di stato HTTP. Questo attributo è disponibile solo quando viene ricevuto un codice di risposta della connessione HTTP. (Numero)\n\n  * **body** Corpo della risposta. Questo attributo è disponibile solo quando viene ricevuta una risposta dalla connessione HTTP. (String)\n\n  * **exception**: O e.getMessage o e.toString (String)\n\n### Costanti\n\n  * 1 = `FileTransferError.FILE_NOT_FOUND_ERR`\n  * 2 = `FileTransferError.INVALID_URL_ERR`\n  * 3 = `FileTransferError.CONNECTION_ERR`\n  * 4 = `FileTransferError.ABORT_ERR`\n  * 5 = `FileTransferError.NOT_MODIFIED_ERR`\n\n## Note di compatibilità all'indietro\n\nVersioni precedenti di questo plugin accetterebbe solo dispositivo-assoluto-percorsi di file come origine per upload, o come destinazione per il download. Questi percorsi si sarebbero generalmente di forma\n\n    /var/mobile/Applications/<application UUID>/Documents/path/to/file  (iOS)\n    /storage/emulated/0/path/to/file                                    (Android)\n    \n\nPer indietro compatibilità, questi percorsi sono ancora accettati, e se l'applicazione ha registrato percorsi come questi in un archivio permanente, quindi possono continuare a essere utilizzato.\n\nQuesti percorsi sono stati precedentemente esposti nella proprietà `fullPath` di `FileEntry` e oggetti `DirectoryEntry` restituiti dal File plugin. Nuove versioni del File plugin, tuttavia, non è più espongono questi percorsi a JavaScript.\n\nSe si esegue l'aggiornamento a una nuova (1.0.0 o più recente) versione del File e si hanno precedentemente utilizzato `entry.fullPath` come argomenti per `download()` o `upload()`, quindi sarà necessario cambiare il codice per utilizzare gli URL filesystem invece.\n\n`FileEntry.toURL()` e `DirectoryEntry.toURL()` restituiscono un filesystem URL del modulo\n\n    cdvfile://localhost/persistent/path/to/file\n    \n\nche può essere utilizzato al posto del percorso assoluto nei metodi sia `download()` e `upload()`."
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/doc/it/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-file-transfer\n\nQuesto plugin permette di caricare e scaricare file.\n\nQuesto plugin definisce globale `FileTransfer`, costruttori di `FileUploadOptions`.\n\nAnche se in ambito globale, non sono disponibili fino a dopo l'evento `deviceready`.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(FileTransfer);\n    }\n    \n\n## Installazione\n\n    cordova plugin add cordova-plugin-file-transfer\n    \n\n## Piattaforme supportate\n\n*   Amazon fuoco OS\n*   Android\n*   BlackBerry 10\n*   Browser\n*   Firefox OS**\n*   iOS\n*   Windows Phone 7 e 8 *\n*   Windows 8\n*   Windows\n\n* *Supporto `onprogress` né `abort()`*\n\n** *Non supportano `onprogress`*\n\n# FileTransfer\n\nL'oggetto `FileTransfer` fornisce un modo per caricare i file utilizzando una richiesta HTTP di POST più parte e scaricare file pure.\n\n## Proprietà\n\n*   **OnProgress**: chiamata con un `ProgressEvent` ogni volta che un nuovo blocco di dati viene trasferito. *(Funzione)*\n\n## Metodi\n\n*   **caricare**: invia un file a un server.\n\n*   **Scarica**: Scarica un file dal server.\n\n*   **Abort**: interrompe un trasferimento in corso.\n\n## caricare\n\n**Parametri**:\n\n*   **fileURL**: Filesystem URL che rappresenta il file nel dispositivo. Per indietro la compatibilità, questo può anche essere il percorso completo del file sul dispositivo. (Vedere [indietro compatibilità rileva] qui sotto)\n\n*   **server**: URL del server per ricevere il file, come codificato dal`encodeURI()`.\n\n*   **successCallback**: un callback che viene passato un oggetto `FileUploadResult`. *(Funzione)*\n\n*   **errorCallback**: un callback che viene eseguito se si verifica un errore di recupero `FileUploadResult`. Richiamato con un oggetto `FileTransferError`. *(Funzione)*\n\n*   **opzioni**: parametri facoltativi *(oggetto)*. Chiavi valide:\n    \n    *   **fileKey**: il nome dell'elemento form. Valore predefinito è `file` . (DOMString)\n    *   **nome file**: il nome del file da utilizzare quando si salva il file sul server. Valore predefinito è `image.jpg` . (DOMString)\n    *   **httpMethod**: metodo HTTP da utilizzare - `PUT` o `POST`. Impostazioni predefinite per `POST`. (DOMString)\n    *   **mimeType**: il tipo mime dei dati da caricare. Impostazioni predefinite su `image/jpeg`. (DOMString)\n    *   **params**: un insieme di coppie chiave/valore opzionale per passare nella richiesta HTTP. (Object)\n    *   **chunkedMode**: se a caricare i dati in modalità streaming chunked. Impostazione predefinita è `true`. (Boolean)\n    *   **headers**: mappa di valori nome/intestazione intestazione. Utilizzare una matrice per specificare più valori. (Object)\n\n*   **trustAllHosts**: parametro opzionale, valore predefinito è `false` . Se impostata su `true` , accetta tutti i certificati di sicurezza. Questo è utile poiché Android respinge i certificati autofirmati sicurezza. Non raccomandato per uso in produzione. Supportato su Android e iOS. *(boolean)*\n\n### Esempio\n\n    // !! Assumes variable fileURL contains a valid URL to a text file on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/file.txt\n    \n    var win = function (r) {\n        console.log(\"Code = \" + r.responseCode);\n        console.log(\"Response = \" + r.response);\n        console.log(\"Sent = \" + r.bytesSent);\n    }\n    \n    var fail = function (error) {\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n    \n    var options = new FileUploadOptions();\n    options.fileKey = \"file\";\n    options.fileName = fileURL.substr(fileURL.lastIndexOf('/') + 1);\n    options.mimeType = \"text/plain\";\n    \n    var params = {};\n    params.value1 = \"test\";\n    params.value2 = \"param\";\n    \n    options.params = params;\n    \n    var ft = new FileTransfer();\n    ft.upload(fileURL, encodeURI(\"http://some.server.com/upload.php\"), win, fail, options);\n    \n\n### Esempio con intestazioni di caricare ed eventi Progress (Android e iOS solo)\n\n    function win(r) {\n        console.log(\"Code = \" + r.responseCode);\n        console.log(\"Response = \" + r.response);\n        console.log(\"Sent = \" + r.bytesSent);\n    }\n    \n    function fail(error) {\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n    \n    var uri = encodeURI(\"http://some.server.com/upload.php\");\n    \n    var options = new FileUploadOptions();\n    options.fileKey=\"file\";\n    options.fileName=fileURL.substr(fileURL.lastIndexOf('/')+1);\n    options.mimeType=\"text/plain\";\n    \n    var headers={'headerParam':'headerValue'};\n    \n    options.headers = headers;\n    \n    var ft = new FileTransfer();\n    ft.onprogress = function(progressEvent) {\n        if (progressEvent.lengthComputable) {\n          loadingStatus.setPercentage(progressEvent.loaded / progressEvent.total);\n        } else {\n          loadingStatus.increment();\n        }\n    };\n    ft.upload(fileURL, uri, win, fail, options);\n    \n\n## FileUploadResult\n\nUn oggetto `FileUploadResult` viene passato al metodo di callback del metodo `upload()` dell'oggetto `FileTransfer` successo.\n\n### Proprietà\n\n*   **bytesSent**: il numero di byte inviati al server come parte dell'upload. (lungo)\n\n*   **responseCode**: codice di risposta HTTP restituito dal server. (lungo)\n\n*   **risposta**: risposta HTTP restituito dal server. (DOMString)\n\n*   **intestazioni**: intestazioni di risposta HTTP dal server. (Oggetto)\n    \n    *   Attualmente supportato solo iOS.\n\n### iOS stranezze\n\n*   Non supporta `responseCode` o`bytesSent`.\n\n## Scarica\n\n**Parametri**:\n\n*   **fonte**: URL del server per scaricare il file, come codificato dal`encodeURI()`.\n\n*   **destinazione**: Filesystem url che rappresenta il file nel dispositivo. Per indietro la compatibilità, questo può anche essere il percorso completo del file sul dispositivo. (Vedere [indietro compatibilità rileva] qui sotto)\n\n*   **successCallback**: un callback passato un `FileEntry` oggetto. *(Funzione)*\n\n*   **errorCallback**: un callback che viene eseguito se si verifica un errore durante il recupero `FileEntry`. Richiamato con un oggetto `FileTransferError`. *(Function)*\n\n*   **trustAllHosts**: parametro opzionale, valore predefinito è `false` . Se impostata su `true` , accetta tutti i certificati di sicurezza. Questo è utile perché Android respinge i certificati autofirmati sicurezza. Non raccomandato per uso in produzione. Supportato su Android e iOS. *(boolean)*\n\n*   **opzioni**: parametri facoltativi, attualmente solo supporti intestazioni (ad esempio autorizzazione (autenticazione di base), ecc.).\n\n### Esempio\n\n    // !! Assumes variable fileURL contains a valid URL to a path on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/downloads/\n    \n    var fileTransfer = new FileTransfer();\n    var uri = encodeURI(\"http://some.server.com/download.php\");\n    \n    fileTransfer.download(\n        uri,\n        fileURL,\n        function(entry) {\n            console.log(\"download complete: \" + entry.toURL());\n        },\n        function(error) {\n            console.log(\"download error source \" + error.source);\n            console.log(\"download error target \" + error.target);\n            console.log(\"upload error code\" + error.code);\n        },\n        false,\n        {\n            headers: {\n                \"Authorization\": \"Basic dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA==\"\n            }\n        }\n    );\n    \n\n## Abort\n\nInterrompe un trasferimento in corso. Il callback onerror viene passato un oggetto FileTransferError che presenta un codice di errore di FileTransferError.ABORT_ERR.\n\n### Esempio\n\n    // !! Assumes variable fileURL contains a valid URL to a text file on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/file.txt\n    \n    var win = function(r) {\n        console.log(\"Should not be called.\");\n    }\n    \n    var fail = function(error) {\n        // error.code == FileTransferError.ABORT_ERR\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n    \n    var options = new FileUploadOptions();\n    options.fileKey=\"file\";\n    options.fileName=\"myphoto.jpg\";\n    options.mimeType=\"image/jpeg\";\n    \n    var ft = new FileTransfer();\n    ft.upload(fileURL, encodeURI(\"http://some.server.com/upload.php\"), win, fail, options);\n    ft.abort();\n    \n\n## FileTransferError\n\nUn oggetto `FileTransferError` viene passato a un callback di errore quando si verifica un errore.\n\n### Proprietà\n\n*   **codice**: uno dei codici di errore predefiniti elencati di seguito. (Numero)\n\n*   **fonte**: URL all'origine. (String)\n\n*   **destinazione**: URL di destinazione. (String)\n\n*   **http_status**: codice di stato HTTP. Questo attributo è disponibile solo quando viene ricevuto un codice di risposta della connessione HTTP. (Numero)\n\n*   **body** Corpo della risposta. Questo attributo è disponibile solo quando viene ricevuta una risposta dalla connessione HTTP. (String)\n\n*   **exception**: O e.getMessage o e.toString (String)\n\n### Costanti\n\n*   1 = `FileTransferError.FILE_NOT_FOUND_ERR`\n*   2 = `FileTransferError.INVALID_URL_ERR`\n*   3 = `FileTransferError.CONNECTION_ERR`\n*   4 = `FileTransferError.ABORT_ERR`\n*   5 = `FileTransferError.NOT_MODIFIED_ERR`\n\n## Note di compatibilità all'indietro\n\nVersioni precedenti di questo plugin accetterebbe solo dispositivo-assoluto-percorsi di file come origine per upload, o come destinazione per il download. Questi percorsi si sarebbero generalmente di forma\n\n    /var/mobile/Applications/<application UUID>/Documents/path/to/file  (iOS)\n    /storage/emulated/0/path/to/file                                    (Android)\n    \n\nPer indietro compatibilità, questi percorsi sono ancora accettati, e se l'applicazione ha registrato percorsi come questi in un archivio permanente, quindi possono continuare a essere utilizzato.\n\nQuesti percorsi sono stati precedentemente esposti nella proprietà `fullPath` di `FileEntry` e oggetti `DirectoryEntry` restituiti dal File plugin. Nuove versioni del File plugin, tuttavia, non è più espongono questi percorsi a JavaScript.\n\nSe si esegue l'aggiornamento a una nuova (1.0.0 o più recente) versione del File e si hanno precedentemente utilizzato `entry.fullPath` come argomenti per `download()` o `upload()`, quindi sarà necessario cambiare il codice per utilizzare gli URL filesystem invece.\n\n`FileEntry.toURL()` e `DirectoryEntry.toURL()` restituiscono un filesystem URL del modulo\n\n    cdvfile://localhost/persistent/path/to/file\n    \n\nche può essere utilizzato al posto del percorso assoluto nei metodi sia `download()` e `upload()`.\n"
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/doc/ja/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-file-transfer\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-file-transfer.svg)](https://travis-ci.org/apache/cordova-plugin-file-transfer)\n\nプラグインのマニュアル: <doc/index.md>\n\nこのプラグインは、アップロードし、ファイルをダウンロードすることができます。\n\nこのプラグインでは、グローバル `FileTransfer`、`FileUploadOptions` コンス トラクターを定義します。\n\nグローバル スコープでは使用できませんまで `deviceready` イベントの後です。\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(FileTransfer);\n    }\n    \n\n## インストール\n\n    cordova plugin add cordova-plugin-file-transfer\n    \n\n## サポートされているプラットフォーム\n\n  * アマゾン火 OS\n  * アンドロイド\n  * ブラックベリー 10\n  * ブラウザー\n  * Firefox の OS * *\n  * iOS\n  * Windows Phone 7 と 8 *\n  * Windows 8\n  * Windows\n\n\\ * * `Onprogress`も`abort()`をサポートしていません。*\n\n\\ * * * `Onprogress`をサポートしていません。*\n\n# 出色\n\n`出色`オブジェクトは、HTTP マルチパート POST または PUT 要求を使用してファイルをアップロードし、同様にファイルをダウンロードする方法を提供します。\n\n## プロパティ\n\n  * **onprogress**: と呼ばれる、 `ProgressEvent` データの新しいチャンクが転送されるたびに。*(機能)*\n\n## メソッド\n\n  * **アップロード**: サーバーにファイルを送信します。\n\n  * **ダウンロード**: サーバーからファイルをダウンロードします。\n\n  * **中止**: 進行中の転送を中止します。\n\n## upload\n\n**パラメーター**:\n\n  * **fileURL**: デバイス上のファイルを表すファイルシステム URL。 下位互換性は、このことも、デバイス上のファイルの完全パスであります。 （参照してください [後方互換性メモ] の下)\n\n  * **サーバー**: によって符号化されるように、ファイルを受信するサーバーの URL`encodeURI()`.\n\n  * **successCallback**: `FileUploadResult` オブジェクトが渡されるコールバック。*(機能)*\n\n  * **errorCallback**: エラー `FileUploadResult` を取得するが発生した場合に実行されるコールバック。`FileTransferError` オブジェクトを使って呼び出されます。*(機能)*\n\n  * **オプション**: 省略可能なパラメーター *(オブジェクト)*。有効なキー:\n    \n      * **fileKey**: フォーム要素の名前。既定値は `file` です。（，）\n      * **ファイル名**： ファイル名、サーバー上のファイルを保存するときに使用します。既定値は `image.jpg` です。（，）\n      * **httpMethod**: - `を置く` または `POST` のいずれかを使用する HTTP メソッド。デフォルト `のポスト` です。（，）\n      * **mimeType**: アップロードするデータの mime タイプ。`イメージ/jpeg` のデフォルトです。（，）\n      * **params**: HTTP リクエストに渡すために任意のキー/値ペアのセット。(オブジェクト)\n      * **chunkedMode**: チャンク ストリーミング モードでデータをアップロードするかどうか。デフォルトは `true` です。(ブール値)\n      * **headers**: ヘッダー名/ヘッダー値のマップ。 配列を使用して、1 つ以上の値を指定します。 IOS、FireOS、アンドロイドではという名前のコンテンツ タイプ ヘッダーが存在する場合、マルチパート フォーム データは使用されません。 (Object)\n      * **httpMethod**: 例えばを使用する HTTP メソッドを POST または PUT です。 デフォルト`のポスト`です。(DOMString)\n\n  * **trustAllHosts**: 省略可能なパラメーターは、デフォルト `false` 。 場合設定 `true` 、セキュリティ証明書をすべて受け付けます。 これは Android の自己署名入りセキュリティ証明書を拒否するので便利です。 運用環境で使用しないでください。 Android と iOS でサポートされています。 *(ブール値)*\n\n### 例\n\n    // !! Assumes variable fileURL contains a valid URL to a text file on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/file.txt\n    \n    var win = function (r) {\n        console.log(\"Code = \" + r.responseCode);\n        console.log(\"Response = \" + r.response);\n        console.log(\"Sent = \" + r.bytesSent);\n    }\n    \n    var fail = function (error) {\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n    \n    var options = new FileUploadOptions();\n    options.fileKey = \"file\";\n    options.fileName = fileURL.substr(fileURL.lastIndexOf('/') + 1);\n    options.mimeType = \"text/plain\";\n    \n    var params = {};\n    params.value1 = \"test\";\n    params.value2 = \"param\";\n    \n    options.params = params;\n    \n    var ft = new FileTransfer();\n    ft.upload(fileURL, encodeURI(\"http://some.server.com/upload.php\"), win, fail, options);\n    \n\n### サンプルのアップロード ヘッダーと進行状況のイベント （Android と iOS のみ）\n\n    function win(r) {\n        console.log(\"Code = \" + r.responseCode);\n        console.log(\"Response = \" + r.response);\n        console.log(\"Sent = \" + r.bytesSent);\n    }\n    \n    function fail(error) {\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n    \n    var uri = encodeURI(\"http://some.server.com/upload.php\");\n    \n    var options = new FileUploadOptions();\n    options.fileKey=\"file\";\n    options.fileName=fileURL.substr(fileURL.lastIndexOf('/')+1);\n    options.mimeType=\"text/plain\";\n    \n    var headers={'headerParam':'headerValue'};\n    \n    options.headers = headers;\n    \n    var ft = new FileTransfer();\n    ft.onprogress = function(progressEvent) {\n        if (progressEvent.lengthComputable) {\n          loadingStatus.setPercentage(progressEvent.loaded / progressEvent.total);\n        } else {\n          loadingStatus.increment();\n        }\n    };\n    ft.upload(fileURL, uri, win, fail, options);\n    \n\n## FileUploadResult\n\n`FileUploadResult` オブジェクトは `FileTransfer` オブジェクト `upload()` メソッドの成功時のコールバックに渡されます。\n\n### プロパティ\n\n  * **bytesSent**: アップロードの一部としてサーバーに送信されたバイト数。（ロング）\n\n  * **記述**: サーバーによって返される HTTP 応答コード。（ロング）\n\n  * **応答**: サーバーによって返される HTTP 応答。（，）\n\n  * **ヘッダー**: HTTP 応答ヘッダー サーバーによって。(オブジェクト)\n    \n      * 現在 iOS のみでサポートされます。\n\n### iOS の癖\n\n  * サポートしていない `responseCode` または`bytesSent`.\n\n## download\n\n**パラメーター**:\n\n  * **ソース**: によって符号化されるように、ファイルをダウンロードするサーバーの URL`encodeURI()`.\n\n  * **ターゲット**: デバイス上のファイルを表すファイルシステム url。 下位互換性は、このことも、デバイス上のファイルの完全パスであります。 （参照してください [後方互換性メモ] の下)\n\n  * **successCallback**: 渡されたコールバックを `FileEntry` オブジェクト。*(機能)*\n\n  * **errorCallback**: `FileEntry` を取得するときにエラーが発生した場合に実行されるコールバック。`FileTransferError` オブジェクトを使って呼び出されます。*(機能)*\n\n  * **trustAllHosts**: 省略可能なパラメーターは、デフォルト `false` 。 場合設定 `true` 、セキュリティ証明書をすべて受け付けます。 Android は、自己署名入りセキュリティ証明書を拒否しますので便利です。 運用環境で使用しないでください。 Android と iOS でサポートされています。 *(ブール値)*\n\n  * **オプション**: 省略可能なパラメーターは、現在サポートするヘッダーのみ (認証 (基本認証) など)。\n\n### 例\n\n    // !! Assumes variable fileURL contains a valid URL to a path on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/downloads/\n    \n    var fileTransfer = new FileTransfer();\n    var uri = encodeURI(\"http://some.server.com/download.php\");\n    \n    fileTransfer.download(\n        uri,\n        fileURL,\n        function(entry) {\n            console.log(\"download complete: \" + entry.toURL());\n        },\n        function(error) {\n            console.log(\"download error source \" + error.source);\n            console.log(\"download error target \" + error.target);\n            console.log(\"upload error code\" + error.code);\n        },\n        false,\n        {\n            headers: {\n                \"Authorization\": \"Basic dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA==\"\n            }\n        }\n    );\n    \n\n### WP8 癖\n\n  * ダウンロード要求するネイティブ実装によってキャッシュに格納されています。キャッシュされないように、渡す`以来変更された if`ヘッダー メソッドをダウンロードします。\n\n## abort\n\n進行中の転送を中止します。Onerror コールバックが FileTransferError.ABORT_ERR のエラー コードを持っている FileTransferError オブジェクトに渡されます。\n\n### 例\n\n    // !! Assumes variable fileURL contains a valid URL to a text file on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/file.txt\n    \n    var win = function(r) {\n        console.log(\"Should not be called.\");\n    }\n    \n    var fail = function(error) {\n        // error.code == FileTransferError.ABORT_ERR\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n    \n    var options = new FileUploadOptions();\n    options.fileKey=\"file\";\n    options.fileName=\"myphoto.jpg\";\n    options.mimeType=\"image/jpeg\";\n    \n    var ft = new FileTransfer();\n    ft.upload(fileURL, encodeURI(\"http://some.server.com/upload.php\"), win, fail, options);\n    ft.abort();\n    \n\n## FileTransferError\n\n`FileTransferError` オブジェクトは、エラーが発生したときにエラー コールバックに渡されます。\n\n### プロパティ\n\n  * **コード**: 次のいずれかの定義済みのエラー コード。(数)\n\n  * **ソース**: ソースの URL。(文字列)\n\n  * **ターゲット**: 先の URL。(文字列)\n\n  * **http_status**: HTTP ステータス コード。この属性は、HTTP 接続から応答コードを受信したときにのみ使用できます。(数)\n\n  * **body**応答本体。この属性は、HTTP 接続から応答を受信したときにのみ使用できます。(文字列)\n\n  * **exception**: どちらか e.getMessage または e.toString (文字列)\n\n### 定数\n\n  * 1 = `FileTransferError.FILE_NOT_FOUND_ERR`\n  * 2 = `FileTransferError.INVALID_URL_ERR`\n  * 3 = `FileTransferError.CONNECTION_ERR`\n  * 4 = `FileTransferError.ABORT_ERR`\n  * 5 = `FileTransferError.NOT_MODIFIED_ERR`\n\n## 後方互換性をノートします。\n\nこのプラグインの以前のバージョンまたはダウンロードのターゲットとして、アップロードのソースとしてのみデバイス絶対ファイル パスを受け入れるでしょう。これらのパスの形式は、通常\n\n    /var/mobile/Applications/<application UUID>/Documents/path/to/file  (iOS)\n    /storage/emulated/0/path/to/file                                    (Android)\n    \n\n下位互換性、これらのパスを使用しても、アプリケーションは、永続的なストレージでこのようなパスを記録している場合、し彼らが引き続き使用されます。\n\nこれらのパスの `FileEntry` やファイル プラグインによって返される `DirectoryEntry` オブジェクトの `fullPath` プロパティで公開されていなかった。 新しいプラグインのバージョン、ファイル、ただし、もはや java スクリプトの設定をこれらのパスを公開します。\n\n新しいにアップグレードする場合 (1.0.0 以降) ファイルのバージョン以前を使用している `entry.fullPath` `download()` または `upload()` への引数として、ファイルシステムの Url を代わりに使用するコードを変更する必要があります。\n\n`FileEntry.toURL()` と `DirectoryEntry.toURL()` ファイルシステムの URL を返すフォーム\n\n    cdvfile://localhost/persistent/path/to/file\n    \n\n`download()`、`upload()` メソッドの絶対ファイル パスの代わりに使用できます。"
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/doc/ja/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-file-transfer\n\nこのプラグインは、アップロードし、ファイルをダウンロードすることができます。\n\nこのプラグインでは、グローバル `FileTransfer`、`FileUploadOptions` コンス トラクターを定義します。\n\nグローバル スコープでは使用できませんまで `deviceready` イベントの後です。\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(FileTransfer);\n    }\n    \n\n## インストール\n\n    cordova plugin add cordova-plugin-file-transfer\n    \n\n## サポートされているプラットフォーム\n\n*   アマゾン火 OS\n*   アンドロイド\n*   ブラックベリー 10\n*   ブラウザー\n*   Firefox の OS * *\n*   iOS\n*   Windows Phone 7 と 8 *\n*   Windows 8\n*   Windows\n\n* *`onprogress` も `abort()` をサポートしていません*\n\n* * *`onprogress` をサポートしていません*\n\n# FileTransfer\n\n`FileTransfer` オブジェクトはマルチパートのポスト、HTTP 要求を使用してファイルをアップロードして同様にファイルをダウンロードする方法を提供します。\n\n## プロパティ\n\n*   **onprogress**: と呼ばれる、 `ProgressEvent` データの新しいチャンクが転送されるたびに。*(機能)*\n\n## メソッド\n\n*   **アップロード**: サーバーにファイルを送信します。\n\n*   **ダウンロード**: サーバーからファイルをダウンロードします。\n\n*   **中止**: 進行中の転送を中止します。\n\n## upload\n\n**パラメーター**:\n\n*   **fileURL**: デバイス上のファイルを表すファイルシステム URL。 下位互換性は、このことも、デバイス上のファイルの完全パスであります。 （参照してください [後方互換性メモ] の下)\n\n*   **サーバー**: によって符号化されるように、ファイルを受信するサーバーの URL`encodeURI()`.\n\n*   **successCallback**: `FileUploadResult` オブジェクトが渡されるコールバック。*(機能)*\n\n*   **errorCallback**: エラー `FileUploadResult` を取得するが発生した場合に実行されるコールバック。`FileTransferError` オブジェクトを使って呼び出されます。*(機能)*\n\n*   **オプション**: 省略可能なパラメーター *(オブジェクト)*。有効なキー:\n    \n    *   **fileKey**: フォーム要素の名前。既定値は `file` です。（，）\n    *   **ファイル名**： ファイル名、サーバー上のファイルを保存するときに使用します。既定値は `image.jpg` です。（，）\n    *   **httpMethod**: - `を置く` または `POST` のいずれかを使用する HTTP メソッド。デフォルト `のポスト` です。（，）\n    *   **mimeType**: アップロードするデータの mime タイプ。`イメージ/jpeg` のデフォルトです。（，）\n    *   **params**: HTTP リクエストに渡すために任意のキー/値ペアのセット。(オブジェクト)\n    *   **chunkedMode**: チャンク ストリーミング モードでデータをアップロードするかどうか。デフォルトは `true` です。(ブール値)\n    *   **headers**: ヘッダーの名前/ヘッダー値のマップ。1 つ以上の値を指定するには、配列を使用します。(オブジェクト)\n\n*   **trustAllHosts**: 省略可能なパラメーターは、デフォルト `false` 。 場合設定 `true` 、セキュリティ証明書をすべて受け付けます。 これは Android の自己署名入りセキュリティ証明書を拒否するので便利です。 運用環境で使用しないでください。 Android と iOS でサポートされています。 *(ブール値)*\n\n### 例\n\n    // !! Assumes variable fileURL contains a valid URL to a text file on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/file.txt\n    \n    var win = function (r) {\n        console.log(\"Code = \" + r.responseCode);\n        console.log(\"Response = \" + r.response);\n        console.log(\"Sent = \" + r.bytesSent);\n    }\n    \n    var fail = function (error) {\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n    \n    var options = new FileUploadOptions();\n    options.fileKey = \"file\";\n    options.fileName = fileURL.substr(fileURL.lastIndexOf('/') + 1);\n    options.mimeType = \"text/plain\";\n    \n    var params = {};\n    params.value1 = \"test\";\n    params.value2 = \"param\";\n    \n    options.params = params;\n    \n    var ft = new FileTransfer();\n    ft.upload(fileURL, encodeURI(\"http://some.server.com/upload.php\"), win, fail, options);\n    \n\n### サンプルのアップロード ヘッダーと進行状況のイベント （Android と iOS のみ）\n\n    function win(r) {\n        console.log(\"Code = \" + r.responseCode);\n        console.log(\"Response = \" + r.response);\n        console.log(\"Sent = \" + r.bytesSent);\n    }\n    \n    function fail(error) {\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n    \n    var uri = encodeURI(\"http://some.server.com/upload.php\");\n    \n    var options = new FileUploadOptions();\n    options.fileKey=\"file\";\n    options.fileName=fileURL.substr(fileURL.lastIndexOf('/')+1);\n    options.mimeType=\"text/plain\";\n    \n    var headers={'headerParam':'headerValue'};\n    \n    options.headers = headers;\n    \n    var ft = new FileTransfer();\n    ft.onprogress = function(progressEvent) {\n        if (progressEvent.lengthComputable) {\n          loadingStatus.setPercentage(progressEvent.loaded / progressEvent.total);\n        } else {\n          loadingStatus.increment();\n        }\n    };\n    ft.upload(fileURL, uri, win, fail, options);\n    \n\n## FileUploadResult\n\n`FileUploadResult` オブジェクトは `FileTransfer` オブジェクト `upload()` メソッドの成功時のコールバックに渡されます。\n\n### プロパティ\n\n*   **bytesSent**: アップロードの一部としてサーバーに送信されたバイト数。（ロング）\n\n*   **記述**: サーバーによって返される HTTP 応答コード。（ロング）\n\n*   **応答**: サーバーによって返される HTTP 応答。（，）\n\n*   **ヘッダー**: HTTP 応答ヘッダー サーバーによって。(オブジェクト)\n    \n    *   現在 iOS のみでサポートされます。\n\n### iOS の癖\n\n*   サポートしていない `responseCode` または`bytesSent`.\n\n## download\n\n**パラメーター**:\n\n*   **ソース**: によって符号化されるように、ファイルをダウンロードするサーバーの URL`encodeURI()`.\n\n*   **ターゲット**: デバイス上のファイルを表すファイルシステム url。 下位互換性は、このことも、デバイス上のファイルの完全パスであります。 （参照してください [後方互換性メモ] の下)\n\n*   **successCallback**: 渡されたコールバックを `FileEntry` オブジェクト。*(機能)*\n\n*   **errorCallback**: `FileEntry` を取得するときにエラーが発生した場合に実行されるコールバック。`FileTransferError` オブジェクトを使って呼び出されます。*(機能)*\n\n*   **trustAllHosts**: 省略可能なパラメーターは、デフォルト `false` 。 場合設定 `true` 、セキュリティ証明書をすべて受け付けます。 Android は、自己署名入りセキュリティ証明書を拒否しますので便利です。 運用環境で使用しないでください。 Android と iOS でサポートされています。 *(ブール値)*\n\n*   **オプション**: 省略可能なパラメーターは、現在サポートするヘッダーのみ (認証 (基本認証) など)。\n\n### 例\n\n    // !! Assumes variable fileURL contains a valid URL to a path on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/downloads/\n    \n    var fileTransfer = new FileTransfer();\n    var uri = encodeURI(\"http://some.server.com/download.php\");\n    \n    fileTransfer.download(\n        uri,\n        fileURL,\n        function(entry) {\n            console.log(\"download complete: \" + entry.toURL());\n        },\n        function(error) {\n            console.log(\"download error source \" + error.source);\n            console.log(\"download error target \" + error.target);\n            console.log(\"upload error code\" + error.code);\n        },\n        false,\n        {\n            headers: {\n                \"Authorization\": \"Basic dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA==\"\n            }\n        }\n    );\n    \n\n## abort\n\n進行中の転送を中止します。Onerror コールバックが FileTransferError.ABORT_ERR のエラー コードを持っている FileTransferError オブジェクトに渡されます。\n\n### 例\n\n    // !! Assumes variable fileURL contains a valid URL to a text file on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/file.txt\n    \n    var win = function(r) {\n        console.log(\"Should not be called.\");\n    }\n    \n    var fail = function(error) {\n        // error.code == FileTransferError.ABORT_ERR\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n    \n    var options = new FileUploadOptions();\n    options.fileKey=\"file\";\n    options.fileName=\"myphoto.jpg\";\n    options.mimeType=\"image/jpeg\";\n    \n    var ft = new FileTransfer();\n    ft.upload(fileURL, encodeURI(\"http://some.server.com/upload.php\"), win, fail, options);\n    ft.abort();\n    \n\n## FileTransferError\n\n`FileTransferError` オブジェクトは、エラーが発生したときにエラー コールバックに渡されます。\n\n### プロパティ\n\n*   **コード**: 次のいずれかの定義済みのエラー コード。(数)\n\n*   **ソース**: ソースの URL。(文字列)\n\n*   **ターゲット**: 先の URL。(文字列)\n\n*   **http_status**: HTTP ステータス コード。この属性は、HTTP 接続から応答コードを受信したときにのみ使用できます。(数)\n\n*   **body**応答本体。この属性は、HTTP 接続から応答を受信したときにのみ使用できます。(文字列)\n\n*   **exception**: どちらか e.getMessage または e.toString (文字列)\n\n### 定数\n\n*   1 = `FileTransferError.FILE_NOT_FOUND_ERR`\n*   2 = `FileTransferError.INVALID_URL_ERR`\n*   3 = `FileTransferError.CONNECTION_ERR`\n*   4 = `FileTransferError.ABORT_ERR`\n*   5 = `FileTransferError.NOT_MODIFIED_ERR`\n\n## 後方互換性をノートします。\n\nこのプラグインの以前のバージョンまたはダウンロードのターゲットとして、アップロードのソースとしてのみデバイス絶対ファイル パスを受け入れるでしょう。これらのパスの形式は、通常\n\n    /var/mobile/Applications/<application UUID>/Documents/path/to/file  (iOS)\n    /storage/emulated/0/path/to/file                                    (Android)\n    \n\n下位互換性、これらのパスを使用しても、アプリケーションは、永続的なストレージでこのようなパスを記録している場合、し彼らが引き続き使用されます。\n\nこれらのパスの `FileEntry` やファイル プラグインによって返される `DirectoryEntry` オブジェクトの `fullPath` プロパティで公開されていなかった。 新しいプラグインのバージョン、ファイル、ただし、もはや java スクリプトの設定をこれらのパスを公開します。\n\n新しいにアップグレードする場合 (1.0.0 以降) ファイルのバージョン以前を使用している `entry.fullPath` `download()` または `upload()` への引数として、ファイルシステムの Url を代わりに使用するコードを変更する必要があります。\n\n`FileEntry.toURL()` と `DirectoryEntry.toURL()` ファイルシステムの URL を返すフォーム\n\n    cdvfile://localhost/persistent/path/to/file\n    \n\n`download()`、`upload()` メソッドの絶対ファイル パスの代わりに使用できます。\n"
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/doc/ko/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-file-transfer\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-file-transfer.svg)](https://travis-ci.org/apache/cordova-plugin-file-transfer)\n\n플러그인 문서: <doc/index.md>\n\n이 플러그인을 사용 하면 업로드 및 다운로드 파일 수 있습니다.\n\n이 플러그인 글로벌 `FileTransfer`, `FileUploadOptions` 생성자를 정의합니다.\n\n전역 범위에서 그들은 제공 되지 않습니다 때까지 `deviceready` 이벤트 후.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(FileTransfer);\n    }\n    \n\n## 설치\n\n    cordova plugin add cordova-plugin-file-transfer\n    \n\n## 지원 되는 플랫폼\n\n  * 아마존 화재 운영 체제\n  * 안 드 로이드\n  * 블랙베리 10\n  * 브라우저\n  * 파이어 폭스 OS * *\n  * iOS\n  * Windows Phone 7과 8 *\n  * 윈도우 8\n  * 윈도우\n\n\\** `Onprogress` 도 `abort()` 를 지원 하지 않습니다*\n\n\\*** `Onprogress` 를 지원 하지 않습니다*\n\n# FileTransfer\n\n`FileTransfer` 개체는 HTTP 다중 파트 POST 또는 PUT 요청을 사용 하 여 파일을 업로드 하 고 또한 파일을 다운로드 하는 방법을 제공 합니다.\n\n## 속성\n\n  * **onprogress**:로 불리는 `ProgressEvent` 새로운 양의 데이터를 전송 하는 때마다. *(기능)*\n\n## 메서드\n\n  * **업로드**: 파일을 서버에 보냅니다.\n\n  * **다운로드**: 서버에서 파일을 다운로드 합니다.\n\n  * **중단**: 진행 중인 전송 중단.\n\n## 업로드\n\n**매개 변수**:\n\n  * **fileURL**: 장치에 파일을 나타내는 파일 시스템 URL. 에 대 한 이전 버전과 호환성을이 수도 장치에 있는 파일의 전체 경로 수. (참조 [거꾸로 호환성 노트] 아래)\n\n  * **서버**: 인코딩 파일 수신 서버의 URL`encodeURI()`.\n\n  * **successCallback**: `FileUploadResult` 개체를 전달 하는 콜백. *(기능)*\n\n  * **errorCallback**: `FileUploadResult` 검색에 오류가 발생 하면 실행 되는 콜백. `FileTransferError` 개체와 함께 호출 됩니다. *(기능)*\n\n  * **옵션**: 선택적 매개 변수 *(개체)*. 유효한 키:\n    \n      * **fileKey**: form 요소의 이름. 기본값은 `file` . (DOMString)\n      * **파일 이름**: 파일 이름을 서버에 파일을 저장할 때 사용 합니다. 기본값은 `image.jpg` . (DOMString)\n      * **httpMethod**: `넣어` 또는 `게시물`-사용 하도록 HTTP 메서드. `게시물` 기본값입니다. (DOMString)\n      * **mimeType**: 업로드 데이터의 mime 형식을. `이미지/jpeg`의 기본값입니다. (DOMString)\n      * **params**: HTTP 요청에 전달할 선택적 키/값 쌍의 집합. (개체)\n      * **chunkedMode**: 청크 스트리밍 모드에서 데이터 업로드를 합니다. 기본값은 `true`입니다. (부울)\n      * **headers**: 헤더 이름 및 헤더 값의 지도. 배열을 사용 하 여 하나 이상의 값을 지정. IOS, FireOS, 안 드 로이드에 있으면 라는 콘텐츠 형식 헤더, 다중 양식 데이터는 사용할 수 없습니다. (Object)\n      * **httpMethod**: HTTP 메서드 예를 사용 하 여 게시 하거나 넣어. `게시물`기본값입니다. (DOMString)\n\n  * **trustAllHosts**: 선택적 매개 변수는 기본적으로 `false` . 만약 설정 `true` , 그것은 모든 보안 인증서를 허용 합니다. 이 안 드 로이드 자체 서명 된 보안 인증서를 거부 하기 때문에 유용 합니다. 프로덕션 환경에서 사용 권장 되지 않습니다. 안 드 로이드와 iOS에서 지원. *(부울)*\n\n### 예를 들어\n\n    // !! Assumes variable fileURL contains a valid URL to a text file on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/file.txt\n    \n    var win = function (r) {\n        console.log(\"Code = \" + r.responseCode);\n        console.log(\"Response = \" + r.response);\n        console.log(\"Sent = \" + r.bytesSent);\n    }\n    \n    var fail = function (error) {\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n    \n    var options = new FileUploadOptions();\n    options.fileKey = \"file\";\n    options.fileName = fileURL.substr(fileURL.lastIndexOf('/') + 1);\n    options.mimeType = \"text/plain\";\n    \n    var params = {};\n    params.value1 = \"test\";\n    params.value2 = \"param\";\n    \n    options.params = params;\n    \n    var ft = new FileTransfer();\n    ft.upload(fileURL, encodeURI(\"http://some.server.com/upload.php\"), win, fail, options);\n    \n\n### 예를 들어 헤더 업로드 및 진행 이벤트 (안 드 로이드와 iOS만)\n\n    function win(r) {\n        console.log(\"Code = \" + r.responseCode);\n        console.log(\"Response = \" + r.response);\n        console.log(\"Sent = \" + r.bytesSent);\n    }\n    \n    function fail(error) {\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n    \n    var uri = encodeURI(\"http://some.server.com/upload.php\");\n    \n    var options = new FileUploadOptions();\n    options.fileKey=\"file\";\n    options.fileName=fileURL.substr(fileURL.lastIndexOf('/')+1);\n    options.mimeType=\"text/plain\";\n    \n    var headers={'headerParam':'headerValue'};\n    \n    options.headers = headers;\n    \n    var ft = new FileTransfer();\n    ft.onprogress = function(progressEvent) {\n        if (progressEvent.lengthComputable) {\n          loadingStatus.setPercentage(progressEvent.loaded / progressEvent.total);\n        } else {\n          loadingStatus.increment();\n        }\n    };\n    ft.upload(fileURL, uri, win, fail, options);\n    \n\n## FileUploadResult\n\n`FileUploadResult` 개체 `FileTransfer` 개체의 `원래` 방법의 성공 콜백에 전달 됩니다.\n\n### 속성\n\n  * **bytesSent**: 업로드의 일부로 서버에 보낸 바이트 수. (긴)\n\n  * **responseCode**: 서버에서 반환 된 HTTP 응답 코드. (긴)\n\n  * **response**: 서버에서 반환 되는 HTTP 응답. (DOMString)\n\n  * **headers**: 서버에서 HTTP 응답 헤더. (개체)\n    \n      * 현재 ios만 지원 합니다.\n\n### iOS 단점\n\n  * 지원 하지 않는 `responseCode` 또는`bytesSent`.\n\n## download\n\n**매개 변수**:\n\n  * **source**: URL로 인코딩된 파일, 다운로드 서버`encodeURI()`.\n\n  * **target**: 장치에 파일을 나타내는 파일 시스템 url. 에 대 한 이전 버전과 호환성을이 수도 장치에 있는 파일의 전체 경로 수. (참조 [거꾸로 호환성 노트] 아래)\n\n  * **successCallback**: 콜백 전달 되는 `FileEntry` 개체. *(기능)*\n\n  * **errorCallback**: `FileEntry`를 검색할 때 오류가 발생 하면 실행 되는 콜백. `FileTransferError` 개체와 함께 호출 됩니다. *(기능)*\n\n  * **trustAllHosts**: 선택적 매개 변수는 기본적으로 `false` . 만약 설정 `true` , 그것은 모든 보안 인증서를 허용 합니다. 안 드 로이드 자체 서명 된 보안 인증서를 거부 하기 때문에 유용 합니다. 프로덕션 환경에서 사용 권장 되지 않습니다. 안 드 로이드와 iOS에서 지원. *(부울)*\n\n  * **options**: 선택적 매개 변수를 현재 지 원하는 머리글만 (예: 인증 (기본 인증), 등).\n\n### 예를 들어\n\n    // !! Assumes variable fileURL contains a valid URL to a path on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/downloads/\n    \n    var fileTransfer = new FileTransfer();\n    var uri = encodeURI(\"http://some.server.com/download.php\");\n    \n    fileTransfer.download(\n        uri,\n        fileURL,\n        function(entry) {\n            console.log(\"download complete: \" + entry.toURL());\n        },\n        function(error) {\n            console.log(\"download error source \" + error.source);\n            console.log(\"download error target \" + error.target);\n            console.log(\"upload error code\" + error.code);\n        },\n        false,\n        {\n            headers: {\n                \"Authorization\": \"Basic dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA==\"\n            }\n        }\n    );\n    \n\n### WP8 특수\n\n  * 다운로드 요청 기본 구현에 의해 캐시 되 고. 캐싱을 방지 하려면 전달 `if-수정-이후` 헤더를 다운로드 하는 방법.\n\n## abort\n\n진행 중인 전송을 중단합니다. onerror 콜백 FileTransferError.ABORT_ERR의 오류 코드는 FileTransferError 개체를 전달 합니다.\n\n### 예를 들어\n\n    // !! Assumes variable fileURL contains a valid URL to a text file on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/file.txt\n    \n    var win = function(r) {\n        console.log(\"Should not be called.\");\n    }\n    \n    var fail = function(error) {\n        // error.code == FileTransferError.ABORT_ERR\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n    \n    var options = new FileUploadOptions();\n    options.fileKey=\"file\";\n    options.fileName=\"myphoto.jpg\";\n    options.mimeType=\"image/jpeg\";\n    \n    var ft = new FileTransfer();\n    ft.upload(fileURL, encodeURI(\"http://some.server.com/upload.php\"), win, fail, options);\n    ft.abort();\n    \n\n## FileTransferError\n\n`FileTransferError` 개체 오류가 발생 하면 오류 콜백에 전달 됩니다.\n\n### 속성\n\n  * **code**: 미리 정의 된 오류 코드 중 하나가 아래에 나열 된. (수)\n\n  * **source**: 소스 URL. (문자열)\n\n  * **target**: 대상 URL. (문자열)\n\n  * **http_status**: HTTP 상태 코드. 이 특성은 응답 코드를 HTTP 연결에서 수신에 사용할 수 있습니다. (수)\n\n  * **body** 응답 본문입니다. 이 특성은 HTTP 연결에서 응답을 받을 때에 사용할 수 있습니다. (문자열)\n\n  * **exception**: 어느 e.getMessage 또는 e.toString (문자열)\n\n### 상수\n\n  * 1 = `FileTransferError.FILE_NOT_FOUND_ERR`\n  * 2 = `FileTransferError.INVALID_URL_ERR`\n  * 3 = `FileTransferError.CONNECTION_ERR`\n  * 4 = `FileTransferError.ABORT_ERR`\n  * 5 = `FileTransferError.NOT_MODIFIED_ERR`\n\n## 이전 버전과 호환성 노트\n\n이 플러그인의 이전 버전만 업로드에 대 한 소스 또는 다운로드에 대 한 대상 장치 절대 파일 경로 받아들일 것 이다. 이러한 경로 일반적으로 폼의 것\n\n    /var/mobile/Applications/<application UUID>/Documents/path/to/file  (iOS)\n    /storage/emulated/0/path/to/file                                    (Android)\n    \n\n대 한 뒤 호환성, 이러한 경로 여전히 허용, 그리고 응용 프로그램이 영구 저장소에서 이와 같은 경로 기록 했다, 그때 그들은 계속할 수 있다면 사용할 수.\n\n이러한 경로 `FileEntry` 및 파일 플러그인에 의해 반환 된 `DirectoryEntry` 개체의 `fullPath` 속성에 노출 되었던. 그러나 파일 플러그인의,, 더 이상 새로운 버전 자바 스크립트이 경로 노출.\n\n새로 업그레이드 하는 경우 (1.0.0 이상) 버전의 파일, 및 이전 사용 하 고 `entry.fullPath` `download()` 또는 `upload()` 인수로 다음 대신 파일 시스템 Url을 사용 하 여 코드를 변경 해야 합니다.\n\n폼의 파일 URL을 반환 하는 `FileEntry.toURL()` 및 `DirectoryEntry.toURL()`\n\n    cdvfile://localhost/persistent/path/to/file\n    \n\n어떤 `download()` 및 `upload()` 방법에서 절대 파일 경로 대신 사용할 수 있습니다."
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/doc/ko/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-file-transfer\n\n이 플러그인을 사용 하면 업로드 및 다운로드 파일 수 있습니다.\n\n이 플러그인 글로벌 `FileTransfer`, `FileUploadOptions` 생성자를 정의합니다.\n\n전역 범위에서 그들은 제공 되지 않습니다 때까지 `deviceready` 이벤트 후.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(FileTransfer);\n    }\n    \n\n## 설치\n\n    cordova plugin add cordova-plugin-file-transfer\n    \n\n## 지원 되는 플랫폼\n\n*   아마존 화재 운영 체제\n*   안 드 로이드\n*   블랙베리 10\n*   브라우저\n*   파이어 폭스 OS * *\n*   iOS\n*   Windows Phone 7과 8 *\n*   윈도우 8\n*   윈도우\n\n* *`onprogress`도 `abort()`를 지원 하지 않습니다*\n\n* * *`onprogress`를 지원 하지 않습니다*\n\n# FileTransfer\n\n`FileTransfer` 개체는 HTTP 다중 파트 POST 요청을 사용 하 여 파일 업로드 뿐만 아니라 파일을 다운로드 하는 방법을 제공 합니다.\n\n## 속성\n\n*   **onprogress**:로 불리는 `ProgressEvent` 새로운 양의 데이터를 전송 하는 때마다. *(기능)*\n\n## 메서드\n\n*   **업로드**: 파일을 서버에 보냅니다.\n\n*   **다운로드**: 서버에서 파일을 다운로드 합니다.\n\n*   **중단**: 진행 중인 전송 중단.\n\n## 업로드\n\n**매개 변수**:\n\n*   **fileURL**: 장치에 파일을 나타내는 파일 시스템 URL. 에 대 한 이전 버전과 호환성을이 수도 장치에 있는 파일의 전체 경로 수. (참조 [거꾸로 호환성 노트] 아래)\n\n*   **서버**: 인코딩 파일 수신 서버의 URL`encodeURI()`.\n\n*   **successCallback**: `FileUploadResult` 개체를 전달 하는 콜백. *(기능)*\n\n*   **errorCallback**: `FileUploadResult` 검색에 오류가 발생 하면 실행 되는 콜백. `FileTransferError` 개체와 함께 호출 됩니다. *(기능)*\n\n*   **옵션**: 선택적 매개 변수 *(개체)*. 유효한 키:\n    \n    *   **fileKey**: form 요소의 이름. 기본값은 `file` . (DOMString)\n    *   **파일 이름**: 파일 이름을 서버에 파일을 저장할 때 사용 합니다. 기본값은 `image.jpg` . (DOMString)\n    *   **httpMethod**: `넣어` 또는 `게시물`-사용 하도록 HTTP 메서드. `게시물` 기본값입니다. (DOMString)\n    *   **mimeType**: 업로드 데이터의 mime 형식을. `이미지/jpeg`의 기본값입니다. (DOMString)\n    *   **params**: HTTP 요청에 전달할 선택적 키/값 쌍의 집합. (개체)\n    *   **chunkedMode**: 청크 스트리밍 모드에서 데이터 업로드를 합니다. 기본값은 `true`입니다. (부울)\n    *   **headers**: 헤더 이름/헤더 값의 지도. 배열을 사용 하 여 하나 이상의 값을 지정 합니다. (개체)\n\n*   **trustAllHosts**: 선택적 매개 변수는 기본적으로 `false` . 만약 설정 `true` , 그것은 모든 보안 인증서를 허용 합니다. 이 안 드 로이드 자체 서명 된 보안 인증서를 거부 하기 때문에 유용 합니다. 프로덕션 환경에서 사용 권장 되지 않습니다. 안 드 로이드와 iOS에서 지원. *(부울)*\n\n### 예를 들어\n\n    // !! Assumes variable fileURL contains a valid URL to a text file on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/file.txt\n    \n    var win = function (r) {\n        console.log(\"Code = \" + r.responseCode);\n        console.log(\"Response = \" + r.response);\n        console.log(\"Sent = \" + r.bytesSent);\n    }\n    \n    var fail = function (error) {\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n    \n    var options = new FileUploadOptions();\n    options.fileKey = \"file\";\n    options.fileName = fileURL.substr(fileURL.lastIndexOf('/') + 1);\n    options.mimeType = \"text/plain\";\n    \n    var params = {};\n    params.value1 = \"test\";\n    params.value2 = \"param\";\n    \n    options.params = params;\n    \n    var ft = new FileTransfer();\n    ft.upload(fileURL, encodeURI(\"http://some.server.com/upload.php\"), win, fail, options);\n    \n\n### 예를 들어 헤더 업로드 및 진행 이벤트 (안 드 로이드와 iOS만)\n\n    function win(r) {\n        console.log(\"Code = \" + r.responseCode);\n        console.log(\"Response = \" + r.response);\n        console.log(\"Sent = \" + r.bytesSent);\n    }\n    \n    function fail(error) {\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n    \n    var uri = encodeURI(\"http://some.server.com/upload.php\");\n    \n    var options = new FileUploadOptions();\n    options.fileKey=\"file\";\n    options.fileName=fileURL.substr(fileURL.lastIndexOf('/')+1);\n    options.mimeType=\"text/plain\";\n    \n    var headers={'headerParam':'headerValue'};\n    \n    options.headers = headers;\n    \n    var ft = new FileTransfer();\n    ft.onprogress = function(progressEvent) {\n        if (progressEvent.lengthComputable) {\n          loadingStatus.setPercentage(progressEvent.loaded / progressEvent.total);\n        } else {\n          loadingStatus.increment();\n        }\n    };\n    ft.upload(fileURL, uri, win, fail, options);\n    \n\n## FileUploadResult\n\n`FileUploadResult` 개체 `FileTransfer` 개체의 `원래` 방법의 성공 콜백에 전달 됩니다.\n\n### 속성\n\n*   **bytesSent**: 업로드의 일부로 서버에 보낸 바이트 수. (긴)\n\n*   **responseCode**: 서버에서 반환 된 HTTP 응답 코드. (긴)\n\n*   **response**: 서버에서 반환 되는 HTTP 응답. (DOMString)\n\n*   **headers**: 서버에서 HTTP 응답 헤더. (개체)\n    \n    *   현재 ios만 지원 합니다.\n\n### iOS 단점\n\n*   지원 하지 않는 `responseCode` 또는`bytesSent`.\n\n## download\n\n**매개 변수**:\n\n*   **source**: URL로 인코딩된 파일, 다운로드 서버`encodeURI()`.\n\n*   **target**: 장치에 파일을 나타내는 파일 시스템 url. 에 대 한 이전 버전과 호환성을이 수도 장치에 있는 파일의 전체 경로 수. (참조 [거꾸로 호환성 노트] 아래)\n\n*   **successCallback**: 콜백 전달 되는 `FileEntry` 개체. *(기능)*\n\n*   **errorCallback**: `FileEntry`를 검색할 때 오류가 발생 하면 실행 되는 콜백. `FileTransferError` 개체와 함께 호출 됩니다. *(기능)*\n\n*   **trustAllHosts**: 선택적 매개 변수는 기본적으로 `false` . 만약 설정 `true` , 그것은 모든 보안 인증서를 허용 합니다. 안 드 로이드 자체 서명 된 보안 인증서를 거부 하기 때문에 유용 합니다. 프로덕션 환경에서 사용 권장 되지 않습니다. 안 드 로이드와 iOS에서 지원. *(부울)*\n\n*   **options**: 선택적 매개 변수를 현재 지 원하는 머리글만 (예: 인증 (기본 인증), 등).\n\n### 예를 들어\n\n    // !! Assumes variable fileURL contains a valid URL to a path on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/downloads/\n    \n    var fileTransfer = new FileTransfer();\n    var uri = encodeURI(\"http://some.server.com/download.php\");\n    \n    fileTransfer.download(\n        uri,\n        fileURL,\n        function(entry) {\n            console.log(\"download complete: \" + entry.toURL());\n        },\n        function(error) {\n            console.log(\"download error source \" + error.source);\n            console.log(\"download error target \" + error.target);\n            console.log(\"upload error code\" + error.code);\n        },\n        false,\n        {\n            headers: {\n                \"Authorization\": \"Basic dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA==\"\n            }\n        }\n    );\n    \n\n## abort\n\n진행 중인 전송을 중단합니다. onerror 콜백 FileTransferError.ABORT_ERR의 오류 코드는 FileTransferError 개체를 전달 합니다.\n\n### 예를 들어\n\n    // !! Assumes variable fileURL contains a valid URL to a text file on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/file.txt\n    \n    var win = function(r) {\n        console.log(\"Should not be called.\");\n    }\n    \n    var fail = function(error) {\n        // error.code == FileTransferError.ABORT_ERR\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n    \n    var options = new FileUploadOptions();\n    options.fileKey=\"file\";\n    options.fileName=\"myphoto.jpg\";\n    options.mimeType=\"image/jpeg\";\n    \n    var ft = new FileTransfer();\n    ft.upload(fileURL, encodeURI(\"http://some.server.com/upload.php\"), win, fail, options);\n    ft.abort();\n    \n\n## FileTransferError\n\n`FileTransferError` 개체 오류가 발생 하면 오류 콜백에 전달 됩니다.\n\n### 속성\n\n*   **code**: 미리 정의 된 오류 코드 중 하나가 아래에 나열 된. (수)\n\n*   **source**: 소스 URL. (문자열)\n\n*   **target**: 대상 URL. (문자열)\n\n*   **http_status**: HTTP 상태 코드. 이 특성은 응답 코드를 HTTP 연결에서 수신에 사용할 수 있습니다. (수)\n\n*   **body** 응답 본문입니다. 이 특성은 HTTP 연결에서 응답을 받을 때에 사용할 수 있습니다. (문자열)\n\n*   **exception**: 어느 e.getMessage 또는 e.toString (문자열)\n\n### 상수\n\n*   1 = `FileTransferError.FILE_NOT_FOUND_ERR`\n*   2 = `FileTransferError.INVALID_URL_ERR`\n*   3 = `FileTransferError.CONNECTION_ERR`\n*   4 = `FileTransferError.ABORT_ERR`\n*   5 = `FileTransferError.NOT_MODIFIED_ERR`\n\n## 이전 버전과 호환성 노트\n\n이 플러그인의 이전 버전만 업로드에 대 한 소스 또는 다운로드에 대 한 대상 장치 절대 파일 경로 받아들일 것 이다. 이러한 경로 일반적으로 폼의 것\n\n    /var/mobile/Applications/<application UUID>/Documents/path/to/file  (iOS)\n    /storage/emulated/0/path/to/file                                    (Android)\n    \n\n대 한 뒤 호환성, 이러한 경로 여전히 허용, 그리고 응용 프로그램이 영구 저장소에서 이와 같은 경로 기록 했다, 그때 그들은 계속할 수 있다면 사용할 수.\n\n이러한 경로 `FileEntry` 및 파일 플러그인에 의해 반환 된 `DirectoryEntry` 개체의 `fullPath` 속성에 노출 되었던. 그러나 파일 플러그인의,, 더 이상 새로운 버전 자바 스크립트이 경로 노출.\n\n새로 업그레이드 하는 경우 (1.0.0 이상) 버전의 파일, 및 이전 사용 하 고 `entry.fullPath` `download()` 또는 `upload()` 인수로 다음 대신 파일 시스템 Url을 사용 하 여 코드를 변경 해야 합니다.\n\n폼의 파일 URL을 반환 하는 `FileEntry.toURL()` 및 `DirectoryEntry.toURL()`\n\n    cdvfile://localhost/persistent/path/to/file\n    \n\n어떤 `download()` 및 `upload()` 방법에서 절대 파일 경로 대신 사용할 수 있습니다.\n"
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/doc/pl/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-file-transfer\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-file-transfer.svg)](https://travis-ci.org/apache/cordova-plugin-file-transfer)\n\nPlugin dokumentacja: <doc/index.md>\n\nPlugin pozwala na przesyłanie i pobieranie plików.\n\nTen plugin określa globalne `FileTransfer`, `FileUploadOptions` konstruktorów.\n\nChociaż w globalnym zasięgu, są nie dostępne dopiero po `deviceready` imprezie.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(FileTransfer);\n    }\n    \n\n## Instalacja\n\n    cordova plugin add cordova-plugin-file-transfer\n    \n\n## Obsługiwane platformy\n\n  * Amazon Fire OS\n  * Android\n  * BlackBerry 10\n  * Przeglądarka\n  * Firefox OS **\n  * iOS\n  * Windows Phone 7 i 8 *\n  * Windows 8\n  * Windows\n\n\\ * *Nie obsługują `onprogress` ani `abort()` *\n\n\\ ** *Nie obsługują `onprogress` *\n\n# FileTransfer\n\nObiekt `FileTransfer` zapewnia sposób wgrać pliki za pomocą Multi-część POST lub PUT żądania HTTP i pobierania plików, jak również.\n\n## Właściwości\n\n  * **OnProgress**: o nazwie `ProgressEvent` gdy nowy kawałek danych jest przenoszona. *(Funkcja)*\n\n## Metody\n\n  * **wgraj**: wysyła plik na serwer.\n\n  * **do pobrania**: pliki do pobrania pliku z serwera.\n\n  * **przerwać**: przerywa w toku transferu.\n\n## upload\n\n**Parametry**:\n\n  * **fileURL**: URL plików reprezentujących pliku na urządzenie. Dla wstecznej kompatybilności, to może również być pełną ścieżkę pliku na urządzenie. (Zobacz [wstecz zgodności zauważa] poniżej)\n\n  * **serwer**: adres URL serwera, aby otrzymać plik, jak kodowane przez`encodeURI()`.\n\n  * **successCallback**: wywołania zwrotnego, który jest przekazywany obiekt `FileUploadResult`. *(Funkcja)*\n\n  * **errorCallback**: wywołanie zwrotne, które wykonuje, jeżeli wystąpi błąd pobierania `FileUploadResult`. Wywoływany z obiektu `FileTransferError`. *(Funkcja)*\n\n  * **Opcje**: parametry opcjonalne *(obiektu)*. Ważne klucze:\n    \n      * **fileKey**: nazwa elementu form. Domyślnie `file` . (DOMString)\n      * **Nazwa pliku**: nazwy pliku, aby użyć podczas zapisywania pliku na serwerze. Domyślnie `image.jpg` . (DOMString)\n      * **element httpMethod**: Metoda HTTP do użycia - `umieścić` lub `POST`. Domyślnie `POST`. (DOMString)\n      * **mimeType**: Typ mime danych do przesłania. Domyślnie do `image/jpeg`. (DOMString)\n      * **params**: zestaw par opcjonalny klucz/wartość w żądaniu HTTP. (Obiekt)\n      * **chunkedMode**: czy przekazać dane w trybie pakietowego przesyłania strumieniowego. Wartością domyślną jest `true`. (Wartość logiczna)\n      * **headers**: Mapa wartości Nazwa/nagłówka nagłówek. Aby określić więcej niż jedną wartość, należy użyć tablicę. Na iOS, FireOS i Android jeśli nagłówek o nazwie Content-Type jest obecny, wieloczęściowa forma nie danych. (Object)\n      * **element httpMethod**: Metoda HTTP np. POST lub PUT. Ustawienia domyślne do `POST`. (DOMString)\n\n  * **trustAllHosts**: parametr opcjonalny, domyślnie `false` . Jeśli zestaw `true` , to akceptuje wszystkie certyfikaty bezpieczeństwa. Jest to przydatne, ponieważ Android odrzuca Certyfikaty samopodpisane. Nie zaleca się do użytku produkcyjnego. Obsługiwane na Androida i iOS. *(wartość logiczna)*\n\n### Przykład\n\n    // !! Assumes variable fileURL contains a valid URL to a text file on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/file.txt\n    \n    var win = function (r) {\n        console.log(\"Code = \" + r.responseCode);\n        console.log(\"Response = \" + r.response);\n        console.log(\"Sent = \" + r.bytesSent);\n    }\n    \n    var fail = function (error) {\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n    \n    var options = new FileUploadOptions();\n    options.fileKey = \"file\";\n    options.fileName = fileURL.substr(fileURL.lastIndexOf('/') + 1);\n    options.mimeType = \"text/plain\";\n    \n    var params = {};\n    params.value1 = \"test\";\n    params.value2 = \"param\";\n    \n    options.params = params;\n    \n    var ft = new FileTransfer();\n    ft.upload(fileURL, encodeURI(\"http://some.server.com/upload.php\"), win, fail, options);\n    \n\n### Przykład z Prześlij nagłówki i zdarzeń postępu (Android i iOS tylko)\n\n    function win(r) {\n        console.log(\"Code = \" + r.responseCode);\n        console.log(\"Response = \" + r.response);\n        console.log(\"Sent = \" + r.bytesSent);\n    }\n    \n    function fail(error) {\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n    \n    var uri = encodeURI(\"http://some.server.com/upload.php\");\n    \n    var options = new FileUploadOptions();\n    options.fileKey=\"file\";\n    options.fileName=fileURL.substr(fileURL.lastIndexOf('/')+1);\n    options.mimeType=\"text/plain\";\n    \n    var headers={'headerParam':'headerValue'};\n    \n    options.headers = headers;\n    \n    var ft = new FileTransfer();\n    ft.onprogress = function(progressEvent) {\n        if (progressEvent.lengthComputable) {\n          loadingStatus.setPercentage(progressEvent.loaded / progressEvent.total);\n        } else {\n          loadingStatus.increment();\n        }\n    };\n    ft.upload(fileURL, uri, win, fail, options);\n    \n\n## FileUploadResult\n\nObiekt `FileUploadResult` jest przekazywana do sukcesu wywołania zwrotnego metody `upload() służącą` obiektu `FileTransfer`.\n\n### Właściwości\n\n  * **bytesSent**: liczba bajtów wysłanych do serwera jako część upload. (długie)\n\n  * **responseCode**: kod odpowiedzi HTTP, zwracane przez serwer. (długie)\n\n  * **odpowiedź**: HTTP odpowiedzi zwracane przez serwer. (DOMString)\n\n  * **nagłówki**: nagłówki HTTP odpowiedzi przez serwer. (Obiekt)\n    \n      * Obecnie obsługiwane na iOS tylko.\n\n### Dziwactwa iOS\n\n  * Nie obsługuje `responseCode` lub`bytesSent`.\n\n## download\n\n**Parametry**:\n\n  * **Źródło**: adres URL serwera, aby pobrać plik, jak kodowane przez`encodeURI()`.\n\n  * **cel**: url plików reprezentujących pliku na urządzenie. Dla wstecznej kompatybilności, to może również być pełną ścieżkę pliku na urządzenie. (Zobacz [wstecz zgodności zauważa] poniżej)\n\n  * **successCallback**: wywołania zwrotnego, który jest przekazywany `FileEntry` obiektu. *(Funkcja)*\n\n  * **errorCallback**: wywołanie zwrotne, które wykonuje, jeśli wystąpi błąd podczas pobierania `FileEntry`. Wywoływany z obiektu `FileTransferError`. *(Funkcja)*\n\n  * **trustAllHosts**: parametr opcjonalny, domyślnie `false` . Jeśli zestaw `true` , to akceptuje wszystkie certyfikaty bezpieczeństwa. Jest to przydatne, ponieważ Android odrzuca Certyfikaty samopodpisane. Nie zaleca się do użytku produkcyjnego. Obsługiwane na Androida i iOS. *(wartość logiczna)*\n\n  * **Opcje**: parametry opcjonalne, obecnie tylko obsługuje nagłówki (takie jak autoryzacja (uwierzytelnianie podstawowe), itp.).\n\n### Przykład\n\n    // !! Assumes variable fileURL contains a valid URL to a path on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/downloads/\n    \n    var fileTransfer = new FileTransfer();\n    var uri = encodeURI(\"http://some.server.com/download.php\");\n    \n    fileTransfer.download(\n        uri,\n        fileURL,\n        function(entry) {\n            console.log(\"download complete: \" + entry.toURL());\n        },\n        function(error) {\n            console.log(\"download error source \" + error.source);\n            console.log(\"download error target \" + error.target);\n            console.log(\"upload error code\" + error.code);\n        },\n        false,\n        {\n            headers: {\n                \"Authorization\": \"Basic dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA==\"\n            }\n        }\n    );\n    \n\n### WP8 dziwactwa\n\n  * Pobierz wnioski są buforowane przez rodzimych realizacji. Aby uniknąć, buforowanie, przekazać `if-Modified-Since` nagłówka do pobrania Metoda.\n\n## abort\n\nPrzerywa w toku transferu. Onerror callback jest przekazywany obiekt FileTransferError, który kod błędu z FileTransferError.ABORT_ERR.\n\n### Przykład\n\n    // !! Assumes variable fileURL contains a valid URL to a text file on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/file.txt\n    \n    var win = function(r) {\n        console.log(\"Should not be called.\");\n    }\n    \n    var fail = function(error) {\n        // error.code == FileTransferError.ABORT_ERR\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n    \n    var options = new FileUploadOptions();\n    options.fileKey=\"file\";\n    options.fileName=\"myphoto.jpg\";\n    options.mimeType=\"image/jpeg\";\n    \n    var ft = new FileTransfer();\n    ft.upload(fileURL, encodeURI(\"http://some.server.com/upload.php\"), win, fail, options);\n    ft.abort();\n    \n\n## FileTransferError\n\nObiekt `FileTransferError` jest przekazywana do błąd wywołania zwrotnego, gdy wystąpi błąd.\n\n### Właściwości\n\n  * **Kod**: jeden z kodów błędów wstępnie zdefiniowanych poniżej. (Liczba)\n\n  * **Źródło**: URL do źródła. (String)\n\n  * **cel**: adres URL do docelowego. (String)\n\n  * **HTTP_STATUS**: kod stanu HTTP. Ten atrybut jest dostępna tylko po otrzymaniu kodu odpowiedzi z połączenia HTTP. (Liczba)\n\n  * **body** Treść odpowiedzi. Ten atrybut jest dostępna tylko wtedy, gdy odpowiedź jest otrzymanych od połączenia HTTP. (String)\n\n  * **exception**: albo e.getMessage lub e.toString (String)\n\n### Stałe\n\n  * 1 = `FileTransferError.FILE_NOT_FOUND_ERR`\n  * 2 = `FileTransferError.INVALID_URL_ERR`\n  * 3 = `FileTransferError.CONNECTION_ERR`\n  * 4 = `FileTransferError.ABORT_ERR`\n  * 5 = `FileTransferError.NOT_MODIFIED_ERR`\n\n## Do tyłu zgodności stwierdza\n\nPoprzednie wersje tego pluginu tylko zaakceptować urządzenia bezwzględnych ścieżek jako źródło dla przekazywania, lub w celu pobrania. Te ścieżki będzie zazwyczaj formy\n\n    /var/mobile/Applications/<application UUID>/Documents/path/to/file  (iOS)\n    /storage/emulated/0/path/to/file                                    (Android)\n    \n\nDo tyłu zgodności, akceptowane są jeszcze te ścieżki, i jeśli aplikacja nagrał ścieżki, jak te w trwałej pamięci, następnie można nadal stosować.\n\nTe ścieżki były narażone wcześniej we właściwości `fullPath` `FileEntry` i `DirectoryEntry` obiektów zwróconych przez wtyczki pliku. Nowe wersje pliku plugin, jednak już wystawiać te ścieżki do JavaScript.\n\nJeśli uaktualniasz nowy (1.0.0 lub nowsza) wersja pliku i mieć wcześniej przy `entry.fullPath` jako argumenty `download()` lub `upload() służącą`, a następnie trzeba będzie zmienić kod aby używać adresów URL plików zamiast.\n\n`FileEntry.toURL()` i `DirectoryEntry.toURL()` zwraca adres URL plików formularza\n\n    cdvfile://localhost/persistent/path/to/file\n    \n\nktóre mogą być używane zamiast bezwzględna ścieżka zarówno `download()` i `metody upload()` metody."
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/doc/pl/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-file-transfer\n\nPlugin pozwala na przesyłanie i pobieranie plików.\n\nTen plugin określa globalne `FileTransfer`, `FileUploadOptions` konstruktorów.\n\nChociaż w globalnym zasięgu, są nie dostępne dopiero po `deviceready` imprezie.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(FileTransfer);\n    }\n    \n\n## Instalacja\n\n    cordova plugin add cordova-plugin-file-transfer\n    \n\n## Obsługiwane platformy\n\n*   Amazon Fire OS\n*   Android\n*   BlackBerry 10\n*   Przeglądarka\n*   Firefox OS **\n*   iOS\n*   Windows Phone 7 i 8 *\n*   Windows 8\n*   Windows\n\n* *Nie obsługują `onprogress` ani `abort()`*\n\n* * *Nie obsługują `onprogress`*\n\n# FileTransfer\n\nObiekt `FileTransfer` zapewnia sposób wgrać pliki przy użyciu żądania HTTP wieloczęściowe POST i pobierania plików, jak również.\n\n## Właściwości\n\n*   **OnProgress**: o nazwie `ProgressEvent` gdy nowy kawałek danych jest przenoszona. *(Funkcja)*\n\n## Metody\n\n*   **wgraj**: wysyła plik na serwer.\n\n*   **do pobrania**: pliki do pobrania pliku z serwera.\n\n*   **przerwać**: przerywa w toku transferu.\n\n## upload\n\n**Parametry**:\n\n*   **fileURL**: URL plików reprezentujących pliku na urządzenie. Dla wstecznej kompatybilności, to może również być pełną ścieżkę pliku na urządzenie. (Zobacz [wstecz zgodności zauważa] poniżej)\n\n*   **serwer**: adres URL serwera, aby otrzymać plik, jak kodowane przez`encodeURI()`.\n\n*   **successCallback**: wywołania zwrotnego, który jest przekazywany obiekt `FileUploadResult`. *(Funkcja)*\n\n*   **errorCallback**: wywołanie zwrotne, które wykonuje, jeżeli wystąpi błąd pobierania `FileUploadResult`. Wywoływany z obiektu `FileTransferError`. *(Funkcja)*\n\n*   **Opcje**: parametry opcjonalne *(obiektu)*. Ważne klucze:\n    \n    *   **fileKey**: nazwa elementu form. Domyślnie `file` . (DOMString)\n    *   **Nazwa pliku**: nazwy pliku, aby użyć podczas zapisywania pliku na serwerze. Domyślnie `image.jpg` . (DOMString)\n    *   **element httpMethod**: Metoda HTTP do użycia - `umieścić` lub `POST`. Domyślnie `POST`. (DOMString)\n    *   **mimeType**: Typ mime danych do przesłania. Domyślnie do `image/jpeg`. (DOMString)\n    *   **params**: zestaw par opcjonalny klucz/wartość w żądaniu HTTP. (Obiekt)\n    *   **chunkedMode**: czy przekazać dane w trybie pakietowego przesyłania strumieniowego. Wartością domyślną jest `true`. (Wartość logiczna)\n    *   **headers**: Mapa wartości Nazwa/nagłówka nagłówek. Aby określić więcej niż jedną wartość, należy użyć tablicę. (Obiekt)\n\n*   **trustAllHosts**: parametr opcjonalny, domyślnie `false` . Jeśli zestaw `true` , to akceptuje wszystkie certyfikaty bezpieczeństwa. Jest to przydatne, ponieważ Android odrzuca Certyfikaty samopodpisane. Nie zaleca się do użytku produkcyjnego. Obsługiwane na Androida i iOS. *(wartość logiczna)*\n\n### Przykład\n\n    // !! Assumes variable fileURL contains a valid URL to a text file on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/file.txt\n    \n    var win = function (r) {\n        console.log(\"Code = \" + r.responseCode);\n        console.log(\"Response = \" + r.response);\n        console.log(\"Sent = \" + r.bytesSent);\n    }\n    \n    var fail = function (error) {\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n    \n    var options = new FileUploadOptions();\n    options.fileKey = \"file\";\n    options.fileName = fileURL.substr(fileURL.lastIndexOf('/') + 1);\n    options.mimeType = \"text/plain\";\n    \n    var params = {};\n    params.value1 = \"test\";\n    params.value2 = \"param\";\n    \n    options.params = params;\n    \n    var ft = new FileTransfer();\n    ft.upload(fileURL, encodeURI(\"http://some.server.com/upload.php\"), win, fail, options);\n    \n\n### Przykład z Prześlij nagłówki i zdarzeń postępu (Android i iOS tylko)\n\n    function win(r) {\n        console.log(\"Code = \" + r.responseCode);\n        console.log(\"Response = \" + r.response);\n        console.log(\"Sent = \" + r.bytesSent);\n    }\n    \n    function fail(error) {\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n    \n    var uri = encodeURI(\"http://some.server.com/upload.php\");\n    \n    var options = new FileUploadOptions();\n    options.fileKey=\"file\";\n    options.fileName=fileURL.substr(fileURL.lastIndexOf('/')+1);\n    options.mimeType=\"text/plain\";\n    \n    var headers={'headerParam':'headerValue'};\n    \n    options.headers = headers;\n    \n    var ft = new FileTransfer();\n    ft.onprogress = function(progressEvent) {\n        if (progressEvent.lengthComputable) {\n          loadingStatus.setPercentage(progressEvent.loaded / progressEvent.total);\n        } else {\n          loadingStatus.increment();\n        }\n    };\n    ft.upload(fileURL, uri, win, fail, options);\n    \n\n## FileUploadResult\n\nObiekt `FileUploadResult` jest przekazywana do sukcesu wywołania zwrotnego metody `upload() służącą` obiektu `FileTransfer`.\n\n### Właściwości\n\n*   **bytesSent**: liczba bajtów wysłanych do serwera jako część upload. (długie)\n\n*   **responseCode**: kod odpowiedzi HTTP, zwracane przez serwer. (długie)\n\n*   **odpowiedź**: HTTP odpowiedzi zwracane przez serwer. (DOMString)\n\n*   **nagłówki**: nagłówki HTTP odpowiedzi przez serwer. (Obiekt)\n    \n    *   Obecnie obsługiwane na iOS tylko.\n\n### Dziwactwa iOS\n\n*   Nie obsługuje `responseCode` lub`bytesSent`.\n\n## download\n\n**Parametry**:\n\n*   **Źródło**: adres URL serwera, aby pobrać plik, jak kodowane przez`encodeURI()`.\n\n*   **cel**: url plików reprezentujących pliku na urządzenie. Dla wstecznej kompatybilności, to może również być pełną ścieżkę pliku na urządzenie. (Zobacz [wstecz zgodności zauważa] poniżej)\n\n*   **successCallback**: wywołania zwrotnego, który jest przekazywany `FileEntry` obiektu. *(Funkcja)*\n\n*   **errorCallback**: wywołanie zwrotne, które wykonuje, jeśli wystąpi błąd podczas pobierania `FileEntry`. Wywoływany z obiektu `FileTransferError`. *(Funkcja)*\n\n*   **trustAllHosts**: parametr opcjonalny, domyślnie `false` . Jeśli zestaw `true` , to akceptuje wszystkie certyfikaty bezpieczeństwa. Jest to przydatne, ponieważ Android odrzuca Certyfikaty samopodpisane. Nie zaleca się do użytku produkcyjnego. Obsługiwane na Androida i iOS. *(wartość logiczna)*\n\n*   **Opcje**: parametry opcjonalne, obecnie tylko obsługuje nagłówki (takie jak autoryzacja (uwierzytelnianie podstawowe), itp.).\n\n### Przykład\n\n    // !! Assumes variable fileURL contains a valid URL to a path on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/downloads/\n    \n    var fileTransfer = new FileTransfer();\n    var uri = encodeURI(\"http://some.server.com/download.php\");\n    \n    fileTransfer.download(\n        uri,\n        fileURL,\n        function(entry) {\n            console.log(\"download complete: \" + entry.toURL());\n        },\n        function(error) {\n            console.log(\"download error source \" + error.source);\n            console.log(\"download error target \" + error.target);\n            console.log(\"upload error code\" + error.code);\n        },\n        false,\n        {\n            headers: {\n                \"Authorization\": \"Basic dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA==\"\n            }\n        }\n    );\n    \n\n## abort\n\nPrzerywa w toku transferu. Onerror callback jest przekazywany obiekt FileTransferError, który kod błędu z FileTransferError.ABORT_ERR.\n\n### Przykład\n\n    // !! Assumes variable fileURL contains a valid URL to a text file on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/file.txt\n    \n    var win = function(r) {\n        console.log(\"Should not be called.\");\n    }\n    \n    var fail = function(error) {\n        // error.code == FileTransferError.ABORT_ERR\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n    \n    var options = new FileUploadOptions();\n    options.fileKey=\"file\";\n    options.fileName=\"myphoto.jpg\";\n    options.mimeType=\"image/jpeg\";\n    \n    var ft = new FileTransfer();\n    ft.upload(fileURL, encodeURI(\"http://some.server.com/upload.php\"), win, fail, options);\n    ft.abort();\n    \n\n## FileTransferError\n\nObiekt `FileTransferError` jest przekazywana do błąd wywołania zwrotnego, gdy wystąpi błąd.\n\n### Właściwości\n\n*   **Kod**: jeden z kodów błędów wstępnie zdefiniowanych poniżej. (Liczba)\n\n*   **Źródło**: URL do źródła. (String)\n\n*   **cel**: adres URL do docelowego. (String)\n\n*   **HTTP_STATUS**: kod stanu HTTP. Ten atrybut jest dostępna tylko po otrzymaniu kodu odpowiedzi z połączenia HTTP. (Liczba)\n\n*   **body** Treść odpowiedzi. Ten atrybut jest dostępna tylko wtedy, gdy odpowiedź jest otrzymanych od połączenia HTTP. (String)\n\n*   **exception**: albo e.getMessage lub e.toString (String)\n\n### Stałe\n\n*   1 = `FileTransferError.FILE_NOT_FOUND_ERR`\n*   2 = `FileTransferError.INVALID_URL_ERR`\n*   3 = `FileTransferError.CONNECTION_ERR`\n*   4 = `FileTransferError.ABORT_ERR`\n*   5 = `FileTransferError.NOT_MODIFIED_ERR`\n\n## Do tyłu zgodności stwierdza\n\nPoprzednie wersje tego pluginu tylko zaakceptować urządzenia bezwzględnych ścieżek jako źródło dla przekazywania, lub w celu pobrania. Te ścieżki będzie zazwyczaj formy\n\n    /var/mobile/Applications/<application UUID>/Documents/path/to/file  (iOS)\n    /storage/emulated/0/path/to/file                                    (Android)\n    \n\nDo tyłu zgodności, akceptowane są jeszcze te ścieżki, i jeśli aplikacja nagrał ścieżki, jak te w trwałej pamięci, następnie można nadal stosować.\n\nTe ścieżki były narażone wcześniej we właściwości `fullPath` `FileEntry` i `DirectoryEntry` obiektów zwróconych przez wtyczki pliku. Nowe wersje pliku plugin, jednak już wystawiać te ścieżki do JavaScript.\n\nJeśli uaktualniasz nowy (1.0.0 lub nowsza) wersja pliku i mieć wcześniej przy `entry.fullPath` jako argumenty `download()` lub `upload() służącą`, a następnie trzeba będzie zmienić kod aby używać adresów URL plików zamiast.\n\n`FileEntry.toURL()` i `DirectoryEntry.toURL()` zwraca adres URL plików formularza\n\n    cdvfile://localhost/persistent/path/to/file\n    \n\nktóre mogą być używane zamiast bezwzględna ścieżka zarówno `download()` i `metody upload()` metody.\n"
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/doc/ru/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-file-transfer\n\nЭтот плагин позволяет вам загружать и скачивать файлы.\n\n## Установка\n\n    cordova plugin add cordova-plugin-file-transfer\n    \n\n## Поддерживаемые платформы\n\n*   Amazon Fire OS\n*   Android\n*   BlackBerry 10\n*   Firefox OS **\n*   iOS\n*   Windows Phone 7 и 8 *\n*   Windows 8 ***|\n*   Windows ***|\n\n* *Не поддерживают `onprogress` , ни `abort()` *\n\n** *Не поддерживает `onprogress` *\n\nЧастичная поддержка `onprogress` для закачки метод. `onprogress` вызывается с пустой ход событий благодаря Windows limitations_\n\n# FileTransfer\n\n`FileTransfer`Объект предоставляет способ для загрузки файлов с помощью нескольких частей запроса POST HTTP и для загрузки файлов, а также.\n\n## Параметры\n\n*   **OnProgress**: называется с `ProgressEvent` всякий раз, когда новый фрагмент данных передается. *(Функция)*\n\n## Методы\n\n*   **добавлено**: отправляет файл на сервер.\n\n*   **скачать**: Скачать файл с сервера.\n\n*   **прервать**: прерывает передачу в прогресс.\n\n## загрузить\n\n**Параметры**:\n\n*   **fileURL**: файловой системы URL-адрес, представляющий файл на устройстве. Для обратной совместимости, это также может быть полный путь к файлу на устройстве. (См. [обратной совместимости отмечает] ниже)\n\n*   **сервер**: URL-адрес сервера, чтобы получить файл, как закодированные`encodeURI()`.\n\n*   **successCallback**: обратного вызова, передаваемого `Metadata` объект. *(Функция)*\n\n*   **errorCallback**: обратного вызова, который выполняется в случае получения ошибки `Metadata` . Вызываемый с `FileTransferError` объект. *(Функция)*\n\n*   **опции**: необязательные параметры *(объект)*. Допустимые ключи:\n    \n    *   **fileKey**: имя элемента form. По умолчанию `file` . (DOMString)\n    *   **имя файла**: имя файла для использования при сохранении файла на сервере. По умолчанию `image.jpg` . (DOMString)\n    *   **mimeType**: mime-тип данных для загрузки. По умолчанию `image/jpeg` . (DOMString)\n    *   **params**: набор пар дополнительный ключ/значение для передачи в HTTP-запросе. (Объект)\n    *   **chunkedMode**: следует ли загружать данные в фрагментарности потоковом режиме. По умолчанию `true` . (Логическое значение)\n    *   **заголовки**: Карта значений заголовок имя заголовка. Используйте массив для указания более одного значения. (Объект)\n\n*   **trustAllHosts**: необязательный параметр, по умолчанию `false` . Если значение `true` , она принимает все сертификаты безопасности. Это полезно, поскольку Android отвергает самозаверяющие сертификаты. Не рекомендуется для использования в производстве. Поддерживается на Android и iOS. *(логическое значение)*\n\n### Пример\n\n    // !! Assumes variable fileURL contains a valid URL to a text file on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/file.txt\n    \n    var win = function (r) {\n        console.log(\"Code = \" + r.responseCode);\n        console.log(\"Response = \" + r.response);\n        console.log(\"Sent = \" + r.bytesSent);\n    }\n    \n    var fail = function (error) {\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n    \n    var options = new FileUploadOptions();\n    options.fileKey = \"file\";\n    options.fileName = fileURL.substr(fileURL.lastIndexOf('/') + 1);\n    options.mimeType = \"text/plain\";\n    \n    var params = {};\n    params.value1 = \"test\";\n    params.value2 = \"param\";\n    \n    options.params = params;\n    \n    var ft = new FileTransfer();\n    ft.upload(fileURL, encodeURI(\"http://some.server.com/upload.php\"), win, fail, options);\n    \n\n### Пример с загружать заголовки и события Progress (Android и iOS только)\n\n    function win(r) {\n        console.log(\"Code = \" + r.responseCode);\n        console.log(\"Response = \" + r.response);\n        console.log(\"Sent = \" + r.bytesSent);\n    }\n    \n    function fail(error) {\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n    \n    var uri = encodeURI(\"http://some.server.com/upload.php\");\n    \n    var options = new FileUploadOptions();\n    options.fileKey=\"file\";\n    options.fileName=fileURL.substr(fileURL.lastIndexOf('/')+1);\n    options.mimeType=\"text/plain\";\n    \n    var headers={'headerParam':'headerValue'};\n    \n    options.headers = headers;\n    \n    var ft = new FileTransfer();\n    ft.onprogress = function(progressEvent) {\n        if (progressEvent.lengthComputable) {\n          loadingStatus.setPercentage(progressEvent.loaded / progressEvent.total);\n        } else {\n          loadingStatus.increment();\n        }\n    };\n    ft.upload(fileURL, uri, win, fail, options);\n    \n\n## FileUploadResult\n\nОбъект `FileUploadResult` передается на успех обратного вызова метода `upload()` объекта `FileTransfer`.\n\n### Параметры\n\n*   **bytesSent**: количество байт, отправленных на сервер как часть загрузки. (длинная)\n\n*   **responseCode**: код ответа HTTP, возвращаемых сервером. (длинная)\n\n*   **ответ**: ответ HTTP, возвращаемых сервером. (DOMString)\n\n*   **заголовки**: заголовки ответов HTTP-сервером. (Объект)\n    \n    *   В настоящее время поддерживается только для iOS.\n\n### Особенности iOS\n\n*   Не поддерживает `responseCode` или`bytesSent`.\n\n## Скачать\n\n**Параметры**:\n\n*   **источник**: URL-адрес сервера для загрузки файла, как закодированные`encodeURI()`.\n\n*   **Цель**: файловой системы URL-адрес, представляющий файл на устройстве. Для обратной совместимости, это также может быть полный путь к файлу на устройстве. (См. [обратной совместимости отмечает] ниже)\n\n*   **successCallback**: обратного вызова, передаваемого `FileEntry` объект. *(Функция)*\n\n*   **errorCallback**: обратного вызова, который выполняется, если возникает ошибка при получении `Metadata` . Вызываемый с `FileTransferError` объект. *(Функция)*\n\n*   **trustAllHosts**: необязательный параметр, по умолчанию `false` . Если значение `true` , она принимает все сертификаты безопасности. Это полезно, потому что Android отвергает самозаверяющие сертификаты. Не рекомендуется для использования в производстве. Поддерживается на Android и iOS. *(логическое значение)*\n\n*   **опции**: необязательные параметры, в настоящее время только поддерживает заголовки (например авторизации (базовая аутентификация) и т.д.).\n\n### Пример\n\n    // !! Assumes variable fileURL contains a valid URL to a path on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/downloads/\n    \n    var fileTransfer = new FileTransfer();\n    var uri = encodeURI(\"http://some.server.com/download.php\");\n    \n    fileTransfer.download(\n        uri,\n        fileURL,\n        function(entry) {\n            console.log(\"download complete: \" + entry.toURL());\n        },\n        function(error) {\n            console.log(\"download error source \" + error.source);\n            console.log(\"download error target \" + error.target);\n            console.log(\"upload error code\" + error.code);\n        },\n        false,\n        {\n            headers: {\n                \"Authorization\": \"Basic dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA==\"\n            }\n        }\n    );\n    \n\n## прервать\n\nПрерывает передачу в прогресс. Onerror обратного вызова передается объект FileTransferError, который имеет код ошибки FileTransferError.ABORT_ERR.\n\n### Пример\n\n    // !! Assumes variable fileURL contains a valid URL to a text file on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/file.txt\n    \n    var win = function(r) {\n        console.log(\"Should not be called.\");\n    }\n    \n    var fail = function(error) {\n        // error.code == FileTransferError.ABORT_ERR\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n    \n    var options = new FileUploadOptions();\n    options.fileKey=\"file\";\n    options.fileName=\"myphoto.jpg\";\n    options.mimeType=\"image/jpeg\";\n    \n    var ft = new FileTransfer();\n    ft.upload(fileURL, encodeURI(\"http://some.server.com/upload.php\"), win, fail, options);\n    ft.abort();\n    \n\n## FileTransferError\n\nA `FileTransferError` при ошибке обратного вызова передается объект, при возникновении ошибки.\n\n### Параметры\n\n*   **код**: один из кодов стандартных ошибок, перечисленные ниже. (Число)\n\n*   **источник**: URL-адрес источника. (Строка)\n\n*   **Цель**: URL-адрес к целевому объекту. (Строка)\n\n*   **http_status**: код состояния HTTP. Этот атрибут доступен только при код ответа от HTTP-соединения. (Число)\n\n*   **исключение**: либо e.getMessage или e.toString (строка)\n\n### Константы\n\n*   1 = `FileTransferError.FILE_NOT_FOUND_ERR`\n*   2 = `FileTransferError.INVALID_URL_ERR`\n*   3 = `FileTransferError.CONNECTION_ERR`\n*   4 = `FileTransferError.ABORT_ERR`\n*   5 = `FileTransferError.NOT_MODIFIED_ERR`\n\n## Обратной совместимости отмечает\n\nПредыдущие версии этого плагина будет принимать только устройства Абсолют файлам как источник для закачки, или как целевых для загрузок. Обычно эти пути бы формы\n\n    /var/mobile/Applications/<application UUID>/Documents/path/to/file  (iOS)\n    /storage/emulated/0/path/to/file                                    (Android)\n    \n\nДля обратной совместимости, по-прежнему принимаются эти пути, и если ваше приложение зарегистрировано пути как в постоянное хранилище, то они могут продолжать использоваться.\n\nЭти пути ранее были видны в `fullPath` свойства `FileEntry` и `DirectoryEntry` объекты, возвращаемые файл плагина. Новые версии файла плагина, однако, не подвергать эти пути в JavaScript.\n\nЕсли вы переходите на новый (1.0.0 или новее) версию файла и вы ранее использовали `entry.fullPath` в качестве аргументов `download()` или `upload()` , то вам необходимо будет изменить код для использования файловой системы URL вместо.\n\n`FileEntry.toURL()`и `DirectoryEntry.toURL()` возвращает URL-адрес формы файловой системы\n\n    cdvfile://localhost/persistent/path/to/file\n    \n\nкоторые могут быть использованы вместо абсолютного пути в обоих `download()` и `upload()` методы.\n"
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/doc/zh/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-file-transfer\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-file-transfer.svg)](https://travis-ci.org/apache/cordova-plugin-file-transfer)\n\n外掛程式檔: <doc/index.md>\n\n這個外掛程式允許你上傳和下載檔案。\n\n這個外掛程式定義全域 `FileTransfer`，`FileUploadOptions` 的建構函式。\n\n雖然在全球範圍內，他們不可用直到 `deviceready` 事件之後。\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(FileTransfer);\n    }\n    \n\n## 安裝\n\n    cordova plugin add cordova-plugin-file-transfer\n    \n\n## 支援的平臺\n\n  * 亞馬遜火 OS\n  * Android 系統\n  * 黑莓 10\n  * 瀏覽器\n  * 火狐瀏覽器的作業系統 * *\n  * iOS\n  * Windows Phone 7 和 8 *\n  * Windows 8\n  * Windows\n\n\\ **不支援`onprogress`也`abort()` *\n\n\\ * **不支援`onprogress` *\n\n# 檔案傳輸\n\n`FileTransfer`物件提供上傳檔使用 HTTP 多部分職位或付諸表決的請求，並將檔以及下載的方式。\n\n## 屬性\n\n  * **onprogress**： 使用調用 `ProgressEvent` 每當一塊新的資料傳輸。*（函數）*\n\n## 方法\n\n  * **upload**： 將檔發送到伺服器。\n\n  * **download**： 從伺服器上下載檔案。\n\n  * **abort**: 中止正在進行轉讓。\n\n## upload\n\n**參數**：\n\n  * **fileURL**： 表示檔在設備上的檔案系統 URL。 為向後相容性，這也可以將設備上的檔的完整路徑。 （請參見 [向後相容性注意到] 下面)\n\n  * **server**： 伺服器以接收該檔，由編碼的 URL`encodeURI()`.\n\n  * **successCallback**： 一個通過一個 `FileUploadResult` 物件的回檔。*（函數）*\n\n  * **errorCallback**： 如果發生錯誤，檢索 `FileUploadResult` 執行一個回檔。使用 `FileTransferError` 物件調用。*（函數）*\n\n  * **options**： 可選參數*（物件）*。有效的金鑰：\n    \n      * **fileKey**： 表單元素的名稱。預設值為 `file` 。() DOMString\n      * **fileName**： 要保存在伺服器上的檔時使用的檔案名稱。預設值為 `image.jpg` 。() DOMString\n      * **httpMethod**： HTTP 方法使用-`PUT` 或 `POST`。預設值為 `POST`。() DOMString\n      * **mimeType**： 要上載的資料的 mime 類型。預設設置為 `image/jpeg`。() DOMString\n      * **params**： 一組要在 HTTP 要求中傳遞的可選的鍵值對。（物件）\n      * **chunkedMode**： 是否要分塊的流式處理模式中的資料上載。預設值為 `true`。(布林值)\n      * **headers**: 地圖的標頭名稱/標頭值。 使用陣列來指定多個值。 IOS、 FireOS，和安卓系統，如果已命名的內容類型標頭存在，多部分表單資料不被使用。 (Object)\n      * **httpMethod**: HTTP 方法，例如使用張貼或放。 預設為`開機自檢`。() DOMString\n\n  * **trustAllHosts**: 可選參數，預設值為 `false` 。 如果設置為 `true` ，它可以接受的所有安全證書。 這是有用的因為 android 系統拒絕自簽名的安全證書。 不建議供生產使用。 在 Android 和 iOS 上受支援。 *(布林值)*\n\n### 示例\n\n    // !! Assumes variable fileURL contains a valid URL to a text file on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/file.txt\n    \n    var win = function (r) {\n        console.log(\"Code = \" + r.responseCode);\n        console.log(\"Response = \" + r.response);\n        console.log(\"Sent = \" + r.bytesSent);\n    }\n    \n    var fail = function (error) {\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n    \n    var options = new FileUploadOptions();\n    options.fileKey = \"file\";\n    options.fileName = fileURL.substr(fileURL.lastIndexOf('/') + 1);\n    options.mimeType = \"text/plain\";\n    \n    var params = {};\n    params.value1 = \"test\";\n    params.value2 = \"param\";\n    \n    options.params = params;\n    \n    var ft = new FileTransfer();\n    ft.upload(fileURL, encodeURI(\"http://some.server.com/upload.php\"), win, fail, options);\n    \n\n### 與上傳的標頭和進度事件 （Android 和 iOS 只） 的示例\n\n    function win(r) {\n        console.log(\"Code = \" + r.responseCode);\n        console.log(\"Response = \" + r.response);\n        console.log(\"Sent = \" + r.bytesSent);\n    }\n    \n    function fail(error) {\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n    \n    var uri = encodeURI(\"http://some.server.com/upload.php\");\n    \n    var options = new FileUploadOptions();\n    options.fileKey=\"file\";\n    options.fileName=fileURL.substr(fileURL.lastIndexOf('/')+1);\n    options.mimeType=\"text/plain\";\n    \n    var headers={'headerParam':'headerValue'};\n    \n    options.headers = headers;\n    \n    var ft = new FileTransfer();\n    ft.onprogress = function(progressEvent) {\n        if (progressEvent.lengthComputable) {\n          loadingStatus.setPercentage(progressEvent.loaded / progressEvent.total);\n        } else {\n          loadingStatus.increment();\n        }\n    };\n    ft.upload(fileURL, uri, win, fail, options);\n    \n\n## FileUploadResult\n\n`FileUploadResult` 物件將傳遞給該 `檔案傳輸` 物件的 `upload()` 方法的成功回檔。\n\n### 屬性\n\n  * **bytesSent**： 作為上載的一部分發送到伺服器的位元組數。(長)\n\n  * **responseCode**： 由伺服器返回的 HTTP 回應代碼。(長)\n\n  * **response**： 由伺服器返回的 HTTP 回應。() DOMString\n\n  * **headers**： 由伺服器的 HTTP 回應標頭。（物件）\n    \n      * 目前支援的 iOS 只。\n\n### iOS 的怪癖\n\n  * 不支援 `responseCode` 或`bytesSent`.\n\n## download\n\n**參數**：\n\n  * **source**： 要下載的檔，如由編碼的伺服器的 URL`encodeURI()`.\n\n  * **target**： 表示檔在設備上的檔案系統 url。 為向後相容性，這也可以將設備上的檔的完整路徑。 （請參見 [向後相容性注意到] 下面)\n\n  * **successCallback**： 傳遞一個回檔 `FileEntry` 物件。*（函數）*\n\n  * **errorCallback**： 如果檢索 `FileEntry` 時發生錯誤，則執行一個回檔。使用 `FileTransferError` 物件調用。*（函數）*\n\n  * **trustAllHosts**: 可選參數，預設值為 `false` 。 如果設置為 `true` ，它可以接受的所有安全證書。 這是有用的因為 Android 拒絕自行簽署式安全證書。 不建議供生產使用。 在 Android 和 iOS 上受支援。 *(布林值)*\n\n  * **options**： 可選參數，目前只支援標題 （如授權 （基本驗證） 等）。\n\n### 示例\n\n    // !! Assumes variable fileURL contains a valid URL to a path on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/downloads/\n    \n    var fileTransfer = new FileTransfer();\n    var uri = encodeURI(\"http://some.server.com/download.php\");\n    \n    fileTransfer.download(\n        uri,\n        fileURL,\n        function(entry) {\n            console.log(\"download complete: \" + entry.toURL());\n        },\n        function(error) {\n            console.log(\"download error source \" + error.source);\n            console.log(\"download error target \" + error.target);\n            console.log(\"upload error code\" + error.code);\n        },\n        false,\n        {\n            headers: {\n                \"Authorization\": \"Basic dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA==\"\n            }\n        }\n    );\n    \n\n### WP8 的怪癖\n\n  * 下載請求由本機實現被緩存。若要避免緩存，傳遞`如果修改自`郵件頭以下載方法。\n\n## abort\n\n中止正在進行轉讓。Onerror 回檔傳遞一個 FileTransferError 物件具有 FileTransferError.ABORT_ERR 錯誤代碼。\n\n### 示例\n\n    // !! Assumes variable fileURL contains a valid URL to a text file on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/file.txt\n    \n    var win = function(r) {\n        console.log(\"Should not be called.\");\n    }\n    \n    var fail = function(error) {\n        // error.code == FileTransferError.ABORT_ERR\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n    \n    var options = new FileUploadOptions();\n    options.fileKey=\"file\";\n    options.fileName=\"myphoto.jpg\";\n    options.mimeType=\"image/jpeg\";\n    \n    var ft = new FileTransfer();\n    ft.upload(fileURL, encodeURI(\"http://some.server.com/upload.php\"), win, fail, options);\n    ft.abort();\n    \n\n## FileTransferError\n\n當發生錯誤時，`FileTransferError` 物件將傳遞給錯誤回檔。\n\n### 屬性\n\n  * **code**： 下面列出的預定義的錯誤代碼之一。（人數）\n\n  * **source**： 源的 URL。（字串）\n\n  * **target**： 到目標 URL。（字串）\n\n  * **HTTP_status**： HTTP 狀態碼。從 HTTP 連接收到一個回應代碼時，此屬性才可用。（人數）\n\n  * **body**回應正文。此屬性只能是可用的當該 HTTP 連接收到答覆。（字串）\n\n  * **exception**： 要麼 e.getMessage 或 e.toString （字串）\n\n### 常量\n\n  * 1 = `FileTransferError.FILE_NOT_FOUND_ERR`\n  * 2 = `FileTransferError.INVALID_URL_ERR`\n  * 3 = `FileTransferError.CONNECTION_ERR`\n  * 4 = `FileTransferError.ABORT_ERR`\n  * 5 = `FileTransferError.NOT_MODIFIED_ERR`\n\n## 向後相容性注意到\n\n以前版本的這個外掛程式才會接受設備-絕對檔路徑作為源對於上載，或用於下載的目標。這些路徑通常會在表單\n\n    /var/mobile/Applications/<application UUID>/Documents/path/to/file  (iOS)\n    /storage/emulated/0/path/to/file                                    (Android)\n    \n\n為向後相容性，這些路徑仍會被接受，和如果您的應用程式已錄得像這些在持久性存儲的路徑，然後他們可以繼續使用。\n\n這些路徑被以前暴露在 `FileEntry` 和由檔外掛程式返回的 `DirectoryEntry` 物件的 `fullPath` 屬性中。 新版本的檔的外掛程式，但是，不再公開這些 JavaScript 的路徑。\n\n如果您要升級到新 (1.0.0 或更高版本） 版本的檔，和你以前一直在使用 `entry.fullPath` 作為參數到 `download()` 或 `upload()`，那麼你將需要更改代碼以使用檔案系統的 Url 來代替。\n\n`FileEntry.toURL()` 和 `DirectoryEntry.toURL()` 返回的表單檔案 URL\n\n    cdvfile://localhost/persistent/path/to/file\n    \n\n它可以用在 `download()` 和 `upload()` 兩種方法中的絕對檔路徑位置。"
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/doc/zh/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-file-transfer\n\n這個外掛程式允許你上傳和下載檔案。\n\n這個外掛程式定義全域 `FileTransfer`，`FileUploadOptions` 的建構函式。\n\n雖然在全球範圍內，他們不可用直到 `deviceready` 事件之後。\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(FileTransfer);\n    }\n    \n\n## 安裝\n\n    cordova plugin add cordova-plugin-file-transfer\n    \n\n## 支援的平臺\n\n*   亞馬遜火 OS\n*   Android 系統\n*   黑莓 10\n*   瀏覽器\n*   火狐瀏覽器的作業系統 * *\n*   iOS\n*   Windows Phone 7 和 8 *\n*   Windows 8\n*   Windows\n\n* *不支援 `onprogress` 也 `abort()`*\n\n* * *不支援 `onprogress`*\n\n# FileTransfer\n\n`FileTransfer` 物件提供一種使用 HTTP 多部分 POST 請求的檔上傳，下載檔案以及方式。\n\n## 屬性\n\n*   **onprogress**： 使用調用 `ProgressEvent` 每當一塊新的資料傳輸。*（函數）*\n\n## 方法\n\n*   **upload**： 將檔發送到伺服器。\n\n*   **download**： 從伺服器上下載檔案。\n\n*   **abort**: 中止正在進行轉讓。\n\n## upload\n\n**參數**：\n\n*   **fileURL**： 表示檔在設備上的檔案系統 URL。 為向後相容性，這也可以將設備上的檔的完整路徑。 （請參見 [向後相容性注意到] 下面)\n\n*   **server**： 伺服器以接收該檔，由編碼的 URL`encodeURI()`.\n\n*   **successCallback**： 一個通過一個 `FileUploadResult` 物件的回檔。*（函數）*\n\n*   **errorCallback**： 如果發生錯誤，檢索 `FileUploadResult` 執行一個回檔。使用 `FileTransferError` 物件調用。*（函數）*\n\n*   **options**： 可選參數*（物件）*。有效的金鑰：\n    \n    *   **fileKey**： 表單元素的名稱。預設值為 `file` 。() DOMString\n    *   **fileName**： 要保存在伺服器上的檔時使用的檔案名稱。預設值為 `image.jpg` 。() DOMString\n    *   **httpMethod**： HTTP 方法使用-`PUT` 或 `POST`。預設值為 `POST`。() DOMString\n    *   **mimeType**： 要上載的資料的 mime 類型。預設設置為 `image/jpeg`。() DOMString\n    *   **params**： 一組要在 HTTP 要求中傳遞的可選的鍵值對。（物件）\n    *   **chunkedMode**： 是否要分塊的流式處理模式中的資料上載。預設值為 `true`。(布林值)\n    *   **headers**： 地圖的標頭名稱/標頭值。使用陣列來指定多個值。（物件）\n\n*   **trustAllHosts**: 可選參數，預設值為 `false` 。 如果設置為 `true` ，它接受的所有安全證書。 這是有用的因為 android 系統拒絕自簽名的安全證書。 不建議供生產使用。 支援 Android 和 iOS。 *(布林值)*\n\n### 示例\n\n    // !! Assumes variable fileURL contains a valid URL to a text file on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/file.txt\n    \n    var win = function (r) {\n        console.log(\"Code = \" + r.responseCode);\n        console.log(\"Response = \" + r.response);\n        console.log(\"Sent = \" + r.bytesSent);\n    }\n    \n    var fail = function (error) {\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n    \n    var options = new FileUploadOptions();\n    options.fileKey = \"file\";\n    options.fileName = fileURL.substr(fileURL.lastIndexOf('/') + 1);\n    options.mimeType = \"text/plain\";\n    \n    var params = {};\n    params.value1 = \"test\";\n    params.value2 = \"param\";\n    \n    options.params = params;\n    \n    var ft = new FileTransfer();\n    ft.upload(fileURL, encodeURI(\"http://some.server.com/upload.php\"), win, fail, options);\n    \n\n### 與上傳的標頭和進度事件 （Android 和 iOS 只） 的示例\n\n    function win(r) {\n        console.log(\"Code = \" + r.responseCode);\n        console.log(\"Response = \" + r.response);\n        console.log(\"Sent = \" + r.bytesSent);\n    }\n    \n    function fail(error) {\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n    \n    var uri = encodeURI(\"http://some.server.com/upload.php\");\n    \n    var options = new FileUploadOptions();\n    options.fileKey=\"file\";\n    options.fileName=fileURL.substr(fileURL.lastIndexOf('/')+1);\n    options.mimeType=\"text/plain\";\n    \n    var headers={'headerParam':'headerValue'};\n    \n    options.headers = headers;\n    \n    var ft = new FileTransfer();\n    ft.onprogress = function(progressEvent) {\n        if (progressEvent.lengthComputable) {\n          loadingStatus.setPercentage(progressEvent.loaded / progressEvent.total);\n        } else {\n          loadingStatus.increment();\n        }\n    };\n    ft.upload(fileURL, uri, win, fail, options);\n    \n\n## FileUploadResult\n\n`FileUploadResult` 物件將傳遞給該 `檔案傳輸` 物件的 `upload()` 方法的成功回檔。\n\n### 屬性\n\n*   **bytesSent**： 作為上載的一部分發送到伺服器的位元組數。(長)\n\n*   **responseCode**： 由伺服器返回的 HTTP 回應代碼。(長)\n\n*   **response**： 由伺服器返回的 HTTP 回應。() DOMString\n\n*   **headers**： 由伺服器的 HTTP 回應標頭。（物件）\n    \n    *   目前支援的 iOS 只。\n\n### iOS 的怪癖\n\n*   不支援 `responseCode` 或`bytesSent`.\n\n## download\n\n**參數**：\n\n*   **source**： 要下載的檔，如由編碼的伺服器的 URL`encodeURI()`.\n\n*   **target**： 表示檔在設備上的檔案系統 url。 為向後相容性，這也可以將設備上的檔的完整路徑。 （請參見 [向後相容性注意到] 下面)\n\n*   **successCallback**： 傳遞一個回檔 `FileEntry` 物件。*（函數）*\n\n*   **errorCallback**： 如果檢索 `FileEntry` 時發生錯誤，則執行一個回檔。使用 `FileTransferError` 物件調用。*（函數）*\n\n*   **trustAllHosts**: 可選參數，預設值為 `false` 。 如果設置為 `true` ，它可以接受的所有安全證書。 這是有用的因為 Android 拒絕自行簽署式安全證書。 不建議供生產使用。 在 Android 和 iOS 上受支援。 *(布林值)*\n\n*   **options**： 可選參數，目前只支援標題 （如授權 （基本驗證） 等）。\n\n### 示例\n\n    // !! Assumes variable fileURL contains a valid URL to a path on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/downloads/\n    \n    var fileTransfer = new FileTransfer();\n    var uri = encodeURI(\"http://some.server.com/download.php\");\n    \n    fileTransfer.download(\n        uri,\n        fileURL,\n        function(entry) {\n            console.log(\"download complete: \" + entry.toURL());\n        },\n        function(error) {\n            console.log(\"download error source \" + error.source);\n            console.log(\"download error target \" + error.target);\n            console.log(\"upload error code\" + error.code);\n        },\n        false,\n        {\n            headers: {\n                \"Authorization\": \"Basic dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA==\"\n            }\n        }\n    );\n    \n\n## abort\n\n中止正在進行轉讓。Onerror 回檔傳遞一個 FileTransferError 物件具有 FileTransferError.ABORT_ERR 錯誤代碼。\n\n### 示例\n\n    // !! Assumes variable fileURL contains a valid URL to a text file on the device,\n    //    for example, cdvfile://localhost/persistent/path/to/file.txt\n    \n    var win = function(r) {\n        console.log(\"Should not be called.\");\n    }\n    \n    var fail = function(error) {\n        // error.code == FileTransferError.ABORT_ERR\n        alert(\"An error has occurred: Code = \" + error.code);\n        console.log(\"upload error source \" + error.source);\n        console.log(\"upload error target \" + error.target);\n    }\n    \n    var options = new FileUploadOptions();\n    options.fileKey=\"file\";\n    options.fileName=\"myphoto.jpg\";\n    options.mimeType=\"image/jpeg\";\n    \n    var ft = new FileTransfer();\n    ft.upload(fileURL, encodeURI(\"http://some.server.com/upload.php\"), win, fail, options);\n    ft.abort();\n    \n\n## FileTransferError\n\n當發生錯誤時，`FileTransferError` 物件將傳遞給錯誤回檔。\n\n### 屬性\n\n*   **code**： 下面列出的預定義的錯誤代碼之一。（人數）\n\n*   **source**： 源的 URL。（字串）\n\n*   **target**： 到目標 URL。（字串）\n\n*   **HTTP_status**： HTTP 狀態碼。從 HTTP 連接收到一個回應代碼時，此屬性才可用。（人數）\n\n*   **body**回應正文。此屬性只能是可用的當該 HTTP 連接收到答覆。（字串）\n\n*   **exception**： 要麼 e.getMessage 或 e.toString （字串）\n\n### 常量\n\n*   1 = `FileTransferError.FILE_NOT_FOUND_ERR`\n*   2 = `FileTransferError.INVALID_URL_ERR`\n*   3 = `FileTransferError.CONNECTION_ERR`\n*   4 = `FileTransferError.ABORT_ERR`\n*   5 = `FileTransferError.NOT_MODIFIED_ERR`\n\n## 向後相容性注意到\n\n以前版本的這個外掛程式才會接受設備-絕對檔路徑作為源對於上載，或用於下載的目標。這些路徑通常會在表單\n\n    /var/mobile/Applications/<application UUID>/Documents/path/to/file  (iOS)\n    /storage/emulated/0/path/to/file                                    (Android)\n    \n\n為向後相容性，這些路徑仍會被接受，和如果您的應用程式已錄得像這些在持久性存儲的路徑，然後他們可以繼續使用。\n\n這些路徑被以前暴露在 `FileEntry` 和由檔外掛程式返回的 `DirectoryEntry` 物件的 `fullPath` 屬性中。 新版本的檔的外掛程式，但是，不再公開這些 JavaScript 的路徑。\n\n如果您要升級到新 (1.0.0 或更高版本） 版本的檔，和你以前一直在使用 `entry.fullPath` 作為參數到 `download()` 或 `upload()`，那麼你將需要更改代碼以使用檔案系統的 Url 來代替。\n\n`FileEntry.toURL()` 和 `DirectoryEntry.toURL()` 返回的表單檔案 URL\n\n    cdvfile://localhost/persistent/path/to/file\n    \n\n它可以用在 `download()` 和 `upload()` 兩種方法中的絕對檔路徑位置。\n"
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/package.json",
    "content": "{\n  \"name\": \"cordova-plugin-file-transfer\",\n  \"version\": \"1.5.1\",\n  \"description\": \"Cordova File Transfer Plugin\",\n  \"cordova\": {\n    \"id\": \"cordova-plugin-file-transfer\",\n    \"platforms\": [\n      \"android\",\n      \"amazon-fireos\",\n      \"ubuntu\",\n      \"blackberry10\",\n      \"ios\",\n      \"wp7\",\n      \"wp8\",\n      \"windows8\",\n      \"windows\",\n      \"firefoxos\",\n      \"browser\"\n    ]\n  },\n  \"scripts\": {\n    \"test\": \"npm run lint && npm run style\",\n    \"lint\": \"jshint www && jshint src && jshint tests\",\n    \"style\": \"jscs tests/tests.js\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/apache/cordova-plugin-file-transfer\"\n  },\n  \"keywords\": [\n    \"cordova\",\n    \"file\",\n    \"transfer\",\n    \"ecosystem:cordova\",\n    \"cordova-android\",\n    \"cordova-amazon-fireos\",\n    \"cordova-ubuntu\",\n    \"cordova-blackberry10\",\n    \"cordova-ios\",\n    \"cordova-wp7\",\n    \"cordova-wp8\",\n    \"cordova-windows8\",\n    \"cordova-windows\",\n    \"cordova-firefoxos\",\n    \"cordova-browser\"\n  ],\n  \"peerDependencies\": {\n    \"cordova-plugin-file\": \"^3.0.0\"\n  },\n  \"author\": \"Apache Software Foundation\",\n  \"license\": \"Apache-2.0\",\n  \"devDependencies\": {\n    \"jscs\": \"^2.6.0\",\n    \"jshint\": \"^2.8.0\"\n  }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/plugin.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  Licensed to the Apache Software Foundation (ASF) under one\n  or more contributor license agreements.  See the NOTICE file\n  distributed with this work for additional information\n  regarding copyright ownership.  The ASF licenses this file\n  to you under the Apache License, Version 2.0 (the\n  \"License\"); you may not use this file except in compliance\n  with the License.  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing,\n  software distributed under the License is distributed on an\n  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n  KIND, either express or implied.  See the License for the\n  specific language governing permissions and limitations\n  under the License.\n-->\n\n<plugin xmlns=\"http://apache.org/cordova/ns/plugins/1.0\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    id=\"cordova-plugin-file-transfer\"\n    version=\"1.5.1\">\n    <name>File Transfer</name>\n    <description>Cordova File Transfer Plugin</description>\n    <license>Apache 2.0</license>\n    <keywords>cordova,file,transfer</keywords>\n    <repo>https://git-wip-us.apache.org/repos/asf/cordova-plugin-file-transfer.git</repo>\n    <issue>https://issues.apache.org/jira/browse/CB/component/12320650</issue>\n\n    <dependency id=\"cordova-plugin-file\" version=\"^4.0.0\" />\n\n    <js-module src=\"www/FileTransferError.js\" name=\"FileTransferError\">\n        <clobbers target=\"window.FileTransferError\" />\n    </js-module>\n\n    <js-module src=\"www/FileTransfer.js\" name=\"FileTransfer\">\n        <clobbers target=\"window.FileTransfer\" />\n    </js-module>\n\n    <!-- android -->\n    <platform name=\"android\">\n        <config-file target=\"res/xml/config.xml\" parent=\"/*\">\n            <feature name=\"FileTransfer\" >\n                <param name=\"android-package\" value=\"org.apache.cordova.filetransfer.FileTransfer\"/>\n            </feature>\n        </config-file>\n\n        <config-file target=\"AndroidManifest.xml\" parent=\"/*\">\n            <uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" />\n        </config-file>\n\n        <source-file src=\"src/android/FileTransfer.java\" target-dir=\"src/org/apache/cordova/filetransfer\" />\n        <source-file src=\"src/android/FileProgressResult.java\" target-dir=\"src/org/apache/cordova/filetransfer\" />\n        <source-file src=\"src/android/FileUploadResult.java\" target-dir=\"src/org/apache/cordova/filetransfer\" />\n    </platform>\n\n    <!-- amamzon-fireos -->\n    <platform name=\"amazon-fireos\">\n        <config-file target=\"res/xml/config.xml\" parent=\"/*\">\n            <feature name=\"FileTransfer\" >\n                <param name=\"android-package\" value=\"org.apache.cordova.filetransfer.FileTransfer\"/>\n            </feature>\n        </config-file>\n\n        <config-file target=\"AndroidManifest.xml\" parent=\"/*\">\n            <uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" />\n        </config-file>\n\n        <source-file src=\"src/amazon/FileTransfer.java\" target-dir=\"src/org/apache/cordova/filetransfer\" />\n        <source-file src=\"src/android/FileProgressResult.java\" target-dir=\"src/org/apache/cordova/filetransfer\" />\n        <source-file src=\"src/android/FileUploadResult.java\" target-dir=\"src/org/apache/cordova/filetransfer\" />\n    </platform>\n    \n    <!-- ubuntu -->\n    <platform name=\"ubuntu\">\n        <header-file src=\"src/ubuntu/file-transfer.h\" />\n        <source-file src=\"src/ubuntu/file-transfer.cpp\" />\n    </platform>\n\n    <!-- blackberry10 -->\n    <platform name=\"blackberry10\">\n        <config-file target=\"www/config.xml\" parent=\"/widget\">\n            <feature name=\"FileTransfer\" value=\"FileTransfer\"></feature>\n        </config-file>\n        <js-module src=\"www/blackberry10/FileTransferProxy.js\" name=\"FileTransferProxy\" >\n            <runs />\n        </js-module>\n        <js-module src=\"www/blackberry10/xhrFileTransfer.js\" name=\"xhrFileTransfer\" />\n        <!--\n        <js-module src=\"www/blackberry10/abort.js\" name=\"abortProxy\" />\n        <js-module src=\"www/blackberry10/download.js\" name=\"downloadProxy\" />\n        <js-module src=\"www/blackberry10/upload.js\" name=\"uploadProxy\" />\n        -->\n    </platform>\n\n    <!-- ios -->\n    <platform name=\"ios\">\n        <config-file target=\"config.xml\" parent=\"/*\">\n            <feature name=\"FileTransfer\">\n                <param name=\"ios-package\" value=\"CDVFileTransfer\" />\n            </feature>\n        </config-file>\n        <header-file src=\"src/ios/CDVFileTransfer.h\" />\n        <source-file src=\"src/ios/CDVFileTransfer.m\" />\n\n        <framework src=\"AssetsLibrary.framework\" />\n    </platform>\n\n    <!-- wp7 -->\n    <platform name=\"wp7\">\n        <config-file target=\"config.xml\" parent=\"/*\">\n            <feature name=\"FileTransfer\">\n                <param name=\"wp-package\" value=\"FileTransfer\"/>\n            </feature>\n        </config-file>\n\n        <source-file src=\"src/wp/FileTransfer.cs\" />\n\n        <js-module src=\"www/wp7/base64.js\" name=\"base64\">\n            <clobbers target=\"window.FileTransferBase64\" />\n        </js-module>\n\n    </platform>\n\n    <!-- wp8 -->\n    <platform name=\"wp8\">\n        <config-file target=\"config.xml\" parent=\"/*\">\n            <feature name=\"FileTransfer\">\n                <param name=\"wp-package\" value=\"FileTransfer\"/>\n            </feature>\n        </config-file>\n\n        <source-file src=\"src/wp/FileTransfer.cs\" />\n\n    </platform>\n\n    <!-- windows8 -->\n    <platform name=\"windows8\">\n        <js-module src=\"src/windows/FileTransferProxy.js\" name=\"FileTransferProxy\">\n            <clobbers target=\"\" />\n        </js-module>\n    </platform>\n\n    <!-- windows -->\n    <platform name=\"windows\">\n        <js-module src=\"src/windows/FileTransferProxy.js\" name=\"FileTransferProxy\">\n            <clobbers target=\"\" />\n        </js-module>\n    </platform>\n\n    <!-- firefoxOS -->\n    <platform name=\"firefoxos\">\n        <config-file target=\"config.xml\" parent=\"/*\">\n            <permission name=\"systemXHR\" privileged=\"true\"/>\n        </config-file>\n\n        <js-module src=\"www/firefoxos/FileTransferProxy.js\" name=\"FileTransferProxy\">\n            <runs/>\n        </js-module>\n    </platform>\n\n    <!-- browser -->\n    <platform name=\"browser\">\n        <js-module src=\"www/browser/FileTransfer.js\" name=\"BrowserFileTransfer\">\n            <clobbers target=\"window.FileTransfer\" />\n        </js-module>\n    </platform>\n</plugin>\n"
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/src/amazon/FileTransfer.java",
    "content": "/*\n       Licensed to the Apache Software Foundation (ASF) under one\n       or more contributor license agreements.  See the NOTICE file\n       distributed with this work for additional information\n       regarding copyright ownership.  The ASF licenses this file\n       to you under the Apache License, Version 2.0 (the\n       \"License\"); you may not use this file except in compliance\n       with the License.  You may obtain a copy of the License at\n\n         http://www.apache.org/licenses/LICENSE-2.0\n\n       Unless required by applicable law or agreed to in writing,\n       software distributed under the License is distributed on an\n       \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n       KIND, either express or implied.  See the License for the\n       specific language governing permissions and limitations\n       under the License.\n*/\npackage org.apache.cordova.filetransfer;\n\nimport java.io.BufferedReader;\nimport java.io.ByteArrayOutputStream;\nimport java.io.Closeable;\nimport java.io.File;\nimport java.io.FileNotFoundException;\nimport java.io.FilterInputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.InputStreamReader;\nimport java.io.OutputStream;\nimport java.io.UnsupportedEncodingException;\nimport java.net.HttpURLConnection;\nimport java.net.URLConnection;\nimport java.net.URLDecoder;\nimport java.security.cert.CertificateException;\nimport java.security.cert.X509Certificate;\nimport java.util.HashMap;\nimport java.util.Iterator;\nimport java.util.zip.GZIPInputStream;\nimport java.util.zip.Inflater;\n\nimport javax.net.ssl.HostnameVerifier;\nimport javax.net.ssl.HttpsURLConnection;\nimport javax.net.ssl.SSLContext;\nimport javax.net.ssl.SSLSession;\nimport javax.net.ssl.SSLSocketFactory;\nimport javax.net.ssl.TrustManager;\nimport javax.net.ssl.X509TrustManager;\n\nimport org.apache.cordova.Config;\nimport org.apache.cordova.CallbackContext;\nimport org.apache.cordova.CordovaPlugin;\nimport org.apache.cordova.CordovaResourceApi;\nimport org.apache.cordova.CordovaResourceApi.OpenForReadResult;\nimport org.apache.cordova.PluginResult;\nimport org.apache.cordova.file.FileUtils;\nimport org.json.JSONArray;\nimport org.json.JSONException;\nimport org.json.JSONObject;\n\nimport android.net.Uri;\nimport android.os.Build;\nimport android.util.Log;\nimport com.amazon.android.webkit.AmazonCookieManager;\n\npublic class FileTransfer extends CordovaPlugin {\n\n    private static final String LOG_TAG = \"FileTransfer\";\n    private static final String LINE_START = \"--\";\n    private static final String LINE_END = \"\\r\\n\";\n    private static final String BOUNDARY =  \"+++++\";\n\n    public static int FILE_NOT_FOUND_ERR = 1;\n    public static int INVALID_URL_ERR = 2;\n    public static int CONNECTION_ERR = 3;\n    public static int ABORTED_ERR = 4;\n\n    private static HashMap<String, RequestContext> activeRequests = new HashMap<String, RequestContext>();\n    private static final int MAX_BUFFER_SIZE = 16 * 1024;\n\n    private static final class RequestContext {\n        String source;\n        String target;\n        File targetFile;\n        CallbackContext callbackContext;\n        InputStream currentInputStream;\n        OutputStream currentOutputStream;\n        boolean aborted;\n        RequestContext(String source, String target, CallbackContext callbackContext) {\n            this.source = source;\n            this.target = target;\n            this.callbackContext = callbackContext;\n        }\n        void sendPluginResult(PluginResult pluginResult) {\n            synchronized (this) {\n                if (!aborted) {\n                    callbackContext.sendPluginResult(pluginResult);\n                }\n            }\n        }\n    }\n\n    /**\n     * Adds an interface method to an InputStream to return the number of bytes\n     * read from the raw stream. This is used to track total progress against\n     * the HTTP Content-Length header value from the server.\n     */\n    private static abstract class TrackingInputStream extends FilterInputStream {\n      public TrackingInputStream(final InputStream in) {\n        super(in);\n      }\n        public abstract long getTotalRawBytesRead();\n  }\n\n    private static class ExposedGZIPInputStream extends GZIPInputStream {\n      public ExposedGZIPInputStream(final InputStream in) throws IOException {\n        super(in);\n      }\n      public Inflater getInflater() {\n        return inf;\n      }\n  }\n\n    /**\n     * Provides raw bytes-read tracking for a GZIP input stream. Reports the\n     * total number of compressed bytes read from the input, rather than the\n     * number of uncompressed bytes.\n     */\n    private static class TrackingGZIPInputStream extends TrackingInputStream {\n      private ExposedGZIPInputStream gzin;\n      public TrackingGZIPInputStream(final ExposedGZIPInputStream gzin) throws IOException {\n        super(gzin);\n        this.gzin = gzin;\n      }\n      public long getTotalRawBytesRead() {\n        return gzin.getInflater().getBytesRead();\n      }\n  }\n\n    /**\n     * Provides simple total-bytes-read tracking for an existing InputStream\n     */\n    private static class SimpleTrackingInputStream extends TrackingInputStream {\n        private long bytesRead = 0;\n        public SimpleTrackingInputStream(InputStream stream) {\n            super(stream);\n        }\n\n        private int updateBytesRead(int newBytesRead) {\n          if (newBytesRead != -1) {\n            bytesRead += newBytesRead;\n          }\n          return newBytesRead;\n        }\n\n        @Override\n        public int read() throws IOException {\n            return updateBytesRead(super.read());\n        }\n\n        // Note: FilterInputStream delegates read(byte[] bytes) to the below method,\n        // so we don't override it or else double count (CB-5631).\n        @Override\n        public int read(byte[] bytes, int offset, int count) throws IOException {\n            return updateBytesRead(super.read(bytes, offset, count));\n        }\n\n        public long getTotalRawBytesRead() {\n          return bytesRead;\n        }\n    }\n\n    @Override\n    public boolean execute(String action, JSONArray args, final CallbackContext callbackContext) throws JSONException {\n        if (action.equals(\"upload\") || action.equals(\"download\")) {\n            String source = args.getString(0);\n            String target = args.getString(1);\n\n            if (action.equals(\"upload\")) {\n                try {\n                    source = URLDecoder.decode(source, \"UTF-8\");\n                    upload(source, target, args, callbackContext);\n                } catch (UnsupportedEncodingException e) {\n                    callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.MALFORMED_URL_EXCEPTION, \"UTF-8 error.\"));\n                }\n            } else {\n                download(source, target, args, callbackContext);\n            }\n            return true;\n        } else if (action.equals(\"abort\")) {\n            String objectId = args.getString(0);\n            abort(objectId);\n            callbackContext.success();\n            return true;\n        }\n        return false;\n    }\n\n    private static void addHeadersToRequest(URLConnection connection, JSONObject headers) {\n        try {\n            for (Iterator<?> iter = headers.keys(); iter.hasNext(); ) {\n                String headerKey = iter.next().toString();\n                JSONArray headerValues = headers.optJSONArray(headerKey);\n                if (headerValues == null) {\n                    headerValues = new JSONArray();\n                    headerValues.put(headers.getString(headerKey));\n                }\n                connection.setRequestProperty(headerKey, headerValues.getString(0));\n                for (int i = 1; i < headerValues.length(); ++i) {\n                    connection.addRequestProperty(headerKey, headerValues.getString(i));\n                }\n            }\n        } catch (JSONException e1) {\n          // No headers to be manipulated!\n        }\n    }\n\n    /**\n     * Uploads the specified file to the server URL provided using an HTTP multipart request.\n     * @param source        Full path of the file on the file system\n     * @param target        URL of the server to receive the file\n     * @param args          JSON Array of args\n     * @param callbackContext    callback id for optional progress reports\n     *\n     * args[2] fileKey       Name of file request parameter\n     * args[3] fileName      File name to be used on server\n     * args[4] mimeType      Describes file content type\n     * args[5] params        key:value pairs of user-defined parameters\n     * @return FileUploadResult containing result of upload request\n     */\n    private void upload(final String source, final String target, JSONArray args, CallbackContext callbackContext) throws JSONException {\n        Log.d(LOG_TAG, \"upload \" + source + \" to \" +  target);\n\n        // Setup the options\n        final String fileKey = getArgument(args, 2, \"file\");\n        final String fileName = getArgument(args, 3, \"image.jpg\");\n        final String mimeType = getArgument(args, 4, \"image/jpeg\");\n        final JSONObject params = args.optJSONObject(5) == null ? new JSONObject() : args.optJSONObject(5);\n        final boolean trustEveryone = args.optBoolean(6);\n        // Always use chunked mode unless set to false as per API\n        final boolean chunkedMode = args.optBoolean(7) || args.isNull(7);\n        // Look for headers on the params map for backwards compatibility with older Cordova versions.\n        final JSONObject headers = args.optJSONObject(8) == null ? params.optJSONObject(\"headers\") : args.optJSONObject(8);\n        final String objectId = args.getString(9);\n        final String httpMethod = getArgument(args, 10, \"POST\");\n        \n        final CordovaResourceApi resourceApi = webView.getResourceApi();\n\n        Log.d(LOG_TAG, \"fileKey: \" + fileKey);\n        Log.d(LOG_TAG, \"fileName: \" + fileName);\n        Log.d(LOG_TAG, \"mimeType: \" + mimeType);\n        Log.d(LOG_TAG, \"params: \" + params);\n        Log.d(LOG_TAG, \"trustEveryone: \" + trustEveryone);\n        Log.d(LOG_TAG, \"chunkedMode: \" + chunkedMode);\n        Log.d(LOG_TAG, \"headers: \" + headers);\n        Log.d(LOG_TAG, \"objectId: \" + objectId);\n        Log.d(LOG_TAG, \"httpMethod: \" + httpMethod);\n        \n        final Uri targetUri = resourceApi.remapUri(Uri.parse(target));\n        // Accept a path or a URI for the source.\n        Uri tmpSrc = Uri.parse(source);\n        final Uri sourceUri = resourceApi.remapUri(\n            tmpSrc.getScheme() != null ? tmpSrc : Uri.fromFile(new File(source)));\n\n        int uriType = CordovaResourceApi.getUriType(targetUri);\n        final boolean useHttps = uriType == CordovaResourceApi.URI_TYPE_HTTPS;\n        if (uriType != CordovaResourceApi.URI_TYPE_HTTP && !useHttps) {\n            JSONObject error = createFileTransferError(INVALID_URL_ERR, source, target, null, 0);\n            Log.e(LOG_TAG, \"Unsupported URI: \" + targetUri);\n            callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));\n            return;\n        }\n\n        final RequestContext context = new RequestContext(source, target, callbackContext);\n        synchronized (activeRequests) {\n            activeRequests.put(objectId, context);\n        }\n        \n        cordova.getThreadPool().execute(new Runnable() {\n            public void run() {\n                if (context.aborted) {\n                    return;\n                }\n                HttpURLConnection conn = null;\n                HostnameVerifier oldHostnameVerifier = null;\n                SSLSocketFactory oldSocketFactory = null;\n                int totalBytes = 0;\n                int fixedLength = -1;\n                try {\n                    // Create return object\n                    FileUploadResult result = new FileUploadResult();\n                    FileProgressResult progress = new FileProgressResult();\n\n                    //------------------ CLIENT REQUEST\n                    // Open a HTTP connection to the URL based on protocol\n                    conn = resourceApi.createHttpConnection(targetUri);\n                    if (useHttps && trustEveryone) {\n                        // Setup the HTTPS connection class to trust everyone\n                        HttpsURLConnection https = (HttpsURLConnection)conn;\n                        oldSocketFactory  = trustAllHosts(https);\n                        // Save the current hostnameVerifier\n                        oldHostnameVerifier = https.getHostnameVerifier();\n                        // Setup the connection not to verify hostnames\n                        https.setHostnameVerifier(DO_NOT_VERIFY);\n                    }\n\n                    // Allow Inputs\n                    conn.setDoInput(true);\n\n                    // Allow Outputs\n                    conn.setDoOutput(true);\n\n                    // Don't use a cached copy.\n                    conn.setUseCaches(false);\n\n                    // Use a post method.\n                    conn.setRequestMethod(httpMethod);\n\n                    // if we specified a Content-Type header, don't do multipart form upload\n                    boolean multipartFormUpload = (headers == null) || !headers.has(\"Content-Type\");\n                    if (multipartFormUpload) {\n                        conn.setRequestProperty(\"Content-Type\", \"multipart/form-data; boundary=\" + BOUNDARY);\n                    }\n                    // Set the cookies on the response\n                    String cookie = AmazonCookieManager.getInstance().getCookie(target);\n                    if (cookie != null) {\n                        conn.setRequestProperty(\"Cookie\", cookie);\n                    }\n\n                    // Handle the other headers\n                    if (headers != null) {\n                        addHeadersToRequest(conn, headers);\n                    }\n\n                    /*\n                        * Store the non-file portions of the multipart data as a string, so that we can add it\n                        * to the contentSize, since it is part of the body of the HTTP request.\n                        */\n                    StringBuilder beforeData = new StringBuilder();\n                    try {\n                        for (Iterator<?> iter = params.keys(); iter.hasNext();) {\n                            Object key = iter.next();\n                            if(!String.valueOf(key).equals(\"headers\"))\n                            {\n                              beforeData.append(LINE_START).append(BOUNDARY).append(LINE_END);\n                              beforeData.append(\"Content-Disposition: form-data; name=\\\"\").append(key.toString()).append('\"');\n                              beforeData.append(LINE_END).append(LINE_END);\n                              beforeData.append(params.getString(key.toString()));\n                              beforeData.append(LINE_END);\n                            }\n                        }\n                    } catch (JSONException e) {\n                        Log.e(LOG_TAG, e.getMessage(), e);\n                    }\n\n                    beforeData.append(LINE_START).append(BOUNDARY).append(LINE_END);\n                    beforeData.append(\"Content-Disposition: form-data; name=\\\"\").append(fileKey).append(\"\\\";\");\n                    beforeData.append(\" filename=\\\"\").append(fileName).append('\"').append(LINE_END);\n                    beforeData.append(\"Content-Type: \").append(mimeType).append(LINE_END).append(LINE_END);\n                    byte[] beforeDataBytes = beforeData.toString().getBytes(\"UTF-8\");\n                    byte[] tailParamsBytes = (LINE_END + LINE_START + BOUNDARY + LINE_START + LINE_END).getBytes(\"UTF-8\");\n\n                    \n                    // Get a input stream of the file on the phone\n                    OpenForReadResult readResult = resourceApi.openForRead(sourceUri);\n                    \n                    int stringLength = beforeDataBytes.length + tailParamsBytes.length;\n                    if (readResult.length >= 0) {\n                        fixedLength = (int)readResult.length;\n                        if (multipartFormUpload)\n                            fixedLength += stringLength;\n                        progress.setLengthComputable(true);\n                        progress.setTotal(fixedLength);\n                    }\n                    Log.d(LOG_TAG, \"Content Length: \" + fixedLength);\n                    // setFixedLengthStreamingMode causes and OutOfMemoryException on pre-Froyo devices.\n                    // http://code.google.com/p/android/issues/detail?id=3164\n                    // It also causes OOM if HTTPS is used, even on newer devices.\n                    boolean useChunkedMode = chunkedMode && (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO || useHttps);\n                    useChunkedMode = useChunkedMode || (fixedLength == -1);\n\n                    if (useChunkedMode) {\n                        conn.setChunkedStreamingMode(MAX_BUFFER_SIZE);\n                        // Although setChunkedStreamingMode sets this header, setting it explicitly here works\n                        // around an OutOfMemoryException when using https.\n                        conn.setRequestProperty(\"Transfer-Encoding\", \"chunked\");\n                    } else {\n                        conn.setFixedLengthStreamingMode(fixedLength);\n                    }\n\n                    conn.connect();\n                    \n                    OutputStream sendStream = null;\n                    try {\n                        sendStream = conn.getOutputStream();\n                        synchronized (context) {\n                            if (context.aborted) {\n                                return;\n                            }\n                            context.currentOutputStream = sendStream;\n                        }\n                        \n                        if (multipartFormUpload) {\n                            //We don't want to change encoding, we just want this to write for all Unicode.\n                            sendStream.write(beforeDataBytes);\n                            totalBytes += beforeDataBytes.length;\n                        }\n                        // create a buffer of maximum size\n                        int bytesAvailable = readResult.inputStream.available();\n                        int bufferSize = Math.min(bytesAvailable, MAX_BUFFER_SIZE);\n                        byte[] buffer = new byte[bufferSize];\n    \n                        // read file and write it into form...\n                        int bytesRead = readResult.inputStream.read(buffer, 0, bufferSize);\n    \n                        long prevBytesRead = 0;\n                        while (bytesRead > 0) {\n                            result.setBytesSent(totalBytes);\n                            sendStream.write(buffer, 0, bytesRead);\n                            totalBytes += bytesRead;\n                            if (totalBytes > prevBytesRead + 102400) {\n                                prevBytesRead = totalBytes;\n                                Log.d(LOG_TAG, \"Uploaded \" + totalBytes + \" of \" + fixedLength + \" bytes\");\n                            }\n                            bytesAvailable = readResult.inputStream.available();\n                            bufferSize = Math.min(bytesAvailable, MAX_BUFFER_SIZE);\n                            bytesRead = readResult.inputStream.read(buffer, 0, bufferSize);\n\n                            // Send a progress event.\n                            progress.setLoaded(totalBytes);\n                            PluginResult progressResult = new PluginResult(PluginResult.Status.OK, progress.toJSONObject());\n                            progressResult.setKeepCallback(true);\n                            context.sendPluginResult(progressResult);\n                        }\n    \n                        if (multipartFormUpload) {\n                            // send multipart form data necessary after file data...\n                            sendStream.write(tailParamsBytes);\n                            totalBytes += tailParamsBytes.length;\n                        }\n                        sendStream.flush();\n                    } finally {\n                        safeClose(readResult.inputStream);\n                        safeClose(sendStream);\n                    }\n                    context.currentOutputStream = null;\n                    Log.d(LOG_TAG, \"Sent \" + totalBytes + \" of \" + fixedLength);\n\n                    //------------------ read the SERVER RESPONSE\n                    String responseString;\n                    int responseCode = conn.getResponseCode();\n                    Log.d(LOG_TAG, \"response code: \" + responseCode);\n                    Log.d(LOG_TAG, \"response headers: \" + conn.getHeaderFields());\n                    TrackingInputStream inStream = null;\n                    try {\n                        inStream = getInputStream(conn);\n                        synchronized (context) {\n                            if (context.aborted) {\n                                return;\n                            }\n                            context.currentInputStream = inStream;\n                        }\n                        \n                        ByteArrayOutputStream out = new ByteArrayOutputStream(Math.max(1024, conn.getContentLength()));\n                        byte[] buffer = new byte[1024];\n                        int bytesRead = 0;\n                        // write bytes to file\n                        while ((bytesRead = inStream.read(buffer)) > 0) {\n                            out.write(buffer, 0, bytesRead);\n                        }\n                        responseString = out.toString(\"UTF-8\");\n                    } finally {\n                        context.currentInputStream = null;\n                        safeClose(inStream);\n                    }\n                    \n                    Log.d(LOG_TAG, \"got response from server\");\n                    Log.d(LOG_TAG, responseString.substring(0, Math.min(256, responseString.length())));\n                    \n                    // send request and retrieve response\n                    result.setResponseCode(responseCode);\n                    result.setResponse(responseString);\n\n                    context.sendPluginResult(new PluginResult(PluginResult.Status.OK, result.toJSONObject()));\n                } catch (FileNotFoundException e) {\n                    JSONObject error = createFileTransferError(FILE_NOT_FOUND_ERR, source, target, conn);\n                    Log.e(LOG_TAG, error.toString(), e);\n                    context.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));\n                } catch (IOException e) {\n                    JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, conn);\n                    Log.e(LOG_TAG, error.toString(), e);\n                    Log.e(LOG_TAG, \"Failed after uploading \" + totalBytes + \" of \" + fixedLength + \" bytes.\");\n                    context.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));\n                } catch (JSONException e) {\n                    Log.e(LOG_TAG, e.getMessage(), e);\n                    context.sendPluginResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));\n                } catch (Throwable t) {\n                    // Shouldn't happen, but will\n                    JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, conn);\n                    Log.e(LOG_TAG, error.toString(), t);\n                    context.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));\n                } finally {\n                    synchronized (activeRequests) {\n                        activeRequests.remove(objectId);\n                    }\n\n                    if (conn != null) {\n                        // Revert back to the proper verifier and socket factories\n                        // Revert back to the proper verifier and socket factories\n                        if (trustEveryone && useHttps) {\n                            HttpsURLConnection https = (HttpsURLConnection) conn;\n                            https.setHostnameVerifier(oldHostnameVerifier);\n                            https.setSSLSocketFactory(oldSocketFactory);\n                        }\n                    }\n                }                \n            }\n        });\n    }\n\n    private static void safeClose(Closeable stream) {\n        if (stream != null) {\n            try {\n                stream.close();\n            } catch (IOException e) {\n            }\n        }\n    }\n\n    private static TrackingInputStream getInputStream(URLConnection conn) throws IOException {\n        String encoding = conn.getContentEncoding();\n        if (encoding != null && encoding.equalsIgnoreCase(\"gzip\")) {\n          return new TrackingGZIPInputStream(new ExposedGZIPInputStream(conn.getInputStream()));\n        }\n        return new SimpleTrackingInputStream(conn.getInputStream());\n    }\n\n    // always verify the host - don't check for certificate\n    private static final HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {\n        public boolean verify(String hostname, SSLSession session) {\n            return true;\n        }\n    };\n    // Create a trust manager that does not validate certificate chains\n    private static final TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {\n        public java.security.cert.X509Certificate[] getAcceptedIssuers() {\n            return new java.security.cert.X509Certificate[] {};\n        }\n        \n        public void checkClientTrusted(X509Certificate[] chain,\n                String authType) throws CertificateException {\n        }\n        \n        public void checkServerTrusted(X509Certificate[] chain,\n                String authType) throws CertificateException {\n        }\n    } };\n\n    /**\n     * This function will install a trust manager that will blindly trust all SSL\n     * certificates.  The reason this code is being added is to enable developers\n     * to do development using self signed SSL certificates on their web server.\n     *\n     * The standard HttpsURLConnection class will throw an exception on self\n     * signed certificates if this code is not run.\n     */\n    private static SSLSocketFactory trustAllHosts(HttpsURLConnection connection) {\n        // Install the all-trusting trust manager\n        SSLSocketFactory oldFactory = connection.getSSLSocketFactory();\n        try {\n            // Install our all trusting manager\n            SSLContext sc = SSLContext.getInstance(\"TLS\");\n            sc.init(null, trustAllCerts, new java.security.SecureRandom());\n            SSLSocketFactory newFactory = sc.getSocketFactory();\n            connection.setSSLSocketFactory(newFactory);\n        } catch (Exception e) {\n            Log.e(LOG_TAG, e.getMessage(), e);\n        }\n        return oldFactory;\n    }\n\n    private static JSONObject createFileTransferError(int errorCode, String source, String target, URLConnection connection) {\n\n        int httpStatus = 0;\n        StringBuilder bodyBuilder = new StringBuilder();\n        String body = null;\n        if (connection != null) {\n            try {\n                if (connection instanceof HttpURLConnection) {\n                    httpStatus = ((HttpURLConnection)connection).getResponseCode();\n                    InputStream err = ((HttpURLConnection) connection).getErrorStream();\n                    if(err != null)\n                    {\n                        BufferedReader reader = new BufferedReader(new InputStreamReader(err, \"UTF-8\"));\n                        try {\n                            String line = reader.readLine();\n                            while(line != null) {\n                                bodyBuilder.append(line);\n                                line = reader.readLine();\n                                if(line != null) {\n                                    bodyBuilder.append('\\n');\n                                }\n                            }\n                            body = bodyBuilder.toString();\n                        } finally {\n                            reader.close();\n                        }\n                    }\n                }\n            // IOException can leave connection object in a bad state, so catch all exceptions.\n            } catch (Throwable e) {\n                Log.w(LOG_TAG, \"Error getting HTTP status code from connection.\", e);\n            }\n        }\n\n        return createFileTransferError(errorCode, source, target, body, httpStatus);\n    }\n\n        /**\n        * Create an error object based on the passed in errorCode\n        * @param errorCode      the error\n        * @return JSONObject containing the error\n        */\n    private static JSONObject createFileTransferError(int errorCode, String source, String target, String body, Integer httpStatus) {\n        JSONObject error = null;\n        try {\n            error = new JSONObject();\n            error.put(\"code\", errorCode);\n            error.put(\"source\", source);\n            error.put(\"target\", target);\n            if(body != null)\n            {\n                error.put(\"body\", body);\n            }   \n            if (httpStatus != null) {\n                error.put(\"http_status\", httpStatus);\n            }\n        } catch (JSONException e) {\n            Log.e(LOG_TAG, e.getMessage(), e);\n        }\n        return error;\n    }\n\n    /**\n     * Convenience method to read a parameter from the list of JSON args.\n     * @param args                      the args passed to the Plugin\n     * @param position          the position to retrieve the arg from\n     * @param defaultString the default to be used if the arg does not exist\n     * @return String with the retrieved value\n     */\n    private static String getArgument(JSONArray args, int position, String defaultString) {\n        String arg = defaultString;\n        if (args.length() > position) {\n            arg = args.optString(position);\n            if (arg == null || \"null\".equals(arg)) {\n                arg = defaultString;\n            }\n        }\n        return arg;\n    }\n\n    /**\n     * Downloads a file form a given URL and saves it to the specified directory.\n     *\n     * @param source        URL of the server to receive the file\n     * @param target            Full path of the file on the file system\n     */\n    private void download(final String source, final String target, JSONArray args, CallbackContext callbackContext) throws JSONException {\n        Log.d(LOG_TAG, \"download \" + source + \" to \" +  target);\n\n        final CordovaResourceApi resourceApi = webView.getResourceApi();\n\n        final boolean trustEveryone = args.optBoolean(2);\n        final String objectId = args.getString(3);\n        final JSONObject headers = args.optJSONObject(4);\n        \n        final Uri sourceUri = resourceApi.remapUri(Uri.parse(source));\n        // Accept a path or a URI for the source.\n        Uri tmpTarget = Uri.parse(target);\n        final Uri targetUri = resourceApi.remapUri(\n            tmpTarget.getScheme() != null ? tmpTarget : Uri.fromFile(new File(target)));\n\n        int uriType = CordovaResourceApi.getUriType(sourceUri);\n        final boolean useHttps = uriType == CordovaResourceApi.URI_TYPE_HTTPS;\n        final boolean isLocalTransfer = !useHttps && uriType != CordovaResourceApi.URI_TYPE_HTTP;\n        if (uriType == CordovaResourceApi.URI_TYPE_UNKNOWN) {\n            JSONObject error = createFileTransferError(INVALID_URL_ERR, source, target, null, 0);\n            Log.e(LOG_TAG, \"Unsupported URI: \" + targetUri);\n            callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));\n            return;\n        }\n        \n        // TODO: refactor to also allow resources & content:\n        if (!isLocalTransfer && !Config.isUrlWhiteListed(source)) {\n            Log.w(LOG_TAG, \"Source URL is not in white list: '\" + source + \"'\");\n            JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, null, 401);\n            callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));\n            return;\n        }\n\n        \n        final RequestContext context = new RequestContext(source, target, callbackContext);\n        synchronized (activeRequests) {\n            activeRequests.put(objectId, context);\n        }\n        \n        cordova.getThreadPool().execute(new Runnable() {\n            public void run() {\n                if (context.aborted) {\n                    return;\n                }\n                HttpURLConnection connection = null;\n                HostnameVerifier oldHostnameVerifier = null;\n                SSLSocketFactory oldSocketFactory = null;\n                File file = null;\n                PluginResult result = null;\n                TrackingInputStream inputStream = null;\n\n                OutputStream outputStream = null;\n                try {\n                    OpenForReadResult readResult = null;\n                    outputStream = resourceApi.openOutputStream(targetUri);\n\n                    file = resourceApi.mapUriToFile(targetUri);\n                    context.targetFile = file;\n                    \n                    Log.d(LOG_TAG, \"Download file:\" + sourceUri);\n\n                    FileProgressResult progress = new FileProgressResult();\n\n                    if (isLocalTransfer) {\n                        readResult = resourceApi.openForRead(sourceUri);\n                        if (readResult.length != -1) {\n                            progress.setLengthComputable(true);\n                            progress.setTotal(readResult.length);\n                        }\n                        inputStream = new SimpleTrackingInputStream(readResult.inputStream);\n                    } else {\n                        // connect to server\n                        // Open a HTTP connection to the URL based on protocol\n                        connection = resourceApi.createHttpConnection(sourceUri);\n                        if (useHttps && trustEveryone) {\n                            // Setup the HTTPS connection class to trust everyone\n                            HttpsURLConnection https = (HttpsURLConnection)connection;\n                            oldSocketFactory = trustAllHosts(https);\n                            // Save the current hostnameVerifier\n                            oldHostnameVerifier = https.getHostnameVerifier();\n                            // Setup the connection not to verify hostnames\n                            https.setHostnameVerifier(DO_NOT_VERIFY);\n                        }\n        \n                        connection.setRequestMethod(\"GET\");\n        \n                        // TODO: Make OkHttp use this AmazonCookieManager by default.\n                        String cookie = AmazonCookieManager.getInstance().getCookie(sourceUri.toString());\n                        if(cookie != null)\n                        {\n                            connection.setRequestProperty(\"cookie\", cookie);\n                        }\n                        \n                        // This must be explicitly set for gzip progress tracking to work.\n                        connection.setRequestProperty(\"Accept-Encoding\", \"gzip\");\n    \n                        // Handle the other headers\n                        if (headers != null) {\n                            addHeadersToRequest(connection, headers);\n                        }\n        \n                        connection.connect();\n    \n                        if (connection.getContentEncoding() == null || connection.getContentEncoding().equalsIgnoreCase(\"gzip\")) {\n                            // Only trust content-length header if we understand\n                            // the encoding -- identity or gzip\n                            if (connection.getContentLength() != -1) {\n                                progress.setLengthComputable(true);\n                                progress.setTotal(connection.getContentLength());\n                            }\n                        }\n                        inputStream = getInputStream(connection);\n                    }\n                    \n                    try {\n                        synchronized (context) {\n                            if (context.aborted) {\n                                return;\n                            }\n                            context.currentInputStream = inputStream;\n                        }\n                        \n                        // write bytes to file\n                        byte[] buffer = new byte[MAX_BUFFER_SIZE];\n                        int bytesRead = 0;\n                        while ((bytesRead = inputStream.read(buffer)) > 0) {\n                            outputStream.write(buffer, 0, bytesRead);\n                            // Send a progress event.\n                            progress.setLoaded(inputStream.getTotalRawBytesRead());\n                            PluginResult progressResult = new PluginResult(PluginResult.Status.OK, progress.toJSONObject());\n                            progressResult.setKeepCallback(true);\n                            context.sendPluginResult(progressResult);\n                        }\n                    } finally {\n                        context.currentInputStream = null;\n                        safeClose(inputStream);\n                        safeClose(outputStream);\n                    }\n    \n                    Log.d(LOG_TAG, \"Saved file: \" + target);\n    \n                    // create FileEntry object\n                    FileUtils filePlugin = (FileUtils)webView.pluginManager.getPlugin(\"File\");\n                    if (filePlugin != null) {\n                        JSONObject fileEntry = filePlugin.getEntryForFile(file);\n                        if (fileEntry != null) {\n                            result = new PluginResult(PluginResult.Status.OK, fileEntry);\n                        } else {\n                            JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, connection);\n                            Log.e(LOG_TAG, \"File plugin cannot represent download path\");\n                            result = new PluginResult(PluginResult.Status.IO_EXCEPTION, error);\n                        }\n                    } else {\n                        Log.e(LOG_TAG, \"File plugin not found; cannot save downloaded file\");\n                        result = new PluginResult(PluginResult.Status.ERROR, \"File plugin not found; cannot save downloaded file\");\n                    }\n\n                } catch (FileNotFoundException e) {\n                    JSONObject error = createFileTransferError(FILE_NOT_FOUND_ERR, source, target, connection);\n                    Log.e(LOG_TAG, error.toString(), e);\n                    result = new PluginResult(PluginResult.Status.IO_EXCEPTION, error);\n                } catch (IOException e) {\n                    JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, connection);\n                    Log.e(LOG_TAG, error.toString(), e);\n                    result = new PluginResult(PluginResult.Status.IO_EXCEPTION, error);\n                } catch (JSONException e) {\n                    Log.e(LOG_TAG, e.getMessage(), e);\n                    result = new PluginResult(PluginResult.Status.JSON_EXCEPTION);\n                } catch (Throwable e) {\n                    JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, connection);\n                    Log.e(LOG_TAG, error.toString(), e);\n                    result = new PluginResult(PluginResult.Status.IO_EXCEPTION, error);\n                } finally {\n                    safeClose(outputStream);\n                    synchronized (activeRequests) {\n                        activeRequests.remove(objectId);\n                    }\n\n                    if (connection != null) {\n                        // Revert back to the proper verifier and socket factories\n                        if (trustEveryone && useHttps) {\n                            HttpsURLConnection https = (HttpsURLConnection) connection;\n                            https.setHostnameVerifier(oldHostnameVerifier);\n                            https.setSSLSocketFactory(oldSocketFactory);\n                        }\n                    }\n\n                    if (result == null) {\n                        result = new PluginResult(PluginResult.Status.ERROR, createFileTransferError(CONNECTION_ERR, source, target, connection));\n                    }\n                    // Remove incomplete download.\n                    if (result.getStatus() != PluginResult.Status.OK.ordinal() && file != null) {\n                        file.delete();\n                    }\n                    context.sendPluginResult(result);\n                }\n            }\n        });\n    }\n\n    /**\n     * Abort an ongoing upload or download.\n     */\n    private void abort(String objectId) {\n        final RequestContext context;\n        synchronized (activeRequests) {\n            context = activeRequests.remove(objectId);\n        }\n        if (context != null) {\n            File file = context.targetFile;\n            if (file != null) {\n                file.delete();\n            }\n            // Trigger the abort callback immediately to minimize latency between it and abort() being called.\n            JSONObject error = createFileTransferError(ABORTED_ERR, context.source, context.target, null, -1);\n            synchronized (context) {\n                context.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, error));\n                context.aborted = true;\n            }\n            // Closing the streams can block, so execute on a background thread.\n            cordova.getThreadPool().execute(new Runnable() {\n                public void run() {\n                    synchronized (context) {\n                        safeClose(context.currentInputStream);\n                        safeClose(context.currentOutputStream);\n                    }\n                }\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/src/android/FileProgressResult.java",
    "content": "/*\n       Licensed to the Apache Software Foundation (ASF) under one\n       or more contributor license agreements.  See the NOTICE file\n       distributed with this work for additional information\n       regarding copyright ownership.  The ASF licenses this file\n       to you under the Apache License, Version 2.0 (the\n       \"License\"); you may not use this file except in compliance\n       with the License.  You may obtain a copy of the License at\n\n         http://www.apache.org/licenses/LICENSE-2.0\n\n       Unless required by applicable law or agreed to in writing,\n       software distributed under the License is distributed on an\n       \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n       KIND, either express or implied.  See the License for the\n       specific language governing permissions and limitations\n       under the License.\n*/\npackage org.apache.cordova.filetransfer;\n\nimport org.json.JSONException;\nimport org.json.JSONObject;\n\n/**\n * Encapsulates in-progress status of uploading or downloading a file to a remote server.\n */\npublic class FileProgressResult {\n\n    private boolean lengthComputable = false; // declares whether total is known\n    private long loaded = 0;                  // bytes sent so far\n    private long total = 0;                   // bytes total, if known\n\n    public boolean getLengthComputable() {\n        return lengthComputable;\n    }\n\n    public void setLengthComputable(boolean computable) {\n        this.lengthComputable = computable;\n    }\n\n    public long getLoaded() {\n        return loaded;\n    }\n\n    public void setLoaded(long bytes) {\n        this.loaded = bytes;\n    }\n\n    public long getTotal() {\n        return total;\n    }\n\n    public void setTotal(long bytes) {\n        this.total = bytes;\n    }\n\n    public JSONObject toJSONObject() throws JSONException {\n        return new JSONObject(\n                \"{loaded:\" + loaded +\n                \",total:\" + total +\n                \",lengthComputable:\" + (lengthComputable ? \"true\" : \"false\") + \"}\");\n    }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/src/android/FileTransfer.java",
    "content": "/*\n       Licensed to the Apache Software Foundation (ASF) under one\n       or more contributor license agreements.  See the NOTICE file\n       distributed with this work for additional information\n       regarding copyright ownership.  The ASF licenses this file\n       to you under the Apache License, Version 2.0 (the\n       \"License\"); you may not use this file except in compliance\n       with the License.  You may obtain a copy of the License at\n\n         http://www.apache.org/licenses/LICENSE-2.0\n\n       Unless required by applicable law or agreed to in writing,\n       software distributed under the License is distributed on an\n       \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n       KIND, either express or implied.  See the License for the\n       specific language governing permissions and limitations\n       under the License.\n*/\npackage org.apache.cordova.filetransfer;\n\nimport java.io.BufferedReader;\nimport java.io.ByteArrayOutputStream;\nimport java.io.Closeable;\nimport java.io.File;\nimport java.io.FileNotFoundException;\nimport java.io.FilterInputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.InputStreamReader;\nimport java.io.OutputStream;\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Field;\nimport java.lang.reflect.Method;\nimport java.net.HttpURLConnection;\nimport java.net.URLConnection;\nimport java.security.cert.CertificateException;\nimport java.security.cert.X509Certificate;\nimport java.util.HashMap;\nimport java.util.Iterator;\nimport java.util.zip.GZIPInputStream;\nimport java.util.zip.Inflater;\n\nimport javax.net.ssl.HostnameVerifier;\nimport javax.net.ssl.HttpsURLConnection;\nimport javax.net.ssl.SSLContext;\nimport javax.net.ssl.SSLSession;\nimport javax.net.ssl.SSLSocketFactory;\nimport javax.net.ssl.TrustManager;\nimport javax.net.ssl.X509TrustManager;\n\nimport org.apache.cordova.Config;\nimport org.apache.cordova.CallbackContext;\nimport org.apache.cordova.CordovaPlugin;\nimport org.apache.cordova.CordovaResourceApi;\nimport org.apache.cordova.CordovaResourceApi.OpenForReadResult;\nimport org.apache.cordova.PluginManager;\nimport org.apache.cordova.PluginResult;\nimport org.apache.cordova.Whitelist;\nimport org.apache.cordova.file.FileUtils;\nimport org.json.JSONArray;\nimport org.json.JSONException;\nimport org.json.JSONObject;\n\nimport android.net.Uri;\nimport android.os.Build;\nimport android.util.Log;\nimport android.webkit.CookieManager;\n\npublic class FileTransfer extends CordovaPlugin {\n\n    private static final String LOG_TAG = \"FileTransfer\";\n    private static final String LINE_START = \"--\";\n    private static final String LINE_END = \"\\r\\n\";\n    private static final String BOUNDARY =  \"+++++\";\n\n    public static int FILE_NOT_FOUND_ERR = 1;\n    public static int INVALID_URL_ERR = 2;\n    public static int CONNECTION_ERR = 3;\n    public static int ABORTED_ERR = 4;\n    public static int NOT_MODIFIED_ERR = 5;\n\n    private static HashMap<String, RequestContext> activeRequests = new HashMap<String, RequestContext>();\n    private static final int MAX_BUFFER_SIZE = 16 * 1024;\n\n    private static final class RequestContext {\n        String source;\n        String target;\n        File targetFile;\n        CallbackContext callbackContext;\n        HttpURLConnection connection;\n        boolean aborted;\n        RequestContext(String source, String target, CallbackContext callbackContext) {\n            this.source = source;\n            this.target = target;\n            this.callbackContext = callbackContext;\n        }\n        void sendPluginResult(PluginResult pluginResult) {\n            synchronized (this) {\n                if (!aborted) {\n                    callbackContext.sendPluginResult(pluginResult);\n                }\n            }\n        }\n    }\n\n    /**\n     * Adds an interface method to an InputStream to return the number of bytes\n     * read from the raw stream. This is used to track total progress against\n     * the HTTP Content-Length header value from the server.\n     */\n    private static abstract class TrackingInputStream extends FilterInputStream {\n      public TrackingInputStream(final InputStream in) {\n        super(in);\n      }\n        public abstract long getTotalRawBytesRead();\n  }\n\n    private static class ExposedGZIPInputStream extends GZIPInputStream {\n      public ExposedGZIPInputStream(final InputStream in) throws IOException {\n        super(in);\n      }\n      public Inflater getInflater() {\n        return inf;\n      }\n  }\n\n    /**\n     * Provides raw bytes-read tracking for a GZIP input stream. Reports the\n     * total number of compressed bytes read from the input, rather than the\n     * number of uncompressed bytes.\n     */\n    private static class TrackingGZIPInputStream extends TrackingInputStream {\n      private ExposedGZIPInputStream gzin;\n      public TrackingGZIPInputStream(final ExposedGZIPInputStream gzin) throws IOException {\n        super(gzin);\n        this.gzin = gzin;\n      }\n      public long getTotalRawBytesRead() {\n        return gzin.getInflater().getBytesRead();\n      }\n  }\n\n    /**\n     * Provides simple total-bytes-read tracking for an existing InputStream\n     */\n    private static class SimpleTrackingInputStream extends TrackingInputStream {\n        private long bytesRead = 0;\n        public SimpleTrackingInputStream(InputStream stream) {\n            super(stream);\n        }\n\n        private int updateBytesRead(int newBytesRead) {\n          if (newBytesRead != -1) {\n            bytesRead += newBytesRead;\n          }\n          return newBytesRead;\n        }\n\n        @Override\n        public int read() throws IOException {\n            return updateBytesRead(super.read());\n        }\n\n        // Note: FilterInputStream delegates read(byte[] bytes) to the below method,\n        // so we don't override it or else double count (CB-5631).\n        @Override\n        public int read(byte[] bytes, int offset, int count) throws IOException {\n            return updateBytesRead(super.read(bytes, offset, count));\n        }\n\n        public long getTotalRawBytesRead() {\n          return bytesRead;\n        }\n    }\n\n    @Override\n    public boolean execute(String action, JSONArray args, final CallbackContext callbackContext) throws JSONException {\n        if (action.equals(\"upload\") || action.equals(\"download\")) {\n            String source = args.getString(0);\n            String target = args.getString(1);\n\n            if (action.equals(\"upload\")) {\n                upload(source, target, args, callbackContext);\n            } else {\n                download(source, target, args, callbackContext);\n            }\n            return true;\n        } else if (action.equals(\"abort\")) {\n            String objectId = args.getString(0);\n            abort(objectId);\n            callbackContext.success();\n            return true;\n        }\n        return false;\n    }\n\n    private static void addHeadersToRequest(URLConnection connection, JSONObject headers) {\n        try {\n            for (Iterator<?> iter = headers.keys(); iter.hasNext(); ) {\n                /* RFC 2616 says that non-ASCII characters and control\n                 * characters are not allowed in header names or values.\n                 * Additionally, spaces are not allowed in header names.\n                 * RFC 2046 Quoted-printable encoding may be used to encode\n                 * arbitrary characters, but we donon- not do that encoding here.\n                 */\n                String headerKey = iter.next().toString();\n                String cleanHeaderKey = headerKey.replaceAll(\"\\\\n\",\"\")\n                        .replaceAll(\"\\\\s+\",\"\")\n                        .replaceAll(\":\", \"\")\n                        .replaceAll(\"[^\\\\x20-\\\\x7E]+\", \"\");\n\n                JSONArray headerValues = headers.optJSONArray(headerKey);\n                if (headerValues == null) {\n                    headerValues = new JSONArray();\n\n                     /* RFC 2616 also says that any amount of consecutive linear\n                      * whitespace within a header value can be replaced with a\n                      * single space character, without affecting the meaning of\n                      * that value.\n                      */\n\n                    String headerValue = headers.getString(headerKey);\n                    String finalValue = headerValue.replaceAll(\"\\\\s+\", \" \").replaceAll(\"\\\\n\",\" \").replaceAll(\"[^\\\\x20-\\\\x7E]+\", \" \");\n                    headerValues.put(finalValue);\n                }\n\n                //Use the clean header key, not the one that we passed in\n                connection.setRequestProperty(cleanHeaderKey, headerValues.getString(0));\n                for (int i = 1; i < headerValues.length(); ++i) {\n                    connection.addRequestProperty(headerKey, headerValues.getString(i));\n                }\n            }\n        } catch (JSONException e1) {\n          // No headers to be manipulated!\n        }\n    }\n\n    private String getCookies(final String target) {\n        boolean gotCookie = false;\n        String cookie = null;\n        Class webViewClass = webView.getClass();\n        try {\n            Method gcmMethod = webViewClass.getMethod(\"getCookieManager\");\n            Class iccmClass  = gcmMethod.getReturnType();\n            Method gcMethod  = iccmClass.getMethod(\"getCookie\", String.class);\n\n            cookie = (String)gcMethod.invoke(\n                        iccmClass.cast(\n                            gcmMethod.invoke(webView)\n                        ), target);\n\n            gotCookie = true;\n        } catch (NoSuchMethodException e) {\n        } catch (IllegalAccessException e) {\n        } catch (InvocationTargetException e) {\n        } catch (ClassCastException e) {\n        }\n\n        if (!gotCookie && CookieManager.getInstance() != null) {\n            cookie = CookieManager.getInstance().getCookie(target);\n        }\n\n        return cookie;\n    }\n\n    /**\n     * Uploads the specified file to the server URL provided using an HTTP multipart request.\n     * @param source        Full path of the file on the file system\n     * @param target        URL of the server to receive the file\n     * @param args          JSON Array of args\n     * @param callbackContext    callback id for optional progress reports\n     *\n     * args[2] fileKey       Name of file request parameter\n     * args[3] fileName      File name to be used on server\n     * args[4] mimeType      Describes file content type\n     * args[5] params        key:value pairs of user-defined parameters\n     * @return FileUploadResult containing result of upload request\n     */\n    private void upload(final String source, final String target, JSONArray args, CallbackContext callbackContext) throws JSONException {\n        Log.d(LOG_TAG, \"upload \" + source + \" to \" +  target);\n\n        // Setup the options\n        final String fileKey = getArgument(args, 2, \"file\");\n        final String fileName = getArgument(args, 3, \"image.jpg\");\n        final String mimeType = getArgument(args, 4, \"image/jpeg\");\n        final JSONObject params = args.optJSONObject(5) == null ? new JSONObject() : args.optJSONObject(5);\n        final boolean trustEveryone = args.optBoolean(6);\n        // Always use chunked mode unless set to false as per API\n        final boolean chunkedMode = args.optBoolean(7) || args.isNull(7);\n        // Look for headers on the params map for backwards compatibility with older Cordova versions.\n        final JSONObject headers = args.optJSONObject(8) == null ? params.optJSONObject(\"headers\") : args.optJSONObject(8);\n        final String objectId = args.getString(9);\n        final String httpMethod = getArgument(args, 10, \"POST\");\n\n        final CordovaResourceApi resourceApi = webView.getResourceApi();\n\n        Log.d(LOG_TAG, \"fileKey: \" + fileKey);\n        Log.d(LOG_TAG, \"fileName: \" + fileName);\n        Log.d(LOG_TAG, \"mimeType: \" + mimeType);\n        Log.d(LOG_TAG, \"params: \" + params);\n        Log.d(LOG_TAG, \"trustEveryone: \" + trustEveryone);\n        Log.d(LOG_TAG, \"chunkedMode: \" + chunkedMode);\n        Log.d(LOG_TAG, \"headers: \" + headers);\n        Log.d(LOG_TAG, \"objectId: \" + objectId);\n        Log.d(LOG_TAG, \"httpMethod: \" + httpMethod);\n\n        final Uri targetUri = resourceApi.remapUri(Uri.parse(target));\n        // Accept a path or a URI for the source.\n        Uri tmpSrc = Uri.parse(source);\n        final Uri sourceUri = resourceApi.remapUri(\n            tmpSrc.getScheme() != null ? tmpSrc : Uri.fromFile(new File(source)));\n\n        int uriType = CordovaResourceApi.getUriType(targetUri);\n        final boolean useHttps = uriType == CordovaResourceApi.URI_TYPE_HTTPS;\n        if (uriType != CordovaResourceApi.URI_TYPE_HTTP && !useHttps) {\n            JSONObject error = createFileTransferError(INVALID_URL_ERR, source, target, null, 0, null);\n            Log.e(LOG_TAG, \"Unsupported URI: \" + targetUri);\n            callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));\n            return;\n        }\n\n        final RequestContext context = new RequestContext(source, target, callbackContext);\n        synchronized (activeRequests) {\n            activeRequests.put(objectId, context);\n        }\n\n        cordova.getThreadPool().execute(new Runnable() {\n            public void run() {\n                if (context.aborted) {\n                    return;\n                }\n                HttpURLConnection conn = null;\n                HostnameVerifier oldHostnameVerifier = null;\n                SSLSocketFactory oldSocketFactory = null;\n                int totalBytes = 0;\n                int fixedLength = -1;\n                try {\n                    // Create return object\n                    FileUploadResult result = new FileUploadResult();\n                    FileProgressResult progress = new FileProgressResult();\n\n                    //------------------ CLIENT REQUEST\n                    // Open a HTTP connection to the URL based on protocol\n                    conn = resourceApi.createHttpConnection(targetUri);\n                    if (useHttps && trustEveryone) {\n                        // Setup the HTTPS connection class to trust everyone\n                        HttpsURLConnection https = (HttpsURLConnection)conn;\n                        oldSocketFactory  = trustAllHosts(https);\n                        // Save the current hostnameVerifier\n                        oldHostnameVerifier = https.getHostnameVerifier();\n                        // Setup the connection not to verify hostnames\n                        https.setHostnameVerifier(DO_NOT_VERIFY);\n                    }\n\n                    // Allow Inputs\n                    conn.setDoInput(true);\n\n                    // Allow Outputs\n                    conn.setDoOutput(true);\n\n                    // Don't use a cached copy.\n                    conn.setUseCaches(false);\n\n                    // Use a post method.\n                    conn.setRequestMethod(httpMethod);\n\n                    // if we specified a Content-Type header, don't do multipart form upload\n                    boolean multipartFormUpload = (headers == null) || !headers.has(\"Content-Type\");\n                    if (multipartFormUpload) {\n                        conn.setRequestProperty(\"Content-Type\", \"multipart/form-data; boundary=\" + BOUNDARY);\n                    }\n\n                    // Set the cookies on the response\n                    String cookie = getCookies(target);\n\n                    if (cookie != null) {\n                        conn.setRequestProperty(\"Cookie\", cookie);\n                    }\n\n                    // Handle the other headers\n                    if (headers != null) {\n                        addHeadersToRequest(conn, headers);\n                    }\n\n                    /*\n                        * Store the non-file portions of the multipart data as a string, so that we can add it\n                        * to the contentSize, since it is part of the body of the HTTP request.\n                        */\n                    StringBuilder beforeData = new StringBuilder();\n                    try {\n                        for (Iterator<?> iter = params.keys(); iter.hasNext();) {\n                            Object key = iter.next();\n                            if(!String.valueOf(key).equals(\"headers\"))\n                            {\n                              beforeData.append(LINE_START).append(BOUNDARY).append(LINE_END);\n                              beforeData.append(\"Content-Disposition: form-data; name=\\\"\").append(key.toString()).append('\"');\n                              beforeData.append(LINE_END).append(LINE_END);\n                              beforeData.append(params.getString(key.toString()));\n                              beforeData.append(LINE_END);\n                            }\n                        }\n                    } catch (JSONException e) {\n                        Log.e(LOG_TAG, e.getMessage(), e);\n                    }\n\n                    beforeData.append(LINE_START).append(BOUNDARY).append(LINE_END);\n                    beforeData.append(\"Content-Disposition: form-data; name=\\\"\").append(fileKey).append(\"\\\";\");\n                    beforeData.append(\" filename=\\\"\").append(fileName).append('\"').append(LINE_END);\n                    beforeData.append(\"Content-Type: \").append(mimeType).append(LINE_END).append(LINE_END);\n                    byte[] beforeDataBytes = beforeData.toString().getBytes(\"UTF-8\");\n                    byte[] tailParamsBytes = (LINE_END + LINE_START + BOUNDARY + LINE_START + LINE_END).getBytes(\"UTF-8\");\n\n\n                    // Get a input stream of the file on the phone\n                    OpenForReadResult readResult = resourceApi.openForRead(sourceUri);\n\n                    int stringLength = beforeDataBytes.length + tailParamsBytes.length;\n                    if (readResult.length >= 0) {\n                        fixedLength = (int)readResult.length;\n                        if (multipartFormUpload)\n                            fixedLength += stringLength;\n                        progress.setLengthComputable(true);\n                        progress.setTotal(fixedLength);\n                    }\n                    Log.d(LOG_TAG, \"Content Length: \" + fixedLength);\n                    // setFixedLengthStreamingMode causes and OutOfMemoryException on pre-Froyo devices.\n                    // http://code.google.com/p/android/issues/detail?id=3164\n                    // It also causes OOM if HTTPS is used, even on newer devices.\n                    boolean useChunkedMode = chunkedMode && (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO || useHttps);\n                    useChunkedMode = useChunkedMode || (fixedLength == -1);\n\n                    if (useChunkedMode) {\n                        conn.setChunkedStreamingMode(MAX_BUFFER_SIZE);\n                        // Although setChunkedStreamingMode sets this header, setting it explicitly here works\n                        // around an OutOfMemoryException when using https.\n                        conn.setRequestProperty(\"Transfer-Encoding\", \"chunked\");\n                    } else {\n                        conn.setFixedLengthStreamingMode(fixedLength);\n                    }\n\n                    conn.connect();\n\n                    OutputStream sendStream = null;\n                    try {\n                        sendStream = conn.getOutputStream();\n                        synchronized (context) {\n                            if (context.aborted) {\n                                return;\n                            }\n                            context.connection = conn;\n                        }\n\n                        if (multipartFormUpload) {\n                            //We don't want to change encoding, we just want this to write for all Unicode.\n                            sendStream.write(beforeDataBytes);\n                            totalBytes += beforeDataBytes.length;\n                        }\n\n                        // create a buffer of maximum size\n                        int bytesAvailable = readResult.inputStream.available();\n                        int bufferSize = Math.min(bytesAvailable, MAX_BUFFER_SIZE);\n                        byte[] buffer = new byte[bufferSize];\n\n                        // read file and write it into form...\n                        int bytesRead = readResult.inputStream.read(buffer, 0, bufferSize);\n\n                        long prevBytesRead = 0;\n                        while (bytesRead > 0) {\n                            totalBytes += bytesRead;\n                            result.setBytesSent(totalBytes);\n                            sendStream.write(buffer, 0, bytesRead);\n                            if (totalBytes > prevBytesRead + 102400) {\n                                prevBytesRead = totalBytes;\n                                Log.d(LOG_TAG, \"Uploaded \" + totalBytes + \" of \" + fixedLength + \" bytes\");\n                            }\n                            bytesAvailable = readResult.inputStream.available();\n                            bufferSize = Math.min(bytesAvailable, MAX_BUFFER_SIZE);\n                            bytesRead = readResult.inputStream.read(buffer, 0, bufferSize);\n\n                            // Send a progress event.\n                            progress.setLoaded(totalBytes);\n                            PluginResult progressResult = new PluginResult(PluginResult.Status.OK, progress.toJSONObject());\n                            progressResult.setKeepCallback(true);\n                            context.sendPluginResult(progressResult);\n                        }\n\n                        if (multipartFormUpload) {\n                            // send multipart form data necessary after file data...\n                            sendStream.write(tailParamsBytes);\n                            totalBytes += tailParamsBytes.length;\n                        }\n                        sendStream.flush();\n                    } finally {\n                        safeClose(readResult.inputStream);\n                        safeClose(sendStream);\n                    }\n                    synchronized (context) {\n                        context.connection = null;\n                    }\n                    Log.d(LOG_TAG, \"Sent \" + totalBytes + \" of \" + fixedLength);\n\n                    //------------------ read the SERVER RESPONSE\n                    String responseString;\n                    int responseCode = conn.getResponseCode();\n                    Log.d(LOG_TAG, \"response code: \" + responseCode);\n                    Log.d(LOG_TAG, \"response headers: \" + conn.getHeaderFields());\n                    TrackingInputStream inStream = null;\n                    try {\n                        inStream = getInputStream(conn);\n                        synchronized (context) {\n                            if (context.aborted) {\n                                return;\n                            }\n                            context.connection = conn;\n                        }\n\n                        ByteArrayOutputStream out = new ByteArrayOutputStream(Math.max(1024, conn.getContentLength()));\n                        byte[] buffer = new byte[1024];\n                        int bytesRead = 0;\n                        // write bytes to file\n                        while ((bytesRead = inStream.read(buffer)) > 0) {\n                            out.write(buffer, 0, bytesRead);\n                        }\n                        responseString = out.toString(\"UTF-8\");\n                    } finally {\n                        synchronized (context) {\n                            context.connection = null;\n                        }\n                        safeClose(inStream);\n                    }\n\n                    Log.d(LOG_TAG, \"got response from server\");\n                    Log.d(LOG_TAG, responseString.substring(0, Math.min(256, responseString.length())));\n\n                    // send request and retrieve response\n                    result.setResponseCode(responseCode);\n                    result.setResponse(responseString);\n\n                    context.sendPluginResult(new PluginResult(PluginResult.Status.OK, result.toJSONObject()));\n                } catch (FileNotFoundException e) {\n                    JSONObject error = createFileTransferError(FILE_NOT_FOUND_ERR, source, target, conn, e);\n                    Log.e(LOG_TAG, error.toString(), e);\n                    context.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));\n                } catch (IOException e) {\n                    JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, conn, e);\n                    Log.e(LOG_TAG, error.toString(), e);\n                    Log.e(LOG_TAG, \"Failed after uploading \" + totalBytes + \" of \" + fixedLength + \" bytes.\");\n                    context.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));\n                } catch (JSONException e) {\n                    Log.e(LOG_TAG, e.getMessage(), e);\n                    context.sendPluginResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));\n                } catch (Throwable t) {\n                    // Shouldn't happen, but will\n                    JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, conn, t);\n                    Log.e(LOG_TAG, error.toString(), t);\n                    context.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));\n                } finally {\n                    synchronized (activeRequests) {\n                        activeRequests.remove(objectId);\n                    }\n\n                    if (conn != null) {\n                        // Revert back to the proper verifier and socket factories\n                        // Revert back to the proper verifier and socket factories\n                        if (trustEveryone && useHttps) {\n                            HttpsURLConnection https = (HttpsURLConnection) conn;\n                            https.setHostnameVerifier(oldHostnameVerifier);\n                            https.setSSLSocketFactory(oldSocketFactory);\n                        }\n                    }\n                }\n            }\n        });\n    }\n\n    private static void safeClose(Closeable stream) {\n        if (stream != null) {\n            try {\n                stream.close();\n            } catch (IOException e) {\n            }\n        }\n    }\n\n    private static TrackingInputStream getInputStream(URLConnection conn) throws IOException {\n        String encoding = conn.getContentEncoding();\n        if (encoding != null && encoding.equalsIgnoreCase(\"gzip\")) {\n          return new TrackingGZIPInputStream(new ExposedGZIPInputStream(conn.getInputStream()));\n        }\n        return new SimpleTrackingInputStream(conn.getInputStream());\n    }\n\n    // always verify the host - don't check for certificate\n    private static final HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {\n        public boolean verify(String hostname, SSLSession session) {\n            return true;\n        }\n    };\n    // Create a trust manager that does not validate certificate chains\n    private static final TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {\n        public java.security.cert.X509Certificate[] getAcceptedIssuers() {\n            return new java.security.cert.X509Certificate[] {};\n        }\n\n        public void checkClientTrusted(X509Certificate[] chain,\n                String authType) throws CertificateException {\n        }\n\n        public void checkServerTrusted(X509Certificate[] chain,\n                String authType) throws CertificateException {\n        }\n    } };\n\n    /**\n     * This function will install a trust manager that will blindly trust all SSL\n     * certificates.  The reason this code is being added is to enable developers\n     * to do development using self signed SSL certificates on their web server.\n     *\n     * The standard HttpsURLConnection class will throw an exception on self\n     * signed certificates if this code is not run.\n     */\n    private static SSLSocketFactory trustAllHosts(HttpsURLConnection connection) {\n        // Install the all-trusting trust manager\n        SSLSocketFactory oldFactory = connection.getSSLSocketFactory();\n        try {\n            // Install our all trusting manager\n            SSLContext sc = SSLContext.getInstance(\"TLS\");\n            sc.init(null, trustAllCerts, new java.security.SecureRandom());\n            SSLSocketFactory newFactory = sc.getSocketFactory();\n            connection.setSSLSocketFactory(newFactory);\n        } catch (Exception e) {\n            Log.e(LOG_TAG, e.getMessage(), e);\n        }\n        return oldFactory;\n    }\n\n    private static JSONObject createFileTransferError(int errorCode, String source, String target, URLConnection connection, Throwable throwable) {\n\n        int httpStatus = 0;\n        StringBuilder bodyBuilder = new StringBuilder();\n        String body = null;\n        if (connection != null) {\n            try {\n                if (connection instanceof HttpURLConnection) {\n                    httpStatus = ((HttpURLConnection)connection).getResponseCode();\n                    InputStream err = ((HttpURLConnection) connection).getErrorStream();\n                    if(err != null)\n                    {\n                        BufferedReader reader = new BufferedReader(new InputStreamReader(err, \"UTF-8\"));\n                        try {\n                            String line = reader.readLine();\n                            while(line != null) {\n                                bodyBuilder.append(line);\n                                line = reader.readLine();\n                                if(line != null) {\n                                    bodyBuilder.append('\\n');\n                                }\n                            }\n                            body = bodyBuilder.toString();\n                        } finally {\n                            reader.close();\n                        }\n                    }\n                }\n            // IOException can leave connection object in a bad state, so catch all exceptions.\n            } catch (Throwable e) {\n                Log.w(LOG_TAG, \"Error getting HTTP status code from connection.\", e);\n            }\n        }\n\n        return createFileTransferError(errorCode, source, target, body, httpStatus, throwable);\n    }\n\n        /**\n        * Create an error object based on the passed in errorCode\n        * @param errorCode      the error\n        * @return JSONObject containing the error\n        */\n    private static JSONObject createFileTransferError(int errorCode, String source, String target, String body, Integer httpStatus, Throwable throwable) {\n        JSONObject error = null;\n        try {\n            error = new JSONObject();\n            error.put(\"code\", errorCode);\n            error.put(\"source\", source);\n            error.put(\"target\", target);\n            if(body != null)\n            {\n                error.put(\"body\", body);\n            }   \n            if (httpStatus != null) {\n                error.put(\"http_status\", httpStatus);\n            }\n            if (throwable != null) {\n                String msg = throwable.getMessage();\n                if (msg == null || \"\".equals(msg)) {\n                    msg = throwable.toString();\n                }\n                error.put(\"exception\", msg);\n            }\n        } catch (JSONException e) {\n            Log.e(LOG_TAG, e.getMessage(), e);\n        }\n        return error;\n    }\n\n    /**\n     * Convenience method to read a parameter from the list of JSON args.\n     * @param args                      the args passed to the Plugin\n     * @param position          the position to retrieve the arg from\n     * @param defaultString the default to be used if the arg does not exist\n     * @return String with the retrieved value\n     */\n    private static String getArgument(JSONArray args, int position, String defaultString) {\n        String arg = defaultString;\n        if (args.length() > position) {\n            arg = args.optString(position);\n            if (arg == null || \"null\".equals(arg)) {\n                arg = defaultString;\n            }\n        }\n        return arg;\n    }\n\n    /**\n     * Downloads a file form a given URL and saves it to the specified directory.\n     *\n     * @param source        URL of the server to receive the file\n     * @param target            Full path of the file on the file system\n     */\n    private void download(final String source, final String target, JSONArray args, CallbackContext callbackContext) throws JSONException {\n        Log.d(LOG_TAG, \"download \" + source + \" to \" +  target);\n\n        final CordovaResourceApi resourceApi = webView.getResourceApi();\n\n        final boolean trustEveryone = args.optBoolean(2);\n        final String objectId = args.getString(3);\n        final JSONObject headers = args.optJSONObject(4);\n\n        final Uri sourceUri = resourceApi.remapUri(Uri.parse(source));\n        // Accept a path or a URI for the source.\n        Uri tmpTarget = Uri.parse(target);\n        final Uri targetUri = resourceApi.remapUri(\n            tmpTarget.getScheme() != null ? tmpTarget : Uri.fromFile(new File(target)));\n\n        int uriType = CordovaResourceApi.getUriType(sourceUri);\n        final boolean useHttps = uriType == CordovaResourceApi.URI_TYPE_HTTPS;\n        final boolean isLocalTransfer = !useHttps && uriType != CordovaResourceApi.URI_TYPE_HTTP;\n        if (uriType == CordovaResourceApi.URI_TYPE_UNKNOWN) {\n            JSONObject error = createFileTransferError(INVALID_URL_ERR, source, target, null, 0, null);\n            Log.e(LOG_TAG, \"Unsupported URI: \" + sourceUri);\n            callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));\n            return;\n        }\n\n        /* This code exists for compatibility between 3.x and 4.x versions of Cordova.\n         * Previously the CordovaWebView class had a method, getWhitelist, which would\n         * return a Whitelist object. Since the fixed whitelist is removed in Cordova 4.x,\n         * the correct call now is to shouldAllowRequest from the plugin manager.\n         */\n        Boolean shouldAllowRequest = null;\n        if (isLocalTransfer) {\n            shouldAllowRequest = true;\n        }\n        if (shouldAllowRequest == null) {\n            try {\n                Method gwl = webView.getClass().getMethod(\"getWhitelist\");\n                Whitelist whitelist = (Whitelist)gwl.invoke(webView);\n                shouldAllowRequest = whitelist.isUrlWhiteListed(source);\n            } catch (NoSuchMethodException e) {\n            } catch (IllegalAccessException e) {\n            } catch (InvocationTargetException e) {\n            }\n        }\n        if (shouldAllowRequest == null) {\n            try {\n                Method gpm = webView.getClass().getMethod(\"getPluginManager\");\n                PluginManager pm = (PluginManager)gpm.invoke(webView);\n                Method san = pm.getClass().getMethod(\"shouldAllowRequest\", String.class);\n                shouldAllowRequest = (Boolean)san.invoke(pm, source);\n            } catch (NoSuchMethodException e) {\n            } catch (IllegalAccessException e) {\n            } catch (InvocationTargetException e) {\n            }\n        }\n\n        if (!Boolean.TRUE.equals(shouldAllowRequest)) {\n            Log.w(LOG_TAG, \"Source URL is not in white list: '\" + source + \"'\");\n            JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, null, 401, null);\n            callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));\n            return;\n        }\n\n\n        final RequestContext context = new RequestContext(source, target, callbackContext);\n        synchronized (activeRequests) {\n            activeRequests.put(objectId, context);\n        }\n\n        cordova.getThreadPool().execute(new Runnable() {\n            public void run() {\n                if (context.aborted) {\n                    return;\n                }\n                HttpURLConnection connection = null;\n                HostnameVerifier oldHostnameVerifier = null;\n                SSLSocketFactory oldSocketFactory = null;\n                File file = null;\n                PluginResult result = null;\n                TrackingInputStream inputStream = null;\n                boolean cached = false;\n\n                OutputStream outputStream = null;\n                try {\n                    OpenForReadResult readResult = null;\n\n                    file = resourceApi.mapUriToFile(targetUri);\n                    context.targetFile = file;\n\n                    Log.d(LOG_TAG, \"Download file:\" + sourceUri);\n\n                    FileProgressResult progress = new FileProgressResult();\n\n                    if (isLocalTransfer) {\n                        readResult = resourceApi.openForRead(sourceUri);\n                        if (readResult.length != -1) {\n                            progress.setLengthComputable(true);\n                            progress.setTotal(readResult.length);\n                        }\n                        inputStream = new SimpleTrackingInputStream(readResult.inputStream);\n                    } else {\n                        // connect to server\n                        // Open a HTTP connection to the URL based on protocol\n                        connection = resourceApi.createHttpConnection(sourceUri);\n                        if (useHttps && trustEveryone) {\n                            // Setup the HTTPS connection class to trust everyone\n                            HttpsURLConnection https = (HttpsURLConnection)connection;\n                            oldSocketFactory = trustAllHosts(https);\n                            // Save the current hostnameVerifier\n                            oldHostnameVerifier = https.getHostnameVerifier();\n                            // Setup the connection not to verify hostnames\n                            https.setHostnameVerifier(DO_NOT_VERIFY);\n                        }\n\n                        connection.setRequestMethod(\"GET\");\n\n                        // TODO: Make OkHttp use this CookieManager by default.\n                        String cookie = getCookies(sourceUri.toString());\n\n                        if(cookie != null)\n                        {\n                            connection.setRequestProperty(\"cookie\", cookie);\n                        }\n\n                        // This must be explicitly set for gzip progress tracking to work.\n                        connection.setRequestProperty(\"Accept-Encoding\", \"gzip\");\n\n                        // Handle the other headers\n                        if (headers != null) {\n                            addHeadersToRequest(connection, headers);\n                        }\n\n                        connection.connect();\n                        if (connection.getResponseCode() == HttpURLConnection.HTTP_NOT_MODIFIED) {\n                            cached = true;\n                            connection.disconnect();\n                            Log.d(LOG_TAG, \"Resource not modified: \" + source);\n                            JSONObject error = createFileTransferError(NOT_MODIFIED_ERR, source, target, connection, null);\n                            result = new PluginResult(PluginResult.Status.ERROR, error);\n                        } else {\n                            if (connection.getContentEncoding() == null || connection.getContentEncoding().equalsIgnoreCase(\"gzip\")) {\n                                // Only trust content-length header if we understand\n                                // the encoding -- identity or gzip\n                                if (connection.getContentLength() != -1) {\n                                    progress.setLengthComputable(true);\n                                    progress.setTotal(connection.getContentLength());\n                                }\n                            }\n                            inputStream = getInputStream(connection);\n                        }\n                    }\n\n                    if (!cached) {\n                        try {\n                            synchronized (context) {\n                                if (context.aborted) {\n                                    return;\n                                }\n                                context.connection = connection;\n                            }\n\n                            // write bytes to file\n                            byte[] buffer = new byte[MAX_BUFFER_SIZE];\n                            int bytesRead = 0;\n                            outputStream = resourceApi.openOutputStream(targetUri);\n                            while ((bytesRead = inputStream.read(buffer)) > 0) {\n                                outputStream.write(buffer, 0, bytesRead);\n                                // Send a progress event.\n                                progress.setLoaded(inputStream.getTotalRawBytesRead());\n                                PluginResult progressResult = new PluginResult(PluginResult.Status.OK, progress.toJSONObject());\n                                progressResult.setKeepCallback(true);\n                                context.sendPluginResult(progressResult);\n                            }\n                        } finally {\n                            synchronized (context) {\n                                context.connection = null;\n                            }\n                            safeClose(inputStream);\n                            safeClose(outputStream);\n                        }\n\n                        Log.d(LOG_TAG, \"Saved file: \" + target);\n\n\n                        // create FileEntry object\n                        Class webViewClass = webView.getClass();\n                        PluginManager pm = null;\n                        try {\n                            Method gpm = webViewClass.getMethod(\"getPluginManager\");\n                            pm = (PluginManager) gpm.invoke(webView);\n                        } catch (NoSuchMethodException e) {\n                        } catch (IllegalAccessException e) {\n                        } catch (InvocationTargetException e) {\n                        }\n                        if (pm == null) {\n                            try {\n                                Field pmf = webViewClass.getField(\"pluginManager\");\n                                pm = (PluginManager)pmf.get(webView);\n                            } catch (NoSuchFieldException e) {\n                            } catch (IllegalAccessException e) {\n                            }\n                        }\n                        file = resourceApi.mapUriToFile(targetUri);\n                        context.targetFile = file;\n                        FileUtils filePlugin = (FileUtils) pm.getPlugin(\"File\");\n                        if (filePlugin != null) {\n                            JSONObject fileEntry = filePlugin.getEntryForFile(file);\n                            if (fileEntry != null) {\n                                result = new PluginResult(PluginResult.Status.OK, fileEntry);\n                            } else {\n                                JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, connection, null);\n                                Log.e(LOG_TAG, \"File plugin cannot represent download path\");\n                                result = new PluginResult(PluginResult.Status.IO_EXCEPTION, error);\n                            }\n                        } else {\n                            Log.e(LOG_TAG, \"File plugin not found; cannot save downloaded file\");\n                            result = new PluginResult(PluginResult.Status.ERROR, \"File plugin not found; cannot save downloaded file\");\n                        }\n                    }\n                } catch (FileNotFoundException e) {\n                    JSONObject error = createFileTransferError(FILE_NOT_FOUND_ERR, source, target, connection, e);\n                    Log.e(LOG_TAG, error.toString(), e);\n                    result = new PluginResult(PluginResult.Status.IO_EXCEPTION, error);\n                } catch (IOException e) {\n                    JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, connection, e);\n                    Log.e(LOG_TAG, error.toString(), e);\n                    result = new PluginResult(PluginResult.Status.IO_EXCEPTION, error);\n                } catch (JSONException e) {\n                    Log.e(LOG_TAG, e.getMessage(), e);\n                    result = new PluginResult(PluginResult.Status.JSON_EXCEPTION);\n                } catch (Throwable e) {\n                    JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, connection, e);\n                    Log.e(LOG_TAG, error.toString(), e);\n                    result = new PluginResult(PluginResult.Status.IO_EXCEPTION, error);\n                } finally {\n                    synchronized (activeRequests) {\n                        activeRequests.remove(objectId);\n                    }\n\n                    if (connection != null) {\n                        // Revert back to the proper verifier and socket factories\n                        if (trustEveryone && useHttps) {\n                            HttpsURLConnection https = (HttpsURLConnection) connection;\n                            https.setHostnameVerifier(oldHostnameVerifier);\n                            https.setSSLSocketFactory(oldSocketFactory);\n                        }\n                    }\n\n                    if (result == null) {\n                        result = new PluginResult(PluginResult.Status.ERROR, createFileTransferError(CONNECTION_ERR, source, target, connection, null));\n                    }\n                    // Remove incomplete download.\n                    if (!cached && result.getStatus() != PluginResult.Status.OK.ordinal() && file != null) {\n                        file.delete();\n                    }\n                    context.sendPluginResult(result);\n                }\n            }\n        });\n    }\n\n    /**\n     * Abort an ongoing upload or download.\n     */\n    private void abort(String objectId) {\n        final RequestContext context;\n        synchronized (activeRequests) {\n            context = activeRequests.remove(objectId);\n        }\n        if (context != null) {\n            // Closing the streams can block, so execute on a background thread.\n            cordova.getThreadPool().execute(new Runnable() {\n                public void run() {\n                    synchronized (context) {\n                        File file = context.targetFile;\n                        if (file != null) {\n                            file.delete();\n                        }\n                        // Trigger the abort callback immediately to minimize latency between it and abort() being called.\n                        JSONObject error = createFileTransferError(ABORTED_ERR, context.source, context.target, null, -1, null);\n                        context.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, error));\n                        context.aborted = true;\n                        if (context.connection != null) {\n                            try {\n                                context.connection.disconnect();\n                            } catch (Exception e) {\n                                Log.e(LOG_TAG, \"CB-8431 Catch workaround for fatal exception\", e);\n                            }\n                        }\n                    }\n                }\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/src/android/FileUploadResult.java",
    "content": "/*\n       Licensed to the Apache Software Foundation (ASF) under one\n       or more contributor license agreements.  See the NOTICE file\n       distributed with this work for additional information\n       regarding copyright ownership.  The ASF licenses this file\n       to you under the Apache License, Version 2.0 (the\n       \"License\"); you may not use this file except in compliance\n       with the License.  You may obtain a copy of the License at\n\n         http://www.apache.org/licenses/LICENSE-2.0\n\n       Unless required by applicable law or agreed to in writing,\n       software distributed under the License is distributed on an\n       \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n       KIND, either express or implied.  See the License for the\n       specific language governing permissions and limitations\n       under the License.\n*/\npackage org.apache.cordova.filetransfer;\n\nimport org.json.JSONException;\nimport org.json.JSONObject;\n\n/**\n * Encapsulates the result and/or status of uploading a file to a remote server.\n */\npublic class FileUploadResult {\n\n    private long bytesSent = 0;         // bytes sent\n    private int responseCode = -1;      // HTTP response code\n    private String response = null;     // HTTP response\n    private String objectId = null;     // FileTransfer object id\n\n    public long getBytesSent() {\n        return bytesSent;\n    }\n\n    public void setBytesSent(long bytes) {\n        this.bytesSent = bytes;\n    }\n\n    public int getResponseCode() {\n        return responseCode;\n    }\n\n    public void setResponseCode(int responseCode) {\n        this.responseCode = responseCode;\n    }\n\n    public String getResponse() {\n        return response;\n    }\n\n    public void setResponse(String response) {\n        this.response = response;\n    }\n\n    public String getObjectId() {\n        return objectId;\n    }\n\n    public void setObjectId(String objectId) {\n        this.objectId = objectId;\n    }\n\n    public JSONObject toJSONObject() throws JSONException {\n        return new JSONObject(\n                \"{bytesSent:\" + bytesSent +\n                \",responseCode:\" + responseCode +\n                \",response:\" + JSONObject.quote(response) +\n                \",objectId:\" + JSONObject.quote(objectId) + \"}\");\n    }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/src/ios/CDVFileTransfer.h",
    "content": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements.  See the NOTICE file\n distributed with this work for additional information\n regarding copyright ownership.  The ASF licenses this file\n to you under the Apache License, Version 2.0 (the\n \"License\"); you may not use this file except in compliance\n with the License.  You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an\n \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n KIND, either express or implied.  See the License for the\n specific language governing permissions and limitations\n under the License.\n */\n\n#import <Foundation/Foundation.h>\n#import <Cordova/CDVPlugin.h>\n#import \"CDVFile.h\"\n\nenum CDVFileTransferError {\n    FILE_NOT_FOUND_ERR = 1,\n    INVALID_URL_ERR = 2,\n    CONNECTION_ERR = 3,\n    CONNECTION_ABORTED = 4,\n    NOT_MODIFIED = 5\n};\ntypedef int CDVFileTransferError;\n\nenum CDVFileTransferDirection {\n    CDV_TRANSFER_UPLOAD = 1,\n    CDV_TRANSFER_DOWNLOAD = 2,\n};\ntypedef int CDVFileTransferDirection;\n\n// Magic value within the options dict used to set a cookie.\nextern NSString* const kOptionsKeyCookie;\n\n@interface CDVFileTransfer : CDVPlugin {}\n\n- (void)upload:(CDVInvokedUrlCommand*)command;\n- (void)download:(CDVInvokedUrlCommand*)command;\n- (NSString*)escapePathComponentForUrlString:(NSString*)urlString;\n\n// Visible for testing.\n- (NSURLRequest*)requestForUploadCommand:(CDVInvokedUrlCommand*)command fileData:(NSData*)fileData;\n- (NSMutableDictionary*)createFileTransferError:(int)code AndSource:(NSString*)source AndTarget:(NSString*)target;\n\n- (NSMutableDictionary*)createFileTransferError:(int)code\n                                      AndSource:(NSString*)source\n                                      AndTarget:(NSString*)target\n                                  AndHttpStatus:(int)httpStatus\n                                        AndBody:(NSString*)body;\n@property (nonatomic, strong) NSOperationQueue* queue;\n@property (readonly) NSMutableDictionary* activeTransfers;\n@end\n\n@class CDVFileTransferEntityLengthRequest;\n\n@interface CDVFileTransferDelegate : NSObject {}\n\n- (void)updateBytesExpected:(long long)newBytesExpected;\n- (void)cancelTransfer:(NSURLConnection*)connection;\n\n@property (strong) NSMutableData* responseData; // atomic\n@property (nonatomic, strong) NSDictionary* responseHeaders;\n@property (nonatomic, assign) UIBackgroundTaskIdentifier backgroundTaskID;\n@property (nonatomic, strong) CDVFileTransfer* command;\n@property (nonatomic, assign) CDVFileTransferDirection direction;\n@property (nonatomic, strong) NSURLConnection* connection;\n@property (nonatomic, copy) NSString* callbackId;\n@property (nonatomic, copy) NSString* objectId;\n@property (nonatomic, copy) NSString* source;\n@property (nonatomic, copy) NSString* target;\n@property (nonatomic, copy) NSURL* targetURL;\n@property (nonatomic, copy) NSString* mimeType;\n@property (assign) int responseCode; // atomic\n@property (nonatomic, assign) long long bytesTransfered;\n@property (nonatomic, assign) long long bytesExpected;\n@property (nonatomic, assign) BOOL trustAllHosts;\n@property (strong) NSFileHandle* targetFileHandle;\n@property (nonatomic, strong) CDVFileTransferEntityLengthRequest* entityLengthRequest;\n@property (nonatomic, strong) CDVFile *filePlugin;\n\n@end\n"
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/src/ios/CDVFileTransfer.m",
    "content": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements.  See the NOTICE file\n distributed with this work for additional information\n regarding copyright ownership.  The ASF licenses this file\n to you under the Apache License, Version 2.0 (the\n \"License\"); you may not use this file except in compliance\n with the License.  You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an\n \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n KIND, either express or implied.  See the License for the\n specific language governing permissions and limitations\n under the License.\n */\n\n#import <Cordova/CDV.h>\n#import \"CDVFileTransfer.h\"\n#import \"CDVLocalFilesystem.h\"\n\n#import <AssetsLibrary/ALAsset.h>\n#import <AssetsLibrary/ALAssetRepresentation.h>\n#import <AssetsLibrary/ALAssetsLibrary.h>\n#import <CFNetwork/CFNetwork.h>\n\n#ifndef DLog\n#ifdef DEBUG\n    #define DLog(fmt, ...) NSLog((@\"%s [Line %d] \" fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__)\n#else\n    #define DLog(...)\n#endif\n#endif\n\n@interface CDVFileTransfer ()\n// Sets the requests headers for the request.\n- (void)applyRequestHeaders:(NSDictionary*)headers toRequest:(NSMutableURLRequest*)req;\n// Creates a delegate to handle an upload.\n- (CDVFileTransferDelegate*)delegateForUploadCommand:(CDVInvokedUrlCommand*)command;\n// Creates an NSData* for the file for the given upload arguments.\n- (void)fileDataForUploadCommand:(CDVInvokedUrlCommand*)command;\n@end\n\n// Buffer size to use for streaming uploads.\nstatic const NSUInteger kStreamBufferSize = 32768;\n// Magic value within the options dict used to set a cookie.\nNSString* const kOptionsKeyCookie = @\"__cookie\";\n// Form boundary for multi-part requests.\nNSString* const kFormBoundary = @\"+++++org.apache.cordova.formBoundary\";\n\n// Writes the given data to the stream in a blocking way.\n// If successful, returns bytesToWrite.\n// If the stream was closed on the other end, returns 0.\n// If there was an error, returns -1.\nstatic CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)\n{\n    UInt8* bytes = (UInt8*)[data bytes];\n    long long bytesToWrite = [data length];\n    long long totalBytesWritten = 0;\n\n    while (totalBytesWritten < bytesToWrite) {\n        CFIndex result = CFWriteStreamWrite(stream,\n                bytes + totalBytesWritten,\n                bytesToWrite - totalBytesWritten);\n        if (result < 0) {\n            CFStreamError error = CFWriteStreamGetError(stream);\n            NSLog(@\"WriteStreamError domain: %ld error: %ld\", error.domain, (long)error.error);\n            return result;\n        } else if (result == 0) {\n            return result;\n        }\n        totalBytesWritten += result;\n    }\n\n    return totalBytesWritten;\n}\n\n@implementation CDVFileTransfer\n@synthesize activeTransfers;\n\n- (void)pluginInitialize {\n    activeTransfers = [[NSMutableDictionary alloc] init];\n}\n\n- (NSString*)escapePathComponentForUrlString:(NSString*)urlString\n{\n    NSRange schemeAndHostRange = [urlString rangeOfString:@\"://.*?/\" options:NSRegularExpressionSearch];\n\n    if (schemeAndHostRange.length == 0) {\n        return urlString;\n    }\n\n    NSInteger schemeAndHostEndIndex = NSMaxRange(schemeAndHostRange);\n    NSString* schemeAndHost = [urlString substringToIndex:schemeAndHostEndIndex];\n    NSString* pathComponent = [urlString substringFromIndex:schemeAndHostEndIndex];\n    pathComponent = [pathComponent stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];\n\n    return [schemeAndHost stringByAppendingString:pathComponent];\n}\n\n- (void)applyRequestHeaders:(NSDictionary*)headers toRequest:(NSMutableURLRequest*)req\n{\n    [req setValue:@\"XMLHttpRequest\" forHTTPHeaderField:@\"X-Requested-With\"];\n\n    NSString* userAgent = [self.commandDelegate userAgent];\n    if (userAgent) {\n        [req setValue:userAgent forHTTPHeaderField:@\"User-Agent\"];\n    }\n\n    for (NSString* headerName in headers) {\n        id value = [headers objectForKey:headerName];\n        if (!value || (value == [NSNull null])) {\n            value = @\"null\";\n        }\n\n        // First, remove an existing header if one exists.\n        [req setValue:nil forHTTPHeaderField:headerName];\n\n        if (![value isKindOfClass:[NSArray class]]) {\n            value = [NSArray arrayWithObject:value];\n        }\n\n        // Then, append all header values.\n        for (id __strong subValue in value) {\n            // Convert from an NSNumber -> NSString.\n            if ([subValue respondsToSelector:@selector(stringValue)]) {\n                subValue = [subValue stringValue];\n            }\n            if ([subValue isKindOfClass:[NSString class]]) {\n                [req addValue:subValue forHTTPHeaderField:headerName];\n            }\n        }\n    }\n}\n\n- (NSURLRequest*)requestForUploadCommand:(CDVInvokedUrlCommand*)command fileData:(NSData*)fileData\n{\n    // arguments order from js: [filePath, server, fileKey, fileName, mimeType, params, debug, chunkedMode]\n    // however, params is a JavaScript object and during marshalling is put into the options dict,\n    // thus debug and chunkedMode are the 6th and 7th arguments\n    NSString* target = [command argumentAtIndex:0];\n    NSString* server = [command argumentAtIndex:1];\n    NSString* fileKey = [command argumentAtIndex:2 withDefault:@\"file\"];\n    NSString* fileName = [command argumentAtIndex:3 withDefault:@\"image.jpg\"];\n    NSString* mimeType = [command argumentAtIndex:4 withDefault:@\"image/jpeg\"];\n    NSDictionary* options = [command argumentAtIndex:5 withDefault:nil];\n    //    BOOL trustAllHosts = [[command argumentAtIndex:6 withDefault:[NSNumber numberWithBool:YES]] boolValue]; // allow self-signed certs\n    BOOL chunkedMode = [[command argumentAtIndex:7 withDefault:[NSNumber numberWithBool:YES]] boolValue];\n    NSDictionary* headers = [command argumentAtIndex:8 withDefault:nil];\n    // Allow alternative http method, default to POST. JS side checks\n    // for allowed methods, currently PUT or POST (forces POST for\n    // unrecognised values)\n    NSString* httpMethod = [command argumentAtIndex:10 withDefault:@\"POST\"];\n    CDVPluginResult* result = nil;\n    CDVFileTransferError errorCode = 0;\n\n    // NSURL does not accepts URLs with spaces in the path. We escape the path in order\n    // to be more lenient.\n    NSURL* url = [NSURL URLWithString:server];\n\n    if (!url) {\n        errorCode = INVALID_URL_ERR;\n        NSLog(@\"File Transfer Error: Invalid server URL %@\", server);\n    } else if (!fileData) {\n        errorCode = FILE_NOT_FOUND_ERR;\n    }\n\n    if (errorCode > 0) {\n        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[self createFileTransferError:errorCode AndSource:target AndTarget:server]];\n        [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n        return nil;\n    }\n\n    NSMutableURLRequest* req = [NSMutableURLRequest requestWithURL:url];\n\n    [req setHTTPMethod:httpMethod];\n\n    //    Magic value to set a cookie\n    if ([options objectForKey:kOptionsKeyCookie]) {\n        [req setValue:[options objectForKey:kOptionsKeyCookie] forHTTPHeaderField:@\"Cookie\"];\n        [req setHTTPShouldHandleCookies:NO];\n    }\n\n    // if we specified a Content-Type header, don't do multipart form upload\n    BOOL multipartFormUpload = [headers objectForKey:@\"Content-Type\"] == nil;\n    if (multipartFormUpload) {\n        NSString* contentType = [NSString stringWithFormat:@\"multipart/form-data; boundary=%@\", kFormBoundary];\n        [req setValue:contentType forHTTPHeaderField:@\"Content-Type\"];\n    }\n    [self applyRequestHeaders:headers toRequest:req];\n\n    NSData* formBoundaryData = [[NSString stringWithFormat:@\"--%@\\r\\n\", kFormBoundary] dataUsingEncoding:NSUTF8StringEncoding];\n    NSMutableData* postBodyBeforeFile = [NSMutableData data];\n\n    for (NSString* key in options) {\n        id val = [options objectForKey:key];\n        if (!val || (val == [NSNull null]) || [key isEqualToString:kOptionsKeyCookie]) {\n            continue;\n        }\n        // if it responds to stringValue selector (eg NSNumber) get the NSString\n        if ([val respondsToSelector:@selector(stringValue)]) {\n            val = [val stringValue];\n        }\n        // finally, check whether it is a NSString (for dataUsingEncoding selector below)\n        if (![val isKindOfClass:[NSString class]]) {\n            continue;\n        }\n\n        [postBodyBeforeFile appendData:formBoundaryData];\n        [postBodyBeforeFile appendData:[[NSString stringWithFormat:@\"Content-Disposition: form-data; name=\\\"%@\\\"\\r\\n\\r\\n\", key] dataUsingEncoding:NSUTF8StringEncoding]];\n        [postBodyBeforeFile appendData:[val dataUsingEncoding:NSUTF8StringEncoding]];\n        [postBodyBeforeFile appendData:[@\"\\r\\n\" dataUsingEncoding : NSUTF8StringEncoding]];\n    }\n\n    [postBodyBeforeFile appendData:formBoundaryData];\n    [postBodyBeforeFile appendData:[[NSString stringWithFormat:@\"Content-Disposition: form-data; name=\\\"%@\\\"; filename=\\\"%@\\\"\\r\\n\", fileKey, fileName] dataUsingEncoding:NSUTF8StringEncoding]];\n    if (mimeType != nil) {\n        [postBodyBeforeFile appendData:[[NSString stringWithFormat:@\"Content-Type: %@\\r\\n\", mimeType] dataUsingEncoding:NSUTF8StringEncoding]];\n    }\n    [postBodyBeforeFile appendData:[[NSString stringWithFormat:@\"Content-Length: %ld\\r\\n\\r\\n\", (long)[fileData length]] dataUsingEncoding:NSUTF8StringEncoding]];\n\n    DLog(@\"fileData length: %d\", [fileData length]);\n    NSData* postBodyAfterFile = [[NSString stringWithFormat:@\"\\r\\n--%@--\\r\\n\", kFormBoundary] dataUsingEncoding:NSUTF8StringEncoding];\n\n    long long totalPayloadLength = [fileData length];\n    if (multipartFormUpload) {\n        totalPayloadLength += [postBodyBeforeFile length] + [postBodyAfterFile length];\n    }\n\n    [req setValue:[[NSNumber numberWithLongLong:totalPayloadLength] stringValue] forHTTPHeaderField:@\"Content-Length\"];\n\n    if (chunkedMode) {\n        CFReadStreamRef readStream = NULL;\n        CFWriteStreamRef writeStream = NULL;\n        CFStreamCreateBoundPair(NULL, &readStream, &writeStream, kStreamBufferSize);\n        [req setHTTPBodyStream:CFBridgingRelease(readStream)];\n\n        [self.commandDelegate runInBackground:^{\n            if (CFWriteStreamOpen(writeStream)) {\n                if (multipartFormUpload) {\n                    NSData* chunks[] = { postBodyBeforeFile, fileData, postBodyAfterFile };\n                    int numChunks = sizeof(chunks) / sizeof(chunks[0]);\n\n                    for (int i = 0; i < numChunks; ++i) {\n                        // Allow uploading of an empty file\n                        if (chunks[i].length == 0) {\n                            continue;\n                        }\n\n                        CFIndex result = WriteDataToStream(chunks[i], writeStream);\n                        if (result <= 0) {\n                            break;\n                        }\n                    }\n                } else {\n                    WriteDataToStream(fileData, writeStream);\n                }\n            } else {\n                NSLog(@\"FileTransfer: Failed to open writeStream\");\n            }\n            CFWriteStreamClose(writeStream);\n            CFRelease(writeStream);\n        }];\n    } else {\n        if (multipartFormUpload) {\n            [postBodyBeforeFile appendData:fileData];\n            [postBodyBeforeFile appendData:postBodyAfterFile];\n            [req setHTTPBody:postBodyBeforeFile];\n        } else {\n            [req setHTTPBody:fileData];\n        }\n    }\n    return req;\n}\n\n- (CDVFileTransferDelegate*)delegateForUploadCommand:(CDVInvokedUrlCommand*)command\n{\n    NSString* source = [command argumentAtIndex:0];\n    NSString* server = [command argumentAtIndex:1];\n    BOOL trustAllHosts = [[command argumentAtIndex:6 withDefault:[NSNumber numberWithBool:NO]] boolValue]; // allow self-signed certs\n    NSString* objectId = [command argumentAtIndex:9];\n\n    CDVFileTransferDelegate* delegate = [[CDVFileTransferDelegate alloc] init];\n\n    delegate.command = self;\n    delegate.callbackId = command.callbackId;\n    delegate.direction = CDV_TRANSFER_UPLOAD;\n    delegate.objectId = objectId;\n    delegate.source = source;\n    delegate.target = server;\n    delegate.trustAllHosts = trustAllHosts;\n    delegate.filePlugin = [self.commandDelegate getCommandInstance:@\"File\"];\n\n    return delegate;\n}\n\n- (void)fileDataForUploadCommand:(CDVInvokedUrlCommand*)command\n{\n    NSString* source = (NSString*)[command argumentAtIndex:0];\n    NSString* server = [command argumentAtIndex:1];\n    NSError* __autoreleasing err = nil;\n\n    if ([source hasPrefix:@\"data:\"] && [source rangeOfString:@\"base64\"].location != NSNotFound) {\n        NSRange commaRange = [source rangeOfString: @\",\"];\n        if (commaRange.location == NSNotFound) {\n            // Return error is there is no comma\n            __weak CDVFileTransfer* weakSelf = self;\n            CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[weakSelf createFileTransferError:INVALID_URL_ERR AndSource:source AndTarget:server]];\n            [weakSelf.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n            return;\n        }\n\n        if (commaRange.location + 1 > source.length - 1) {\n            // Init as an empty data\n            NSData *fileData = [[NSData alloc] init];\n            [self uploadData:fileData command:command];\n            return;\n        }\n\n        NSData *fileData = [[NSData alloc] initWithBase64EncodedString:[source substringFromIndex:(commaRange.location + 1)] options:NSDataBase64DecodingIgnoreUnknownCharacters];\n        [self uploadData:fileData command:command];\n        return;\n    }\n\n    CDVFilesystemURL *sourceURL = [CDVFilesystemURL fileSystemURLWithString:source];\n    NSObject<CDVFileSystem> *fs;\n    if (sourceURL) {\n        // Try to get a CDVFileSystem which will handle this file.\n        // This requires talking to the current CDVFile plugin.\n        fs = [[self.commandDelegate getCommandInstance:@\"File\"] filesystemForURL:sourceURL];\n    }\n    if (fs) {\n        __weak CDVFileTransfer* weakSelf = self;\n        [fs readFileAtURL:sourceURL start:0 end:-1 callback:^(NSData *fileData, NSString *mimeType, CDVFileError err) {\n            if (err) {\n                // We couldn't find the asset.  Send the appropriate error.\n                CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[weakSelf createFileTransferError:NOT_FOUND_ERR AndSource:source AndTarget:server]];\n                [weakSelf.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n            }  else {\n                [weakSelf uploadData:fileData command:command];\n            }\n        }];\n        return;\n    } else {\n        // Extract the path part out of a file: URL.\n        NSString* filePath = [source hasPrefix:@\"/\"] ? [source copy] : [(NSURL *)[NSURL URLWithString:source] path];\n        if (filePath == nil) {\n            // We couldn't find the asset.  Send the appropriate error.\n            CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[self createFileTransferError:NOT_FOUND_ERR AndSource:source AndTarget:server]];\n            [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n            return;\n        }\n\n        // Memory map the file so that it can be read efficiently even if it is large.\n        NSData* fileData = [NSData dataWithContentsOfFile:filePath options:NSDataReadingMappedIfSafe error:&err];\n\n        if (err != nil) {\n            NSLog(@\"Error opening file %@: %@\", source, err);\n            CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[self createFileTransferError:NOT_FOUND_ERR AndSource:source AndTarget:server]];\n            [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n        } else {\n            [self uploadData:fileData command:command];\n        }\n    }\n}\n\n- (void)upload:(CDVInvokedUrlCommand*)command\n{\n    // fileData and req are split into helper functions to ease the unit testing of delegateForUpload.\n    // First, get the file data.  This method will call `uploadData:command`.\n    [self fileDataForUploadCommand:command];\n}\n\n- (void)uploadData:(NSData*)fileData command:(CDVInvokedUrlCommand*)command\n{\n    NSURLRequest* req = [self requestForUploadCommand:command fileData:fileData];\n\n    if (req == nil) {\n        return;\n    }\n    CDVFileTransferDelegate* delegate = [self delegateForUploadCommand:command];\n    delegate.connection = [[NSURLConnection alloc] initWithRequest:req delegate:delegate startImmediately:NO];\n    if (self.queue == nil) {\n        self.queue = [[NSOperationQueue alloc] init];\n    }\n    [delegate.connection setDelegateQueue:self.queue];\n\n    // sets a background task ID for the transfer object.\n    delegate.backgroundTaskID = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{\n        [delegate cancelTransfer:delegate.connection];\n    }];\n\n    @synchronized (activeTransfers) {\n        activeTransfers[delegate.objectId] = delegate;\n    }\n    [delegate.connection start];\n}\n\n- (void)abort:(CDVInvokedUrlCommand*)command\n{\n    NSString* objectId = [command argumentAtIndex:0];\n\n    @synchronized (activeTransfers) {\n        CDVFileTransferDelegate* delegate = activeTransfers[objectId];\n        if (delegate != nil) {\n            [delegate cancelTransfer:delegate.connection];\n            CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[self createFileTransferError:CONNECTION_ABORTED AndSource:delegate.source AndTarget:delegate.target]];\n            [self.commandDelegate sendPluginResult:result callbackId:delegate.callbackId];\n        }\n    }\n}\n\n- (void)download:(CDVInvokedUrlCommand*)command\n{\n    DLog(@\"File Transfer downloading file...\");\n    NSString* source = [command argumentAtIndex:0];\n    NSString* target = [command argumentAtIndex:1];\n    BOOL trustAllHosts = [[command argumentAtIndex:2 withDefault:[NSNumber numberWithBool:NO]] boolValue]; // allow self-signed certs\n    NSString* objectId = [command argumentAtIndex:3];\n    NSDictionary* headers = [command argumentAtIndex:4 withDefault:nil];\n\n    CDVPluginResult* result = nil;\n    CDVFileTransferError errorCode = 0;\n\n    NSURL* targetURL;\n\n    if ([target hasPrefix:@\"/\"]) {\n        /* Backwards-compatibility:\n         * Check here to see if it looks like the user passed in a raw filesystem path. (Perhaps they had the path saved, and were previously using it with the old version of File). If so, normalize it by removing empty path segments, and check with File to see if any of the installed filesystems will handle it. If so, then we will end up with a filesystem url to use for the remainder of this operation.\n         */\n        target = [target stringByReplacingOccurrencesOfString:@\"//\" withString:@\"/\"];\n        targetURL = [[self.commandDelegate getCommandInstance:@\"File\"] fileSystemURLforLocalPath:target].url;\n    } else {\n        targetURL = [NSURL URLWithString:target];\n    }\n\n    NSURL* sourceURL = [NSURL URLWithString:source];\n\n    if (!sourceURL) {\n        errorCode = INVALID_URL_ERR;\n        NSLog(@\"File Transfer Error: Invalid server URL %@\", source);\n    } else if (![targetURL isFileURL]) {\n        CDVFilesystemURL *fsURL = [CDVFilesystemURL fileSystemURLWithString:target];\n        if (!fsURL) {\n           errorCode = FILE_NOT_FOUND_ERR;\n           NSLog(@\"File Transfer Error: Invalid file path or URL %@\", target);\n        }\n    }\n\n    if (errorCode > 0) {\n        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[self createFileTransferError:errorCode AndSource:source AndTarget:target]];\n        [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];\n        return;\n    }\n\n    NSMutableURLRequest* req = [NSMutableURLRequest requestWithURL:sourceURL];\n    [self applyRequestHeaders:headers toRequest:req];\n\n    CDVFileTransferDelegate* delegate = [[CDVFileTransferDelegate alloc] init];\n    delegate.command = self;\n    delegate.direction = CDV_TRANSFER_DOWNLOAD;\n    delegate.callbackId = command.callbackId;\n    delegate.objectId = objectId;\n    delegate.source = source;\n    delegate.target = [targetURL absoluteString];\n    delegate.targetURL = targetURL;\n    delegate.trustAllHosts = trustAllHosts;\n    delegate.filePlugin = [self.commandDelegate getCommandInstance:@\"File\"];\n    delegate.backgroundTaskID = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{\n        [delegate cancelTransfer:delegate.connection];\n    }];\n\n    delegate.connection = [[NSURLConnection alloc] initWithRequest:req delegate:delegate startImmediately:NO];\n\n    if (self.queue == nil) {\n        self.queue = [[NSOperationQueue alloc] init];\n    }\n    [delegate.connection setDelegateQueue:self.queue];\n\n    @synchronized (activeTransfers) {\n        activeTransfers[delegate.objectId] = delegate;\n    }\n    // Downloads can take time\n    // sending this to a new thread calling the download_async method\n    dispatch_async(\n                   dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, (unsigned long)NULL),\n                   ^(void) { [delegate.connection start];}\n                   );\n}\n\n- (NSMutableDictionary*)createFileTransferError:(int)code AndSource:(NSString*)source AndTarget:(NSString*)target\n{\n    NSMutableDictionary* result = [NSMutableDictionary dictionaryWithCapacity:3];\n\n    [result setObject:[NSNumber numberWithInt:code] forKey:@\"code\"];\n    if (source != nil) {\n        [result setObject:source forKey:@\"source\"];\n    }\n    if (target != nil) {\n        [result setObject:target forKey:@\"target\"];\n    }\n    NSLog(@\"FileTransferError %@\", result);\n\n    return result;\n}\n\n- (NSMutableDictionary*)createFileTransferError:(int)code\n                                      AndSource:(NSString*)source\n                                      AndTarget:(NSString*)target\n                                  AndHttpStatus:(int)httpStatus\n                                        AndBody:(NSString*)body\n{\n    NSMutableDictionary* result = [NSMutableDictionary dictionaryWithCapacity:5];\n\n    [result setObject:[NSNumber numberWithInt:code] forKey:@\"code\"];\n    if (source != nil) {\n        [result setObject:source forKey:@\"source\"];\n    }\n    if (target != nil) {\n        [result setObject:target forKey:@\"target\"];\n    }\n    [result setObject:[NSNumber numberWithInt:httpStatus] forKey:@\"http_status\"];\n    if (body != nil) {\n        [result setObject:body forKey:@\"body\"];\n    }\n    NSLog(@\"FileTransferError %@\", result);\n\n    return result;\n}\n\n- (void)onReset {\n    @synchronized (activeTransfers) {\n        while ([activeTransfers count] > 0) {\n            CDVFileTransferDelegate* delegate = [activeTransfers allValues][0];\n            [delegate cancelTransfer:delegate.connection];\n        }\n    }\n}\n\n@end\n\n@interface CDVFileTransferEntityLengthRequest : NSObject {\n    NSURLConnection* _connection;\n    CDVFileTransferDelegate* __weak _originalDelegate;\n}\n\n- (CDVFileTransferEntityLengthRequest*)initWithOriginalRequest:(NSURLRequest*)originalRequest andDelegate:(CDVFileTransferDelegate*)originalDelegate;\n\n@end\n\n@implementation CDVFileTransferEntityLengthRequest\n\n- (CDVFileTransferEntityLengthRequest*)initWithOriginalRequest:(NSURLRequest*)originalRequest andDelegate:(CDVFileTransferDelegate*)originalDelegate\n{\n    if (self) {\n        DLog(@\"Requesting entity length for GZIPped content...\");\n\n        NSMutableURLRequest* req = [originalRequest mutableCopy];\n        [req setHTTPMethod:@\"HEAD\"];\n        [req setValue:@\"identity\" forHTTPHeaderField:@\"Accept-Encoding\"];\n\n        _originalDelegate = originalDelegate;\n        _connection = [NSURLConnection connectionWithRequest:req delegate:self];\n    }\n    return self;\n}\n\n- (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response\n{\n    DLog(@\"HEAD request returned; content-length is %lld\", [response expectedContentLength]);\n    [_originalDelegate updateBytesExpected:[response expectedContentLength]];\n}\n\n- (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data\n{}\n\n- (void)connectionDidFinishLoading:(NSURLConnection*)connection\n{}\n\n@end\n\n@implementation CDVFileTransferDelegate\n\n@synthesize callbackId, connection = _connection, source, target, responseData, responseHeaders, command, bytesTransfered, bytesExpected, direction, responseCode, objectId, targetFileHandle, filePlugin;\n\n- (void)connectionDidFinishLoading:(NSURLConnection*)connection\n{\n    NSString* uploadResponse = nil;\n    NSString* downloadResponse = nil;\n    NSMutableDictionary* uploadResult;\n    CDVPluginResult* result = nil;\n\n    NSLog(@\"File Transfer Finished with response code %d\", self.responseCode);\n\n    if (self.direction == CDV_TRANSFER_UPLOAD) {\n        uploadResponse = [[NSString alloc] initWithData:self.responseData encoding:NSUTF8StringEncoding];\n        if (uploadResponse == nil) {\n            uploadResponse = [[NSString alloc] initWithData: self.responseData encoding:NSISOLatin1StringEncoding];\n        }\n\n        if ((self.responseCode >= 200) && (self.responseCode < 300)) {\n            // create dictionary to return FileUploadResult object\n            uploadResult = [NSMutableDictionary dictionaryWithCapacity:3];\n            if (uploadResponse != nil) {\n                [uploadResult setObject:uploadResponse forKey:@\"response\"];\n                [uploadResult setObject:self.responseHeaders forKey:@\"headers\"];\n            }\n            [uploadResult setObject:[NSNumber numberWithLongLong:self.bytesTransfered] forKey:@\"bytesSent\"];\n            [uploadResult setObject:[NSNumber numberWithInt:self.responseCode] forKey:@\"responseCode\"];\n            result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:uploadResult];\n        } else {\n            result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[command createFileTransferError:CONNECTION_ERR AndSource:source AndTarget:target AndHttpStatus:self.responseCode AndBody:uploadResponse]];\n        }\n    }\n    if (self.direction == CDV_TRANSFER_DOWNLOAD) {\n        if (self.targetFileHandle) {\n            [self.targetFileHandle closeFile];\n            self.targetFileHandle = nil;\n            DLog(@\"File Transfer Download success\");\n\n            result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:[self.filePlugin makeEntryForURL:self.targetURL]];\n        } else {\n            downloadResponse = [[NSString alloc] initWithData:self.responseData encoding:NSUTF8StringEncoding];\n            if (downloadResponse == nil) {\n                downloadResponse = [[NSString alloc] initWithData: self.responseData encoding:NSISOLatin1StringEncoding];\n            }\n\n            CDVFileTransferError errorCode = self.responseCode == 404 ? FILE_NOT_FOUND_ERR\n                : (self.responseCode == 304 ? NOT_MODIFIED : CONNECTION_ERR);\n            result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[command createFileTransferError:errorCode AndSource:source AndTarget:target AndHttpStatus:self.responseCode AndBody:downloadResponse]];\n        }\n    }\n\n    [self.command.commandDelegate sendPluginResult:result callbackId:callbackId];\n\n    // remove connection for activeTransfers\n    @synchronized (command.activeTransfers) {\n        [command.activeTransfers removeObjectForKey:objectId];\n        // remove background id task in case our upload was done in the background\n        [[UIApplication sharedApplication] endBackgroundTask:self.backgroundTaskID];\n        self.backgroundTaskID = UIBackgroundTaskInvalid;\n    }\n}\n\n- (void)removeTargetFile\n{\n    NSFileManager* fileMgr = [NSFileManager defaultManager];\n\n    NSString *targetPath = [self targetFilePath];\n    if ([fileMgr fileExistsAtPath:targetPath])\n    {\n        [fileMgr removeItemAtPath:targetPath error:nil];\n    }\n}\n\n- (void)cancelTransfer:(NSURLConnection*)connection\n{\n    [connection cancel];\n    @synchronized (self.command.activeTransfers) {\n        CDVFileTransferDelegate* delegate = self.command.activeTransfers[self.objectId];\n        [self.command.activeTransfers removeObjectForKey:self.objectId];\n        [[UIApplication sharedApplication] endBackgroundTask:delegate.backgroundTaskID];\n        delegate.backgroundTaskID = UIBackgroundTaskInvalid;\n    }\n\n    if (self.direction == CDV_TRANSFER_DOWNLOAD) {\n        [self removeTargetFile];\n    }\n}\n\n- (void)cancelTransferWithError:(NSURLConnection*)connection errorMessage:(NSString*)errorMessage\n{\n    CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsDictionary:[self.command createFileTransferError:FILE_NOT_FOUND_ERR AndSource:self.source AndTarget:self.target AndHttpStatus:self.responseCode AndBody:errorMessage]];\n\n    NSLog(@\"File Transfer Error: %@\", errorMessage);\n    [self cancelTransfer:connection];\n    [self.command.commandDelegate sendPluginResult:result callbackId:callbackId];\n}\n\n- (NSString *)targetFilePath\n{\n    NSString *path = nil;\n    CDVFilesystemURL *sourceURL = [CDVFilesystemURL fileSystemURLWithString:self.target];\n    if (sourceURL && sourceURL.fileSystemName != nil) {\n        // This requires talking to the current CDVFile plugin\n        NSObject<CDVFileSystem> *fs = [self.filePlugin filesystemForURL:sourceURL];\n        path = [fs filesystemPathForURL:sourceURL];\n    } else {\n        // Extract the path part out of a file: URL.\n        path = [self.target hasPrefix:@\"/\"] ? [self.target copy] : [(NSURL *)[NSURL URLWithString:self.target] path];\n    }\n    return path;\n}\n\n- (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response\n{\n    NSError* __autoreleasing error = nil;\n\n    self.mimeType = [response MIMEType];\n    self.targetFileHandle = nil;\n\n    // required for iOS 4.3, for some reason; response is\n    // a plain NSURLResponse, not the HTTP subclass\n    if ([response isKindOfClass:[NSHTTPURLResponse class]]) {\n        NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;\n\n        self.responseCode = (int)[httpResponse statusCode];\n        self.bytesExpected = [response expectedContentLength];\n        self.responseHeaders = [httpResponse allHeaderFields];\n        if ((self.direction == CDV_TRANSFER_DOWNLOAD) && (self.responseCode == 200) && (self.bytesExpected == NSURLResponseUnknownLength)) {\n            // Kick off HEAD request to server to get real length\n            // bytesExpected will be updated when that response is returned\n            self.entityLengthRequest = [[CDVFileTransferEntityLengthRequest alloc] initWithOriginalRequest:connection.currentRequest andDelegate:self];\n        }\n    } else if ([response.URL isFileURL]) {\n        NSDictionary* attr = [[NSFileManager defaultManager] attributesOfItemAtPath:[response.URL path] error:nil];\n        self.responseCode = 200;\n        self.bytesExpected = [attr[NSFileSize] longLongValue];\n    } else {\n        self.responseCode = 200;\n        self.bytesExpected = NSURLResponseUnknownLength;\n    }\n    if ((self.direction == CDV_TRANSFER_DOWNLOAD) && (self.responseCode >= 200) && (self.responseCode < 300)) {\n        // Download response is okay; begin streaming output to file\n        NSString *filePath = [self targetFilePath];\n        if (filePath == nil) {\n            // We couldn't find the asset.  Send the appropriate error.\n            [self cancelTransferWithError:connection errorMessage:[NSString stringWithFormat:@\"Could not create target file\"]];\n            return;\n        }\n\n        NSString* parentPath = [filePath stringByDeletingLastPathComponent];\n\n        // create parent directories if needed\n        if ([[NSFileManager defaultManager] createDirectoryAtPath:parentPath withIntermediateDirectories:YES attributes:nil error:&error] == NO) {\n            if (error) {\n                [self cancelTransferWithError:connection errorMessage:[NSString stringWithFormat:@\"Could not create path to save downloaded file: %@\", [error localizedDescription]]];\n            } else {\n                [self cancelTransferWithError:connection errorMessage:@\"Could not create path to save downloaded file\"];\n            }\n            return;\n        }\n        // create target file\n        if ([[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil] == NO) {\n            [self cancelTransferWithError:connection errorMessage:@\"Could not create target file\"];\n            return;\n        }\n        // open target file for writing\n        self.targetFileHandle = [NSFileHandle fileHandleForWritingAtPath:filePath];\n        if (self.targetFileHandle == nil) {\n            [self cancelTransferWithError:connection errorMessage:@\"Could not open target file for writing\"];\n        }\n        DLog(@\"Streaming to file %@\", filePath);\n    }\n}\n\n- (void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error\n{\n    NSString* body = [[NSString alloc] initWithData:self.responseData encoding:NSUTF8StringEncoding];\n    CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[command createFileTransferError:CONNECTION_ERR AndSource:source AndTarget:target AndHttpStatus:self.responseCode AndBody:body]];\n\n    NSLog(@\"File Transfer Error: %@\", [error localizedDescription]);\n\n    [self cancelTransfer:connection];\n    [self.command.commandDelegate sendPluginResult:result callbackId:callbackId];\n}\n\n- (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data\n{\n    self.bytesTransfered += data.length;\n    if (self.targetFileHandle) {\n        [self.targetFileHandle writeData:data];\n    } else {\n        [self.responseData appendData:data];\n    }\n    [self updateProgress];\n}\n\n- (void)updateBytesExpected:(long long)newBytesExpected\n{\n    DLog(@\"Updating bytesExpected to %lld\", newBytesExpected);\n    self.bytesExpected = newBytesExpected;\n    [self updateProgress];\n}\n\n- (void)updateProgress\n{\n    if (self.direction == CDV_TRANSFER_DOWNLOAD) {\n        BOOL lengthComputable = (self.bytesExpected != NSURLResponseUnknownLength);\n        // If the response is GZipped, and we have an outstanding HEAD request to get\n        // the length, then hold off on sending progress events.\n        if (!lengthComputable && (self.entityLengthRequest != nil)) {\n            return;\n        }\n        NSMutableDictionary* downloadProgress = [NSMutableDictionary dictionaryWithCapacity:3];\n        [downloadProgress setObject:[NSNumber numberWithBool:lengthComputable] forKey:@\"lengthComputable\"];\n        [downloadProgress setObject:[NSNumber numberWithLongLong:self.bytesTransfered] forKey:@\"loaded\"];\n        [downloadProgress setObject:[NSNumber numberWithLongLong:self.bytesExpected] forKey:@\"total\"];\n        CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:downloadProgress];\n        [result setKeepCallbackAsBool:true];\n        [self.command.commandDelegate sendPluginResult:result callbackId:callbackId];\n    }\n}\n\n- (void)connection:(NSURLConnection*)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite\n{\n    if (self.direction == CDV_TRANSFER_UPLOAD) {\n        NSMutableDictionary* uploadProgress = [NSMutableDictionary dictionaryWithCapacity:3];\n\n        [uploadProgress setObject:[NSNumber numberWithBool:true] forKey:@\"lengthComputable\"];\n        [uploadProgress setObject:[NSNumber numberWithLongLong:totalBytesWritten] forKey:@\"loaded\"];\n        [uploadProgress setObject:[NSNumber numberWithLongLong:totalBytesExpectedToWrite] forKey:@\"total\"];\n        CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:uploadProgress];\n        [result setKeepCallbackAsBool:true];\n        [self.command.commandDelegate sendPluginResult:result callbackId:callbackId];\n    }\n    self.bytesTransfered = totalBytesWritten;\n}\n\n// for self signed certificates\n- (void)connection:(NSURLConnection*)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge*)challenge\n{\n    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {\n        if (self.trustAllHosts) {\n            NSURLCredential* credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];\n            [challenge.sender useCredential:credential forAuthenticationChallenge:challenge];\n        }\n        [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];\n    } else {\n        [challenge.sender performDefaultHandlingForAuthenticationChallenge:challenge];\n    }\n}\n\n- (id)init\n{\n    if ((self = [super init])) {\n        self.responseData = [NSMutableData data];\n        self.targetFileHandle = nil;\n    }\n    return self;\n}\n\n@end\n"
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/src/ubuntu/file-transfer.cpp",
    "content": "/*\n *\n * Copyright 2013 Canonical Ltd.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n#include \"file-transfer.h\"\n#include <plugins/cordova-plugin-file/file.h>\n#include <cassert>\n\nstatic void SetHeaders(QNetworkRequest &request, const QVariantMap &headers) {\n    for (const QString &key: headers.keys()) {\n        QVariant val = *headers.find(key);\n        QString value = val.toString();\n        if (val.userType() == QMetaType::QVariantList || val.userType() == QMetaType::QStringList) {\n            QList<QVariant> list = val.toList();\n            for (QVariant v: list) {\n                if (value.size())\n                    value += \", \";\n                value += v.toString();\n            }\n        }\n        request.setRawHeader(key.toUtf8(), value.toUtf8());\n    }\n}\n\nvoid FileTransfer::download(int scId, int ecId, const QString& url, const QString &target, bool /*trustAllHost*/, int id, const QVariantMap &headers) {\n    QSharedPointer<FileTransferRequest> request(new FileTransferRequest(_manager, scId, ecId, id, this));\n\n    assert(_id2request.find(id) == _id2request.end());\n\n    _id2request.insert(id, request);\n\n    request->connect(request.data(), &FileTransferRequest::done, [&]() {\n        auto it = _id2request.find(id);\n        while (it != _id2request.end() && it.key() == id) {\n            if (it.value().data() == request.data()) {\n                _id2request.erase(it);\n                break;\n            }\n            it++;\n        }\n    });\n    request->download(url, target, headers);\n}\n\nvoid FileTransfer::upload(int scId, int ecId, const QString &fileURI, const QString& url, const QString& fileKey, const QString& fileName, const QString& mimeType,\n                          const QVariantMap & params, bool /*trustAllHosts*/, bool /*chunkedMode*/, const QVariantMap &headers, int id, const QString &/*httpMethod*/) {\n    QSharedPointer<FileTransferRequest> request(new FileTransferRequest(_manager, scId, ecId, id, this));\n\n    assert(_id2request.find(id) == _id2request.end());\n\n    _id2request.insert(id, request);\n\n    request->connect(request.data(), &FileTransferRequest::done, [&]() {\n        auto it = _id2request.find(id);\n        while (it != _id2request.end() && it.key() == id) {\n            if (it.value().data() == request.data()) {\n                _id2request.erase(it);\n                break;\n            }\n            it++;\n        }\n    });\n    request->upload(url, fileURI, fileKey, fileName, mimeType, params, headers);\n}\n\nvoid FileTransfer::abort(int scId, int ecId, int id) {\n    Q_UNUSED(scId)\n    Q_UNUSED(ecId)\n\n    auto it = _id2request.find(id);\n    while (it != _id2request.end() && it.key() == id) {\n        (*it)->abort();\n        it++;\n    }\n}\n\nvoid FileTransferRequest::download(const QString& uri, const QString &targetURI, const QVariantMap &headers) {\n    QUrl url(uri);\n    QNetworkRequest request;\n\n    QSharedPointer<CPlugin> filePlugin(_plugin->cordova()->getPlugin<File>());\n\n    if (!filePlugin.data())\n        return;\n\n    if (!url.isValid()) {\n        QVariantMap map;\n        map.insert(\"code\", INVALID_URL_ERR);\n        map.insert(\"source\", uri);\n        map.insert(\"target\", targetURI);\n        _plugin->cb(_ecId, map);\n        emit done();\n        return;\n    }\n\n    request.setUrl(url);\n    if (url.password().size() || url.userName().size()) {\n        QString headerData = \"Basic \" + (url.userName() + \":\" + url.password()).toLocal8Bit().toBase64();\n        request.setRawHeader(\"Authorization\", headerData.toLocal8Bit());\n    }\n    SetHeaders(request, headers);\n    _reply = QSharedPointer<QNetworkReply>(_manager.get(request));\n\n    _reply->connect(_reply.data(), &QNetworkReply::finished, [this, targetURI, uri, filePlugin]() {\n        if (!_scId || _reply->error() != QNetworkReply::NoError)\n            return;\n\n        QPair<bool, QFileInfo> f1(dynamic_cast<File*>(filePlugin.data())->resolveURI(targetURI));\n\n        QFile res(f1.second.absoluteFilePath());\n        if (!f1.first || !res.open(QIODevice::WriteOnly)) {\n            QVariantMap map;\n            map.insert(\"code\", INVALID_URL_ERR);\n            map.insert(\"source\", uri);\n            map.insert(\"target\", targetURI);\n            _plugin->cb(_ecId, map);\n            emit done();\n            return;\n        }\n        res.write(_reply->readAll());\n\n        _plugin->cb(_scId, dynamic_cast<File*>(filePlugin.data())->file2map(f1.second));\n\n        emit done();\n    });\n    _reply->connect(_reply.data(), SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(error(QNetworkReply::NetworkError)));\n    _reply->connect(_reply.data(), SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(progress(qint64, qint64)));\n}\n\nvoid FileTransferRequest::upload(const QString& _url, const QString& fileURI, QString fileKey, QString fileName, QString mimeType, const QVariantMap &params, const QVariantMap &headers) {\n    QUrl url(_url);\n    QNetworkRequest request;\n\n    QSharedPointer<CPlugin> filePlugin(_plugin->cordova()->getPlugin<File>());\n\n    if (!filePlugin.data())\n        return;\n\n    if (!url.isValid()) {\n        QVariantMap map;\n        map.insert(\"code\", INVALID_URL_ERR);\n        map.insert(\"source\", fileURI);\n        map.insert(\"target\", _url);\n        _plugin->cb(_ecId, map);\n        emit done();\n        return;\n    }\n\n    QPair<bool, QFileInfo> f1(dynamic_cast<File*>(filePlugin.data())->resolveURI(fileURI));\n    QFile file(f1.second.absoluteFilePath());\n    if (!f1.first || !file.open(QIODevice::ReadOnly)) {\n        QVariantMap map;\n        map.insert(\"code\", FILE_NOT_FOUND_ERR);\n        map.insert(\"source\", fileURI);\n        map.insert(\"target\", _url);\n        _plugin->cb(_ecId, map);\n        emit done();\n        return;\n    }\n    QString content{file.readAll()};\n\n    request.setUrl(url);\n    if (url.password().size() || url.userName().size()) {\n        QString headerData = \"Basic \" + (url.userName() + \":\" + url.password()).toLocal8Bit().toBase64();\n        request.setRawHeader(\"Authorization\", headerData.toLocal8Bit());\n    }\n    SetHeaders(request, headers);\n\n    QString boundary = QString(\"CORDOVA-QT-%1A\").arg(qrand());\n    while (content.contains(boundary)) {\n        boundary += QString(\"B%1A\").arg(qrand());\n    }\n\n    request.setHeader(QNetworkRequest::ContentTypeHeader, QString(\"multipart/form-data; boundary=\") + boundary);\n\n    fileKey.replace(\"\\\"\", \"\");\n    fileName.replace(\"\\\"\", \"\");\n    mimeType.replace(\"\\\"\", \"\");\n    QString part = \"--\" + boundary + \"\\r\\n\";\n\n    part += \"Content-Disposition: form-data; name=\\\"\" + fileKey +\"\\\"; filename=\\\"\" + fileName + \"\\\"\\r\\n\";\n    part += \"Content-Type: \" + mimeType + \"\\r\\n\\r\\n\";\n    part += content + \"\\r\\n\";\n\n    for (QString key: params.keys()) {\n        part += \"--\" + boundary + \"\\r\\n\";\n        part += \"Content-Disposition: form-data; name=\\\"\" +  key + \"\\\";\\r\\n\\r\\n\";\n        part += params.find(key)->toString();\n        part += \"\\r\\n\";\n    }\n\n    part += QString(\"--\") + boundary + \"--\" + \"\\r\\n\";\n\n    _reply = QSharedPointer<QNetworkReply>(_manager.post(request, QByteArray(part.toUtf8())));\n\n    _reply->connect(_reply.data(), &QNetworkReply::finished, [this, content]() {\n        if (_reply->error() != QNetworkReply::NoError)\n            return;\n        int status = 200;\n        QVariant statusCode = _reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);\n\n        if (statusCode.isValid()) {\n            status = statusCode.toInt();\n        }\n\n        QVariantMap map;\n        map.insert(\"responseCode\", status);\n        map.insert(\"response\", QString(_reply->readAll()));\n        map.insert(\"bytesSent\", content.size());\n        _plugin->cb(_scId, map);\n        emit done();\n    });\n    _reply->connect(_reply.data(), SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(error(QNetworkReply::NetworkError)));\n    _reply->connect(_reply.data(), SIGNAL(uploadProgress(qint64, qint64)), this, SLOT(progress(qint64, qint64)));\n}\n\nvoid FileTransferRequest::abort() {\n    QVariantMap map;\n    map.insert(\"code\", ABORT_ERR);\n    _plugin->cb(_ecId, map);\n    _scId = 0;\n    emit done();\n}\n\nvoid FileTransferRequest::error(QNetworkReply::NetworkError code) {\n    Q_UNUSED(code);\n\n    int status = 404;\n    QVariant statusCode = _reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);\n    if (statusCode.isValid()) {\n        status = statusCode.toInt();\n    }\n\n    QVariantMap map;\n    map.insert(\"http_status\", status);\n    map.insert(\"body\", QString(_reply->readAll()));\n    map.insert(\"code\", CONNECTION_ERR);\n    _plugin->cb(_ecId, map);\n    emit done();\n}\n\nvoid FileTransferRequest::progress(qint64 bytesReceived, qint64 bytesTotal) {\n    QVariantMap map;\n    map.insert(\"lengthComputable\", true);\n    map.insert(\"total\", bytesTotal);\n    map.insert(\"loaded\", bytesReceived);\n\n    if (bytesReceived && bytesTotal && _scId)\n        _plugin->callbackWithoutRemove(_scId, CordovaInternal::format(map));\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/src/ubuntu/file-transfer.h",
    "content": "/*\n *\n * Copyright 2013 Canonical Ltd.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n#ifndef FILE_TRANSFER_H_SDASDASDAS\n#define FILE_TRANSFER_H_SDASDASDAS\n\n#include <QtCore>\n#include <QtNetwork>\n\n#include <cplugin.h>\n\nclass FileTransfer;\n\nclass FileTransferRequest: public QObject {\n    Q_OBJECT\n\n    QNetworkAccessManager &_manager;\n    int _scId, _ecId;\n    int _id;\n    QSharedPointer<QNetworkReply> _reply;\n\n    enum FileTransferError {\n        FILE_NOT_FOUND_ERR = 1,\n        INVALID_URL_ERR = 2,\n        CONNECTION_ERR = 3,\n        ABORT_ERR = 4\n    };\n\npublic:\n    FileTransferRequest(QNetworkAccessManager &manager, int scId, int ecId, int id, FileTransfer *plugin):\n        _manager(manager),\n        _scId(scId),\n        _ecId(ecId),\n        _id(id),\n        _plugin(plugin) {\n    }\n\n    void download(const QString& url, const QString &targetURI, const QVariantMap &headers);\n    void upload(const QString& _url, const QString& fileURI, QString fileKey, QString fileName, QString mimeType, const QVariantMap &params, const QVariantMap &headers);\n    void abort();\n\nsignals:\n    void done();\n\nprivate slots:\n    void progress(qint64 bytesReceived, qint64 bytesTotal);\n    void error(QNetworkReply::NetworkError code);\nprivate:\n    FileTransfer *_plugin;\n    Q_DISABLE_COPY(FileTransferRequest);\n};\n\nclass FileTransfer : public CPlugin {\n    Q_OBJECT\npublic:\n    explicit FileTransfer(Cordova *cordova): CPlugin(cordova) {\n    }\n\n    Cordova* cordova() {\n        return m_cordova;\n    }\n\n    virtual const QString fullName() override {\n        return FileTransfer::fullID();\n    }\n\n    virtual const QString shortName() override {\n        return \"FileTransfer\";\n    }\n\n    static const QString fullID() {\n        return \"FileTransfer\";\n    }\n\npublic slots:\n    void abort(int scId, int ecId, int id);\n    void download(int scId, int ecId, const QString& url, const QString &target, bool /*trustAllHost*/, int id, const QVariantMap &/*headers*/);\n    void upload(int scId, int ecId, const QString &filePath, const QString& url, const QString& fileKey, const QString& fileName, const QString& mimeType,\n                const QVariantMap & params, bool /*trustAllHosts*/, bool /*chunkedMode*/, const QVariantMap &headers, int id, const QString &httpMethod);\n\nprivate:\n    QNetworkAccessManager _manager;\n    QMultiMap<int, QSharedPointer<FileTransferRequest> > _id2request;\n    int lastRequestId;\n};\n\n#endif\n"
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/src/windows/FileTransferProxy.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/*jshint -W030 */\n/*global Windows, WinJS*/\n/*global module, require*/\n\nvar FTErr = require('./FileTransferError'),\n    ProgressEvent = require('cordova-plugin-file.ProgressEvent'),\n    FileUploadResult = require('cordova-plugin-file.FileUploadResult'),\n    FileProxy = require('cordova-plugin-file.FileProxy');\n\nvar appData = Windows.Storage.ApplicationData.current;\n\nvar LINE_START = \"--\";\nvar LINE_END = \"\\r\\n\";\nvar BOUNDARY = '+++++';\n\nvar fileTransferOps = [];\n\n// Some private helper functions, hidden by the module\nfunction cordovaPathToNative(path) {\n\n    var cleanPath = String(path);\n    // turn / into \\\\\n    cleanPath = cleanPath.replace(/\\//g, '\\\\');\n    // turn  \\\\ into \\\n    cleanPath = cleanPath.replace(/\\\\\\\\/g, '\\\\');\n    // strip end \\\\ characters\n    cleanPath = cleanPath.replace(/\\\\+$/g, '');\n    return cleanPath;\n}\n\nfunction nativePathToCordova(path) {\n    return String(path).replace(/\\\\/g, '/');\n}\n\nfunction alreadyCancelled(opId) {\n    var op = fileTransferOps[opId];\n    return op && op.state === FileTransferOperation.CANCELLED;\n}\n\nfunction doUpload (upload, uploadId, filePath, server, successCallback, errorCallback) {\n    if (alreadyCancelled(uploadId)) {\n        errorCallback(new FTErr(FTErr.ABORT_ERR, nativePathToCordova(filePath), server));\n        return;\n    }\n\n    // update internal TransferOperation object with newly created promise\n    var uploadOperation = upload.startAsync();\n    fileTransferOps[uploadId].promise = uploadOperation;\n\n    uploadOperation.then(\n        function (result) {\n            // Update TransferOperation object with new state, delete promise property\n            // since it is not actual anymore\n            var currentUploadOp = fileTransferOps[uploadId];\n            if (currentUploadOp) {\n                currentUploadOp.state = FileTransferOperation.DONE;\n                currentUploadOp.promise = null;\n            }\n\n            var response = result.getResponseInformation();\n            var ftResult = new FileUploadResult(result.progress.bytesSent, response.statusCode, '');\n\n            // if server's response doesn't contain any data, then resolve operation now\n            if (result.progress.bytesReceived === 0) {\n                successCallback(ftResult);\n                return;\n            }\n\n            // otherwise create a data reader, attached to response stream to get server's response\n            var reader = new Windows.Storage.Streams.DataReader(result.getResultStreamAt(0));\n            reader.loadAsync(result.progress.bytesReceived).then(function (size) {\n                ftResult.response = reader.readString(size);\n                successCallback(ftResult);\n                reader.close();\n            });\n        },\n        function (error) {\n            var source = nativePathToCordova(filePath);\n\n            // Handle download error here.\n            // Wrap this routines into promise due to some async methods\n            var getTransferError = new WinJS.Promise(function (resolve) {\n                if (error.message === 'Canceled') {\n                    // If download was cancelled, message property will be specified\n                    resolve(new FTErr(FTErr.ABORT_ERR, source, server, null, null, error));\n                } else {\n                    // in the other way, try to get response property\n                    var response = upload.getResponseInformation();\n                    if (!response) {\n                        resolve(new FTErr(FTErr.CONNECTION_ERR, source, server));\n                    } else {\n                        var reader = new Windows.Storage.Streams.DataReader(upload.getResultStreamAt(0));\n                        reader.loadAsync(upload.progress.bytesReceived).then(function (size) {\n                            var responseText = reader.readString(size);\n                            resolve(new FTErr(FTErr.FILE_NOT_FOUND_ERR, source, server, response.statusCode, responseText, error));\n                            reader.close();\n                        });\n                    }\n                }\n            });\n\n            // Update TransferOperation object with new state, delete promise property\n            // since it is not actual anymore\n            var currentUploadOp = fileTransferOps[uploadId];\n            if (currentUploadOp) {\n                currentUploadOp.state = FileTransferOperation.CANCELLED;\n                currentUploadOp.promise = null;\n            }\n\n            // Report the upload error back\n            getTransferError.then(function (transferError) {\n                errorCallback(transferError);\n            });\n        },\n        function (evt) {\n            var progressEvent = new ProgressEvent('progress', {\n                loaded: evt.progress.bytesSent,\n                total: evt.progress.totalBytesToSend,\n                target: evt.resultFile\n            });\n            progressEvent.lengthComputable = true;\n            successCallback(progressEvent, { keepCallback: true });\n        }\n    );\n}\n\nfunction FileTransferOperation(state, promise) {\n    this.state = state;\n    this.promise = promise;\n}\n\nFileTransferOperation.PENDING = 0;\nFileTransferOperation.DONE = 1;\nFileTransferOperation.CANCELLED = 2;\n\nvar HTTP_E_STATUS_NOT_MODIFIED = -2145844944;\n\nmodule.exports = {\n\n/*\nexec(win, fail, 'FileTransfer', 'upload', \n[filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode, headers, this._id, httpMethod]);\n*/\n    upload: function (successCallback, errorCallback, options) {\n        var filePath = options[0];\n        var server = options[1];\n        var fileKey = options[2] || 'source';\n        var fileName = options[3];\n        var mimeType = options[4];\n        var params = options[5];\n        // var trustAllHosts = options[6]; // todo\n        // var chunkedMode = options[7]; // todo \n        var headers = options[8] || {};\n        var uploadId = options[9];\n        var httpMethod = options[10];\n\n        var isMultipart = typeof headers[\"Content-Type\"] === 'undefined';\n\n        function stringToByteArray(str) {\n            var byteCharacters = atob(str);\n            var byteNumbers = new Array(byteCharacters.length);\n            for (var i = 0; i < byteCharacters.length; i++) {\n                byteNumbers[i] = byteCharacters.charCodeAt(i);\n            }\n            return new Uint8Array(byteNumbers);\n        }\n\n        if (!filePath || (typeof filePath !== 'string')) {\n            errorCallback(new FTErr(FTErr.FILE_NOT_FOUND_ERR, null, server));\n            return;\n        }\n\n        if (filePath.indexOf(\"data:\") === 0 && filePath.indexOf(\"base64\") !== -1) {\n            // First a DataWriter object is created, backed by an in-memory stream where \n            // the data will be stored.\n            var writer = Windows.Storage.Streams.DataWriter(new Windows.Storage.Streams.InMemoryRandomAccessStream());\n            writer.unicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.utf8;\n            writer.byteOrder = Windows.Storage.Streams.ByteOrder.littleEndian;\n\n            var commaIndex = filePath.indexOf(\",\");\n            if (commaIndex === -1) {\n                errorCallback(new FTErr(FTErr.INVALID_URL_ERR, fileName, server, null, null, \"No comma in data: URI\"));\n                return;\n            }\n\n            // Create internal download operation object\n            fileTransferOps[uploadId] = new FileTransferOperation(FileTransferOperation.PENDING, null);\n\n            var fileDataString = filePath.substr(commaIndex + 1);\n\n            // setting request headers for uploader\n            var uploader = new Windows.Networking.BackgroundTransfer.BackgroundUploader();\n            uploader.method = httpMethod;\n            for (var header in headers) {\n                if (headers.hasOwnProperty(header)) {\n                    uploader.setRequestHeader(header, headers[header]);\n                }\n            }\n\n            if (isMultipart) {\n                // adding params supplied to request payload\n                var multipartParams = '';\n                for (var key in params) {\n                    if (params.hasOwnProperty(key)) {\n                        multipartParams += LINE_START + BOUNDARY + LINE_END;\n                        multipartParams += \"Content-Disposition: form-data; name=\\\"\" + key + \"\\\"\";\n                        multipartParams += LINE_END + LINE_END;\n                        multipartParams += params[key];\n                        multipartParams += LINE_END;\n                    }\n                }\n\n                var multipartFile = LINE_START + BOUNDARY + LINE_END;\n                multipartFile += \"Content-Disposition: form-data; name=\\\"file\\\";\";\n                multipartFile += \" filename=\\\"\" + fileName + \"\\\"\" + LINE_END;\n                multipartFile += \"Content-Type: \" + mimeType + LINE_END + LINE_END;\n\n                var bound = LINE_END + LINE_START + BOUNDARY + LINE_START + LINE_END;\n\n                uploader.setRequestHeader(\"Content-Type\", \"multipart/form-data; boundary=\" + BOUNDARY);\n                writer.writeString(multipartParams);\n                writer.writeString(multipartFile);\n                writer.writeBytes(stringToByteArray(fileDataString));\n                writer.writeString(bound);\n            } else {\n                writer.writeBytes(stringToByteArray(fileDataString));\n            }\n\n            var stream;\n\n            // The call to store async sends the actual contents of the writer \n            // to the backing stream.\n            writer.storeAsync().then(function () {\n                // For the in-memory stream implementation we are using, the flushAsync call \n                // is superfluous, but other types of streams may require it.\n                return writer.flushAsync();\n            }).then(function () {\n                // We detach the stream to prolong its useful lifetime. Were we to fail \n                // to detach the stream, the call to writer.close() would close the underlying \n                // stream, preventing its subsequent use by the DataReader below. Most clients \n                // of DataWriter will have no reason to use the underlying stream after \n                // writer.close() is called, and will therefore have no reason to call\n                // writer.detachStream(). Note that once we detach the stream, we assume \n                // responsibility for closing the stream subsequently; after the stream \n                // has been detached, a call to writer.close() will have no effect on the stream.\n                stream = writer.detachStream();\n                // Make sure the stream is read from the beginning in the reader \n                // we are creating below.\n                stream.seek(0);\n                // Most DataWriter clients will not call writer.detachStream(), \n                // and furthermore will be working with a file-backed or network-backed stream, \n                // rather than an in-memory-stream. In such cases, it would be particularly \n                // important to call writer.close(). Doing so is always a best practice.\n                writer.close();\n\n                if (alreadyCancelled(uploadId)) {\n                    errorCallback(new FTErr(FTErr.ABORT_ERR, nativePathToCordova(filePath), server));\n                    return;\n                }\n\n                // create download object. This will throw an exception if URL is malformed\n                var uri = new Windows.Foundation.Uri(server);\n\n                var createUploadOperation;\n                try {\n                    createUploadOperation = uploader.createUploadFromStreamAsync(uri, stream);\n                } catch (e) {\n                    errorCallback(new FTErr(FTErr.INVALID_URL_ERR));\n                    return;\n                }\n\n                createUploadOperation.then(\n                    function (upload) {\n                        doUpload(upload, uploadId, filePath, server, successCallback, errorCallback);\n                    },\n                    function (err) {\n                        var errorObj = new FTErr(FTErr.INVALID_URL_ERR);\n                        errorObj.exception = err;\n                        errorCallback(errorObj);\n                    });\n            });\n\n            return;\n        }\n\n        if (filePath.substr(0, 8) === \"file:///\") {\n            filePath = appData.localFolder.path + filePath.substr(8).split(\"/\").join(\"\\\\\");\n        } else if (filePath.indexOf('ms-appdata:///') === 0) {\n            // Handle 'ms-appdata' scheme\n            filePath = filePath.replace('ms-appdata:///local', appData.localFolder.path)\n                               .replace('ms-appdata:///temp', appData.temporaryFolder.path);\n        } else if (filePath.indexOf('cdvfile://') === 0) {\n            filePath = filePath.replace('cdvfile://localhost/persistent', appData.localFolder.path)\n                               .replace('cdvfile://localhost/temporary', appData.temporaryFolder.path);\n        }\n\n        // normalize path separators\n        filePath = cordovaPathToNative(filePath);\n\n        // Create internal download operation object\n        fileTransferOps[uploadId] = new FileTransferOperation(FileTransferOperation.PENDING, null);\n\n        Windows.Storage.StorageFile.getFileFromPathAsync(filePath)\n        .then(function (storageFile) {\n\n            if (!fileName) {\n                fileName = storageFile.name;\n            }\n            if (!mimeType) {\n                // use the actual content type of the file, probably this should be the default way.\n                // other platforms probably can't look this up.\n                mimeType = storageFile.contentType;\n            }\n\n            if (alreadyCancelled(uploadId)) {\n                errorCallback(new FTErr(FTErr.ABORT_ERR, nativePathToCordova(filePath), server));\n                return;\n            }\n\n            // setting request headers for uploader\n            var uploader = new Windows.Networking.BackgroundTransfer.BackgroundUploader();\n            uploader.method = httpMethod;\n            for (var header in headers) {\n                if (headers.hasOwnProperty(header)) {\n                    uploader.setRequestHeader(header, headers[header]);\n                }\n            }\n\n            // create download object. This will throw an exception if URL is malformed\n            var uri = new Windows.Foundation.Uri(server);\n\n            var createUploadOperation;\n            try {\n                if (isMultipart) {\n                    // adding params supplied to request payload\n                    var transferParts = [];\n                    for (var key in params) {\n                        // Create content part for params only if value is specified because CreateUploadAsync fails otherwise\n                        if (params.hasOwnProperty(key) && params[key] !== null && params[key] !== undefined && params[key].toString() !== \"\") {\n                            var contentPart = new Windows.Networking.BackgroundTransfer.BackgroundTransferContentPart();\n                            contentPart.setHeader(\"Content-Disposition\", \"form-data; name=\\\"\" + key + \"\\\"\");\n                            contentPart.setText(params[key]);\n                            transferParts.push(contentPart);\n                        }\n                    }\n\n                    // Adding file to upload to request payload\n                    var fileToUploadPart = new Windows.Networking.BackgroundTransfer.BackgroundTransferContentPart(fileKey, fileName);\n                    fileToUploadPart.setFile(storageFile);\n                    transferParts.push(fileToUploadPart);\n\n                    createUploadOperation = uploader.createUploadAsync(uri, transferParts);\n                } else {\n                    createUploadOperation = WinJS.Promise.wrap(uploader.createUpload(uri, storageFile));\n                }\n            } catch (e) {\n                errorCallback(new FTErr(FTErr.INVALID_URL_ERR));\n                return;\n            }\n\n            createUploadOperation.then(\n                function (upload) {\n                    doUpload(upload, uploadId, filePath, server, successCallback, errorCallback);\n                },\n                function (err) {\n                    var errorObj = new FTErr(FTErr.INVALID_URL_ERR);\n                    errorObj.exception = err;\n                    errorCallback(errorObj);\n                }\n            );\n        }, function (err) {\n            errorCallback(new FTErr(FTErr.FILE_NOT_FOUND_ERR, fileName, server, null, null, err));\n        });\n    },\n\n    // [source, target, trustAllHosts, id, headers]\n    download:function(successCallback, errorCallback, options) {\n        var source = options[0];\n        var target = options[1];\n        var downloadId = options[3];\n        var headers = options[4] || {};\n\n        if (!target) {\n            errorCallback(new FTErr(FTErr.FILE_NOT_FOUND_ERR));\n            return;\n        }\n        if (target.substr(0, 8) === \"file:///\") {\n            target = appData.localFolder.path + target.substr(8).split(\"/\").join(\"\\\\\");\n        } else if (target.indexOf('ms-appdata:///') === 0) {\n            // Handle 'ms-appdata' scheme\n            target = target.replace('ms-appdata:///local', appData.localFolder.path)\n                           .replace('ms-appdata:///temp', appData.temporaryFolder.path);\n        } else if (target.indexOf('cdvfile://') === 0) {\n            target = target.replace('cdvfile://localhost/persistent', appData.localFolder.path)\n                           .replace('cdvfile://localhost/temporary', appData.temporaryFolder.path);\n        }\n        target = cordovaPathToNative(target);\n\n        var path = target.substr(0, target.lastIndexOf(\"\\\\\"));\n        var fileName = target.substr(target.lastIndexOf(\"\\\\\") + 1);\n        if (path === null || fileName === null) {\n            errorCallback(new FTErr(FTErr.FILE_NOT_FOUND_ERR));\n            return;\n        }\n        // Download to a temp file to avoid the file deletion on 304 \n        // CB-7006 Empty file is created on file transfer if server response is 304\n        var tempFileName = '~' + fileName;\n\n        var download = null;\n\n        // Create internal download operation object\n        fileTransferOps[downloadId] = new FileTransferOperation(FileTransferOperation.PENDING, null);\n\n        var downloadCallback = function(storageFolder) {\n            storageFolder.createFileAsync(tempFileName, Windows.Storage.CreationCollisionOption.replaceExisting).then(function (storageFile) {\n\n                if (alreadyCancelled(downloadId)) {\n                    errorCallback(new FTErr(FTErr.ABORT_ERR, source, target));\n                    return;\n                }\n\n                // if download isn't cancelled, contunue with creating and preparing download operation\n                var downloader = new Windows.Networking.BackgroundTransfer.BackgroundDownloader();\n                for (var header in headers) {\n                    if (headers.hasOwnProperty(header)) {\n                        downloader.setRequestHeader(header, headers[header]);\n                    }\n                }\n\n                // create download object. This will throw an exception if URL is malformed\n                try {\n                    var uri = Windows.Foundation.Uri(source);\n                    download = downloader.createDownload(uri, storageFile);\n                } catch (e) {\n                    // so we handle this and call errorCallback\n                    errorCallback(new FTErr(FTErr.INVALID_URL_ERR));\n                    return;\n                }\n\n                var downloadOperation = download.startAsync();\n                // update internal TransferOperation object with newly created promise\n                fileTransferOps[downloadId].promise = downloadOperation;\n\n                downloadOperation.then(function () {\n\n                    // Update TransferOperation object with new state, delete promise property\n                    // since it is not actual anymore\n                    var currentDownloadOp = fileTransferOps[downloadId];\n                    if (currentDownloadOp) {\n                        currentDownloadOp.state = FileTransferOperation.DONE;\n                        currentDownloadOp.promise = null;\n                    }\n\n                    storageFile.renameAsync(fileName, Windows.Storage.CreationCollisionOption.replaceExisting).done(function () {\n                        var nativeURI = storageFile.path.replace(appData.localFolder.path, 'ms-appdata:///local')\n                        .replace(appData.temporaryFolder.path, 'ms-appdata:///temp')\n                        .replace(/\\\\/g, '/');\n\n                        // Passing null as error callback here because downloaded file should exist in any case\n                        // otherwise the error callback will be hit during file creation in another place\n                        FileProxy.resolveLocalFileSystemURI(successCallback, null, [nativeURI]);\n                    }, function(error) {\n                        errorCallback(new FTErr(FTErr.FILE_NOT_FOUND_ERR, source, target, null, null, error));\n                    });\n                }, function(error) {\n\n                    var getTransferError = new WinJS.Promise(function (resolve) {\n                        // Handle download error here. If download was cancelled,\n                        // message property will be specified\n                        if (error.message === 'Canceled') {\n                            resolve(new FTErr(FTErr.ABORT_ERR, source, target, null, null, error));\n                        } else if (error && error.number === HTTP_E_STATUS_NOT_MODIFIED) {\n                            resolve(new FTErr(FTErr.NOT_MODIFIED_ERR, source, target, 304, null, error));\n                        } else {\n                            // in the other way, try to get response property\n                            var response = download.getResponseInformation();\n                            if (!response) {\n                                resolve(new FTErr(FTErr.CONNECTION_ERR, source, target));\n                            } else {\n                                var reader = new Windows.Storage.Streams.DataReader(download.getResultStreamAt(0));\n                                reader.loadAsync(download.progress.bytesReceived).then(function (bytesLoaded) {\n                                    var payload = reader.readString(bytesLoaded);\n                                    resolve(new FTErr(FTErr.FILE_NOT_FOUND_ERR, source, target, response.statusCode, payload, error));\n                                });\n                            }\n                        }\n                    });\n                    getTransferError.then(function (fileTransferError) {\n\n                        // Update TransferOperation object with new state, delete promise property\n                        // since it is not actual anymore\n                        var currentDownloadOp = fileTransferOps[downloadId];\n                        if (currentDownloadOp) {\n                            currentDownloadOp.state = FileTransferOperation.CANCELLED;\n                            currentDownloadOp.promise = null;\n                        }\n\n                        // Cleanup, remove incompleted file\n                        storageFile.deleteAsync().then(function() {\n                            errorCallback(fileTransferError);\n                        });\n                    });\n\n                }, function(evt) {\n\n                    var progressEvent = new ProgressEvent('progress', {\n                        loaded: evt.progress.bytesReceived,\n                        total: evt.progress.totalBytesToReceive,\n                        target: evt.resultFile\n                    });\n                    // when bytesReceived == 0, BackgroundDownloader has not yet differentiated whether it could get file length or not,\n                    // when totalBytesToReceive == 0, BackgroundDownloader is unable to get file length\n                    progressEvent.lengthComputable = (evt.progress.bytesReceived > 0) && (evt.progress.totalBytesToReceive > 0);\n\n                    successCallback(progressEvent, { keepCallback: true });\n                });\n            }, function(error) {\n                errorCallback(new FTErr(FTErr.FILE_NOT_FOUND_ERR, source, target, null, null, error));\n            });\n        };\n\n        var fileNotFoundErrorCallback = function(error) {\n            errorCallback(new FTErr(FTErr.FILE_NOT_FOUND_ERR, source, target, null, null, error));\n        };\n\n        Windows.Storage.StorageFolder.getFolderFromPathAsync(path).then(downloadCallback, function (error) {\n            // Handle non-existent directory\n            if (error.number === -2147024894) {\n                var parent = path.substr(0, path.lastIndexOf('\\\\')),\n                    folderNameToCreate = path.substr(path.lastIndexOf('\\\\') + 1);\n\n                Windows.Storage.StorageFolder.getFolderFromPathAsync(parent).then(function(parentFolder) {\n                    parentFolder.createFolderAsync(folderNameToCreate).then(downloadCallback, fileNotFoundErrorCallback);\n                }, fileNotFoundErrorCallback);\n            } else {\n                fileNotFoundErrorCallback();\n            }\n        });\n    },\n\n    abort: function (successCallback, error, options) {\n        var fileTransferOpId = options[0];\n\n        // Try to find transferOperation with id specified, and cancel its' promise\n        var currentOp = fileTransferOps[fileTransferOpId];\n        if (currentOp) {\n            currentOp.state = FileTransferOperation.CANCELLED;\n            currentOp.promise && currentOp.promise.cancel();\n        } else if (typeof fileTransferOpId !== 'undefined') {\n            // Create the operation in cancelled state to be aborted right away\n            fileTransferOps[fileTransferOpId] = new FileTransferOperation(FileTransferOperation.CANCELLED, null);\n        }\n    }\n\n};\n\nrequire(\"cordova/exec/proxy\").add(\"FileTransfer\",module.exports);\n"
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/src/wp/FileTransfer.cs",
    "content": "/*\n\tLicensed under the Apache License, Version 2.0 (the \"License\");\n\tyou may not use this file except in compliance with the License.\n\tYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\n\tUnless required by applicable law or agreed to in writing, software\n\tdistributed under the License is distributed on an \"AS IS\" BASIS,\n\tWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n\tSee the License for the specific language governing permissions and\n\tlimitations under the License.\n*/\n\nusing Microsoft.Phone.Controls;\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.IO.IsolatedStorage;\nusing System.Linq;\nusing System.Net;\nusing System.Runtime.Serialization;\nusing System.Windows;\nusing System.Security;\nusing System.Diagnostics;\nusing System.Threading.Tasks;\nusing WPCordovaClassLib.Cordova.JSON;\nusing System.Reflection;\n\nnamespace WPCordovaClassLib.Cordova.Commands\n{\n    public class FileTransfer : BaseCommand\n    {\n        public class DownloadRequestState\n        {\n            // This class stores the State of the request.\n            public HttpWebRequest request;\n            public TransferOptions options;\n            public bool isCancelled;\n\n            public DownloadRequestState()\n            {\n                request = null;\n                options = null;\n                isCancelled = false;\n            }\n        }\n\n        public class TransferOptions\n        {\n            /// File path to upload  OR File path to download to\n            public string FilePath { get; set; }\n\n            public string Url { get; set; }\n            /// Flag to recognize if we should trust every host (only in debug environments)\n            public bool TrustAllHosts { get; set; }\n            public string Id { get; set; }\n            public string Headers { get; set; }\n            public string CallbackId { get; set; }\n            public bool ChunkedMode { get; set; }\n            /// Server address\n            public string Server { get; set; }\n            /// File key\n            public string FileKey { get; set; }\n            /// File name on the server\n            public string FileName { get; set; }\n            /// File Mime type\n            public string MimeType { get; set; }\n            /// Additional options\n            public string Params { get; set; }\n            public string Method { get; set; }\n\n            public TransferOptions()\n            {\n                FileKey = \"file\";\n                FileName = \"image.jpg\";\n                MimeType = \"image/jpeg\";\n            }\n        }\n\n        /// <summary>\n        /// Boundary symbol\n        /// </summary>\n        private string Boundary = \"----------------------------\" + DateTime.Now.Ticks.ToString(\"x\");\n\n        // Error codes\n        public const int FileNotFoundError = 1;\n        public const int InvalidUrlError = 2;\n        public const int ConnectionError = 3;\n        public const int AbortError = 4; // not really an error, but whatevs\n\n        private static Dictionary<string, DownloadRequestState> InProcDownloads = new Dictionary<string,DownloadRequestState>();\n\n        // Private instance of the main WebBrowser instance\n        // NOTE: Any access to this object needs to occur on the UI thread via the Dispatcher\n        private WebBrowser browser;\n\n\n\n        /// <summary>\n        /// Uploading response info\n        /// </summary>\n        [DataContract]\n        public class FileUploadResult\n        {\n            /// <summary>\n            /// Amount of sent bytes\n            /// </summary>\n            [DataMember(Name = \"bytesSent\")]\n            public long BytesSent { get; set; }\n\n            /// <summary>\n            /// Server response code\n            /// </summary>\n            [DataMember(Name = \"responseCode\")]\n            public long ResponseCode { get; set; }\n\n            /// <summary>\n            /// Server response\n            /// </summary>\n            [DataMember(Name = \"response\", EmitDefaultValue = false)]\n            public string Response { get; set; }\n\n            /// <summary>\n            /// Creates FileUploadResult object with response values\n            /// </summary>\n            /// <param name=\"bytesSent\">Amount of sent bytes</param>\n            /// <param name=\"responseCode\">Server response code</param>\n            /// <param name=\"response\">Server response</param>\n            public FileUploadResult(long bytesSent, long responseCode, string response)\n            {\n                this.BytesSent = bytesSent;\n                this.ResponseCode = responseCode;\n                this.Response = response;\n            }\n        }\n        /// <summary>\n        /// Represents transfer error codes for callback\n        /// </summary>\n        [DataContract]\n        public class FileTransferError\n        {\n            /// <summary>\n            /// Error code\n            /// </summary>\n            [DataMember(Name = \"code\", IsRequired = true)]\n            public int Code { get; set; }\n\n            /// <summary>\n            /// The source URI\n            /// </summary>\n            [DataMember(Name = \"source\", IsRequired = true)]\n            public string Source { get; set; }\n\n            /// <summary>\n            /// The target URI\n            /// </summary>\n            ///\n            [DataMember(Name = \"target\", IsRequired = true)]\n            public string Target { get; set; }\n\n            [DataMember(Name = \"body\", IsRequired = true)]\n            public string Body { get; set; }\n\n            /// <summary>\n            /// The http status code response from the remote URI\n            /// </summary>\n            [DataMember(Name = \"http_status\", IsRequired = true)]\n            public int HttpStatus { get; set; }\n\n            /// <summary>\n            /// Creates FileTransferError object\n            /// </summary>\n            /// <param name=\"errorCode\">Error code</param>\n            public FileTransferError(int errorCode)\n            {\n                this.Code = errorCode;\n                this.Source = null;\n                this.Target = null;\n                this.HttpStatus = 0;\n                this.Body = \"\";\n            }\n            public FileTransferError(int errorCode, string source, string target, int status, string body = \"\")\n            {\n                this.Code = errorCode;\n                this.Source = source;\n                this.Target = target;\n                this.HttpStatus = status;\n                this.Body = body;\n            }\n        }\n\n        /// <summary>\n        /// Represents a singular progress event to be passed back to javascript\n        /// </summary>\n        [DataContract]\n        public class FileTransferProgress\n        {\n            /// <summary>\n            /// Is the length of the response known?\n            /// </summary>\n            [DataMember(Name = \"lengthComputable\", IsRequired = true)]\n            public bool LengthComputable { get; set; }\n            /// <summary>\n            /// amount of bytes loaded\n            /// </summary>\n            [DataMember(Name = \"loaded\", IsRequired = true)]\n            public long BytesLoaded { get; set; }\n            /// <summary>\n            /// Total bytes\n            /// </summary>\n            [DataMember(Name = \"total\", IsRequired = false)]\n            public long BytesTotal { get; set; }\n\n            public FileTransferProgress(long bTotal = 0, long bLoaded = 0)\n            {\n                LengthComputable = bTotal > 0;\n                BytesLoaded = bLoaded;\n                BytesTotal = bTotal;\n            }\n        }\n\n        /// <summary>\n        /// Represents a request header passed from Javascript to upload/download operations\n        /// </summary>\n        [DataContract]\n        protected struct Header\n        {\n            [DataMember(Name = \"name\")]\n            public string Name;\n\n            [DataMember(Name = \"value\")]\n            public string Value;\n        }\n\n        private static MethodInfo JsonDeserializeUsingJsonNet;\n\n        public FileTransfer()\n        {\n            if (JsonDeserializeUsingJsonNet == null)\n            {\n                var method = typeof(JsonHelper).GetMethod(\"Deserialize\", new Type[] { typeof(string), typeof(bool) });\n                if (method != null) \n                {\n                    JsonDeserializeUsingJsonNet = method.MakeGenericMethod(new Type[] { typeof(Header[]) });\n                }\n            }\n        }\n\n        /// Helper method to copy all relevant cookies from the WebBrowser control into a header on\n        /// the HttpWebRequest\n        /// </summary>\n        /// <param name=\"browser\">The source browser to copy the cookies from</param>\n        /// <param name=\"webRequest\">The destination HttpWebRequest to add the cookie header to</param>\n        /// <returns>Nothing</returns>\n        private async Task CopyCookiesFromWebBrowser(HttpWebRequest webRequest)\n        {\n            var tcs = new TaskCompletionSource<object>();\n\n            // Accessing WebBrowser needs to happen on the UI thread\n            Deployment.Current.Dispatcher.BeginInvoke(() =>\n            {\n                // Get the WebBrowser control\n                if (this.browser == null)\n                {\n                    PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;\n                    if (frame != null)\n                    {\n                        PhoneApplicationPage page = frame.Content as PhoneApplicationPage;\n                        if (page != null)\n                        {\n                            CordovaView cView = page.FindName(\"CordovaView\") as CordovaView;\n                            if (cView != null)\n                            {\n                                this.browser = cView.Browser;\n                            }\n                        }\n                    }\n                }\n\n                try\n                {\n                    // Only copy the cookies if the scheme and host match (to avoid any issues with secure/insecure cookies)\n                    // NOTE: since the returned CookieCollection appears to munge the original cookie's domain value in favor of the actual Source domain,\n                    // we can't know for sure whether the cookies would be applicable to any other hosts, so best to play it safe and skip for now.\n                    if (this.browser != null && this.browser.Source.IsAbsoluteUri == true &&\n                        this.browser.Source.Scheme == webRequest.RequestUri.Scheme && this.browser.Source.Host == webRequest.RequestUri.Host)\n                    {\n                        string cookieHeader = \"\";\n                        string requestPath = webRequest.RequestUri.PathAndQuery;\n                        CookieCollection cookies = this.browser.GetCookies();\n\n                        // Iterate over the cookies and add to the header\n                        foreach (Cookie cookie in cookies)\n                        {\n                            // Check that the path is allowed, first\n                            // NOTE: Path always seems to be empty for now, even if the cookie has a path set by the server.\n                            if (cookie.Path.Length == 0 || requestPath.IndexOf(cookie.Path, StringComparison.InvariantCultureIgnoreCase) == 0)\n                            {\n                                cookieHeader += cookie.Name + \"=\" + cookie.Value + \"; \";\n                            }\n                        }\n\n                        // Finally, set the header if we found any cookies\n                        if (cookieHeader.Length > 0)\n                        {\n                            webRequest.Headers[\"Cookie\"] = cookieHeader;\n                        }\n                    }\n                }\n                catch (Exception)\n                {\n                    // Swallow the exception\n                }\n\n                // Complete the task\n                tcs.SetResult(Type.Missing);\n            });\n\n            await tcs.Task;\n        }\n\n        /// <summary>\n        /// Upload options\n        /// </summary>\n        //private TransferOptions uploadOptions;\n\n        /// <summary>\n        /// Bytes sent\n        /// </summary>\n        private long bytesSent;\n\n        /// <summary>\n        /// sends a file to a server\n        /// </summary>\n        /// <param name=\"options\">Upload options</param>\n        /// exec(win, fail, 'FileTransfer', 'upload', [filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode, headers, this._id, httpMethod]);\n        public void upload(string options)\n        {\n            options = options.Replace(\"{}\", \"\"); // empty objects screw up the Deserializer\n            string callbackId = \"\";\n\n            TransferOptions uploadOptions = null;\n            HttpWebRequest webRequest = null;\n\n            try\n            {\n                try\n                {\n                    string[] args = JSON.JsonHelper.Deserialize<string[]>(options);\n                    uploadOptions = new TransferOptions();\n                    uploadOptions.FilePath = args[0];\n                    uploadOptions.Server = args[1];\n                    uploadOptions.FileKey = args[2];\n                    uploadOptions.FileName = args[3];\n                    uploadOptions.MimeType = args[4];\n                    uploadOptions.Params = args[5];\n\n                    bool trustAll = false;\n                    bool.TryParse(args[6],out trustAll);\n                    uploadOptions.TrustAllHosts = trustAll;\n\n                    bool doChunked = false;\n                    bool.TryParse(args[7], out doChunked);\n                    uploadOptions.ChunkedMode = doChunked;\n\n                    //8 : Headers\n                    //9 : id\n                    //10: method\n\n                    uploadOptions.Headers = args[8];\n                    uploadOptions.Id = args[9];\n                    uploadOptions.Method = args[10];\n\n                    uploadOptions.CallbackId = callbackId = args[11];\n                }\n                catch (Exception)\n                {\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));\n                    return;\n                }\n\n                Uri serverUri;\n                try\n                {\n                    serverUri = new Uri(uploadOptions.Server);\n                }\n                catch (Exception)\n                {\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(InvalidUrlError, uploadOptions.Server, null, 0)));\n                    return;\n                }\n                webRequest = (HttpWebRequest)WebRequest.Create(serverUri);\n                webRequest.ContentType = \"multipart/form-data; boundary=\" + Boundary;\n                webRequest.Method = uploadOptions.Method;\n\n                DownloadRequestState reqState = new DownloadRequestState();\n                InProcDownloads[uploadOptions.Id] = reqState;\n                reqState.options = uploadOptions;\n                reqState.request = webRequest;\n\n                try\n                {\n                    // Associate cookies with the request\n                    // This is an async call, so we need to await it in order to preserve proper control flow\n                    Task cookieTask = CopyCookiesFromWebBrowser(webRequest);\n                    cookieTask.Wait();\n                }\n                catch (AggregateException ae)\n                {\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR,\n                        new FileTransferError(FileTransfer.ConnectionError, uploadOptions.FilePath, uploadOptions.Server, 0, ae.InnerException.Message)));\n                    return;\n                }\n\n                if (!string.IsNullOrEmpty(uploadOptions.Headers))\n                {\n                    Dictionary<string, string> headers = parseHeaders(uploadOptions.Headers);\n                    if (headers != null)\n                    {\n                        foreach (string key in headers.Keys)\n                        {\n                            webRequest.Headers[key] = headers[key];\n                        }\n                    }\n                }\n\n                webRequest.BeginGetRequestStream(uploadCallback, reqState);\n            }\n            catch (Exception /*ex*/)\n            {\n                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError)),callbackId);\n            }\n        }\n\n        // example : \"{\\\"Authorization\\\":\\\"Basic Y29yZG92YV91c2VyOmNvcmRvdmFfcGFzc3dvcmQ=\\\"}\"\n        protected Dictionary<string,string> parseHeaders(string jsonHeaders)\n        {\n            try\n            {\n                if (FileTransfer.JsonDeserializeUsingJsonNet != null)\n                {\n                    return ((Header[])FileTransfer.JsonDeserializeUsingJsonNet.Invoke(null, new object[] { jsonHeaders, true }))\n                         .ToDictionary(header => header.Name, header => header.Value);\n                }\n                else\n                {\n                    return JsonHelper.Deserialize<Header[]>(jsonHeaders)\n                        .ToDictionary(header => header.Name, header => header.Value);\n                }\n            }\n            catch (Exception)\n            {\n                Debug.WriteLine(\"Failed to parseHeaders from string :: \" + jsonHeaders);\n            }\n            return new Dictionary<string, string>();\n        }\n\n        public void download(string options)\n        {\n            TransferOptions downloadOptions = null;\n            HttpWebRequest webRequest = null;\n            string callbackId;\n\n            try\n            {\n                // source, target, trustAllHosts, this._id, headers\n                string[] optionStrings = JSON.JsonHelper.Deserialize<string[]>(options);\n\n                downloadOptions = new TransferOptions();\n                downloadOptions.Url = optionStrings[0];\n                downloadOptions.FilePath = optionStrings[1];\n\n                bool trustAll = false;\n                bool.TryParse(optionStrings[2],out trustAll);\n                downloadOptions.TrustAllHosts = trustAll;\n\n                downloadOptions.Id = optionStrings[3];\n                downloadOptions.Headers = optionStrings[4];\n                downloadOptions.CallbackId = callbackId = optionStrings[5];\n            }\n            catch (Exception)\n            {\n                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));\n                return;\n            }\n\n            try\n            {\n                // is the URL a local app file?\n                if (downloadOptions.Url.StartsWith(\"x-wmapp0\") || downloadOptions.Url.StartsWith(\"file:\"))\n                {\n                    using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())\n                    {\n                        string cleanUrl = downloadOptions.Url.Replace(\"x-wmapp0:\", \"\").Replace(\"file:\", \"\").Replace(\"//\",\"\");\n\n                        // pre-emptively create any directories in the FilePath that do not exist\n                        string directoryName = getDirectoryName(downloadOptions.FilePath);\n                        if (!string.IsNullOrEmpty(directoryName) && !isoFile.DirectoryExists(directoryName))\n                        {\n                            isoFile.CreateDirectory(directoryName);\n                        }\n\n                        // just copy from one area of iso-store to another ...\n                        if (isoFile.FileExists(downloadOptions.Url))\n                        {\n                            isoFile.CopyFile(downloadOptions.Url, downloadOptions.FilePath);\n                        }\n                        else\n                        {\n                            // need to unpack resource from the dll\n                            Uri uri = new Uri(cleanUrl, UriKind.Relative);\n                            var resource = Application.GetResourceStream(uri);\n\n                            if (resource != null)\n                            {\n                                // create the file destination\n                                if (!isoFile.FileExists(downloadOptions.FilePath))\n                                {\n                                    var destFile = isoFile.CreateFile(downloadOptions.FilePath);\n                                    destFile.Close();\n                                }\n\n                                using (FileStream fileStream = new IsolatedStorageFileStream(downloadOptions.FilePath, FileMode.Open, FileAccess.Write, isoFile))\n                                {\n                                    long totalBytes = resource.Stream.Length;\n                                    int bytesRead = 0;\n                                    using (BinaryReader reader = new BinaryReader(resource.Stream))\n                                    {\n                                        using (BinaryWriter writer = new BinaryWriter(fileStream))\n                                        {\n                                            int BUFFER_SIZE = 1024;\n                                            byte[] buffer;\n\n                                            while (true)\n                                            {\n                                                buffer = reader.ReadBytes(BUFFER_SIZE);\n                                                // fire a progress event ?\n                                                bytesRead += buffer.Length;\n                                                if (buffer.Length > 0)\n                                                {\n                                                    writer.Write(buffer);\n                                                    DispatchFileTransferProgress(bytesRead, totalBytes, callbackId);\n                                                }\n                                                else\n                                                {\n                                                    writer.Close();\n                                                    reader.Close();\n                                                    fileStream.Close();\n                                                    break;\n                                                }\n                                            }\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n\n                    File.FileEntry entry = File.FileEntry.GetEntry(downloadOptions.FilePath);\n                    if (entry != null)\n                    {\n                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry), callbackId);\n                    }\n                    else\n                    {\n                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, File.NOT_FOUND_ERR), callbackId);\n                    }\n\n                    return;\n                }\n                else\n                {\n                    // otherwise it is web-bound, we will actually download it\n                    //Debug.WriteLine(\"Creating WebRequest for url : \" + downloadOptions.Url);\n                    webRequest = (HttpWebRequest)WebRequest.Create(downloadOptions.Url);\n                }\n            }\n            catch (Exception /*ex*/)\n            {\n                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR,\n                                      new FileTransferError(InvalidUrlError, downloadOptions.Url, null, 0)));\n                return;\n            }\n\n            if (downloadOptions != null && webRequest != null)\n            {\n                DownloadRequestState state = new DownloadRequestState();\n                state.options = downloadOptions;\n                state.request = webRequest;\n                InProcDownloads[downloadOptions.Id] = state;\n\n                try\n                {\n                    // Associate cookies with the request\n                    // This is an async call, so we need to await it in order to preserve proper control flow\n                    Task cookieTask = CopyCookiesFromWebBrowser(webRequest);\n                    cookieTask.Wait();\n                }\n                catch (AggregateException ae) \n                {\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR,\n                        new FileTransferError(FileTransfer.ConnectionError, downloadOptions.Url, downloadOptions.FilePath, 0, ae.InnerException.Message)));\n                    return;\n                }\n\n                if (!string.IsNullOrEmpty(downloadOptions.Headers))\n                {\n                    Dictionary<string, string> headers = parseHeaders(downloadOptions.Headers);\n                    foreach (string key in headers.Keys)\n                    {\n                        webRequest.Headers[key] = headers[key];\n                    }\n                }\n\n                try\n                {\n                    webRequest.BeginGetResponse(new AsyncCallback(downloadCallback), state);\n                }\n                catch (WebException)\n                {\n                    // eat it\n                }\n                // dispatch an event for progress ( 0 )\n                lock (state)\n                {\n                    if (!state.isCancelled)\n                    {\n                        var plugRes = new PluginResult(PluginResult.Status.OK, new FileTransferProgress());\n                        plugRes.KeepCallback = true;\n                        plugRes.CallbackId = callbackId;\n                        DispatchCommandResult(plugRes, callbackId);\n                    }\n                }\n            }\n        }\n\n        public void abort(string options)\n        {\n            Debug.WriteLine(\"Abort :: \" + options);\n            string[] optionStrings = JSON.JsonHelper.Deserialize<string[]>(options);\n            string id = optionStrings[0];\n            string callbackId = optionStrings[1];\n\n            if (id != null && InProcDownloads.ContainsKey(id))\n            {\n                DownloadRequestState state = InProcDownloads[id];\n                if (!state.isCancelled)\n                { // prevent multiple callbacks for the same abort\n                    state.isCancelled = true;\n                    if (!state.request.HaveResponse)\n                    {\n                        state.request.Abort();\n                        InProcDownloads.Remove(id);\n                        //callbackId = state.options.CallbackId;\n                        //state = null;\n                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR,\n                                                               new FileTransferError(FileTransfer.AbortError)),\n                                                               state.options.CallbackId);\n                    }\n                }\n            }\n            else\n            {\n                DispatchCommandResult(new PluginResult(PluginResult.Status.IO_EXCEPTION), callbackId); // TODO: is it an IO exception?\n            }\n        }\n\n        private void DispatchFileTransferProgress(long bytesLoaded, long bytesTotal, string callbackId, bool keepCallback = true)\n        {\n            Debug.WriteLine(\"DispatchFileTransferProgress : \" + callbackId);\n            // send a progress change event\n            FileTransferProgress progEvent = new FileTransferProgress(bytesTotal);\n            progEvent.BytesLoaded = bytesLoaded;\n            PluginResult plugRes = new PluginResult(PluginResult.Status.OK, progEvent);\n            plugRes.KeepCallback = keepCallback;\n            plugRes.CallbackId = callbackId;\n            DispatchCommandResult(plugRes, callbackId);\n        }\n\n        /// <summary>\n        ///\n        /// </summary>\n        /// <param name=\"asynchronousResult\"></param>\n        private void downloadCallback(IAsyncResult asynchronousResult)\n        {\n            DownloadRequestState reqState = (DownloadRequestState)asynchronousResult.AsyncState;\n            HttpWebRequest request = reqState.request;\n\n            string callbackId = reqState.options.CallbackId;\n            try\n            {\n                HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);\n\n                // send a progress change event\n                DispatchFileTransferProgress(0, response.ContentLength, callbackId);\n\n                using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())\n                {\n                    // create any directories in the path that do not exist\n                    string directoryName = getDirectoryName(reqState.options.FilePath);\n                    if (!string.IsNullOrEmpty(directoryName) && !isoFile.DirectoryExists(directoryName))\n                    {\n                        isoFile.CreateDirectory(directoryName);\n                    }\n\n                    // create the file if not exists\n                    if (!isoFile.FileExists(reqState.options.FilePath))\n                    {\n                        var file = isoFile.CreateFile(reqState.options.FilePath);\n                        file.Close();\n                    }\n\n                    using (FileStream fileStream = new IsolatedStorageFileStream(reqState.options.FilePath, FileMode.Open, FileAccess.Write, isoFile))\n                    {\n                        long totalBytes = response.ContentLength;\n                        int bytesRead = 0;\n                        using (BinaryReader reader = new BinaryReader(response.GetResponseStream()))\n                        {\n                            using (BinaryWriter writer = new BinaryWriter(fileStream))\n                            {\n                                int BUFFER_SIZE = 1024;\n                                byte[] buffer;\n\n                                while (true)\n                                {\n                                    buffer = reader.ReadBytes(BUFFER_SIZE);\n                                    // fire a progress event ?\n                                    bytesRead += buffer.Length;\n                                    if (buffer.Length > 0 && !reqState.isCancelled)\n                                    {\n                                        writer.Write(buffer);\n                                        DispatchFileTransferProgress(bytesRead, totalBytes, callbackId);\n                                    }\n                                    else\n                                    {\n                                        writer.Close();\n                                        reader.Close();\n                                        fileStream.Close();\n                                        break;\n                                    }\n                                    System.Threading.Thread.Sleep(1);\n                                }\n                            }\n                        }\n                    }\n                    if (reqState.isCancelled)\n                    {\n                        isoFile.DeleteFile(reqState.options.FilePath);\n                    }\n                }\n\n                if (reqState.isCancelled)\n                {\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(AbortError)),\n                  callbackId);\n                }\n                else\n                {\n                    File.FileEntry entry = new File.FileEntry(reqState.options.FilePath);\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry), callbackId);\n                }\n            }\n            catch (IsolatedStorageException)\n            {\n                // Trying to write the file somewhere within the IsoStorage.\n                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError)),\n                                      callbackId);\n            }\n            catch (SecurityException)\n            {\n                // Trying to write the file somewhere not allowed.\n                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError)),\n                                      callbackId);\n            }\n            catch (WebException webex)\n            {\n                // TODO: probably need better work here to properly respond with all http status codes back to JS\n                // Right now am jumping through hoops just to detect 404.\n                HttpWebResponse response = (HttpWebResponse)webex.Response;\n                if ((webex.Status == WebExceptionStatus.ProtocolError && response.StatusCode == HttpStatusCode.NotFound)\n                    || webex.Status == WebExceptionStatus.UnknownError)\n                {\n                    // Weird MSFT detection of 404... seriously... just give us the f(*&#$@ status code as a number ffs!!!\n                    // \"Numbers for HTTP status codes? Nah.... let's create our own set of enums/structs to abstract that stuff away.\"\n                    // FACEPALM\n                    // Or just cast it to an int, whiner ... -jm\n                    int statusCode = (int)response.StatusCode;\n                    string body = \"\";\n\n                    using (Stream streamResponse = response.GetResponseStream())\n                    {\n                        using (StreamReader streamReader = new StreamReader(streamResponse))\n                        {\n                            body = streamReader.ReadToEnd();\n                        }\n                    }\n                    FileTransferError ftError = new FileTransferError(ConnectionError, null, null, statusCode, body);\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ftError),\n                                          callbackId);\n                }\n                else\n                {\n                    lock (reqState)\n                    {\n                        if (!reqState.isCancelled)\n                        {\n                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR,\n                                                                   new FileTransferError(ConnectionError)),\n                                                  callbackId);\n                        }\n                        else\n                        {\n                            Debug.WriteLine(\"It happened\");\n                        }\n                    }\n                }\n            }\n            catch (Exception)\n            {\n                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR,\n                                                        new FileTransferError(FileNotFoundError)),\n                                      callbackId);\n            }\n\n            //System.Threading.Thread.Sleep(1000);\n            if (InProcDownloads.ContainsKey(reqState.options.Id))\n            {\n                InProcDownloads.Remove(reqState.options.Id);\n            }\n        }\n\n        /// <summary>\n        /// Read file from Isolated Storage and sends it to server\n        /// </summary>\n        /// <param name=\"asynchronousResult\"></param>\n        private void uploadCallback(IAsyncResult asynchronousResult)\n        {\n            DownloadRequestState reqState = (DownloadRequestState)asynchronousResult.AsyncState;\n            HttpWebRequest webRequest = reqState.request;\n            string callbackId = reqState.options.CallbackId;\n\n            try\n            {\n                using (Stream requestStream = (webRequest.EndGetRequestStream(asynchronousResult)))\n                {\n                    string lineStart = \"--\";\n                    string lineEnd = Environment.NewLine;\n                    byte[] boundaryBytes = System.Text.Encoding.UTF8.GetBytes(lineStart + Boundary + lineEnd);\n                    string formdataTemplate = \"Content-Disposition: form-data; name=\\\"{0}\\\"\" + lineEnd + lineEnd + \"{1}\" + lineEnd;\n\n                    if (!string.IsNullOrEmpty(reqState.options.Params))\n                    {\n                        Dictionary<string, string> paramMap = parseHeaders(reqState.options.Params);\n                        foreach (string key in paramMap.Keys)\n                        {\n                            requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);\n                            string formItem = string.Format(formdataTemplate, key, paramMap[key]);\n                            byte[] formItemBytes = System.Text.Encoding.UTF8.GetBytes(formItem);\n                            requestStream.Write(formItemBytes, 0, formItemBytes.Length);\n                        }\n                    }\n                    using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())\n                    {\n                        if (!isoFile.FileExists(reqState.options.FilePath))\n                        {\n                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(FileNotFoundError, reqState.options.Server, reqState.options.FilePath, 0)));\n                            return;\n                        }\n\n                        byte[] endRequest = System.Text.Encoding.UTF8.GetBytes(lineEnd + lineStart + Boundary + lineStart + lineEnd);\n                        long totalBytesToSend = 0;\n\n                        using (FileStream fileStream = new IsolatedStorageFileStream(reqState.options.FilePath, FileMode.Open, isoFile))\n                        {\n                            string headerTemplate = \"Content-Disposition: form-data; name=\\\"{0}\\\"; filename=\\\"{1}\\\"\" + lineEnd + \"Content-Type: {2}\" + lineEnd + lineEnd;\n                            string header = string.Format(headerTemplate, reqState.options.FileKey, reqState.options.FileName, reqState.options.MimeType);\n                            byte[] headerBytes = System.Text.Encoding.UTF8.GetBytes(header);\n\n                            byte[] buffer = new byte[4096];\n                            int bytesRead = 0;\n                            //sent bytes needs to be reseted before new upload\n                            bytesSent = 0;\n                            totalBytesToSend = fileStream.Length;\n\n                            requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);\n\n                            requestStream.Write(headerBytes, 0, headerBytes.Length);\n\n                            while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)\n                            {\n                                if (!reqState.isCancelled)\n                                {\n                                    requestStream.Write(buffer, 0, bytesRead);\n                                    bytesSent += bytesRead;\n                                    DispatchFileTransferProgress(bytesSent, totalBytesToSend, callbackId);\n                                    System.Threading.Thread.Sleep(1);\n                                }\n                                else\n                                {\n                                    throw new Exception(\"UploadCancelledException\");\n                                }\n                            }\n                        }\n\n                        requestStream.Write(endRequest, 0, endRequest.Length);\n                    }\n                }\n                // webRequest\n\n                webRequest.BeginGetResponse(ReadCallback, reqState);\n            }\n            catch (Exception /*ex*/)\n            {\n                if (!reqState.isCancelled)\n                {\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new FileTransferError(ConnectionError)), callbackId);\n                }\n            }\n        }\n\n        /// <summary>\n        /// Reads response into FileUploadResult\n        /// </summary>\n        /// <param name=\"asynchronousResult\"></param>\n        private void ReadCallback(IAsyncResult asynchronousResult)\n        {\n            DownloadRequestState reqState = (DownloadRequestState)asynchronousResult.AsyncState;\n            try\n            {\n                HttpWebRequest webRequest = reqState.request;\n                string callbackId = reqState.options.CallbackId;\n\n                if (InProcDownloads.ContainsKey(reqState.options.Id))\n                {\n                    InProcDownloads.Remove(reqState.options.Id);\n                }\n\n                using (HttpWebResponse response = (HttpWebResponse)webRequest.EndGetResponse(asynchronousResult))\n                {\n                    using (Stream streamResponse = response.GetResponseStream())\n                    {\n                        using (StreamReader streamReader = new StreamReader(streamResponse))\n                        {\n                            string responseString = streamReader.ReadToEnd();\n                            Deployment.Current.Dispatcher.BeginInvoke(() =>\n                            {\n                                DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileUploadResult(bytesSent, (long)response.StatusCode, responseString)));\n                            });\n                        }\n                    }\n                }\n            }\n            catch (WebException webex)\n            {\n                // TODO: probably need better work here to properly respond with all http status codes back to JS\n                // Right now am jumping through hoops just to detect 404.\n                if ((webex.Status == WebExceptionStatus.ProtocolError && ((HttpWebResponse)webex.Response).StatusCode == HttpStatusCode.NotFound)\n                    || webex.Status == WebExceptionStatus.UnknownError)\n                {\n                    int statusCode = (int)((HttpWebResponse)webex.Response).StatusCode;\n                    FileTransferError ftError = new FileTransferError(ConnectionError, null, null, statusCode);\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ftError), reqState.options.CallbackId);\n                }\n                else\n                {\n                    DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR,\n                                                           new FileTransferError(ConnectionError)),\n                                          reqState.options.CallbackId);\n                }\n            }\n            catch (Exception /*ex*/)\n            {\n                FileTransferError transferError = new FileTransferError(ConnectionError, reqState.options.Server, reqState.options.FilePath, 403);\n                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, transferError), reqState.options.CallbackId);\n            }\n        }\n\n        // Gets the full path without the filename\n        private string getDirectoryName(String filePath)\n        {\n            string directoryName;\n            try\n            {\n                directoryName = filePath.Substring(0, filePath.LastIndexOf('/'));\n            }\n            catch\n            {\n                directoryName = \"\";\n            }\n            return directoryName;\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/tests/plugin.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  Licensed to the Apache Software Foundation (ASF) under one\n  or more contributor license agreements.  See the NOTICE file\n  distributed with this work for additional information\n  regarding copyright ownership.  The ASF licenses this file\n  to you under the Apache License, Version 2.0 (the\n  \"License\"); you may not use this file except in compliance\n  with the License.  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing,\n  software distributed under the License is distributed on an\n  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n  KIND, either express or implied.  See the License for the\n  specific language governing permissions and limitations\n  under the License.\n-->\n\n<plugin xmlns=\"http://apache.org/cordova/ns/plugins/1.0\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    id=\"cordova-plugin-file-transfer-tests\"\n    version=\"1.5.1\">\n    <name>Cordova File Transfer Plugin Tests</name>\n    <license>Apache 2.0</license>\n\n    <js-module src=\"tests.js\" name=\"tests\">\n    </js-module>\n</plugin>\n"
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/tests/tests.js",
    "content": "/*\n*\n* Licensed to the Apache Software Foundation (ASF) under one\n* or more contributor license agreements.  See the NOTICE file\n* distributed with this work for additional information\n* regarding copyright ownership.  The ASF licenses this file\n* to you under the Apache License, Version 2.0 (the\n* \"License\"); you may not use this file except in compliance\n* with the License.  You may obtain a copy of the License at\n*\n*   http://www.apache.org/licenses/LICENSE-2.0\n*\n* Unless required by applicable law or agreed to in writing,\n* software distributed under the License is distributed on an\n* \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n* KIND, either express or implied.  See the License for the\n* specific language governing permissions and limitations\n* under the License.\n*\n*/\n\n/* global exports, cordova, FileTransfer, FileTransferError, FileUploadOptions, LocalFileSystem */\n\n/* jshint jasmine: true */\n\nexports.defineAutoTests = function () {\n\n    \"use strict\";\n\n    // constants\n    var ONE_SECOND = 1000; // in milliseconds\n    var GRACE_TIME_DELTA = 600; // in milliseconds\n    var DEFAULT_FILESYSTEM_SIZE = 1024 * 50; // filesystem size in bytes\n    var UNKNOWN_HOST = \"http://foobar.apache.org\";\n    var HEADERS_ECHO = \"http://whatheaders.com\"; // NOTE: this site is very useful!\n    var DOWNLOAD_TIMEOUT = 7 * ONE_SECOND;\n    var WINDOWS_UNKNOWN_HOST_TIMEOUT = 35 * ONE_SECOND;\n    var UPLOAD_TIMEOUT = 7 * ONE_SECOND;\n    var ABORT_DELAY = 100; // for abort() tests\n    var LATIN1_SYMBOLS = '¥§©ÆÖÑøøø¼';\n    var DATA_URI_PREFIX = \"data:image/png;base64,\";\n    var DATA_URI_CONTENT = \"iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==\";\n    var DATA_URI_CONTENT_LENGTH = 85; // bytes. (This is the raw file size: used https://en.wikipedia.org/wiki/File:Red-dot-5px.png from https://en.wikipedia.org/wiki/Data_URI_scheme)\n\n    // config for upload test server\n    // NOTE:\n    //      more info at https://github.com/apache/cordova-labs/tree/cordova-filetransfer\n    var SERVER                  = \"http://cordova-vm.apache.org:5000\";\n    var SERVER_WITH_CREDENTIALS = \"http://cordova_user:cordova_password@cordova-vm.apache.org:5000\";\n\n    // flags\n    var isWindows = cordova.platformId === \"windows8\" || cordova.platformId === \"windows\";\n    var isWP8 = cordova.platformId === \"windowsphone\";\n    var isBrowser = cordova.platformId === \"browser\";\n    var isIE = isBrowser && navigator.userAgent.indexOf(\"Trident\") >= 0;\n    var isIos = cordova.platformId === \"ios\";\n\n    // tests\n    describe(\"FileTransferError\", function () {\n\n        it(\"should exist\", function () {\n            expect(FileTransferError).toBeDefined();\n        });\n\n        it(\"should be constructable\", function () {\n            var transferError = new FileTransferError();\n            expect(transferError).toBeDefined();\n        });\n\n        it(\"filetransfer.spec.3 should expose proper constants\", function () {\n\n            expect(FileTransferError.FILE_NOT_FOUND_ERR).toBeDefined();\n            expect(FileTransferError.INVALID_URL_ERR).toBeDefined();\n            expect(FileTransferError.CONNECTION_ERR).toBeDefined();\n            expect(FileTransferError.ABORT_ERR).toBeDefined();\n            expect(FileTransferError.NOT_MODIFIED_ERR).toBeDefined();\n\n            expect(FileTransferError.FILE_NOT_FOUND_ERR).toBe(1);\n            expect(FileTransferError.INVALID_URL_ERR).toBe(2);\n            expect(FileTransferError.CONNECTION_ERR).toBe(3);\n            expect(FileTransferError.ABORT_ERR).toBe(4);\n            expect(FileTransferError.NOT_MODIFIED_ERR).toBe(5);\n        });\n    });\n\n    describe(\"FileUploadOptions\", function () {\n\n        it(\"should exist\", function () {\n            expect(FileUploadOptions).toBeDefined();\n        });\n\n        it(\"should be constructable\", function () {\n            var transferOptions = new FileUploadOptions();\n            expect(transferOptions).toBeDefined();\n        });\n    });\n\n    describe(\"FileTransfer\", function () {\n        this.persistentRoot = null;\n        this.tempRoot       = null;\n\n        // named callbacks\n        var unexpectedCallbacks = {\n            httpFail:          function () {},\n            httpWin:           function () {},\n            fileSystemFail:    function () {},\n            fileSystemWin:     function () {},\n            fileOperationFail: function () {},\n            fileOperationWin:  function () {},\n        };\n\n        var expectedCallbacks = {\n            unsupportedOperation: function (response) {\n                console.log(\"spec called unsupported functionality; response:\", response);\n            },\n        };\n\n        // helpers\n        var deleteFile = function (fileSystem, name, done) {\n            fileSystem.getFile(name, null,\n                function (fileEntry) {\n                    fileEntry.remove(\n                        function () {\n                            done();\n                        },\n                        function () {\n                            throw new Error(\"failed to delete: '\" + name + \"'\");\n                        }\n                    );\n                },\n                function () {\n                    done();\n                }\n            );\n        };\n\n        var writeFile = function (fileSystem, name, content, success, done) {\n            var fileOperationFail = function() {\n                unexpectedCallbacks.fileOperationFail();\n                done();\n            };\n\n            fileSystem.getFile(name, { create: true },\n                function (fileEntry) {\n                    fileEntry.createWriter(function (writer) {\n\n                        writer.onwrite = function () {\n                            success(fileEntry);\n                        };\n\n                        writer.onabort = function (evt) {\n                            throw new Error(\"aborted creating test file '\" + name + \"': \" + evt);\n                        };\n\n                        writer.error = function (evt) {\n                            throw new Error(\"aborted creating test file '\" + name + \"': \" + evt);\n                        };\n\n                        if (cordova.platformId === \"browser\") {\n                            var blob = new Blob([content + \"\\n\"], { type: \"text/plain\" });\n                            writer.write(blob);\n                        } else {\n                            writer.write(content + \"\\n\");\n                        }\n\n                    }, fileOperationFail);\n                },\n                function () {\n                    throw new Error(\"could not create test file '\" + name + \"'\");\n                }\n            );\n        };\n\n        // according to documentation, wp8 does not support onProgress:\n        // https://github.com/apache/cordova-plugin-file-transfer/blob/master/doc/index.md#supported-platforms\n        var wp8OnProgressHandler = function () {};\n\n        var defaultOnProgressHandler = function (event) {\n            if (event.lengthComputable) {\n                expect(event.loaded).toBeGreaterThan(1);\n                expect(event.total).toBeGreaterThan(0);\n                expect(event.total).not.toBeLessThan(event.loaded);\n                expect(event.lengthComputable).toBe(true, \"lengthComputable\");\n            } else {\n                // In IE, when lengthComputable === false, event.total somehow is equal to 2^64\n                if (isIE) {\n                    expect(event.total).toBe(Math.pow(2, 64));\n                } else {\n                    // iOS returns -1, and other platforms return 0\n                    expect(event.total).toBeLessThan(1);\n                }\n            }\n        };\n\n        var getMalformedUrl = function () {\n            if (cordova.platformId === \"android\" || cordova.platformId === \"amazon-fireos\") {\n                // bad protocol causes a MalformedUrlException on Android\n                return \"httpssss://example.com\";\n            } else {\n                // iOS doesn't care about protocol, space in hostname causes error\n                return \"httpssss://exa mple.com\";\n            }\n        };\n\n        // NOTE:\n        //      there are several beforeEach calls, one per async call; since calling done()\n        //      signifies a completed async call, each async call needs its own done(), and\n        //      therefore its own beforeEach\n        beforeEach(function (done) {\n            var specContext = this;\n\n            window.requestFileSystem(LocalFileSystem.PERSISTENT, DEFAULT_FILESYSTEM_SIZE,\n                function (fileSystem) {\n                    specContext.persistentRoot = fileSystem.root;\n                    done();\n                },\n                function () {\n                    throw new Error(\"Failed to initialize persistent file system.\");\n                }\n            );\n        });\n\n        beforeEach(function (done) {\n            var specContext = this;\n\n            window.requestFileSystem(LocalFileSystem.TEMPORARY, DEFAULT_FILESYSTEM_SIZE,\n                function (fileSystem) {\n                    specContext.tempRoot = fileSystem.root;\n                    done();\n                },\n                function () {\n                    throw new Error(\"Failed to initialize temporary file system.\");\n                }\n            );\n        });\n\n        // spy on all named callbacks\n        beforeEach(function() {\n\n            // ignore the actual implementations of the unexpected callbacks\n            for (var callback in unexpectedCallbacks) {\n                if (unexpectedCallbacks.hasOwnProperty(callback)) {\n                    spyOn(unexpectedCallbacks, callback);\n                }\n            }\n\n            // but run the implementations of the expected callbacks\n            for (callback in expectedCallbacks) { // jshint ignore: line\n                if (expectedCallbacks.hasOwnProperty(callback)) {\n                    spyOn(expectedCallbacks, callback).and.callThrough();\n                }\n            }\n        });\n\n        // at the end, check that none of the unexpected callbacks got called,\n        // and act on the expected callbacks\n        afterEach(function() {\n            for (var callback in unexpectedCallbacks) {\n                if (unexpectedCallbacks.hasOwnProperty(callback)) {\n                    expect(unexpectedCallbacks[callback]).not.toHaveBeenCalled();\n                }\n            }\n\n            if (expectedCallbacks.unsupportedOperation.calls.any()) {\n                pending();\n            }\n        });\n\n        it(\"should initialise correctly\", function() {\n            expect(this.persistentRoot).toBeDefined();\n            expect(this.tempRoot).toBeDefined();\n        });\n\n        it(\"should exist\", function () {\n            expect(FileTransfer).toBeDefined();\n        });\n\n        it(\"filetransfer.spec.1 should be constructable\", function () {\n            var transfer = new FileTransfer();\n            expect(transfer).toBeDefined();\n        });\n\n        it(\"filetransfer.spec.2 should expose proper functions\", function () {\n\n            var transfer = new FileTransfer();\n\n            expect(transfer.upload).toBeDefined();\n            expect(transfer.download).toBeDefined();\n\n            expect(transfer.upload).toEqual(jasmine.any(Function));\n            expect(transfer.download).toEqual(jasmine.any(Function));\n        });\n\n        describe(\"methods\", function() {\n            this.transfer       = null;\n            this.root           = null;\n            this.fileName       = null;\n            this.localFilePath  = null;\n\n            beforeEach(function() {\n\n                this.transfer = new FileTransfer();\n\n                // assign onprogress handler\n                this.transfer.onprogress = isWP8 ? wp8OnProgressHandler : defaultOnProgressHandler;\n\n                // spy on the onprogress handler, but still call through to it\n                spyOn(this.transfer, \"onprogress\").and.callThrough();\n\n                this.root          = this.persistentRoot;\n                this.fileName      = \"testFile.txt\";\n                this.localFilePath = this.root.toURL() + this.fileName;\n            });\n\n            // NOTE:\n            //      if download tests are failing, check the\n            //      URL white list for the following URLs:\n            //         - 'httpssss://example.com'\n            //         - 'apache.org', with subdomains=\"true\"\n            //         - 'cordova-filetransfer.jitsu.com'\n            describe(\"download\", function () {\n\n                // helpers\n                var verifyDownload = function (fileEntry, specContext) {\n                    expect(fileEntry.name).toBe(specContext.fileName);\n                };\n\n                // delete the downloaded file\n                afterEach(function (done) {\n                    deleteFile(this.root, this.fileName, done);\n                });\n\n                it(\"ensures that test file does not exist\", function (done) {\n                    deleteFile(this.root, this.fileName, done);\n                });\n\n                it(\"filetransfer.spec.4 should download a file\", function (done) {\n\n                    var fileURL = SERVER + \"/robots.txt\";\n                    var specContext = this;\n\n                    var fileWin = function (blob) {\n\n                        if (specContext.transfer.onprogress.calls.any()) {\n                            var lastProgressEvent = specContext.transfer.onprogress.calls.mostRecent().args[0];\n                            expect(lastProgressEvent.loaded).not.toBeGreaterThan(blob.size);\n                        } else {\n                            console.log(\"no progress events were emitted\");\n                        }\n\n                        done();\n                    };\n\n                    var fileSystemFail = function() {\n                        unexpectedCallbacks.fileSystemFail();\n                        done();\n                    };\n\n                    var downloadFail = function() {\n                        unexpectedCallbacks.httpFail();\n                        done();\n                    };\n\n                    var downloadWin = function (entry) {\n\n                        verifyDownload(entry, specContext);\n\n                        // verify the FileEntry representing this file\n                        entry.file(fileWin, fileSystemFail);\n                    };\n\n                    specContext.transfer.download(fileURL, specContext.localFilePath, downloadWin, downloadFail);\n                }, DOWNLOAD_TIMEOUT);\n\n                it(\"filetransfer.spec.5 should download a file using http basic auth\", function (done) {\n\n                    var fileURL = SERVER_WITH_CREDENTIALS + \"/download_basic_auth\";\n                    var specContext = this;\n\n                    var downloadWin = function (entry) {\n                        verifyDownload(entry, specContext);\n                        done();\n                    };\n\n                    var downloadFail = function() {\n                        unexpectedCallbacks.httpFail();\n                        done();\n                    };\n\n                    specContext.transfer.download(fileURL, specContext.localFilePath, downloadWin, downloadFail);\n                }, DOWNLOAD_TIMEOUT);\n\n                it(\"filetransfer.spec.6 should get 401 status on http basic auth failure\", function (done) {\n\n                    // NOTE:\n                    //      using server without credentials\n                    var fileURL = SERVER + \"/download_basic_auth\";\n\n                    var downloadFail = function (error) {\n                        expect(error.http_status).toBe(401);\n                        expect(error.http_status).not.toBe(404, \"Ensure \" + fileURL + \" is in the white list\");\n                        done();\n                    };\n\n                    var downloadWin = function() {\n                        unexpectedCallbacks.httpWin();\n                        done();\n                    };\n\n                    this.transfer.download(fileURL, this.localFilePath, downloadWin, downloadFail, null,\n                        {\n                            headers: {\n                                \"If-Modified-Since\": \"Thu, 19 Mar 2015 00:00:00 GMT\"\n                            }\n                        });\n                }, DOWNLOAD_TIMEOUT);\n\n                it(\"filetransfer.spec.7 should download a file using file:// (when hosted from file://)\", function (done) {\n\n                    // for Windows platform it's ms-appdata:/// by default, not file://\n                    if (isWindows) {\n                        pending();\n                        return;\n                    }\n\n                    var fileURL = window.location.protocol + \"//\" + window.location.pathname.replace(/ /g, \"%20\");\n                    var specContext = this;\n\n                    if (!/^file:/.exec(fileURL) && cordova.platformId !== \"blackberry10\") {\n                        if (cordova.platformId === \"windowsphone\") {\n                            expect(fileURL).toMatch(/^x-wmapp0:/);\n                        }\n                        done();\n                        return;\n                    }\n\n                    var downloadWin = function (entry) {\n                        verifyDownload(entry, specContext);\n                        done();\n                    };\n\n                    var downloadFail = function() {\n                        unexpectedCallbacks.httpFail();\n                        done();\n                    };\n\n                    specContext.transfer.download(fileURL, specContext.localFilePath, downloadWin, downloadFail);\n                }, DOWNLOAD_TIMEOUT);\n\n                it(\"filetransfer.spec.8 should download a file using https://\", function (done) {\n\n                    var fileURL = \"https://www.apache.org/licenses/\";\n                    var specContext = this;\n\n                    var downloadFail = function() {\n                        unexpectedCallbacks.httpFail();\n                        done();\n                    };\n\n                    var fileOperationFail = function() {\n                        unexpectedCallbacks.fileOperationFail();\n                        done();\n                    };\n\n                    var fileSystemFail = function() {\n                        unexpectedCallbacks.fileSystemFail();\n                        done();\n                    };\n\n                    var fileWin = function (file) {\n\n                        var reader = new FileReader();\n\n                        reader.onerror = fileOperationFail;\n                        reader.onload  = function () {\n                            expect(reader.result).toMatch(/The Apache Software Foundation/);\n                            done();\n                        };\n\n                        reader.readAsText(file);\n                    };\n\n                    var downloadWin = function (entry) {\n                        verifyDownload(entry, specContext);\n                        entry.file(fileWin, fileSystemFail);\n                    };\n\n                    specContext.transfer.download(fileURL, specContext.localFilePath, downloadWin, downloadFail);\n                }, DOWNLOAD_TIMEOUT);\n\n                it(\"filetransfer.spec.11 should call the error callback on abort()\", function (done) {\n\n                    var fileURL = \"http://cordova.apache.org/downloads/BlueZedEx.mp3\";\n                    fileURL = fileURL + \"?q=\" + (new Date()).getTime();\n                    var specContext = this;\n\n                    var downloadWin = function () {\n                        unexpectedCallbacks.httpWin();\n                        done();\n                    };\n\n                    specContext.transfer.download(fileURL, specContext.localFilePath, downloadWin, done);\n                    setTimeout(function() {\n                        specContext.transfer.abort();\n                    }, ABORT_DELAY);\n                }, DOWNLOAD_TIMEOUT);\n\n                it(\"filetransfer.spec.9 should not leave partial file due to abort\", function (done) {\n\n                    var fileURL = \"http://cordova.apache.org/downloads/logos_2.zip\";\n                    var specContext = this;\n\n                    var fileSystemWin = function() {\n                        unexpectedCallbacks.fileSystemWin();\n                        done();\n                    };\n\n                    var downloadWin = function() {\n                        unexpectedCallbacks.httpWin();\n                        done();\n                    };\n\n                    var downloadFail = function (error) {\n\n                        var result = (error.code === FileTransferError.ABORT_ERR || error.code === FileTransferError.CONNECTION_ERR)? true: false;\n                        if (!result) {\n                            fail(\"Expected \" + error.code + \" to be \" + FileTransferError.ABORT_ERR + \" or \" + FileTransferError.CONNECTION_ERR);\n                        }\n                        expect(specContext.transfer.onprogress).toHaveBeenCalled();\n\n                        // check that there is no file\n                        specContext.root.getFile(specContext.fileName, null, fileSystemWin, done);\n                    };\n\n                    // abort at the first onprogress event\n                    specContext.transfer.onprogress = function (event) {\n                        if (event.loaded > 0) {\n                            specContext.transfer.abort();\n                        }\n                    };\n\n                    spyOn(specContext.transfer, \"onprogress\").and.callThrough();\n\n                    specContext.transfer.download(fileURL, specContext.localFilePath, downloadWin, downloadFail);\n                }, DOWNLOAD_TIMEOUT);\n\n                it(\"filetransfer.spec.10 should be stopped by abort()\", function (done) {\n\n                    var fileURL = \"http://cordova.apache.org/downloads/BlueZedEx.mp3\";\n                    fileURL = fileURL + \"?q=\" + (new Date()).getTime();\n                    var specContext = this;\n\n                    expect(specContext.transfer.abort).not.toThrow(); // should be a no-op.\n\n                    var downloadWin = function() {\n                        unexpectedCallbacks.httpWin();\n                        done();\n                    };\n\n                    var downloadFail = function (error) {\n\n                        expect(error.code).toBe(FileTransferError.ABORT_ERR);\n\n                        // delay calling done() to wait for the bogus abort()\n                        setTimeout(done, GRACE_TIME_DELTA * 2);\n                    };\n\n                    specContext.transfer.download(fileURL, specContext.localFilePath, downloadWin, downloadFail);\n                    setTimeout(function() {\n                        specContext.transfer.abort();\n                    }, ABORT_DELAY);\n\n                    // call abort() again, after a time greater than the grace period\n                    setTimeout(function () {\n                        expect(specContext.transfer.abort).not.toThrow();\n                    }, GRACE_TIME_DELTA);\n                }, DOWNLOAD_TIMEOUT);\n\n                it(\"filetransfer.spec.12 should get http status on failure\", function (done) {\n\n                    var fileURL = SERVER + \"/404\";\n\n                    var downloadFail = function (error) {\n\n                        expect(error.http_status).not.toBe(401, \"Ensure \" + fileURL + \" is in the white list\");\n                        expect(error.http_status).toBe(404);\n\n                        // wp8 does not make difference between 404 and unknown host\n                        if (isWP8) {\n                            expect(error.code).toBe(FileTransferError.CONNECTION_ERR);\n                        } else {\n                            expect(error.code).toBe(FileTransferError.FILE_NOT_FOUND_ERR);\n                        }\n\n                        done();\n                    };\n\n                    var downloadWin = function() {\n                        unexpectedCallbacks.httpWin();\n                        done();\n                    };\n\n                    this.transfer.download(fileURL, this.localFilePath, downloadWin, downloadFail);\n                }, DOWNLOAD_TIMEOUT);\n\n                it(\"filetransfer.spec.13 should get http body on failure\", function (done) {\n\n                    var fileURL = SERVER + \"/404\";\n\n                    var downloadFail = function (error) {\n\n                        expect(error.http_status).not.toBe(401, \"Ensure \" + fileURL + \" is in the white list\");\n                        expect(error.http_status).toBe(404);\n\n                        expect(error.body).toBeDefined();\n                        expect(error.body).toMatch(\"You requested a 404\");\n\n                        done();\n                    };\n\n                    var downloadWin = function() {\n                        unexpectedCallbacks.httpWin();\n                        done();\n                    };\n\n                    this.transfer.download(fileURL, this.localFilePath, downloadWin, downloadFail);\n                }, DOWNLOAD_TIMEOUT);\n\n                it(\"filetransfer.spec.14 should handle malformed urls\", function (done) {\n\n                    var fileURL = getMalformedUrl();\n\n                    var downloadFail = function (error) {\n\n                        // Note: Android needs the bad protocol to be added to the access list\n                        // <access origin=\".*\"/> won't match because ^https?:// is prepended to the regex\n                        // The bad protocol must begin with http to avoid automatic prefix\n                        expect(error.http_status).not.toBe(401, \"Ensure \" + fileURL + \" is in the white list\");\n                        expect(error.code).toBe(FileTransferError.INVALID_URL_ERR);\n\n                        done();\n                    };\n\n                    var downloadWin = function() {\n                        unexpectedCallbacks.httpWin();\n                        done();\n                    };\n\n                    this.transfer.download(fileURL, this.localFilePath, downloadWin, downloadFail);\n                });\n\n                it(\"filetransfer.spec.15 should handle unknown host\", function (done) {\n                    var fileURL = UNKNOWN_HOST;\n\n                    var downloadFail = function (error) {\n                        expect(error.code).toBe(FileTransferError.CONNECTION_ERR);\n                        done();\n                    };\n\n                    var downloadWin = function() {\n                        unexpectedCallbacks.httpWin();\n                        done();\n                    };\n\n                    // turn off the onprogress handler\n                    this.transfer.onprogress = function () {};\n\n                    this.transfer.download(fileURL, this.localFilePath, downloadWin, downloadFail);\n                }, isWindows ? WINDOWS_UNKNOWN_HOST_TIMEOUT : DOWNLOAD_TIMEOUT);\n\n                it(\"filetransfer.spec.16 should handle bad file path\", function (done) {\n                    var fileURL = SERVER;\n\n                    var downloadWin = function() {\n                        unexpectedCallbacks.httpWin();\n                        done();\n                    };\n\n                    this.transfer.download(fileURL, \"c:\\\\54321\", downloadWin, done);\n                });\n\n                it(\"filetransfer.spec.17 progress should work with gzip encoding\", function (done) {\n\n                    // lengthComputable false on bb10 when downloading gzip\n                    if (cordova.platformId === \"blackberry10\") {\n                        pending();\n                        return;\n                    }\n\n                    var fileURL = \"http://www.apache.org/\";\n                    var specContext = this;\n\n                    var downloadWin = function (entry) {\n                        verifyDownload(entry, specContext);\n                        done();\n                    };\n\n                    var downloadFail = function () {\n                        unexpectedCallbacks.httpFail();\n                        done();\n                    };\n\n                    specContext.transfer.download(fileURL, specContext.localFilePath, downloadWin,downloadFail);\n                }, DOWNLOAD_TIMEOUT);\n\n                it(\"filetransfer.spec.30 downloaded file entries should have a toNativeURL method\", function (done) {\n\n                    if (cordova.platformId === \"browser\") {\n                        pending();\n                        return;\n                    }\n\n                    var fileURL = SERVER + \"/robots.txt\";\n\n                    var downloadWin = function (entry) {\n\n                        expect(entry.toNativeURL).toBeDefined();\n                        expect(entry.toNativeURL).toEqual(jasmine.any(Function));\n\n                        var nativeURL = entry.toNativeURL();\n\n                        expect(nativeURL).toBeTruthy();\n                        expect(nativeURL).toEqual(jasmine.any(String));\n\n                        if (isWindows) {\n                            expect(nativeURL.substring(0, 14)).toBe(\"ms-appdata:///\");\n                        } else if (isWP8) {\n                            expect(nativeURL.substring(0, 1)).toBe(\"/\");\n                        } else {\n                            expect(nativeURL.substring(0, 7)).toBe(\"file://\");\n                        }\n\n                        done();\n                    };\n\n                    var downloadFail = function() {\n                        unexpectedCallbacks.httpFail();\n                        done();\n                    };\n\n                    this.transfer.download(fileURL, this.localFilePath, downloadWin, downloadFail);\n                }, DOWNLOAD_TIMEOUT);\n\n                it(\"filetransfer.spec.28 (compatibility) should be able to download a file using local paths\", function (done) {\n\n                    var fileURL = SERVER + \"/robots.txt\";\n                    var specContext = this;\n\n                    var unsupported = function (response) {\n                        expectedCallbacks.unsupportedOperation(response);\n                        done();\n                    };\n\n                    var downloadWin = function (entry) {\n                        verifyDownload(entry, specContext);\n                        done();\n                    };\n\n                    var internalFilePath;\n                    if (specContext.root.toInternalURL) {\n                        internalFilePath = specContext.root.toInternalURL() + specContext.fileName;\n                    } else {\n                        internalFilePath = specContext.localFilePath;\n                    }\n\n                    var downloadFail = function() {\n                        unexpectedCallbacks.httpFail();\n                        done();\n                    };\n\n                    // This is an undocumented interface to File which exists only for testing\n                    // backwards compatibilty. By obtaining the raw filesystem path of the download\n                    // location, we can pass that to transfer.download() to make sure that previously-stored\n                    // paths are still valid.\n                    cordova.exec(function (localPath) {\n                        specContext.transfer.download(fileURL, localPath, downloadWin, downloadFail);\n                    }, unsupported, \"File\", \"_getLocalFilesystemPath\", [internalFilePath]);\n                });\n\n                it(\"filetransfer.spec.33 should properly handle 304\", function (done) {\n\n                    if (isWP8) {\n                        pending();\n                        return;\n                    }\n\n                    var imageURL = \"http://apache.org/images/feather-small.gif\";\n                    var lastModified = new Date();\n\n                    var downloadFail = function (error) {\n                        expect(error.http_status).toBe(304);\n                        expect(error.code).toBe(FileTransferError.NOT_MODIFIED_ERR);\n                        done();\n                    };\n\n                    var downloadWin = function() {\n                        unexpectedCallbacks.httpWin();\n                        done();\n                    };\n\n                    this.transfer.download(imageURL + \"?q=\" + lastModified.getTime(), this.localFilePath, downloadWin, downloadFail, null,\n                        {\n                            headers: {\n                                \"If-Modified-Since\": lastModified.toUTCString()\n                            }\n                        });\n                }, DOWNLOAD_TIMEOUT);\n\n                it(\"filetransfer.spec.35 304 should not result in the deletion of a cached file\", function (done) {\n\n                    if (isWP8) {\n                        pending();\n                        return;\n                    }\n\n                    var imageURL = \"http://apache.org/images/feather-small.gif\";\n                    var lastModified = new Date();\n                    var specContext = this;\n\n                    var fileOperationFail = function() {\n                        unexpectedCallbacks.fileOperationFail();\n                        done();\n                    };\n\n                    var fileSystemFail = function() {\n                        unexpectedCallbacks.fileSystemFail();\n                        done();\n                    };\n\n                    var httpWin =  function() {\n                        unexpectedCallbacks.httpWin();\n                        done();\n                    };\n\n                    var httpFail =  function() {\n                        unexpectedCallbacks.httpFail();\n                        done();\n                    };\n\n                    var downloadFail = function (error) {\n                        expect(error.http_status).toBe(304);\n                        expect(error.code).toBe(FileTransferError.NOT_MODIFIED_ERR);\n\n                        specContext.persistentRoot.getFile(specContext.fileName, { create: false },\n                            function (entry) {\n                                var fileWin = function (file) {\n                                    var reader = new FileReader();\n\n                                    reader.onerror = fileOperationFail;\n                                    reader.onloadend  = function () {\n\n                                        expect(reader.result).toBeTruthy();\n                                        if (reader.result !== null) {\n                                            expect(reader.result.length).toBeGreaterThan(0);\n                                        }\n\n                                        done();\n                                    };\n\n                                    reader.readAsBinaryString(file);\n                                };\n\n                                entry.file(fileWin, fileSystemFail);\n                            },\n                            function (err) {\n                                expect(\"Could not open test file '\" + specContext.fileName + \"': \" + JSON.stringify(err)).not.toBeDefined();\n                                done();\n                            }\n                        );\n                    };\n\n                    // Adding parameters to the requests to avoid caching on iOS, which leads to 200\n                    // instead of 304 in result of the second request. (a similar issue is described in CB-8606, CB-10088)\n                    specContext.transfer.download(imageURL + \"?q=\" + lastModified.getTime(), specContext.localFilePath, function () {\n                        specContext.transfer.download(imageURL + \"?q=\" + (lastModified.getTime() + 1), specContext.localFilePath, httpWin, downloadFail, null,\n                        {\n                            headers: {\n                                \"If-Modified-Since\": lastModified.toUTCString()\n                            }\n                        });\n                    }, httpFail);\n                }, DOWNLOAD_TIMEOUT * 2);\n\n                it(\"filetransfer.spec.36 should handle non-UTF8 encoded download response\", function (done) {\n\n                    // Only iOS is supported: https://issues.apache.org/jira/browse/CB-9840\n                    if (!isIos) {\n                        pending();\n                    }\n\n                    var fileURL = SERVER + '/download_non_utf';\n                    var specContext = this;\n\n                    var fileOperationFail = function() {\n                        unexpectedCallbacks.fileOperationFail();\n                        done();\n                    };\n\n                    var fileSystemFail = function() {\n                        unexpectedCallbacks.fileSystemFail();\n                        done();\n                    };\n\n                    var httpFail = function() {\n                        unexpectedCallbacks.httpFail();\n                        done();\n                    };\n\n                    var fileWin = function (blob) {\n\n                        if (specContext.transfer.onprogress.calls.any()) {\n                            var lastProgressEvent = specContext.transfer.onprogress.calls.mostRecent().args[0];\n                            expect(lastProgressEvent.loaded).not.toBeGreaterThan(blob.size);\n                        } else {\n                            console.log(\"no progress events were emitted\");\n                        }\n\n                        expect(blob.size).toBeGreaterThan(0);\n\n                        var reader = new FileReader();\n\n                        reader.onerror = fileOperationFail;\n                        reader.onloadend  = function () {\n                            expect(reader.result.indexOf(LATIN1_SYMBOLS)).not.toBe(-1);\n                            done();\n                        };\n\n                        reader.readAsBinaryString(blob);\n                    };\n\n                    var downloadWin = function (entry) {\n\n                        verifyDownload(entry, specContext);\n\n                        // verify the FileEntry representing this file\n                        entry.file(fileWin, fileSystemFail);\n                    };\n\n                    specContext.transfer.download(fileURL, specContext.localFilePath, downloadWin, httpFail);\n                }, UPLOAD_TIMEOUT);\n            });\n\n            describe(\"upload\", function() {\n                this.uploadParams   = null;\n                this.uploadOptions  = null;\n                this.fileName       = null;\n                this.fileContents   = null;\n                this.localFilePath  = null;\n\n                // helpers\n                var verifyUpload = function (uploadResult, specContext) {\n\n                    expect(uploadResult.bytesSent).toBeGreaterThan(0);\n                    expect(uploadResult.responseCode).toBe(200);\n\n                    var obj = null;\n                    try {\n                        obj = JSON.parse(uploadResult.response);\n                        expect(obj.fields).toBeDefined();\n                        expect(obj.fields.value1).toBe(\"test\");\n                        expect(obj.fields.value2).toBe(\"param\");\n                    } catch (e) {\n                        expect(obj).not.toBeNull(\"returned data from server should be valid json\");\n                    }\n\n                    expect(specContext.transfer.onprogress).toHaveBeenCalled();\n                };\n\n                beforeEach(function(done) {\n                    var specContext = this;\n\n                    specContext.fileName               = \"fileToUpload.txt\";\n                    specContext.fileContents           = \"upload test file\";\n\n                    specContext.uploadParams           = {};\n                    specContext.uploadParams.value1    = \"test\";\n                    specContext.uploadParams.value2    = \"param\";\n\n                    specContext.uploadOptions          = new FileUploadOptions();\n                    specContext.uploadOptions.fileKey  = \"file\";\n                    specContext.uploadOptions.fileName = specContext.fileName;\n                    specContext.uploadOptions.mimeType = \"text/plain\";\n                    specContext.uploadOptions.params   = specContext.uploadParams;\n\n                    var fileWin = function (entry) {\n                        specContext.localFilePath = entry.toURL();\n                        done();\n                    };\n\n                    // create a file to upload\n                    writeFile(specContext.root, specContext.fileName, specContext.fileContents, fileWin, done);\n                });\n\n                // delete the uploaded file\n                afterEach(function (done) {\n                    deleteFile(this.root, this.fileName, done);\n                });\n\n                it(\"filetransfer.spec.18 should be able to upload a file\", function (done) {\n\n                    var fileURL = SERVER + \"/upload\";\n                    var specContext = this;\n\n                    var uploadWin = function (uploadResult) {\n\n                        verifyUpload(uploadResult, specContext);\n\n                        if (cordova.platformId === \"ios\") {\n                            expect(uploadResult.headers).toBeDefined(\"Expected headers to be defined.\");\n                            expect(uploadResult.headers[\"Content-Type\"]).toBeDefined(\"Expected content-type header to be defined.\");\n                        }\n\n                        done();\n                    };\n\n                    var uploadFail = function() {\n                        unexpectedCallbacks.httpFail();\n                        done();\n                    };\n\n                    // NOTE: removing uploadOptions cause Android to timeout\n                    specContext.transfer.upload(specContext.localFilePath, fileURL, uploadWin, uploadFail, specContext.uploadOptions);\n                }, UPLOAD_TIMEOUT);\n\n                it(\"filetransfer.spec.19 should be able to upload a file with http basic auth\", function (done) {\n\n                    var fileURL = SERVER_WITH_CREDENTIALS + \"/upload_basic_auth\";\n                    var specContext = this;\n\n                    var uploadWin = function (uploadResult) {\n                        verifyUpload(uploadResult, specContext);\n                        done();\n                    };\n\n                    var uploadFail = function() {\n                        unexpectedCallbacks.httpFail();\n                        done();\n                    };\n\n                    // NOTE: removing uploadOptions cause Android to timeout\n                    specContext.transfer.upload(specContext.localFilePath, fileURL, uploadWin, uploadFail, specContext.uploadOptions);\n                }, UPLOAD_TIMEOUT);\n\n                it(\"filetransfer.spec.21 should be stopped by abort()\", function (done) {\n\n                    var fileURL = SERVER + \"/upload\";\n                    var specContext = this;\n\n                    var uploadFail = function (e) {\n                        expect(e.code).toBe(FileTransferError.ABORT_ERR);\n\n                        // delay calling done() to wait for the bogus abort()\n                        setTimeout(done, GRACE_TIME_DELTA * 2);\n                    };\n\n                    var uploadWin = function() {\n                        unexpectedCallbacks.httpWin();\n                        done();\n                    };\n\n                    var fileWin = function () {\n\n                        expect(specContext.transfer.abort).not.toThrow();\n\n                        // NOTE: removing uploadOptions cause Android to timeout\n                        specContext.transfer.upload(specContext.localFilePath, fileURL, uploadWin, uploadFail, specContext.uploadOptions);\n                        setTimeout(function() {\n                            specContext.transfer.abort();\n                        }, ABORT_DELAY);\n\n                        setTimeout(function () {\n                            expect(specContext.transfer.abort).not.toThrow();\n                        }, GRACE_TIME_DELTA);\n                    };\n\n                    writeFile(specContext.root, specContext.fileName, new Array(200000).join(\"aborttest!\"), fileWin, done);\n                }, UPLOAD_TIMEOUT);\n\n                it(\"filetransfer.spec.22 should get http status and body on failure\", function (done) {\n\n                    var fileURL = SERVER + \"/403\";\n\n                    var uploadFail = function (error) {\n                        expect(error.http_status).toBe(403);\n                        expect(error.http_status).not.toBe(401, \"Ensure \" + fileURL + \" is in the white list\");\n                        done();\n                    };\n\n                    var uploadWin = function() {\n                        unexpectedCallbacks.httpWin();\n                        done();\n                    };\n\n                    this.transfer.upload(this.localFilePath, fileURL, uploadWin, uploadFail, this.uploadOptions);\n                }, UPLOAD_TIMEOUT);\n\n                it(\"filetransfer.spec.24 should handle malformed urls\", function (done) {\n\n                    var fileURL = getMalformedUrl();\n\n                    var uploadFail = function (error) {\n                        expect(error.code).toBe(FileTransferError.INVALID_URL_ERR);\n                        expect(error.http_status).not.toBe(401, \"Ensure \" + fileURL + \" is in the white list\");\n                        done();\n                    };\n\n                    var uploadWin = function() {\n                        unexpectedCallbacks.httpWin();\n                        done();\n                    };\n\n                    this.transfer.upload(this.localFilePath, fileURL, uploadWin, uploadFail, {});\n                });\n\n                it(\"filetransfer.spec.25 should handle unknown host\", function (done) {\n\n                    var fileURL = UNKNOWN_HOST;\n\n                    var uploadFail = function (error) {\n                        expect(error.code).toBe(FileTransferError.CONNECTION_ERR);\n                        expect(error.http_status).not.toBe(401, \"Ensure \" + fileURL + \" is in the white list\");\n                        done();\n                    };\n\n                    var uploadWin = function() {\n                        unexpectedCallbacks.httpWin();\n                        done();\n                    };\n\n                    this.transfer.upload(this.localFilePath, fileURL, uploadWin, uploadFail, {});\n                }, UPLOAD_TIMEOUT);\n\n                it(\"filetransfer.spec.25 should handle missing file\", function (done) {\n\n                    var fileURL = SERVER + \"/upload\";\n\n                    var uploadFail = function (error) {\n                        expect(error.code).toBe(FileTransferError.FILE_NOT_FOUND_ERR);\n                        expect(error.http_status).not.toBe(401, \"Ensure \" + fileURL + \" is in the white list\");\n                        done();\n                    };\n\n                    var uploadWin = function() {\n                        unexpectedCallbacks.httpWin();\n                        done();\n                    };\n\n                    this.transfer.upload(\"does_not_exist.txt\", fileURL, uploadWin, uploadFail);\n                }, UPLOAD_TIMEOUT);\n\n                it(\"filetransfer.spec.26 should handle bad file path\", function (done) {\n\n                    var fileURL = SERVER + \"/upload\";\n\n                    var uploadFail = function (error) {\n                        expect(error.http_status).not.toBe(401, \"Ensure \" + fileURL + \" is in the white list\");\n                        done();\n                    };\n\n                    var uploadWin = function() {\n                        unexpectedCallbacks.httpWin();\n                        done();\n                    };\n\n                    this.transfer.upload(\"c:\\\\54321\", fileURL, uploadWin, uploadFail);\n                });\n\n                it(\"filetransfer.spec.27 should be able to set custom headers\", function (done) {\n\n                    var fileURL = HEADERS_ECHO;\n\n                    var uploadWin = function (uploadResult) {\n\n                        expect(uploadResult.bytesSent).toBeGreaterThan(0);\n                        expect(uploadResult.responseCode).toBe(200);\n                        expect(uploadResult.response).toBeDefined();\n\n                        var responseHtml = decodeURIComponent(uploadResult.response);\n\n                        expect(responseHtml).toMatch(/CustomHeader1[\\s\\S]*CustomValue1/i);\n                        expect(responseHtml).toMatch(/CustomHeader2[\\s\\S]*CustomValue2[\\s\\S]*CustomValue3/i, \"Should allow array values\");\n\n                        done();\n                    };\n\n                    var uploadFail = function() {\n                        unexpectedCallbacks.httpFail();\n                        done();\n                    };\n\n                    this.uploadOptions.headers = {\n                        \"CustomHeader1\": \"CustomValue1\",\n                        \"CustomHeader2\": [\"CustomValue2\", \"CustomValue3\"],\n                    };\n\n                    // NOTE: removing uploadOptions cause Android to timeout\n                    this.transfer.upload(this.localFilePath, fileURL, uploadWin, uploadFail, this.uploadOptions);\n                }, UPLOAD_TIMEOUT);\n\n                it(\"filetransfer.spec.29 (compatibility) should be able to upload a file using local paths\", function (done) {\n\n                    var fileURL = SERVER + \"/upload\";\n                    var specContext = this;\n\n                    var unsupported = function (response) {\n                        expectedCallbacks.unsupportedOperation(response);\n                        done();\n                    };\n\n                    var uploadWin = function (uploadResult) {\n                        verifyUpload(uploadResult, specContext);\n                        done();\n                    };\n\n                    var uploadFail = function() {\n                        unexpectedCallbacks.httpFail();\n                        done();\n                    };\n\n                    var internalFilePath;\n                    if (specContext.root.toInternalURL) {\n                        internalFilePath = specContext.root.toInternalURL() + specContext.fileName;\n                    } else {\n                        internalFilePath = specContext.localFilePath;\n                    }\n\n                    // This is an undocumented interface to File which exists only for testing\n                    // backwards compatibilty. By obtaining the raw filesystem path of the download\n                    // location, we can pass that to transfer.download() to make sure that previously-stored\n                    // paths are still valid.\n                    cordova.exec(function (localPath) {\n                        specContext.transfer.upload(localPath, fileURL, uploadWin, uploadFail, specContext.uploadOptions);\n                    }, unsupported, \"File\", \"_getLocalFilesystemPath\", [internalFilePath]);\n                }, UPLOAD_TIMEOUT);\n\n                it(\"filetransfer.spec.31 should be able to upload a file using PUT method\", function (done) {\n\n                    var fileURL = SERVER + \"/upload\";\n                    var specContext = this;\n\n                    var uploadWin = function (uploadResult) {\n\n                        verifyUpload(uploadResult, specContext);\n\n                        if (cordova.platformId === \"ios\") {\n                            expect(uploadResult.headers).toBeDefined(\"Expected headers to be defined.\");\n                            expect(uploadResult.headers[\"Content-Type\"]).toBeDefined(\"Expected content-type header to be defined.\");\n                        }\n\n                        done();\n                    };\n\n                    var uploadFail = function() {\n                        unexpectedCallbacks.httpFail();\n                        done();\n                    };\n\n                    specContext.uploadOptions.httpMethod = \"PUT\";\n\n                    // NOTE: removing uploadOptions cause Android to timeout\n                    specContext.transfer.upload(specContext.localFilePath, fileURL, uploadWin, uploadFail, specContext.uploadOptions);\n                }, UPLOAD_TIMEOUT);\n\n                it(\"filetransfer.spec.32 should be able to upload a file (non-multipart)\", function (done) {\n\n                    var fileURL = SERVER + \"/upload\";\n                    var specContext = this;\n\n                    var uploadWin = function (uploadResult) {\n\n                        expect(uploadResult.bytesSent).toBeGreaterThan(0);\n                        expect(uploadResult.responseCode).toBe(200);\n                        expect(uploadResult.response).toBeDefined();\n                        if (uploadResult.response) {\n                            expect(uploadResult.response).toEqual(specContext.fileContents + \"\\n\");\n                        }\n                        expect(specContext.transfer.onprogress).toHaveBeenCalled();\n\n                        if (cordova.platformId === \"ios\") {\n                            expect(uploadResult.headers).toBeDefined(\"Expected headers to be defined.\");\n                            expect(uploadResult.headers[\"Content-Type\"]).toBeDefined(\"Expected content-type header to be defined.\");\n                        }\n\n                        done();\n                    };\n\n                    var uploadFail = function() {\n                        unexpectedCallbacks.httpFail();\n                        done();\n                    };\n\n                    // Content-Type header disables multipart\n                    specContext.uploadOptions.headers = {\n                        \"Content-Type\": \"text/plain\"\n                    };\n\n                    // NOTE: removing uploadOptions cause Android to timeout\n                    specContext.transfer.upload(specContext.localFilePath, fileURL, uploadWin, uploadFail, specContext.uploadOptions);\n                }, UPLOAD_TIMEOUT);\n\n                it(\"filetransfer.spec.34 should not delete a file on upload error\", function (done) {\n\n                    var fileURL = SERVER + \"/upload\";\n                    var specContext = this;\n\n                    var uploadFail = function (e) {\n                        expect(e.code).toBe(FileTransferError.ABORT_ERR);\n\n                        // check that the file is there\n                        specContext.root.getFile(specContext.fileName, null, function(entry) {\n                            expect(entry).toBeDefined();\n                            // delay calling done() to wait for the bogus abort()\n                            setTimeout(done, GRACE_TIME_DELTA * 2);\n                        }, function(err) {\n                            expect(err).not.toBeDefined(err && err.code);\n                            done();\n                        });\n                    };\n\n                    var uploadWin = function() {\n                        unexpectedCallbacks.httpWin();\n                        done();\n                    };\n\n                    var fileWin = function () {\n\n                        expect(specContext.transfer.abort).not.toThrow();\n\n                        // abort at the first onprogress event\n                        specContext.transfer.onprogress = function (event) {\n                            if (event.loaded > 0) {\n                                specContext.transfer.abort();\n                            }\n                        };\n\n                        // NOTE: removing uploadOptions cause Android to timeout\n                        specContext.transfer.upload(specContext.localFilePath, fileURL, uploadWin, uploadFail, specContext.uploadOptions);\n                    };\n\n                    writeFile(specContext.root, specContext.fileName, new Array(100000).join(\"aborttest!\"), fileWin, done);\n                }, UPLOAD_TIMEOUT);\n\n                it(\"filetransfer.spec.37 should handle non-UTF8 encoded upload response\", function (done) {\n\n                    // Only iOS is supported: https://issues.apache.org/jira/browse/CB-9840\n                    if (!isIos) {\n                        pending();\n                    }\n\n                    var fileURL = SERVER + '/upload_non_utf';\n                    var specContext = this;\n\n                    var uploadWin = function (uploadResult) {\n\n                        verifyUpload(uploadResult, specContext);\n\n                        var obj = null;\n                        try {\n                            obj = JSON.parse(uploadResult.response);\n                            expect(obj.latin1Symbols).toBe(LATIN1_SYMBOLS);\n                        } catch (e) {\n                            expect(obj).not.toBeNull(\"returned data from server should be valid json\");\n                        }\n\n                        if (cordova.platformId === 'ios') {\n                            expect(uploadResult.headers).toBeDefined('Expected headers to be defined.');\n                            expect(uploadResult.headers['Content-Type']).toBeDefined('Expected content-type header to be defined.');\n                        }\n\n                        done();\n                    };\n\n                    var uploadFail = function() {\n                        unexpectedCallbacks.httpFail();\n                        done();\n                    };\n\n                    // NOTE: removing uploadOptions cause Android to timeout\n                    specContext.transfer.upload(specContext.localFilePath, fileURL, uploadWin, uploadFail, specContext.uploadOptions);\n                }, UPLOAD_TIMEOUT);\n\n                it(\"filetransfer.spec.38 should be able to upload a file using data: source uri\", function (done) {\n\n                    var fileURL = SERVER + \"/upload\";\n                    var specContext = this;\n\n                    var uploadWin = function (uploadResult) {\n\n                        verifyUpload(uploadResult,specContext);\n\n                        var obj = null;\n                        try {\n                            obj = JSON.parse(uploadResult.response);\n                            expect(obj.files.file.size).toBe(DATA_URI_CONTENT_LENGTH);\n                        } catch (e) {\n                            expect(obj).not.toBeNull(\"returned data from server should be valid json\");\n                        }\n\n                        if (cordova.platformId === \"ios\") {\n                            expect(uploadResult.headers).toBeDefined(\"Expected headers to be defined.\");\n                            expect(uploadResult.headers[\"Content-Type\"]).toBeDefined(\"Expected content-type header to be defined.\");\n                        }\n\n                        done();\n                    };\n\n                    var dataUri = DATA_URI_PREFIX + DATA_URI_CONTENT;\n                    // NOTE: removing uploadOptions cause Android to timeout\n                    specContext.transfer.upload(dataUri, fileURL, uploadWin, function (err) {\n                        console.error('err: ' + JSON.stringify(err));\n                        expect(err).not.toBeDefined();\n                        done();\n                    }, specContext.uploadOptions);\n                }, UPLOAD_TIMEOUT);\n\n                it(\"filetransfer.spec.39 should be able to upload a file using data: source uri (non-multipart)\", function (done) {\n\n                    var fileURL = SERVER + \"/upload\";\n\n                    var uploadWin = function (uploadResult) {\n\n                        expect(uploadResult.responseCode).toBe(200);\n                        expect(uploadResult.bytesSent).toBeGreaterThan(0);\n\n                        if (cordova.platformId === \"ios\") {\n                            expect(uploadResult.headers).toBeDefined(\"Expected headers to be defined.\");\n                            expect(uploadResult.headers[\"Content-Type\"]).toBeDefined(\"Expected content-type header to be defined.\");\n                        }\n\n                        done();\n                    };\n\n                    var uploadFail = function() {\n                        unexpectedCallbacks.httpFail();\n                        done();\n                    };\n\n                    // Content-Type header disables multipart\n                    this.uploadOptions.headers = {\n                        \"Content-Type\": \"image/png\"\n                    };\n\n                    var dataUri = DATA_URI_PREFIX + DATA_URI_CONTENT;\n                    // NOTE: removing uploadOptions cause Android to timeout\n                    this.transfer.upload(dataUri, fileURL, uploadWin, uploadFail, this.uploadOptions);\n                }, UPLOAD_TIMEOUT);\n\n                it(\"filetransfer.spec.40 should not fail to upload a file using data: source uri when the data is empty\", function (done) {\n\n                    var fileURL = SERVER + \"/upload\";\n\n                    var dataUri = DATA_URI_PREFIX;\n\n                    var uploadFail = function() {\n                        unexpectedCallbacks.httpFail();\n                        done();\n                    };\n\n                    // NOTE: removing uploadOptions cause Android to timeout\n                    this.transfer.upload(dataUri, fileURL, done, uploadFail, this.uploadOptions);\n                }, UPLOAD_TIMEOUT);\n\n                it(\"filetransfer.spec.41 should not fail to upload a file using data: source uri when the data is empty (non-multipart)\", function (done) {\n\n                    var fileURL = SERVER + \"/upload\";\n\n                    // Content-Type header disables multipart\n                    this.uploadOptions.headers = {\n                        \"Content-Type\": \"image/png\"\n                    };\n\n                    // turn off the onprogress handler\n                    this.transfer.onprogress = function () { };\n\n                    var dataUri = DATA_URI_PREFIX;\n\n                    var uploadFail = function() {\n                        unexpectedCallbacks.httpFail();\n                        done();\n                    };\n\n                    // NOTE: removing uploadOptions cause Android to timeout\n                    this.transfer.upload(dataUri, fileURL, done, uploadFail, this.uploadOptions);\n                }, UPLOAD_TIMEOUT);\n            });\n        });\n    });\n};\n\n/******************************************************************************/\n/******************************************************************************/\n/******************************************************************************/\n\nexports.defineManualTests = function (contentEl, createActionButton) {\n\n    \"use strict\";\n\n    var imageURL = \"http://apache.org/images/feather-small.gif\";\n    var videoURL = \"http://techslides.com/demos/sample-videos/small.mp4\";\n\n    function clearResults() {\n        var results = document.getElementById(\"info\");\n        results.innerHTML = \"\";\n    }\n\n    function downloadImg(source, urlFn, element, directory) {\n        var filename = source.substring(source.lastIndexOf(\"/\") + 1);\n        filename = (directory || \"\") + filename;\n\n        function download(fileSystem) {\n            var ft = new FileTransfer();\n            console.log(\"Starting download\");\n\n            var progress = document.getElementById(\"loadingStatus\");\n            progress.value = 0;\n\n            ft.onprogress = function(progressEvent) {\n                if (progressEvent.lengthComputable) {\n                    var currPercents = parseInt(100 * (progressEvent.loaded / progressEvent.total), 10);\n                    if (currPercents > progress.value) {\n                        progress.value = currPercents;\n                    }\n                } else {\n                    progress.value = null;\n                }\n            };\n\n            ft.download(source, fileSystem.root.toURL() + filename, function (entry) {\n                console.log(\"Download complete\");\n                element.src = urlFn(entry);\n                console.log(\"Src URL is \" + element.src);\n                console.log(\"Inserting element\");\n                document.getElementById(\"info\").appendChild(element);\n            }, function (e) { console.log(\"ERROR: ft.download \" + e.code); });\n        }\n        console.log(\"Requesting filesystem\");\n        clearResults();\n        window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, function (fileSystem) {\n            console.log(\"Checking for existing file\");\n            if (typeof directory !== \"undefined\") {\n                console.log(\"Checking for existing directory.\");\n                fileSystem.root.getDirectory(directory, {}, function (dirEntry) {\n                    dirEntry.removeRecursively(function () {\n                        download(fileSystem);\n                    }, function () { console.log(\"ERROR: dirEntry.removeRecursively\"); });\n                }, function () {\n                    download(fileSystem);\n                });\n            } else {\n                fileSystem.root.getFile(filename, { create: false }, function (entry) {\n                    console.log(\"Removing existing file\");\n                    entry.remove(function () {\n                        download(fileSystem);\n                    }, function () { console.log(\"ERROR: entry.remove\"); });\n                }, function () {\n                    download(fileSystem);\n                });\n            }\n        }, function () { console.log(\"ERROR: requestFileSystem\"); });\n    }\n\n    /******************************************************************************/\n\n    var progress_tag = \"<progress id=\\\"loadingStatus\\\" value=\\\"0\\\" max=\\\"100\\\" style=\\\"width: 100%;\\\"></progress>\";\n    var file_transfer_tests = \"<h2>Image File Transfer Tests</h2>\" +\n        \"<h3>The following tests should display an image of the Apache feather in the status box</h3>\" +\n        \"<div id=\\\"cdv_image\\\"></div>\" +\n        \"<div id=\\\"native_image\\\"></div>\" +\n        \"<div id=\\\"non-existent_dir\\\"></div>\" +\n        \"<h2>Video File Transfer Tests</h2>\" +\n        \"<h3>The following tests should display a video in the status box. The video should play when play is pressed</h3>\" +\n        \"<div id=\\\"cdv_video\\\"></div>\" +\n        \"<div id=\\\"native_video\\\"></div>\";\n\n    contentEl.innerHTML = \"<div id=\\\"info\\\"></div>\" + \"<br>\" + progress_tag +\n        file_transfer_tests;\n\n    createActionButton(\"Download and display img (cdvfile)\", function () {\n        downloadImg(imageURL, function (entry) { return entry.toInternalURL(); }, new Image());\n    }, \"cdv_image\");\n\n    createActionButton(\"Download and display img (native)\", function () {\n        downloadImg(imageURL, function (entry) { return entry.toURL(); }, new Image());\n    }, \"native_image\");\n\n    createActionButton(\"Download to a non-existent dir (should work)\", function () {\n        downloadImg(imageURL, function (entry) { return entry.toURL(); }, new Image(), \"/nonExistentDirTest/\");\n    }, \"non-existent_dir\");\n\n    createActionButton(\"Download and play video (cdvfile)\", function () {\n        var videoElement = document.createElement(\"video\");\n        videoElement.controls = \"controls\";\n        downloadImg(videoURL, function (entry) { return entry.toInternalURL(); }, videoElement);\n    }, \"cdv_video\");\n\n    createActionButton(\"Download and play video (native)\", function () {\n        var videoElement = document.createElement(\"video\");\n        videoElement.controls = \"controls\";\n        downloadImg(videoURL, function (entry) { return entry.toURL(); }, videoElement);\n    }, \"native_video\");\n};\n"
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/www/FileTransfer.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/* global cordova, FileSystem */\n\nvar argscheck = require('cordova/argscheck'),\n    exec = require('cordova/exec'),\n    FileTransferError = require('./FileTransferError'),\n    ProgressEvent = require('cordova-plugin-file.ProgressEvent');\n\nfunction newProgressEvent(result) {\n    var pe = new ProgressEvent();\n    pe.lengthComputable = result.lengthComputable;\n    pe.loaded = result.loaded;\n    pe.total = result.total;\n    return pe;\n}\n\nfunction getUrlCredentials(urlString) {\n    var credentialsPattern = /^https?\\:\\/\\/(?:(?:(([^:@\\/]*)(?::([^@\\/]*))?)?@)?([^:\\/?#]*)(?::(\\d*))?).*$/,\n        credentials = credentialsPattern.exec(urlString);\n\n    return credentials && credentials[1];\n}\n\nfunction getBasicAuthHeader(urlString) {\n    var header =  null;\n\n\n    // This is changed due to MS Windows doesn't support credentials in http uris\n    // so we detect them by regexp and strip off from result url\n    // Proof: http://social.msdn.microsoft.com/Forums/windowsapps/en-US/a327cf3c-f033-4a54-8b7f-03c56ba3203f/windows-foundation-uri-security-problem\n\n    if (window.btoa) {\n        var credentials = getUrlCredentials(urlString);\n        if (credentials) {\n            var authHeader = \"Authorization\";\n            var authHeaderValue = \"Basic \" + window.btoa(credentials);\n\n            header = {\n                name : authHeader,\n                value : authHeaderValue\n            };\n        }\n    }\n\n    return header;\n}\n\nfunction convertHeadersToArray(headers) {\n    var result = [];\n    for (var header in headers) {\n        if (headers.hasOwnProperty(header)) {\n            var headerValue = headers[header];\n            result.push({\n                name: header,\n                value: headerValue.toString()\n            });\n        }\n    }\n    return result;\n}\n\nvar idCounter = 0;\n\n/**\n * FileTransfer uploads a file to a remote server.\n * @constructor\n */\nvar FileTransfer = function() {\n    this._id = ++idCounter;\n    this.onprogress = null; // optional callback\n};\n\n/**\n* Given an absolute file path, uploads a file on the device to a remote server\n* using a multipart HTTP request.\n* @param filePath {String}           Full path of the file on the device\n* @param server {String}             URL of the server to receive the file\n* @param successCallback (Function}  Callback to be invoked when upload has completed\n* @param errorCallback {Function}    Callback to be invoked upon error\n* @param options {FileUploadOptions} Optional parameters such as file name and mimetype\n* @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false\n*/\nFileTransfer.prototype.upload = function(filePath, server, successCallback, errorCallback, options, trustAllHosts) {\n    argscheck.checkArgs('ssFFO*', 'FileTransfer.upload', arguments);\n    // check for options\n    var fileKey = null;\n    var fileName = null;\n    var mimeType = null;\n    var params = null;\n    var chunkedMode = true;\n    var headers = null;\n    var httpMethod = null;\n    var basicAuthHeader = getBasicAuthHeader(server);\n    if (basicAuthHeader) {\n        server = server.replace(getUrlCredentials(server) + '@', '');\n\n        options = options || {};\n        options.headers = options.headers || {};\n        options.headers[basicAuthHeader.name] = basicAuthHeader.value;\n    }\n\n    if (options) {\n        fileKey = options.fileKey;\n        fileName = options.fileName;\n        mimeType = options.mimeType;\n        headers = options.headers;\n        httpMethod = options.httpMethod || \"POST\";\n        if (httpMethod.toUpperCase() == \"PUT\"){\n            httpMethod = \"PUT\";\n        } else {\n            httpMethod = \"POST\";\n        }\n        if (options.chunkedMode !== null || typeof options.chunkedMode != \"undefined\") {\n            chunkedMode = options.chunkedMode;\n        }\n        if (options.params) {\n            params = options.params;\n        }\n        else {\n            params = {};\n        }\n    }\n\n    if (cordova.platformId === \"windowsphone\") {\n        headers = headers && convertHeadersToArray(headers);\n        params = params && convertHeadersToArray(params);\n    }\n\n    var fail = errorCallback && function(e) {\n        var error = new FileTransferError(e.code, e.source, e.target, e.http_status, e.body, e.exception);\n        errorCallback(error);\n    };\n\n    var self = this;\n    var win = function(result) {\n        if (typeof result.lengthComputable != \"undefined\") {\n            if (self.onprogress) {\n                self.onprogress(newProgressEvent(result));\n            }\n        } else {\n            if (successCallback) {\n                successCallback(result);\n            }\n        }\n    };\n    exec(win, fail, 'FileTransfer', 'upload', [filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode, headers, this._id, httpMethod]);\n};\n\n/**\n * Downloads a file form a given URL and saves it to the specified directory.\n * @param source {String}          URL of the server to receive the file\n * @param target {String}         Full path of the file on the device\n * @param successCallback (Function}  Callback to be invoked when upload has completed\n * @param errorCallback {Function}    Callback to be invoked upon error\n * @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false\n * @param options {FileDownloadOptions} Optional parameters such as headers\n */\nFileTransfer.prototype.download = function(source, target, successCallback, errorCallback, trustAllHosts, options) {\n    argscheck.checkArgs('ssFF*', 'FileTransfer.download', arguments);\n    var self = this;\n\n    var basicAuthHeader = getBasicAuthHeader(source);\n    if (basicAuthHeader) {\n        source = source.replace(getUrlCredentials(source) + '@', '');\n\n        options = options || {};\n        options.headers = options.headers || {};\n        options.headers[basicAuthHeader.name] = basicAuthHeader.value;\n    }\n\n    var headers = null;\n    if (options) {\n        headers = options.headers || null;\n    }\n\n    if (cordova.platformId === \"windowsphone\" && headers) {\n        headers = convertHeadersToArray(headers);\n    }\n\n    var win = function(result) {\n        if (typeof result.lengthComputable != \"undefined\") {\n            if (self.onprogress) {\n                return self.onprogress(newProgressEvent(result));\n            }\n        } else if (successCallback) {\n            var entry = null;\n            if (result.isDirectory) {\n                entry = new (require('cordova-plugin-file.DirectoryEntry'))();\n            }\n            else if (result.isFile) {\n                entry = new (require('cordova-plugin-file.FileEntry'))();\n            }\n            entry.isDirectory = result.isDirectory;\n            entry.isFile = result.isFile;\n            entry.name = result.name;\n            entry.fullPath = result.fullPath;\n            entry.filesystem = new FileSystem(result.filesystemName || (result.filesystem == window.PERSISTENT ? 'persistent' : 'temporary'));\n            entry.nativeURL = result.nativeURL;\n            successCallback(entry);\n        }\n    };\n\n    var fail = errorCallback && function(e) {\n        var error = new FileTransferError(e.code, e.source, e.target, e.http_status, e.body, e.exception);\n        errorCallback(error);\n    };\n\n    exec(win, fail, 'FileTransfer', 'download', [source, target, trustAllHosts, this._id, headers]);\n};\n\n/**\n * Aborts the ongoing file transfer on this object. The original error\n * callback for the file transfer will be called if necessary.\n */\nFileTransfer.prototype.abort = function() {\n    exec(null, null, 'FileTransfer', 'abort', [this._id]);\n};\n\nmodule.exports = FileTransfer;\n"
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/www/FileTransferError.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/**\n * FileTransferError\n * @constructor\n */\nvar FileTransferError = function(code, source, target, status, body, exception) {\n    this.code = code || null;\n    this.source = source || null;\n    this.target = target || null;\n    this.http_status = status || null;\n    this.body = body || null;\n    this.exception = exception || null;\n};\n\nFileTransferError.FILE_NOT_FOUND_ERR = 1;\nFileTransferError.INVALID_URL_ERR = 2;\nFileTransferError.CONNECTION_ERR = 3;\nFileTransferError.ABORT_ERR = 4;\nFileTransferError.NOT_MODIFIED_ERR = 5;\n\nmodule.exports = FileTransferError;\n"
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/www/blackberry10/.jshintrc",
    "content": "{\n    \"globals\": {\n        \"requestAnimationFrame\": true\n    }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/www/blackberry10/FileTransfer.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\nvar argscheck = require('cordova/argscheck'),\n    FileTransferError = require('./FileTransferError'),\n    xhrImpl = require('./BB10XHRImplementation');\n\n\nfunction getBasicAuthHeader(urlString) {\n    var header =  null;\n\n    if (window.btoa) {\n        // parse the url using the Location object\n        var url = document.createElement('a');\n        url.href = urlString;\n\n        var credentials = null;\n        var protocol = url.protocol + \"//\";\n        var origin = protocol + url.host;\n\n        // check whether there are the username:password credentials in the url\n        if (url.href.indexOf(origin) !== 0) { // credentials found\n            var atIndex = url.href.indexOf(\"@\");\n            credentials = url.href.substring(protocol.length, atIndex);\n        }\n\n        if (credentials) {\n            var authHeader = \"Authorization\";\n            var authHeaderValue = \"Basic \" + window.btoa(credentials);\n\n            header = {\n                name : authHeader,\n                value : authHeaderValue\n            };\n        }\n    }\n\n    return header;\n}\n\nvar idCounter = 0;\n\n/**\n * FileTransfer uploads a file to a remote server.\n * @constructor\n */\nvar FileTransfer = function() {\n    this._id = ++idCounter;\n    this.onprogress = null; // optional callback\n};\n\n/**\n* Given an absolute file path, uploads a file on the device to a remote server\n* using a multipart HTTP request.\n* @param filePath {String}           Full path of the file on the device\n* @param server {String}             URL of the server to receive the file\n* @param successCallback (Function}  Callback to be invoked when upload has completed\n* @param errorCallback {Function}    Callback to be invoked upon error\n* @param options {FileUploadOptions} Optional parameters such as file name and mimetype\n* @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false\n*/\nFileTransfer.prototype.upload = function(filePath, server, successCallback, errorCallback, options, trustAllHosts) {\n    argscheck.checkArgs('ssFFO*', 'FileTransfer.upload', arguments);\n    // check for options\n    var fileKey = null;\n    var fileName = null;\n    var mimeType = null;\n    var params = null;\n    var chunkedMode = true;\n    var headers = null;\n    var httpMethod = null;\n    var basicAuthHeader = getBasicAuthHeader(server);\n    if (basicAuthHeader) {\n        options = options || {};\n        options.headers = options.headers || {};\n        options.headers[basicAuthHeader.name] = basicAuthHeader.value;\n    }\n\n    if (options) {\n        fileKey = options.fileKey;\n        fileName = options.fileName;\n        mimeType = options.mimeType;\n        headers = options.headers;\n        httpMethod = options.httpMethod || \"POST\";\n        if (httpMethod.toUpperCase() == \"PUT\"){\n            httpMethod = \"PUT\";\n        } else {\n            httpMethod = \"POST\";\n        }\n        if (options.chunkedMode !== null || typeof options.chunkedMode != \"undefined\") {\n            chunkedMode = options.chunkedMode;\n        }\n        if (options.params) {\n            params = options.params;\n        }\n        else {\n            params = {};\n        }\n    }\n\n    var fail = errorCallback && function(e) {\n        var error = new FileTransferError(e.code, e.source, e.target, e.http_status, e.body);\n        errorCallback(error);\n    };\n\n    var self = this;\n    var win = function(result) {\n        if (typeof result.lengthComputable != \"undefined\") {\n            if (self.onprogress) {\n                self.onprogress(result);\n            }\n        } else {\n            if (successCallback) {\n                successCallback(result);\n            }\n        }\n    };\n    xhrImpl.upload(win, fail, [filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode, headers, this._id, httpMethod]);\n};\n\n/**\n * Downloads a file form a given URL and saves it to the specified directory.\n * @param source {String}          URL of the server to receive the file\n * @param target {String}         Full path of the file on the device\n * @param successCallback (Function}  Callback to be invoked when upload has completed\n * @param errorCallback {Function}    Callback to be invoked upon error\n * @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false\n * @param options {FileDownloadOptions} Optional parameters such as headers\n */\nFileTransfer.prototype.download = function(source, target, successCallback, errorCallback, trustAllHosts, options) {\n    argscheck.checkArgs('ssFF*', 'FileTransfer.download', arguments);\n    var self = this;\n\n    var basicAuthHeader = getBasicAuthHeader(source);\n    if (basicAuthHeader) {\n        options = options || {};\n        options.headers = options.headers || {};\n        options.headers[basicAuthHeader.name] = basicAuthHeader.value;\n    }\n\n    var headers = null;\n    if (options) {\n        headers = options.headers || null;\n    }\n\n    var win = function(result) {\n        if (typeof result.lengthComputable != \"undefined\") {\n            if (self.onprogress) {\n                return self.onprogress(result);\n            }\n        } else if (successCallback) {\n            successCallback(result);\n        }\n    };\n\n    var fail = errorCallback && function(e) {\n        var error = new FileTransferError(e.code, e.source, e.target, e.http_status, e.body);\n        errorCallback(error);\n    };\n\n    xhrImpl.download(win, fail, [source, target, trustAllHosts, this._id, headers]);\n};\n\n/**\n * Aborts the ongoing file transfer on this object. The original error\n * callback for the file transfer will be called if necessary.\n */\nFileTransfer.prototype.abort = function() {\n    xhrImpl.abort(null, null, [this._id]);\n};\n\nmodule.exports = FileTransfer;\n"
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/www/blackberry10/FileTransferProxy.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/*\n * FileTransferProxy\n *\n * Register all FileTransfer exec calls to be handled by proxy\n */\n\nvar xhrFileTransfer = require('cordova-plugin-file-transfer.xhrFileTransfer');\n\nmodule.exports = {\n    abort: xhrFileTransfer.abort,\n    download: xhrFileTransfer.download,\n    upload: xhrFileTransfer.upload\n};\n\nrequire('cordova/exec/proxy').add('FileTransfer', module.exports);\n"
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/www/blackberry10/xhrFileTransfer.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/* global Blob:false */\n\nvar cordova = require('cordova'),\n    resolve = cordova.require('cordova-plugin-file.resolveLocalFileSystemURIProxy'),\n    requestAnimationFrame = cordova.require('cordova-plugin-file.bb10RequestAnimationFrame'),\n    xhr = {};\n\nfunction getParentPath(filePath) {\n    var pos = filePath.lastIndexOf('/');\n    return filePath.substring(0, pos + 1);\n}\n\nfunction getFileName(filePath) {\n    var pos = filePath.lastIndexOf('/');\n    return filePath.substring(pos + 1);\n}\n\nfunction checkURL(url) {\n    return url.indexOf(' ') === -1 ?  true : false;\n}\n\nmodule.exports = {\n    abort: function (win, fail, args) {\n        var id = args[0];\n        if (xhr[id]) {\n            xhr[id].abort();\n            if (typeof(win) === 'function') {\n                win();\n            }\n        } else if (typeof(fail) === 'function') {\n            fail();\n        }\n    },\n\n    upload: function(win, fail, args) {\n        var filePath = args[0],\n            server = args[1],\n            fileKey = args[2],\n            fileName = args[3],\n            mimeType = args[4],\n            params = args[5],\n            /*trustAllHosts = args[6],*/\n            chunkedMode = args[7],\n            headers = args[8],\n            onSuccess = function (data) {\n                if (typeof(win) === 'function') {\n                    win(data);\n                }\n            },\n            onFail = function (code) {\n                delete xhr[fileKey];\n                if (typeof(fail) === 'function') {\n                    fail(code);\n                }\n            };\n\n        if (!checkURL(server)) {\n            onFail(new FileTransferError(FileTransferError.INVALID_URL_ERR, server, filePath));\n        }\n\n        xhr[fileKey] = new XMLHttpRequest();\n        xhr[fileKey].onabort = function () {\n            onFail(new FileTransferError(FileTransferError.ABORT_ERR, server, filePath, this.status, xhr[fileKey].response));\n        };\n\n        resolve(function(entry) {\n            requestAnimationFrame(function () {\n                entry.nativeEntry.file(function(file) {\n                    function uploadFile(blobFile) {\n                        var fd = new FormData();\n\n                        fd.append(fileKey, blobFile, fileName);\n                        for (var prop in params) {\n                            if(params.hasOwnProperty(prop)) {\n                                fd.append(prop, params[prop]);\n                            }\n                        }\n\n                        xhr[fileKey].open(\"POST\", server);\n                        xhr[fileKey].onload = function(evt) {\n                            if (xhr[fileKey].status === 200) {\n                                var result = new FileUploadResult();\n                                result.bytesSent = file.size;\n                                result.responseCode = xhr[fileKey].status;\n                                result.response = xhr[fileKey].response;\n                                delete xhr[fileKey];\n                                onSuccess(result);\n                            } else if (xhr[fileKey].status === 404) {\n                                onFail(new FileTransferError(FileTransferError.INVALID_URL_ERR, server, filePath, xhr[fileKey].status, xhr[fileKey].response));\n                            } else {\n                                onFail(new FileTransferError(FileTransferError.CONNECTION_ERR, server, filePath, xhr[fileKey].status, xhr[fileKey].response));\n                            }\n                        };\n                        xhr[fileKey].ontimeout = function(evt) {\n                            onFail(new FileTransferError(FileTransferError.CONNECTION_ERR, server, filePath, xhr[fileKey].status, xhr[fileKey].response));\n                        };\n                        xhr[fileKey].onerror = function () {\n                            onFail(new FileTransferError(FileTransferError.CONNECTION_ERR, server, filePath, this.status, xhr[fileKey].response));\n                        };\n                        xhr[fileKey].upload.onprogress = function (evt) {\n                            if (evt.loaded > 0) {\n                                onSuccess(evt);\n                            }\n                        };\n\n                        for (var header in headers) {\n                            if (headers.hasOwnProperty(header)) {\n                                xhr[fileKey].setRequestHeader(header, headers[header]);\n                            }\n                        }\n\n                        requestAnimationFrame(function () {\n                            xhr[fileKey].send(fd);\n                        });\n                    }\n\n                    var bytesPerChunk;\n                    if (chunkedMode === true) {\n                        bytesPerChunk = 1024 * 1024; // 1MB chunk sizes.\n                    } else {\n                        bytesPerChunk = file.size;\n                    }\n                    var start = 0;\n                    var end = bytesPerChunk;\n                    while (start < file.size) {\n                        var chunk = file.slice(start, end, mimeType);\n                        uploadFile(chunk);\n                        start = end;\n                        end = start + bytesPerChunk;\n                    }\n                }, function(error) {\n                    onFail(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR, server, filePath));\n                });\n            });\n        }, function(error) {\n            onFail(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR, server, filePath));\n        }, [filePath]);\n    },\n\n    download: function (win, fail, args) {\n        var source = args[0],\n            target = args[1],\n            id = args[3],\n            headers = args[4],\n            fileWriter,\n            onSuccess = function (entry) {\n                if (typeof(win) === 'function') {\n                    win(entry);\n                }\n            },\n            onFail = function (error) {\n                var reader;\n                delete xhr[id];\n                if (typeof(fail) === 'function') {\n                    if (error && error.body && typeof(error.body) === 'object') {\n                        reader = new FileReader()._realReader;\n                        reader.onloadend = function () {\n                            error.body = this.result;\n                            fail(error);\n                        };\n                        reader.onerror = function () {\n                            fail(error);\n                        };\n                        reader.readAsText(error.body);\n                    } else {\n                        fail(error);\n                    }\n                }\n            };\n\n        if (!checkURL(source)) {\n            onFail(new FileTransferError(FileTransferError.INVALID_URL_ERR, source, target));\n        }\n\n        xhr[id] = new XMLHttpRequest();\n\n        function writeFile(entry) {\n            entry.createWriter(function (writer) {\n                fileWriter = writer;\n                fileWriter.onwriteend = function (evt) {\n                    if (!evt.target.error) {\n                        entry.filesystemName = entry.filesystem.name;\n                        delete xhr[id];\n                        onSuccess(entry);\n                    } else {\n                        onFail(evt.target.error);\n                    }\n                };\n                fileWriter.onerror = function (evt) {\n                    onFail(evt.target.error);\n                };\n                fileWriter.write(new Blob([xhr[id].response]));\n            }, function (error) {\n                onFail(error);\n            });\n        }\n\n        xhr[id].onerror = function (e) {\n            onFail(new FileTransferError(FileTransferError.CONNECTION_ERR, source, target, xhr[id].status, xhr[id].response));\n        };\n\n        xhr[id].onabort = function (e) {\n            onFail(new FileTransferError(FileTransferError.ABORT_ERR, source, target, xhr[id].status, xhr[id].response));\n        };\n\n        xhr[id].onload = function () {\n            if (xhr[id].readyState === xhr[id].DONE) {\n                if (xhr[id].status === 200 && xhr[id].response) {\n                    resolveLocalFileSystemURI(getParentPath(target), function (dir) {\n                        dir.getFile(getFileName(target), {create: true}, writeFile, function (error) {\n                            onFail(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR, source, target, xhr[id].status, xhr[id].response));\n                        });\n                    }, function (error) {\n                        onFail(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR, source, target, xhr[id].status, xhr[id].response));\n                    });\n                } else if (xhr[id].status === 404) {\n                    onFail(new FileTransferError(FileTransferError.INVALID_URL_ERR, source, target, xhr[id].status, xhr[id].response));\n                } else {\n                    onFail(new FileTransferError(FileTransferError.CONNECTION_ERR, source, target, xhr[id].status, xhr[id].response));\n                }\n            }\n        };\n        xhr[id].onprogress = function (evt) {\n            onSuccess(evt);\n        };\n        xhr[id].open(\"GET\", source, true);\n        for (var header in headers) {\n            if (headers.hasOwnProperty(header)) {\n                xhr[id].setRequestHeader(header, headers[header]);\n            }\n        }\n        xhr[id].responseType = \"blob\";\n        requestAnimationFrame(function () {\n            if (xhr[id]) {\n                xhr[id].send();\n            }\n        });\n    }\n};\n"
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/www/browser/FileTransfer.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/*global module, require*/\n\nvar argscheck = require('cordova/argscheck'),\n    FileTransferError = require('./FileTransferError');\n\nfunction getParentPath(filePath) {\n    var pos = filePath.lastIndexOf('/');\n    return filePath.substring(0, pos + 1);\n}\n\nfunction getFileName(filePath) {\n    var pos = filePath.lastIndexOf('/');\n    return filePath.substring(pos + 1);\n}\n\nfunction getUrlCredentials(urlString) {\n    var credentialsPattern = /^https?\\:\\/\\/(?:(?:(([^:@\\/]*)(?::([^@\\/]*))?)?@)?([^:\\/?#]*)(?::(\\d*))?).*$/,\n        credentials = credentialsPattern.exec(urlString);\n\n    return credentials && credentials[1];\n}\n\nfunction getBasicAuthHeader(urlString) {\n    var header =  null;\n\n\n    // This is changed due to MS Windows doesn't support credentials in http uris\n    // so we detect them by regexp and strip off from result url\n    // Proof: http://social.msdn.microsoft.com/Forums/windowsapps/en-US/a327cf3c-f033-4a54-8b7f-03c56ba3203f/windows-foundation-uri-security-problem\n\n    if (window.btoa) {\n        var credentials = getUrlCredentials(urlString);\n        if (credentials) {\n            var authHeader = \"Authorization\";\n            var authHeaderValue = \"Basic \" + window.btoa(credentials);\n\n            header = {\n                name : authHeader,\n                value : authHeaderValue\n            };\n        }\n    }\n\n    return header;\n}\n\nfunction checkURL(url) {\n    return url.indexOf(' ') === -1 ?  true : false;\n}\n\nvar idCounter = 0;\n\nvar transfers = {};\n\n/**\n * FileTransfer uploads a file to a remote server.\n * @constructor\n */\nvar FileTransfer = function() {\n    this._id = ++idCounter;\n    this.onprogress = null; // optional callback\n};\n\n/**\n * Given an absolute file path, uploads a file on the device to a remote server\n * using a multipart HTTP request.\n * @param filePath {String}           Full path of the file on the device\n * @param server {String}             URL of the server to receive the file\n * @param successCallback (Function}  Callback to be invoked when upload has completed\n * @param errorCallback {Function}    Callback to be invoked upon error\n * @param options {FileUploadOptions} Optional parameters such as file name and mimetype\n * @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false\n */\nFileTransfer.prototype.upload = function(filePath, server, successCallback, errorCallback, options) {\n    // check for arguments\n    argscheck.checkArgs('ssFFO*', 'FileTransfer.upload', arguments);\n\n    // Check if target URL doesn't contain spaces. If contains, it should be escaped first\n    // (see https://github.com/apache/cordova-plugin-file-transfer/blob/master/doc/index.md#upload)\n    if (!checkURL(server)) {\n        if (errorCallback) {\n            errorCallback(new FileTransferError(FileTransferError.INVALID_URL_ERR, filePath, server));\n        }\n        return;\n    }\n\n    options = options || {};\n\n    var fileKey = options.fileKey || \"file\";\n    var fileName = options.fileName || \"image.jpg\";\n    var mimeType = options.mimeType || \"image/jpeg\";\n    var params = options.params || {};\n    var withCredentials = options.withCredentials || false;\n    // var chunkedMode = !!options.chunkedMode; // Not supported\n    var headers = options.headers || {};\n    var httpMethod = options.httpMethod && options.httpMethod.toUpperCase() === \"PUT\" ? \"PUT\" : \"POST\";\n\n    var basicAuthHeader = getBasicAuthHeader(server);\n    if (basicAuthHeader) {\n        server = server.replace(getUrlCredentials(server) + '@', '');\n        headers[basicAuthHeader.name] = basicAuthHeader.value;\n    }\n\n    var that = this;\n    var xhr = transfers[this._id] = new XMLHttpRequest();\n    xhr.withCredentials = withCredentials;\n\n    var fail = errorCallback && function(code, status, response) {\n        if (transfers[this._id]) {\n            delete transfers[this._id];\n        }\n        var error = new FileTransferError(code, filePath, server, status, response);\n        if (errorCallback) {\n            errorCallback(error);\n        }\n    };\n\n    window.resolveLocalFileSystemURL(filePath, function(entry) {\n        entry.file(function(file) {\n            var reader = new FileReader();\n            reader.onloadend = function() {\n                var blob = new Blob([this.result], {type: mimeType});\n\n                // Prepare form data to send to server\n                var fd = new FormData();\n                fd.append(fileKey, blob, fileName);\n                for (var prop in params) {\n                    if (params.hasOwnProperty(prop)) {\n                        fd.append(prop, params[prop]);\n                    }\n                }\n\n                xhr.open(httpMethod, server);\n\n                // Fill XHR headers\n                for (var header in headers) {\n                    if (headers.hasOwnProperty(header)) {\n                        xhr.setRequestHeader(header, headers[header]);\n                    }\n                }\n\n                xhr.onload = function() {\n                    if (this.status === 200) {\n                        var result = new FileUploadResult(); // jshint ignore:line\n                        result.bytesSent = blob.size;\n                        result.responseCode = this.status;\n                        result.response = this.response;\n                        delete transfers[that._id];\n                        successCallback(result);\n                    } else if (this.status === 404) {\n                        fail(FileTransferError.INVALID_URL_ERR, this.status, this.response);\n                    } else {\n                        fail(FileTransferError.CONNECTION_ERR, this.status, this.response);\n                    }\n                };\n\n                xhr.ontimeout = function() {\n                    fail(FileTransferError.CONNECTION_ERR, this.status, this.response);\n                };\n\n                xhr.onerror = function() {\n                    fail(FileTransferError.CONNECTION_ERR, this.status, this.response);\n                };\n\n                xhr.onabort = function () {\n                    fail(FileTransferError.ABORT_ERR, this.status, this.response);\n                };\n\n                xhr.upload.onprogress = function (e) {\n                    if (that.onprogress) {\n                        that.onprogress(e);\n                    }\n                };\n\n                xhr.send(fd);\n                // Special case when transfer already aborted, but XHR isn't sent.\n                // In this case XHR won't fire an abort event, so we need to check if transfers record\n                // isn't deleted by filetransfer.abort and if so, call XHR's abort method again\n                if (!transfers[that._id]) {\n                    xhr.abort();\n                }\n            };\n            reader.readAsArrayBuffer(file);\n        }, function() {\n            fail(FileTransferError.FILE_NOT_FOUND_ERR);\n        });\n    }, function() {\n        fail(FileTransferError.FILE_NOT_FOUND_ERR);\n    });\n};\n\n/**\n * Downloads a file form a given URL and saves it to the specified directory.\n * @param source {String}          URL of the server to receive the file\n * @param target {String}         Full path of the file on the device\n * @param successCallback (Function}  Callback to be invoked when upload has completed\n * @param errorCallback {Function}    Callback to be invoked upon error\n * @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false\n * @param options {FileDownloadOptions} Optional parameters such as headers\n */\nFileTransfer.prototype.download = function(source, target, successCallback, errorCallback, trustAllHosts, options) {\n    argscheck.checkArgs('ssFF*', 'FileTransfer.download', arguments);\n\n    // Check if target URL doesn't contain spaces. If contains, it should be escaped first\n    // (see https://github.com/apache/cordova-plugin-file-transfer/blob/master/doc/index.md#download)\n    if (!checkURL(source)) {\n        if (errorCallback) {\n            errorCallback(new FileTransferError(FileTransferError.INVALID_URL_ERR, source, target));\n        }\n        return;\n    }\n\n    options = options || {};\n    \n    var headers = options.headers || {};\n    var withCredentials = options.withCredentials || false;\n\n    var basicAuthHeader = getBasicAuthHeader(source);\n    if (basicAuthHeader) {\n        source = source.replace(getUrlCredentials(source) + '@', '');\n        headers[basicAuthHeader.name] = basicAuthHeader.value;\n    }\n\n    var that = this;\n    var xhr = transfers[this._id] = new XMLHttpRequest();\n    xhr.withCredentials = withCredentials;\n    var fail = errorCallback && function(code, status, response) {\n        if (transfers[that._id]) {\n            delete transfers[that._id];\n        }\n        // In XHR GET reqests we're setting response type to Blob\n        // but in case of error we need to raise event with plain text response\n        if (response instanceof Blob) {\n            var reader = new FileReader();\n            reader.readAsText(response);\n            reader.onloadend = function(e) {\n                var error = new FileTransferError(code, source, target, status, e.target.result);\n                errorCallback(error);\n            };\n        } else {\n            var error = new FileTransferError(code, source, target, status, response);\n            errorCallback(error);\n        }\n    };\n\n    xhr.onload = function (e) {\n\n        var fileNotFound = function () {\n            fail(FileTransferError.FILE_NOT_FOUND_ERR);\n        };\n\n        var req = e.target;\n        // req.status === 0 is special case for local files with file:// URI scheme\n        if ((req.status === 200 || req.status === 0) && req.response) {\n            window.resolveLocalFileSystemURL(getParentPath(target), function (dir) {\n                dir.getFile(getFileName(target), {create: true}, function writeFile(entry) {\n                    entry.createWriter(function (fileWriter) {\n                        fileWriter.onwriteend = function (evt) {\n                            if (!evt.target.error) {\n                                entry.filesystemName = entry.filesystem.name;\n                                delete transfers[that._id];\n                                if (successCallback) {\n                                    successCallback(entry);\n                                }\n                            } else {\n                                fail(FileTransferError.FILE_NOT_FOUND_ERR);\n                            }\n                        };\n                        fileWriter.onerror = function () {\n                            fail(FileTransferError.FILE_NOT_FOUND_ERR);\n                        };\n                        fileWriter.write(req.response);\n                    }, fileNotFound);\n                }, fileNotFound);\n            }, fileNotFound);\n        } else if (req.status === 404) {\n            fail(FileTransferError.INVALID_URL_ERR, req.status, req.response);\n        } else {\n            fail(FileTransferError.CONNECTION_ERR, req.status, req.response);\n        }\n    };\n\n    xhr.onprogress = function (e) {\n        if (that.onprogress) {\n            that.onprogress(e);\n        }\n    };\n\n    xhr.onerror = function () {\n        fail(FileTransferError.CONNECTION_ERR, this.status, this.response);\n    };\n\n    xhr.onabort = function () {\n        fail(FileTransferError.ABORT_ERR, this.status, this.response);\n    };\n\n    xhr.open(\"GET\", source, true);\n\n    for (var header in headers) {\n        if (headers.hasOwnProperty(header)) {\n            xhr.setRequestHeader(header, headers[header]);\n        }\n    }\n\n    xhr.responseType = \"blob\";\n\n    xhr.send();\n};\n\n/**\n * Aborts the ongoing file transfer on this object. The original error\n * callback for the file transfer will be called if necessary.\n */\nFileTransfer.prototype.abort = function() {\n    if (this instanceof FileTransfer) {\n        if (transfers[this._id]) {\n            transfers[this._id].abort();\n            delete transfers[this._id];\n        }\n    }\n};\n\nmodule.exports = FileTransfer;\n"
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/www/firefoxos/FileTransferProxy.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\nvar FileTransferError = require('./FileTransferError'),\n    xhr = {};\n\nfunction getParentPath(filePath) {\n    var pos = filePath.lastIndexOf('/');\n    return filePath.substring(0, pos + 1);\n}\n\nfunction getFileName(filePath) {\n    var pos = filePath.lastIndexOf('/');\n    return filePath.substring(pos + 1);\n}\n\nmodule.exports = {\n    abort: function (successCallback, errorCallback, args) {\n        var id = args[0];\n        if (xhr[id]) {\n            xhr[id].abort();\n            if (typeof(successCallback) === 'function') {\n                successCallback();\n            }\n        } else if (typeof(errorCallback) === 'function') {\n            errorCallback();\n        }\n    },\n\n    upload: function(successCallback, errorCallback, args) {\n        var filePath = args[0],\n            server = args[1],\n            fileKey = args[2],\n            fileName = args[3],\n            mimeType = args[4],\n            params = args[5],\n            /*trustAllHosts = args[6],*/\n            /*chunkedMode = args[7],*/\n            headers = args[8];\n\n        xhr[fileKey] = new XMLHttpRequest({mozSystem: true});\n        xhr[fileKey].onabort = function() {\n            onFail(new FileTransferError(FileTransferError.ABORT_ERR, server, filePath, this.status, xhr[fileKey].response));\n        };\n\n        window.resolveLocalFileSystemURL(filePath, function(entry) {\n            entry.file(function(file) {\n                var reader = new FileReader();\n\n                reader.onloadend = function() {\n                    var blob = new Blob([this.result], {type: mimeType});\n                    var fd = new FormData();\n\n                    fd.append(fileKey, blob, fileName);\n\n                    for (var prop in params) {\n                        if (params.hasOwnProperty(prop)) {\n                            fd.append(prop, params[prop]);\n                        }\n                    }\n\n                    xhr[fileKey].open(\"POST\", server);\n\n                    xhr[fileKey].onload = function(evt) {\n                        if (xhr[fileKey].status === 200) {\n                            var result = new FileUploadResult();\n                            result.bytesSent = blob.size;\n                            result.responseCode = xhr[fileKey].status;\n                            result.response = xhr[fileKey].response;\n                            delete xhr[fileKey];\n                            onSuccess(result);\n                        } else if (xhr[fileKey].status === 404) {\n                            onFail(new FileTransferError(FileTransferError.INVALID_URL_ERR, server, filePath, xhr[fileKey].status, xhr[fileKey].response));\n                        } else {\n                            onFail(new FileTransferError(FileTransferError.CONNECTION_ERR, server, filePath, xhr[fileKey].status, xhr[fileKey].response));\n                        }\n                    };\n\n                    xhr[fileKey].ontimeout = function() {\n                        onFail(new FileTransferError(FileTransferError.CONNECTION_ERR, server, filePath, xhr[fileKey].status, xhr[fileKey].response));\n                    };\n\n                    xhr[fileKey].onerror = function() {\n                        onFail(new FileTransferError(FileTransferError.CONNECTION_ERR, server, filePath, this.status, xhr[fileKey].response));\n                    };\n\n                    for (var header in headers) {\n                        if (headers.hasOwnProperty(header)) {\n                            xhr[fileKey].setRequestHeader(header, headers[header]);\n                        }\n                    }\n\n                    xhr[fileKey].send(fd);\n                };\n\n                reader.readAsArrayBuffer(file);\n\n            }, function() {\n                onFail(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR, server, filePath));\n            });\n        }, function() {\n            onFail(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR, server, filePath));\n        });\n\n        function onSuccess(data) {\n            if (typeof(successCallback) === 'function') {\n                successCallback(data);\n            }\n        }\n\n        function onFail(code) {\n            delete xhr[fileKey];\n            if (typeof(errorCallback) === 'function') {\n                errorCallback(code);\n            }\n        }\n    },\n\n    download: function (successCallback, errorCallback, args) {\n        var source = args[0],\n            target = args[1],\n            id = args[3],\n            headers = args[4];\n\n        xhr[id] = new XMLHttpRequest({mozSystem: true});\n\n        xhr[id].onload = function () {\n            if (xhr[id].readyState === xhr[id].DONE) {\n                if (xhr[id].status === 200 && xhr[id].response) {\n                    window.resolveLocalFileSystemURL(getParentPath(target), function (dir) {\n                        dir.getFile(getFileName(target), {create: true}, writeFile, function (error) {\n                            onFail(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR, source, target, xhr[id].status, xhr[id].response));\n                        });\n                    }, function () {\n                        onFail(new FileTransferError(FileTransferError.FILE_NOT_FOUND_ERR, source, target, xhr[id].status, xhr[id].response));\n                    });\n                } else if (xhr[id].status === 404) {\n                    onFail(new FileTransferError(FileTransferError.INVALID_URL_ERR, source, target, xhr[id].status, xhr[id].response));\n                } else {\n                    onFail(new FileTransferError(FileTransferError.CONNECTION_ERR, source, target, xhr[id].status, xhr[id].response));\n                }\n            }\n        };\n\n        function writeFile(entry) {\n            entry.createWriter(function (fileWriter) {\n                fileWriter.onwriteend = function (evt) {\n                    if (!evt.target.error) {\n                        entry.filesystemName = entry.filesystem.name;\n                        delete xhr[id];\n                        onSuccess(entry);\n                    } else {\n                        onFail(evt.target.error);\n                    }\n                };\n                fileWriter.onerror = function (evt) {\n                    onFail(evt.target.error);\n                };\n                fileWriter.write(new Blob([xhr[id].response]));\n            }, function (error) {\n                onFail(error);\n            });\n        }\n\n        xhr[id].onerror = function (e) {\n            onFail(new FileTransferError(FileTransferError.CONNECTION_ERR, source, target, xhr[id].status, xhr[id].response));\n        };\n\n        xhr[id].onabort = function (e) {\n            onFail(new FileTransferError(FileTransferError.ABORT_ERR, source, target, xhr[id].status, xhr[id].response));\n        };\n\n        xhr[id].open(\"GET\", source, true);\n\n        for (var header in headers) {\n            if (headers.hasOwnProperty(header)) {\n                xhr[id].setRequestHeader(header, headers[header]);\n            }\n        }\n\n        xhr[id].responseType = \"blob\";\n\n        setTimeout(function () {\n            if (xhr[id]) {\n                xhr[id].send();\n            }\n        }, 0);\n\n        function onSuccess(entry) {\n            if (typeof(successCallback) === 'function') {\n                successCallback(entry);\n            }\n        }\n\n        function onFail(error) {\n            delete xhr[id];\n            if (typeof(errorCallback) === 'function') {\n                errorCallback(error);\n            }\n        }\n    }\n};\n\nrequire('cordova/exec/proxy').add('FileTransfer', module.exports);\n"
  },
  {
    "path": "plugins/cordova-plugin-file-transfer/www/wp7/base64.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n// jshint ignore: start\n\nvar chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',\n    INVALID_CHARACTER_ERR = (function () {\n        // fabricate a suitable error object\n        try { document.createElement('$'); }\n        catch (error) { return error; }\n    }());\n\n    // encoder\n    // [https://gist.github.com/999166] by [https://github.com/nignag]\n    window.btoa || (\n    window.btoa = function (input) {\n        for (\n            // initialize result and counter\n          var block, charCode, idx = 0, map = chars, output = '';\n            // if the next input index does not exist:\n            //   change the mapping table to \"=\"\n            //   check if d has no fractional digits\n          input.charAt(idx | 0) || (map = '=', idx % 1) ;\n            // \"8 - idx % 1 * 8\" generates the sequence 2, 4, 6, 8\n          output += map.charAt(63 & block >> 8 - idx % 1 * 8)\n        ) {\n            charCode = input.charCodeAt(idx += 3 / 4);\n            if (charCode > 0xFF) throw INVALID_CHARACTER_ERR;\n            block = block << 8 | charCode;\n        }\n        return output;\n    });\n\n    // decoder\n    // [https://gist.github.com/1020396] by [https://github.com/atk]\n    window.atob || (\n    window.atob = function (input) {\n        input = input.replace(/=+$/, '')\n        if (input.length % 4 == 1) throw INVALID_CHARACTER_ERR;\n        for (\n            // initialize result and counters\n          var bc = 0, bs, buffer, idx = 0, output = '';\n            // get next character\n          buffer = input.charAt(idx++) ;\n            // character found in table? initialize bit storage and add its ascii value;\n          ~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer,\n            // and if not first of each 4 characters,\n            // convert the first 8 bits to one ascii character\n            bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0\n        ) {\n            // try to find character in table (0-63, not found => -1)\n            buffer = chars.indexOf(buffer);\n        }\n        return output;\n    });"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/CONTRIBUTING.md",
    "content": "<!--\n#\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#  KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n#\n-->\n\n# Contributing to Apache Cordova\n\nAnyone can contribute to Cordova. And we need your contributions.\n\nThere are multiple ways to contribute: report bugs, improve the docs, and\ncontribute code.\n\nFor instructions on this, start with the\n[contribution overview](http://cordova.apache.org/contribute/).\n\nThe details are explained there, but the important items are:\n - Sign and submit an Apache ICLA (Contributor License Agreement).\n - Have a Jira issue open that corresponds to your contribution.\n - Run the tests so your patch doesn't break existing functionality.\n\nWe look forward to your contributions!\n\nThe notes on [Commit Workflow](https://github.com/apache/cordova-coho/blob/master/docs/committer-workflow.md#commit-workflow) can be helpful even if you are not a committer.\n\n## Running plugin tests\n\n* clone and install [cordova-plugin-test-framework](https://github.com/apache/cordova-plugin-test-framework)\n```\ngit clone git@github.com:apache/cordova-plugin-test-framework.git\n```\n* edit ```cordova-plugin-test-framework/www/assets/index.html``` and add the following line\n```\n<meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self' data: gap: https://ssl.gstatic.com http://cordova.apache.org http://google.co.uk https://google.co.uk 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *\">\n```\n* create test project\n```\ncordova create plugintest\ncd plugintest\ncordova platform add android\ncordova plugin add ../cordova-plugin-inappbrowser\ncordova plugin add ../cordova-plugin-inappbrowser/tests\ncordova plugin add ../cordova-plugin-test-framework\n```\n* edit ```config.xml``` and replace ```<content src=\"index.html\" />``` with ```<content src=\"cdvtests/index.html\" />```\n* run application\n```\ncordova run\n```\n"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License."
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/NOTICE",
    "content": "Apache Cordova\nCopyright 2012 The Apache Software Foundation\n\nThis product includes software developed at\nThe Apache Software Foundation (http://www.apache.org/).\n"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-inappbrowser.svg?branch=master)](https://travis-ci.org/apache/cordova-plugin-inappbrowser)\n\n# cordova-plugin-inappbrowser\n\nThis plugin provides a web browser view that displays when calling `cordova.InAppBrowser.open()`.\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n\nThe `cordova.InAppBrowser.open()` function is defined to be a drop-in replacement\nfor the `window.open()` function.  Existing `window.open()` calls can use the\nInAppBrowser window, by replacing window.open:\n\n    window.open = cordova.InAppBrowser.open;\n\nThe InAppBrowser window behaves like a standard web browser,\nand can't access Cordova APIs. For this reason, the InAppBrowser is recommended\nif you need to load third-party (untrusted) content, instead of loading that\ninto the main Cordova webview. The InAppBrowser is not subject to the\nwhitelist, nor is opening links in the system browser.\n\nThe InAppBrowser provides by default its own GUI controls for the user (back,\nforward, done).\n\nFor backwards compatibility, this plugin also hooks `window.open`.\nHowever, the plugin-installed hook of `window.open` can have unintended side\neffects (especially if this plugin is included only as a dependency of another\nplugin).  The hook of `window.open` will be removed in a future major release.\nUntil the hook is removed from the plugin, apps can manually restore the default\nbehaviour:\n\n    delete window.open // Reverts the call back to it's prototype's default\n\nAlthough `window.open` is in the global scope, InAppBrowser is not available until after the `deviceready` event.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(\"window.open works well\");\n    }\n\nReport issues with this plugin on the [Apache Cordova issue tracker](https://issues.apache.org/jira/issues/?jql=project%20%3D%20CB%20AND%20status%20in%20%28Open%2C%20%22In%20Progress%22%2C%20Reopened%29%20AND%20resolution%20%3D%20Unresolved%20AND%20component%20%3D%20%22Plugin%20InAppBrowser%22%20ORDER%20BY%20priority%20DESC%2C%20summary%20ASC%2C%20updatedDate%20DESC)\n\n\n\n## Installation\n\n    cordova plugin add cordova-plugin-inappbrowser\n\nIf you want all page loads in your app to go through the InAppBrowser, you can\nsimply hook `window.open` during initialization.  For example:\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        window.open = cordova.InAppBrowser.open;\n    }\n\n## cordova.InAppBrowser.open\n\nOpens a URL in a new `InAppBrowser` instance, the current browser\ninstance, or the system browser.\n\n    var ref = cordova.InAppBrowser.open(url, target, options);\n\n- __ref__: Reference to the `InAppBrowser` window. _(InAppBrowser)_\n\n- __url__: The URL to load _(String)_. Call `encodeURI()` on this if the URL contains Unicode characters.\n\n- __target__: The target in which to load the URL, an optional parameter that defaults to `_self`. _(String)_\n\n    - `_self`: Opens in the Cordova WebView if the URL is in the white list, otherwise it opens in the `InAppBrowser`.\n    - `_blank`: Opens in the `InAppBrowser`.\n    - `_system`: Opens in the system's web browser.\n\n- __options__: Options for the `InAppBrowser`. Optional, defaulting to: `location=yes`. _(String)_\n\n    The `options` string must not contain any blank space, and each feature's name/value pairs must be separated by a comma. Feature names are case insensitive. All platforms support the value below:\n\n    - __location__: Set to `yes` or `no` to turn the `InAppBrowser`'s location bar on or off.\n\n    Android only:\n\n    - __hidden__: set to `yes` to create the browser and load the page, but not show it. The loadstop event fires when loading is complete. Omit or set to `no` (default) to have the browser open and load normally.\n    - __clearcache__: set to `yes` to have the browser's cookie cache cleared before the new window is opened\n    - __clearsessioncache__: set to `yes` to have the session cookie cache cleared before the new window is opened\n    - __zoom__: set to `yes` to show Android browser's zoom controls, set to `no` to hide them.  Default value is `yes`.\n    - __hardwareback__: set to `yes` to use the hardware back button to navigate backwards through the `InAppBrowser`'s history. If there is no previous page, the `InAppBrowser` will close.  The default value is `yes`, so you must set it to `no` if you want the back button to simply close the InAppBrowser.\n    - __mediaPlaybackRequiresUserAction__: Set to `yes` to prevent HTML5 audio or video from autoplaying (defaults to `no`).\n\n    iOS only:\n\n    - __closebuttoncaption__: set to a string to use as the __Done__ button's caption. Note that you need to localize this value yourself.\n    - __disallowoverscroll__: Set to `yes` or `no` (default is `no`). Turns on/off the UIWebViewBounce property.\n    - __hidden__: set to `yes` to create the browser and load the page, but not show it. The loadstop event fires when loading is complete. Omit or set to `no` (default) to have the browser open and load normally.\n    - __clearcache__: set to `yes` to have the browser's cookie cache cleared before the new window is opened\n    - __clearsessioncache__: set to `yes` to have the session cookie cache cleared before the new window is opened\n    - __toolbar__:  set to `yes` or `no` to turn the toolbar on or off for the InAppBrowser (defaults to `yes`)\n    - __enableViewportScale__:  Set to `yes` or `no` to prevent viewport scaling through a meta tag (defaults to `no`).\n    - __mediaPlaybackRequiresUserAction__: Set to `yes` to prevent HTML5 audio or video from autoplaying (defaults to `no`).\n    - __allowInlineMediaPlayback__: Set to `yes` or `no` to allow in-line HTML5 media playback, displaying within the browser window rather than a device-specific playback interface. The HTML's `video` element must also include the `webkit-playsinline` attribute (defaults to `no`)\n    - __keyboardDisplayRequiresUserAction__: Set to `yes` or `no` to open the keyboard when form elements receive focus via JavaScript's `focus()` call (defaults to `yes`).\n    - __suppressesIncrementalRendering__: Set to `yes` or `no` to wait until all new view content is received before being rendered (defaults to `no`).\n    - __presentationstyle__:  Set to `pagesheet`, `formsheet` or `fullscreen` to set the [presentation style](http://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalPresentationStyle) (defaults to `fullscreen`).\n    - __transitionstyle__: Set to `fliphorizontal`, `crossdissolve` or `coververtical` to set the [transition style](http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalTransitionStyle) (defaults to `coververtical`).\n    - __toolbarposition__: Set to `top` or `bottom` (default is `bottom`). Causes the toolbar to be at the top or bottom of the window.\n\n    Windows only:\n\n    - __hidden__: set to `yes` to create the browser and load the page, but not show it. The loadstop event fires when loading is complete. Omit or set to `no` (default) to have the browser open and load normally.\n    - __fullscreen__: set to `yes` to create the browser control without a border around it. Please note that if __location=no__ is also specified, there will be no control presented to user to close IAB window.\n\n### Supported Platforms\n\n- Amazon Fire OS\n- Android\n- BlackBerry 10\n- Firefox OS\n- iOS\n- Windows 8 and 8.1\n- Windows Phone 7 and 8\n- Browser\n\n### Example\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    var ref2 = cordova.InAppBrowser.open(encodeURI('http://ja.m.wikipedia.org/wiki/ハングル'), '_blank', 'location=yes');\n\n### Firefox OS Quirks\n\nAs plugin doesn't enforce any design there is a need to add some CSS rules if\nopened with `target='_blank'`. The rules might look like these\n\n``` css\n.inAppBrowserWrap {\n  background-color: rgba(0,0,0,0.75);\n  color: rgba(235,235,235,1.0);\n}\n.inAppBrowserWrap menu {\n  overflow: auto;\n  list-style-type: none;\n  padding-left: 0;\n}\n.inAppBrowserWrap menu li {\n  font-size: 25px;\n  height: 25px;\n  float: left;\n  margin: 0 10px;\n  padding: 3px 10px;\n  text-decoration: none;\n  color: #ccc;\n  display: block;\n  background: rgba(30,30,30,0.50);\n}\n.inAppBrowserWrap menu li.disabled {\n\tcolor: #777;\n}\n```\n\n### Windows Quirks\n\nWindows 8.0, 8.1 and Windows Phone 8.1 don't support remote urls to be opened in the Cordova WebView so remote urls are always showed in the system's web browser if opened with `target='_self'`.\n\nOn Windows 10 if the URL is NOT in the white list and is opened with `target='_self'` it will be showed in the system's web browser instead of InAppBrowser popup.\n\nSimilar to Firefox OS IAB window visual behaviour can be overridden via `inAppBrowserWrap`/`inAppBrowserWrapFullscreen` CSS classes\n\n### Browser Quirks\n\n- Plugin is implemented via iframe,\n\n- Navigation history (`back` and `forward` buttons in LocationBar) is not implemented.\n\n## InAppBrowser\n\nThe object returned from a call to `cordova.InAppBrowser.open`.\n\n### Methods\n\n- addEventListener\n- removeEventListener\n- close\n- show\n- executeScript\n- insertCSS\n\n## InAppBrowser.addEventListener\n\n> Adds a listener for an event from the `InAppBrowser`.\n\n    ref.addEventListener(eventname, callback);\n\n- __ref__: reference to the `InAppBrowser` window _(InAppBrowser)_\n\n- __eventname__: the event to listen for _(String)_\n\n  - __loadstart__: event fires when the `InAppBrowser` starts to load a URL.\n  - __loadstop__: event fires when the `InAppBrowser` finishes loading a URL.\n  - __loaderror__: event fires when the `InAppBrowser` encounters an error when loading a URL.\n  - __exit__: event fires when the `InAppBrowser` window is closed.\n\n- __callback__: the function that executes when the event fires. The function is passed an `InAppBrowserEvent` object as a parameter.\n\n### InAppBrowserEvent Properties\n\n- __type__: the eventname, either `loadstart`, `loadstop`, `loaderror`, or `exit`. _(String)_\n\n- __url__: the URL that was loaded. _(String)_\n\n- __code__: the error code, only in the case of `loaderror`. _(Number)_\n\n- __message__: the error message, only in the case of `loaderror`. _(String)_\n\n\n### Supported Platforms\n\n- Amazon Fire OS\n- Android\n- iOS\n- Windows 8 and 8.1\n- Windows Phone 7 and 8\n- Browser\n\n### Browser Quirks\n\n`loadstart` and `loaderror` events are not being fired.\n\n### Quick Example\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstart', function(event) { alert(event.url); });\n\n## InAppBrowser.removeEventListener\n\n> Removes a listener for an event from the `InAppBrowser`.\n\n    ref.removeEventListener(eventname, callback);\n\n- __ref__: reference to the `InAppBrowser` window. _(InAppBrowser)_\n\n- __eventname__: the event to stop listening for. _(String)_\n\n  - __loadstart__: event fires when the `InAppBrowser` starts to load a URL.\n  - __loadstop__: event fires when the `InAppBrowser` finishes loading a URL.\n  - __loaderror__: event fires when the `InAppBrowser` encounters an error loading a URL.\n  - __exit__: event fires when the `InAppBrowser` window is closed.\n\n- __callback__: the function to execute when the event fires.\nThe function is passed an `InAppBrowserEvent` object.\n\n### Supported Platforms\n\n- Amazon Fire OS\n- Android\n- iOS\n- Windows 8 and 8.1\n- Windows Phone 7 and 8\n- Browser\n\n### Quick Example\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    var myCallback = function(event) { alert(event.url); }\n    ref.addEventListener('loadstart', myCallback);\n    ref.removeEventListener('loadstart', myCallback);\n\n## InAppBrowser.close\n\n> Closes the `InAppBrowser` window.\n\n    ref.close();\n\n- __ref__: reference to the `InAppBrowser` window _(InAppBrowser)_\n\n### Supported Platforms\n\n- Amazon Fire OS\n- Android\n- Firefox OS\n- iOS\n- Windows 8 and 8.1\n- Windows Phone 7 and 8\n- Browser\n\n### Quick Example\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.close();\n\n## InAppBrowser.show\n\n> Displays an InAppBrowser window that was opened hidden. Calling this has no effect if the InAppBrowser was already visible.\n\n    ref.show();\n\n- __ref__: reference to the InAppBrowser window (`InAppBrowser`)\n\n### Supported Platforms\n\n- Amazon Fire OS\n- Android\n- iOS\n- Windows 8 and 8.1\n- Browser\n\n### Quick Example\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'hidden=yes');\n    // some time later...\n    ref.show();\n\n## InAppBrowser.executeScript\n\n> Injects JavaScript code into the `InAppBrowser` window\n\n    ref.executeScript(details, callback);\n\n- __ref__: reference to the `InAppBrowser` window. _(InAppBrowser)_\n\n- __injectDetails__: details of the script to run, specifying either a `file` or `code` key. _(Object)_\n  - __file__: URL of the script to inject.\n  - __code__: Text of the script to inject.\n\n- __callback__: the function that executes after the JavaScript code is injected.\n    - If the injected script is of type `code`, the callback executes\n      with a single parameter, which is the return value of the\n      script, wrapped in an `Array`. For multi-line scripts, this is\n      the return value of the last statement, or the last expression\n      evaluated.\n\n### Supported Platforms\n\n- Amazon Fire OS\n- Android\n- iOS\n- Windows 8 and 8.1\n- Browser\n\n### Quick Example\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstop', function() {\n        ref.executeScript({file: \"myscript.js\"});\n    });\n\n### Browser Quirks\n\n- only __code__ key is supported.\n\n### Windows Quirks\n\nDue to [MSDN docs](https://msdn.microsoft.com/en-us/library/windows.ui.xaml.controls.webview.invokescriptasync.aspx) the invoked script can return only string values, otherwise the parameter, passed to __callback__ will be `[null]`.\n\n## InAppBrowser.insertCSS\n\n> Injects CSS into the `InAppBrowser` window.\n\n    ref.insertCSS(details, callback);\n\n- __ref__: reference to the `InAppBrowser` window _(InAppBrowser)_\n\n- __injectDetails__: details of the script to run, specifying either a `file` or `code` key. _(Object)_\n  - __file__: URL of the stylesheet to inject.\n  - __code__: Text of the stylesheet to inject.\n\n- __callback__: the function that executes after the CSS is injected.\n\n### Supported Platforms\n\n- Amazon Fire OS\n- Android\n- iOS\n- Windows\n\n### Quick Example\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstop', function() {\n        ref.insertCSS({file: \"mystyles.css\"});\n    });\n"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/RELEASENOTES.md",
    "content": "<!--\n#\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n# \n# http://www.apache.org/licenses/LICENSE-2.0\n# \n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#  KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n#\n-->\n# Release Notes\n\n### 1.4.0 (Apr 15, 2016)\n* CB-7679 add fix for **iOS** upload.\n* CB-10944 `NoSuchMethodError` in `InAppBrowser` plugin\n* CB-10937 fix stretched icons\n* CB-10760 Fixing README for display on Cordova website\n* CB-10636 Add `JSHint` for plugins\n\n### 1.3.0 (Feb 09, 2016)\n* [CB-3360](https://issues.apache.org/jira/browse/CB-3360) Set custom inappbrowser user agent for android\n* [CB-10538](https://issues.apache.org/jira/browse/CB-10538) cordova-plugin-inappbrowser timeout issue\n* [CB-10395](https://issues.apache.org/jira/browse/CB-10395) InAppBrowser's WebView not storing cookies reliable on Android\n* Edit package.json license to match SPDX id\n* [CB-10305](https://issues.apache.org/jira/browse/CB-10305) Gray bar appears in the wrong place on iOS\n* [CB-7786](https://issues.apache.org/jira/browse/CB-7786) Support mediaPlaybackRequiresUserAction on Android\n* [CB-7500](https://issues.apache.org/jira/browse/CB-7500) executeScript with callback kills/blurs inAppBrowser window on Android\n\n### 1.2.1 (Feb 02, 2016)\n* [CB-10407](https://issues.apache.org/jira/browse/CB-10407) InAppBrowser not firing loadstart event on android\n* [CB-10428](https://issues.apache.org/jira/browse/CB-10428) Fix syntax error when browserifying inAppBrowser plugin\n* handle app store urls in system browser\n* [CB-6702](https://issues.apache.org/jira/browse/CB-6702) InAppBrowser hangs when opening more than one instance\n* [CB-10456](https://issues.apache.org/jira/browse/CB-10456) InAppBrowser is not closed if I close it programmatically on Android\n* [CB-10451](https://issues.apache.org/jira/browse/CB-10451) InAppBrowser: loadstart event is not triggered on Windows\n* [CB-10452](https://issues.apache.org/jira/browse/CB-10452) InAppBrowser: 'exit' event is not triggered on Windows\n* [CB-10454](https://issues.apache.org/jira/browse/CB-10454) InAppBrowser: 'loaderror' event does not have code and message on Windows\n* [CB-10450](https://issues.apache.org/jira/browse/CB-10450) InAppBrowser: Unable to get property 'canGoBack' of undefined on Windows\n* [CB-10441](https://issues.apache.org/jira/browse/CB-10441) Add auto tests for InAppBrowser plugin\n\n### 1.2.0 (Jan 15, 2016)\n* CB-8180: Changing methods of interception in `WebViewClient` class\n* CB-10009 Improve `InAppBrowser` toolbar look and feel on **Windows**\n* Open a new window on the **Browser** platform\n\n### 1.1.1 (Dec 10, 2015)\n\n* CB-9445 Improves executeScript callbacks on iOS\n* CB-10035 Incremented plugin version.\n* CB-10040 - re-fix: backwards compatible with cordova-ios < 4.0\n* CB-8534: Allow plugins to respond to onReceivedHttpAuthRequest. This closes #82\n* CB-3750: Fixes spinner on iOS. This closes #89\n* CB-7696 Document target=_self behavior for Windows\n* CB-10040 - Compile Error in InAppBrowser Plugin for iOS - No known instance method for selector 'URLIsWhitelisted:'\n\n### 1.1.0 (Nov 18, 2015)\n* [CB-10035](https://issues.apache.org/jira/browse/CB-10035) Updated `RELEASENOTES` to be newest to oldest\n* Invoke webview if using local file\n* Fixed `zIndex` issue on **Windows 8**, **8.188 where InAppBrowser opens behind default app.\n* fix `async` self usage\n* [CB-9150](https://issues.apache.org/jira/browse/CB-9150) Fix InAppBrowser `executeScript` crash on **Windows** if no data returned\n* [CB-10008](https://issues.apache.org/jira/browse/CB-10008) Fix InAppBrowser popup layout on **Windows**\n* Setting `setStatusBarStyle` to `-1` causes `CGContextSaveGState`.\n* [CB-9167](https://issues.apache.org/jira/browse/CB-9167) Fix crash on **browser** window close \n* [CB-9799](https://issues.apache.org/jira/browse/CB-9799) Fixed `javaDoc` errors.\n* Fixing contribute link.\n* [CB-9760](https://issues.apache.org/jira/browse/CB-9760) InAppBrowser: fallback to default `window.open` behavior on **Ripple**\n* [CB-9378](https://issues.apache.org/jira/browse/CB-9378) Fix InAppBrowser not taking whole screen on **Windows**\n* [CB-9158](https://issues.apache.org/jira/browse/CB-9158) - InAppBrowser `zoomControls` are always set to true\n\n### 1.0.1 (Jun 17, 2015)\n* [CB-9128](https://issues.apache.org/jira/browse/CB-9128) cordova-plugin-inappbrowser documentation translation: cordova-plugin-inappbrowser\n* fix npm md issue\n\n### 1.0.0 (Apr 15, 2015)\n* [CB-8746](https://issues.apache.org/jira/browse/CB-8746) gave plugin major version bump\n* [CB-7689](https://issues.apache.org/jira/browse/CB-7689) Adds insertCSS support for windows platform\n* [CB-4930](https://issues.apache.org/jira/browse/CB-4930) - (prefix) InAppBrowser should take into account the status bar\n* [CB-8635](https://issues.apache.org/jira/browse/CB-8635) Improves UX on windows platform\n* [CB-8661](https://issues.apache.org/jira/browse/CB-8661) Return executed script result on Windows\n* [CB-8683](https://issues.apache.org/jira/browse/CB-8683) updated wp and browser specific references of old id to new id\n* [CB-8683](https://issues.apache.org/jira/browse/CB-8683) changed plugin-id to pacakge-name\n* [CB-8653](https://issues.apache.org/jira/browse/CB-8653) properly updated translated docs to use new id\n* [CB-8653](https://issues.apache.org/jira/browse/CB-8653) updated translated docs to use new id\n* Use TRAVIS_BUILD_DIR, install paramedic by npm\n* [CB-8432](https://issues.apache.org/jira/browse/CB-8432) Correct styles for browser wrapper to display it correctly on some pages\n* [CB-8659](https://issues.apache.org/jira/browse/CB-8659) - Update InAppBrowser to support both cordova-ios 4.0.x and 3.x (closes #93)\n* [CB-7961](https://issues.apache.org/jira/browse/CB-7961) Add cordova-plugin-inappbrowser support for browser platform\n* [CB-8653](https://issues.apache.org/jira/browse/CB-8653) Updated Readme\n* Update docs for Android zoom=no option\n* Added option to disable/enable zoom controls\n* updated docs, set hardwareback default to true\n* Add a hardwareback option to allow for the hardware back button to go back.\n* [CB-8570](https://issues.apache.org/jira/browse/CB-8570) Integrate TravisCI\n* [CB-8438](https://issues.apache.org/jira/browse/CB-8438) cordova-plugin-inappbrowser documentation translation: cordova-plugin-inappbrowser\n* [CB-8538](https://issues.apache.org/jira/browse/CB-8538) Added package.json file\n* Keep external android pages in a single tab. (close #61)\n* [CB-8444](https://issues.apache.org/jira/browse/CB-8444) Add a clobber for `cordova.InAppBrowser.open` (close #80)\n* [CB-8444](https://issues.apache.org/jira/browse/CB-8444) Don't clobber `window.open` - Add new symbol/clobber to access open function (`cordova.InAppBrowser.open`) - Change existing tests to use new symbol (i.e. don't rely on plugin clobber of `window.open`) - Add tests to use `window.open` via manual replace with new symbol - Update docs to deprecate plugin clobber of `window.open`\n\n### 0.6.0 (Feb 04, 2015)\n* [CB-8270](https://issues.apache.org/jira/browse/CB-8270) ios: Remove usage of `[arr JSONString]`, since it's been renamed to `cdv_JSONString`\n* ubuntu: implement `inject*` functions\n* ubuntu: port to oxide\n* [CB-7897](https://issues.apache.org/jira/browse/CB-7897) ios, android: Update to work with whilelist plugins in Cordova 4.x\n\n### 0.5.4 (Dec 02, 2014)\n* [CB-7784](https://issues.apache.org/jira/browse/CB-7784) Exit event is not fired after `InAppBrowser` closing\n* [CB-7697](https://issues.apache.org/jira/browse/CB-7697) Add `locationBar` support to `InAppBrowser` **Windows** platform version\n* [CB-7690](https://issues.apache.org/jira/browse/CB-7690) `InAppBrowser` `loadstart/loadstop` events issues\n* [CB-7695](https://issues.apache.org/jira/browse/CB-7695) Fix `InAppBrowser` `injectScriptFile` for **Windows 8.1** / **Windows Phone 8.1**\n* [CB-7692](https://issues.apache.org/jira/browse/CB-7692) `InAppBrowser` local url opening bug in 8.1\n* [CB-7688](https://issues.apache.org/jira/browse/CB-7688) `Alert` is not supported in `InAppBrowser` on **Windows** platform\n* [CB-7977](https://issues.apache.org/jira/browse/CB-7977) Mention `deviceready` in plugin docs\n* [CB-7876](https://issues.apache.org/jira/browse/CB-7876) change test target to avoid undesired redirects\n* [CB-7712](https://issues.apache.org/jira/browse/CB-7712) remove references to `closebuttoncaption`\n* [CB-7850](https://issues.apache.org/jira/browse/CB-7850) clarify role of whitelist\n* [CB-7720](https://issues.apache.org/jira/browse/CB-7720) check if event is null since OK string from success callback was removed\n* [CB-7471](https://issues.apache.org/jira/browse/CB-7471) cordova-plugin-inappbrowser documentation translation: cordova-plugin-inappbrowser\n\n### 0.5.3 (Oct 03, 2014)\n* Windows implementation fixes and improvements\n* zIndex fixed\n* renamed InAppBrowser back to inappbrowser for case sensitive operating systems\n* Update french translation\n* Update doc to add Windows 8\n* Update windows proxy to be both compatible with windows 8 and 8.1\n* Rename windows81 by windows8 in src directory\n* Append Windows 8.1 platform configuration in plugin.xml\n* Append Windows 8.1 proxy using x-ms-webview\n\n### 0.5.2 (Sep 17, 2014)\n* [CB-7471](https://issues.apache.org/jira/browse/CB-7471) cordova-plugin-inappbrowser documentation translation: cordova-plugin-inappbrowser\n* [CB-7490](https://issues.apache.org/jira/browse/CB-7490) Fixes InAppBrowser manual tests crash on windows platform\n* [CB-7249](https://issues.apache.org/jira/browse/CB-7249) cordova-plugin-inappbrowser documentation translation: cordova-plugin-inappbrowser\n* [CB-7424](https://issues.apache.org/jira/browse/CB-7424) Wrong docs: anchor tags are not supported by the InAppBrowser\n* [CB-7133](https://issues.apache.org/jira/browse/CB-7133) clarify that anchor1 doesn't exist\n* [CB-7133](https://issues.apache.org/jira/browse/CB-7133) more fixup of tests on Android\n* [CB-7133](https://issues.apache.org/jira/browse/CB-7133) fix up the tests for Android\n* Add just a bit more logging\n* [CB-7133](https://issues.apache.org/jira/browse/CB-7133) port inappbrowser to plugin-test-framework\n* phonegap events supported for \\_blank target\n* inappbrowser \\_blank target position is fixed\n* amazon-fireos related changes.\n\n### 0.5.1 (Aug 06, 2014)\n* ubuntu: support qt 5.2\n* **FFOS** update InAppBrowserProxy.js\n* **FFOS** app needs to be privileged\n* [CB-6127](https://issues.apache.org/jira/browse/CB-6127) Updated translations for docs\n* [CB-6769](https://issues.apache.org/jira/browse/CB-6769) ios: Fix statusbar color reset wasn't working on iOS7+\n\n### 0.5.0 (Jun 05, 2014)\n* [CB-6127](https://issues.apache.org/jira/browse/CB-6127) Spanish and rench Translations added. Github close #23\n* Clean up whitespace (mainly due to no newline at eof warning)\n* Adding permission info\n* [CB-6806](https://issues.apache.org/jira/browse/CB-6806) Add license\n* [CB-6491](https://issues.apache.org/jira/browse/CB-6491) add CONTRIBUTING.md\n* Add necessary capability so the plugin works on its own\n* [CB-6474](https://issues.apache.org/jira/browse/CB-6474) InAppBrowser. Add data urls support to WP8\n* [CB-6482](https://issues.apache.org/jira/browse/CB-6482) InAppBrowser calls incorrect callback on WP8\n* Fixed use of iOS 6 deprecated methods\n* [CB-6360](https://issues.apache.org/jira/browse/CB-6360) - improvement: feature detection instead of iOS version detection\n* [CB-5649](https://issues.apache.org/jira/browse/CB-5649) - InAppBrowser overrides App's orientation\n* refactoring fixed\n* [CB-6396](https://issues.apache.org/jira/browse/CB-6396) [Firefox OS] Adding basic support\n\n### 0.4.0 (Apr 17, 2014)\n* [CB-6360](https://issues.apache.org/jira/browse/CB-6360): [ios] Fix for crash on iOS < 6.0 (closes #37)\n* [CB-3324](https://issues.apache.org/jira/browse/CB-3324): [WP8] Add support for back-button inappbrowser [WP8] if there is no history -> InAppBrowser is closed\n* [WP] await async calls, resolve warnings\n* [WP] Make InAppBrowser work with embedded files, using system behavior\n* [CB-6402](https://issues.apache.org/jira/browse/CB-6402): [WP8] pass empty string instead of null for [optional] windowFeatures string\n* [CB-6422](https://issues.apache.org/jira/browse/CB-6422): [windows8] use cordova/exec/proxy\n* [CB-6389](https://issues.apache.org/jira/browse/CB-6389) [CB-3617](https://issues.apache.org/jira/browse/CB-3617): Add clearcache and clearsessioncache options to iOS (like Android)\n* Doc update: event name and example param (closes #31)\n* [CB-6253](https://issues.apache.org/jira/browse/CB-6253): [WP] Add Network Capability to WMAppManifest.xml\n* [CB-6212](https://issues.apache.org/jira/browse/CB-6212): [iOS] fix warnings compiled under arm64 64-bit\n* [CB-6218](https://issues.apache.org/jira/browse/CB-6218): Update docs for BB10\n* [CB-6460](https://issues.apache.org/jira/browse/CB-6460): Update license headers\n\n### 0.3.3 (Mar 5, 2014)\n* [CB-5534](https://issues.apache.org/jira/browse/CB-5534) Fix video/audio does not stop playing when browser is closed\n* [CB-6172](https://issues.apache.org/jira/browse/CB-6172) Fix broken install on case-sensitive file-systems\n\n### 0.3.2 (Feb 26, 2014)\n* Validate that callbackId is correctly formed\n* [CB-6035](https://issues.apache.org/jira/browse/CB-6035) Move js-module so it is not loaded on unsupported platforms\n* Removed some iOS6 Deprecations\n\n### 0.3.1 (Feb 05, 2014)\n* [CB-5756](https://issues.apache.org/jira/browse/CB-5756): Android: Use WebView.evaluateJavascript for script injection on Android 4.4+\n* Didn't test on ICS or lower, getDrawable isn't supported until Jellybean\n* add ubuntu platform\n* Adding drawables to the inAppBrowser.  This doesn't look quite right, but it's a HUGE improvement over the previous settings\n* [CB-5756](https://issues.apache.org/jira/browse/CB-5756): Android: Use WebView.evaluateJavascript for script injection on Android 4.4+\n* Remove alive from InAppBrowser.js since it didn't catch the case where the browser is closed by the user.\n* [CB-5733](https://issues.apache.org/jira/browse/CB-5733) Fix IAB.close() not working if called before show() animation is done\n\n### 0.2.5 (Dec 4, 2013)\n* Remove merge conflict tag\n* [CB-4724](https://issues.apache.org/jira/browse/CB-4724) fixed UriFormatException\n* add ubuntu platform\n* [CB-3420](https://issues.apache.org/jira/browse/CB-3420) WP feature hidden=yes implemented\n* Added amazon-fireos platform. Change to use amazon-fireos as the platform if user agent string contains 'cordova-amazon-fireos'\n\n### 0.2.4 (Oct 28, 2013)\n* [CB-5128](https://issues.apache.org/jira/browse/CB-5128): added repo + issue tag to plugin.xml for inappbrowser plugin\n* [CB-4995](https://issues.apache.org/jira/browse/CB-4995) Fix crash when WebView is quickly opened then closed.\n* [CB-4930](https://issues.apache.org/jira/browse/CB-4930) - iOS - InAppBrowser should take into account the status bar\n* [CB-5010](https://issues.apache.org/jira/browse/CB-5010) Incremented plugin version on dev branch.\n* [CB-5010](https://issues.apache.org/jira/browse/CB-5010) Updated version and RELEASENOTES.md for release 0.2.3\n* [CB-4858](https://issues.apache.org/jira/browse/CB-4858) - Run IAB methods on the UI thread.\n* [CB-4858](https://issues.apache.org/jira/browse/CB-4858) Convert relative URLs to absolute URLs in JS\n* [CB-3747](https://issues.apache.org/jira/browse/CB-3747) Fix back button having different dismiss logic from the close button.\n* [CB-5021](https://issues.apache.org/jira/browse/CB-5021) Expose closeDialog() as a public function and make it safe to call multiple times.\n* [CB-5021](https://issues.apache.org/jira/browse/CB-5021) Make it safe to call close() multiple times\n\n### 0.2.3 (Oct 9, 2013)\n* [CB-4915](https://issues.apache.org/jira/browse/CB-4915) Incremented plugin version on dev branch.\n* [CB-4926](https://issues.apache.org/jira/browse/CB-4926) Fixes inappbrowser plugin loading for windows8\n\n### 0.2.2 (Sept 25, 2013)\n* [CB-4889](https://issues.apache.org/jira/browse/CB-4889) bumping&resetting version\n* [CB-4788](https://issues.apache.org/jira/browse/CB-4788): Modified the onJsPrompt to warn against Cordova calls\n* [windows8] commandProxy was moved\n* [CB-4788](https://issues.apache.org/jira/browse/CB-4788): Modified the onJsPrompt to warn against Cordova calls\n* [windows8] commandProxy was moved\n* [CB-4889](https://issues.apache.org/jira/browse/CB-4889) renaming core references\n* [CB-4889](https://issues.apache.org/jira/browse/CB-4889) renaming org.apache.cordova.core.inappbrowser to org.apache.cordova.inappbrowser\n* [CB-4864](https://issues.apache.org/jira/browse/CB-4864), [CB-4865](https://issues.apache.org/jira/browse/CB-4865): Minor improvements to InAppBrowser\n* Rename CHANGELOG.md -> RELEASENOTES.md\n* [CB-4792](https://issues.apache.org/jira/browse/CB-4792) Added keepCallback to the show function.\n* [CB-4752](https://issues.apache.org/jira/browse/CB-4752) Incremented plugin version on dev branch.\n"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/doc/de/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-inappbrowser\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-inappbrowser.svg)](https://travis-ci.org/apache/cordova-plugin-inappbrowser)\n\nDieses Plugin bietet eine Web-Browser-Ansicht, die beim Aufruf von `cordova.InAppBrowser.open()`.\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    \n\nDie `cordova.InAppBrowser.open()` Funktion ist definiert als Ersatz für die `window.open()` Funktion. InAppBrowser Fenster, können vorhandene `window.open()` Aufrufe durch window.open ersetzen:\n\n    window.open = cordova.InAppBrowser.open;\n    \n\nDas InAppBrowser-Fenster verhält sich wie einen standard-Webbrowser und Cordova APIs kann nicht zugegriffen werden kann. Aus diesem Grund empfiehlt sich die InAppBrowser Wenn Sie von Drittanbietern (nicht vertrauenswürdige) Inhalte, statt zu laden, die in den wichtigsten Cordova Webview laden müssen. Die InAppBrowser unterliegt nicht der weißen Liste, noch ist Links in der Systembrowser öffnen.\n\nDie InAppBrowser bietet standardmäßig eine eigene GUI-Steuerelemente für den Benutzer (zurück, vor, erledigt).\n\nFür rückwärts Kompatibilität, dieses Plugin auch `window.open` Haken. Jedoch kann der Plugin installiert Haken der `window.open` haben unbeabsichtigte Nebenwirkungen (vor allem, wenn dieses Plugin nur als eine Abhängigkeit von einem anderen Plugin enthalten ist). Der Haken der `window.open` wird in einer zukünftigen Version entfernt. Bis der Haken aus dem Plugin entfernt wird, können die Vorgabe von apps manuell wiederherstellen:\n\n    delete window.open // Reverts the call back to it's prototype's default\n    \n\n`window.open` im globalen Gültigkeitsbereich ist zwar InAppBrowser nicht verfügbar bis nach dem `deviceready`-Ereignis.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(\"window.open works well\");\n    }\n    \n\n## Installation\n\n    cordova plugin add cordova-plugin-inappbrowser\n    \n\nWenn Sie alle Seite Lasten in Ihrer Anwendung durch die InAppBrowser gehen möchten, können Sie einfach `window.open` während der Initialisierung Haken. Zum Beispiel:\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        window.open = cordova.InAppBrowser.open;\n    }\n    \n\n## cordova.InAppBrowser.open\n\nÖffnet eine URL in eine neue `InAppBrowser`-Instanz, die aktuelle Browserinstanz oder der Systembrowser.\n\n    var ref = cordova.InAppBrowser.open(url, target, options);\n    \n\n  * **Ref**: Bezugnahme auf das `InAppBrowser` Fenster. *(InAppBrowser)*\n\n  * **URL**: die URL um den *(String)* zu laden. Rufen Sie `encodeURI()` auf, wenn die URL Unicode-Zeichen enthält.\n\n  * **target**: das Ziel in welchem die URL geladen werden soll. Standardmäßig entspricht dieser Wert `_self` . *(String)*\n    \n      * `_self`: Öffnet sich in der Cordova WebView wenn der URL in der Whitelist ist, andernfalls es öffnet sich in der`InAppBrowser`.\n      * `_blank`: Öffnet den`InAppBrowser`.\n      * `_system`: Öffnet in den System-Web-Browser.\n\n  * **options**: Optionen für die `InAppBrowser` . Optional, säumige an: `location=yes` . *(String)*\n    \n    Die `options` Zeichenfolge muss keine Leerstelle enthalten, und jede Funktion Name/Wert-Paare müssen durch ein Komma getrennt werden. Featurenamen Groß-/Kleinschreibung. Alle Plattformen unterstützen die anderen Werte:\n    \n      * **location**: Legen Sie auf `yes` oder `no` , machen die `InAppBrowser` der Adressleiste ein- oder ausschalten.\n    \n    Nur Android:\n    \n      * **hidden**: Legen Sie auf `yes` um den Browser zu erstellen und laden Sie die Seite, aber nicht zeigen. Das Loadstop-Ereignis wird ausgelöst, wenn der Ladevorgang abgeschlossen ist. Weglassen oder auf `no` (Standard), den Browser öffnen und laden normalerweise zu haben.\n      * **clearcache**: Legen Sie auf `yes` , der Browser ist Cookiecache gelöscht, bevor das neue Fenster geöffnet wird\n      * **clearsessioncache**: Legen Sie auf `yes` zu der Session Cookie Cache gelöscht, bevor das neue Fenster geöffnet wird\n      * **zoom**: Legen Sie auf `yes` zu zeigen Android Browser-Zoom-Steuerelementen, die auf `no` festlegen, um sie zu verbergen. Standardwert ist `yes`.\n      * **hardwareback**: auf `yes` festlegen, um die Zurück-Taste verwenden, um die `InAppBrowser`Geschichte rückwärts navigieren. Wenn es keine vorherige Seite, wird der `InAppBrowser` geschlossen. Der Standardwert ist `yes`, so dass Sie es auf `no` festlegen müssen, wenn Sie die Schaltfläche \"zurück\", die InAppBrowser einfach zu schließen möchten.\n    \n    iOS nur:\n    \n      * **closebuttoncaption**: Legen Sie auf eine Zeichenfolge als Beschriftung der **fertig** -Schaltfläche verwenden. Beachten Sie, dass Sie diesen Wert selbst zu lokalisieren müssen.\n      * **disallowoverscroll**: Legen Sie auf `yes` oder `no` (Standard ist `no` ). Aktiviert/deaktiviert die UIWebViewBounce-Eigenschaft.\n      * **hidden**: Legen Sie auf `yes` um den Browser zu erstellen und laden Sie die Seite, aber nicht zeigen. Das Loadstop-Ereignis wird ausgelöst, wenn der Ladevorgang abgeschlossen ist. Weglassen oder auf `no` (Standard), den Browser öffnen und laden normalerweise zu haben.\n      * **clearcache**: Legen Sie auf `yes` , der Browser ist Cookiecache gelöscht, bevor das neue Fenster geöffnet wird\n      * **clearsessioncache**: Legen Sie auf `yes` zu der Session Cookie Cache gelöscht, bevor das neue Fenster geöffnet wird\n      * **toolbar**: Legen Sie auf `yes` oder `no` Aktivieren Sie die Symbolleiste ein- oder Ausschalten für InAppBrowser (Standard:`yes`)\n      * **enableViewportScale**: Legen Sie auf `yes` oder `no` , Viewport Skalierung durch ein Meta-Tag (standardmäßig zu verhindern`no`).\n      * **mediaPlaybackRequiresUserAction**: Legen Sie auf `yes` oder `no` , HTML5 audio oder video von automatisches Abspielen (standardmäßig zu verhindern`no`).\n      * **allowInlineMediaPlayback**: Legen Sie auf `yes` oder `no` Inline-HTML5-Media-Wiedergabe, Darstellung im Browser-Fenster, sondern in eine gerätespezifische Wiedergabe-Schnittstelle ermöglichen. Des HTML `video` Element muss auch die `webkit-playsinline` Attribut (Standard:`no`)\n      * **keyboardDisplayRequiresUserAction**: Legen Sie auf `yes` oder `no` um die Tastatur zu öffnen, wenn Formularelemente Fokus per JavaScript erhalten `focus()` Anruf (Standard:`yes`).\n      * **suppressesIncrementalRendering**: Legen Sie auf `yes` oder `no` zu warten, bis alle neuen anzeigen-Inhalte empfangen wird, bevor Sie wiedergegeben wird (standardmäßig`no`).\n      * **presentationstyle**: Legen Sie auf `pagesheet` , `formsheet` oder `fullscreen` [Präsentationsstil](http://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalPresentationStyle) (standardmäßig fest`fullscreen`).\n      * **transitionstyle**: Legen Sie auf `fliphorizontal` , `crossdissolve` oder `coververtical` [Übergangsstil](http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalTransitionStyle) (standardmäßig fest`coververtical`).\n      * **toolbarposition**: Legen Sie auf `top` oder `bottom` (Standard ist `bottom` ). Bewirkt, dass die Symbolleiste am oberen oder unteren Rand des Fensters sein.\n    \n    Nur Windows:\n    \n      * **hidden**: Legen Sie auf `yes` um den Browser zu erstellen und laden Sie die Seite, aber nicht zeigen. Das Loadstop-Ereignis wird ausgelöst, wenn der Ladevorgang abgeschlossen ist. Weglassen oder auf `no` (Standard), den Browser öffnen und laden normalerweise zu haben.\n      * **fullscreen**: auf `yes` festlegen, um das WebBrowser-Steuerelement ohne Rahmen drumherum zu erstellen. Bitte beachten Sie, dass bei **location=no** wird auch angegeben, gibt es keine Kontrolle, die Benutzer zum IAB-Fenster schließen.\n\n### Unterstützte Plattformen\n\n  * Amazon Fire OS\n  * Android\n  * BlackBerry 10\n  * Firefox OS\n  * iOS\n  * Windows 8 und 8.1\n  * Windows Phone 7 und 8\n  * Browser\n\n### Beispiel\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    var ref2 = cordova.InAppBrowser.open(encodeURI('http://ja.m.wikipedia.org/wiki/ハングル'), '_blank', 'location=yes');\n    \n\n### Firefox OS Macken\n\nAls Plugin jedes Design erzwingen nicht besteht die Notwendigkeit, einige CSS-Regeln hinzuzufügen, wenn bei `target='_blank'`. Die Regeln könnte wie diese aussehen.\n\n```css\n.inAppBrowserWrap {\n  background-color: rgba(0,0,0,0.75);\n  color: rgba(235,235,235,1.0);\n}\n.inAppBrowserWrap menu {\n  overflow: auto;\n  list-style-type: none;\n  padding-left: 0;\n}\n.inAppBrowserWrap menu li {\n  font-size: 25px;\n  height: 25px;\n  float: left;\n  margin: 0 10px;\n  padding: 3px 10px;\n  text-decoration: none;\n  color: #ccc;\n  display: block;\n  background: rgba(30,30,30,0.50);\n}\n.inAppBrowserWrap menu li.disabled {\n    color: #777;\n}\n```\n\n### Windows-Eigenheiten\n\nÄhnlich wie Firefox OS IAB Fenster visuelle Verhalten kann überschrieben werden, über `InAppBrowserWrap`/`InAppBrowserWrapFullscreen` -CSS-Klassen\n\n### Browser-Eigenheiten\n\n  * Plugin wird per Iframe implementiert,\n\n  * Navigationsverlauf (Schaltflächen`zurück` und `Vorwärts` in LocationBar) ist nicht implementiert.\n\n## InAppBrowser\n\nBei einem Aufruf von `cordova.InAppBrowser.open` zurückgegebene Objekt..\n\n### Methoden\n\n  * addEventListener\n  * removeEventListener\n  * Schließen\n  * Karte\n  * executeScript\n  * insertCSS\n\n## addEventListener\n\n> Fügt einen Listener für eine Veranstaltung aus der`InAppBrowser`.\n\n    ref.addEventListener(eventname, callback);\n    \n\n  * **Ref**: Bezugnahme auf die `InAppBrowser` Fenster *(InAppBrowser)*\n\n  * **EventName**: das Ereignis zu warten *(String)*\n    \n      * **Loadstart**: Ereignis wird ausgelöst, wenn die `InAppBrowser` beginnt, eine URL zu laden.\n      * **Loadstop**: Ereignis wird ausgelöst, wenn der `InAppBrowser` beendet ist, eine URL laden.\n      * **LoadError**: Ereignis wird ausgelöst, wenn der `InAppBrowser` ein Fehler auftritt, wenn Sie eine URL zu laden.\n      * **Ausfahrt**: Ereignis wird ausgelöst, wenn das `InAppBrowser` -Fenster wird geschlossen.\n\n  * **Rückruf**: die Funktion, die ausgeführt wird, wenn das Ereignis ausgelöst wird. Die Funktion übergeben wird ein `InAppBrowserEvent` -Objekt als Parameter.\n\n### InAppBrowserEvent Eigenschaften\n\n  * **Typ**: Eventname, entweder `loadstart` , `loadstop` , `loaderror` , oder `exit` . *(String)*\n\n  * **URL**: die URL, die geladen wurde. *(String)*\n\n  * **Code**: der Fehler-Code, nur im Fall von `loaderror` . *(Anzahl)*\n\n  * **Nachricht**: die Fehlermeldung angezeigt, nur im Fall von `loaderror` . *(String)*\n\n### Unterstützte Plattformen\n\n  * Amazon Fire OS\n  * Android\n  * iOS\n  * Windows 8 und 8.1\n  * Windows Phone 7 und 8\n  * Browser\n\n### Browser-Eigenheiten\n\n`loadstart` und `loaderror` Ereignisse werden nicht ausgelöst wird.\n\n### Kurzes Beispiel\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstart', function(event) { alert(event.url); });\n    \n\n## removeEventListener\n\n> Entfernt einen Listener für eine Veranstaltung aus der`InAppBrowser`.\n\n    ref.removeEventListener(eventname, callback);\n    \n\n  * **Ref**: Bezugnahme auf die `InAppBrowser` Fenster. *(InAppBrowser)*\n\n  * **EventName**: das Ereignis zu warten. *(String)*\n    \n      * **Loadstart**: Ereignis wird ausgelöst, wenn die `InAppBrowser` beginnt, eine URL zu laden.\n      * **Loadstop**: Ereignis wird ausgelöst, wenn der `InAppBrowser` beendet ist, eine URL laden.\n      * **LoadError**: Ereignis wird ausgelöst, wenn die `InAppBrowser` trifft einen Fehler beim Laden einer URLs.\n      * **Ausfahrt**: Ereignis wird ausgelöst, wenn das `InAppBrowser` -Fenster wird geschlossen.\n\n  * **Rückruf**: die Funktion ausgeführt, wenn das Ereignis ausgelöst wird. Die Funktion übergeben wird ein `InAppBrowserEvent` Objekt.\n\n### Unterstützte Plattformen\n\n  * Amazon Fire OS\n  * Android\n  * iOS\n  * Windows 8 und 8.1\n  * Windows Phone 7 und 8\n  * Browser\n\n### Kurzes Beispiel\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    var myCallback = function(event) { alert(event.url); }\n    ref.addEventListener('loadstart', myCallback);\n    ref.removeEventListener('loadstart', myCallback);\n    \n\n## Schließen\n\n> Schließt die `InAppBrowser` Fenster.\n\n    ref.close();\n    \n\n  * **Ref**: Bezugnahme auf die `InAppBrowser` Fenster *(InAppBrowser)*\n\n### Unterstützte Plattformen\n\n  * Amazon Fire OS\n  * Android\n  * Firefox OS\n  * iOS\n  * Windows 8 und 8.1\n  * Windows Phone 7 und 8\n  * Browser\n\n### Kurzes Beispiel\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.close();\n    \n\n## Karte\n\n> Zeigt ein InAppBrowser-Fenster, das geöffnet wurde, versteckt. Aufrufen, dies hat keine Auswirkungen, wenn die InAppBrowser schon sichtbar war.\n\n    ref.show();\n    \n\n  * **Ref**: Verweis auf die (InAppBrowser) Fenster`InAppBrowser`)\n\n### Unterstützte Plattformen\n\n  * Amazon Fire OS\n  * Android\n  * iOS\n  * Windows 8 und 8.1\n  * Browser\n\n### Kurzes Beispiel\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'hidden=yes');\n    // some time later...\n    ref.show();\n    \n\n## executeScript\n\n> Fügt JavaScript-Code in das `InAppBrowser` Fenster\n\n    ref.executeScript(details, callback);\n    \n\n  * **Ref**: Bezugnahme auf die `InAppBrowser` Fenster. *(InAppBrowser)*\n\n  * **InjectDetails**: Informationen über das Skript ausgeführt, angeben, entweder ein `file` oder `code` Schlüssel. *(Objekt)*\n    \n      * **Datei**: URL des Skripts zu injizieren.\n      * **Code**: Text des Skripts zu injizieren.\n\n  * **Rückruf**: die Funktion, die ausgeführt wird, nachdem der JavaScript-Code injiziert wird.\n    \n      * Wenn das eingefügte Skript vom Typ ist `code` , der Rückruf führt mit einen einzelnen Parameter, der der Rückgabewert des Skripts ist, umwickelt ein `Array` . Bei Multi-Line-Skripten ist der Rückgabewert von der letzten Anweisung oder den letzten Ausdruck ausgewertet.\n\n### Unterstützte Plattformen\n\n  * Amazon Fire OS\n  * Android\n  * iOS\n  * Windows 8 und 8.1\n  * Browser\n\n### Kurzes Beispiel\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstop', function() {\n        ref.executeScript({file: \"myscript.js\"});\n    });\n    \n\n### Browser-Eigenheiten\n\n  * **code** -Schlüssel wird unterstützt.\n\n### Windows-Eigenheiten\n\nAufgrund der [MSDN-Dokumentation](https://msdn.microsoft.com/en-us/library/windows.ui.xaml.controls.webview.invokescriptasync.aspx) das aufgerufene Skript kehren nur Zeichenfolgenwerte, andernfalls des Parameters, an **Rückruf** übergeben werden `[null]`.\n\n## insertCSS\n\n> Injiziert CSS in der `InAppBrowser` Fenster.\n\n    ref.insertCSS(details, callback);\n    \n\n  * **Ref**: Bezugnahme auf die `InAppBrowser` Fenster *(InAppBrowser)*\n\n  * **InjectDetails**: Informationen über das Skript ausgeführt, angeben, entweder ein `file` oder `code` Schlüssel. *(Objekt)*\n    \n      * **Datei**: URL des Stylesheets zu injizieren.\n      * **Code**: Text des Stylesheets zu injizieren.\n\n  * **Rückruf**: die Funktion, die ausgeführt wird, nachdem die CSS injiziert wird.\n\n### Unterstützte Plattformen\n\n  * Amazon Fire OS\n  * Android\n  * iOS\n  * Windows\n\n### Kurzes Beispiel\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstop', function() {\n        ref.insertCSS({file: \"mystyles.css\"});\n    });"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/doc/de/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-inappbrowser\n\nDieses Plugin bietet eine Web-Browser-Ansicht, die beim Aufruf von `cordova.InAppBrowser.open()`.\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    \n\nDie `cordova.InAppBrowser.open()` Funktion ist definiert als Ersatz für die `window.open()` Funktion. InAppBrowser Fenster, können vorhandene `window.open()` Aufrufe durch window.open ersetzen:\n\n    window.open = cordova.InAppBrowser.open;\n    \n\nDas InAppBrowser-Fenster verhält sich wie einen standard-Webbrowser und Cordova APIs kann nicht zugegriffen werden kann. Aus diesem Grund empfiehlt sich die InAppBrowser Wenn Sie von Drittanbietern (nicht vertrauenswürdige) Inhalte, statt zu laden, die in den wichtigsten Cordova Webview laden müssen. Die InAppBrowser unterliegt nicht der weißen Liste, noch ist Links in der Systembrowser öffnen.\n\nDie InAppBrowser bietet standardmäßig eine eigene GUI-Steuerelemente für den Benutzer (zurück, vor, erledigt).\n\nFür rückwärts Kompatibilität, dieses Plugin auch `window.open` Haken. Jedoch kann der Plugin installiert Haken der `window.open` haben unbeabsichtigte Nebenwirkungen (vor allem, wenn dieses Plugin nur als eine Abhängigkeit von einem anderen Plugin enthalten ist). Der Haken der `window.open` wird in einer zukünftigen Version entfernt. Bis der Haken aus dem Plugin entfernt wird, können die Vorgabe von apps manuell wiederherstellen:\n\n    delete window.open // Reverts the call back to it's prototype's default\n    \n\n`window.open` im globalen Gültigkeitsbereich ist zwar InAppBrowser nicht verfügbar bis nach dem `deviceready`-Ereignis.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(\"window.open works well\");\n    }\n    \n\n## Installation\n\n    cordova plugin add cordova-plugin-inappbrowser\n    \n\nWenn Sie alle Seite Lasten in Ihrer Anwendung durch die InAppBrowser gehen möchten, können Sie einfach `window.open` während der Initialisierung Haken. Zum Beispiel:\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        window.open = cordova.InAppBrowser.open;\n    }\n    \n\n## cordova.InAppBrowser.open\n\nÖffnet eine URL in eine neue `InAppBrowser`-Instanz, die aktuelle Browserinstanz oder der Systembrowser.\n\n    var ref = cordova.InAppBrowser.open(url, target, options);\n    \n\n*   **Ref**: Bezugnahme auf das `InAppBrowser` Fenster. *(InAppBrowser)*\n\n*   **URL**: die URL um den *(String)* zu laden. Rufen Sie `encodeURI()` auf, wenn die URL Unicode-Zeichen enthält.\n\n*   **target**: das Ziel in welchem die URL geladen werden soll. Standardmäßig entspricht dieser Wert `_self` . *(String)*\n    \n    *   `_self`: Öffnet sich in der Cordova WebView wenn der URL in der Whitelist ist, andernfalls es öffnet sich in der`InAppBrowser`.\n    *   `_blank`: Öffnet den`InAppBrowser`.\n    *   `_system`: Öffnet in den System-Web-Browser.\n\n*   **options**: Optionen für die `InAppBrowser` . Optional, säumige an: `location=yes` . *(String)*\n    \n    Die `options` Zeichenfolge muss keine Leerstelle enthalten, und jede Funktion Name/Wert-Paare müssen durch ein Komma getrennt werden. Featurenamen Groß-/Kleinschreibung. Alle Plattformen unterstützen die anderen Werte:\n    \n    *   **location**: Legen Sie auf `yes` oder `no` , machen die `InAppBrowser` der Adressleiste ein- oder ausschalten.\n    \n    Nur Android:\n    \n    *   **hidden**: Legen Sie auf `yes` um den Browser zu erstellen und laden Sie die Seite, aber nicht zeigen. Das Loadstop-Ereignis wird ausgelöst, wenn der Ladevorgang abgeschlossen ist. Weglassen oder auf `no` (Standard), den Browser öffnen und laden normalerweise zu haben.\n    *   **clearcache**: Legen Sie auf `yes` , der Browser ist Cookiecache gelöscht, bevor das neue Fenster geöffnet wird\n    *   **clearsessioncache**: Legen Sie auf `yes` zu der Session Cookie Cache gelöscht, bevor das neue Fenster geöffnet wird\n    \n    iOS nur:\n    \n    *   **closebuttoncaption**: Legen Sie auf eine Zeichenfolge als Beschriftung der **fertig** -Schaltfläche verwenden. Beachten Sie, dass Sie diesen Wert selbst zu lokalisieren müssen.\n    *   **disallowoverscroll**: Legen Sie auf `yes` oder `no` (Standard ist `no` ). Aktiviert/deaktiviert die UIWebViewBounce-Eigenschaft.\n    *   **hidden**: Legen Sie auf `yes` um den Browser zu erstellen und laden Sie die Seite, aber nicht zeigen. Das Loadstop-Ereignis wird ausgelöst, wenn der Ladevorgang abgeschlossen ist. Weglassen oder auf `no` (Standard), den Browser öffnen und laden normalerweise zu haben.\n    *   **clearcache**: Legen Sie auf `yes` , der Browser ist Cookiecache gelöscht, bevor das neue Fenster geöffnet wird\n    *   **clearsessioncache**: Legen Sie auf `yes` zu der Session Cookie Cache gelöscht, bevor das neue Fenster geöffnet wird\n    *   **toolbar**: Legen Sie auf `yes` oder `no` Aktivieren Sie die Symbolleiste ein- oder Ausschalten für InAppBrowser (Standard:`yes`)\n    *   **enableViewportScale**: Legen Sie auf `yes` oder `no` , Viewport Skalierung durch ein Meta-Tag (standardmäßig zu verhindern`no`).\n    *   **mediaPlaybackRequiresUserAction**: Legen Sie auf `yes` oder `no` , HTML5 audio oder video von automatisches Abspielen (standardmäßig zu verhindern`no`).\n    *   **allowInlineMediaPlayback**: Legen Sie auf `yes` oder `no` Inline-HTML5-Media-Wiedergabe, Darstellung im Browser-Fenster, sondern in eine gerätespezifische Wiedergabe-Schnittstelle ermöglichen. Des HTML `video` Element muss auch die `webkit-playsinline` Attribut (Standard:`no`)\n    *   **keyboardDisplayRequiresUserAction**: Legen Sie auf `yes` oder `no` um die Tastatur zu öffnen, wenn Formularelemente Fokus per JavaScript erhalten `focus()` Anruf (Standard:`yes`).\n    *   **suppressesIncrementalRendering**: Legen Sie auf `yes` oder `no` zu warten, bis alle neuen anzeigen-Inhalte empfangen wird, bevor Sie wiedergegeben wird (standardmäßig`no`).\n    *   **presentationstyle**: Legen Sie auf `pagesheet` , `formsheet` oder `fullscreen` [Präsentationsstil][1] (standardmäßig fest`fullscreen`).\n    *   **transitionstyle**: Legen Sie auf `fliphorizontal` , `crossdissolve` oder `coververtical` [Übergangsstil][2] (standardmäßig fest`coververtical`).\n    *   **toolbarposition**: Legen Sie auf `top` oder `bottom` (Standard ist `bottom` ). Bewirkt, dass die Symbolleiste am oberen oder unteren Rand des Fensters sein.\n    \n    Nur Windows:\n    \n    *   **hidden**: Legen Sie auf `yes` um den Browser zu erstellen und laden Sie die Seite, aber nicht zeigen. Das Loadstop-Ereignis wird ausgelöst, wenn der Ladevorgang abgeschlossen ist. Weglassen oder auf `no` (Standard), den Browser öffnen und laden normalerweise zu haben.\n\n [1]: http://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalPresentationStyle\n [2]: http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalTransitionStyle\n\n### Unterstützte Plattformen\n\n*   Amazon Fire OS\n*   Android\n*   BlackBerry 10\n*   Firefox OS\n*   iOS\n*   Windows 8 und 8.1\n*   Windows Phone 7 und 8\n\n### Beispiel\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    var ref2 = cordova.InAppBrowser.open(encodeURI('http://ja.m.wikipedia.org/wiki/ハングル'), '_blank', 'location=yes');\n    \n\n### Firefox OS Macken\n\nAls Plugin jedes Design erzwingen nicht besteht die Notwendigkeit, einige CSS-Regeln hinzuzufügen, wenn bei `target='_blank'`. Die Regeln könnte wie diese aussehen.\n\n     css\n    .inAppBrowserWrap {\n      background-color: rgba(0,0,0,0.75);\n      color: rgba(235,235,235,1.0);\n    }\n    .inAppBrowserWrap menu {\n      overflow: auto;\n      list-style-type: none;\n      padding-left: 0;\n    }\n    .inAppBrowserWrap menu li {\n      font-size: 25px;\n      height: 25px;\n      float: left;\n      margin: 0 10px;\n      padding: 3px 10px;\n      text-decoration: none;\n      color: #ccc;\n      display: block;\n      background: rgba(30,30,30,0.50);\n    }\n    .inAppBrowserWrap menu li.disabled {\n        color: #777;\n    }\n    \n\n## InAppBrowser\n\nBei einem Aufruf von `cordova.InAppBrowser.open` zurückgegebene Objekt..\n\n### Methoden\n\n*   addEventListener\n*   removeEventListener\n*   Schließen\n*   Karte\n*   executeScript\n*   insertCSS\n\n## addEventListener\n\n> Fügt einen Listener für eine Veranstaltung aus der`InAppBrowser`.\n\n    ref.addEventListener(eventname, callback);\n    \n\n*   **Ref**: Bezugnahme auf die `InAppBrowser` Fenster *(InAppBrowser)*\n\n*   **EventName**: das Ereignis zu warten *(String)*\n    \n    *   **Loadstart**: Ereignis wird ausgelöst, wenn die `InAppBrowser` beginnt, eine URL zu laden.\n    *   **Loadstop**: Ereignis wird ausgelöst, wenn der `InAppBrowser` beendet ist, eine URL laden.\n    *   **LoadError**: Ereignis wird ausgelöst, wenn der `InAppBrowser` ein Fehler auftritt, wenn Sie eine URL zu laden.\n    *   **Ausfahrt**: Ereignis wird ausgelöst, wenn das `InAppBrowser` -Fenster wird geschlossen.\n\n*   **Rückruf**: die Funktion, die ausgeführt wird, wenn das Ereignis ausgelöst wird. Die Funktion übergeben wird ein `InAppBrowserEvent` -Objekt als Parameter.\n\n### InAppBrowserEvent Eigenschaften\n\n*   **Typ**: Eventname, entweder `loadstart` , `loadstop` , `loaderror` , oder `exit` . *(String)*\n\n*   **URL**: die URL, die geladen wurde. *(String)*\n\n*   **Code**: der Fehler-Code, nur im Fall von `loaderror` . *(Anzahl)*\n\n*   **Nachricht**: die Fehlermeldung angezeigt, nur im Fall von `loaderror` . *(String)*\n\n### Unterstützte Plattformen\n\n*   Amazon Fire OS\n*   Android\n*   iOS\n*   Windows 8 und 8.1\n*   Windows Phone 7 und 8\n\n### Kurzes Beispiel\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstart', function(event) { alert(event.url); });\n    \n\n## removeEventListener\n\n> Entfernt einen Listener für eine Veranstaltung aus der`InAppBrowser`.\n\n    ref.removeEventListener(eventname, callback);\n    \n\n*   **Ref**: Bezugnahme auf die `InAppBrowser` Fenster. *(InAppBrowser)*\n\n*   **EventName**: das Ereignis zu warten. *(String)*\n    \n    *   **Loadstart**: Ereignis wird ausgelöst, wenn die `InAppBrowser` beginnt, eine URL zu laden.\n    *   **Loadstop**: Ereignis wird ausgelöst, wenn der `InAppBrowser` beendet ist, eine URL laden.\n    *   **LoadError**: Ereignis wird ausgelöst, wenn die `InAppBrowser` trifft einen Fehler beim Laden einer URLs.\n    *   **Ausfahrt**: Ereignis wird ausgelöst, wenn das `InAppBrowser` -Fenster wird geschlossen.\n\n*   **Rückruf**: die Funktion ausgeführt, wenn das Ereignis ausgelöst wird. Die Funktion übergeben wird ein `InAppBrowserEvent` Objekt.\n\n### Unterstützte Plattformen\n\n*   Amazon Fire OS\n*   Android\n*   iOS\n*   Windows 8 und 8.1\n*   Windows Phone 7 und 8\n\n### Kurzes Beispiel\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    var myCallback = function(event) { alert(event.url); }\n    ref.addEventListener('loadstart', myCallback);\n    ref.removeEventListener('loadstart', myCallback);\n    \n\n## Schließen\n\n> Schließt die `InAppBrowser` Fenster.\n\n    ref.close();\n    \n\n*   **Ref**: Bezugnahme auf die `InAppBrowser` Fenster *(InAppBrowser)*\n\n### Unterstützte Plattformen\n\n*   Amazon Fire OS\n*   Android\n*   Firefox OS\n*   iOS\n*   Windows 8 und 8.1\n*   Windows Phone 7 und 8\n\n### Kurzes Beispiel\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.close();\n    \n\n## Karte\n\n> Zeigt ein InAppBrowser-Fenster, das geöffnet wurde, versteckt. Aufrufen, dies hat keine Auswirkungen, wenn die InAppBrowser schon sichtbar war.\n\n    ref.show();\n    \n\n*   **Ref**: Verweis auf die (InAppBrowser) Fenster`InAppBrowser`)\n\n### Unterstützte Plattformen\n\n*   Amazon Fire OS\n*   Android\n*   iOS\n*   Windows 8 und 8.1\n\n### Kurzes Beispiel\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'hidden=yes');\n    // some time later...\n    ref.show();\n    \n\n## executeScript\n\n> Fügt JavaScript-Code in das `InAppBrowser` Fenster\n\n    ref.executeScript(details, callback);\n    \n\n*   **Ref**: Bezugnahme auf die `InAppBrowser` Fenster. *(InAppBrowser)*\n\n*   **InjectDetails**: Informationen über das Skript ausgeführt, angeben, entweder ein `file` oder `code` Schlüssel. *(Objekt)*\n    \n    *   **Datei**: URL des Skripts zu injizieren.\n    *   **Code**: Text des Skripts zu injizieren.\n\n*   **Rückruf**: die Funktion, die ausgeführt wird, nachdem der JavaScript-Code injiziert wird.\n    \n    *   Wenn das eingefügte Skript vom Typ ist `code` , der Rückruf führt mit einen einzelnen Parameter, der der Rückgabewert des Skripts ist, umwickelt ein `Array` . Bei Multi-Line-Skripten ist der Rückgabewert von der letzten Anweisung oder den letzten Ausdruck ausgewertet.\n\n### Unterstützte Plattformen\n\n*   Amazon Fire OS\n*   Android\n*   iOS\n*   Windows 8 und 8.1\n\n### Kurzes Beispiel\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstop', function() {\n        ref.executeScript({file: \"myscript.js\"});\n    });\n    \n\n## insertCSS\n\n> Injiziert CSS in der `InAppBrowser` Fenster.\n\n    ref.insertCSS(details, callback);\n    \n\n*   **Ref**: Bezugnahme auf die `InAppBrowser` Fenster *(InAppBrowser)*\n\n*   **InjectDetails**: Informationen über das Skript ausgeführt, angeben, entweder ein `file` oder `code` Schlüssel. *(Objekt)*\n    \n    *   **Datei**: URL des Stylesheets zu injizieren.\n    *   **Code**: Text des Stylesheets zu injizieren.\n\n*   **Rückruf**: die Funktion, die ausgeführt wird, nachdem die CSS injiziert wird.\n\n### Unterstützte Plattformen\n\n*   Amazon Fire OS\n*   Android\n*   iOS\n\n### Kurzes Beispiel\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstop', function() {\n        ref.insertCSS({file: \"mystyles.css\"});\n    });\n"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/doc/es/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-inappbrowser\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-inappbrowser.svg)](https://travis-ci.org/apache/cordova-plugin-inappbrowser)\n\nEste plugin proporciona una vista de navegador web que se muestra cuando se llama a `cordova.InAppBrowser.open()`.\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    \n\nEl `cordova.InAppBrowser.open()` función se define como un reemplazo de sobreponer para la función `window.Open ()`. Llamadas existentes `window.Open ()` pueden utilizar la ventana InAppBrowser, mediante la sustitución de window.open:\n\n    window.open = cordova.InAppBrowser.open;\n    \n\nLa ventana de InAppBrowser se comporta como un navegador web estándar y no puede acceder a Cordova APIs. Por este motivo, se recomienda la InAppBrowser si necesita cargar contenido de terceros (confianza), en lugar de que cargar en el principal webview Cordova. El InAppBrowser no está sujeta a la lista blanca, ni va a abrir enlaces en el navegador del sistema.\n\nEl InAppBrowser proporciona por defecto sus propios controles GUI para el usuario (atras, adelante, hacer).\n\nPara atrás compatibilidad, este plugin también ganchos `window.open`. Sin embargo, el gancho de `window.open` plugin instalado puede tener efectos secundarios no deseados (especialmente si este plugin está incluido únicamente como una dependencia de otro plugin). El gancho de `window.open` se quitará en una versión futura de principal. Hasta que el gancho se ha extraído el plugin, aplicaciones pueden restaurar manualmente el comportamiento por defecto:\n\n    delete window.open // Reverts the call back to it's prototype's default\n    \n\nAunque `window.open` es en el ámbito global, InAppBrowser no está disponible hasta después del evento `deviceready`.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(\"window.open works well\");\n    }\n    \n\n## Instalación\n\n    cordova plugin add cordova-plugin-inappbrowser\n    \n\nSi quieres todas las cargas de página en su aplicación para ir a través de la InAppBrowser, simplemente puedes conectar `window.open` durante la inicialización. Por ejemplo:\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        window.open = cordova.InAppBrowser.open;\n    }\n    \n\n## cordova.InAppBrowser.open\n\nSe abre una dirección URL en una nueva instancia de `InAppBrowser`, en la instancia actual del navegador o el navegador del sistema.\n\n    var ref = cordova.InAppBrowser.open(url, target, options);\n    \n\n  * **ref**: referencia a la `InAppBrowser` ventana. *(InAppBrowser)*\n\n  * **url**: el URL para cargar *(String)*. Llame a `encodeURI()` en esto si la URL contiene caracteres Unicode.\n\n  * **target**: el objetivo en el que se carga la URL, un parámetro opcional que se utiliza de forma predeterminada `_self`. *(String)*\n    \n      * `_self`: se abre en el Cordova WebView si la URL está en la lista blanca, de lo contrario se abre en el `InAppBrowser`.\n      * `_blank`: abre en el `InAppBrowser`.\n      * `_system`: se abre en el navegador del sistema.\n\n  * **options**: opciones para el `InAppBrowser`. Opcional, contumaz a: `location=yes`. *(String)*\n    \n    La cadena de `options` no debe contener ningún espacio en blanco, y los pares de nombre y valor de cada característica deben estar separados por una coma. Los nombres de función son minúsculas. Todas las plataformas admiten el valor siguiente:\n    \n      * **location**: se establece en `yes` o `no` para activar o desactivar la barra de ubicación de la `InAppBrowser`.\n    \n    Sólo Android:\n    \n      * **oculta**: a `yes` para crear el navegador y cargar la página, pero no lo demuestra. El evento loadstop se desencadena cuando termine la carga. Omitir o a `no` (por defecto) para que el navegador abra y carga normalmente.\n      * **clearcache**: a `yes` para que el navegador es caché de galleta despejado antes de que se abra la nueva ventana\n      * **clearsessioncache**: a `yes` que la caché de cookie de sesión despejado antes de que se abra la nueva ventana\n      * **zoom**: establezca en `sí` para mostrar los controles de zoom del navegador de Android, a `no` para ocultarlas. El valor predeterminado es `sí`.\n      * **hardwareback**: se establece en `sí` para utilizar el botón back de hardware para navegar hacia atrás a través de la historia de la `InAppBrowser`. Si no hay ninguna página anterior, se cerrará el `InAppBrowser` . El valor predeterminado es `sí`, por lo que se debe establecer en `no` si desea que el botón back para simplemente cerrar el InAppBrowser.\n    \n    Sólo iOS:\n    \n      * **closebuttoncaption**: establecer una cadena para usar como título del botón **hecho** . Tenga en cuenta que necesitas localizar este valor por sí mismo.\n      * **disallowoverscroll**: A `yes` o `no` (valor por defecto es `no` ). Activa/desactiva la propiedad UIWebViewBounce.\n      * **oculta**: a `yes` para crear el navegador y cargar la página, pero no lo demuestra. El evento loadstop se desencadena cuando termine la carga. Omitir o a `no` (por defecto) para que el navegador abra y carga normalmente.\n      * **clearcache**: a `yes` para que el navegador es caché de galleta despejado antes de que se abra la nueva ventana\n      * **clearsessioncache**: a `yes` que la caché de cookie de sesión despejado antes de que se abra la nueva ventana\n      * **barra de herramientas**: a `yes` o `no` para activar la barra de herramientas on u off para el InAppBrowser (por defecto`yes`)\n      * **enableViewportScale**: Set a `yes` o `no` para evitar viewport escalar a través de una etiqueta meta (por defecto a `no`).\n      * **mediaPlaybackRequiresUserAction**: Set a `yes` o `no` para evitar HTML5 audio o vídeo de reproducción automática (por defecto a `no`).\n      * **allowInlineMediaPlayback**: A `yes` o `no` para permitir la reproducción de los medios de comunicación en línea HTML5, mostrando en la ventana del navegador en lugar de una interfaz específica del dispositivo de reproducción. Elemento `video` de HTML también debe incluir el atributo de `webkit-playsinline` (por defecto a `no`)\n      * **keyboardDisplayRequiresUserAction**: se establece en `yes` o `no` para abrir el teclado cuando elementos de formulario reciben el foco mediante llamada de JavaScript de `focus()` (por defecto a `yes`).\n      * **suppressesIncrementalRendering**: se establece en `yes` o `no` para esperar hasta que todos los nuevos contenidos de vista se recibieron antes de ser prestados (por defecto a `no`).\n      * **presentationstyle**: se establece en `pagesheet`, `formsheet` o `fullscreen` para definir el [estilo de la presentación](http://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalPresentationStyle) (por defecto a `fullscreen`).\n      * **transitionstyle**: se establece en `fliphorizontal`, `crossdissolve` o `coververtical` para definir el [estilo de transición](http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalTransitionStyle) (por defecto `coververtical`).\n      * **toolbarposition**: A `top` o `bottom` (valor por defecto es `bottom` ). Hace que la barra de herramientas en la parte superior o inferior de la ventana.\n    \n    Sólo Windows:\n    \n      * **oculta**: a `yes` para crear el navegador y cargar la página, pero no lo demuestra. El evento loadstop se desencadena cuando termine la carga. Omitir o a `no` (por defecto) para que el navegador abra y carga normalmente.\n      * **fullscreen**: se establece en `sí` para crear el control del navegador sin un borde alrededor de él. Por favor tenga en cuenta que si **location=no** también se especifica, no habrá ningún control presentado al usuario para cerrar la ventana IAB.\n\n### Plataformas soportadas\n\n  * Amazon fire OS\n  * Android\n  * BlackBerry 10\n  * Firefox OS\n  * iOS\n  * Windows 8 y 8.1\n  * Windows Phone 7 y 8\n  * Explorador\n\n### Ejemplo\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    var ref2 = cordova.InAppBrowser.open(encodeURI('http://ja.m.wikipedia.org/wiki/ハングル'), '_blank', 'location=yes');\n    \n\n### Firefox OS rarezas\n\nComo plugin no cumplir cualquier diseño es necesario añadir algunas reglas CSS si abre con `target = '_blank'`. Las reglas pueden parecerse a estos\n\n```css\n.inAppBrowserWrap {\n  background-color: rgba(0,0,0,0.75);\n  color: rgba(235,235,235,1.0);\n}\n.inAppBrowserWrap menu {\n  overflow: auto;\n  list-style-type: none;\n  padding-left: 0;\n}\n.inAppBrowserWrap menu li {\n  font-size: 25px;\n  height: 25px;\n  float: left;\n  margin: 0 10px;\n  padding: 3px 10px;\n  text-decoration: none;\n  color: #ccc;\n  display: block;\n  background: rgba(30,30,30,0.50);\n}\n.inAppBrowserWrap menu li.disabled {\n    color: #777;\n}\n```\n\n### Windows rarezas\n\nSimilar al comportamiento visual de la ventana de Firefox OS IAB puede anularse mediante `inAppBrowserWrap`/`inAppBrowserWrapFullscreen` clases CSS\n\n### Navegador rarezas\n\n  * Plugin se implementa mediante iframe,\n\n  * Historial de navegación (botones`atrás` y `adelante` en LocationBar) no está implementado.\n\n## InAppBrowser\n\nEl objeto devuelto desde una llamada a `cordova.InAppBrowser.open`.\n\n### Métodos\n\n  * addEventListener\n  * removeEventListener\n  * close\n  * show\n  * executeScript\n  * insertCSS\n\n## addEventListener\n\n> Añade un detector para un evento de la `InAppBrowser`.\n\n    ref.addEventListener(eventname, callback);\n    \n\n  * **ref**: referencia a la ventana de `InAppBrowser` *(InAppBrowser)*\n\n  * **eventName**: el evento para escuchar *(String)*\n    \n      * **loadstart**: evento se desencadena cuando el `InAppBrowser` comienza a cargar una dirección URL.\n      * **loadstop**: evento desencadena cuando los acabados `InAppBrowser` cargar una dirección URL.\n      * **loaderror**: evento se desencadena cuando el `InAppBrowser` encuentra un error al cargar una dirección URL.\n      * **exit**: evento se desencadena cuando se cierra la ventana de `InAppBrowser`.\n\n  * **callback**: la función que se ejecuta cuando se desencadene el evento. La función se pasa un objeto `InAppBrowserEvent` como un parámetro.\n\n### InAppBrowserEvent propiedades\n\n  * **type**: eventname, `loadstart`, `loadstop`, `loaderror` o `exit`. *(String)*\n\n  * **url**: la URL que se cargó. *(String)*\n\n  * **code**: el código de error, sólo en el caso de `loaderror`. *(Número)*\n\n  * **message**: el mensaje de error, sólo en el caso de `loaderror`. *(String)*\n\n### Plataformas soportadas\n\n  * Amazon fire OS\n  * Android\n  * iOS\n  * Windows 8 y 8.1\n  * Windows Phone 7 y 8\n  * Explorador\n\n### Navegador rarezas\n\neventos `loadstart` y `loaderror` no son alimentados.\n\n### Ejemplo rápido\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstart', function(event) { alert(event.url); });\n    \n\n## removeEventListener\n\n> Elimina un detector para un evento de la `InAppBrowser`.\n\n    ref.removeEventListener(eventname, callback);\n    \n\n  * **ref**: referencia a la ventana de `InAppBrowser`. *(InAppBrowser)*\n\n  * **eventName**: dejar de escuchar para el evento. *(String)*\n    \n      * **loadstart**: evento se desencadena cuando el `InAppBrowser` comienza a cargar una dirección URL.\n      * **loadstop**: evento desencadena cuando los acabados `InAppBrowser` cargar una dirección URL.\n      * **loaderror**: evento se desencadena cuando el `InAppBrowser` se encuentra con un error al cargar una dirección URL.\n      * **exit**: evento se desencadena cuando se cierra la ventana de `InAppBrowser`.\n\n  * **callback**: la función a ejecutar cuando se desencadene el evento. La función se pasa un objeto `InAppBrowserEvent`.\n\n### Plataformas soportadas\n\n  * Amazon fire OS\n  * Android\n  * iOS\n  * Windows 8 y 8.1\n  * Windows Phone 7 y 8\n  * Explorador\n\n### Ejemplo rápido\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    var myCallback = function(event) { alert(event.url); }\n    ref.addEventListener('loadstart', myCallback);\n    ref.removeEventListener('loadstart', myCallback);\n    \n\n## close\n\n> Cierra la ventana de `InAppBrowser`.\n\n    ref.close();\n    \n\n  * **ref**: referencia a la ventana de `InAppBrowser` *(InAppBrowser)*\n\n### Plataformas soportadas\n\n  * Amazon fire OS\n  * Android\n  * Firefox OS\n  * iOS\n  * Windows 8 y 8.1\n  * Windows Phone 7 y 8\n  * Explorador\n\n### Ejemplo rápido\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.close();\n    \n\n## show\n\n> Muestra una ventana InAppBrowser que abrió sus puertas ocultada. Esto no tiene efecto si el InAppBrowser ya era visible.\n\n    ref.show();\n    \n\n  * **ref**: referencia a la (ventana) InAppBrowser`InAppBrowser`)\n\n### Plataformas soportadas\n\n  * Amazon fire OS\n  * Android\n  * iOS\n  * Windows 8 y 8.1\n  * Explorador\n\n### Ejemplo rápido\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'hidden=yes');\n    // some time later...\n    ref.show();\n    \n\n## executeScript\n\n> Inyecta código JavaScript en la ventana de `InAppBrowser`\n\n    ref.executeScript(details, callback);\n    \n\n  * **ref**: referencia a la ventana de `InAppBrowser`. *(InAppBrowser)*\n\n  * **injectDetails**: detalles de la secuencia de comandos para ejecutar, o especificar un `file` o `code` clave. *(Objeto)*\n    \n      * **file**: URL del script para inyectar.\n      * **code**: texto de la escritura para inyectar.\n\n  * **devolución de llamada**: la función que se ejecuta después de inyecta el código JavaScript.\n    \n      * Si el script inyectado es del tipo de `code`, la devolución de llamada se ejecuta con un solo parámetro, que es el valor devuelto del guión, envuelto en una `Array`. Para scripts multilíneas, este es el valor devuelto de la última declaración, o la última expresión evaluada.\n\n### Plataformas soportadas\n\n  * Amazon fire OS\n  * Android\n  * iOS\n  * Windows 8 y 8.1\n  * Explorador\n\n### Ejemplo rápido\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstop', function() {\n        ref.executeScript({file: \"myscript.js\"});\n    });\n    \n\n### Navegador rarezas\n\n  * sólo **code** es compatible.\n\n### Windows rarezas\n\nDebido a la [documentación MSDN](https://msdn.microsoft.com/en-us/library/windows.ui.xaml.controls.webview.invokescriptasync.aspx) el script invocado puede devolver únicamente valores de cadena, de lo contrario el parámetro, pasa al **callback** será `[null]`.\n\n## insertCSS\n\n> Inyecta CSS en la ventana de `InAppBrowser`.\n\n    ref.insertCSS(details, callback);\n    \n\n  * **ref**: referencia a la ventana de `InAppBrowser` *(InAppBrowser)*\n\n  * **injectDetails**: detalles de la secuencia de comandos para ejecutar, o especificar un `file` o `code` clave. *(Objeto)*\n    \n      * **file**: URL de la hoja de estilos para inyectar.\n      * **code**: texto de la hoja de estilos para inyectar.\n\n  * **callback**: la función que se ejecuta después de inyectar el CSS.\n\n### Plataformas soportadas\n\n  * Amazon fire OS\n  * Android\n  * iOS\n  * Windows\n\n### Ejemplo rápido\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstop', function() {\n        ref.insertCSS({file: \"mystyles.css\"});\n    });"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/doc/es/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-inappbrowser\n\nEste plugin proporciona una vista de navegador web que se muestra cuando se llama a `cordova.InAppBrowser.open()`.\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    \n\nEl `cordova.InAppBrowser.open()` función se define como un reemplazo de sobreponer para la función `window.Open ()`. Llamadas existentes `window.Open ()` pueden utilizar la ventana InAppBrowser, mediante la sustitución de window.open:\n\n    window.open = cordova.InAppBrowser.open;\n    \n\nLa ventana de InAppBrowser se comporta como un navegador web estándar y no puede acceder a Cordova APIs. Por este motivo, se recomienda la InAppBrowser si necesita cargar contenido de terceros (confianza), en lugar de que cargar en el principal webview Cordova. El InAppBrowser no está sujeta a la lista blanca, ni va a abrir enlaces en el navegador del sistema.\n\nEl InAppBrowser proporciona por defecto sus propios controles GUI para el usuario (atras, adelante, hacer).\n\nPara atrás compatibilidad, este plugin también ganchos `window.open`. Sin embargo, el gancho de `window.open` plugin instalado puede tener efectos secundarios no deseados (especialmente si este plugin está incluido únicamente como una dependencia de otro plugin). El gancho de `window.open` se quitará en una versión futura de principal. Hasta que el gancho se ha extraído el plugin, aplicaciones pueden restaurar manualmente el comportamiento por defecto:\n\n    delete window.open // Reverts the call back to it's prototype's default\n    \n\nAunque `window.open` es en el ámbito global, InAppBrowser no está disponible hasta después del evento `deviceready`.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(\"window.open works well\");\n    }\n    \n\n## Instalación\n\n    cordova plugin add cordova-plugin-inappbrowser\n    \n\nSi quieres todas las cargas de página en su aplicación para ir a través de la InAppBrowser, simplemente puedes conectar `window.open` durante la inicialización. Por ejemplo:\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        window.open = cordova.InAppBrowser.open;\n    }\n    \n\n## cordova.InAppBrowser.open\n\nSe abre una dirección URL en una nueva instancia de `InAppBrowser`, en la instancia actual del navegador o el navegador del sistema.\n\n    var ref = cordova.InAppBrowser.open(url, target, options);\n    \n\n*   **ref**: referencia a la `InAppBrowser` ventana. *(InAppBrowser)*\n\n*   **url**: el URL para cargar *(String)*. Llame a `encodeURI()` en esto si la URL contiene caracteres Unicode.\n\n*   **target**: el objetivo en el que se carga la URL, un parámetro opcional que se utiliza de forma predeterminada `_self`. *(String)*\n    \n    *   `_self`: se abre en el Cordova WebView si la URL está en la lista blanca, de lo contrario se abre en el `InAppBrowser`.\n    *   `_blank`: abre en el `InAppBrowser`.\n    *   `_system`: se abre en el navegador del sistema.\n\n*   **options**: opciones para el `InAppBrowser`. Opcional, contumaz a: `location=yes`. *(String)*\n    \n    La cadena de `options` no debe contener ningún espacio en blanco, y los pares de nombre y valor de cada característica deben estar separados por una coma. Los nombres de función son minúsculas. Todas las plataformas admiten el valor siguiente:\n    \n    *   **location**: se establece en `yes` o `no` para activar o desactivar la barra de ubicación de la `InAppBrowser`.\n    \n    Sólo Android:\n    \n    *   **oculta**: a `yes` para crear el navegador y cargar la página, pero no lo demuestra. El evento loadstop se desencadena cuando termine la carga. Omitir o establecer en `no` (por defecto) para que el navegador abra y carga normalmente.\n    *   **clearcache**: a `yes` para que el navegador es caché de galleta despejado antes de que se abra la nueva ventana\n    *   **clearsessioncache**: a `yes` que la caché de cookie de sesión despejado antes de que se abra la nueva ventana\n    \n    Sólo iOS:\n    \n    *   **closebuttoncaption**: establecer una cadena para usar como título del botón **hecho** . Tenga en cuenta que necesitas localizar este valor por sí mismo.\n    *   **disallowoverscroll**: A `yes` o `no` (valor por defecto es `no` ). Activa/desactiva la propiedad UIWebViewBounce.\n    *   **oculta**: a `yes` para crear el navegador y cargar la página, pero no lo demuestra. El evento loadstop se desencadena cuando termine la carga. Omitir o a `no` (por defecto) para que el navegador abra y carga normalmente.\n    *   **clearcache**: a `yes` para que el navegador es caché de galleta despejado antes de que se abra la nueva ventana\n    *   **clearsessioncache**: a `yes` que la caché de cookie de sesión despejado antes de que se abra la nueva ventana\n    *   **barra de herramientas**: a `yes` o `no` para activar la barra de herramientas on u off para el InAppBrowser (por defecto`yes`)\n    *   **enableViewportScale**: Set a `yes` o `no` para evitar viewport escalar a través de una etiqueta meta (por defecto a `no`).\n    *   **mediaPlaybackRequiresUserAction**: Set a `yes` o `no` para evitar HTML5 audio o vídeo de reproducción automática (por defecto a `no`).\n    *   **allowInlineMediaPlayback**: A `yes` o `no` para permitir la reproducción de los medios de comunicación en línea HTML5, mostrando en la ventana del navegador en lugar de una interfaz específica del dispositivo de reproducción. Elemento `video` de HTML también debe incluir el atributo de `webkit-playsinline` (por defecto a `no`)\n    *   **keyboardDisplayRequiresUserAction**: se establece en `yes` o `no` para abrir el teclado cuando elementos de formulario reciben el foco mediante llamada de JavaScript de `focus()` (por defecto a `yes`).\n    *   **suppressesIncrementalRendering**: se establece en `yes` o `no` para esperar hasta que todos los nuevos contenidos de vista se recibieron antes de ser prestados (por defecto a `no`).\n    *   **presentationstyle**: se establece en `pagesheet`, `formsheet` o `fullscreen` para definir el [estilo de la presentación][1] (por defecto a `fullscreen`).\n    *   **transitionstyle**: se establece en `fliphorizontal`, `crossdissolve` o `coververtical` para definir el [estilo de transición][2] (por defecto `coververtical`).\n    *   **toolbarposition**: A `top` o `bottom` (valor por defecto es `bottom` ). Hace que la barra de herramientas en la parte superior o inferior de la ventana.\n    \n    Sólo Windows:\n    \n    *   **oculta**: a `yes` para crear el navegador y cargar la página, pero no lo demuestra. El evento loadstop se desencadena cuando termine la carga. Omitir o a `no` (por defecto) para que el navegador abra y carga normalmente.\n\n [1]: http://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalPresentationStyle\n [2]: http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalTransitionStyle\n\n### Plataformas soportadas\n\n*   Amazon fire OS\n*   Android\n*   BlackBerry 10\n*   Firefox OS\n*   iOS\n*   Windows 8 y 8.1\n*   Windows Phone 7 y 8\n\n### Ejemplo\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    var ref2 = cordova.InAppBrowser.open(encodeURI('http://ja.m.wikipedia.org/wiki/ハングル'), '_blank', 'location=yes');\n    \n\n### Firefox OS rarezas\n\nComo plugin no cumplir cualquier diseño es necesario añadir algunas reglas CSS si abre con `target = '_blank'`. Las reglas pueden parecerse a estos\n\n     css\n    .inAppBrowserWrap {\n      background-color: rgba(0,0,0,0.75);\n      color: rgba(235,235,235,1.0);\n    }\n    .inAppBrowserWrap menu {\n      overflow: auto;\n      list-style-type: none;\n      padding-left: 0;\n    }\n    .inAppBrowserWrap menu li {\n      font-size: 25px;\n      height: 25px;\n      float: left;\n      margin: 0 10px;\n      padding: 3px 10px;\n      text-decoration: none;\n      color: #ccc;\n      display: block;\n      background: rgba(30,30,30,0.50);\n    }\n    .inAppBrowserWrap menu li.disabled {\n        color: #777;\n    }\n    \n\n## InAppBrowser\n\nEl objeto devuelto desde una llamada a `cordova.InAppBrowser.open`.\n\n### Métodos\n\n*   addEventListener\n*   removeEventListener\n*   close\n*   show\n*   executeScript\n*   insertCSS\n\n## addEventListener\n\n> Añade un detector para un evento de la `InAppBrowser`.\n\n    ref.addEventListener(eventname, callback);\n    \n\n*   **ref**: referencia a la ventana de `InAppBrowser` *(InAppBrowser)*\n\n*   **eventName**: el evento para escuchar *(String)*\n    \n    *   **loadstart**: evento se desencadena cuando el `InAppBrowser` comienza a cargar una dirección URL.\n    *   **loadstop**: evento desencadena cuando los acabados `InAppBrowser` cargar una dirección URL.\n    *   **loaderror**: evento se desencadena cuando el `InAppBrowser` encuentra un error al cargar una dirección URL.\n    *   **exit**: evento se desencadena cuando se cierra la ventana de `InAppBrowser`.\n\n*   **callback**: la función que se ejecuta cuando se desencadene el evento. La función se pasa un objeto `InAppBrowserEvent` como un parámetro.\n\n### InAppBrowserEvent propiedades\n\n*   **type**: eventname, `loadstart`, `loadstop`, `loaderror` o `exit`. *(String)*\n\n*   **url**: la URL que se cargó. *(String)*\n\n*   **code**: el código de error, sólo en el caso de `loaderror`. *(Número)*\n\n*   **message**: el mensaje de error, sólo en el caso de `loaderror`. *(String)*\n\n### Plataformas soportadas\n\n*   Amazon fire OS\n*   Android\n*   iOS\n*   Windows 8 y 8.1\n*   Windows Phone 7 y 8\n\n### Ejemplo rápido\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstart', function(event) { alert(event.url); });\n    \n\n## removeEventListener\n\n> Elimina un detector para un evento de la `InAppBrowser`.\n\n    ref.removeEventListener(eventname, callback);\n    \n\n*   **ref**: referencia a la ventana de `InAppBrowser`. *(InAppBrowser)*\n\n*   **eventName**: dejar de escuchar para el evento. *(String)*\n    \n    *   **loadstart**: evento se desencadena cuando el `InAppBrowser` comienza a cargar una dirección URL.\n    *   **loadstop**: evento desencadena cuando los acabados `InAppBrowser` cargar una dirección URL.\n    *   **loaderror**: evento se desencadena cuando el `InAppBrowser` se encuentra con un error al cargar una dirección URL.\n    *   **exit**: evento se desencadena cuando se cierra la ventana de `InAppBrowser`.\n\n*   **callback**: la función a ejecutar cuando se desencadene el evento. La función se pasa un objeto `InAppBrowserEvent`.\n\n### Plataformas soportadas\n\n*   Amazon fire OS\n*   Android\n*   iOS\n*   Windows 8 y 8.1\n*   Windows Phone 7 y 8\n\n### Ejemplo rápido\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    var myCallback = function(event) { alert(event.url); }\n    ref.addEventListener('loadstart', myCallback);\n    ref.removeEventListener('loadstart', myCallback);\n    \n\n## close\n\n> Cierra la ventana de `InAppBrowser`.\n\n    ref.close();\n    \n\n*   **ref**: referencia a la ventana de `InAppBrowser` *(InAppBrowser)*\n\n### Plataformas soportadas\n\n*   Amazon fire OS\n*   Android\n*   Firefox OS\n*   iOS\n*   Windows 8 y 8.1\n*   Windows Phone 7 y 8\n\n### Ejemplo rápido\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.close();\n    \n\n## show\n\n> Muestra una ventana InAppBrowser que abrió sus puertas ocultada. Esto no tiene efecto si el InAppBrowser ya era visible.\n\n    ref.show();\n    \n\n*   **ref**: referencia a la (ventana) InAppBrowser`InAppBrowser`)\n\n### Plataformas soportadas\n\n*   Amazon fire OS\n*   Android\n*   iOS\n*   Windows 8 y 8.1\n\n### Ejemplo rápido\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'hidden=yes');\n    // some time later...\n    ref.show();\n    \n\n## executeScript\n\n> Inyecta código JavaScript en la ventana de `InAppBrowser`\n\n    ref.executeScript(details, callback);\n    \n\n*   **ref**: referencia a la ventana de `InAppBrowser`. *(InAppBrowser)*\n\n*   **injectDetails**: detalles de la secuencia de comandos para ejecutar, o especificar un `file` o `code` clave. *(Objeto)*\n    \n    *   **file**: URL del script para inyectar.\n    *   **code**: texto de la escritura para inyectar.\n\n*   **devolución de llamada**: la función que se ejecuta después de inyecta el código JavaScript.\n    \n    *   Si el script inyectado es del tipo de `code`, la devolución de llamada se ejecuta con un solo parámetro, que es el valor devuelto del guión, envuelto en una `Array`. Para scripts multilíneas, este es el valor devuelto de la última declaración, o la última expresión evaluada.\n\n### Plataformas soportadas\n\n*   Amazon fire OS\n*   Android\n*   iOS\n*   Windows 8 y 8.1\n\n### Ejemplo rápido\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstop', function() {\n        ref.executeScript({file: \"myscript.js\"});\n    });\n    \n\n## insertCSS\n\n> Inyecta CSS en la ventana de `InAppBrowser`.\n\n    ref.insertCSS(details, callback);\n    \n\n*   **ref**: referencia a la ventana de `InAppBrowser` *(InAppBrowser)*\n\n*   **injectDetails**: detalles de la secuencia de comandos para ejecutar, o especificar un `file` o `code` clave. *(Objeto)*\n    \n    *   **file**: URL de la hoja de estilos para inyectar.\n    *   **code**: texto de la hoja de estilos para inyectar.\n\n*   **callback**: la función que se ejecuta después de inyectar el CSS.\n\n### Plataformas soportadas\n\n*   Amazon fire OS\n*   Android\n*   iOS\n\n### Ejemplo rápido\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstop', function() {\n        ref.insertCSS({file: \"mystyles.css\"});\n    });\n"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/doc/fr/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-inappbrowser\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-inappbrowser.svg)](https://travis-ci.org/apache/cordova-plugin-inappbrowser)\n\nCe module fournit une vue de navigateur web qui s'affiche lorsque vous appelez `cordova.InAppBrowser.open()`.\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    \n\nLe `cordova.InAppBrowser.open()` fonction est définie pour être un remplacement rapide de la fonction `window.open()`. Les appels existants `window.open()` peuvent utiliser la fenêtre de InAppBrowser, en remplaçant window.open :\n\n    window.open = cordova.InAppBrowser.open;\n    \n\nLa fenêtre de InAppBrowser se comporte comme un navigateur web standard et ne peut pas accéder aux APIs Cordova. Pour cette raison, le InAppBrowser est recommandé si vous devez charger le contenu de tiers (non approuvé), au lieu de chargement que dans le principaux webview Cordova. Le InAppBrowser n'est pas soumis à la liste blanche, ni s'ouvre les liens dans le navigateur de système.\n\nLe InAppBrowser fournit par défaut ses propres contrôles de GUI pour l'utilisateur (arrière, avant, fait).\n\nPour vers l'arrière la compatibilité, ce plugin crochets également `window.open`. Cependant, le plugin installé crochet de `window.open` peut avoir des effets secondaires involontaires (surtout si ce plugin est inclus uniquement comme une dépendance d'un autre plugin). Le crochet de `window.open` sera supprimé dans une future version majeure. Jusqu'à ce que le crochet est supprimé de la plugin, apps peuvent restaurer manuellement le comportement par défaut :\n\n    delete window.open // Reverts the call back to it's prototype's default\n    \n\nBien que `window.open` est dans la portée globale, InAppBrowser n'est pas disponible jusqu'à ce qu'après l'événement `deviceready`.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(\"window.open works well\");\n    }\n    \n\n## Installation\n\n    cordova plugin add cordova-plugin-inappbrowser\n    \n\nSi vous souhaitez que toutes les charges de la page dans votre application de passer par le InAppBrowser, vous pouvez simplement accrocher `window.open` pendant l'initialisation. Par exemple :\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        window.open = cordova.InAppBrowser.open;\n    }\n    \n\n## cordova.InAppBrowser.open\n\nOuvre une URL dans une nouvelle instance de `InAppBrowser`, l'instance de navigateur actuelle ou dans l'Explorateur du système.\n\n    var ref = cordova.InAppBrowser.open(url, target, options);\n    \n\n  * **ref** : référence à la fenêtre `InAppBrowser`. *(InAppBrowser)*\n\n  * **url** : l'URL à charger *(String)*. À encoder au préalable via `encodeURI()` si celle-ci contient des caractères Unicode.\n\n  * **target** : la cible du chargement de l'URL, ce paramètre est optionnel, sa valeur par défaut est `_self`. *(String)*\n    \n      * `_self` : dirige le chargement vers la WebView Cordova si l'URL figure dans la liste blanche, sinon dans une fenêtre `InAppBrowser`.\n      * `_blank` : dirige le chargement vers une fenêtre `InAppBrowser`.\n      * `_system` : dirige le chargement vers le navigateur Web du système.\n\n  * **options** : permet de personnaliser la fenêtre `InAppBrowser`. Paramètre facultatif dont la valeur par défaut est `location=yes`. *(String)*\n    \n    La chaîne `options` ne doit contenir aucun caractère vide, chaque paire nom/valeur représentant une fonctionnalité doit être séparée de la précédente par une virgule. Les noms de fonctionnalités sont sensibles à la casse. Toutes les plates-formes prennent en charge la valeur ci-dessous :\n    \n      * **location** : régler à `yes` ou `no` afin d'afficher ou masquer la barre d'adresse de la fenêtre `InAppBrowser`.\n    \n    Android uniquement :\n    \n      * **caché**: la valeur `yes` pour créer le navigateur et charger la page, mais ne pas le montrer. L'événement loadstop est déclenché lorsque le chargement est terminé. Omettre ou la valeur `no` (par défaut) pour que le navigateur ouvrir et charger normalement.\n      * **ClearCache**: la valeur `yes` pour que le navigateur du cache de cookie effacé, avant l'ouverture de la nouvelle fenêtre\n      * **clearsessioncache**: la valeur `yes` pour avoir le cache de cookie de session autorisé avant l'ouverture de la nouvelle fenêtre\n      * **zoom**: la valeur `yes` pour afficher les commandes de zoom du navigateur Android, affectez `no` de les cacher. Valeur par défaut est `yes`.\n      * **hardwareback**: utilisez le bouton de retour de matériel pour naviguer vers l'arrière à travers l'histoire de `InAppBrowser`de la valeur `Oui` . S'il n'y a aucune page précédente, `InAppBrowser` fermera. La valeur par défaut est `yes`, alors vous devez le définir à `no` si vous souhaitez que le bouton back de simplement fermer la InAppBrowser.\n    \n    iOS uniquement :\n    \n      * **closebuttoncaption**: affectez une chaîne à utiliser comme la **fait** légende du bouton. Notez que vous devrez localiser cette valeur vous-même.\n      * **disallowoverscroll**: la valeur `yes` ou `no` (valeur par défaut est `no` ). Active/désactive la propriété UIWebViewBounce.\n      * **caché**: la valeur `yes` pour créer le navigateur et charger la page, mais ne pas le montrer. L'événement loadstop est déclenché lorsque le chargement est terminé. Omettre ou la valeur `no` (par défaut) pour que le navigateur ouvrir et charger normalement.\n      * **ClearCache**: la valeur `yes` pour que le navigateur du cache de cookie effacé, avant l'ouverture de la nouvelle fenêtre\n      * **clearsessioncache**: la valeur `yes` pour avoir le cache de cookie de session autorisé avant l'ouverture de la nouvelle fenêtre\n      * **barre d'outils**: la valeur `yes` ou `no` pour activer la barre d'outils ou désactiver pour le InAppBrowser (par défaut,`yes`)\n      * **enableViewportScale**: la valeur `yes` ou `no` pour empêcher la fenêtre de mise à l'échelle par une balise meta (par défaut,`no`).\n      * **mediaPlaybackRequiresUserAction**: la valeur `yes` ou `no` pour empêcher le HTML5 audio ou vidéo de la lecture automatique (par défaut,`no`).\n      * **allowInlineMediaPlayback**: la valeur `yes` ou `no` pour permettre la lecture du média en ligne HTML5, affichage dans la fenêtre du navigateur plutôt que d'une interface de lecture spécifique au périphérique. L'HTML `video` élément doit également inclure la `webkit-playsinline` attribut (par défaut,`no`)\n      * **keyboardDisplayRequiresUserAction**: la valeur `yes` ou `no` pour ouvrir le clavier lorsque les éléments reçoivent le focus par l'intermédiaire de JavaScript `focus()` appel (par défaut,`yes`).\n      * **suppressesIncrementalRendering**: la valeur `yes` ou `no` d'attendre que toutes les nouveautés de vue sont reçue avant d'être restitué (par défaut,`no`).\n      * **presentationstyle**: la valeur `pagesheet` , `formsheet` ou `fullscreen` pour définir le [style de présentation](http://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalPresentationStyle) (par défaut,`fullscreen`).\n      * **transitionstyle**: la valeur `fliphorizontal` , `crossdissolve` ou `coververtical` pour définir le [style de transition](http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalTransitionStyle) (par défaut,`coververtical`).\n      * **toolbarposition**: la valeur `top` ou `bottom` (valeur par défaut est `bottom` ). Causes de la barre d'outils être en haut ou en bas de la fenêtre.\n    \n    Windows uniquement :\n    \n      * **caché**: la valeur `yes` pour créer le navigateur et charger la page, mais ne pas le montrer. L'événement loadstop est déclenché lorsque le chargement est terminé. Omettre ou la valeur `no` (par défaut) pour que le navigateur ouvrir et charger normalement.\n      * **fullscreen**: défini à `yes` pour créer le contrôle de navigateur sans bordure autour d'elle. Veuillez noter que si **location=no** est également spécifiée, il n'y n'aura aucun contrôle a présenté à l'utilisateur de fermer la fenêtre du CCI.\n\n### Plates-formes supportées\n\n  * Amazon Fire OS\n  * Android\n  * BlackBerry 10\n  * Firefox OS\n  * iOS\n  * Windows 8 et 8.1\n  * Windows Phone 7 et 8\n  * Navigateur\n\n### Exemple\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    var ref2 = cordova.InAppBrowser.open(encodeURI('http://ja.m.wikipedia.org/wiki/ハングル'), '_blank', 'location=yes');\n    \n\n### Firefox OS Quirks\n\nComme plugin n'est pas appliquer n'importe quelle conception il est nécessaire d'ajouter quelques règles CSS si ouvert avec `target= _blank`. Les règles pourraient ressembler à ces\n\n```css\n.inAppBrowserWrap {\n  background-color: rgba(0,0,0,0.75);\n  color: rgba(235,235,235,1.0);\n}\n.inAppBrowserWrap menu {\n  overflow: auto;\n  list-style-type: none;\n  padding-left: 0;\n}\n.inAppBrowserWrap menu li {\n  font-size: 25px;\n  height: 25px;\n  float: left;\n  margin: 0 10px;\n  padding: 3px 10px;\n  text-decoration: none;\n  color: #ccc;\n  display: block;\n  background: rgba(30,30,30,0.50);\n}\n.inAppBrowserWrap menu li.disabled {\n    color: #777;\n}\n```\n\n### Bizarreries de Windows\n\nSemblable à un comportement visuel fenêtre Firefox OS CCI peut être substituée par l'intermédiaire de `inAppBrowserWrap`/`inAppBrowserWrapFullscreen` des classes CSS\n\n### Bizarreries navigateur\n\n  * Plugin est implémentée via iframe,\n\n  * Historique de navigation (boutons`back` et `forward` dans LocationBar) n'est pas implémentée.\n\n## InAppBrowser\n\nL'objet retourné par un appel à `cordova.InAppBrowser.open`.\n\n### Méthodes\n\n  * addEventListener\n  * removeEventListener\n  * close\n  * show\n  * executeScript\n  * insertCSS\n\n## addEventListener\n\n> Ajoute un écouteur pour un évènement de la fenêtre `InAppBrowser`.\n\n    ref.addEventListener(eventname, callback);\n    \n\n  * **ref** : référence à la fenêtre `InAppBrowser`. *(InAppBrowser)*\n\n  * **eventname** : l'évènement à écouter *(String)*\n    \n      * **loadstart** : évènement déclenché lorsque le chargement d'une URL débute dans la fenêtre `InAppBrowser`.\n      * **loadstop** : évènement déclenché lorsque la fenêtre `InAppBrowser` finit de charger une URL.\n      * **loaderror** : évènement déclenché si la fenêtre `InAppBrowser` rencontre une erreur lors du chargement d'une URL.\n      * **exit** : évènement déclenché lorsque la fenêtre `InAppBrowser` est fermée.\n\n  * **callback** : la fonction à exécuter lorsque l'évènement se déclenche. Un objet `InAppBrowserEvent` lui est transmis comme paramètre.\n\n### Propriétés de InAppBrowserEvent\n\n  * **type** : le nom de l'évènement, soit `loadstart`, `loadstop`, `loaderror` ou `exit`. *(String)*\n\n  * **url** : l'URL ayant été chargée. *(String)*\n\n  * **code** : le code d'erreur, seulement pour `loaderror`. *(Number)*\n\n  * **message** : un message d'erreur, seulement pour `loaderror`. *(String)*\n\n### Plates-formes supportées\n\n  * Amazon Fire OS\n  * Android\n  * iOS\n  * Windows 8 et 8.1\n  * Windows Phone 7 et 8\n  * Navigateur\n\n### Bizarreries navigateur\n\nles événements `loadstart` et `loaderror` ne sont pas déclenchés.\n\n### Exemple court\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstart', function(event) { alert(event.url); });\n    \n\n## removeEventListener\n\n> Supprime un écouteur pour un évènement de la fenêtre `InAppBrowser`.\n\n    ref.removeEventListener(eventname, callback);\n    \n\n  * **ref** : référence à la fenêtre `InAppBrowser`. *(InAppBrowser)*\n\n  * **eventname** : l'évènement pour lequel arrêter l'écoute. *(String)*\n    \n      * **loadstart** : évènement déclenché lorsque le chargement d'une URL débute dans la fenêtre `InAppBrowser`.\n      * **loadstop** : évènement déclenché lorsque la fenêtre `InAppBrowser` finit de charger une URL.\n      * **loaderror** : évènement déclenché si la fenêtre `InAppBrowser` rencontre une erreur lors du chargement d'une URL.\n      * **exit** : évènement déclenché lorsque la fenêtre `InAppBrowser` est fermée.\n\n  * **callback** : la fonction à exécuter lorsque l'évènement se déclenche. Un objet `InAppBrowserEvent` lui est transmis comme paramètre.\n\n### Plates-formes supportées\n\n  * Amazon Fire OS\n  * Android\n  * iOS\n  * Windows 8 et 8.1\n  * Windows Phone 7 et 8\n  * Navigateur\n\n### Exemple court\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    var myCallback = function(event) { alert(event.url); }\n    ref.addEventListener('loadstart', myCallback);\n    ref.removeEventListener('loadstart', myCallback);\n    \n\n## close\n\n> Ferme la fenêtre `InAppBrowser`.\n\n    ref.close();\n    \n\n  * **ref** : référence à la fenêtre `InAppBrowser`. *(InAppBrowser)*\n\n### Plates-formes supportées\n\n  * Amazon Fire OS\n  * Android\n  * Firefox OS\n  * iOS\n  * Windows 8 et 8.1\n  * Windows Phone 7 et 8\n  * Navigateur\n\n### Exemple court\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.close();\n    \n\n## show\n\n> Affiche une fenêtre InAppBrowser qui a été ouverte cachée. Appeler cette méthode n'a aucun effet si la fenêtre en question est déjà visible.\n\n    ref.show();\n    \n\n  * **Réf**: référence à la fenêtre () InAppBrowser`InAppBrowser`)\n\n### Plates-formes supportées\n\n  * Amazon Fire OS\n  * Android\n  * iOS\n  * Windows 8 et 8.1\n  * Navigateur\n\n### Exemple court\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'hidden=yes');\n    // some time later...\n    ref.show();\n    \n\n## executeScript\n\n> Injecte du code JavaScript dans la fenêtre `InAppBrowser`\n\n    ref.executeScript(details, callback);\n    \n\n  * **ref** : référence à la fenêtre `InAppBrowser`. *(InAppBrowser)*\n\n  * **injectDetails** : détails du script à exécuter, requérant une propriété `file` ou `code`. *(Object)*\n    \n      * **file** : URL du script à injecter.\n      * **code** : texte du script à injecter.\n\n  * **callback** : une fonction exécutée après l'injection du code JavaScript.\n    \n      * Si le script injecté est de type `code`, un seul paramètre est transmis à la fonction callback, correspondant à la valeur de retour du script enveloppée dans un `Array`. Pour les scripts multilignes, il s'agit de la valeur renvoyée par la dernière instruction ou la dernière expression évaluée.\n\n### Plates-formes supportées\n\n  * Amazon Fire OS\n  * Android\n  * iOS\n  * Windows 8 et 8.1\n  * Navigateur\n\n### Exemple court\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstop', function() {\n        ref.executeScript({file: \"myscript.js\"});\n    });\n    \n\n### Bizarreries navigateur\n\n  * clef de **code** uniquement est pris en charge.\n\n### Bizarreries de Windows\n\nEn raison de la [documentation MSDN](https://msdn.microsoft.com/en-us/library/windows.ui.xaml.controls.webview.invokescriptasync.aspx) le script appelé peut retourner uniquement les valeurs de chaîne, sinon le paramètre, passé au **rappel** sera `[null]`.\n\n## insertCSS\n\n> Injecte des règles CSS dans la fenêtre `InAppBrowser`.\n\n    ref.insertCSS(details, callback);\n    \n\n  * **ref** : référence à la fenêtre `InAppBrowser`. *(InAppBrowser)*\n\n  * **injectDetails** : détails du script à exécuter, requérant une propriété `file` ou `code`. *(Object)*\n    \n      * **file** : URL de la feuille de style à injecter.\n      * **code** : contenu de la feuille de style à injecter.\n\n  * **callback** : une fonction exécutée après l'injection du fichier CSS.\n\n### Plates-formes supportées\n\n  * Amazon Fire OS\n  * Android\n  * iOS\n  * Windows\n\n### Exemple court\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstop', function() {\n        ref.insertCSS({file: \"mystyles.css\"});\n    });"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/doc/fr/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-inappbrowser\n\nCe module fournit une vue de navigateur web qui s'affiche lorsque vous appelez `cordova.InAppBrowser.open()`.\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    \n\nLe `cordova.InAppBrowser.open()` fonction est définie pour être un remplacement rapide de la fonction `window.open()`. Les appels existants `window.open()` peuvent utiliser la fenêtre de InAppBrowser, en remplaçant window.open :\n\n    window.open = cordova.InAppBrowser.open;\n    \n\nLa fenêtre de InAppBrowser se comporte comme un navigateur web standard et ne peut pas accéder aux APIs Cordova. Pour cette raison, le InAppBrowser est recommandé si vous devez charger le contenu de tiers (non approuvé), au lieu de chargement que dans le principaux webview Cordova. Le InAppBrowser n'est pas soumis à la liste blanche, ni s'ouvre les liens dans le navigateur de système.\n\nLe InAppBrowser fournit par défaut ses propres contrôles de GUI pour l'utilisateur (arrière, avant, fait).\n\nPour vers l'arrière la compatibilité, ce plugin crochets également `window.open`. Cependant, le plugin installé crochet de `window.open` peut avoir des effets secondaires involontaires (surtout si ce plugin est inclus uniquement comme une dépendance d'un autre plugin). Le crochet de `window.open` sera supprimé dans une future version majeure. Jusqu'à ce que le crochet est supprimé de la plugin, apps peuvent restaurer manuellement le comportement par défaut :\n\n    delete window.open // Reverts the call back to it's prototype's default\n    \n\nBien que `window.open` est dans la portée globale, InAppBrowser n'est pas disponible jusqu'à ce qu'après l'événement `deviceready`.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(\"window.open works well\");\n    }\n    \n\n## Installation\n\n    cordova plugin add cordova-plugin-inappbrowser\n    \n\nSi vous souhaitez que toutes les charges de la page dans votre application de passer par le InAppBrowser, vous pouvez simplement accrocher `window.open` pendant l'initialisation. Par exemple :\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        window.open = cordova.InAppBrowser.open;\n    }\n    \n\n## cordova.InAppBrowser.open\n\nOuvre une URL dans une nouvelle instance de `InAppBrowser`, l'instance de navigateur actuelle ou dans l'Explorateur du système.\n\n    var ref = cordova.InAppBrowser.open(url, target, options);\n    \n\n*   **ref** : référence à la fenêtre `InAppBrowser`. *(InAppBrowser)*\n\n*   **url** : l'URL à charger *(String)*. À encoder au préalable via `encodeURI()` si celle-ci contient des caractères Unicode.\n\n*   **target** : la cible du chargement de l'URL, ce paramètre est optionnel, sa valeur par défaut est `_self`. *(String)*\n    \n    *   `_self` : dirige le chargement vers la WebView Cordova si l'URL figure dans la liste blanche, sinon dans une fenêtre `InAppBrowser`.\n    *   `_blank` : dirige le chargement vers une fenêtre `InAppBrowser`.\n    *   `_system` : dirige le chargement vers le navigateur Web du système.\n\n*   **options** : permet de personnaliser la fenêtre `InAppBrowser`. Paramètre facultatif dont la valeur par défaut est `location=yes`. *(String)*\n    \n    La chaîne `options` ne doit contenir aucun caractère vide, chaque paire nom/valeur représentant une fonctionnalité doit être séparée de la précédente par une virgule. Les noms de fonctionnalités sont sensibles à la casse. Toutes les plates-formes prennent en charge la valeur ci-dessous :\n    \n    *   **location** : régler à `yes` ou `no` afin d'afficher ou masquer la barre d'adresse de la fenêtre `InAppBrowser`.\n    \n    Android uniquement :\n    \n    *   **caché**: la valeur `yes` pour créer le navigateur et charger la page, mais ne pas le montrer. L'événement loadstop est déclenché lorsque le chargement est terminé. Omettre ou la valeur `no` (par défaut) pour que le navigateur ouvrir et charger normalement.\n    *   **ClearCache**: la valeur `yes` pour que le navigateur du cache de cookie effacé, avant l'ouverture de la nouvelle fenêtre\n    *   **clearsessioncache**: la valeur `yes` pour avoir le cache de cookie de session autorisé avant l'ouverture de la nouvelle fenêtre\n    \n    iOS uniquement :\n    \n    *   **closebuttoncaption**: affectez une chaîne à utiliser comme la **fait** légende du bouton. Notez que vous devrez localiser cette valeur vous-même.\n    *   **disallowoverscroll**: la valeur `yes` ou `no` (valeur par défaut est `no` ). Active/désactive la propriété UIWebViewBounce.\n    *   **caché**: la valeur `yes` pour créer le navigateur et charger la page, mais ne pas le montrer. L'événement loadstop est déclenché lorsque le chargement est terminé. Omettre ou la valeur `no` (par défaut) pour que le navigateur ouvrir et charger normalement.\n    *   **ClearCache**: la valeur `yes` pour que le navigateur du cache de cookie effacé, avant l'ouverture de la nouvelle fenêtre\n    *   **clearsessioncache**: la valeur `yes` pour avoir le cache de cookie de session autorisé avant l'ouverture de la nouvelle fenêtre\n    *   **barre d'outils**: la valeur `yes` ou `no` pour activer la barre d'outils ou désactiver pour le InAppBrowser (par défaut,`yes`)\n    *   **enableViewportScale**: la valeur `yes` ou `no` pour empêcher la fenêtre de mise à l'échelle par une balise meta (par défaut,`no`).\n    *   **mediaPlaybackRequiresUserAction**: la valeur `yes` ou `no` pour empêcher le HTML5 audio ou vidéo de la lecture automatique (par défaut,`no`).\n    *   **allowInlineMediaPlayback**: la valeur `yes` ou `no` pour permettre la lecture du média en ligne HTML5, affichage dans la fenêtre du navigateur plutôt que d'une interface de lecture spécifique au périphérique. L'HTML `video` élément doit également inclure la `webkit-playsinline` attribut (par défaut,`no`)\n    *   **keyboardDisplayRequiresUserAction**: la valeur `yes` ou `no` pour ouvrir le clavier lorsque les éléments reçoivent le focus par l'intermédiaire de JavaScript `focus()` appel (par défaut,`yes`).\n    *   **suppressesIncrementalRendering**: la valeur `yes` ou `no` d'attendre que toutes les nouveautés de vue sont reçue avant d'être restitué (par défaut,`no`).\n    *   **presentationstyle**: la valeur `pagesheet` , `formsheet` ou `fullscreen` pour définir le [style de présentation][1] (par défaut,`fullscreen`).\n    *   **transitionstyle**: la valeur `fliphorizontal` , `crossdissolve` ou `coververtical` pour définir le [style de transition][2] (par défaut,`coververtical`).\n    *   **toolbarposition**: la valeur `top` ou `bottom` (valeur par défaut est `bottom` ). Causes de la barre d'outils être en haut ou en bas de la fenêtre.\n    \n    Windows uniquement :\n    \n    *   **caché**: la valeur `yes` pour créer le navigateur et charger la page, mais ne pas le montrer. L'événement loadstop est déclenché lorsque le chargement est terminé. Omettre ou la valeur `no` (par défaut) pour que le navigateur ouvrir et charger normalement.\n\n [1]: http://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalPresentationStyle\n [2]: http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalTransitionStyle\n\n### Plates-formes prises en charge\n\n*   Amazon Fire OS\n*   Android\n*   BlackBerry 10\n*   Firefox OS\n*   iOS\n*   Windows 8 et 8.1\n*   Windows Phone 7 et 8\n\n### Exemple\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    var ref2 = cordova.InAppBrowser.open(encodeURI('http://ja.m.wikipedia.org/wiki/ハングル'), '_blank', 'location=yes');\n    \n\n### Firefox OS Quirks\n\nComme plugin n'est pas appliquer n'importe quelle conception il est nécessaire d'ajouter quelques règles CSS si ouvert avec `target= _blank`. Les règles pourraient ressembler à ces\n\n     css\n    .inAppBrowserWrap {\n      background-color: rgba(0,0,0,0.75);\n      color: rgba(235,235,235,1.0);\n    }\n    .inAppBrowserWrap menu {\n      overflow: auto;\n      list-style-type: none;\n      padding-left: 0;\n    }\n    .inAppBrowserWrap menu li {\n      font-size: 25px;\n      height: 25px;\n      float: left;\n      margin: 0 10px;\n      padding: 3px 10px;\n      text-decoration: none;\n      color: #ccc;\n      display: block;\n      background: rgba(30,30,30,0.50);\n    }\n    .inAppBrowserWrap menu li.disabled {\n        color: #777;\n    }\n    \n\n## InAppBrowser\n\nL'objet retourné par un appel à `cordova.InAppBrowser.open`.\n\n### Méthodes\n\n*   addEventListener\n*   removeEventListener\n*   close\n*   show\n*   executeScript\n*   insertCSS\n\n## addEventListener\n\n> Ajoute un écouteur pour un évènement de la fenêtre `InAppBrowser`.\n\n    ref.addEventListener(eventname, callback);\n    \n\n*   **ref** : référence à la fenêtre `InAppBrowser`. *(InAppBrowser)*\n\n*   **eventname** : l'évènement à écouter *(String)*\n    \n    *   **loadstart** : évènement déclenché lorsque le chargement d'une URL débute dans la fenêtre `InAppBrowser`.\n    *   **loadstop** : évènement déclenché lorsque la fenêtre `InAppBrowser` finit de charger une URL.\n    *   **loaderror** : évènement déclenché si la fenêtre `InAppBrowser` rencontre une erreur lors du chargement d'une URL.\n    *   **exit** : évènement déclenché lorsque la fenêtre `InAppBrowser` est fermée.\n\n*   **callback** : la fonction à exécuter lorsque l'évènement se déclenche. Un objet `InAppBrowserEvent` lui est transmis comme paramètre.\n\n### Propriétés de InAppBrowserEvent\n\n*   **type** : le nom de l'évènement, soit `loadstart`, `loadstop`, `loaderror` ou `exit`. *(String)*\n\n*   **url** : l'URL ayant été chargée. *(String)*\n\n*   **code** : le code d'erreur, seulement pour `loaderror`. *(Number)*\n\n*   **message** : un message d'erreur, seulement pour `loaderror`. *(String)*\n\n### Plates-formes prises en charge\n\n*   Amazon Fire OS\n*   Android\n*   iOS\n*   Windows 8 et 8.1\n*   Windows Phone 7 et 8\n\n### Petit exemple\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstart', function(event) { alert(event.url); });\n    \n\n## removeEventListener\n\n> Supprime un écouteur pour un évènement de la fenêtre `InAppBrowser`.\n\n    ref.removeEventListener(eventname, callback);\n    \n\n*   **ref** : référence à la fenêtre `InAppBrowser`. *(InAppBrowser)*\n\n*   **eventname** : l'évènement pour lequel arrêter l'écoute. *(String)*\n    \n    *   **loadstart**: événement déclenche quand le `InAppBrowser` commence à charger une URL.\n    *   **loadstop**: événement déclenche lorsque la `InAppBrowser` finit de charger une URL.\n    *   **loaderror** : évènement déclenché si la fenêtre `InAppBrowser` rencontre une erreur lors du chargement d'une URL.\n    *   **sortie**: événement déclenche quand le `InAppBrowser` fenêtre est fermée.\n\n*   **callback** : la fonction à exécuter lorsque l'évènement se déclenche. Un objet `InAppBrowserEvent` lui est transmis comme paramètre.\n\n### Plates-formes prises en charge\n\n*   Amazon Fire OS\n*   Android\n*   iOS\n*   Windows 8 et 8.1\n*   Windows Phone 7 et 8\n\n### Petit exemple\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    var myCallback = function(event) { alert(event.url); }\n    ref.addEventListener('loadstart', myCallback);\n    ref.removeEventListener('loadstart', myCallback);\n    \n\n## close\n\n> Ferme la fenêtre `InAppBrowser`.\n\n    ref.close();\n    \n\n*   **Réf**: référence à la `InAppBrowser` fenêtre *(InAppBrowser)*\n\n### Plates-formes prises en charge\n\n*   Amazon Fire OS\n*   Android\n*   Firefox OS\n*   iOS\n*   Windows 8 et 8.1\n*   Windows Phone 7 et 8\n\n### Petit exemple\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.close();\n    \n\n## show\n\n> Affiche une fenêtre InAppBrowser qui a été ouverte cachée. Appeler cette méthode n'a aucun effet si la fenêtre en question est déjà visible.\n\n    ref.show();\n    \n\n*   **Réf**: référence à la fenêtre () InAppBrowser`InAppBrowser`)\n\n### Plates-formes prises en charge\n\n*   Amazon Fire OS\n*   Android\n*   iOS\n*   Windows 8 et 8.1\n\n### Petit exemple\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'hidden=yes');\n    // some time later...\n    ref.show();\n    \n\n## executeScript\n\n> Injecte du code JavaScript dans la fenêtre `InAppBrowser`\n\n    ref.executeScript(details, callback);\n    \n\n*   **Réf**: référence à la `InAppBrowser` fenêtre. *(InAppBrowser)*\n\n*   **injectDetails** : détails du script à exécuter, requérant une propriété `file` ou `code`. *(Object)*\n    \n    *   **file** : URL du script à injecter.\n    *   **code** : texte du script à injecter.\n\n*   **callback** : une fonction exécutée après l'injection du code JavaScript.\n    \n    *   Si le script injecté est de type `code`, un seul paramètre est transmis à la fonction callback, correspondant à la valeur de retour du script enveloppée dans un `Array`. Pour les scripts multilignes, il s'agit de la valeur renvoyée par la dernière instruction ou la dernière expression évaluée.\n\n### Plates-formes prises en charge\n\n*   Amazon Fire OS\n*   Android\n*   iOS\n*   Windows 8 et 8.1\n\n### Petit exemple\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstop', function() {\n        ref.executeScript({file: \"myscript.js\"});\n    });\n    \n\n## insertCSS\n\n> Injecte des règles CSS dans la fenêtre `InAppBrowser`.\n\n    ref.insertCSS(details, callback);\n    \n\n*   **Réf**: référence à la `InAppBrowser` fenêtre *(InAppBrowser)*\n\n*   **injectDetails**: Détails du script à exécuter, spécifiant soit un `file` ou `code` clés. *(Objet)*\n    \n    *   **file** : URL de la feuille de style à injecter.\n    *   **code** : contenu de la feuille de style à injecter.\n\n*   **callback** : une fonction exécutée après l'injection du fichier CSS.\n\n### Plates-formes prises en charge\n\n*   Amazon Fire OS\n*   Android\n*   iOS\n\n### Petit exemple\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstop', function() {\n        ref.insertCSS({file: \"mystyles.css\"});\n    });\n"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/doc/it/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-inappbrowser\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-inappbrowser.svg)](https://travis-ci.org/apache/cordova-plugin-inappbrowser)\n\nQuesto plugin fornisce una vista di browser web che viene visualizzato quando si chiama `di cordova.InAppBrowser.open()`.\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    \n\nIl `cordova.InAppBrowser.open()` funzione è definita per essere un rimpiazzo per la funzione `window.open`. Esistenti chiamate `Window` possono utilizzare la finestra di InAppBrowser, sostituendo window.open():\n\n    window.open = cordova.InAppBrowser.open;\n    \n\nLa finestra di InAppBrowser si comporta come un browser web standard e non può accedere a Cordova APIs. Per questo motivo, è consigliabile la InAppBrowser se è necessario caricare il contenuto (non attendibile) di terze parti, invece di caricamento che in webview Cordova principale. Il InAppBrowser non è soggetto alla whitelist, né sta aprendo il link nel browser di sistema.\n\nLa InAppBrowser fornisce di default propri controlli GUI per l'utente (indietro, avanti, fatto).\n\nPer indietro la compatibilità, questo plugin ganci anche `window.open`. Tuttavia, il plugin installato gancio di `window.open` può avere effetti collaterali indesiderati (soprattutto se questo plugin è incluso solo come dipendenza di un altro plugin). Il gancio di `window. open` verrà rimosso in una futura release principale. Fino a quando il gancio è rimosso dal plugin, apps può ripristinare manualmente il comportamento predefinito:\n\n    delete window.open // Reverts the call back to it's prototype's default\n    \n\nSebbene `window.open` sia in ambito globale, InAppBrowser non è disponibile fino a dopo l'evento `deviceready`.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(\"window.open works well\");\n    }\n    \n\n## Installazione\n\n    cordova plugin add cordova-plugin-inappbrowser\n    \n\nSe si desidera che tutti i carichi di pagina nell'app di passare attraverso il InAppBrowser, si può semplicemente collegare `window.open` durante l'inizializzazione. Per esempio:\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        window.open = cordova.InAppBrowser.open;\n    }\n    \n\n## cordova.InAppBrowser.open\n\nApre un URL in una nuova istanza di `InAppBrowser`, l'istanza corrente del browser o il browser di sistema.\n\n    var ref = cordova.InAppBrowser.open(url, target, options);\n    \n\n  * **ref**: fare riferimento alla `InAppBrowser` finestra. *(InAppBrowser)*\n\n  * **url**: l'URL da caricare *(String)*. Chiamare `encodeURI()` su questo, se l'URL contiene caratteri Unicode.\n\n  * **target**: la destinazione in cui caricare l'URL, un parametro facoltativo che il valore predefinito è `_self` . *(String)*\n    \n      * `_self`: Si apre in Cordova WebView se l'URL è nella lista bianca, altrimenti si apre nella`InAppBrowser`.\n      * `_blank`: Apre il`InAppBrowser`.\n      * `_system`: Si apre nel browser web del sistema.\n\n  * **options**: opzioni per il `InAppBrowser` . Opzionale, inadempiente a: `location=yes` . *(String)*\n    \n    Il `options` stringa non deve contenere alcun spazio vuoto, e coppie nome/valore ogni funzionalità devono essere separate da una virgola. Caratteristica nomi sono tra maiuscole e minuscole. Tutte le piattaforme supportano il valore riportato di seguito:\n    \n      * **posizione**: impostata su `yes` o `no` per trasformare il `InAppBrowser` di barra di posizione on o off.\n    \n    Solo su Android:\n    \n      * **nascosti**: impostare su `yes` per creare il browser e caricare la pagina, ma non mostrarlo. L'evento loadstop viene generato quando il caricamento è completato. Omettere o impostata su `no` (impostazione predefinita) per avere il browser aperto e caricare normalmente.\n      * **ClearCache**: impostare su `yes` per avere il browser cache cookie ha lasciata prima dell'apertura della nuova finestra\n      * **clearsessioncache**: impostare su `yes` per avere la cache cookie di sessione cancellata prima dell'apertura della nuova finestra\n      * **zoom**: impostare su `yes` per mostrare i controlli di zoom del browser Android, impostata su `no` per nasconderli. Valore predefinito è `yes`.\n      * **hardwareback**: impostare `yes` per utilizzare il pulsante Indietro hardware per spostarsi all'indietro tra il `InAppBrowser`di storia. Se esiste una pagina precedente, si chiuderà il `InAppBrowser` . Il valore predefinito è `yes`, quindi è necessario impostare a `no` , se si desidera che il pulsante indietro per chiudere semplicemente il InAppBrowser.\n    \n    solo iOS:\n    \n      * **closebuttoncaption**: impostare una stringa da utilizzare come didascalia del pulsante **fatto** . Si noti che è necessario localizzare questo valore a te stesso.\n      * **disallowoverscroll**: impostare su `yes` o `no` (default è `no` ). Attiva/disattiva la proprietà UIWebViewBounce.\n      * **nascosti**: impostare su `yes` per creare il browser e caricare la pagina, ma non mostrarlo. L'evento loadstop viene generato quando il caricamento è completato. Omettere o impostata su `no` (impostazione predefinita) per avere il browser aperto e caricare normalmente.\n      * **ClearCache**: impostare su `yes` per avere il browser cache cookie ha lasciata prima dell'apertura della nuova finestra\n      * **clearsessioncache**: impostare su `yes` per avere la cache cookie di sessione cancellata prima dell'apertura della nuova finestra\n      * **Toolbar**: impostare su `yes` o `no` per attivare la barra degli strumenti o disattivare per il InAppBrowser (default`yes`)\n      * **enableViewportScale**: impostare su `yes` o `no` per impedire la viewport ridimensionamento tramite un tag meta (default`no`).\n      * **mediaPlaybackRequiresUserAction**: impostare su `yes` o `no` per impedire HTML5 audio o video da AutoPlay (default`no`).\n      * **allowInlineMediaPlayback**: impostare su `yes` o `no` per consentire la riproduzione dei supporti HTML5 in linea, visualizzare all'interno della finestra del browser, piuttosto che un'interfaccia specifica del dispositivo di riproduzione. L'HTML `video` elemento deve includere anche il `webkit-playsinline` (default di attributo`no`)\n      * **keyboardDisplayRequiresUserAction**: impostare su `yes` o `no` per aprire la tastiera quando elementi form ricevano lo stato attivo tramite di JavaScript `focus()` chiamata (default`yes`).\n      * **suppressesIncrementalRendering**: impostare su `yes` o `no` aspettare fino a quando tutti i nuovi contenuti di vista viene ricevuto prima il rendering (default`no`).\n      * **presentationstyle**: impostare su `pagesheet` , `formsheet` o `fullscreen` per impostare lo [stile di presentazione](http://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalPresentationStyle) (default`fullscreen`).\n      * **transitionstyle**: impostare su `fliphorizontal` , `crossdissolve` o `coververtical` per impostare lo [stile di transizione](http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalTransitionStyle) (default`coververtical`).\n      * **toolbarposition**: impostare su `top` o `bottom` (default è `bottom` ). Provoca la barra degli strumenti sia nella parte superiore o inferiore della finestra.\n    \n    Solo per Windows:\n    \n      * **nascosti**: impostare su `yes` per creare il browser e caricare la pagina, ma non mostrarlo. L'evento loadstop viene generato quando il caricamento è completato. Omettere o impostata su `no` (impostazione predefinita) per avere il browser aperto e caricare normalmente.\n      * **fullscreen**: impostata su `yes` per creare il controllo browser senza un bordo attorno ad esso. Siete pregati di notare che se **location=no** viene specificato, non ci sarà nessun controllo presentato all'utente per chiudere la finestra IAB.\n\n### Piattaforme supportate\n\n  * Amazon fuoco OS\n  * Android\n  * BlackBerry 10\n  * Firefox OS\n  * iOS\n  * Windows 8 e 8.1\n  * Windows Phone 7 e 8\n  * Browser\n\n### Esempio\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    var ref2 = cordova.InAppBrowser.open(encodeURI('http://ja.m.wikipedia.org/wiki/ハングル'), '_blank', 'location=yes');\n    \n\n### Firefox OS stranezze\n\nCome plugin non imporre alcun disegno c'è bisogno di aggiungere alcune regole CSS se aperto con `target='_blank'`. Le regole potrebbero apparire come questi\n\n```css\n.inAppBrowserWrap {\n  background-color: rgba(0,0,0,0.75);\n  color: rgba(235,235,235,1.0);\n}\n.inAppBrowserWrap menu {\n  overflow: auto;\n  list-style-type: none;\n  padding-left: 0;\n}\n.inAppBrowserWrap menu li {\n  font-size: 25px;\n  height: 25px;\n  float: left;\n  margin: 0 10px;\n  padding: 3px 10px;\n  text-decoration: none;\n  color: #ccc;\n  display: block;\n  background: rgba(30,30,30,0.50);\n}\n.inAppBrowserWrap menu li.disabled {\n    color: #777;\n}\n```\n\n### Stranezze di Windows\n\nSimile al comportamento visivo finestra di Firefox OS IAB può essere sottoposto a override tramite `inAppBrowserWrap`/ classi CSS`inAppBrowserWrapFullscreen`\n\n### Stranezze browser\n\n  * Plugin viene implementato tramite iframe,\n\n  * Cronologia di navigazione (pulsanti`indietro` e `Avanti` in LocationBar) non è implementato.\n\n## InAppBrowser\n\nL'oggetto restituito da una chiamata a `di cordova.InAppBrowser.open`.\n\n### Metodi\n\n  * addEventListener\n  * removeEventListener\n  * close\n  * show\n  * executeScript\n  * insertCSS\n\n## addEventListener\n\n> Aggiunge un listener per un evento dal`InAppBrowser`.\n\n    ref.addEventListener(eventname, callback);\n    \n\n  * **Rif**: fare riferimento alla `InAppBrowser` finestra *(InAppBrowser)*\n\n  * **EventName**: l'evento per l'ascolto *(String)*\n    \n      * **loadstart**: evento viene generato quando il `InAppBrowser` comincia a caricare un URL.\n      * **loadstop**: evento viene generato quando il `InAppBrowser` termina il caricamento di un URL.\n      * **LoadError**: evento viene generato quando il `InAppBrowser` rileva un errore durante il caricamento di un URL.\n      * **uscita**: evento viene generato quando il `InAppBrowser` finestra è chiusa.\n\n  * **richiamata**: la funzione che viene eseguito quando viene generato l'evento. La funzione viene passata un `InAppBrowserEvent` oggetto come parametro.\n\n### Proprietà InAppBrowserEvent\n\n  * **tipo**: il eventname, o `loadstart` , `loadstop` , `loaderror` , o `exit` . *(String)*\n\n  * **URL**: l'URL che è stato caricato. *(String)*\n\n  * **codice**: il codice di errore, solo nel caso di `loaderror` . *(Numero)*\n\n  * **messaggio**: il messaggio di errore, solo nel caso di `loaderror` . *(String)*\n\n### Piattaforme supportate\n\n  * Amazon fuoco OS\n  * Android\n  * iOS\n  * Windows 8 e 8.1\n  * Windows Phone 7 e 8\n  * Browser\n\n### Stranezze browser\n\neventi `onloadstart` e `loaderror` non sono stati licenziati.\n\n### Esempio rapido\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstart', function(event) { alert(event.url); });\n    \n\n## removeEventListener\n\n> Rimuove un listener per un evento dal`InAppBrowser`.\n\n    ref.removeEventListener(eventname, callback);\n    \n\n  * **Rif**: fare riferimento alla `InAppBrowser` finestra. *(InAppBrowser)*\n\n  * **EventName**: interrompere l'attesa per l'evento. *(String)*\n    \n      * **loadstart**: evento viene generato quando il `InAppBrowser` comincia a caricare un URL.\n      * **loadstop**: evento viene generato quando il `InAppBrowser` termina il caricamento di un URL.\n      * **LoadError**: evento viene generato quando il `InAppBrowser` rileva un errore di caricamento di un URL.\n      * **uscita**: evento viene generato quando il `InAppBrowser` finestra è chiusa.\n\n  * **richiamata**: la funzione da eseguire quando viene generato l'evento. La funzione viene passata un `InAppBrowserEvent` oggetto.\n\n### Piattaforme supportate\n\n  * Amazon fuoco OS\n  * Android\n  * iOS\n  * Windows 8 e 8.1\n  * Windows Phone 7 e 8\n  * Browser\n\n### Esempio rapido\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    var myCallback = function(event) { alert(event.url); }\n    ref.addEventListener('loadstart', myCallback);\n    ref.removeEventListener('loadstart', myCallback);\n    \n\n## close\n\n> Chiude la `InAppBrowser` finestra.\n\n    ref.close();\n    \n\n  * **Rif**: fare riferimento alla `InAppBrowser` finestra *(InAppBrowser)*\n\n### Piattaforme supportate\n\n  * Amazon fuoco OS\n  * Android\n  * Firefox OS\n  * iOS\n  * Windows 8 e 8.1\n  * Windows Phone 7 e 8\n  * Browser\n\n### Esempio rapido\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.close();\n    \n\n## show\n\n> Visualizza una finestra di InAppBrowser che è stato aperto nascosta. Questa chiamata non ha effetto se la InAppBrowser era già visibile.\n\n    ref.show();\n    \n\n  * **Rif**: riferimento per il InAppBrowser finestra (`InAppBrowser`)\n\n### Piattaforme supportate\n\n  * Amazon fuoco OS\n  * Android\n  * iOS\n  * Windows 8 e 8.1\n  * Browser\n\n### Esempio rapido\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'hidden=yes');\n    // some time later...\n    ref.show();\n    \n\n## executeScript\n\n> Inserisce il codice JavaScript nella `InAppBrowser` finestra\n\n    ref.executeScript(details, callback);\n    \n\n  * **Rif**: fare riferimento alla `InAppBrowser` finestra. *(InAppBrowser)*\n\n  * **injectDetails**: dettagli dello script da eseguire, specificando un `file` o `code` chiave. *(Oggetto)*\n    \n      * **file**: URL dello script da iniettare.\n      * **codice**: testo dello script da iniettare.\n\n  * **richiamata**: la funzione che viene eseguito dopo che il codice JavaScript viene iniettato.\n    \n      * Se lo script iniettato è di tipo `code` , il callback viene eseguita con un singolo parametro, che è il valore restituito del copione, avvolto in un `Array` . Per gli script multi-linea, questo è il valore restituito dell'ultima istruzione, o l'ultima espressione valutata.\n\n### Piattaforme supportate\n\n  * Amazon fuoco OS\n  * Android\n  * iOS\n  * Windows 8 e 8.1\n  * Browser\n\n### Esempio rapido\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstop', function() {\n        ref.executeScript({file: \"myscript.js\"});\n    });\n    \n\n### Stranezze browser\n\n  * è supportato solo il **code** chiave.\n\n### Stranezze di Windows\n\nA causa di [documenti MSDN](https://msdn.microsoft.com/en-us/library/windows.ui.xaml.controls.webview.invokescriptasync.aspx) lo script richiamato può restituire solo i valori di stringa, altrimenti il parametro, passato al **callback** sarà `[null]`.\n\n## insertCSS\n\n> Inietta CSS nella `InAppBrowser` finestra.\n\n    ref.insertCSS(details, callback);\n    \n\n  * **Rif**: fare riferimento alla `InAppBrowser` finestra *(InAppBrowser)*\n\n  * **injectDetails**: dettagli dello script da eseguire, specificando un `file` o `code` chiave. *(Oggetto)*\n    \n      * **file**: URL del foglio di stile per iniettare.\n      * **codice**: testo del foglio di stile per iniettare.\n\n  * **richiamata**: la funzione che viene eseguito dopo che il CSS viene iniettato.\n\n### Piattaforme supportate\n\n  * Amazon fuoco OS\n  * Android\n  * iOS\n  * Windows\n\n### Esempio rapido\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstop', function() {\n        ref.insertCSS({file: \"mystyles.css\"});\n    });"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/doc/it/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-inappbrowser\n\nQuesto plugin fornisce una vista di browser web che viene visualizzato quando si chiama `di cordova.InAppBrowser.open()`.\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    \n\nIl `cordova.InAppBrowser.open()` funzione è definita per essere un rimpiazzo per la funzione `window.open`. Esistenti chiamate `Window` possono utilizzare la finestra di InAppBrowser, sostituendo window.open():\n\n    window.open = cordova.InAppBrowser.open;\n    \n\nLa finestra di InAppBrowser si comporta come un browser web standard e non può accedere a Cordova APIs. Per questo motivo, è consigliabile la InAppBrowser se è necessario caricare il contenuto (non attendibile) di terze parti, invece di caricamento che in webview Cordova principale. Il InAppBrowser non è soggetto alla whitelist, né sta aprendo il link nel browser di sistema.\n\nLa InAppBrowser fornisce di default propri controlli GUI per l'utente (indietro, avanti, fatto).\n\nPer indietro la compatibilità, questo plugin ganci anche `window.open`. Tuttavia, il plugin installato gancio di `window.open` può avere effetti collaterali indesiderati (soprattutto se questo plugin è incluso solo come dipendenza di un altro plugin). Il gancio di `window. open` verrà rimosso in una futura release principale. Fino a quando il gancio è rimosso dal plugin, apps può ripristinare manualmente il comportamento predefinito:\n\n    delete window.open // Reverts the call back to it's prototype's default\n    \n\nSebbene `window.open` sia in ambito globale, InAppBrowser non è disponibile fino a dopo l'evento `deviceready`.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(\"window.open works well\");\n    }\n    \n\n## Installazione\n\n    cordova plugin add cordova-plugin-inappbrowser\n    \n\nSe si desidera che tutti i carichi di pagina nell'app di passare attraverso il InAppBrowser, si può semplicemente collegare `window.open` durante l'inizializzazione. Per esempio:\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        window.open = cordova.InAppBrowser.open;\n    }\n    \n\n## cordova.InAppBrowser.open\n\nApre un URL in una nuova istanza di `InAppBrowser`, l'istanza corrente del browser o il browser di sistema.\n\n    var ref = cordova.InAppBrowser.open(url, target, options);\n    \n\n*   **ref**: fare riferimento alla `InAppBrowser` finestra. *(InAppBrowser)*\n\n*   **url**: l'URL da caricare *(String)*. Chiamare `encodeURI()` su questo, se l'URL contiene caratteri Unicode.\n\n*   **target**: la destinazione in cui caricare l'URL, un parametro facoltativo che il valore predefinito è `_self` . *(String)*\n    \n    *   `_self`: Si apre in Cordova WebView se l'URL è nella lista bianca, altrimenti si apre nella`InAppBrowser`.\n    *   `_blank`: Apre il`InAppBrowser`.\n    *   `_system`: Si apre nel browser web del sistema.\n\n*   **options**: opzioni per il `InAppBrowser` . Opzionale, inadempiente a: `location=yes` . *(String)*\n    \n    Il `options` stringa non deve contenere alcun spazio vuoto, e coppie nome/valore ogni funzionalità devono essere separate da una virgola. Caratteristica nomi sono tra maiuscole e minuscole. Tutte le piattaforme supportano il valore riportato di seguito:\n    \n    *   **posizione**: impostata su `yes` o `no` per trasformare il `InAppBrowser` di barra di posizione on o off.\n    \n    Solo su Android:\n    \n    *   **nascosti**: impostare su `yes` per creare il browser e caricare la pagina, ma non mostrarlo. L'evento loadstop viene generato quando il caricamento è completato. Omettere o impostata su `no` (impostazione predefinita) per avere il browser aperto e caricare normalmente.\n    *   **ClearCache**: impostare su `yes` per avere il browser cache cookie ha lasciata prima dell'apertura della nuova finestra\n    *   **clearsessioncache**: impostare su `yes` per avere la cache cookie di sessione cancellata prima dell'apertura della nuova finestra\n    \n    solo iOS:\n    \n    *   **closebuttoncaption**: impostare una stringa da utilizzare come didascalia del pulsante **fatto** . Si noti che è necessario localizzare questo valore a te stesso.\n    *   **disallowoverscroll**: impostare su `yes` o `no` (default è `no` ). Attiva/disattiva la proprietà UIWebViewBounce.\n    *   **nascosti**: impostare su `yes` per creare il browser e caricare la pagina, ma non mostrarlo. L'evento loadstop viene generato quando il caricamento è completato. Omettere o impostata su `no` (impostazione predefinita) per avere il browser aperto e caricare normalmente.\n    *   **ClearCache**: impostare su `yes` per avere il browser cache cookie ha lasciata prima dell'apertura della nuova finestra\n    *   **clearsessioncache**: impostare su `yes` per avere la cache cookie di sessione cancellata prima dell'apertura della nuova finestra\n    *   **Toolbar**: impostare su `yes` o `no` per attivare la barra degli strumenti o disattivare per il InAppBrowser (default`yes`)\n    *   **enableViewportScale**: impostare su `yes` o `no` per impedire la viewport ridimensionamento tramite un tag meta (default`no`).\n    *   **mediaPlaybackRequiresUserAction**: impostare su `yes` o `no` per impedire HTML5 audio o video da AutoPlay (default`no`).\n    *   **allowInlineMediaPlayback**: impostare su `yes` o `no` per consentire la riproduzione dei supporti HTML5 in linea, visualizzare all'interno della finestra del browser, piuttosto che un'interfaccia specifica del dispositivo di riproduzione. L'HTML `video` elemento deve includere anche il `webkit-playsinline` (default di attributo`no`)\n    *   **keyboardDisplayRequiresUserAction**: impostare su `yes` o `no` per aprire la tastiera quando elementi form ricevano lo stato attivo tramite di JavaScript `focus()` chiamata (default`yes`).\n    *   **suppressesIncrementalRendering**: impostare su `yes` o `no` aspettare fino a quando tutti i nuovi contenuti di vista viene ricevuto prima il rendering (default`no`).\n    *   **presentationstyle**: impostare su `pagesheet` , `formsheet` o `fullscreen` per impostare lo [stile di presentazione][1] (default`fullscreen`).\n    *   **transitionstyle**: impostare su `fliphorizontal` , `crossdissolve` o `coververtical` per impostare lo [stile di transizione][2] (default`coververtical`).\n    *   **toolbarposition**: impostare su `top` o `bottom` (default è `bottom` ). Provoca la barra degli strumenti sia nella parte superiore o inferiore della finestra.\n    \n    Solo per Windows:\n    \n    *   **nascosti**: impostare su `yes` per creare il browser e caricare la pagina, ma non mostrarlo. L'evento loadstop viene generato quando il caricamento è completato. Omettere o impostata su `no` (impostazione predefinita) per avere il browser aperto e caricare normalmente.\n\n [1]: http://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalPresentationStyle\n [2]: http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalTransitionStyle\n\n### Piattaforme supportate\n\n*   Amazon fuoco OS\n*   Android\n*   BlackBerry 10\n*   Firefox OS\n*   iOS\n*   Windows 8 e 8.1\n*   Windows Phone 7 e 8\n\n### Esempio\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    var ref2 = cordova.InAppBrowser.open(encodeURI('http://ja.m.wikipedia.org/wiki/ハングル'), '_blank', 'location=yes');\n    \n\n### Firefox OS stranezze\n\nCome plugin non imporre alcun disegno c'è bisogno di aggiungere alcune regole CSS se aperto con `target='_blank'`. Le regole potrebbero apparire come questi\n\n     css\n    .inAppBrowserWrap {\n      background-color: rgba(0,0,0,0.75);\n      color: rgba(235,235,235,1.0);\n    }\n    .inAppBrowserWrap menu {\n      overflow: auto;\n      list-style-type: none;\n      padding-left: 0;\n    }\n    .inAppBrowserWrap menu li {\n      font-size: 25px;\n      height: 25px;\n      float: left;\n      margin: 0 10px;\n      padding: 3px 10px;\n      text-decoration: none;\n      color: #ccc;\n      display: block;\n      background: rgba(30,30,30,0.50);\n    }\n    .inAppBrowserWrap menu li.disabled {\n        color: #777;\n    }\n    \n\n## InAppBrowser\n\nL'oggetto restituito da una chiamata a `di cordova.InAppBrowser.open`.\n\n### Metodi\n\n*   addEventListener\n*   removeEventListener\n*   close\n*   show\n*   executeScript\n*   insertCSS\n\n## addEventListener\n\n> Aggiunge un listener per un evento dal`InAppBrowser`.\n\n    ref.addEventListener(eventname, callback);\n    \n\n*   **Rif**: fare riferimento alla `InAppBrowser` finestra *(InAppBrowser)*\n\n*   **EventName**: l'evento per l'ascolto *(String)*\n    \n    *   **loadstart**: evento viene generato quando il `InAppBrowser` comincia a caricare un URL.\n    *   **loadstop**: evento viene generato quando il `InAppBrowser` termina il caricamento di un URL.\n    *   **LoadError**: evento viene generato quando il `InAppBrowser` rileva un errore durante il caricamento di un URL.\n    *   **uscita**: evento viene generato quando il `InAppBrowser` finestra è chiusa.\n\n*   **richiamata**: la funzione che viene eseguito quando viene generato l'evento. La funzione viene passata un `InAppBrowserEvent` oggetto come parametro.\n\n### Proprietà InAppBrowserEvent\n\n*   **tipo**: il eventname, o `loadstart` , `loadstop` , `loaderror` , o `exit` . *(String)*\n\n*   **URL**: l'URL che è stato caricato. *(String)*\n\n*   **codice**: il codice di errore, solo nel caso di `loaderror` . *(Numero)*\n\n*   **messaggio**: il messaggio di errore, solo nel caso di `loaderror` . *(String)*\n\n### Piattaforme supportate\n\n*   Amazon fuoco OS\n*   Android\n*   iOS\n*   Windows 8 e 8.1\n*   Windows Phone 7 e 8\n\n### Esempio rapido\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstart', function(event) { alert(event.url); });\n    \n\n## removeEventListener\n\n> Rimuove un listener per un evento dal`InAppBrowser`.\n\n    ref.removeEventListener(eventname, callback);\n    \n\n*   **Rif**: fare riferimento alla `InAppBrowser` finestra. *(InAppBrowser)*\n\n*   **EventName**: interrompere l'attesa per l'evento. *(String)*\n    \n    *   **loadstart**: evento viene generato quando il `InAppBrowser` comincia a caricare un URL.\n    *   **loadstop**: evento viene generato quando il `InAppBrowser` termina il caricamento di un URL.\n    *   **LoadError**: evento viene generato quando il `InAppBrowser` rileva un errore di caricamento di un URL.\n    *   **uscita**: evento viene generato quando il `InAppBrowser` finestra è chiusa.\n\n*   **richiamata**: la funzione da eseguire quando viene generato l'evento. La funzione viene passata un `InAppBrowserEvent` oggetto.\n\n### Piattaforme supportate\n\n*   Amazon fuoco OS\n*   Android\n*   iOS\n*   Windows 8 e 8.1\n*   Windows Phone 7 e 8\n\n### Esempio rapido\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    var myCallback = function(event) { alert(event.url); }\n    ref.addEventListener('loadstart', myCallback);\n    ref.removeEventListener('loadstart', myCallback);\n    \n\n## close\n\n> Chiude la `InAppBrowser` finestra.\n\n    ref.close();\n    \n\n*   **Rif**: fare riferimento alla `InAppBrowser` finestra *(InAppBrowser)*\n\n### Piattaforme supportate\n\n*   Amazon fuoco OS\n*   Android\n*   Firefox OS\n*   iOS\n*   Windows 8 e 8.1\n*   Windows Phone 7 e 8\n\n### Esempio rapido\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.close();\n    \n\n## show\n\n> Visualizza una finestra di InAppBrowser che è stato aperto nascosta. Questa chiamata non ha effetto se la InAppBrowser era già visibile.\n\n    ref.show();\n    \n\n*   **Rif**: riferimento per il InAppBrowser finestra (`InAppBrowser`)\n\n### Piattaforme supportate\n\n*   Amazon fuoco OS\n*   Android\n*   iOS\n*   Windows 8 e 8.1\n\n### Esempio rapido\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'hidden=yes');\n    // some time later...\n    ref.show();\n    \n\n## executeScript\n\n> Inserisce il codice JavaScript nella `InAppBrowser` finestra\n\n    ref.executeScript(details, callback);\n    \n\n*   **Rif**: fare riferimento alla `InAppBrowser` finestra. *(InAppBrowser)*\n\n*   **injectDetails**: dettagli dello script da eseguire, specificando un `file` o `code` chiave. *(Oggetto)*\n    \n    *   **file**: URL dello script da iniettare.\n    *   **codice**: testo dello script da iniettare.\n\n*   **richiamata**: la funzione che viene eseguito dopo che il codice JavaScript viene iniettato.\n    \n    *   Se lo script iniettato è di tipo `code` , il callback viene eseguita con un singolo parametro, che è il valore restituito del copione, avvolto in un `Array` . Per gli script multi-linea, questo è il valore restituito dell'ultima istruzione, o l'ultima espressione valutata.\n\n### Piattaforme supportate\n\n*   Amazon fuoco OS\n*   Android\n*   iOS\n*   Windows 8 e 8.1\n\n### Esempio rapido\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstop', function() {\n        ref.executeScript({file: \"myscript.js\"});\n    });\n    \n\n## insertCSS\n\n> Inietta CSS nella `InAppBrowser` finestra.\n\n    ref.insertCSS(details, callback);\n    \n\n*   **Rif**: fare riferimento alla `InAppBrowser` finestra *(InAppBrowser)*\n\n*   **injectDetails**: dettagli dello script da eseguire, specificando un `file` o `code` chiave. *(Oggetto)*\n    \n    *   **file**: URL del foglio di stile per iniettare.\n    *   **codice**: testo del foglio di stile per iniettare.\n\n*   **richiamata**: la funzione che viene eseguito dopo che il CSS viene iniettato.\n\n### Piattaforme supportate\n\n*   Amazon fuoco OS\n*   Android\n*   iOS\n\n### Esempio rapido\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstop', function() {\n        ref.insertCSS({file: \"mystyles.css\"});\n    });\n"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/doc/ja/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-inappbrowser\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-inappbrowser.svg)](https://travis-ci.org/apache/cordova-plugin-inappbrowser)\n\nこのプラグインは `コルドバを呼び出すときに表示される web ブラウザーのビューを提供します。InAppBrowser.open()`.\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    \n\n`コルドバ。InAppBrowser.open()` `window.open()` 関数との交換を定義する関数。 既存の `window.open()` 呼び出しは、window.open を置き換えることによって InAppBrowser ウィンドウを使用できます。\n\n    window.open = cordova.InAppBrowser.open;\n    \n\nInAppBrowser ウィンドウは標準的な web ブラウザーのように動作し、コルドバ Api にアクセスできません。 この理由から、InAppBrowser お勧めする場合はメインのコルドバの webview を読み込むのではなくサード パーティ (信頼されていない) コンテンツをロードする必要があります。 InAppBrowser、ホワイト リストの対象ではないも、システムのブラウザーでリンクを開くです。\n\nInAppBrowser を提供しますデフォルトで GUI コントロール (戻る、進む、行う)。\n\n後方互換性、このプラグインは、また `window.open` をフックのため。 ただし、`window.open` のプラグイン インストール フックを持つことができます意図しない副作用 （特に場合は、このプラグインは別のプラグインの依存関係としてのみ含まれています)。 `window.open` のフックは、将来のメジャー リリースで削除されます。 プラグインから、フックが削除されるまでアプリはデフォルトの動作を手動で復元できます。\n\n    delete window.open // Reverts the call back to it's prototype's default\n    \n\n`window.open` はグローバル スコープでは、InAppBrowser は、`deviceready` イベントの後まで利用できません。\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(\"window.open works well\");\n    }\n    \n\n## インストール\n\n    cordova plugin add cordova-plugin-inappbrowser\n    \n\nInAppBrowser を通過するアプリですべてのページの読み込みをする場合は初期化中に `window.open` を単にフックできます。たとえば。\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        window.open = cordova.InAppBrowser.open;\n    }\n    \n\n## cordova.InAppBrowser.open\n\n新しい `InAppBrowser` インスタンスを現在のブラウザー インスタンスまたはシステムのブラウザーで URL を開きます。\n\n    var ref = cordova.InAppBrowser.open(url, target, options);\n    \n\n  * **ref**: への参照を `InAppBrowser` ウィンドウ。*(InAppBrowser)*\n\n  * **url**: *(文字列)*をロードする URL。電話 `encodeURI()` 場合は、この上の URL は Unicode 文字を含みます。\n\n  * **ターゲット**: ターゲット URL は、既定値は、省略可能なパラメーターをロードするを `_self` 。*(文字列)*\n    \n      * `_self`: コルドバ WebView URL がホワイト リストにある場合で開きます、それ以外の場合で開きます、`InAppBrowser`.\n      * `_blank`: で開きます、`InAppBrowser`.\n      * `_system`: システムの web ブラウザーで開きます。\n\n  * **オプション**: おぷしょん、 `InAppBrowser` 。省略可能にする: `location=yes` 。*(文字列)*\n    \n    `options`文字列にはする必要があります任意の空白スペースが含まれていないと、各機能の名前と値のペアをコンマで区切る必要があります。 機能名では大文字小文字を区別します。 以下の値をサポートするプラットフォーム。\n    \n      * **場所**： に設定 `yes` または `no` を有効にする、 `InAppBrowser` の場所バー オンまたはオフにします。\n    \n    アンドロイドのみ：\n    \n      * **非表示**: 設定 `yes` ブラウザーを作成して、ページの読み込みが表示されません。 Loadstop イベントは、読み込みが完了すると発生します。 省略するか設定 `no` (既定値) を開くし、通常読み込みブラウザーを持っています。\n      * **clearcache**: に設定されている `yes` 、ブラウザーのクッキー キャッシュ クリア新しいウィンドウが開く前に\n      * **clearsessioncache**： に設定されている `yes` はセッション cookie のキャッシュをオフにすると、新しいウィンドウが開く前に\n      * **zoom**:`yes`Android ブラウザーのズーム コントロールの表示を`no`に設定すると、それらを非表示に設定します。 既定値は`yes`.\n      * **hardwareback**: `InAppBrowser`の履歴を後方に移動するのにハードウェアの戻るボタンを使用して`yes`に設定します。 前のページがない場合は、 `InAppBrowser`が終了します。 既定値は`はい`、ため場合は、単に、InAppBrowser を閉じる戻るボタン`なし`を設定する必要があります。\n    \n    iOS のみ:\n    \n      * **closebuttoncaption**: [**完了**] ボタンのキャプションとして使用する文字列に設定します。自分でこの値をローカライズする必要があることに注意してください。\n      * **disallowoverscroll**： に設定されている `yes` または `no` (既定値は `no` )。/UIWebViewBounce プロパティをオフにします。\n      * **非表示**: 設定 `yes` ブラウザーを作成して、ページの読み込みが表示されません。 Loadstop イベントは、読み込みが完了すると発生します。 省略するか設定 `no` (既定値) を開くし、通常読み込みブラウザーを持っています。\n      * **clearcache**: に設定されている `yes` 、ブラウザーのクッキー キャッシュ クリア新しいウィンドウが開く前に\n      * **clearsessioncache**： に設定されている `yes` はセッション cookie のキャッシュをオフにすると、新しいウィンドウが開く前に\n      * **ツールバー**: に設定されている `yes` または `no` InAppBrowser (デフォルトのツールバーのオンまたはオフを有効にするには`yes`)\n      * **enableViewportScale**： に設定されている `yes` または `no` を (デフォルトではメタタグを介してスケーリング ビューポートを防ぐために`no`).\n      * **mediaPlaybackRequiresUserAction**： に設定されている `yes` または `no` を HTML5 オーディオまたはビデオを自動再生 （初期設定から防ぐために`no`).\n      * **allowInlineMediaPlayback**： に設定されている `yes` または `no` ラインで HTML5 メディア再生には、デバイス固有再生インターフェイスではなく、ブラウザー ウィンドウ内に表示するようにします。 HTML の `video` 要素を含める必要がありますまた、 `webkit-playsinline` 属性 (デフォルトは`no`)\n      * **keyboardDisplayRequiresUserAction**： に設定されている `yes` または `no` をフォーム要素の JavaScript を介してフォーカスを受け取るときに、キーボードを開く `focus()` コール （デフォルトは`yes`).\n      * **suppressesIncrementalRendering**： に設定されている `yes` または `no` (デフォルトでは表示される前にビューのすべての新しいコンテンツを受信するまで待機するには`no`).\n      * **presentationstyle**： に設定されている `pagesheet` 、 `formsheet` または `fullscreen` (デフォルトでは、[プレゼンテーション スタイル](http://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalPresentationStyle)を設定するには`fullscreen`).\n      * **transitionstyle**： に設定されている `fliphorizontal` 、 `crossdissolve` または `coververtical` (デフォルトでは、[トランジションのスタイル](http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalTransitionStyle)を設定するには`coververtical`).\n      * **toolbarposition**： に設定されている `top` または `bottom` (既定値は `bottom` )。上部またはウィンドウの下部にツールバーが発生します。\n    \n    Windows のみ：\n    \n      * **非表示**: 設定 `yes` ブラウザーを作成して、ページの読み込みが表示されません。 Loadstop イベントは、読み込みが完了すると発生します。 省略するか設定 `no` (既定値) を開くし、通常読み込みブラウザーを持っています。\n      * **fullscreen**: 周りに境界線なしブラウザー コントロールを作成する`[yes]`に設定します。 その場合に注意してください**location=no**指定また、IAB ウィンドウを閉じるためにユーザーに提示はコントロールされます。\n\n### サポートされているプラットフォーム\n\n  * アマゾン火 OS\n  * アンドロイド\n  * ブラックベリー 10\n  * Firefox の OS\n  * iOS\n  * Windows 8 および 8.1\n  * Windows Phone 7 と 8\n  * ブラウザー\n\n### 例\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    var ref2 = cordova.InAppBrowser.open(encodeURI('http://ja.m.wikipedia.org/wiki/ハングル'), '_blank', 'location=yes');\n    \n\n### Firefox OS 癖\n\n開かれた場合にいくつかの CSS ルールを追加する必要があるプラグインは任意のデザインを適用しないと `target ='_blank'`。これらのような規則になります。\n\n```css\n.inAppBrowserWrap {\n  background-color: rgba(0,0,0,0.75);\n  color: rgba(235,235,235,1.0);\n}\n.inAppBrowserWrap menu {\n  overflow: auto;\n  list-style-type: none;\n  padding-left: 0;\n}\n.inAppBrowserWrap menu li {\n  font-size: 25px;\n  height: 25px;\n  float: left;\n  margin: 0 10px;\n  padding: 3px 10px;\n  text-decoration: none;\n  color: #ccc;\n  display: block;\n  background: rgba(30,30,30,0.50);\n}\n.inAppBrowserWrap menu li.disabled {\n    color: #777;\n}\n```\n\n### Windows の癖\n\n`InAppBrowserWrap`経由で Firefox OS IAB ウィンドウの視覚的動作に似ていますをオーバーライドできます/`inAppBrowserWrapFullscreen` CSS クラス\n\n### ブラウザーの癖\n\n  * Iframe を介してプラグインを実装します。\n\n  * ナビゲーション履歴 (LocationBar の`進む`と`戻る`ボタン) は実装されていません。\n\n## InAppBrowser\n\n`コルドバへの呼び出しから返されるオブジェクト。InAppBrowser.open`.\n\n### メソッド\n\n  * addEventListener\n  * removeEventListener\n  * close\n  * show\n  * executeScript\n  * insertCSS\n\n## addEventListener\n\n> イベントのリスナーを追加します、`InAppBrowser`.\n\n    ref.addEventListener(eventname, callback);\n    \n\n  * **ref**: への参照を `InAppBrowser` ウィンドウ*(InAppBrowser)*\n\n  * **eventname**: *(文字列)*をリッスンするイベント\n    \n      * ****： イベントが発生するとき、 `InAppBrowser` の URL の読み込みが開始します。\n      * **loadstop**： イベントが発生するとき、 `InAppBrowser` URL の読み込みが完了します。\n      * **loaderror**： イベントが発生するとき、 `InAppBrowser` URL の読み込みでエラーが発生します。\n      * **終了**: イベントが発生するとき、 `InAppBrowser` ウィンドウが閉じられます。\n\n  * **コールバック**: イベントが発生したときに実行される関数。関数に渡されますが、 `InAppBrowserEvent` オブジェクトをパラメーターとして。\n\n### InAppBrowserEvent プロパティ\n\n  * **タイプ**: eventname どちらか `loadstart` 、 `loadstop` 、 `loaderror` 、または `exit` 。*(文字列)*\n\n  * **url**: URL が読み込まれました。*(文字列)*\n\n  * **コード**: の場合にのみ、エラー コード `loaderror` 。*(数)*\n\n  * **メッセージ**: の場合にのみ、エラー メッセージ `loaderror` 。*(文字列)*\n\n### サポートされているプラットフォーム\n\n  * アマゾン火 OS\n  * アンドロイド\n  * iOS\n  * Windows 8 および 8.1\n  * Windows Phone 7 と 8\n  * ブラウザー\n\n### ブラウザーの癖\n\n`loadstart` `loaderror`イベントが発生していません。\n\n### 簡単な例\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstart', function(event) { alert(event.url); });\n    \n\n## removeEventListener\n\n> イベントのリスナーを削除します、`InAppBrowser`.\n\n    ref.removeEventListener(eventname, callback);\n    \n\n  * **ref**: への参照を `InAppBrowser` ウィンドウ。*(InAppBrowser)*\n\n  * **eventname**: イベントのリッスンを停止します。*(文字列)*\n    \n      * ****： イベントが発生するとき、 `InAppBrowser` の URL の読み込みが開始します。\n      * **loadstop**： イベントが発生するとき、 `InAppBrowser` URL の読み込みが完了します。\n      * **loaderror**： イベントが発生するとき、 `InAppBrowser` URL の読み込みエラーが発生します。\n      * **終了**: イベントが発生するとき、 `InAppBrowser` ウィンドウが閉じられます。\n\n  * **コールバック**: イベントが発生するときに実行する関数。関数に渡されますが、 `InAppBrowserEvent` オブジェクト。\n\n### サポートされているプラットフォーム\n\n  * アマゾン火 OS\n  * アンドロイド\n  * iOS\n  * Windows 8 および 8.1\n  * Windows Phone 7 と 8\n  * ブラウザー\n\n### 簡単な例\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    var myCallback = function(event) { alert(event.url); }\n    ref.addEventListener('loadstart', myCallback);\n    ref.removeEventListener('loadstart', myCallback);\n    \n\n## close\n\n> 閉じる、 `InAppBrowser` ウィンドウ。\n\n    ref.close();\n    \n\n  * **ref**: への参照を `InAppBrowser` ウィンドウ*(InAppBrowser)*\n\n### サポートされているプラットフォーム\n\n  * アマゾン火 OS\n  * アンドロイド\n  * Firefox の OS\n  * iOS\n  * Windows 8 および 8.1\n  * Windows Phone 7 と 8\n  * ブラウザー\n\n### 簡単な例\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.close();\n    \n\n## show\n\n> 隠された開かれた InAppBrowser ウィンドウが表示されます。この関数を呼び出すは影響しません、InAppBrowser が既に表示されている場合。\n\n    ref.show();\n    \n\n  * **ref**: InAppBrowser ウィンドウ (への参照`InAppBrowser`)\n\n### サポートされているプラットフォーム\n\n  * アマゾン火 OS\n  * アンドロイド\n  * iOS\n  * Windows 8 および 8.1\n  * ブラウザー\n\n### 簡単な例\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'hidden=yes');\n    // some time later...\n    ref.show();\n    \n\n## executeScript\n\n> JavaScript コードに挿入します、 `InAppBrowser` ウィンドウ\n\n    ref.executeScript(details, callback);\n    \n\n  * **ref**: への参照を `InAppBrowser` ウィンドウ。*(InAppBrowser)*\n\n  * **injectDetails**： 詳細を実行するスクリプトのいずれかを指定する、 `file` または `code` キー。*(オブジェクト)*\n    \n      * **ファイル**： スクリプトの URL を注入します。\n      * **コード**: スクリプトのテキストを挿入します。\n\n  * **コールバック**: JavaScript コードを注入した後に実行される関数。\n    \n      * 挿入されたスクリプトが型の場合 `code` 、スクリプトの戻り値は、1 つのパラメーターでコールバックを実行するのに包まれて、 `Array` 。 マルチライン スクリプトについては、最後のステートメントでは、または評価した最後の式の戻り値です。\n\n### サポートされているプラットフォーム\n\n  * アマゾン火 OS\n  * アンドロイド\n  * iOS\n  * Windows 8 および 8.1\n  * ブラウザー\n\n### 簡単な例\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstop', function() {\n        ref.executeScript({file: \"myscript.js\"});\n    });\n    \n\n### ブラウザーの癖\n\n  * **code**キーのみをサポートします。\n\n### Windows の癖\n\n[MSDN ドキュメント](https://msdn.microsoft.com/en-us/library/windows.ui.xaml.controls.webview.invokescriptasync.aspx)のため呼び出されたスクリプト パラメーターを返す文字列値のみそれ以外の場合は、**コールバック**に渡される`[null]`になります.\n\n## insertCSS\n\n> CSS に注入する、 `InAppBrowser` ウィンドウ。\n\n    ref.insertCSS(details, callback);\n    \n\n  * **ref**: への参照を `InAppBrowser` ウィンドウ*(InAppBrowser)*\n\n  * **injectDetails**： 詳細を実行するスクリプトのいずれかを指定する、 `file` または `code` キー。*(オブジェクト)*\n    \n      * **ファイル**: 注入するスタイル シートの URL。\n      * **コード**: 注入するスタイル シートのテキスト。\n\n  * **コールバック**: CSS の注入後に実行される関数。\n\n### サポートされているプラットフォーム\n\n  * アマゾン火 OS\n  * アンドロイド\n  * iOS\n  * Windows\n\n### 簡単な例\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstop', function() {\n        ref.insertCSS({file: \"mystyles.css\"});\n    });"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/doc/ja/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-inappbrowser\n\nこのプラグインは `コルドバを呼び出すときに表示される web ブラウザーのビューを提供します。InAppBrowser.open()`.\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    \n\n`コルドバ。InAppBrowser.open()` `window.open()` 関数との交換を定義する関数。 既存の `window.open()` 呼び出しは、window.open を置き換えることによって InAppBrowser ウィンドウを使用できます。\n\n    window.open = cordova.InAppBrowser.open;\n    \n\nInAppBrowser ウィンドウは標準的な web ブラウザーのように動作し、コルドバ Api にアクセスできません。 この理由から、InAppBrowser お勧めする場合はメインのコルドバの webview を読み込むのではなくサード パーティ (信頼されていない) コンテンツをロードする必要があります。 InAppBrowser、ホワイト リストの対象ではないも、システムのブラウザーでリンクを開くです。\n\nInAppBrowser を提供しますデフォルトで GUI コントロール (戻る、進む、行う)。\n\n後方互換性、このプラグインは、また `window.open` をフックのため。 ただし、`window.open` のプラグイン インストール フックを持つことができます意図しない副作用 （特に場合は、このプラグインは別のプラグインの依存関係としてのみ含まれています)。 `window.open` のフックは、将来のメジャー リリースで削除されます。 プラグインから、フックが削除されるまでアプリはデフォルトの動作を手動で復元できます。\n\n    delete window.open // Reverts the call back to it's prototype's default\n    \n\n`window.open` はグローバル スコープでは、InAppBrowser は、`deviceready` イベントの後まで利用できません。\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(\"window.open works well\");\n    }\n    \n\n## インストール\n\n    cordova plugin add cordova-plugin-inappbrowser\n    \n\nInAppBrowser を通過するアプリですべてのページの読み込みをする場合は初期化中に `window.open` を単にフックできます。たとえば。\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        window.open = cordova.InAppBrowser.open;\n    }\n    \n\n## cordova.InAppBrowser.open\n\n新しい `InAppBrowser` インスタンスを現在のブラウザー インスタンスまたはシステムのブラウザーで URL を開きます。\n\n    var ref = cordova.InAppBrowser.open(url, target, options);\n    \n\n*   **ref**: への参照を `InAppBrowser` ウィンドウ。*(InAppBrowser)*\n\n*   **url**: *(文字列)*をロードする URL。電話 `encodeURI()` 場合は、この上の URL は Unicode 文字を含みます。\n\n*   **ターゲット**: ターゲット URL は、既定値は、省略可能なパラメーターをロードするを `_self` 。*(文字列)*\n    \n    *   `_self`: コルドバ WebView URL がホワイト リストにある場合で開きます、それ以外の場合で開きます、`InAppBrowser`.\n    *   `_blank`: で開きます、`InAppBrowser`.\n    *   `_system`: システムの web ブラウザーで開きます。\n\n*   **オプション**: おぷしょん、 `InAppBrowser` 。省略可能にする: `location=yes` 。*(文字列)*\n    \n    `options`文字列にはする必要があります任意の空白スペースが含まれていないと、各機能の名前と値のペアをコンマで区切る必要があります。 機能名では大文字小文字を区別します。 以下の値をサポートするプラットフォーム。\n    \n    *   **場所**： に設定 `yes` または `no` を有効にする、 `InAppBrowser` の場所バー オンまたはオフにします。\n    \n    アンドロイドのみ：\n    \n    *   **非表示**: 設定 `yes` ブラウザーを作成して、ページの読み込みが表示されません。 Loadstop イベントは、読み込みが完了すると発生します。 省略するか設定 `no` (既定値) を開くし、通常読み込みブラウザーを持っています。\n    *   **clearcache**: に設定されている `yes` 、ブラウザーのクッキー キャッシュ クリア新しいウィンドウが開く前に\n    *   **clearsessioncache**： に設定されている `yes` はセッション cookie のキャッシュをオフにすると、新しいウィンドウが開く前に\n    \n    iOS のみ:\n    \n    *   **closebuttoncaption**: [**完了**] ボタンのキャプションとして使用する文字列に設定します。自分でこの値をローカライズする必要があることに注意してください。\n    *   **disallowoverscroll**： に設定されている `yes` または `no` (既定値は `no` )。/UIWebViewBounce プロパティをオフにします。\n    *   **非表示**: 設定 `yes` ブラウザーを作成して、ページの読み込みが表示されません。 Loadstop イベントは、読み込みが完了すると発生します。 省略するか設定 `no` (既定値) を開くし、通常読み込みブラウザーを持っています。\n    *   **clearcache**: に設定されている `yes` 、ブラウザーのクッキー キャッシュ クリア新しいウィンドウが開く前に\n    *   **clearsessioncache**： に設定されている `yes` はセッション cookie のキャッシュをオフにすると、新しいウィンドウが開く前に\n    *   **ツールバー**: に設定されている `yes` または `no` InAppBrowser (デフォルトのツールバーのオンまたはオフを有効にするには`yes`)\n    *   **enableViewportScale**： に設定されている `yes` または `no` を (デフォルトではメタタグを介してスケーリング ビューポートを防ぐために`no`).\n    *   **mediaPlaybackRequiresUserAction**： に設定されている `yes` または `no` を HTML5 オーディオまたはビデオを自動再生 （初期設定から防ぐために`no`).\n    *   **allowInlineMediaPlayback**： に設定されている `yes` または `no` ラインで HTML5 メディア再生には、デバイス固有再生インターフェイスではなく、ブラウザー ウィンドウ内に表示するようにします。 HTML の `video` 要素を含める必要がありますまた、 `webkit-playsinline` 属性 (デフォルトは`no`)\n    *   **keyboardDisplayRequiresUserAction**： に設定されている `yes` または `no` をフォーム要素の JavaScript を介してフォーカスを受け取るときに、キーボードを開く `focus()` コール （デフォルトは`yes`).\n    *   **suppressesIncrementalRendering**： に設定されている `yes` または `no` (デフォルトでは表示される前にビューのすべての新しいコンテンツを受信するまで待機するには`no`).\n    *   **presentationstyle**： に設定されている `pagesheet` 、 `formsheet` または `fullscreen` (デフォルトでは、[プレゼンテーション スタイル][1]を設定するには`fullscreen`).\n    *   **transitionstyle**： に設定されている `fliphorizontal` 、 `crossdissolve` または `coververtical` (デフォルトでは、[トランジションのスタイル][2]を設定するには`coververtical`).\n    *   **toolbarposition**： に設定されている `top` または `bottom` (既定値は `bottom` )。上部またはウィンドウの下部にツールバーが発生します。\n    \n    Windows のみ：\n    \n    *   **非表示**: 設定 `yes` ブラウザーを作成して、ページの読み込みが表示されません。 Loadstop イベントは、読み込みが完了すると発生します。 省略するか設定 `no` (既定値) を開くし、通常読み込みブラウザーを持っています。\n\n [1]: http://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalPresentationStyle\n [2]: http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalTransitionStyle\n\n### サポートされているプラットフォーム\n\n*   アマゾン火 OS\n*   アンドロイド\n*   ブラックベリー 10\n*   Firefox の OS\n*   iOS\n*   Windows 8 および 8.1\n*   Windows Phone 7 と 8\n\n### 例\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    var ref2 = cordova.InAppBrowser.open(encodeURI('http://ja.m.wikipedia.org/wiki/ハングル'), '_blank', 'location=yes');\n    \n\n### Firefox OS 癖\n\n開かれた場合にいくつかの CSS ルールを追加する必要があるプラグインは任意のデザインを適用しないと `target ='_blank'`。これらのような規則になります。\n\n     css\n    .inAppBrowserWrap {\n      background-color: rgba(0,0,0,0.75);\n      color: rgba(235,235,235,1.0);\n    }\n    .inAppBrowserWrap menu {\n      overflow: auto;\n      list-style-type: none;\n      padding-left: 0;\n    }\n    .inAppBrowserWrap menu li {\n      font-size: 25px;\n      height: 25px;\n      float: left;\n      margin: 0 10px;\n      padding: 3px 10px;\n      text-decoration: none;\n      color: #ccc;\n      display: block;\n      background: rgba(30,30,30,0.50);\n    }\n    .inAppBrowserWrap menu li.disabled {\n        color: #777;\n    }\n    \n\n## InAppBrowser\n\n`コルドバへの呼び出しから返されるオブジェクト。InAppBrowser.open`.\n\n### メソッド\n\n*   addEventListener\n*   removeEventListener\n*   close\n*   show\n*   executeScript\n*   insertCSS\n\n## addEventListener\n\n> イベントのリスナーを追加します、`InAppBrowser`.\n\n    ref.addEventListener(eventname, callback);\n    \n\n*   **ref**: への参照を `InAppBrowser` ウィンドウ*(InAppBrowser)*\n\n*   **eventname**: *(文字列)*をリッスンするイベント\n    \n    *   ****： イベントが発生するとき、 `InAppBrowser` の URL の読み込みが開始します。\n    *   **loadstop**： イベントが発生するとき、 `InAppBrowser` URL の読み込みが完了します。\n    *   **loaderror**： イベントが発生するとき、 `InAppBrowser` URL の読み込みでエラーが発生します。\n    *   **終了**: イベントが発生するとき、 `InAppBrowser` ウィンドウが閉じられます。\n\n*   **コールバック**: イベントが発生したときに実行される関数。関数に渡されますが、 `InAppBrowserEvent` オブジェクトをパラメーターとして。\n\n### InAppBrowserEvent プロパティ\n\n*   **タイプ**: eventname どちらか `loadstart` 、 `loadstop` 、 `loaderror` 、または `exit` 。*(文字列)*\n\n*   **url**: URL が読み込まれました。*(文字列)*\n\n*   **コード**: の場合にのみ、エラー コード `loaderror` 。*(数)*\n\n*   **メッセージ**: の場合にのみ、エラー メッセージ `loaderror` 。*(文字列)*\n\n### サポートされているプラットフォーム\n\n*   アマゾン火 OS\n*   アンドロイド\n*   iOS\n*   Windows 8 および 8.1\n*   Windows Phone 7 と 8\n\n### 簡単な例\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstart', function(event) { alert(event.url); });\n    \n\n## removeEventListener\n\n> イベントのリスナーを削除します、`InAppBrowser`.\n\n    ref.removeEventListener(eventname, callback);\n    \n\n*   **ref**: への参照を `InAppBrowser` ウィンドウ。*(InAppBrowser)*\n\n*   **eventname**: イベントのリッスンを停止します。*(文字列)*\n    \n    *   ****： イベントが発生するとき、 `InAppBrowser` の URL の読み込みが開始します。\n    *   **loadstop**： イベントが発生するとき、 `InAppBrowser` URL の読み込みが完了します。\n    *   **loaderror**： イベントが発生するとき、 `InAppBrowser` URL の読み込みエラーが発生します。\n    *   **終了**: イベントが発生するとき、 `InAppBrowser` ウィンドウが閉じられます。\n\n*   **コールバック**: イベントが発生するときに実行する関数。関数に渡されますが、 `InAppBrowserEvent` オブジェクト。\n\n### サポートされているプラットフォーム\n\n*   アマゾン火 OS\n*   アンドロイド\n*   iOS\n*   Windows 8 および 8.1\n*   Windows Phone 7 と 8\n\n### 簡単な例\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    var myCallback = function(event) { alert(event.url); }\n    ref.addEventListener('loadstart', myCallback);\n    ref.removeEventListener('loadstart', myCallback);\n    \n\n## close\n\n> 閉じる、 `InAppBrowser` ウィンドウ。\n\n    ref.close();\n    \n\n*   **ref**: への参照を `InAppBrowser` ウィンドウ*(InAppBrowser)*\n\n### サポートされているプラットフォーム\n\n*   アマゾン火 OS\n*   アンドロイド\n*   Firefox の OS\n*   iOS\n*   Windows 8 および 8.1\n*   Windows Phone 7 と 8\n\n### 簡単な例\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.close();\n    \n\n## show\n\n> 隠された開かれた InAppBrowser ウィンドウが表示されます。この関数を呼び出すは影響しません、InAppBrowser が既に表示されている場合。\n\n    ref.show();\n    \n\n*   **ref**: InAppBrowser ウィンドウ (への参照`InAppBrowser`)\n\n### サポートされているプラットフォーム\n\n*   アマゾン火 OS\n*   アンドロイド\n*   iOS\n*   Windows 8 および 8.1\n\n### 簡単な例\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'hidden=yes');\n    // some time later...\n    ref.show();\n    \n\n## executeScript\n\n> JavaScript コードに挿入します、 `InAppBrowser` ウィンドウ\n\n    ref.executeScript(details, callback);\n    \n\n*   **ref**: への参照を `InAppBrowser` ウィンドウ。*(InAppBrowser)*\n\n*   **injectDetails**： 詳細を実行するスクリプトのいずれかを指定する、 `file` または `code` キー。*(オブジェクト)*\n    \n    *   **ファイル**： スクリプトの URL を注入します。\n    *   **コード**: スクリプトのテキストを挿入します。\n\n*   **コールバック**: JavaScript コードを注入した後に実行される関数。\n    \n    *   挿入されたスクリプトが型の場合 `code` 、スクリプトの戻り値は、1 つのパラメーターでコールバックを実行するのに包まれて、 `Array` 。 マルチライン スクリプトについては、最後のステートメントでは、または評価した最後の式の戻り値です。\n\n### サポートされているプラットフォーム\n\n*   アマゾン火 OS\n*   アンドロイド\n*   iOS\n*   Windows 8 および 8.1\n\n### 簡単な例\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstop', function() {\n        ref.executeScript({file: \"myscript.js\"});\n    });\n    \n\n## insertCSS\n\n> CSS に注入する、 `InAppBrowser` ウィンドウ。\n\n    ref.insertCSS(details, callback);\n    \n\n*   **ref**: への参照を `InAppBrowser` ウィンドウ*(InAppBrowser)*\n\n*   **injectDetails**： 詳細を実行するスクリプトのいずれかを指定する、 `file` または `code` キー。*(オブジェクト)*\n    \n    *   **ファイル**: 注入するスタイル シートの URL。\n    *   **コード**: 注入するスタイル シートのテキスト。\n\n*   **コールバック**: CSS の注入後に実行される関数。\n\n### サポートされているプラットフォーム\n\n*   アマゾン火 OS\n*   アンドロイド\n*   iOS\n\n### 簡単な例\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstop', function() {\n        ref.insertCSS({file: \"mystyles.css\"});\n    });\n"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/doc/ko/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-inappbrowser\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-inappbrowser.svg)](https://travis-ci.org/apache/cordova-plugin-inappbrowser)\n\n이 플러그인 `코르도바를 호출할 때 표시 하는 웹 브라우저 보기를 제공 합니다.InAppBrowser.open()`.\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    \n\n`코르도바입니다.InAppBrowser.open()` 함수 `window.open ()` 함수에 대 한 대체품 정의 됩니다. 기존의 `window.open ()` 호출 window.open을 대체 하 여 InAppBrowser 윈도우를 사용할 수 있습니다.\n\n    window.open = cordova.InAppBrowser.open;\n    \n\nInAppBrowser 창 표준 웹 브라우저 처럼 동작 및 코르도바 Api에 액세스할 수 없습니다. 이 이유는 InAppBrowser는 것이 좋습니다는 주요 코르도바 webview로 로드 하는 대신 제 3 자 (신뢰할 수 없는) 콘텐츠를 로드 해야 할 경우. InAppBrowser는 허용 될 수도 시스템 브라우저에서 링크를 여는.\n\n사용자에 대 한 자체 GUI 컨트롤에서 기본적으로 제공 된 InAppBrowser (뒤로, 앞으로, 완료).\n\n대 한 뒤 호환성,이 플러그인도 `window.open` 후크. 그러나, `window.open`의 플러그인 설치 후크를 가질 수 있습니다 의도 하지 않은 부작용 (특히 경우이 플러그인이 다른 플러그인 종속성 으로만 포함). `window.open` 후크 주요 릴리스에서 제거 됩니다. 후크 플러그인에서 제거 될 때까지 애플 리 케이 션 수 있습니다 수동으로 기본 동작을 복원 하 게 됩니다.\n\n    delete window.open // Reverts the call back to it's prototype's default\n    \n\n`window.open` 전역 범위에 있지만 InAppBrowser 제공 되지 않습니다 때까지 `deviceready` 이벤트 후.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(\"window.open works well\");\n    }\n    \n\n## 설치\n\n    cordova plugin add cordova-plugin-inappbrowser\n    \n\nInAppBrowser를 통해가 서 당신의 애플 리 케이 션에서 모든 페이지를 로드 하려는 경우 초기화 하는 동안 `window.open` 간단 하 게 연결할 수 있습니다. 예를 들어:\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        window.open = cordova.InAppBrowser.open;\n    }\n    \n\n## cordova.InAppBrowser.open\n\n새 `InAppBrowser` 인스턴스, 현재 브라우저 인스턴스 또는 시스템 브라우저에서 URL을 엽니다.\n\n    var ref = cordova.InAppBrowser.open(url, target, options);\n    \n\n  * **심판**:에 대 한 참조는 `InAppBrowser` 창. *(InAppBrowser)*\n\n  * **url**: *(문자열)를*로드 하는 URL. 전화 `encodeURI()` 이 경우에는 URL 유니코드 문자를 포함 합니다.\n\n  * **대상**: 대상 URL, 기본적으로 선택적 매개 변수를 로드 하는 `_self` . *(문자열)*\n    \n      * `_self`: URL 화이트 리스트에 있으면 코르도바 WebView에서 열리고, 그렇지 않으면 열에`InAppBrowser`.\n      * `_blank`: 준공에`InAppBrowser`.\n      * `_system`: 시스템의 웹 브라우저에서 엽니다.\n\n  * **옵션**: 옵션은 `InAppBrowser` . 선택적, 디폴트에: `location=yes` . *(문자열)*\n    \n    `options`문자열 텅 빈 어떤 스페이스 포함 해서는 안 그리고 쉼표 각 기능의 이름/값 쌍을 구분 합니다. 기능 이름은 대/소문자입니다. 모든 플랫폼 지원 아래 값:\n    \n      * **위치**: 설정 `yes` 또는 `no` 설정 하는 `InAppBrowser` 의 위치 표시줄 켜거나 끕니다.\n    \n    안 드 로이드만:\n    \n      * **숨겨진**: 설정 `yes` 브라우저를 만들 페이지를 로드 하면, 하지만 그것을 보여주지. Loadstop 이벤트는 로드가 완료 되 면 발생 합니다. 생략 하거나 설정 `no` (기본값) 브라우저 열고 정상적으로 로드 해야 합니다.\n      * **clearcache**: 설정 `yes` 브라우저를 쿠키 캐시 삭제 하기 전에 새 창이 열립니다\n      * **clearsessioncache**: 설정 `yes` 세션 쿠키 캐시를 삭제 하기 전에 새 창이 열립니다\n      * **zoom/축소**: `네` 안 드 로이드 브라우저의 확대/축소 컨트롤을 표시, 그들을 숨길 수 `없는` 로 설정으로 설정. 기본값은 `네`.\n      * **hardwareback**: 하드웨어 뒤로 버튼을 사용 하 여 `InAppBrowser`의 역사를 통해 뒤로 이동 하려면 `예` 로 설정. 이전 페이지 없음이 있는 경우에, `InAppBrowser` 닫힙니다. 기본 값 이므로 `yes`, 뒤로 버튼을 간단 하 게는 InAppBrowser를 하려면 `no` 로 설정 해야 합니다.\n    \n    iOS만:\n    \n      * **closebuttoncaption**: **수행** 하는 단추의 캡션으로 사용할 문자열을 설정 합니다. 참고 직접이 값을 지역화 해야 합니다.\n      * **disallowoverscroll**: 설정 `yes` 또는 `no` (기본값은 `no` ). 회전 온/오프 UIWebViewBounce 속성입니다.\n      * **숨겨진**: 설정 `yes` 브라우저를 만들 페이지를 로드 하면, 하지만 그것을 보여주지. Loadstop 이벤트는 로드가 완료 되 면 발생 합니다. 생략 하거나 설정 `no` (기본값) 브라우저 열고 정상적으로 로드 해야 합니다.\n      * **clearcache**: 설정 `yes` 브라우저를 쿠키 캐시 삭제 하기 전에 새 창이 열립니다\n      * **clearsessioncache**: 설정 `yes` 세션 쿠키 캐시를 삭제 하기 전에 새 창이 열립니다\n      * **도구 모음**: 설정 `yes` 또는 `no` InAppBrowser (기본값:에 대 한 도구 모음 온 / 오프를 돌기 위하여`yes`)\n      * **enableViewportScale**: 설정 `yes` 또는 `no` 뷰포트 메타 태그 (기본값:를 통해 확장을 방지 하기 위해`no`).\n      * **mediaPlaybackRequiresUserAction**: 설정 `yes` 또는 `no` HTML5 오디오 또는 비디오 자동 재생 (기본값에서에서 방지 하기 위해`no`).\n      * **allowInlineMediaPlayback**: 설정 `yes` 또는 `no` 인라인 HTML5 미디어 재생, 장치 전용 재생 인터페이스 보다는 브라우저 창 내에서 표시할 수 있도록 합니다. HTML의 `video` 요소가 포함 되어야 합니다는 `webkit-playsinline` 특성 (기본값:`no`)\n      * **keyboardDisplayRequiresUserAction**: 설정 `yes` 또는 `no` 양식 요소는 자바 스크립트를 통해 포커스를 받을 때 키보드를 열고 `focus()` 전화 (기본값:`yes`).\n      * **suppressesIncrementalRendering**: 설정 `yes` 또는 `no` (기본값을 렌더링 하기 전에 모든 새로운 보기 콘텐츠를 받을 때까지 기다려야`no`).\n      * **presentationstyle**: 설정 `pagesheet` , `formsheet` 또는 `fullscreen` [프레 젠 테이 션 스타일](http://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalPresentationStyle) (기본값을 설정 하려면`fullscreen`).\n      * **transitionstyle**: 설정 `fliphorizontal` , `crossdissolve` 또는 `coververtical` [전환 스타일](http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalTransitionStyle) (기본값을 설정 하려면`coververtical`).\n      * **toolbarposition**: 설정 `top` 또는 `bottom` (기본값은 `bottom` ). 위쪽 또는 아래쪽 창에 도구 모음을 발생 합니다.\n    \n    Windows에만 해당:\n    \n      * **숨겨진**: 설정 `yes` 브라우저를 만들 페이지를 로드 하면, 하지만 그것을 보여주지. Loadstop 이벤트는 로드가 완료 되 면 발생 합니다. 생략 하거나 설정 `no` (기본값) 브라우저 열고 정상적으로 로드 해야 합니다.\n      * **fullscreen**: 주위 테두리 없이 브라우저 컨트롤을 만드는 `yes` 를 설정. 참고로 만약 **location=no** 지정, 통제 내 사 창 닫기를 사용자에 게 표시 될 것입니다.\n\n### 지원 되는 플랫폼\n\n  * 아마존 화재 운영 체제\n  * 안 드 로이드\n  * 블랙베리 10\n  * Firefox 운영 체제\n  * iOS\n  * 윈도우 8과 8.1\n  * Windows Phone 7과 8\n  * 브라우저\n\n### 예를 들어\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    var ref2 = cordova.InAppBrowser.open(encodeURI('http://ja.m.wikipedia.org/wiki/ハングル'), '_blank', 'location=yes');\n    \n\n### 파이어 폭스 OS 단점\n\n플러그인 어떤 디자인을 적용 하지 않는 경우 열 일부 CSS의 규칙을 추가할 필요가 있다 `target='_blank'`. 이 같이 규칙\n\n```css\n.inAppBrowserWrap {\n  background-color: rgba(0,0,0,0.75);\n  color: rgba(235,235,235,1.0);\n}\n.inAppBrowserWrap menu {\n  overflow: auto;\n  list-style-type: none;\n  padding-left: 0;\n}\n.inAppBrowserWrap menu li {\n  font-size: 25px;\n  height: 25px;\n  float: left;\n  margin: 0 10px;\n  padding: 3px 10px;\n  text-decoration: none;\n  color: #ccc;\n  display: block;\n  background: rgba(30,30,30,0.50);\n}\n.inAppBrowserWrap menu li.disabled {\n    color: #777;\n}\n```\n\n### 윈도우 특수\n\n파이어 폭스 OS 내 사 창 시각적 행동 비슷한 `inAppBrowserWrap`통해 재정의할 수 /`inAppBrowserWrapFullscreen` CSS 클래스\n\n### 브라우저 만지면\n\n  * 플러그인은 iframe을 통해 구현\n\n  * 탐색 기록 (LocationBar에서`뒤로` 및 `앞으로` 단추)은 구현 되지 않습니다.\n\n## InAppBrowser\n\n`Cordova에 대 한 호출에서 반환 하는 개체.InAppBrowser.open`.\n\n### 메서드\n\n  * addEventListener\n  * removeEventListener\n  * close\n  * show\n  * executeScript\n  * insertCSS\n\n## addEventListener\n\n> 이벤트에 대 한 수신기를 추가 합니다`InAppBrowser`.\n\n    ref.addEventListener(eventname, callback);\n    \n\n  * **심판**:에 대 한 참조는 `InAppBrowser` 창 *(InAppBrowser)*\n\n  * **eventname**: *(문자열)를* 수신 하도록 이벤트\n    \n      * **loadstart**: 이벤트 발생 때는 `InAppBrowser` URL 로드를 시작 합니다.\n      * **loadstop**: 이벤트가 발생 시기는 `InAppBrowser` URL 로드 완료.\n      * **loaderror**: 이벤트 발생 때는 `InAppBrowser` URL을 로드할 때 오류가 발생 합니다.\n      * **종료**: 이벤트가 발생 시기는 `InAppBrowser` 창이 닫힙니다.\n\n  * **콜백**: 이벤트가 발생 될 때 실행 되는 함수. 함수는 전달 된 `InAppBrowserEvent` 개체를 매개 변수로 합니다.\n\n### InAppBrowserEvent 속성\n\n  * **유형**: eventname, 중 `loadstart` , `loadstop` , `loaderror` , 또는 `exit` . *(문자열)*\n\n  * **url**: URL 로드 된. *(문자열)*\n\n  * **코드**: 오류 코드의 경우에만 `loaderror` . *(수)*\n\n  * **메시지**: 오류 메시지의 경우에만 `loaderror` . *(문자열)*\n\n### 지원 되는 플랫폼\n\n  * 아마존 화재 운영 체제\n  * 안 드 로이드\n  * iOS\n  * 윈도우 8과 8.1\n  * Windows Phone 7과 8\n  * 브라우저\n\n### 브라우저 만지면\n\n`loadstart` 및 `loaderror` 이벤트 해 고는 되 고.\n\n### 빠른 예제\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstart', function(event) { alert(event.url); });\n    \n\n## removeEventListener\n\n> 이벤트에 대 한 수신기를 제거 합니다`InAppBrowser`.\n\n    ref.removeEventListener(eventname, callback);\n    \n\n  * **심판**:에 대 한 참조는 `InAppBrowser` 창. *(InAppBrowser)*\n\n  * **eventname**: 이벤트 수신 대기를 중지 합니다. *(문자열)*\n    \n      * **loadstart**: 이벤트 발생 때는 `InAppBrowser` URL 로드를 시작 합니다.\n      * **loadstop**: 이벤트가 발생 시기는 `InAppBrowser` URL 로드 완료.\n      * **loaderror**: 이벤트 발생 때는 `InAppBrowser` URL 로드 오류가 발생 합니다.\n      * **종료**: 이벤트가 발생 시기는 `InAppBrowser` 창이 닫힙니다.\n\n  * **콜백**: 이벤트가 발생 하면 실행할 함수. 함수는 전달 된 `InAppBrowserEvent` 개체.\n\n### 지원 되는 플랫폼\n\n  * 아마존 화재 운영 체제\n  * 안 드 로이드\n  * iOS\n  * 윈도우 8과 8.1\n  * Windows Phone 7과 8\n  * 브라우저\n\n### 빠른 예제\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    var myCallback = function(event) { alert(event.url); }\n    ref.addEventListener('loadstart', myCallback);\n    ref.removeEventListener('loadstart', myCallback);\n    \n\n## close\n\n> 종료는 `InAppBrowser` 창.\n\n    ref.close();\n    \n\n  * **심판**:에 대 한 참조는 `InAppBrowser` 창 *(InAppBrowser)*\n\n### 지원 되는 플랫폼\n\n  * 아마존 화재 운영 체제\n  * 안 드 로이드\n  * Firefox 운영 체제\n  * iOS\n  * 윈도우 8과 8.1\n  * Windows Phone 7과 8\n  * 브라우저\n\n### 빠른 예제\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.close();\n    \n\n## show\n\n> 숨겨진 열은 한 InAppBrowser 창을 표시 합니다. 전화는 InAppBrowser가 이미 보이는 경우는 효과가 없습니다.\n\n    ref.show();\n    \n\n  * **ref**: InAppBrowser 창 (참조`InAppBrowser`)\n\n### 지원 되는 플랫폼\n\n  * 아마존 화재 운영 체제\n  * 안 드 로이드\n  * iOS\n  * 윈도우 8과 8.1\n  * 브라우저\n\n### 빠른 예제\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'hidden=yes');\n    // some time later...\n    ref.show();\n    \n\n## executeScript\n\n> 에 자바 스크립트 코드를 삽입는 `InAppBrowser` 창\n\n    ref.executeScript(details, callback);\n    \n\n  * **심판**:에 대 한 참조는 `InAppBrowser` 창. *(InAppBrowser)*\n\n  * **injectDetails**: 스크립트 실행의 세부 사항 중 하나를 지정 하는 `file` 또는 `code` 키. *(개체)*\n    \n      * **파일**: 삽입 하는 스크립트의 URL.\n      * **코드**: 스크립트 텍스트를 삽입 합니다.\n\n  * **콜백**: 자바 스크립트 코드를 주입 후 실행 기능.\n    \n      * 삽입 된 스크립트 유형의 경우 `code` , 스크립트의 반환 값은 단일 매개 변수는 콜백 실행에 싸여 있는 `Array` . 여러 줄 스크립트에 대 한 마지막 문 또는 평가 마지막 식의 반환 값입니다.\n\n### 지원 되는 플랫폼\n\n  * 아마존 화재 운영 체제\n  * 안 드 로이드\n  * iOS\n  * 윈도우 8과 8.1\n  * 브라우저\n\n### 빠른 예제\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstop', function() {\n        ref.executeScript({file: \"myscript.js\"});\n    });\n    \n\n### 브라우저 만지면\n\n  * **code** 키만 지원 됩니다.\n\n### 윈도우 특수\n\n[MSDN 문서](https://msdn.microsoft.com/en-us/library/windows.ui.xaml.controls.webview.invokescriptasync.aspx) 인해 호출된 스크립트 반환할 수 있습니다 문자열 값만 그렇지 않으면 매개 변수, **콜백** 전달 `[null]` 될 것입니다..\n\n## insertCSS\n\n> 주사로 CSS는 `InAppBrowser` 창.\n\n    ref.insertCSS(details, callback);\n    \n\n  * **심판**:에 대 한 참조는 `InAppBrowser` 창 *(InAppBrowser)*\n\n  * **injectDetails**: 스크립트 실행의 세부 사항 중 하나를 지정 하는 `file` 또는 `code` 키. *(개체)*\n    \n      * **파일**: 삽입 하는 스타일 시트의 URL.\n      * **코드**: 삽입 하는 스타일 시트의 텍스트.\n\n  * **콜백**: CSS 주입 후 실행 기능.\n\n### 지원 되는 플랫폼\n\n  * 아마존 화재 운영 체제\n  * 안 드 로이드\n  * iOS\n  * 윈도우\n\n### 빠른 예제\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstop', function() {\n        ref.insertCSS({file: \"mystyles.css\"});\n    });"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/doc/ko/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-inappbrowser\n\n이 플러그인 `코르도바를 호출할 때 표시 하는 웹 브라우저 보기를 제공 합니다.InAppBrowser.open()`.\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    \n\n`코르도바입니다.InAppBrowser.open()` 함수 `window.open ()` 함수에 대 한 대체품 정의 됩니다. 기존의 `window.open ()` 호출 window.open을 대체 하 여 InAppBrowser 윈도우를 사용할 수 있습니다.\n\n    window.open = cordova.InAppBrowser.open;\n    \n\nInAppBrowser 창 표준 웹 브라우저 처럼 동작 및 코르도바 Api에 액세스할 수 없습니다. 이 이유는 InAppBrowser는 것이 좋습니다는 주요 코르도바 webview로 로드 하는 대신 제 3 자 (신뢰할 수 없는) 콘텐츠를 로드 해야 할 경우. InAppBrowser는 허용 될 수도 시스템 브라우저에서 링크를 여는.\n\n사용자에 대 한 자체 GUI 컨트롤에서 기본적으로 제공 된 InAppBrowser (뒤로, 앞으로, 완료).\n\n대 한 뒤 호환성,이 플러그인도 `window.open` 후크. 그러나, `window.open`의 플러그인 설치 후크를 가질 수 있습니다 의도 하지 않은 부작용 (특히 경우이 플러그인이 다른 플러그인 종속성 으로만 포함). `window.open` 후크 주요 릴리스에서 제거 됩니다. 후크 플러그인에서 제거 될 때까지 애플 리 케이 션 수 있습니다 수동으로 기본 동작을 복원 하 게 됩니다.\n\n    delete window.open // Reverts the call back to it's prototype's default\n    \n\n`window.open` 전역 범위에 있지만 InAppBrowser 제공 되지 않습니다 때까지 `deviceready` 이벤트 후.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(\"window.open works well\");\n    }\n    \n\n## 설치\n\n    cordova plugin add cordova-plugin-inappbrowser\n    \n\nInAppBrowser를 통해가 서 당신의 애플 리 케이 션에서 모든 페이지를 로드 하려는 경우 초기화 하는 동안 `window.open` 간단 하 게 연결할 수 있습니다. 예를 들어:\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        window.open = cordova.InAppBrowser.open;\n    }\n    \n\n## cordova.InAppBrowser.open\n\n새 `InAppBrowser` 인스턴스, 현재 브라우저 인스턴스 또는 시스템 브라우저에서 URL을 엽니다.\n\n    var ref = cordova.InAppBrowser.open(url, target, options);\n    \n\n*   **심판**:에 대 한 참조는 `InAppBrowser` 창. *(InAppBrowser)*\n\n*   **url**: *(문자열)를*로드 하는 URL. 전화 `encodeURI()` 이 경우에는 URL 유니코드 문자를 포함 합니다.\n\n*   **대상**: 대상 URL, 기본적으로 선택적 매개 변수를 로드 하는 `_self` . *(문자열)*\n    \n    *   `_self`: URL 화이트 리스트에 있으면 코르도바 WebView에서 열리고, 그렇지 않으면 열에`InAppBrowser`.\n    *   `_blank`: 준공에`InAppBrowser`.\n    *   `_system`: 시스템의 웹 브라우저에서 엽니다.\n\n*   **옵션**: 옵션은 `InAppBrowser` . 선택적, 디폴트에: `location=yes` . *(문자열)*\n    \n    `options`문자열 텅 빈 어떤 스페이스 포함 해서는 안 그리고 쉼표 각 기능의 이름/값 쌍을 구분 합니다. 기능 이름은 대/소문자입니다. 모든 플랫폼 지원 아래 값:\n    \n    *   **위치**: 설정 `yes` 또는 `no` 설정 하는 `InAppBrowser` 의 위치 표시줄 켜거나 끕니다.\n    \n    안 드 로이드만:\n    \n    *   **숨겨진**: 설정 `yes` 브라우저를 만들 페이지를 로드 하면, 하지만 그것을 보여주지. Loadstop 이벤트는 로드가 완료 되 면 발생 합니다. 생략 하거나 설정 `no` (기본값) 브라우저 열고 정상적으로 로드 해야 합니다.\n    *   **clearcache**: 설정 `yes` 브라우저를 쿠키 캐시 삭제 하기 전에 새 창이 열립니다\n    *   **clearsessioncache**: 설정 `yes` 세션 쿠키 캐시를 삭제 하기 전에 새 창이 열립니다\n    \n    iOS만:\n    \n    *   **closebuttoncaption**: **수행** 하는 단추의 캡션으로 사용할 문자열을 설정 합니다. 참고 직접이 값을 지역화 해야 합니다.\n    *   **disallowoverscroll**: 설정 `yes` 또는 `no` (기본값은 `no` ). 회전 온/오프 UIWebViewBounce 속성입니다.\n    *   **숨겨진**: 설정 `yes` 브라우저를 만들 페이지를 로드 하면, 하지만 그것을 보여주지. Loadstop 이벤트는 로드가 완료 되 면 발생 합니다. 생략 하거나 설정 `no` (기본값) 브라우저 열고 정상적으로 로드 해야 합니다.\n    *   **clearcache**: 설정 `yes` 브라우저를 쿠키 캐시 삭제 하기 전에 새 창이 열립니다\n    *   **clearsessioncache**: 설정 `yes` 세션 쿠키 캐시를 삭제 하기 전에 새 창이 열립니다\n    *   **도구 모음**: 설정 `yes` 또는 `no` InAppBrowser (기본값:에 대 한 도구 모음 온 / 오프를 돌기 위하여`yes`)\n    *   **enableViewportScale**: 설정 `yes` 또는 `no` 뷰포트 메타 태그 (기본값:를 통해 확장을 방지 하기 위해`no`).\n    *   **mediaPlaybackRequiresUserAction**: 설정 `yes` 또는 `no` HTML5 오디오 또는 비디오 자동 재생 (기본값에서에서 방지 하기 위해`no`).\n    *   **allowInlineMediaPlayback**: 설정 `yes` 또는 `no` 인라인 HTML5 미디어 재생, 장치 전용 재생 인터페이스 보다는 브라우저 창 내에서 표시할 수 있도록 합니다. HTML의 `video` 요소가 포함 되어야 합니다는 `webkit-playsinline` 특성 (기본값:`no`)\n    *   **keyboardDisplayRequiresUserAction**: 설정 `yes` 또는 `no` 양식 요소는 자바 스크립트를 통해 포커스를 받을 때 키보드를 열고 `focus()` 전화 (기본값:`yes`).\n    *   **suppressesIncrementalRendering**: 설정 `yes` 또는 `no` (기본값을 렌더링 하기 전에 모든 새로운 보기 콘텐츠를 받을 때까지 기다려야`no`).\n    *   **presentationstyle**: 설정 `pagesheet` , `formsheet` 또는 `fullscreen` [프레 젠 테이 션 스타일][1] (기본값을 설정 하려면`fullscreen`).\n    *   **transitionstyle**: 설정 `fliphorizontal` , `crossdissolve` 또는 `coververtical` [전환 스타일][2] (기본값을 설정 하려면`coververtical`).\n    *   **toolbarposition**: 설정 `top` 또는 `bottom` (기본값은 `bottom` ). 위쪽 또는 아래쪽 창에 도구 모음을 발생 합니다.\n    \n    Windows에만 해당:\n    \n    *   **숨겨진**: 설정 `yes` 브라우저를 만들 페이지를 로드 하면, 하지만 그것을 보여주지. Loadstop 이벤트는 로드가 완료 되 면 발생 합니다. 생략 하거나 설정 `no` (기본값) 브라우저 열고 정상적으로 로드 해야 합니다.\n\n [1]: http://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalPresentationStyle\n [2]: http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalTransitionStyle\n\n### 지원 되는 플랫폼\n\n*   아마존 화재 운영 체제\n*   안 드 로이드\n*   블랙베리 10\n*   Firefox 운영 체제\n*   iOS\n*   윈도우 8과 8.1\n*   Windows Phone 7과 8\n\n### 예를 들어\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    var ref2 = cordova.InAppBrowser.open(encodeURI('http://ja.m.wikipedia.org/wiki/ハングル'), '_blank', 'location=yes');\n    \n\n### 파이어 폭스 OS 단점\n\n플러그인 어떤 디자인을 적용 하지 않는 경우 열 일부 CSS의 규칙을 추가할 필요가 있다 `target='_blank'`. 이 같이 규칙\n\n     css\n    .inAppBrowserWrap {\n      background-color: rgba(0,0,0,0.75);\n      color: rgba(235,235,235,1.0);\n    }\n    .inAppBrowserWrap menu {\n      overflow: auto;\n      list-style-type: none;\n      padding-left: 0;\n    }\n    .inAppBrowserWrap menu li {\n      font-size: 25px;\n      height: 25px;\n      float: left;\n      margin: 0 10px;\n      padding: 3px 10px;\n      text-decoration: none;\n      color: #ccc;\n      display: block;\n      background: rgba(30,30,30,0.50);\n    }\n    .inAppBrowserWrap menu li.disabled {\n        color: #777;\n    }\n    \n\n## InAppBrowser\n\n`Cordova에 대 한 호출에서 반환 하는 개체.InAppBrowser.open`.\n\n### 메서드\n\n*   addEventListener\n*   removeEventListener\n*   close\n*   show\n*   executeScript\n*   insertCSS\n\n## addEventListener\n\n> 이벤트에 대 한 수신기를 추가 합니다`InAppBrowser`.\n\n    ref.addEventListener(eventname, callback);\n    \n\n*   **심판**:에 대 한 참조는 `InAppBrowser` 창 *(InAppBrowser)*\n\n*   **eventname**: *(문자열)를* 수신 하도록 이벤트\n    \n    *   **loadstart**: 이벤트 발생 때는 `InAppBrowser` URL 로드를 시작 합니다.\n    *   **loadstop**: 이벤트가 발생 시기는 `InAppBrowser` URL 로드 완료.\n    *   **loaderror**: 이벤트 발생 때는 `InAppBrowser` URL을 로드할 때 오류가 발생 합니다.\n    *   **종료**: 이벤트가 발생 시기는 `InAppBrowser` 창이 닫힙니다.\n\n*   **콜백**: 이벤트가 발생 될 때 실행 되는 함수. 함수는 전달 된 `InAppBrowserEvent` 개체를 매개 변수로 합니다.\n\n### InAppBrowserEvent 속성\n\n*   **유형**: eventname, 중 `loadstart` , `loadstop` , `loaderror` , 또는 `exit` . *(문자열)*\n\n*   **url**: URL 로드 된. *(문자열)*\n\n*   **코드**: 오류 코드의 경우에만 `loaderror` . *(수)*\n\n*   **메시지**: 오류 메시지의 경우에만 `loaderror` . *(문자열)*\n\n### 지원 되는 플랫폼\n\n*   아마존 화재 운영 체제\n*   안 드 로이드\n*   iOS\n*   윈도우 8과 8.1\n*   Windows Phone 7과 8\n\n### 빠른 예제\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstart', function(event) { alert(event.url); });\n    \n\n## removeEventListener\n\n> 이벤트에 대 한 수신기를 제거 합니다`InAppBrowser`.\n\n    ref.removeEventListener(eventname, callback);\n    \n\n*   **심판**:에 대 한 참조는 `InAppBrowser` 창. *(InAppBrowser)*\n\n*   **eventname**: 이벤트 수신 대기를 중지 합니다. *(문자열)*\n    \n    *   **loadstart**: 이벤트 발생 때는 `InAppBrowser` URL 로드를 시작 합니다.\n    *   **loadstop**: 이벤트가 발생 시기는 `InAppBrowser` URL 로드 완료.\n    *   **loaderror**: 이벤트 발생 때는 `InAppBrowser` URL 로드 오류가 발생 합니다.\n    *   **종료**: 이벤트가 발생 시기는 `InAppBrowser` 창이 닫힙니다.\n\n*   **콜백**: 이벤트가 발생 하면 실행할 함수. 함수는 전달 된 `InAppBrowserEvent` 개체.\n\n### 지원 되는 플랫폼\n\n*   아마존 화재 운영 체제\n*   안 드 로이드\n*   iOS\n*   윈도우 8과 8.1\n*   Windows Phone 7과 8\n\n### 빠른 예제\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    var myCallback = function(event) { alert(event.url); }\n    ref.addEventListener('loadstart', myCallback);\n    ref.removeEventListener('loadstart', myCallback);\n    \n\n## close\n\n> 종료는 `InAppBrowser` 창.\n\n    ref.close();\n    \n\n*   **심판**:에 대 한 참조는 `InAppBrowser` 창 *(InAppBrowser)*\n\n### 지원 되는 플랫폼\n\n*   아마존 화재 운영 체제\n*   안 드 로이드\n*   Firefox 운영 체제\n*   iOS\n*   윈도우 8과 8.1\n*   Windows Phone 7과 8\n\n### 빠른 예제\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.close();\n    \n\n## show\n\n> 숨겨진 열은 한 InAppBrowser 창을 표시 합니다. 전화는 InAppBrowser가 이미 보이는 경우는 효과가 없습니다.\n\n    ref.show();\n    \n\n*   **ref**: InAppBrowser 창 (참조`InAppBrowser`)\n\n### 지원 되는 플랫폼\n\n*   아마존 화재 운영 체제\n*   안 드 로이드\n*   iOS\n*   윈도우 8과 8.1\n\n### 빠른 예제\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'hidden=yes');\n    // some time later...\n    ref.show();\n    \n\n## executeScript\n\n> 에 자바 스크립트 코드를 삽입는 `InAppBrowser` 창\n\n    ref.executeScript(details, callback);\n    \n\n*   **심판**:에 대 한 참조는 `InAppBrowser` 창. *(InAppBrowser)*\n\n*   **injectDetails**: 스크립트 실행의 세부 사항 중 하나를 지정 하는 `file` 또는 `code` 키. *(개체)*\n    \n    *   **파일**: 삽입 하는 스크립트의 URL.\n    *   **코드**: 스크립트 텍스트를 삽입 합니다.\n\n*   **콜백**: 자바 스크립트 코드를 주입 후 실행 기능.\n    \n    *   삽입 된 스크립트 유형의 경우 `code` , 스크립트의 반환 값은 단일 매개 변수는 콜백 실행에 싸여 있는 `Array` . 여러 줄 스크립트에 대 한 마지막 문 또는 평가 마지막 식의 반환 값입니다.\n\n### 지원 되는 플랫폼\n\n*   아마존 화재 운영 체제\n*   안 드 로이드\n*   iOS\n*   윈도우 8과 8.1\n\n### 빠른 예제\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstop', function() {\n        ref.executeScript({file: \"myscript.js\"});\n    });\n    \n\n## insertCSS\n\n> 주사로 CSS는 `InAppBrowser` 창.\n\n    ref.insertCSS(details, callback);\n    \n\n*   **심판**:에 대 한 참조는 `InAppBrowser` 창 *(InAppBrowser)*\n\n*   **injectDetails**: 스크립트 실행의 세부 사항 중 하나를 지정 하는 `file` 또는 `code` 키. *(개체)*\n    \n    *   **파일**: 삽입 하는 스타일 시트의 URL.\n    *   **코드**: 삽입 하는 스타일 시트의 텍스트.\n\n*   **콜백**: CSS 주입 후 실행 기능.\n\n### 지원 되는 플랫폼\n\n*   아마존 화재 운영 체제\n*   안 드 로이드\n*   iOS\n\n### 빠른 예제\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstop', function() {\n        ref.insertCSS({file: \"mystyles.css\"});\n    });\n"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/doc/pl/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-inappbrowser\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-inappbrowser.svg)](https://travis-ci.org/apache/cordova-plugin-inappbrowser)\n\nPlugin daje widok przeglądarki sieci web, które są wyświetlane podczas wywoływania `cordova.InAppBrowser.open()`.\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    \n\n`cordova.InAppBrowser.open()` funkcja jest definiowana jako zamiennik dla funkcji `window.open()`. Istniejące wywołania `window.open()` służy okno InAppBrowser, zastępując window.open:\n\n    window.open = cordova.InAppBrowser.open;\n    \n\nOkna InAppBrowser zachowuje się jak standardowe przeglądarki i nie ma dostępu do API Cordova. Z tego powodu zaleca się InAppBrowser jeśli ty potrzebować wobec ciężar (niezaufanej) treści osób trzecich, a nie że wczytywanie głównym webview Cordova. InAppBrowser nie jest biała, ani nie jest otwieranie linków w przeglądarce systemu.\n\nInAppBrowser zawiera domyślnie kontrole GUI dla użytkownika (tył, przód, zrobić).\n\nDo tyłu zgodności, ten plugin również haki `window.open`. Jednak może mieć zainstalowane wtyczki haka `window.open` niezamierzone skutki uboczne (zwłaszcza, jeśli ten plugin jest włączone tylko jako część innej wtyczki). Hak `window.open` zostaną usunięte w przyszłej wersji głównych. Dopóki hak jest usuwany z wtyczki, aplikacje można ręcznie przywrócić domyślne zachowanie:\n\n    delete window.open // Reverts the call back to it's prototype's default\n    \n\nChociaż `window.open` w globalnym zasięgu, InAppBrowser nie jest dostępne dopiero po zdarzeniu `deviceready`.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(\"window.open works well\");\n    }\n    \n\n## Instalacja\n\n    cordova plugin add cordova-plugin-inappbrowser\n    \n\nJeśli chcesz wszystko stronica ładunki w swojej aplikacji, aby przejść przez InAppBrowser, można po prostu podłączyć `window.open` podczas inicjowania. Na przykład:\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        window.open = cordova.InAppBrowser.open;\n    }\n    \n\n## cordova.InAppBrowser.open\n\nOtwiera URL w nowe wystąpienie `InAppBrowser`, bieżące wystąpienie przeglądarki lub przeglądarki systemu.\n\n    var ref = cordova.InAppBrowser.open(url, target, options);\n    \n\n  * **ref**: odniesienie do `InAppBrowser` okna. *(InAppBrowser)*\n\n  * **adres**: adres URL do ładowania *(ciąg)*. Wywołanie `encodeURI()` na to, czy adres URL zawiera znaki Unicode.\n\n  * **miejsce docelowe**: miejsce docelowe, w którym wobec ciężar ten URL parametr opcjonalny, który domyślnie `_self` . *(String)*\n    \n      * `_self`: Otwiera w Cordova WebView, jeśli adres URL jest na białej liście, inaczej ono otwiera w`InAppBrowser`.\n      * `_blank`: Otwiera w`InAppBrowser`.\n      * `_system`: Otwiera w przeglądarce internetowej systemu.\n\n  * **Opcje**: opcje dla `InAppBrowser` . Opcjonalnie, nie stawiła się: `location=yes` . *(String)*\n    \n    `options`Ciąg nie może zawierać żadnych spacji, i pary nazwa/wartość każdej funkcji muszą być oddzielone przecinkami. Nazwy funkcji jest rozróżniana. Wszystkich platform obsługuje wartości poniżej:\n    \n      * **Lokalizacja**: zestaw `yes` lub `no` Aby włączyć `InAppBrowser` na pasek lub wyłączyć.\n    \n    Android:\n    \n      * **ukryte**: zestaw `yes` do stworzenia przeglądarki i ładowania strony, ale nie pokazuje go. Loadstop zdarzenie fires po zakończeniu ładowania. Pominąć lub zestaw `no` (domyślnie) do przeglądarki otworzyć i załadować normalnie.\n      * **ClearCache**: zestaw `yes` do przeglądarki w pamięci podręcznej plików cookie wyczyszczone zanim otworzy się nowe okno\n      * **clearsessioncache**: zestaw `yes` mieć w pamięci podręcznej plików cookie sesji wyczyszczone zanim otworzy się nowe okno\n      * **zoom**: `yes` aby pokazać formantami powiększania Android przeglądarka, ustawiona na `nie` aby je ukryć. Wartość domyślna to `tak`.\n      * **hardwareback**: zestaw do `yes` , aby użyć przycisk Wstecz sprzętu do nawigacji wstecz historii `InAppBrowser`. Jeśli nie ma żadnej poprzedniej strony, `InAppBrowser` zostanie zamknięta. Wartością domyślną jest `yes`, więc należy ustawić ją na `no` jeśli chcesz przycisk Wstecz, aby po prostu zamknąć InAppBrowser.\n    \n    tylko iOS:\n    \n      * **closebuttoncaption**: aby użyć jak **zrobić** przycisk Podpis ustawiona na ciąg. Należy pamiętać, że trzeba zlokalizować tę wartość siebie.\n      * **disallowoverscroll**: zestaw `yes` lub `no` (domyślnie `no` ). Włącza/wyłącza właściwość UIWebViewBounce.\n      * **ukryte**: zestaw `yes` do stworzenia przeglądarki i ładowania strony, ale nie pokazuje go. Loadstop zdarzenie fires po zakończeniu ładowania. Pominąć lub zestaw `no` (domyślnie) do przeglądarki otworzyć i załadować normalnie.\n      * **ClearCache**: zestaw `yes` do przeglądarki w pamięci podręcznej plików cookie wyczyszczone zanim otworzy się nowe okno\n      * **clearsessioncache**: zestaw `yes` mieć w pamięci podręcznej plików cookie sesji wyczyszczone zanim otworzy się nowe okno\n      * **pasek narzędzi**: zestaw `yes` lub `no` Aby włączyć pasek narzędzi lub wyłączyć dla InAppBrowser (domyślnie`yes`)\n      * **enableViewportScale**: zestaw `yes` lub `no` Aby zapobiec rzutni skalowanie za pomocą tagu meta (domyślnie`no`).\n      * **mediaPlaybackRequiresUserAction**: zestaw `yes` lub `no` Aby zapobiec HTML5 audio lub wideo z Autoodtwarzanie (domyślnie`no`).\n      * **allowInlineMediaPlayback**: zestaw `yes` lub `no` Aby w linii HTML5 odtwarzanie, wyświetlanie w oknie przeglądarki, a nie interfejs odtwarzanie specyficzne dla urządzenia. HTML `video` również musi zawierać element `webkit-playsinline` atrybut (domyślnie`no`)\n      * **keyboardDisplayRequiresUserAction**: zestaw `yes` lub `no` Aby otworzyć klawiaturę ekranową, gdy elementy formularza ostrości za pomocą JavaScript `focus()` połączenia (domyślnie`yes`).\n      * **suppressesIncrementalRendering**: zestaw `yes` lub `no` czekać, aż wszystkie nowe widok zawartości jest otrzymane przed renderowany (domyślnie`no`).\n      * **presentationstyle**: zestaw `pagesheet` , `formsheet` lub `fullscreen` Aby ustawić [styl prezentacji](http://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalPresentationStyle) (domyślnie`fullscreen`).\n      * **transitionstyle**: zestaw `fliphorizontal` , `crossdissolve` lub `coververtical` Aby ustawić [styl przejścia](http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalTransitionStyle) (domyślnie`coververtical`).\n      * **toolbarposition**: zestaw `top` lub `bottom` (domyślnie `bottom` ). Powoduje, że pasek ma być na górze lub na dole okna.\n    \n    Windows tylko:\n    \n      * **ukryte**: zestaw `yes` do stworzenia przeglądarki i ładowania strony, ale nie pokazuje go. Loadstop zdarzenie fires po zakończeniu ładowania. Pominąć lub zestaw `no` (domyślnie) do przeglądarki otworzyć i załadować normalnie.\n      * **fullscreen**: zestaw do `yes` , aby utworzyć formant przeglądarki bez obramowania wokół niego. Należy pamiętać, że jeśli **location=no** również jest określony, nie będzie żadnej kontroli przedstawione do użytkownika, aby zamknąć okno IAB.\n\n### Obsługiwane platformy\n\n  * Amazon Fire OS\n  * Android\n  * BlackBerry 10\n  * Firefox OS\n  * iOS\n  * Windows 8 i 8.1\n  * Windows Phone 7 i 8\n  * Przeglądarka\n\n### Przykład\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    var ref2 = cordova.InAppBrowser.open(encodeURI('http://ja.m.wikipedia.org/wiki/ハングル'), '_blank', 'location=yes');\n    \n\n### Firefox OS dziwactwa\n\nJak plugin nie wymuszać każdy projekt to trzeba dodać pewne reguły CSS jeśli otwarty z `target = \"_blank\"`. Zasady może wyglądać jak te\n\n```css\n.inAppBrowserWrap {\n  background-color: rgba(0,0,0,0.75);\n  color: rgba(235,235,235,1.0);\n}\n.inAppBrowserWrap menu {\n  overflow: auto;\n  list-style-type: none;\n  padding-left: 0;\n}\n.inAppBrowserWrap menu li {\n  font-size: 25px;\n  height: 25px;\n  float: left;\n  margin: 0 10px;\n  padding: 3px 10px;\n  text-decoration: none;\n  color: #ccc;\n  display: block;\n  background: rgba(30,30,30,0.50);\n}\n.inAppBrowserWrap menu li.disabled {\n    color: #777;\n}\n```\n\n### Windows dziwactwa\n\nPodobne do Firefox OS IAB okno wizualne zachowanie może być zastąpiona przez `inAppBrowserWrap`/`inAppBrowserWrapFullscreen` klas CSS\n\n### Quirks przeglądarki\n\n  * Plugin jest realizowane za pośrednictwem iframe,\n\n  * Historia nawigacji (przyciski`wstecz` i `do przodu` w LocationBar) nie jest zaimplementowana.\n\n## InAppBrowser\n\nObiekt zwrócony z wywołania `cordova.InAppBrowser.open`.\n\n### Metody\n\n  * metody addEventListener\n  * removeEventListener\n  * Zamknij\n  * Pokaż\n  * executeScript\n  * insertCSS\n\n## metody addEventListener\n\n> Dodaje detektor zdarzenia z`InAppBrowser`.\n\n    ref.addEventListener(eventname, callback);\n    \n\n  * **ref**: odniesienie do `InAppBrowser` okna *(InAppBrowser)*\n\n  * **EventName**: zdarzenie słuchać *(String)*\n    \n      * **loadstart**: zdarzenie gdy odpalam `InAppBrowser` zaczyna się ładować adresu URL.\n      * **loadstop**: zdarzenie gdy odpalam `InAppBrowser` zakończeniu ładowania adresu URL.\n      * **LoadError**: zdarzenie odpala gdy `InAppBrowser` napotka błąd podczas ładowania adresu URL.\n      * **wyjście**: zdarzenie gdy odpalam `InAppBrowser` okno jest zamknięte.\n\n  * **wywołania zwrotnego**: funkcja, która wykonuje, gdy zdarzenie. Funkcja jest przekazywany `InAppBrowserEvent` obiektu jako parametr.\n\n### Właściwości InAppBrowserEvent\n\n  * **Typ**: eventname, albo `loadstart` , `loadstop` , `loaderror` , lub `exit` . *(String)*\n\n  * **adres**: adres URL, który został załadowany. *(String)*\n\n  * **Kod**: kod błędu, tylko w przypadku `loaderror` . *(Liczba)*\n\n  * **wiadomość**: komunikat o błędzie, tylko w przypadku `loaderror` . *(String)*\n\n### Obsługiwane platformy\n\n  * Amazon Fire OS\n  * Android\n  * iOS\n  * Windows 8 i 8.1\n  * Windows Phone 7 i 8\n  * Przeglądarka\n\n### Quirks przeglądarki\n\nwydarzenia `loadstart` i `loaderror` nie są być opalane.\n\n### Szybki przykład\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstart', function(event) { alert(event.url); });\n    \n\n## removeEventListener\n\n> Usuwa detektor zdarzenia z`InAppBrowser`.\n\n    ref.removeEventListener(eventname, callback);\n    \n\n  * **ref**: odniesienie do `InAppBrowser` okna. *(InAppBrowser)*\n\n  * **EventName**: zdarzenie przestanie słuchać. *(String)*\n    \n      * **loadstart**: zdarzenie gdy odpalam `InAppBrowser` zaczyna się ładować adresu URL.\n      * **loadstop**: zdarzenie gdy odpalam `InAppBrowser` zakończeniu ładowania adresu URL.\n      * **LoadError**: zdarzenie odpala gdy `InAppBrowser` napotka błąd ładowania adresu URL.\n      * **wyjście**: zdarzenie gdy odpalam `InAppBrowser` okno jest zamknięte.\n\n  * **wywołania zwrotnego**: funkcja do wykonania, gdy zdarzenie. Funkcja jest przekazywany `InAppBrowserEvent` obiektu.\n\n### Obsługiwane platformy\n\n  * Amazon Fire OS\n  * Android\n  * iOS\n  * Windows 8 i 8.1\n  * Windows Phone 7 i 8\n  * Przeglądarka\n\n### Szybki przykład\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    var myCallback = function(event) { alert(event.url); }\n    ref.addEventListener('loadstart', myCallback);\n    ref.removeEventListener('loadstart', myCallback);\n    \n\n## Zamknij\n\n> Zamyka `InAppBrowser` okna.\n\n    ref.close();\n    \n\n  * **ref**: odniesienie do `InAppBrowser` okna *(InAppBrowser)*\n\n### Obsługiwane platformy\n\n  * Amazon Fire OS\n  * Android\n  * Firefox OS\n  * iOS\n  * Windows 8 i 8.1\n  * Windows Phone 7 i 8\n  * Przeglądarka\n\n### Szybki przykład\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.close();\n    \n\n## Pokaż\n\n> Wyświetla InAppBrowser okno, który został otwarty ukryte. Zawód ten jest ignorowany, jeśli InAppBrowser już był widoczny.\n\n    ref.show();\n    \n\n  * **ref**: odwołanie do InAppBrowser (okno`InAppBrowser`)\n\n### Obsługiwane platformy\n\n  * Amazon Fire OS\n  * Android\n  * iOS\n  * Windows 8 i 8.1\n  * Przeglądarka\n\n### Szybki przykład\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'hidden=yes');\n    // some time later...\n    ref.show();\n    \n\n## executeScript\n\n> Wstrzykuje kod JavaScript w `InAppBrowser` okna\n\n    ref.executeScript(details, callback);\n    \n\n  * **ref**: odniesienie do `InAppBrowser` okna. *(InAppBrowser)*\n\n  * **injectDetails**: Szczegóły dotyczące skryptu, określając albo `file` lub `code` klucz. *(Obiekt)*\n    \n      * **plik**: adres URL skryptu, aby wstrzyknąć.\n      * **Kod**: tekst skryptu, aby wstrzyknąć.\n\n  * **wywołania zwrotnego**: funkcja, która wykonuje po kod JavaScript jest wstrzykiwany.\n    \n      * Jeśli taki skrypt jest typu `code` , wykonuje wywołanie zwrotne z pojedynczym parametrem, który jest wartość zwracana przez skrypt, owinięte w `Array` . Dla wielu linii skrypty to wartość zwracana ostatniej instrukcja, lub ostatni wyrażenie oceniane.\n\n### Obsługiwane platformy\n\n  * Amazon Fire OS\n  * Android\n  * iOS\n  * Windows 8 i 8.1\n  * Przeglądarka\n\n### Szybki przykład\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstop', function() {\n        ref.executeScript({file: \"myscript.js\"});\n    });\n    \n\n### Quirks przeglądarki\n\n  * obsługiwany jest tylko **code** klucza.\n\n### Windows dziwactwa\n\nZe względu na [MSDN dokumenty](https://msdn.microsoft.com/en-us/library/windows.ui.xaml.controls.webview.invokescriptasync.aspx) wywołany skrypt może zwracać tylko wartości ciągów, inaczej parametr, przekazywany do **wywołania zwrotnego** będzie `[null]`.\n\n## insertCSS\n\n> Wstrzykuje CSS w `InAppBrowser` okna.\n\n    ref.insertCSS(details, callback);\n    \n\n  * **ref**: odniesienie do `InAppBrowser` okna *(InAppBrowser)*\n\n  * **injectDetails**: Szczegóły dotyczące skryptu, określając albo `file` lub `code` klucz. *(Obiekt)*\n    \n      * **plik**: URL arkusza stylów do wsuwania.\n      * **Kod**: tekst z arkusza stylów do wstrzykiwania.\n\n  * **wywołania zwrotnego**: funkcja, która wykonuje po CSS jest wstrzykiwany.\n\n### Obsługiwane platformy\n\n  * Amazon Fire OS\n  * Android\n  * iOS\n  * Windows\n\n### Szybki przykład\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstop', function() {\n        ref.insertCSS({file: \"mystyles.css\"});\n    });"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/doc/pl/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-inappbrowser\n\nPlugin daje widok przeglądarki sieci web, które są wyświetlane podczas wywoływania `cordova.InAppBrowser.open()`.\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    \n\n`cordova.InAppBrowser.open()` funkcja jest definiowana jako zamiennik dla funkcji `window.open()`. Istniejące wywołania `window.open()` służy okno InAppBrowser, zastępując window.open:\n\n    window.open = cordova.InAppBrowser.open;\n    \n\nOkna InAppBrowser zachowuje się jak standardowe przeglądarki i nie ma dostępu do API Cordova. Z tego powodu zaleca się InAppBrowser jeśli ty potrzebować wobec ciężar (niezaufanej) treści osób trzecich, a nie że wczytywanie głównym webview Cordova. InAppBrowser nie jest biała, ani nie jest otwieranie linków w przeglądarce systemu.\n\nInAppBrowser zawiera domyślnie kontrole GUI dla użytkownika (tył, przód, zrobić).\n\nDo tyłu zgodności, ten plugin również haki `window.open`. Jednak może mieć zainstalowane wtyczki haka `window.open` niezamierzone skutki uboczne (zwłaszcza, jeśli ten plugin jest włączone tylko jako część innej wtyczki). Hak `window.open` zostaną usunięte w przyszłej wersji głównych. Dopóki hak jest usuwany z wtyczki, aplikacje można ręcznie przywrócić domyślne zachowanie:\n\n    delete window.open // Reverts the call back to it's prototype's default\n    \n\nChociaż `window.open` w globalnym zasięgu, InAppBrowser nie jest dostępne dopiero po zdarzeniu `deviceready`.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(\"window.open works well\");\n    }\n    \n\n## Instalacja\n\n    cordova plugin add cordova-plugin-inappbrowser\n    \n\nJeśli chcesz wszystko stronica ładunki w swojej aplikacji, aby przejść przez InAppBrowser, można po prostu podłączyć `window.open` podczas inicjowania. Na przykład:\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        window.open = cordova.InAppBrowser.open;\n    }\n    \n\n## cordova.InAppBrowser.open\n\nOtwiera URL w nowe wystąpienie `InAppBrowser`, bieżące wystąpienie przeglądarki lub przeglądarki systemu.\n\n    var ref = cordova.InAppBrowser.open(url, target, options);\n    \n\n*   **ref**: odniesienie do `InAppBrowser` okna. *(InAppBrowser)*\n\n*   **adres**: adres URL do ładowania *(ciąg)*. Wywołanie `encodeURI()` na to, czy adres URL zawiera znaki Unicode.\n\n*   **miejsce docelowe**: miejsce docelowe, w którym wobec ciężar ten URL parametr opcjonalny, który domyślnie `_self` . *(String)*\n    \n    *   `_self`: Otwiera w Cordova WebView, jeśli adres URL jest na białej liście, inaczej ono otwiera w`InAppBrowser`.\n    *   `_blank`: Otwiera w`InAppBrowser`.\n    *   `_system`: Otwiera w przeglądarce internetowej systemu.\n\n*   **Opcje**: opcje dla `InAppBrowser` . Opcjonalnie, nie stawiła się: `location=yes` . *(String)*\n    \n    `options`Ciąg nie może zawierać żadnych spacji, i pary nazwa/wartość każdej funkcji muszą być oddzielone przecinkami. Nazwy funkcji jest rozróżniana. Wszystkich platform obsługuje wartości poniżej:\n    \n    *   **Lokalizacja**: zestaw `yes` lub `no` Aby włączyć `InAppBrowser` na pasek lub wyłączyć.\n    \n    Android:\n    \n    *   **ukryte**: zestaw `yes` do stworzenia przeglądarki i ładowania strony, ale nie pokazuje go. Loadstop zdarzenie fires po zakończeniu ładowania. Pominąć lub zestaw `no` (domyślnie) do przeglądarki otworzyć i załadować normalnie.\n    *   **ClearCache**: zestaw `yes` do przeglądarki w pamięci podręcznej plików cookie wyczyszczone zanim otworzy się nowe okno\n    *   **clearsessioncache**: zestaw `yes` mieć w pamięci podręcznej plików cookie sesji wyczyszczone zanim otworzy się nowe okno\n    \n    tylko iOS:\n    \n    *   **closebuttoncaption**: aby użyć jak **zrobić** przycisk Podpis ustawiona na ciąg. Należy pamiętać, że trzeba zlokalizować tę wartość siebie.\n    *   **disallowoverscroll**: zestaw `yes` lub `no` (domyślnie `no` ). Włącza/wyłącza właściwość UIWebViewBounce.\n    *   **ukryte**: zestaw `yes` do stworzenia przeglądarki i ładowania strony, ale nie pokazuje go. Loadstop zdarzenie fires po zakończeniu ładowania. Pominąć lub zestaw `no` (domyślnie) do przeglądarki otworzyć i załadować normalnie.\n    *   **ClearCache**: zestaw `yes` do przeglądarki w pamięci podręcznej plików cookie wyczyszczone zanim otworzy się nowe okno\n    *   **clearsessioncache**: zestaw `yes` mieć w pamięci podręcznej plików cookie sesji wyczyszczone zanim otworzy się nowe okno\n    *   **pasek narzędzi**: zestaw `yes` lub `no` Aby włączyć pasek narzędzi lub wyłączyć dla InAppBrowser (domyślnie`yes`)\n    *   **enableViewportScale**: zestaw `yes` lub `no` Aby zapobiec rzutni skalowanie za pomocą tagu meta (domyślnie`no`).\n    *   **mediaPlaybackRequiresUserAction**: zestaw `yes` lub `no` Aby zapobiec HTML5 audio lub wideo z Autoodtwarzanie (domyślnie`no`).\n    *   **allowInlineMediaPlayback**: zestaw `yes` lub `no` Aby w linii HTML5 odtwarzanie, wyświetlanie w oknie przeglądarki, a nie interfejs odtwarzanie specyficzne dla urządzenia. HTML `video` również musi zawierać element `webkit-playsinline` atrybut (domyślnie`no`)\n    *   **keyboardDisplayRequiresUserAction**: zestaw `yes` lub `no` Aby otworzyć klawiaturę ekranową, gdy elementy formularza ostrości za pomocą JavaScript `focus()` połączenia (domyślnie`yes`).\n    *   **suppressesIncrementalRendering**: zestaw `yes` lub `no` czekać, aż wszystkie nowe widok zawartości jest otrzymane przed renderowany (domyślnie`no`).\n    *   **presentationstyle**: zestaw `pagesheet` , `formsheet` lub `fullscreen` Aby ustawić [styl prezentacji][1] (domyślnie`fullscreen`).\n    *   **transitionstyle**: zestaw `fliphorizontal` , `crossdissolve` lub `coververtical` Aby ustawić [styl przejścia][2] (domyślnie`coververtical`).\n    *   **toolbarposition**: zestaw `top` lub `bottom` (domyślnie `bottom` ). Powoduje, że pasek ma być na górze lub na dole okna.\n    \n    Windows tylko:\n    \n    *   **ukryte**: zestaw `yes` do stworzenia przeglądarki i ładowania strony, ale nie pokazuje go. Loadstop zdarzenie fires po zakończeniu ładowania. Pominąć lub zestaw `no` (domyślnie) do przeglądarki otworzyć i załadować normalnie.\n\n [1]: http://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalPresentationStyle\n [2]: http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalTransitionStyle\n\n### Obsługiwane platformy\n\n*   Amazon Fire OS\n*   Android\n*   BlackBerry 10\n*   Firefox OS\n*   iOS\n*   Windows 8 i 8.1\n*   Windows Phone 7 i 8\n\n### Przykład\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    var ref2 = cordova.InAppBrowser.open(encodeURI('http://ja.m.wikipedia.org/wiki/ハングル'), '_blank', 'location=yes');\n    \n\n### Firefox OS dziwactwa\n\nJak plugin nie wymuszać każdy projekt to trzeba dodać pewne reguły CSS jeśli otwarty z `target = \"_blank\"`. Zasady może wyglądać jak te\n\n     css\n    .inAppBrowserWrap {\n      background-color: rgba(0,0,0,0.75);\n      color: rgba(235,235,235,1.0);\n    }\n    .inAppBrowserWrap menu {\n      overflow: auto;\n      list-style-type: none;\n      padding-left: 0;\n    }\n    .inAppBrowserWrap menu li {\n      font-size: 25px;\n      height: 25px;\n      float: left;\n      margin: 0 10px;\n      padding: 3px 10px;\n      text-decoration: none;\n      color: #ccc;\n      display: block;\n      background: rgba(30,30,30,0.50);\n    }\n    .inAppBrowserWrap menu li.disabled {\n        color: #777;\n    }\n    \n\n## InAppBrowser\n\nObiekt zwrócony z wywołania `cordova.InAppBrowser.open`.\n\n### Metody\n\n*   metody addEventListener\n*   removeEventListener\n*   Zamknij\n*   Pokaż\n*   executeScript\n*   insertCSS\n\n## metody addEventListener\n\n> Dodaje detektor zdarzenia z`InAppBrowser`.\n\n    ref.addEventListener(eventname, callback);\n    \n\n*   **ref**: odniesienie do `InAppBrowser` okna *(InAppBrowser)*\n\n*   **EventName**: zdarzenie słuchać *(String)*\n    \n    *   **loadstart**: zdarzenie gdy odpalam `InAppBrowser` zaczyna się ładować adresu URL.\n    *   **loadstop**: zdarzenie gdy odpalam `InAppBrowser` zakończeniu ładowania adresu URL.\n    *   **LoadError**: zdarzenie odpala gdy `InAppBrowser` napotka błąd podczas ładowania adresu URL.\n    *   **wyjście**: zdarzenie gdy odpalam `InAppBrowser` okno jest zamknięte.\n\n*   **wywołania zwrotnego**: funkcja, która wykonuje, gdy zdarzenie. Funkcja jest przekazywany `InAppBrowserEvent` obiektu jako parametr.\n\n### Właściwości InAppBrowserEvent\n\n*   **Typ**: eventname, albo `loadstart` , `loadstop` , `loaderror` , lub `exit` . *(String)*\n\n*   **adres**: adres URL, który został załadowany. *(String)*\n\n*   **Kod**: kod błędu, tylko w przypadku `loaderror` . *(Liczba)*\n\n*   **wiadomość**: komunikat o błędzie, tylko w przypadku `loaderror` . *(String)*\n\n### Obsługiwane platformy\n\n*   Amazon Fire OS\n*   Android\n*   iOS\n*   Windows 8 i 8.1\n*   Windows Phone 7 i 8\n\n### Szybki przykład\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstart', function(event) { alert(event.url); });\n    \n\n## removeEventListener\n\n> Usuwa detektor zdarzenia z`InAppBrowser`.\n\n    ref.removeEventListener(eventname, callback);\n    \n\n*   **ref**: odniesienie do `InAppBrowser` okna. *(InAppBrowser)*\n\n*   **EventName**: zdarzenie przestanie słuchać. *(String)*\n    \n    *   **loadstart**: zdarzenie gdy odpalam `InAppBrowser` zaczyna się ładować adresu URL.\n    *   **loadstop**: zdarzenie gdy odpalam `InAppBrowser` zakończeniu ładowania adresu URL.\n    *   **LoadError**: zdarzenie odpala gdy `InAppBrowser` napotka błąd ładowania adresu URL.\n    *   **wyjście**: zdarzenie gdy odpalam `InAppBrowser` okno jest zamknięte.\n\n*   **wywołania zwrotnego**: funkcja do wykonania, gdy zdarzenie. Funkcja jest przekazywany `InAppBrowserEvent` obiektu.\n\n### Obsługiwane platformy\n\n*   Amazon Fire OS\n*   Android\n*   iOS\n*   Windows 8 i 8.1\n*   Windows Phone 7 i 8\n\n### Szybki przykład\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    var myCallback = function(event) { alert(event.url); }\n    ref.addEventListener('loadstart', myCallback);\n    ref.removeEventListener('loadstart', myCallback);\n    \n\n## Zamknij\n\n> Zamyka `InAppBrowser` okna.\n\n    ref.close();\n    \n\n*   **ref**: odniesienie do `InAppBrowser` okna *(InAppBrowser)*\n\n### Obsługiwane platformy\n\n*   Amazon Fire OS\n*   Android\n*   Firefox OS\n*   iOS\n*   Windows 8 i 8.1\n*   Windows Phone 7 i 8\n\n### Szybki przykład\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.close();\n    \n\n## Pokaż\n\n> Wyświetla InAppBrowser okno, który został otwarty ukryte. Zawód ten jest ignorowany, jeśli InAppBrowser już był widoczny.\n\n    ref.show();\n    \n\n*   **ref**: odwołanie do InAppBrowser (okno`InAppBrowser`)\n\n### Obsługiwane platformy\n\n*   Amazon Fire OS\n*   Android\n*   iOS\n*   Windows 8 i 8.1\n\n### Szybki przykład\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'hidden=yes');\n    // some time later...\n    ref.show();\n    \n\n## executeScript\n\n> Wstrzykuje kod JavaScript w `InAppBrowser` okna\n\n    ref.executeScript(details, callback);\n    \n\n*   **ref**: odniesienie do `InAppBrowser` okna. *(InAppBrowser)*\n\n*   **injectDetails**: Szczegóły dotyczące skryptu, określając albo `file` lub `code` klucz. *(Obiekt)*\n    \n    *   **plik**: adres URL skryptu, aby wstrzyknąć.\n    *   **Kod**: tekst skryptu, aby wstrzyknąć.\n\n*   **wywołania zwrotnego**: funkcja, która wykonuje po kod JavaScript jest wstrzykiwany.\n    \n    *   Jeśli taki skrypt jest typu `code` , wykonuje wywołanie zwrotne z pojedynczym parametrem, który jest wartość zwracana przez skrypt, owinięte w `Array` . Dla wielu linii skrypty to wartość zwracana ostatniej instrukcja, lub ostatni wyrażenie oceniane.\n\n### Obsługiwane platformy\n\n*   Amazon Fire OS\n*   Android\n*   iOS\n*   Windows 8 i 8.1\n\n### Szybki przykład\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstop', function() {\n        ref.executeScript({file: \"myscript.js\"});\n    });\n    \n\n## insertCSS\n\n> Wstrzykuje CSS w `InAppBrowser` okna.\n\n    ref.insertCSS(details, callback);\n    \n\n*   **ref**: odniesienie do `InAppBrowser` okna *(InAppBrowser)*\n\n*   **injectDetails**: Szczegóły dotyczące skryptu, określając albo `file` lub `code` klucz. *(Obiekt)*\n    \n    *   **plik**: URL arkusza stylów do wsuwania.\n    *   **Kod**: tekst z arkusza stylów do wstrzykiwania.\n\n*   **wywołania zwrotnego**: funkcja, która wykonuje po CSS jest wstrzykiwany.\n\n### Obsługiwane platformy\n\n*   Amazon Fire OS\n*   Android\n*   iOS\n\n### Szybki przykład\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstop', function() {\n        ref.insertCSS({file: \"mystyles.css\"});\n    });\n"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/doc/ru/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-inappbrowser\n\nЭтот плагин обеспечивает представление веб-браузера, что показывает при вызове`window.open()`.\n\n    var ref = window.open('http://apache.org', '_blank', 'location=yes');\n    \n\n**Примечание**: InAppBrowser окно ведет себя как стандартный веб-браузер и не может доступ API Cordova.\n\n## Установка\n\n    cordova plugin add cordova-plugin-inappbrowser\n    \n\n## window.open\n\nОткрывает URL-адрес в новом `InAppBrowser` например, текущий экземпляр браузера или браузера системы.\n\n    var ref = window.open(url, target, options);\n    \n\n*   **ссылка**: ссылка для `InAppBrowser` окно. *(InAppBrowser)*\n\n*   **URL**: URL-адрес для загрузки *(String)*. Вызвать `encodeURI()` на это, если URL-адрес содержит символы Unicode.\n\n*   **Цель**: цель для загрузки URL-адреса, необязательный параметр, по умолчанию `_self` . *(Строка)*\n    \n    *   `_self`: Открывается в Cordova WebView, если URL-адрес в белый список, в противном случае он открывается в`InAppBrowser`.\n    *   `_blank`: Открывает в`InAppBrowser`.\n    *   `_system`: Открывается в веб-браузера системы.\n\n*   **опции**: параметры для `InAppBrowser` . Необязательный параметр, виновная в: `location=yes` . *(Строка)*\n    \n    `options`Строка не должна содержать каких-либо пустое пространство, и каждая функция пар имя/значение должны быть разделены запятой. Функция имена нечувствительны к регистру. Все платформы поддерживают исходное значение:\n    \n    *   **Расположение**: равным `yes` или `no` превратить `InAppBrowser` в адресную строку или выключить.\n    \n    Только андроид:\n    \n    *   **closebuttoncaption**: задайте строку для использования в качестве заголовка кнопки **сделали** .\n    *   **скрытые**: значение `yes` для создания браузера и загрузки страницы, но не показать его. Событие loadstop возникает, когда загрузка завершена. Опустить или набор `no` (по умолчанию), чтобы браузер открыть и загрузить нормально.\n    *   **ClearCache**: набор `yes` иметь браузера куки кэш очищен перед открытием нового окна\n    *   **clearsessioncache**: значение `yes` иметь кэш cookie сеанса очищается перед открытием нового окна\n    \n    только iOS:\n    \n    *   **closebuttoncaption**: задайте строку для использования в качестве заголовка кнопки **сделали** . Обратите внимание, что вам нужно самостоятельно локализовать это значение.\n    *   **disallowoverscroll**: значение `yes` или `no` (по умолчанию `no` ). Включает/отключает свойство UIWebViewBounce.\n    *   **скрытые**: значение `yes` для создания браузера и загрузки страницы, но не показать его. Событие loadstop возникает, когда загрузка завершена. Опустить или набор `no` (по умолчанию), чтобы браузер открыть и загрузить нормально.\n    *   **ClearCache**: набор `yes` иметь браузера куки кэш очищен перед открытием нового окна\n    *   **clearsessioncache**: значение `yes` иметь кэш cookie сеанса очищается перед открытием нового окна\n    *   **панели инструментов**: набор `yes` или `no` для включения панели инструментов или выключить InAppBrowser (по умолчанию`yes`)\n    *   **enableViewportScale**: значение `yes` или `no` для предотвращения просмотра, масштабирования через тег meta (по умолчанию`no`).\n    *   **mediaPlaybackRequiresUserAction**: значение `yes` или `no` для предотвращения HTML5 аудио или видео от Автовоспроизведение (по умолчанию`no`).\n    *   **allowInlineMediaPlayback**: значение `yes` или `no` чтобы разрешить воспроизведение мультимедиа HTML5 в строки, отображения в окне браузера, а не конкретного устройства воспроизведения интерфейс. HTML `video` элемент должен также включать `webkit-playsinline` атрибут (по умолчанию`no`)\n    *   **keyboardDisplayRequiresUserAction**: значение `yes` или `no` чтобы открыть клавиатуру, когда формы элементы получают фокус через JavaScript в `focus()` вызов (по умолчанию`yes`).\n    *   **suppressesIncrementalRendering**: значение `yes` или `no` ждать, пока все новое содержание представление получено до визуализации (по умолчанию`no`).\n    *   **presentationstyle**: набор `pagesheet` , `formsheet` или `fullscreen` чтобы задать [стиль презентации][1] (по умолчанию`fullscreen`).\n    *   **transitionstyle**: набор `fliphorizontal` , `crossdissolve` или `coververtical` чтобы задать [стиль перехода][2] (по умолчанию`coververtical`).\n    *   **toolbarposition**: значение `top` или `bottom` (по умолчанию `bottom` ). Вызывает панели инструментов, чтобы быть в верхней или нижней части окна.\n    \n    Windows только:\n    \n    *   **скрытые**: значение `yes` для создания браузера и загрузки страницы, но не показать его. Событие loadstop возникает, когда загрузка завершена. Опустить или набор `no` (по умолчанию), чтобы браузер открыть и загрузить нормально.\n\n [1]: http://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalPresentationStyle\n [2]: http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalTransitionStyle\n\n### Поддерживаемые платформы\n\n*   Amazon Fire OS\n*   Android\n*   BlackBerry 10\n*   Firefox OS\n*   iOS\n*   Windows 8 и 8.1\n*   Windows Phone 7 и 8\n\n### Пример\n\n    var ref = window.open('http://apache.org', '_blank', 'location=yes');\n    var ref2 = window.open(encodeURI('http://ja.m.wikipedia.org/wiki/ハングル'), '_blank', 'location=yes');\n    \n\n### Особенности Firefox OS\n\nКак плагин не применять любой дизайн есть необходимость добавить некоторые правила CSS, если открыт с `target='_blank'` . Правила может выглядеть как эти\n\n     css\n    .inAppBrowserWrap {\n      background-color: rgba(0,0,0,0.75);\n      color: rgba(235,235,235,1.0);\n    }\n    .inAppBrowserWrap menu {\n      overflow: auto;\n      list-style-type: none;\n      padding-left: 0;\n    }\n    .inAppBrowserWrap menu li {\n      font-size: 25px;\n      height: 25px;\n      float: left;\n      margin: 0 10px;\n      padding: 3px 10px;\n      text-decoration: none;\n      color: #ccc;\n      display: block;\n      background: rgba(30,30,30,0.50);\n    }\n    .inAppBrowserWrap menu li.disabled {\n        color: #777;\n    }\n    \n\n## Внутренний браузер\n\nОбъект, возвращаемый из вызова`window.open`.\n\n### Методы\n\n*   addEventListener\n*   removeEventListener\n*   close\n*   show\n*   executeScript\n*   insertCSS\n\n## addEventListener\n\n> Добавляет прослушиватель для события от`InAppBrowser`.\n\n    ref.addEventListener(eventname, callback);\n    \n\n*   **ссылка**: ссылка для `InAppBrowser` окно *(InAppBrowser)*\n\n*   **EventName**: событие для прослушивания *(String)*\n    \n    *   **loadstart**: событие возникает, когда `InAppBrowser` начинает для загрузки URL-адреса.\n    *   **loadstop**: событие возникает, когда `InAppBrowser` завершит загрузку URL-адреса.\n    *   **loaderror**: событие возникает, когда `InAppBrowser` обнаруживает ошибку при загрузке URL-адреса.\n    *   **выход**: возникает событие, когда `InAppBrowser` окно закрыто.\n\n*   **обратного вызова**: функция, которая выполняется, когда возникает событие. Функция передается `InAppBrowserEvent` объект в качестве параметра.\n\n### InAppBrowserEvent свойства\n\n*   **тип**: eventname, либо `loadstart` , `loadstop` , `loaderror` , или `exit` . *(Строка)*\n\n*   **URL**: URL-адрес, который был загружен. *(Строка)*\n\n*   **код**: код ошибки, только в случае `loaderror` . *(Число)*\n\n*   **сообщение**: сообщение об ошибке, только в случае `loaderror` . *(Строка)*\n\n### Поддерживаемые платформы\n\n*   Amazon Fire OS\n*   Android\n*   iOS\n*   Windows 8 и 8.1\n*   Windows Phone 7 и 8\n\n### Краткий пример\n\n    var ref = window.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstart', function(event) { alert(event.url); });\n    \n\n## метод removeEventListener\n\n> Удаляет прослушиватель для события от`InAppBrowser`.\n\n    ref.removeEventListener(eventname, callback);\n    \n\n*   **ссылка**: ссылка для `InAppBrowser` окно. *(InAppBrowser)*\n\n*   **EventName**: событие прекратить прослушивание. *(Строка)*\n    \n    *   **loadstart**: событие возникает, когда `InAppBrowser` начинает для загрузки URL-адреса.\n    *   **loadstop**: событие возникает, когда `InAppBrowser` завершит загрузку URL-адреса.\n    *   **loaderror**: событие возникает, когда `InAppBrowser` обнаруживает ошибку загрузки URL-адреса.\n    *   **выход**: возникает событие, когда `InAppBrowser` окно закрывается.\n\n*   **обратного вызова**: функция, выполняемая когда это событие наступает. Функция передается `InAppBrowserEvent` объект.\n\n### Поддерживаемые платформы\n\n*   Amazon Fire OS\n*   Android\n*   iOS\n*   Windows 8 и 8.1\n*   Windows Phone 7 и 8\n\n### Краткий пример\n\n    var ref = window.open('http://apache.org', '_blank', 'location=yes');\n    var myCallback = function(event) { alert(event.url); }\n    ref.addEventListener('loadstart', myCallback);\n    ref.removeEventListener('loadstart', myCallback);\n    \n\n## close\n\n> Закрывает `InAppBrowser` окно.\n\n    Ref.Close();\n    \n\n*   **ссылка**: ссылка на `InAppBrowser` окно *(InAppBrowser)*\n\n### Поддерживаемые платформы\n\n*   Amazon Fire OS\n*   Android\n*   Firefox OS\n*   iOS\n*   Windows 8 и 8.1\n*   Windows Phone 7 и 8\n\n### Краткий пример\n\n    var ref = window.open('http://apache.org', '_blank', 'location=yes');\n    ref.close();\n    \n\n## show\n\n> Отображается окно InAppBrowser, был открыт скрытые. Вызов это не имеет эффекта при InAppBrowser уже был виден.\n\n    Ref.Show();\n    \n\n*   **ссылка**: ссылка на окно (InAppBrowser`InAppBrowser`)\n\n### Поддерживаемые платформы\n\n*   Amazon Fire OS\n*   Android\n*   iOS\n*   Windows 8 и 8.1\n\n### Краткий пример\n\n    var ref = window.open('http://apache.org', '_blank', 'hidden=yes');\n    // some time later...\n    ref.show();\n    \n\n## executeScript\n\n> Вставляет код JavaScript в `InAppBrowser` окно\n\n    ref.executeScript(details, callback);\n    \n\n*   **ссылка**: ссылка на `InAppBrowser` окно. *(InAppBrowser)*\n\n*   **injectDetails**: подробности сценария для запуска, указав либо `file` или `code` ключ. *(Объект)*\n    \n    *   **файл**: URL-адрес сценария вставки.\n    *   **код**: текст сценария для вставки.\n\n*   **обратного вызова**: функция, которая выполняет после вводят JavaScript-код.\n    \n    *   Если введенный скрипт имеет тип `code` , обратный вызов выполняется с одним параметром, который является возвращаемое значение сценария, завернутые в `Array` . Для многострочных сценариев это возвращаемое значение последнего оператора, или последнее вычисленное выражение.\n\n### Поддерживаемые платформы\n\n*   Amazon Fire OS\n*   Android\n*   iOS\n*   Windows 8 и 8.1\n\n### Краткий пример\n\n    var ref = window.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstop', function() {\n        ref.executeScript({file: \"myscript.js\"});\n    });\n    \n\n## insertCSS\n\n> Внедряет CSS в `InAppBrowser` окно.\n\n    ref.insertCSS(details, callback);\n    \n\n*   **ссылка**: ссылка на `InAppBrowser` окно *(InAppBrowser)*\n\n*   **injectDetails**: детали сценария для запуска, указав либо `file` или `code` ключ. *(Объект)*\n    \n    *   **файл**: URL-адрес таблицы стилей для вставки.\n    *   **код**: текст таблицы стилей для вставки.\n\n*   **обратного вызова**: функция, которая выполняет после вводят CSS.\n\n### Поддерживаемые платформы\n\n*   Amazon Fire OS\n*   Android\n*   iOS\n\n### Краткий пример\n\n    var ref = window.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstop', function() {\n        ref.insertCSS({file: \"mystyles.css\"});\n    });\n"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/doc/zh/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-inappbrowser\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-inappbrowser.svg)](https://travis-ci.org/apache/cordova-plugin-inappbrowser)\n\n這個外掛程式提供了一個 web 瀏覽器視圖，顯示在調用 `cordova.InAppBrowser.open()`.\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    \n\n`cordova.InAppBrowser.open()` 函數被定義為一個臨時替代 `window.open ()` 函數。 現有 `window.open ()` 調用，可以通過替換 window.open 使用 InAppBrowser 視窗：\n\n    window.open = cordova.InAppBrowser.open;\n    \n\nInAppBrowser 視窗像一個標準的 web 瀏覽器中，並且無法訪問科爾多瓦 Api。 為此，建議 InAppBrowser 如果您需要載入協力廠商 （不可信） 的內容，而不是載入，進入主要的科爾多瓦 web 視圖。 InAppBrowser 是不受白名單中，也不在系統瀏覽器中打開的連結。\n\nInAppBrowser 預設情況下它自己的 GUI 控制項為使用者提供 （後退、 前進、 完成）。\n\n為向後相容性，此外掛程式還鉤 `window.open`。 然而，`window.open` 外掛程式安裝鉤子可以有副作用 （尤其是如果這個外掛程式是只列為另一個外掛程式的依賴項）。 在未來的主要發行版本中，將刪除 `window.open` 鉤。 一直至從該外掛程式鉤子後，應用程式可以手動還原預設行為：\n\n    delete window.open // Reverts the call back to it's prototype's default\n    \n\n雖然 `window.open` 在全球範圍內，InAppBrowser 不可用直到 `deviceready` 事件之後。\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(\"window.open works well\");\n    }\n    \n\n## 安裝\n\n    cordova plugin add cordova-plugin-inappbrowser\n    \n\n如果您希望所有頁面載入中您的應用程式要通過 InAppBrowser，你可以簡單地在初始化過程中鉤 `window.open`。舉個例子：\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        window.open = cordova.InAppBrowser.open;\n    }\n    \n\n## cordova.InAppBrowser.open\n\n在新的 `InAppBrowser` 實例，當前的瀏覽器實例或系統瀏覽器中打開的 URL。\n\n    var ref = cordova.InAppBrowser.open(url, target, options);\n    \n\n  * **ref**： 參考 `InAppBrowser` 視窗。*() InAppBrowser*\n\n  * **url**： 要載入*（字串）*的 URL。調用 `encodeURI()` 這個如果 URL 包含 Unicode 字元。\n\n  * **target**： 目標在其中載入的 URL，可選參數，預設值為 `_self` 。*（字串）*\n    \n      * `_self`： 打開在科爾多瓦 web 視圖如果 URL 是在白名單中，否則它在打開`InAppBrowser`.\n      * `_blank`： 在打開`InAppBrowser`.\n      * `_system`： 在該系統的 web 瀏覽器中打開。\n\n  * **options**： 選項為 `InAppBrowser` 。可選，拖欠到： `location=yes` 。*（字串）*\n    \n    `options`字串必須不包含任何空白的空間，和必須用逗號分隔每個功能的名稱/值對。 功能名稱區分大小寫。 所有平臺都支援下面的值：\n    \n      * **location**： 設置為 `yes` 或 `no` ，打開 `InAppBrowser` 的位置欄打開或關閉。\n    \n    Android 系統只有：\n    \n      * **hidden**： 將設置為 `yes` ，創建瀏覽器和載入頁面，但不是顯示它。 載入完成時，將觸發 loadstop 事件。 省略或設置為 `no` （預設值），有的瀏覽器打開，然後以正常方式載入。\n      * **clearcache**： 將設置為 `yes` 有瀏覽器的 cookie 清除緩存之前打開新視窗\n      * **clearsessioncache**： 將設置為 `yes` 有會話 cookie 緩存清除之前打開新視窗\n      * **zoom**: 設置為`yes`，顯示 Android 瀏覽器的縮放控制項，設置為`no`，以隱藏它們。 `預設值是`.\n      * **hardwareback**: 設置為`yes`要使用硬體後退按鈕通過`InAppBrowser`的歷史向後導航。 如果沒有前一頁， `InAppBrowser`將會關閉。 預設值是的`yes`所以你必須將其設置為`no`，如果你想要的後退按鈕，只需關閉 InAppBrowser。\n    \n    只有 iOS：\n    \n      * **closebuttoncaption**: 設置為一個字串，以用作**做**按鈕的標題。請注意您需要對此值進行當地語系化你自己。\n      * **disallowoverscroll**： 將設置為 `yes` 或 `no` （預設值是 `no` ）。打開/關閉的 UIWebViewBounce 屬性。\n      * **hidden**： 將設置為 `yes` ，創建瀏覽器和載入頁面，但不是顯示它。 載入完成時，將觸發 loadstop 事件。 省略或設置為 `no` （預設值），有的瀏覽器打開，然後以正常方式載入。\n      * **clearcache**： 將設置為 `yes` 有瀏覽器的 cookie 清除緩存之前打開新視窗\n      * **clearsessioncache**： 將設置為 `yes` 有會話 cookie 緩存清除之前打開新視窗\n      * **toolbar**： 設置為 `yes` 或 `no` ，為 InAppBrowser （預設為打開或關閉工具列`yes`)\n      * **enableViewportScale**： 將設置為 `yes` 或 `no` ，防止通過 meta 標記 （預設為縮放的視區`no`).\n      * **mediaPlaybackRequiresUserAction**： 將設置為 `yes` 或 `no` ，防止 HTML5 音訊或視頻從 autoplaying （預設為`no`).\n      * **allowInlineMediaPlayback**： 將設置為 `yes` 或 `no` ，讓線在 HTML5 播放媒體，在瀏覽器視窗中，而不是特定于設備播放介面內顯示。 HTML 的 `video` 元素還必須包括 `webkit-playsinline` 屬性 （預設為`no`)\n      * **keyboardDisplayRequiresUserAction**： 將設置為 `yes` 或 `no` 時，要打開鍵盤表單元素接收焦點通過 JavaScript 的 `focus()` 調用 （預設為`yes`).\n      * **suppressesIncrementalRendering**： 將設置為 `yes` 或 `no` 等待，直到所有新查看的內容正在呈現 （預設為前收到`no`).\n      * **presentationstyle**： 將設置為 `pagesheet` ， `formsheet` 或 `fullscreen` 來設置[演示文稿樣式](http://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalPresentationStyle)(預設為`fullscreen`).\n      * **transitionstyle**： 將設置為 `fliphorizontal` ， `crossdissolve` 或 `coververtical` 設置[過渡樣式](http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalTransitionStyle)(預設為`coververtical`).\n      * **toolbarposition**： 將設置為 `top` 或 `bottom` （預設值是 `bottom` ）。使工具列，則在頂部或底部的視窗。\n    \n    僅限 Windows：\n    \n      * **hidden**： 將設置為 `yes` ，創建瀏覽器和載入頁面，但不是顯示它。 載入完成時，將觸發 loadstop 事件。 省略或設置為 `no` （預設值），有的瀏覽器打開，然後以正常方式載入。\n      * **fullscreen**: 設置為`yes`，以創建無邊框的瀏覽器控制項。 請注意，如果**location=no**同時指定，則將呈現給使用者到密切 IAB 視窗沒有控制。\n\n### 支援的平臺\n\n  * 亞馬遜火 OS\n  * Android 系統\n  * 黑莓 10\n  * 火狐瀏覽器作業系統\n  * iOS\n  * Windows 8 和 8.1\n  * Windows Phone 7 和 8\n  * 瀏覽器\n\n### 示例\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    var ref2 = cordova.InAppBrowser.open(encodeURI('http://ja.m.wikipedia.org/wiki/ハングル'), '_blank', 'location=yes');\n    \n\n### 火狐瀏覽器作業系統的怪癖\n\n外掛程式不會強制任何設計是需要添加一些 CSS 規則，如果打開與 `target=_blank`。規則 》 可能看起來像這些\n\n```css\n.inAppBrowserWrap {\n  background-color: rgba(0,0,0,0.75);\n  color: rgba(235,235,235,1.0);\n}\n.inAppBrowserWrap menu {\n  overflow: auto;\n  list-style-type: none;\n  padding-left: 0;\n}\n.inAppBrowserWrap menu li {\n  font-size: 25px;\n  height: 25px;\n  float: left;\n  margin: 0 10px;\n  padding: 3px 10px;\n  text-decoration: none;\n  color: #ccc;\n  display: block;\n  background: rgba(30,30,30,0.50);\n}\n.inAppBrowserWrap menu li.disabled {\n    color: #777;\n}\n```\n\n### Windows 的怪癖\n\n類似于 Firefox OS IAB 視窗視覺行為可以重寫通過`inAppBrowserWrap`/`inAppBrowserWrapFullscreen`的 CSS 類\n\n### 瀏覽器的怪癖\n\n  * 外掛程式是通過 iframe，執行\n\n  * 未實現導航歷史記錄 (在 LocationBar 的`回顧`與`展望`按鈕)。\n\n## InAppBrowser\n\n對 `科爾多瓦的調用返回的物件。InAppBrowser.open`.\n\n### 方法\n\n  * addEventListener\n  * removeEventListener\n  * close\n  * show\n  * executeScript\n  * insertCSS\n\n## addEventListener\n\n> 為事件添加一個攔截器`InAppBrowser`.\n\n    ref.addEventListener(eventname, callback);\n    \n\n  * **ref**： 參考 `InAppBrowser` 視窗*(InAppBrowser)*\n\n  * **eventname**： 事件偵聽*（字串）*\n    \n      * **loadstart**： 當觸發事件 `InAppBrowser` 開始載入一個 URL。\n      * **loadstop**： 當觸發事件 `InAppBrowser` 完成載入一個 URL。\n      * **loaderror**： 當觸發事件 `InAppBrowser` 載入 URL 時遇到錯誤。\n      * **exit**： 當觸發事件 `InAppBrowser` 關閉視窗。\n\n  * **callback**： 執行時觸發該事件的函數。該函數通過 `InAppBrowserEvent` 物件作為參數。\n\n### InAppBrowserEvent 屬性\n\n  * **type**： eventname，或者 `loadstart` ， `loadstop` ， `loaderror` ，或 `exit` 。*（字串）*\n\n  * **url**: 已載入的 URL。*（字串）*\n\n  * **code**： 僅中的情況的錯誤代碼 `loaderror` 。*（人數）*\n\n  * **message**： 該錯誤訊息，只有在的情況下 `loaderror` 。*（字串）*\n\n### 支援的平臺\n\n  * 亞馬遜火 OS\n  * Android 系統\n  * iOS\n  * Windows 8 和 8.1\n  * Windows Phone 7 和 8\n  * 瀏覽器\n\n### 瀏覽器的怪癖\n\n`loadstart`和`loaderror`的事件不會被觸發。\n\n### 快速的示例\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstart', function(event) { alert(event.url); });\n    \n\n## removeEventListener\n\n> 移除的事件攔截器`InAppBrowser`.\n\n    ref.removeEventListener(eventname, callback);\n    \n\n  * **ref**： 參考 `InAppBrowser` 視窗。*() InAppBrowser*\n\n  * **eventname**： 要停止偵聽的事件。*（字串）*\n    \n      * **loadstart**： 當觸發事件 `InAppBrowser` 開始載入一個 URL。\n      * **loadstop**： 當觸發事件 `InAppBrowser` 完成載入一個 URL。\n      * **loaderror**： 當觸發事件 `InAppBrowser` 遇到錯誤載入一個 URL。\n      * **exit**： 當觸發事件 `InAppBrowser` 關閉視窗。\n\n  * **callback**: 要在事件觸發時執行的函數。該函數通過 `InAppBrowserEvent` 物件。\n\n### 支援的平臺\n\n  * 亞馬遜火 OS\n  * Android 系統\n  * iOS\n  * Windows 8 和 8.1\n  * Windows Phone 7 和 8\n  * 瀏覽器\n\n### 快速的示例\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    var myCallback = function(event) { alert(event.url); }\n    ref.addEventListener('loadstart', myCallback);\n    ref.removeEventListener('loadstart', myCallback);\n    \n\n## close\n\n> 關閉 `InAppBrowser` 視窗。\n\n    ref.close();\n    \n\n  * **ref**： 參考 `InAppBrowser` 視窗*(InAppBrowser)*\n\n### 支援的平臺\n\n  * 亞馬遜火 OS\n  * Android 系統\n  * 火狐瀏覽器作業系統\n  * iOS\n  * Windows 8 和 8.1\n  * Windows Phone 7 和 8\n  * 瀏覽器\n\n### 快速的示例\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.close();\n    \n\n## show\n\n> 顯示打開了隱藏的 InAppBrowser 視窗。調用這沒有任何影響，如果 InAppBrowser 是已經可見。\n\n    ref.show();\n    \n\n  * **ref**： InAppBrowser 視窗 (參考`InAppBrowser`)\n\n### 支援的平臺\n\n  * 亞馬遜火 OS\n  * Android 系統\n  * iOS\n  * Windows 8 和 8.1\n  * 瀏覽器\n\n### 快速的示例\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'hidden=yes');\n    // some time later...\n    ref.show();\n    \n\n## executeScript\n\n> 注入到 JavaScript 代碼 `InAppBrowser` 視窗\n\n    ref.executeScript(details, callback);\n    \n\n  * **ref**： 參考 `InAppBrowser` 視窗。*() InAppBrowser*\n\n  * **injectDetails**: 要運行的腳本的詳細資訊或指定 `file` 或 `code` 的關鍵。*（物件）*\n    \n      * **檔**： 腳本的 URL 來注入。\n      * **代碼**： 要注入腳本的文本。\n\n  * **回檔**： 執行後注入的 JavaScript 代碼的函數。\n    \n      * 如果插入的腳本的類型 `code` ，回檔執行使用單個參數，這是該腳本的傳回值，裹在 `Array` 。 對於多行腳本，這是最後一條語句或最後計算的運算式的傳回值。\n\n### 支援的平臺\n\n  * 亞馬遜火 OS\n  * Android 系統\n  * iOS\n  * Windows 8 和 8.1\n  * 瀏覽器\n\n### 快速的示例\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstop', function() {\n        ref.executeScript({file: \"myscript.js\"});\n    });\n    \n\n### 瀏覽器的怪癖\n\n  * 只有**code**關鍵被支援。\n\n### Windows 的怪癖\n\n由於[MSDN 文檔](https://msdn.microsoft.com/en-us/library/windows.ui.xaml.controls.webview.invokescriptasync.aspx)調用的腳本可以返回唯一字串值，否則該參數，傳遞給**回檔**將是`[null]`.\n\n## insertCSS\n\n> 注入到 CSS `InAppBrowser` 視窗。\n\n    ref.insertCSS(details, callback);\n    \n\n  * **ref**： 參考 `InAppBrowser` 視窗*(InAppBrowser)*\n\n  * **injectDetails**: 要運行的腳本的詳細資訊或指定 `file` 或 `code` 的關鍵。*（物件）*\n    \n      * **file**： 樣式表的 URL 來注入。\n      * **code**： 文本樣式表的注入。\n\n  * **callback**： 在 CSS 注射後執行的函數。\n\n### 支援的平臺\n\n  * 亞馬遜火 OS\n  * Android 系統\n  * iOS\n  * Windows\n\n### 快速的示例\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstop', function() {\n        ref.insertCSS({file: \"mystyles.css\"});\n    });"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/doc/zh/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-inappbrowser\n\n這個外掛程式提供了一個 web 瀏覽器視圖，顯示在調用 `cordova.InAppBrowser.open()`.\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    \n\n`cordova.InAppBrowser.open()` 函數被定義為一個臨時替代 `window.open ()` 函數。 現有 `window.open ()` 調用，可以通過替換 window.open 使用 InAppBrowser 視窗：\n\n    window.open = cordova.InAppBrowser.open;\n    \n\nInAppBrowser 視窗像一個標準的 web 瀏覽器中，並且無法訪問科爾多瓦 Api。 為此，建議 InAppBrowser 如果您需要載入協力廠商 （不可信） 的內容，而不是載入，進入主要的科爾多瓦 web 視圖。 InAppBrowser 是不受白名單中，也不在系統瀏覽器中打開的連結。\n\nInAppBrowser 預設情況下它自己的 GUI 控制項為使用者提供 （後退、 前進、 完成）。\n\n為向後相容性，此外掛程式還鉤 `window.open`。 然而，`window.open` 外掛程式安裝鉤子可以有副作用 （尤其是如果這個外掛程式是只列為另一個外掛程式的依賴項）。 在未來的主要發行版本中，將刪除 `window.open` 鉤。 一直至從該外掛程式鉤子後，應用程式可以手動還原預設行為：\n\n    delete window.open // Reverts the call back to it's prototype's default\n    \n\n雖然 `window.open` 在全球範圍內，InAppBrowser 不可用直到 `deviceready` 事件之後。\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(\"window.open works well\");\n    }\n    \n\n## 安裝\n\n    cordova plugin add cordova-plugin-inappbrowser\n    \n\n如果您希望所有頁面載入中您的應用程式要通過 InAppBrowser，你可以簡單地在初始化過程中鉤 `window.open`。舉個例子：\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        window.open = cordova.InAppBrowser.open;\n    }\n    \n\n## cordova.InAppBrowser.open\n\n在新的 `InAppBrowser` 實例，當前的瀏覽器實例或系統瀏覽器中打開的 URL。\n\n    var ref = cordova.InAppBrowser.open(url, target, options);\n    \n\n*   **ref**： 參考 `InAppBrowser` 視窗。*() InAppBrowser*\n\n*   **url**： 要載入*（字串）*的 URL。調用 `encodeURI()` 這個如果 URL 包含 Unicode 字元。\n\n*   **target**： 目標在其中載入的 URL，可選參數，預設值為 `_self` 。*（字串）*\n    \n    *   `_self`： 打開在科爾多瓦 web 視圖如果 URL 是在白名單中，否則它在打開`InAppBrowser`.\n    *   `_blank`： 在打開`InAppBrowser`.\n    *   `_system`： 在該系統的 web 瀏覽器中打開。\n\n*   **options**： 選項為 `InAppBrowser` 。可選，拖欠到： `location=yes` 。*（字串）*\n    \n    `options`字串必須不包含任何空白的空間，和必須用逗號分隔每個功能的名稱/值對。 功能名稱區分大小寫。 所有平臺都支援下面的值：\n    \n    *   **location**： 設置為 `yes` 或 `no` ，打開 `InAppBrowser` 的位置欄打開或關閉。\n    \n    Android 系統只有：\n    \n    *   **hidden**： 將設置為 `yes` ，創建瀏覽器和載入頁面，但不是顯示它。 載入完成時，將觸發 loadstop 事件。 省略或設置為 `no` （預設值），有的瀏覽器打開，然後以正常方式載入。\n    *   **clearcache**： 將設置為 `yes` 有瀏覽器的 cookie 清除緩存之前打開新視窗\n    *   **clearsessioncache**： 將設置為 `yes` 有會話 cookie 緩存清除之前打開新視窗\n    \n    只有 iOS：\n    \n    *   **closebuttoncaption**: 設置為一個字串，以用作**做**按鈕的標題。請注意您需要對此值進行當地語系化你自己。\n    *   **disallowoverscroll**： 將設置為 `yes` 或 `no` （預設值是 `no` ）。打開/關閉的 UIWebViewBounce 屬性。\n    *   **hidden**： 將設置為 `yes` ，創建瀏覽器和載入頁面，但不是顯示它。 載入完成時，將觸發 loadstop 事件。 省略或設置為 `no` （預設值），有的瀏覽器打開，然後以正常方式載入。\n    *   **clearcache**： 將設置為 `yes` 有瀏覽器的 cookie 清除緩存之前打開新視窗\n    *   **clearsessioncache**： 將設置為 `yes` 有會話 cookie 緩存清除之前打開新視窗\n    *   **toolbar**： 設置為 `yes` 或 `no` ，為 InAppBrowser （預設為打開或關閉工具列`yes`)\n    *   **enableViewportScale**： 將設置為 `yes` 或 `no` ，防止通過 meta 標記 （預設為縮放的視區`no`).\n    *   **mediaPlaybackRequiresUserAction**： 將設置為 `yes` 或 `no` ，防止 HTML5 音訊或視頻從 autoplaying （預設為`no`).\n    *   **allowInlineMediaPlayback**： 將設置為 `yes` 或 `no` ，讓線在 HTML5 播放媒體，在瀏覽器視窗中，而不是特定于設備播放介面內顯示。 HTML 的 `video` 元素還必須包括 `webkit-playsinline` 屬性 （預設為`no`)\n    *   **keyboardDisplayRequiresUserAction**： 將設置為 `yes` 或 `no` 時，要打開鍵盤表單元素接收焦點通過 JavaScript 的 `focus()` 調用 （預設為`yes`).\n    *   **suppressesIncrementalRendering**： 將設置為 `yes` 或 `no` 等待，直到所有新查看的內容正在呈現 （預設為前收到`no`).\n    *   **presentationstyle**： 將設置為 `pagesheet` ， `formsheet` 或 `fullscreen` 來設置[演示文稿樣式][1](預設為`fullscreen`).\n    *   **transitionstyle**： 將設置為 `fliphorizontal` ， `crossdissolve` 或 `coververtical` 設置[過渡樣式][2](預設為`coververtical`).\n    *   **toolbarposition**： 將設置為 `top` 或 `bottom` （預設值是 `bottom` ）。使工具列，則在頂部或底部的視窗。\n    \n    僅限 Windows：\n    \n    *   **hidden**： 將設置為 `yes` ，創建瀏覽器並載入頁面，但不是顯示它。 載入完成時，將觸發 loadstop 事件。 省略或被設置為 `no` （預設值），有的瀏覽器打開，以正常方式載入。\n\n [1]: http://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalPresentationStyle\n [2]: http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalTransitionStyle\n\n### 支援的平臺\n\n*   亞馬遜火 OS\n*   Android 系統\n*   黑莓 10\n*   火狐瀏覽器的作業系統\n*   iOS\n*   Windows 8 和 8.1\n*   Windows Phone 7 和 8\n\n### 示例\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    var ref2 = cordova.InAppBrowser.open(encodeURI('http://ja.m.wikipedia.org/wiki/ハングル'), '_blank', 'location=yes');\n    \n\n### 火狐瀏覽器作業系統的怪癖\n\n外掛程式不會強制任何設計是需要添加一些 CSS 規則，如果打開與 `target=_blank`。規則 》 可能看起來像這些\n\n     css\n    .inAppBrowserWrap {\n      background-color: rgba(0,0,0,0.75);\n      color: rgba(235,235,235,1.0);\n    }\n    .inAppBrowserWrap menu {\n      overflow: auto;\n      list-style-type: none;\n      padding-left: 0;\n    }\n    .inAppBrowserWrap menu li {\n      font-size: 25px;\n      height: 25px;\n      float: left;\n      margin: 0 10px;\n      padding: 3px 10px;\n      text-decoration: none;\n      color: #ccc;\n      display: block;\n      background: rgba(30,30,30,0.50);\n    }\n    .inAppBrowserWrap menu li.disabled {\n        color: #777;\n    }\n    \n\n## InAppBrowser\n\n對 `科爾多瓦的調用返回的物件。InAppBrowser.open`.\n\n### 方法\n\n*   addEventListener\n*   removeEventListener\n*   close\n*   show\n*   executeScript\n*   insertCSS\n\n## addEventListener\n\n> 為事件添加一個攔截器`InAppBrowser`.\n\n    ref.addEventListener(eventname, callback);\n    \n\n*   **ref**： 參考 `InAppBrowser` 視窗*(InAppBrowser)*\n\n*   **eventname**： 事件偵聽*（字串）*\n    \n    *   **loadstart**： 當觸發事件 `InAppBrowser` 開始載入一個 URL。\n    *   **loadstop**： 當觸發事件 `InAppBrowser` 完成載入一個 URL。\n    *   **loaderror**： 當觸發事件 `InAppBrowser` 載入 URL 時遇到錯誤。\n    *   **exit**： 當觸發事件 `InAppBrowser` 關閉視窗。\n\n*   **callback**： 執行時觸發該事件的函數。該函數通過 `InAppBrowserEvent` 物件作為參數。\n\n### InAppBrowserEvent 屬性\n\n*   **type**： eventname，或者 `loadstart` ， `loadstop` ， `loaderror` ，或 `exit` 。*（字串）*\n\n*   **url**: 已載入的 URL。*（字串）*\n\n*   **code**： 僅中的情況的錯誤代碼 `loaderror` 。*（人數）*\n\n*   **message**： 該錯誤訊息，只有在的情況下 `loaderror` 。*（字串）*\n\n### 支援的平臺\n\n*   亞馬遜火 OS\n*   Android 系統\n*   iOS\n*   Windows 8 和 8.1\n*   Windows Phone 7 和 8\n\n### 快速的示例\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstart', function(event) { alert(event.url); });\n    \n\n## removeEventListener\n\n> 移除的事件攔截器`InAppBrowser`.\n\n    ref.removeEventListener(eventname, callback);\n    \n\n*   **ref**： 參考 `InAppBrowser` 視窗。*() InAppBrowser*\n\n*   **eventname**： 要停止偵聽的事件。*（字串）*\n    \n    *   **loadstart**： 當觸發事件 `InAppBrowser` 開始載入一個 URL。\n    *   **loadstop**： 當觸發事件 `InAppBrowser` 完成載入一個 URL。\n    *   **loaderror**： 當觸發事件 `InAppBrowser` 遇到錯誤載入一個 URL。\n    *   **exit**： 當觸發事件 `InAppBrowser` 關閉視窗。\n\n*   **callback**: 要在事件觸發時執行的函數。該函數通過 `InAppBrowserEvent` 物件。\n\n### 支援的平臺\n\n*   亞馬遜火 OS\n*   Android 系統\n*   iOS\n*   Windows 8 和 8.1\n*   Windows Phone 7 和 8\n\n### 快速的示例\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    var myCallback = function(event) { alert(event.url); }\n    ref.addEventListener('loadstart', myCallback);\n    ref.removeEventListener('loadstart', myCallback);\n    \n\n## close\n\n> 關閉 `InAppBrowser` 視窗。\n\n    ref.close();\n    \n\n*   **ref**： 參考 `InAppBrowser` 視窗*(InAppBrowser)*\n\n### 支援的平臺\n\n*   亞馬遜火 OS\n*   Android 系統\n*   火狐瀏覽器的作業系統\n*   iOS\n*   Windows 8 和 8.1\n*   Windows Phone 7 和 8\n\n### 快速的示例\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.close();\n    \n\n## show\n\n> 顯示打開了隱藏的 InAppBrowser 視窗。調用這沒有任何影響，如果 InAppBrowser 是已經可見。\n\n    ref.show();\n    \n\n*   **ref**： InAppBrowser 視窗 (參考`InAppBrowser`)\n\n### 支援的平臺\n\n*   亞馬遜火 OS\n*   Android 系統\n*   iOS\n*   Windows 8 和 8.1\n\n### 快速的示例\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'hidden=yes');\n    // some time later...\n    ref.show();\n    \n\n## executeScript\n\n> 注入到 JavaScript 代碼 `InAppBrowser` 視窗\n\n    ref.executeScript(details, callback);\n    \n\n*   **ref**： 參考 `InAppBrowser` 視窗。*() InAppBrowser*\n\n*   **injectDetails**: 要運行的腳本的詳細資訊或指定 `file` 或 `code` 的關鍵。*（物件）*\n    \n    *   **檔**： 腳本的 URL 來注入。\n    *   **代碼**： 要注入腳本的文本。\n\n*   **回檔**： 執行後注入的 JavaScript 代碼的函數。\n    \n    *   如果插入的腳本的類型 `code` ，回檔執行使用單個參數，這是該腳本的傳回值，裹在 `Array` 。 對於多行腳本，這是最後一條語句或最後計算的運算式的傳回值。\n\n### 支援的平臺\n\n*   亞馬遜火 OS\n*   Android 系統\n*   iOS\n*   Windows 8 和 8.1\n\n### 快速的示例\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstop', function() {\n        ref.executeScript({file: \"myscript.js\"});\n    });\n    \n\n## insertCSS\n\n> 注入到 CSS `InAppBrowser` 視窗。\n\n    ref.insertCSS(details, callback);\n    \n\n*   **ref**： 參考 `InAppBrowser` 視窗*(InAppBrowser)*\n\n*   **injectDetails**: 要運行的腳本的詳細資訊或指定 `file` 或 `code` 的關鍵。*（物件）*\n    \n    *   **file**： 樣式表的 URL 來注入。\n    *   **code**： 文本樣式表的注入。\n\n*   **callback**： 在 CSS 注射後執行的函數。\n\n### 支援的平臺\n\n*   亞馬遜火 OS\n*   Android 系統\n*   iOS\n\n### 快速的示例\n\n    var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');\n    ref.addEventListener('loadstop', function() {\n        ref.insertCSS({file: \"mystyles.css\"});\n    });\n"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/package.json",
    "content": "{\n  \"name\": \"cordova-plugin-inappbrowser\",\n  \"version\": \"1.4.0\",\n  \"description\": \"Cordova InAppBrowser Plugin\",\n  \"cordova\": {\n    \"id\": \"cordova-plugin-inappbrowser\",\n    \"platforms\": [\n      \"android\",\n      \"amazon-fireos\",\n      \"ubuntu\",\n      \"ios\",\n      \"wp7\",\n      \"wp8\",\n      \"windows8\",\n      \"windows\",\n      \"firefoxos\"\n    ]\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/apache/cordova-plugin-inappbrowser\"\n  },\n  \"keywords\": [\n    \"cordova\",\n    \"in\",\n    \"app\",\n    \"browser\",\n    \"inappbrowser\",\n    \"ecosystem:cordova\",\n    \"cordova-android\",\n    \"cordova-amazon-fireos\",\n    \"cordova-ubuntu\",\n    \"cordova-ios\",\n    \"cordova-wp7\",\n    \"cordova-wp8\",\n    \"cordova-windows8\",\n    \"cordova-windows\",\n    \"cordova-firefoxos\"\n  ],\n  \"scripts\": {\n    \"test\": \"npm run jshint\",\n    \"jshint\": \"node node_modules/jshint/bin/jshint www && node node_modules/jshint/bin/jshint src && node node_modules/jshint/bin/jshint tests\"\n  },\n  \"engines\": [\n    {\n      \"name\": \"cordova\",\n      \"version\": \">=3.1.0\"\n    }\n  ],\n  \"author\": \"Apache Software Foundation\",\n  \"license\": \"Apache-2.0\",\n  \"devDependencies\": {\n    \"jshint\": \"^2.6.0\"\n  }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/plugin.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  Licensed to the Apache Software Foundation (ASF) under one\n  or more contributor license agreements.  See the NOTICE file\n  distributed with this work for additional information\n  regarding copyright ownership.  The ASF licenses this file\n  to you under the Apache License, Version 2.0 (the\n  \"License\"); you may not use this file except in compliance\n  with the License.  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing,\n  software distributed under the License is distributed on an\n  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n  KIND, either express or implied.  See the License for the\n  specific language governing permissions and limitations\n  under the License.\n-->\n\n<plugin xmlns=\"http://apache.org/cordova/ns/plugins/1.0\"\n           id=\"cordova-plugin-inappbrowser\"\n      version=\"1.4.0\">\n\n    <name>InAppBrowser</name>\n    <description>Cordova InAppBrowser Plugin</description>\n    <license>Apache 2.0</license>\n    <keywords>cordova,in,app,browser,inappbrowser</keywords>\n    <repo>https://git-wip-us.apache.org/repos/asf/cordova-plugin-inappbrowser.git</repo>\n    <issue>https://issues.apache.org/jira/browse/CB/component/12320641</issue>\n\n    <engines>\n      <engine name=\"cordova\" version=\">=3.1.0\" /><!-- Needs cordova/urlutil -->\n    </engines>\n\n    <!-- android -->\n    <platform name=\"android\">\n        <js-module src=\"www/inappbrowser.js\" name=\"inappbrowser\">\n            <clobbers target=\"cordova.InAppBrowser.open\" />\n            <clobbers target=\"window.open\" />\n        </js-module>\n        <config-file target=\"res/xml/config.xml\" parent=\"/*\">\n            <feature name=\"InAppBrowser\"> \n                <param name=\"android-package\" value=\"org.apache.cordova.inappbrowser.InAppBrowser\"/>\n            </feature>\n        </config-file>\n\n        <source-file src=\"src/android/InAppBrowser.java\" target-dir=\"src/org/apache/cordova/inappbrowser\" />\n        <source-file src=\"src/android/InAppBrowserDialog.java\" target-dir=\"src/org/apache/cordova/inappbrowser\" />\n        <source-file src=\"src/android/InAppChromeClient.java\" target-dir=\"src/org/apache/cordova/inappbrowser\" />\n\n        <!--  drawable src/android/resources -->\n        <resource-file src=\"src/android/res/drawable-hdpi/ic_action_next_item.png\" target=\"res/drawable-hdpi/ic_action_next_item.png\" />\n        <resource-file src=\"src/android/res/drawable-mdpi/ic_action_next_item.png\" target=\"res/drawable-mdpi/ic_action_next_item.png\" />\n        <resource-file src=\"src/android/res/drawable-xhdpi/ic_action_next_item.png\" target=\"res/drawable-xhdpi/ic_action_next_item.png\" />\n        <resource-file src=\"src/android/res/drawable-xxhdpi/ic_action_next_item.png\" target=\"res/drawable-xxhdpi/ic_action_next_item.png\" />\n\n        <resource-file src=\"src/android/res/drawable-hdpi/ic_action_previous_item.png\" target=\"res/drawable-hdpi/ic_action_previous_item.png\" />\n        <resource-file src=\"src/android/res/drawable-mdpi/ic_action_previous_item.png\" target=\"res/drawable-mdpi/ic_action_previous_item.png\" />\n        <resource-file src=\"src/android/res/drawable-xhdpi/ic_action_previous_item.png\" target=\"res/drawable-xhdpi/ic_action_previous_item.png\" />\n        <resource-file src=\"src/android/res/drawable-xxhdpi/ic_action_previous_item.png\" target=\"res/drawable-xxhdpi/ic_action_previous_item.png\" />\n\n        <resource-file src=\"src/android/res/drawable-hdpi/ic_action_remove.png\" target=\"res/drawable-hdpi/ic_action_remove.png\" />\n        <resource-file src=\"src/android/res/drawable-mdpi/ic_action_remove.png\" target=\"res/drawable-mdpi/ic_action_remove.png\" />\n        <resource-file src=\"src/android/res/drawable-xhdpi/ic_action_remove.png\" target=\"res/drawable-xhdpi/ic_action_remove.png\" />\n        <resource-file src=\"src/android/res/drawable-xxhdpi/ic_action_remove.png\" target=\"res/drawable-xxhdpi/ic_action_remove.png\" />\n\n    </platform>\n\n    <!-- amazon-fireos -->\n    <platform name=\"amazon-fireos\">\n        <js-module src=\"www/inappbrowser.js\" name=\"inappbrowser\">\n            <clobbers target=\"cordova.InAppBrowser.open\" />\n            <clobbers target=\"window.open\" />\n        </js-module>\n        <config-file target=\"res/xml/config.xml\" parent=\"/*\">\n            <feature name=\"InAppBrowser\"> \n                <param name=\"android-package\" value=\"org.apache.cordova.inappbrowser.InAppBrowser\"/>\n            </feature>\n        </config-file>\n\n        <source-file src=\"src/amazon/InAppBrowser.java\" target-dir=\"src/org/apache/cordova/inappbrowser\" />\n        <source-file src=\"src/android/InAppBrowserDialog.java\" target-dir=\"src/org/apache/cordova/inappbrowser\" />\n        <source-file src=\"src/amazon/InAppChromeClient.java\" target-dir=\"src/org/apache/cordova/inappbrowser\" />\n        \n        <!--  drawable src/android/resources -->\n        <resource-file src=\"src/android/res/drawable-hdpi/ic_action_next_item.png\" target=\"res/drawable-hdpi/ic_action_next_item.png\" />\n        <resource-file src=\"src/android/res/drawable-mdpi/ic_action_next_item.png\" target=\"res/drawable-mdpi/ic_action_next_item.png\" />\n        <resource-file src=\"src/android/res/drawable-xhdpi/ic_action_next_item.png\" target=\"res/drawable-xhdpi/ic_action_next_item.png\" />\n        <resource-file src=\"src/android/res/drawable-xxhdpi/ic_action_next_item.png\" target=\"res/drawable-xxhdpi/ic_action_next_item.png\" />\n        \n        <resource-file src=\"src/android/res/drawable-hdpi/ic_action_previous_item.png\" target=\"res/drawable-hdpi/ic_action_previous_item.png\" />\n        <resource-file src=\"src/android/res/drawable-mdpi/ic_action_previous_item.png\" target=\"res/drawable-mdpi/ic_action_previous_item.png\" />\n        <resource-file src=\"src/android/res/drawable-xhdpi/ic_action_previous_item.png\" target=\"res/drawable-xhdpi/ic_action_previous_item.png\" />\n        <resource-file src=\"src/android/res/drawable-xxhdpi/ic_action_previous_item.png\" target=\"res/drawable-xxhdpi/ic_action_previous_item.png\" />\n        \n        <resource-file src=\"src/android/res/drawable-hdpi/ic_action_remove.png\" target=\"res/drawable-hdpi/ic_action_remove.png\" />\n        <resource-file src=\"src/android/res/drawable-mdpi/ic_action_remove.png\" target=\"res/drawable-mdpi/ic_action_remove.png\" />\n        <resource-file src=\"src/android/res/drawable-xhdpi/ic_action_remove.png\" target=\"res/drawable-xhdpi/ic_action_remove.png\" />\n        <resource-file src=\"src/android/res/drawable-xxhdpi/ic_action_remove.png\" target=\"res/drawable-xxhdpi/ic_action_remove.png\" />\n    </platform>\n    \n    <!-- ubuntu -->\n    <platform name=\"ubuntu\">\n        <js-module src=\"www/inappbrowser.js\" name=\"inappbrowser\">\n            <clobbers target=\"cordova.InAppBrowser.open\" />\n            <clobbers target=\"window.open\" />\n        </js-module>\n        <header-file src=\"src/ubuntu/inappbrowser.h\" />\n        <source-file src=\"src/ubuntu/inappbrowser.cpp\" />\n        <resource-file src=\"src/ubuntu/InAppBrowser.qml\" />\n        <resource-file src=\"src/ubuntu/InAppBrowser_escapeScript.js\" />\n        <resource-file src=\"src/ubuntu/close.png\" />\n    </platform>\n\n    <!-- ios -->\n    <platform name=\"ios\">\n        <js-module src=\"www/inappbrowser.js\" name=\"inappbrowser\">\n            <clobbers target=\"cordova.InAppBrowser.open\" />\n            <clobbers target=\"window.open\" />\n        </js-module>  \n        <config-file target=\"config.xml\" parent=\"/*\">\n            <feature name=\"InAppBrowser\">\n                <param name=\"ios-package\" value=\"CDVInAppBrowser\" /> \n            </feature>\n        </config-file>\n\n        <header-file src=\"src/ios/CDVInAppBrowser.h\" />\n\t    <source-file src=\"src/ios/CDVInAppBrowser.m\" />\n\t    \n\t    <framework src=\"CoreGraphics.framework\" />\n    </platform>\n\n    <!-- wp7 -->\n    <platform name=\"wp7\">\n        <config-file target=\"Properties/WMAppManifest.xml\" parent=\"/Deployment/App/Capabilities\">\n            <Capability Name=\"ID_CAP_NETWORKING\"/>\n        </config-file>\n\n        <js-module src=\"www/inappbrowser.js\" name=\"inappbrowser\">\n            <clobbers target=\"cordova.InAppBrowser.open\" />\n            <clobbers target=\"window.open\" />\n        </js-module>\n        <config-file target=\"config.xml\" parent=\"/*\">\n            <feature name=\"InAppBrowser\">\n                <param name=\"wp-package\" value=\"InAppBrowser\"/>\n            </feature>\n        </config-file>\n\n        <config-file target=\"Properties/WMAppManifest.xml\" parent=\"/Deployment/App/Capabilities\">\n            <Capability Name=\"ID_CAP_NETWORKING\" />\n        </config-file>\n\n        <source-file src=\"src/wp/InAppBrowser.cs\" />\n    </platform>\n\n    <!-- wp8 -->\n    <platform name=\"wp8\">\n        <config-file target=\"Properties/WMAppManifest.xml\" parent=\"/Deployment/App/Capabilities\">\n            <Capability Name=\"ID_CAP_NETWORKING\"/>\n        </config-file>\n                \n        <js-module src=\"www/inappbrowser.js\" name=\"inappbrowser\">\n            <clobbers target=\"cordova.InAppBrowser.open\" />\n            <clobbers target=\"window.open\" />\n        </js-module>\n        <config-file target=\"config.xml\" parent=\"/*\">\n            <feature name=\"InAppBrowser\">\n                <param name=\"wp-package\" value=\"InAppBrowser\"/>\n            </feature>\n        </config-file>\n\n        <config-file target=\"Properties/WMAppManifest.xml\" parent=\"/Deployment/App/Capabilities\">\n            <Capability Name=\"ID_CAP_NETWORKING\" />\n        </config-file>\n\n        <source-file src=\"src/wp/InAppBrowser.cs\" />\n    </platform>\n\n    <!-- windows8 -->\n    <platform name=\"windows8\">\n        <js-module src=\"www/inappbrowser.js\" name=\"inappbrowser\">\n            <clobbers target=\"cordova.InAppBrowser.open\" />\n            <clobbers target=\"window.open\" />\n        </js-module>\n        <js-module src=\"www/windows8/InAppBrowserProxy.js\" name=\"InAppBrowserProxy\">\n            <merges target=\"\" />\n        </js-module>\n    </platform>\n\n    <!-- windows universal apps (Windows 8.1, Windows Phone 8.1, Windows 8.0) -->\n    <platform name=\"windows\">\n        <js-module src=\"www/inappbrowser.js\" name=\"inappbrowser\">\n            <clobbers target=\"cordova.InAppBrowser.open\" />\n            <clobbers target=\"window.open\" />\n        </js-module>\n        <js-module src=\"src/windows/InAppBrowserProxy.js\" name=\"InAppBrowserProxy\">\n            <merges target=\"\" />\n        </js-module>\n        <asset src=\"www/inappbrowser.css\" target=\"css/inappbrowser.css\" />\n    </platform>\n  \n    <!-- firefoxos -->\n    <platform name=\"firefoxos\">\n        <config-file target=\"config.xml\" parent=\"/*\">\n            <permission name=\"browser\" description=\"Enables the app to implement a browser in an iframe.\" privileged=\"true\"/>\n        </config-file>\n        <js-module src=\"www/inappbrowser.js\" name=\"inappbrowser\">\n            <clobbers target=\"cordova.InAppBrowser.open\" />\n            <clobbers target=\"window.open\" />\n        </js-module>\n        <js-module src=\"src/firefoxos/InAppBrowserProxy.js\" name=\"InAppBrowserProxy\">\n            <merges target=\"\" />\n        </js-module>\n    </platform>\n\n    <!-- browser -->\n    <platform name=\"browser\">\n        <js-module src=\"www/inappbrowser.js\" name=\"inappbrowser\">\n            <clobbers target=\"cordova.InAppBrowser.open\" />\n            <clobbers target=\"window.open\" />\n        </js-module>\n        <js-module src=\"src/browser/InAppBrowserProxy.js\" name=\"InAppBrowserProxy\">\n            <merges target=\"\" />\n        </js-module>\n    </platform>\n</plugin>\n"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/src/amazon/InAppBrowser.java",
    "content": "/*\n       Licensed to the Apache Software Foundation (ASF) under one\n       or more contributor license agreements.  See the NOTICE file\n       distributed with this work for additional information\n       regarding copyright ownership.  The ASF licenses this file\n       to you under the Apache License, Version 2.0 (the\n       \"License\"); you may not use this file except in compliance\n       with the License.  You may obtain a copy of the License at\n\n         http://www.apache.org/licenses/LICENSE-2.0\n\n       Unless required by applicable law or agreed to in writing,\n       software distributed under the License is distributed on an\n       \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n       KIND, either express or implied.  See the License for the\n       specific language governing permissions and limitations\n       under the License.\n*/\npackage org.apache.cordova.inappbrowser;\n\nimport android.annotation.SuppressLint;\nimport org.apache.cordova.inappbrowser.InAppBrowserDialog;\nimport android.content.Context;\nimport android.content.DialogInterface;\nimport android.content.Intent;\nimport android.content.res.Resources;\nimport android.graphics.Bitmap;\nimport android.graphics.drawable.Drawable;\nimport android.net.Uri;\nimport android.os.Build;\nimport android.os.Bundle;\nimport android.text.InputType;\nimport android.util.Log;\nimport android.util.TypedValue;\nimport android.view.Gravity;\nimport android.view.KeyEvent;\nimport android.view.View;\nimport android.view.Window;\nimport android.view.WindowManager;\nimport android.view.WindowManager.LayoutParams;\nimport android.view.inputmethod.EditorInfo;\nimport android.view.inputmethod.InputMethodManager;\nimport com.amazon.android.webkit.AmazonWebChromeClient;\nimport com.amazon.android.webkit.AmazonGeolocationPermissions.Callback;\nimport com.amazon.android.webkit.AmazonJsPromptResult;\nimport com.amazon.android.webkit.AmazonWebSettings;\nimport com.amazon.android.webkit.AmazonWebStorage;\nimport com.amazon.android.webkit.AmazonWebView;\nimport com.amazon.android.webkit.AmazonWebViewClient;\nimport com.amazon.android.webkit.AmazonCookieManager;\nimport android.widget.Button;\nimport android.widget.EditText;\nimport android.widget.LinearLayout;\nimport android.widget.RelativeLayout;\n\nimport org.apache.cordova.CallbackContext;\nimport org.apache.cordova.Config;\nimport org.apache.cordova.CordovaArgs;\nimport org.apache.cordova.CordovaPlugin;\nimport org.apache.cordova.CordovaWebView;\nimport org.apache.cordova.LOG;\nimport org.apache.cordova.PluginResult;\nimport org.apache.cordova.CordovaActivity;\nimport org.json.JSONException;\nimport org.json.JSONObject;\n\nimport java.util.HashMap;\nimport java.util.StringTokenizer;\n\n@SuppressLint(\"SetJavaScriptEnabled\")\npublic class InAppBrowser extends CordovaPlugin {\n\n    private static final String NULL = \"null\";\n    protected static final String LOG_TAG = \"InAppBrowser\";\n    private static final String SELF = \"_self\";\n    private static final String SYSTEM = \"_system\";\n    // private static final String BLANK = \"_blank\";\n    private static final String EXIT_EVENT = \"exit\";\n    private static final String LOCATION = \"location\";\n    private static final String HIDDEN = \"hidden\";\n    private static final String ZOOM = \"zoom\";\n    private static final String LOAD_START_EVENT = \"loadstart\";\n    private static final String LOAD_STOP_EVENT = \"loadstop\";\n    private static final String LOAD_ERROR_EVENT = \"loaderror\";\n    private static final String CLEAR_ALL_CACHE = \"clearcache\";\n    private static final String CLEAR_SESSION_CACHE = \"clearsessioncache\";\n\n    private InAppBrowserDialog dialog;\n    private AmazonWebView inAppWebView;\n    private EditText edittext;\n    private CallbackContext callbackContext;\n    private boolean showLocationBar = true;\n    private boolean showZoomControls = true;\n    private boolean openWindowHidden = false;\n    private boolean clearAllCache= false;\n    private boolean clearSessionCache=false;\n\n    /**\n     * Executes the request and returns PluginResult.\n     *\n     * @param action        The action to execute.\n     * @param args          JSONArry of arguments for the plugin.\n     * @param callbackId    The callback id used when calling back into JavaScript.\n     * @return              A PluginResult object with a status and message.\n     */\n    public boolean execute(String action, CordovaArgs args, final CallbackContext callbackContext) throws JSONException {\n        if (action.equals(\"open\")) {\n            this.callbackContext = callbackContext;\n            final String url = args.getString(0);\n            String t = args.optString(1);\n            if (t == null || t.equals(\"\") || t.equals(NULL)) {\n                t = SELF;\n            }\n            final String target = t;\n            final HashMap<String, Boolean> features = parseFeature(args.optString(2));\n            \n            Log.d(LOG_TAG, \"target = \" + target);\n            \n            this.cordova.getActivity().runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    String result = \"\";\n                    // SELF\n                    if (SELF.equals(target)) {\n                        Log.d(LOG_TAG, \"in self\");\n                        // load in webview\n                        if (url.startsWith(\"file://\") || url.startsWith(\"javascript:\") \n                                || Config.isUrlWhiteListed(url)) {\n                            Log.d(LOG_TAG, \"loading in webview\");\n                            webView.loadUrl(url);\n                        }\n                        //Load the dialer\n                        else if (url.startsWith(AmazonWebView.SCHEME_TEL))\n                        {\n                            try {\n                                Log.d(LOG_TAG, \"loading in dialer\");\n                                Intent intent = new Intent(Intent.ACTION_DIAL);\n                                intent.setData(Uri.parse(url));\n                                cordova.getActivity().startActivity(intent);\n                            } catch (android.content.ActivityNotFoundException e) {\n                                LOG.e(LOG_TAG, \"Error dialing \" + url + \": \" + e.toString());\n                            }\n                        }\n                        // load in InAppBrowser\n                        else {\n                            Log.d(LOG_TAG, \"loading in InAppBrowser\");\n                            result = showWebPage(url, features);\n                        }\n                    }\n                    // SYSTEM\n                    else if (SYSTEM.equals(target)) {\n                        Log.d(LOG_TAG, \"in system\");\n                        result = openExternal(url);\n                    }\n                    // BLANK - or anything else\n                    else {\n                        Log.d(LOG_TAG, \"in blank\");\n                        result = showWebPage(url, features);\n                    }\n    \n                    PluginResult pluginResult = new PluginResult(PluginResult.Status.OK, result);\n                    pluginResult.setKeepCallback(true);\n                    callbackContext.sendPluginResult(pluginResult);\n                }\n            });\n        }\n        else if (action.equals(\"close\")) {\n            closeDialog();\n        }\n        else if (action.equals(\"injectScriptCode\")) {\n            String jsWrapper = null;\n            if (args.getBoolean(1)) {\n                jsWrapper = String.format(\"prompt(JSON.stringify([eval(%%s)]), 'gap-iab://%s')\", callbackContext.getCallbackId());\n            }\n            injectDeferredObject(args.getString(0), jsWrapper);\n        }\n        else if (action.equals(\"injectScriptFile\")) {\n            String jsWrapper;\n            if (args.getBoolean(1)) {\n                jsWrapper = String.format(\"(function(d) { var c = d.createElement('script'); c.src = %%s; c.onload = function() { prompt('', 'gap-iab://%s'); }; d.body.appendChild(c); })(document)\", callbackContext.getCallbackId());\n            } else {\n                jsWrapper = \"(function(d) { var c = d.createElement('script'); c.src = %s; d.body.appendChild(c); })(document)\";\n            }\n            injectDeferredObject(args.getString(0), jsWrapper);\n        }\n        else if (action.equals(\"injectStyleCode\")) {\n            String jsWrapper;\n            if (args.getBoolean(1)) {\n                jsWrapper = String.format(\"(function(d) { var c = d.createElement('style'); c.innerHTML = %%s; d.body.appendChild(c); prompt('', 'gap-iab://%s');})(document)\", callbackContext.getCallbackId());\n            } else {\n                jsWrapper = \"(function(d) { var c = d.createElement('style'); c.innerHTML = %s; d.body.appendChild(c); })(document)\";\n            }\n            injectDeferredObject(args.getString(0), jsWrapper);\n        }\n        else if (action.equals(\"injectStyleFile\")) {\n            String jsWrapper;\n            if (args.getBoolean(1)) {\n                jsWrapper = String.format(\"(function(d) { var c = d.createElement('link'); c.rel='stylesheet'; c.type='text/css'; c.href = %%s; d.head.appendChild(c); prompt('', 'gap-iab://%s');})(document)\", callbackContext.getCallbackId());\n            } else {\n                jsWrapper = \"(function(d) { var c = d.createElement('link'); c.rel='stylesheet'; c.type='text/css'; c.href = %s; d.head.appendChild(c); })(document)\";\n            }\n            injectDeferredObject(args.getString(0), jsWrapper);\n        }\n        else if (action.equals(\"show\")) {\n            this.cordova.getActivity().runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    dialog.show();\n                }\n            });\n            PluginResult pluginResult = new PluginResult(PluginResult.Status.OK);\n            pluginResult.setKeepCallback(true);\n            this.callbackContext.sendPluginResult(pluginResult);\n        }\n        else {\n            return false;\n        }\n        return true;\n    }\n\n    /**\n     * Called when the view navigates.\n     */\n    @Override\n    public void onReset() {\n        closeDialog();        \n    }\n    \n    /**\n     * Called by AccelBroker when listener is to be shut down.\n     * Stop listener.\n     */\n    public void onDestroy() {\n        closeDialog();\n    }\n    \n    /**\n     * Inject an object (script or style) into the InAppBrowser AmazonWebView.\n     *\n     * This is a helper method for the inject{Script|Style}{Code|File} API calls, which\n     * provides a consistent method for injecting JavaScript code into the document.\n     *\n     * If a wrapper string is supplied, then the source string will be JSON-encoded (adding\n     * quotes) and wrapped using string formatting. (The wrapper string should have a single\n     * '%s' marker)\n     *\n     * @param source      The source object (filename or script/style text) to inject into\n     *                    the document.\n     * @param jsWrapper   A JavaScript string to wrap the source string in, so that the object\n     *                    is properly injected, or null if the source string is JavaScript text\n     *                    which should be executed directly.\n     */\n    private void injectDeferredObject(String source, String jsWrapper) {\n        final String scriptToInject;\n        if (jsWrapper != null) {\n            org.json.JSONArray jsonEsc = new org.json.JSONArray();\n            jsonEsc.put(source);\n            String jsonRepr = jsonEsc.toString();\n            String jsonSourceString = jsonRepr.substring(1, jsonRepr.length()-1);\n            scriptToInject = String.format(jsWrapper, jsonSourceString);\n        } else {\n            scriptToInject = source;\n        }\n        final String finalScriptToInject = scriptToInject;\n        this.cordova.getActivity().runOnUiThread(new Runnable() {\n            @SuppressLint(\"NewApi\")\n            @Override\n            public void run() {\n                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {\n                    // This action will have the side-effect of blurring the currently focused element\n                    inAppWebView.loadUrl(\"javascript:\" + finalScriptToInject);\n                } /*else {\n                    inAppWebView.evaluateJavascript(finalScriptToInject, null);\n                }*/\n            }\n        });\n    }\n\n    /**\n     * Put the list of features into a hash map\n     * \n     * @param optString\n     * @return\n     */\n    private HashMap<String, Boolean> parseFeature(String optString) {\n        if (optString.equals(NULL)) {\n            return null;\n        } else {\n            HashMap<String, Boolean> map = new HashMap<String, Boolean>();\n            StringTokenizer features = new StringTokenizer(optString, \",\");\n            StringTokenizer option;\n            while(features.hasMoreElements()) {\n                option = new StringTokenizer(features.nextToken(), \"=\");\n                if (option.hasMoreElements()) {\n                    String key = option.nextToken();\n                    Boolean value = option.nextToken().equals(\"no\") ? Boolean.FALSE : Boolean.TRUE;\n                    map.put(key, value);\n                }\n            }\n            return map;\n        }\n    }\n\n    /**\n     * Display a new browser with the specified URL.\n     *\n     * @param url           The url to load.\n     * @param usePhoneGap   Load url in PhoneGap webview\n     * @return              \"\" if ok, or error message.\n     */\n    public String openExternal(String url) {\n        try {\n            Intent intent = null;\n            intent = new Intent(Intent.ACTION_VIEW);\n            // Omitting the MIME type for file: URLs causes \"No Activity found to handle Intent\".\n            // Adding the MIME type to http: URLs causes them to not be handled by the downloader.\n            Uri uri = Uri.parse(url);\n            if (\"file\".equals(uri.getScheme())) {\n                intent.setDataAndType(uri, webView.getResourceApi().getMimeType(uri));\n            } else {\n                intent.setData(uri);\n            }\n            this.cordova.getActivity().startActivity(intent);\n            return \"\";\n        } catch (android.content.ActivityNotFoundException e) {\n            Log.d(LOG_TAG, \"InAppBrowser: Error loading url \"+url+\":\"+ e.toString());\n            return e.toString();\n        }\n    }\n\n    /**\n     * Closes the dialog\n     */\n    public void closeDialog() {\n        final AmazonWebView childView = this.inAppWebView;\n        // The JS protects against multiple calls, so this should happen only when\n        // closeDialog() is called by other native code.\n        if (childView == null) {\n            return;\n        }\n        this.cordova.getActivity().runOnUiThread(new Runnable() {\n            @Override\n            public void run() {\n                childView.setWebViewClient(new AmazonWebViewClient() {\n                    // NB: wait for about:blank before dismissing\n                    public void onPageFinished(AmazonWebView view, String url) {\n                        if (dialog != null) {\n                            dialog.dismiss();\n                        }\n                    }\n                });\n                // NB: From SDK 19: \"If you call methods on WebView from any thread\n                // other than your app's UI thread, it can cause unexpected results.\"\n                // http://developer.android.com/guide/webapps/migrating.html#Threads\n                childView.loadUrl(\"about:blank\");\n            }\n        });\n        \n        try {\n            JSONObject obj = new JSONObject();\n            obj.put(\"type\", EXIT_EVENT);\n            sendUpdate(obj, false);\n        } catch (JSONException ex) {\n            Log.d(LOG_TAG, \"Should never happen\");\n        }\n    }\n    /**\n     * Checks to see if it is possible to go back one page in history, then does so.\n     */\n    private void goBack() {\n        this.cordova.getActivity().runOnUiThread(new Runnable() {\n            public void run() {\n                if (InAppBrowser.this.inAppWebView.canGoBack()) {\n                    InAppBrowser.this.inAppWebView.goBack();\n                }\n            }\n        });\n    }\n\n    /**\n     * Checks to see if it is possible to go forward one page in history, then does so.\n     */\n    private void goForward() {\n        this.cordova.getActivity().runOnUiThread(new Runnable() {\n            public void run() {\n                if (InAppBrowser.this.inAppWebView.canGoForward()) {\n                    InAppBrowser.this.inAppWebView.goForward();\n                }\n            }\n        });\n    }\n\n    /**\n     * Navigate to the new page\n     *\n     * @param url to load\n     */\n    private void navigate(final String url) {\n        InputMethodManager imm = (InputMethodManager)this.cordova.getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);\n        imm.hideSoftInputFromWindow(edittext.getWindowToken(), 0);\n\n        this.cordova.getActivity().runOnUiThread(new Runnable() {\n            public void run() {\n                if (!url.startsWith(\"http\") && !url.startsWith(\"file:\")) {\n                    InAppBrowser.this.inAppWebView.loadUrl(\"http://\" + url);\n                } else {\n                    InAppBrowser.this.inAppWebView.loadUrl(url);\n                }\n                InAppBrowser.this.inAppWebView.requestFocus();\n            }\n        });\n    }\n\n\n    /**\n     * Should we show the location bar?\n     *\n     * @return boolean\n     */\n    private boolean getShowLocationBar() {\n        return this.showLocationBar;\n    }\n\n    /**\n     * Should we show the zoom controls?\n     *\n     * @return boolean\n     */\n    private boolean getShowZoomControls() {\n        return this.showZoomControls;\n    }\n\n    private InAppBrowser getInAppBrowser(){\n        return this;\n    }\n\n    /**\n     * Display a new browser with the specified URL.\n     *\n     * @param url           The url to load.\n     * @param jsonObject\n     */\n    public String showWebPage(final String url, HashMap<String, Boolean> features) {\n        // Determine if we should hide the location bar.\n        showLocationBar = true;\n        showZoomControls = true;\n        openWindowHidden = false;\n        if (features != null) {\n            Boolean show = features.get(LOCATION);\n            if (show != null) {\n                showLocationBar = show.booleanValue();\n            }\n            Boolean zoom = features.get(ZOOM);\n            if (zoom != null) {\n                showZoomControls = zoom.booleanValue();\n            }\n            Boolean hidden = features.get(HIDDEN);\n            if (hidden != null) {\n                openWindowHidden = hidden.booleanValue();\n            }\n            Boolean cache = features.get(CLEAR_ALL_CACHE);\n            if (cache != null) {\n                clearAllCache = cache.booleanValue();\n            } else {\n                cache = features.get(CLEAR_SESSION_CACHE);\n                if (cache != null) {\n                    clearSessionCache = cache.booleanValue();\n                }\n            }\n        }\n        \n        final CordovaWebView thatWebView = this.webView;\n\n        // Create dialog in new thread\n        Runnable runnable = new Runnable() {\n            /**\n             * Convert our DIP units to Pixels\n             *\n             * @return int\n             */\n            private int dpToPixels(int dipValue) {\n                int value = (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP,\n                                                            (float) dipValue,\n                                                            cordova.getActivity().getResources().getDisplayMetrics()\n                );\n\n                return value;\n            }\n\n            @SuppressLint(\"NewApi\")\n            public void run() {\n                // Let's create the main dialog\n                dialog = new InAppBrowserDialog(cordova.getActivity(), android.R.style.Theme_NoTitleBar);\n                dialog.getWindow().getAttributes().windowAnimations = android.R.style.Animation_Dialog;\n                dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);\n                dialog.setCancelable(true);\n                dialog.setInAppBroswer(getInAppBrowser());\n\n                // Main container layout\n                LinearLayout main = new LinearLayout(cordova.getActivity());\n                main.setOrientation(LinearLayout.VERTICAL);\n\n                // Toolbar layout\n                RelativeLayout toolbar = new RelativeLayout(cordova.getActivity());\n                //Please, no more black! \n                toolbar.setBackgroundColor(android.graphics.Color.LTGRAY);\n                toolbar.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, this.dpToPixels(44)));\n                toolbar.setPadding(this.dpToPixels(2), this.dpToPixels(2), this.dpToPixels(2), this.dpToPixels(2));\n                toolbar.setHorizontalGravity(Gravity.LEFT);\n                toolbar.setVerticalGravity(Gravity.TOP);\n\n                // Action Button Container layout\n                RelativeLayout actionButtonContainer = new RelativeLayout(cordova.getActivity());\n                actionButtonContainer.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));\n                actionButtonContainer.setHorizontalGravity(Gravity.LEFT);\n                actionButtonContainer.setVerticalGravity(Gravity.CENTER_VERTICAL);\n                actionButtonContainer.setId(1);\n\n                // Back button\n                Button back = new Button(cordova.getActivity());\n                RelativeLayout.LayoutParams backLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);\n                backLayoutParams.addRule(RelativeLayout.ALIGN_LEFT);\n                back.setLayoutParams(backLayoutParams);\n                back.setContentDescription(\"Back Button\");\n                back.setId(2);\n                Resources activityRes = cordova.getActivity().getResources();\n                int backResId = activityRes.getIdentifier(\"ic_action_previous_item\", \"drawable\", cordova.getActivity().getPackageName());\n                Drawable backIcon = activityRes.getDrawable(backResId);\n                if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN)\n                {\n                    back.setBackgroundDrawable(backIcon);\n                }\n                else\n                {\n                    back.setBackground(backIcon);\n                }\n\n                back.setOnClickListener(new View.OnClickListener() {\n                    public void onClick(View v) {\n                        goBack();\n                    }\n                });\n\n                // Forward button\n                Button forward = new Button(cordova.getActivity());\n                RelativeLayout.LayoutParams forwardLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);\n                forwardLayoutParams.addRule(RelativeLayout.RIGHT_OF, 2);\n                forward.setLayoutParams(forwardLayoutParams);\n                forward.setContentDescription(\"Forward Button\");\n                forward.setId(3);\n                int fwdResId = activityRes.getIdentifier(\"ic_action_next_item\", \"drawable\", cordova.getActivity().getPackageName());\n                Drawable fwdIcon = activityRes.getDrawable(fwdResId);\n                if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN)\n                {\n                    forward.setBackgroundDrawable(fwdIcon);\n                }\n                else\n                {\n                    forward.setBackground(fwdIcon);\n                }\n                forward.setOnClickListener(new View.OnClickListener() {\n                    public void onClick(View v) {\n                        goForward();\n                    }\n                });\n\n                // Edit Text Box\n                edittext = new EditText(cordova.getActivity());\n                RelativeLayout.LayoutParams textLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);\n                textLayoutParams.addRule(RelativeLayout.RIGHT_OF, 1);\n                textLayoutParams.addRule(RelativeLayout.LEFT_OF, 5);\n                edittext.setLayoutParams(textLayoutParams);\n                edittext.setId(4);\n                edittext.setSingleLine(true);\n                edittext.setText(url);\n                edittext.setInputType(InputType.TYPE_TEXT_VARIATION_URI);\n                edittext.setImeOptions(EditorInfo.IME_ACTION_GO);\n                edittext.setInputType(InputType.TYPE_NULL); // Will not except input... Makes the text NON-EDITABLE\n                edittext.setOnKeyListener(new View.OnKeyListener() {\n                    public boolean onKey(View v, int keyCode, KeyEvent event) {\n                        // If the event is a key-down event on the \"enter\" button\n                        if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) {\n                          navigate(edittext.getText().toString());\n                          return true;\n                        }\n                        return false;\n                    }\n                });\n\n                // Close/Done button\n                Button close = new Button(cordova.getActivity());\n                RelativeLayout.LayoutParams closeLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);\n                closeLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);\n                close.setLayoutParams(closeLayoutParams);\n                forward.setContentDescription(\"Close Button\");\n                close.setId(5);\n                int closeResId = activityRes.getIdentifier(\"ic_action_remove\", \"drawable\", cordova.getActivity().getPackageName());\n                Drawable closeIcon = activityRes.getDrawable(closeResId);\n                if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN)\n                {\n                    close.setBackgroundDrawable(closeIcon);\n                }\n                else\n                {\n                    close.setBackground(closeIcon);\n                }\n                close.setOnClickListener(new View.OnClickListener() {\n                    public void onClick(View v) {\n                        closeDialog();\n                    }\n                });\n\n                // WebView\n                inAppWebView = new AmazonWebView(cordova.getActivity());\n                \n                CordovaActivity app = (CordovaActivity) cordova.getActivity();\n                cordova.getFactory().initializeWebView(inAppWebView, 0x00FF00, false, null);\n                \n                inAppWebView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));\n                inAppWebView.setWebChromeClient(new InAppChromeClient(thatWebView));\n                AmazonWebViewClient client = new InAppBrowserClient(thatWebView, edittext);\n                inAppWebView.setWebViewClient(client);\n                AmazonWebSettings settings = inAppWebView.getSettings();\n                settings.setJavaScriptEnabled(true);\n                settings.setJavaScriptCanOpenWindowsAutomatically(true);\n                settings.setBuiltInZoomControls(getShowZoomControls());\n                settings.setPluginState(com.amazon.android.webkit.AmazonWebSettings.PluginState.ON);\n\n                //Toggle whether this is enabled or not!\n                Bundle appSettings = cordova.getActivity().getIntent().getExtras();\n                boolean enableDatabase = appSettings == null ? true : appSettings.getBoolean(\"InAppBrowserStorageEnabled\", true);\n                if (enableDatabase) {\n                    String databasePath = cordova.getActivity().getApplicationContext().getDir(\"inAppBrowserDB\", Context.MODE_PRIVATE).getPath();\n                    settings.setDatabasePath(databasePath);\n                    settings.setDatabaseEnabled(true);\n                }\n                settings.setDomStorageEnabled(true);\n\n                if (clearAllCache) {\n                    AmazonCookieManager.getInstance().removeAllCookie();\n                } else if (clearSessionCache) {\n                    AmazonCookieManager.getInstance().removeSessionCookie();\n                }\n\n                inAppWebView.loadUrl(url);\n                inAppWebView.setId(6);\n                inAppWebView.getSettings().setLoadWithOverviewMode(true);\n                inAppWebView.getSettings().setUseWideViewPort(true);\n                inAppWebView.requestFocus();\n                inAppWebView.requestFocusFromTouch();\n\n                // Add the back and forward buttons to our action button container layout\n                actionButtonContainer.addView(back);\n                actionButtonContainer.addView(forward);\n\n                // Add the views to our toolbar\n                toolbar.addView(actionButtonContainer);\n                toolbar.addView(edittext);\n                toolbar.addView(close);\n\n                // Don't add the toolbar if its been disabled\n                if (getShowLocationBar()) {\n                    // Add our toolbar to our main view/layout\n                    main.addView(toolbar);\n                }\n\n                // Add our webview to our main view/layout\n                main.addView(inAppWebView);\n\n                WindowManager.LayoutParams lp = new WindowManager.LayoutParams();\n                lp.copyFrom(dialog.getWindow().getAttributes());\n                lp.width = WindowManager.LayoutParams.MATCH_PARENT;\n                lp.height = WindowManager.LayoutParams.MATCH_PARENT;\n\n                dialog.setContentView(main);\n                dialog.show();\n                dialog.getWindow().setAttributes(lp);\n                // the goal of openhidden is to load the url and not display it\n                // Show() needs to be called to cause the URL to be loaded\n                if(openWindowHidden) {\n                    dialog.hide();\n                }\n            }\n        };\n        this.cordova.getActivity().runOnUiThread(runnable);\n        return \"\";\n    }\n\n    /**\n     * Create a new plugin success result and send it back to JavaScript\n     *\n     * @param obj a JSONObject contain event payload information\n     */\n    private void sendUpdate(JSONObject obj, boolean keepCallback) {\n        sendUpdate(obj, keepCallback, PluginResult.Status.OK);\n    }\n\n    /**\n     * Create a new plugin result and send it back to JavaScript\n     *\n     * @param obj a JSONObject contain event payload information\n     * @param status the status code to return to the JavaScript environment\n     */    \n    private void sendUpdate(JSONObject obj, boolean keepCallback, PluginResult.Status status) {\n        if (callbackContext != null) {\n            PluginResult result = new PluginResult(status, obj);\n            result.setKeepCallback(keepCallback);\n            callbackContext.sendPluginResult(result);\n            if (!keepCallback) {\n                callbackContext = null;\n            }\n        }\n    }\n    \n    /**\n     * The webview client receives notifications about appView\n     */\n    public class InAppBrowserClient extends AmazonWebViewClient {\n        EditText edittext;\n        CordovaWebView webView;\n\n        /**\n         * Constructor.\n         *\n         * @param mContext\n         * @param edittext\n         */\n        public InAppBrowserClient(CordovaWebView webView, EditText mEditText) {\n            this.webView = webView;\n            this.edittext = mEditText;\n        }\n\n        /**\n         * Notify the host application that a page has started loading.\n         *\n         * @param view          The webview initiating the callback.\n         * @param url           The url of the page.\n         */\n        @Override\n        public void onPageStarted(AmazonWebView view, String url,  Bitmap favicon) {\n            super.onPageStarted(view, url, favicon);\n            String newloc = \"\";\n            if (url.startsWith(\"http:\") || url.startsWith(\"https:\") || url.startsWith(\"file:\")) {\n                newloc = url;\n            } \n            // If dialing phone (tel:5551212)\n            else if (url.startsWith(AmazonWebView.SCHEME_TEL)) {\n                try {\n                    Intent intent = new Intent(Intent.ACTION_DIAL);\n                    intent.setData(Uri.parse(url));\n                    cordova.getActivity().startActivity(intent);\n                } catch (android.content.ActivityNotFoundException e) {\n                    LOG.e(LOG_TAG, \"Error dialing \" + url + \": \" + e.toString());\n                }\n            }\n\n            else if (url.startsWith(\"geo:\") || url.startsWith(AmazonWebView.SCHEME_MAILTO) || url.startsWith(\"market:\")) {\n                try {\n                    Intent intent = new Intent(Intent.ACTION_VIEW);\n                    intent.setData(Uri.parse(url));\n                    cordova.getActivity().startActivity(intent);\n                } catch (android.content.ActivityNotFoundException e) {\n                    LOG.e(LOG_TAG, \"Error with \" + url + \": \" + e.toString());\n                }\n            }\n            // If sms:5551212?body=This is the message\n            else if (url.startsWith(\"sms:\")) {\n                try {\n                    Intent intent = new Intent(Intent.ACTION_VIEW);\n\n                    // Get address\n                    String address = null;\n                    int parmIndex = url.indexOf('?');\n                    if (parmIndex == -1) {\n                        address = url.substring(4);\n                    }\n                    else {\n                        address = url.substring(4, parmIndex);\n\n                        // If body, then set sms body\n                        Uri uri = Uri.parse(url);\n                        String query = uri.getQuery();\n                        if (query != null) {\n                            if (query.startsWith(\"body=\")) {\n                                intent.putExtra(\"sms_body\", query.substring(5));\n                            }\n                        }\n                    }\n                    intent.setData(Uri.parse(\"sms:\" + address));\n                    intent.putExtra(\"address\", address);\n                    intent.setType(\"vnd.android-dir/mms-sms\");\n                    cordova.getActivity().startActivity(intent);\n                } catch (android.content.ActivityNotFoundException e) {\n                    LOG.e(LOG_TAG, \"Error sending sms \" + url + \":\" + e.toString());\n                }\n            }\n            else {\n                newloc = \"http://\" + url;\n            }\n\n            if (!newloc.equals(edittext.getText().toString())) {\n                edittext.setText(newloc);\n            }\n\n            try {\n                JSONObject obj = new JSONObject();\n                obj.put(\"type\", LOAD_START_EVENT);\n                obj.put(\"url\", newloc);\n    \n                sendUpdate(obj, true);\n            } catch (JSONException ex) {\n                Log.d(LOG_TAG, \"Should never happen\");\n            }\n        }\n        \n        public void onPageFinished(AmazonWebView view, String url) {\n            super.onPageFinished(view, url);\n            \n            try {\n                JSONObject obj = new JSONObject();\n                obj.put(\"type\", LOAD_STOP_EVENT);\n                obj.put(\"url\", url);\n    \n                sendUpdate(obj, true);\n            } catch (JSONException ex) {\n                Log.d(LOG_TAG, \"Should never happen\");\n            }\n        }\n        \n        public void onReceivedError(AmazonWebView view, int errorCode, String description, String failingUrl) {\n            super.onReceivedError(view, errorCode, description, failingUrl);\n            \n            try {\n                JSONObject obj = new JSONObject();\n                obj.put(\"type\", LOAD_ERROR_EVENT);\n                obj.put(\"url\", failingUrl);\n                obj.put(\"code\", errorCode);\n                obj.put(\"message\", description);\n    \n                sendUpdate(obj, true, PluginResult.Status.ERROR);\n            } catch (JSONException ex) {\n                Log.d(LOG_TAG, \"Should never happen\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/src/amazon/InAppChromeClient.java",
    "content": "/*\n       Licensed to the Apache Software Foundation (ASF) under one\n       or more contributor license agreements.  See the NOTICE file\n       distributed with this work for additional information\n       regarding copyright ownership.  The ASF licenses this file\n       to you under the Apache License, Version 2.0 (the\n       \"License\"); you may not use this file except in compliance\n       with the License.  You may obtain a copy of the License at\n\n         http://www.apache.org/licenses/LICENSE-2.0\n\n       Unless required by applicable law or agreed to in writing,\n       software distributed under the License is distributed on an\n       \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n       KIND, either express or implied.  See the License for the\n       specific language governing permissions and limitations\n       under the License.\n*/\npackage org.apache.cordova.inappbrowser;\n\nimport org.apache.cordova.CordovaWebView;\nimport org.apache.cordova.LOG;\nimport org.apache.cordova.PluginResult;\nimport org.json.JSONArray;\nimport org.json.JSONException;\n\nimport com.amazon.android.webkit.AmazonWebChromeClient;\nimport com.amazon.android.webkit.AmazonGeolocationPermissions.Callback;\nimport com.amazon.android.webkit.AmazonJsPromptResult;\nimport com.amazon.android.webkit.AmazonWebStorage;\nimport com.amazon.android.webkit.AmazonWebView;\nimport com.amazon.android.webkit.AmazonWebViewClient;\n\npublic class InAppChromeClient extends AmazonWebChromeClient {\n\n    private CordovaWebView webView;\n    private String LOG_TAG = \"InAppChromeClient\";\n    private long MAX_QUOTA = 100 * 1024 * 1024;\n\n    public InAppChromeClient(CordovaWebView webView) {\n        super();\n        this.webView = webView;\n    }\n    /**\n     * Handle database quota exceeded notification.\n     *\n     * @param url\n     * @param databaseIdentifier\n     * @param currentQuota\n     * @param estimatedSize\n     * @param totalUsedQuota\n     * @param quotaUpdater\n     */\n    @Override\n    public void onExceededDatabaseQuota(String url, String databaseIdentifier, long currentQuota, long estimatedSize,\n            long totalUsedQuota, AmazonWebStorage.QuotaUpdater quotaUpdater)\n    {\n        LOG.d(LOG_TAG, \"onExceededDatabaseQuota estimatedSize: %d  currentQuota: %d  totalUsedQuota: %d\", estimatedSize, currentQuota, totalUsedQuota);\n\n        if (estimatedSize < MAX_QUOTA)\n        {\n            //increase for 1Mb\n            long newQuota = estimatedSize;\n            LOG.d(LOG_TAG, \"calling quotaUpdater.updateQuota newQuota: %d\", newQuota);\n            quotaUpdater.updateQuota(newQuota);\n        }\n        else\n        {\n            // Set the quota to whatever it is and force an error\n            // TODO: get docs on how to handle this properly\n            quotaUpdater.updateQuota(currentQuota);\n        }\n    }\n\n    /**\n     * Instructs the client to show a prompt to ask the user to set the Geolocation permission state for the specified origin.\n     *\n     * @param origin\n     * @param callback\n     */\n    @Override\n    public void onGeolocationPermissionsShowPrompt(String origin, Callback callback) {\n        super.onGeolocationPermissionsShowPrompt(origin, callback);\n        callback.invoke(origin, true, false);\n    }\n\n    /**\n     * Tell the client to display a prompt dialog to the user.\n     * If the client returns true, WebView will assume that the client will\n     * handle the prompt dialog and call the appropriate JsPromptResult method.\n     *\n     * The prompt bridge provided for the InAppBrowser is capable of executing any\n     * oustanding callback belonging to the InAppBrowser plugin. Care has been\n     * taken that other callbacks cannot be triggered, and that no other code\n     * execution is possible.\n     *\n     * To trigger the bridge, the prompt default value should be of the form:\n     *\n     * gap-iab://<callbackId>\n     *\n     * where <callbackId> is the string id of the callback to trigger (something\n     * like \"InAppBrowser0123456789\")\n     *\n     * If present, the prompt message is expected to be a JSON-encoded value to\n     * pass to the callback. A JSON_EXCEPTION is returned if the JSON is invalid.\n     *\n     * @param view\n     * @param url\n     * @param message\n     * @param defaultValue\n     * @param result\n     */\n    @Override\n    public boolean onJsPrompt(AmazonWebView view, String url, String message, String defaultValue, AmazonJsPromptResult result) {\n        // See if the prompt string uses the 'gap-iab' protocol. If so, the remainder should be the id of a callback to execute.\n        if (defaultValue != null && defaultValue.startsWith(\"gap\")) {\n            if(defaultValue.startsWith(\"gap-iab://\")) {\n                PluginResult scriptResult;\n                String scriptCallbackId = defaultValue.substring(10);\n                if (scriptCallbackId.startsWith(\"InAppBrowser\")) {\n                    if(message == null || message.length() == 0) {\n                        scriptResult = new PluginResult(PluginResult.Status.OK, new JSONArray());\n                    } else {\n                        try {\n                            scriptResult = new PluginResult(PluginResult.Status.OK, new JSONArray(message));\n                        } catch(JSONException e) {\n                            scriptResult = new PluginResult(PluginResult.Status.JSON_EXCEPTION, e.getMessage());\n                        }\n                    }\n                    this.webView.sendPluginResult(scriptResult, scriptCallbackId);\n                    result.confirm(\"\");\n                    return true;\n                }\n            }\n            else\n            {\n                // Anything else with a gap: prefix should get this message\n                LOG.w(LOG_TAG, \"InAppBrowser does not support Cordova API calls: \" + url + \" \" + defaultValue); \n                result.cancel();\n                return true;\n            }\n        }\n        return false;\n    }\n\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/src/android/InAppBrowser.java",
    "content": "/*\n       Licensed to the Apache Software Foundation (ASF) under one\n       or more contributor license agreements.  See the NOTICE file\n       distributed with this work for additional information\n       regarding copyright ownership.  The ASF licenses this file\n       to you under the Apache License, Version 2.0 (the\n       \"License\"); you may not use this file except in compliance\n       with the License.  You may obtain a copy of the License at\n\n         http://www.apache.org/licenses/LICENSE-2.0\n\n       Unless required by applicable law or agreed to in writing,\n       software distributed under the License is distributed on an\n       \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n       KIND, either express or implied.  See the License for the\n       specific language governing permissions and limitations\n       under the License.\n*/\npackage org.apache.cordova.inappbrowser;\n\nimport android.annotation.SuppressLint;\nimport android.content.Context;\nimport android.content.Intent;\nimport android.provider.Browser;\nimport android.content.res.Resources;\nimport android.graphics.Bitmap;\nimport android.graphics.drawable.Drawable;\nimport android.net.Uri;\nimport android.os.Build;\nimport android.os.Bundle;\nimport android.text.InputType;\nimport android.util.Log;\nimport android.util.TypedValue;\nimport android.view.Gravity;\nimport android.view.KeyEvent;\nimport android.view.View;\nimport android.view.Window;\nimport android.view.WindowManager;\nimport android.view.WindowManager.LayoutParams;\nimport android.view.inputmethod.EditorInfo;\nimport android.view.inputmethod.InputMethodManager;\nimport android.webkit.CookieManager;\nimport android.webkit.CookieSyncManager;\nimport android.webkit.HttpAuthHandler;\nimport android.webkit.WebSettings;\nimport android.webkit.WebView;\nimport android.webkit.WebViewClient;\nimport android.widget.EditText;\nimport android.widget.ImageButton;\nimport android.widget.ImageView;\nimport android.widget.LinearLayout;\nimport android.widget.RelativeLayout;\n\nimport org.apache.cordova.CallbackContext;\nimport org.apache.cordova.Config;\nimport org.apache.cordova.CordovaArgs;\nimport org.apache.cordova.CordovaHttpAuthHandler;\nimport org.apache.cordova.CordovaPlugin;\nimport org.apache.cordova.CordovaWebView;\nimport org.apache.cordova.LOG;\nimport org.apache.cordova.PluginManager;\nimport org.apache.cordova.PluginResult;\nimport org.json.JSONException;\nimport org.json.JSONObject;\n\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Field;\nimport java.lang.reflect.Method;\nimport java.util.HashMap;\nimport java.util.StringTokenizer;\n\n@SuppressLint(\"SetJavaScriptEnabled\")\npublic class InAppBrowser extends CordovaPlugin {\n\n    private static final String NULL = \"null\";\n    protected static final String LOG_TAG = \"InAppBrowser\";\n    private static final String SELF = \"_self\";\n    private static final String SYSTEM = \"_system\";\n    private static final String EXIT_EVENT = \"exit\";\n    private static final String LOCATION = \"location\";\n    private static final String ZOOM = \"zoom\";\n    private static final String HIDDEN = \"hidden\";\n    private static final String LOAD_START_EVENT = \"loadstart\";\n    private static final String LOAD_STOP_EVENT = \"loadstop\";\n    private static final String LOAD_ERROR_EVENT = \"loaderror\";\n    private static final String CLEAR_ALL_CACHE = \"clearcache\";\n    private static final String CLEAR_SESSION_CACHE = \"clearsessioncache\";\n    private static final String HARDWARE_BACK_BUTTON = \"hardwareback\";\n    private static final String MEDIA_PLAYBACK_REQUIRES_USER_ACTION = \"mediaPlaybackRequiresUserAction\";\n\n    private InAppBrowserDialog dialog;\n    private WebView inAppWebView;\n    private EditText edittext;\n    private CallbackContext callbackContext;\n    private boolean showLocationBar = true;\n    private boolean showZoomControls = true;\n    private boolean openWindowHidden = false;\n    private boolean clearAllCache = false;\n    private boolean clearSessionCache = false;\n    private boolean hadwareBackButton = true;\n    private boolean mediaPlaybackRequiresUserGesture = false;\n\n    /**\n     * Executes the request and returns PluginResult.\n     *\n     * @param action the action to execute.\n     * @param args JSONArry of arguments for the plugin.\n     * @param callbackContext the callbackContext used when calling back into JavaScript.\n     * @return A PluginResult object with a status and message.\n     */\n    public boolean execute(String action, CordovaArgs args, final CallbackContext callbackContext) throws JSONException {\n        if (action.equals(\"open\")) {\n            this.callbackContext = callbackContext;\n            final String url = args.getString(0);\n            String t = args.optString(1);\n            if (t == null || t.equals(\"\") || t.equals(NULL)) {\n                t = SELF;\n            }\n            final String target = t;\n            final HashMap<String, Boolean> features = parseFeature(args.optString(2));\n\n            Log.d(LOG_TAG, \"target = \" + target);\n\n            this.cordova.getActivity().runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    String result = \"\";\n                    // SELF\n                    if (SELF.equals(target)) {\n                        Log.d(LOG_TAG, \"in self\");\n                        /* This code exists for compatibility between 3.x and 4.x versions of Cordova.\n                         * Previously the Config class had a static method, isUrlWhitelisted(). That\n                         * responsibility has been moved to the plugins, with an aggregating method in\n                         * PluginManager.\n                         */\n                        Boolean shouldAllowNavigation = null;\n                        if (url.startsWith(\"javascript:\")) {\n                            shouldAllowNavigation = true;\n                        }\n                        if (shouldAllowNavigation == null) {\n                            try {\n                                Method iuw = Config.class.getMethod(\"isUrlWhiteListed\", String.class);\n                                shouldAllowNavigation = (Boolean)iuw.invoke(null, url);\n                            } catch (NoSuchMethodException e) {\n                            } catch (IllegalAccessException e) {\n                            } catch (InvocationTargetException e) {\n                            }\n                        }\n                        if (shouldAllowNavigation == null) {\n                            try {\n                                Method gpm = webView.getClass().getMethod(\"getPluginManager\");\n                                PluginManager pm = (PluginManager)gpm.invoke(webView);\n                                Method san = pm.getClass().getMethod(\"shouldAllowNavigation\", String.class);\n                                shouldAllowNavigation = (Boolean)san.invoke(pm, url);\n                            } catch (NoSuchMethodException e) {\n                            } catch (IllegalAccessException e) {\n                            } catch (InvocationTargetException e) {\n                            }\n                        }\n                        // load in webview\n                        if (Boolean.TRUE.equals(shouldAllowNavigation)) {\n                            Log.d(LOG_TAG, \"loading in webview\");\n                            webView.loadUrl(url);\n                        }\n                        //Load the dialer\n                        else if (url.startsWith(WebView.SCHEME_TEL))\n                        {\n                            try {\n                                Log.d(LOG_TAG, \"loading in dialer\");\n                                Intent intent = new Intent(Intent.ACTION_DIAL);\n                                intent.setData(Uri.parse(url));\n                                cordova.getActivity().startActivity(intent);\n                            } catch (android.content.ActivityNotFoundException e) {\n                                LOG.e(LOG_TAG, \"Error dialing \" + url + \": \" + e.toString());\n                            }\n                        }\n                        // load in InAppBrowser\n                        else {\n                            Log.d(LOG_TAG, \"loading in InAppBrowser\");\n                            result = showWebPage(url, features);\n                        }\n                    }\n                    // SYSTEM\n                    else if (SYSTEM.equals(target)) {\n                        Log.d(LOG_TAG, \"in system\");\n                        result = openExternal(url);\n                    }\n                    // BLANK - or anything else\n                    else {\n                        Log.d(LOG_TAG, \"in blank\");\n                        result = showWebPage(url, features);\n                    }\n\n                    PluginResult pluginResult = new PluginResult(PluginResult.Status.OK, result);\n                    pluginResult.setKeepCallback(true);\n                    callbackContext.sendPluginResult(pluginResult);\n                }\n            });\n        }\n        else if (action.equals(\"close\")) {\n            closeDialog();\n        }\n        else if (action.equals(\"injectScriptCode\")) {\n            String jsWrapper = null;\n            if (args.getBoolean(1)) {\n                jsWrapper = String.format(\"(function(){prompt(JSON.stringify([eval(%%s)]), 'gap-iab://%s')})()\", callbackContext.getCallbackId());\n            }\n            injectDeferredObject(args.getString(0), jsWrapper);\n        }\n        else if (action.equals(\"injectScriptFile\")) {\n            String jsWrapper;\n            if (args.getBoolean(1)) {\n                jsWrapper = String.format(\"(function(d) { var c = d.createElement('script'); c.src = %%s; c.onload = function() { prompt('', 'gap-iab://%s'); }; d.body.appendChild(c); })(document)\", callbackContext.getCallbackId());\n            } else {\n                jsWrapper = \"(function(d) { var c = d.createElement('script'); c.src = %s; d.body.appendChild(c); })(document)\";\n            }\n            injectDeferredObject(args.getString(0), jsWrapper);\n        }\n        else if (action.equals(\"injectStyleCode\")) {\n            String jsWrapper;\n            if (args.getBoolean(1)) {\n                jsWrapper = String.format(\"(function(d) { var c = d.createElement('style'); c.innerHTML = %%s; d.body.appendChild(c); prompt('', 'gap-iab://%s');})(document)\", callbackContext.getCallbackId());\n            } else {\n                jsWrapper = \"(function(d) { var c = d.createElement('style'); c.innerHTML = %s; d.body.appendChild(c); })(document)\";\n            }\n            injectDeferredObject(args.getString(0), jsWrapper);\n        }\n        else if (action.equals(\"injectStyleFile\")) {\n            String jsWrapper;\n            if (args.getBoolean(1)) {\n                jsWrapper = String.format(\"(function(d) { var c = d.createElement('link'); c.rel='stylesheet'; c.type='text/css'; c.href = %%s; d.head.appendChild(c); prompt('', 'gap-iab://%s');})(document)\", callbackContext.getCallbackId());\n            } else {\n                jsWrapper = \"(function(d) { var c = d.createElement('link'); c.rel='stylesheet'; c.type='text/css'; c.href = %s; d.head.appendChild(c); })(document)\";\n            }\n            injectDeferredObject(args.getString(0), jsWrapper);\n        }\n        else if (action.equals(\"show\")) {\n            this.cordova.getActivity().runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    dialog.show();\n                }\n            });\n            PluginResult pluginResult = new PluginResult(PluginResult.Status.OK);\n            pluginResult.setKeepCallback(true);\n            this.callbackContext.sendPluginResult(pluginResult);\n        }\n        else {\n            return false;\n        }\n        return true;\n    }\n\n    /**\n     * Called when the view navigates.\n     */\n    @Override\n    public void onReset() {\n        closeDialog();\n    }\n\n    /**\n     * Called by AccelBroker when listener is to be shut down.\n     * Stop listener.\n     */\n    public void onDestroy() {\n        closeDialog();\n    }\n\n    /**\n     * Inject an object (script or style) into the InAppBrowser WebView.\n     *\n     * This is a helper method for the inject{Script|Style}{Code|File} API calls, which\n     * provides a consistent method for injecting JavaScript code into the document.\n     *\n     * If a wrapper string is supplied, then the source string will be JSON-encoded (adding\n     * quotes) and wrapped using string formatting. (The wrapper string should have a single\n     * '%s' marker)\n     *\n     * @param source      The source object (filename or script/style text) to inject into\n     *                    the document.\n     * @param jsWrapper   A JavaScript string to wrap the source string in, so that the object\n     *                    is properly injected, or null if the source string is JavaScript text\n     *                    which should be executed directly.\n     */\n    private void injectDeferredObject(String source, String jsWrapper) {\n        String scriptToInject;\n        if (jsWrapper != null) {\n            org.json.JSONArray jsonEsc = new org.json.JSONArray();\n            jsonEsc.put(source);\n            String jsonRepr = jsonEsc.toString();\n            String jsonSourceString = jsonRepr.substring(1, jsonRepr.length()-1);\n            scriptToInject = String.format(jsWrapper, jsonSourceString);\n        } else {\n            scriptToInject = source;\n        }\n        final String finalScriptToInject = scriptToInject;\n        this.cordova.getActivity().runOnUiThread(new Runnable() {\n            @SuppressLint(\"NewApi\")\n            @Override\n            public void run() {\n                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {\n                    // This action will have the side-effect of blurring the currently focused element\n                    inAppWebView.loadUrl(\"javascript:\" + finalScriptToInject);\n                } else {\n                    inAppWebView.evaluateJavascript(finalScriptToInject, null);\n                }\n            }\n        });\n    }\n\n    /**\n     * Put the list of features into a hash map\n     *\n     * @param optString\n     * @return\n     */\n    private HashMap<String, Boolean> parseFeature(String optString) {\n        if (optString.equals(NULL)) {\n            return null;\n        } else {\n            HashMap<String, Boolean> map = new HashMap<String, Boolean>();\n            StringTokenizer features = new StringTokenizer(optString, \",\");\n            StringTokenizer option;\n            while(features.hasMoreElements()) {\n                option = new StringTokenizer(features.nextToken(), \"=\");\n                if (option.hasMoreElements()) {\n                    String key = option.nextToken();\n                    Boolean value = option.nextToken().equals(\"no\") ? Boolean.FALSE : Boolean.TRUE;\n                    map.put(key, value);\n                }\n            }\n            return map;\n        }\n    }\n\n    /**\n     * Display a new browser with the specified URL.\n     *\n     * @param url the url to load.\n     * @return \"\" if ok, or error message.\n     */\n    public String openExternal(String url) {\n        try {\n            Intent intent = null;\n            intent = new Intent(Intent.ACTION_VIEW);\n            // Omitting the MIME type for file: URLs causes \"No Activity found to handle Intent\".\n            // Adding the MIME type to http: URLs causes them to not be handled by the downloader.\n            Uri uri = Uri.parse(url);\n            if (\"file\".equals(uri.getScheme())) {\n                intent.setDataAndType(uri, webView.getResourceApi().getMimeType(uri));\n            } else {\n                intent.setData(uri);\n            }\n            intent.putExtra(Browser.EXTRA_APPLICATION_ID, cordova.getActivity().getPackageName());\n            this.cordova.getActivity().startActivity(intent);\n            return \"\";\n        } catch (android.content.ActivityNotFoundException e) {\n            Log.d(LOG_TAG, \"InAppBrowser: Error loading url \"+url+\":\"+ e.toString());\n            return e.toString();\n        }\n    }\n\n    /**\n     * Closes the dialog\n     */\n    public void closeDialog() {\n        this.cordova.getActivity().runOnUiThread(new Runnable() {\n            @Override\n            public void run() {\n                final WebView childView = inAppWebView;\n                // The JS protects against multiple calls, so this should happen only when\n                // closeDialog() is called by other native code.\n                if (childView == null) {\n                    return;\n                }\n\n                childView.setWebViewClient(new WebViewClient() {\n                    // NB: wait for about:blank before dismissing\n                    public void onPageFinished(WebView view, String url) {\n                        if (dialog != null) {\n                            dialog.dismiss();\n                            dialog = null;\n                        }\n                    }\n                });\n                // NB: From SDK 19: \"If you call methods on WebView from any thread\n                // other than your app's UI thread, it can cause unexpected results.\"\n                // http://developer.android.com/guide/webapps/migrating.html#Threads\n                childView.loadUrl(\"about:blank\");\n\n                try {\n                    JSONObject obj = new JSONObject();\n                    obj.put(\"type\", EXIT_EVENT);\n                    sendUpdate(obj, false);\n                } catch (JSONException ex) {\n                    Log.d(LOG_TAG, \"Should never happen\");\n                }\n            }\n        });\n    }\n\n    /**\n     * Checks to see if it is possible to go back one page in history, then does so.\n     */\n    public void goBack() {\n        if (this.inAppWebView.canGoBack()) {\n            this.inAppWebView.goBack();\n        }\n    }\n\n    /**\n     * Can the web browser go back?\n     * @return boolean\n     */\n    public boolean canGoBack() {\n        return this.inAppWebView.canGoBack();\n    }\n\n    /**\n     * Has the user set the hardware back button to go back\n     * @return boolean\n     */\n    public boolean hardwareBack() {\n        return hadwareBackButton;\n    }\n\n    /**\n     * Checks to see if it is possible to go forward one page in history, then does so.\n     */\n    private void goForward() {\n        if (this.inAppWebView.canGoForward()) {\n            this.inAppWebView.goForward();\n        }\n    }\n\n    /**\n     * Navigate to the new page\n     *\n     * @param url to load\n     */\n    private void navigate(String url) {\n        InputMethodManager imm = (InputMethodManager)this.cordova.getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);\n        imm.hideSoftInputFromWindow(edittext.getWindowToken(), 0);\n\n        if (!url.startsWith(\"http\") && !url.startsWith(\"file:\")) {\n            this.inAppWebView.loadUrl(\"http://\" + url);\n        } else {\n            this.inAppWebView.loadUrl(url);\n        }\n        this.inAppWebView.requestFocus();\n    }\n\n\n    /**\n     * Should we show the location bar?\n     *\n     * @return boolean\n     */\n    private boolean getShowLocationBar() {\n        return this.showLocationBar;\n    }\n\n    private InAppBrowser getInAppBrowser(){\n        return this;\n    }\n\n    /**\n     * Display a new browser with the specified URL.\n     *\n     * @param url the url to load.\n     * @param features jsonObject\n     */\n    public String showWebPage(final String url, HashMap<String, Boolean> features) {\n        // Determine if we should hide the location bar.\n        showLocationBar = true;\n        showZoomControls = true;\n        openWindowHidden = false;\n        mediaPlaybackRequiresUserGesture = false;\n\n        if (features != null) {\n            Boolean show = features.get(LOCATION);\n            if (show != null) {\n                showLocationBar = show.booleanValue();\n            }\n            Boolean zoom = features.get(ZOOM);\n            if (zoom != null) {\n                showZoomControls = zoom.booleanValue();\n            }\n            Boolean hidden = features.get(HIDDEN);\n            if (hidden != null) {\n                openWindowHidden = hidden.booleanValue();\n            }\n            Boolean hardwareBack = features.get(HARDWARE_BACK_BUTTON);\n            if (hardwareBack != null) {\n                hadwareBackButton = hardwareBack.booleanValue();\n            }\n            Boolean mediaPlayback = features.get(MEDIA_PLAYBACK_REQUIRES_USER_ACTION);\n            if (mediaPlayback != null) {\n                mediaPlaybackRequiresUserGesture = mediaPlayback.booleanValue();\n            }\n            Boolean cache = features.get(CLEAR_ALL_CACHE);\n            if (cache != null) {\n                clearAllCache = cache.booleanValue();\n            } else {\n                cache = features.get(CLEAR_SESSION_CACHE);\n                if (cache != null) {\n                    clearSessionCache = cache.booleanValue();\n                }\n            }\n        }\n\n        final CordovaWebView thatWebView = this.webView;\n\n        // Create dialog in new thread\n        Runnable runnable = new Runnable() {\n            /**\n             * Convert our DIP units to Pixels\n             *\n             * @return int\n             */\n            private int dpToPixels(int dipValue) {\n                int value = (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP,\n                                                            (float) dipValue,\n                                                            cordova.getActivity().getResources().getDisplayMetrics()\n                );\n\n                return value;\n            }\n\n            @SuppressLint(\"NewApi\")\n            public void run() {\n\n                // CB-6702 InAppBrowser hangs when opening more than one instance\n                if (dialog != null) {\n                    dialog.dismiss();\n                };\n\n                // Let's create the main dialog\n                dialog = new InAppBrowserDialog(cordova.getActivity(), android.R.style.Theme_NoTitleBar);\n                dialog.getWindow().getAttributes().windowAnimations = android.R.style.Animation_Dialog;\n                dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);\n                dialog.setCancelable(true);\n                dialog.setInAppBroswer(getInAppBrowser());\n\n                // Main container layout\n                LinearLayout main = new LinearLayout(cordova.getActivity());\n                main.setOrientation(LinearLayout.VERTICAL);\n\n                // Toolbar layout\n                RelativeLayout toolbar = new RelativeLayout(cordova.getActivity());\n                //Please, no more black!\n                toolbar.setBackgroundColor(android.graphics.Color.LTGRAY);\n                toolbar.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, this.dpToPixels(44)));\n                toolbar.setPadding(this.dpToPixels(2), this.dpToPixels(2), this.dpToPixels(2), this.dpToPixels(2));\n                toolbar.setHorizontalGravity(Gravity.LEFT);\n                toolbar.setVerticalGravity(Gravity.TOP);\n\n                // Action Button Container layout\n                RelativeLayout actionButtonContainer = new RelativeLayout(cordova.getActivity());\n                actionButtonContainer.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));\n                actionButtonContainer.setHorizontalGravity(Gravity.LEFT);\n                actionButtonContainer.setVerticalGravity(Gravity.CENTER_VERTICAL);\n                actionButtonContainer.setId(Integer.valueOf(1));\n\n                // Back button\n                ImageButton back = new ImageButton(cordova.getActivity());\n                RelativeLayout.LayoutParams backLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);\n                backLayoutParams.addRule(RelativeLayout.ALIGN_LEFT);\n                back.setLayoutParams(backLayoutParams);\n                back.setContentDescription(\"Back Button\");\n                back.setId(Integer.valueOf(2));\n                Resources activityRes = cordova.getActivity().getResources();\n                int backResId = activityRes.getIdentifier(\"ic_action_previous_item\", \"drawable\", cordova.getActivity().getPackageName());\n                Drawable backIcon = activityRes.getDrawable(backResId);\n                back.setBackground(null);\n                back.setImageDrawable(backIcon);\n                back.setScaleType(ImageView.ScaleType.FIT_CENTER);\n                back.setPadding(0, this.dpToPixels(10), 0, this.dpToPixels(10));\n                back.getAdjustViewBounds();\n\n                back.setOnClickListener(new View.OnClickListener() {\n                    public void onClick(View v) {\n                        goBack();\n                    }\n                });\n\n                // Forward button\n                ImageButton forward = new ImageButton(cordova.getActivity());\n                RelativeLayout.LayoutParams forwardLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);\n                forwardLayoutParams.addRule(RelativeLayout.RIGHT_OF, 2);\n                forward.setLayoutParams(forwardLayoutParams);\n                forward.setContentDescription(\"Forward Button\");\n                forward.setId(Integer.valueOf(3));\n                int fwdResId = activityRes.getIdentifier(\"ic_action_next_item\", \"drawable\", cordova.getActivity().getPackageName());\n                Drawable fwdIcon = activityRes.getDrawable(fwdResId);\n                forward.setBackground(null);\n                forward.setImageDrawable(fwdIcon);\n                forward.setScaleType(ImageView.ScaleType.FIT_CENTER);\n                forward.setPadding(0, this.dpToPixels(10), 0, this.dpToPixels(10));\n                forward.getAdjustViewBounds();\n\n                forward.setOnClickListener(new View.OnClickListener() {\n                    public void onClick(View v) {\n                        goForward();\n                    }\n                });\n\n                // Edit Text Box\n                edittext = new EditText(cordova.getActivity());\n                RelativeLayout.LayoutParams textLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);\n                textLayoutParams.addRule(RelativeLayout.RIGHT_OF, 1);\n                textLayoutParams.addRule(RelativeLayout.LEFT_OF, 5);\n                edittext.setLayoutParams(textLayoutParams);\n                edittext.setId(Integer.valueOf(4));\n                edittext.setSingleLine(true);\n                edittext.setText(url);\n                edittext.setInputType(InputType.TYPE_TEXT_VARIATION_URI);\n                edittext.setImeOptions(EditorInfo.IME_ACTION_GO);\n                edittext.setInputType(InputType.TYPE_NULL); // Will not except input... Makes the text NON-EDITABLE\n                edittext.setOnKeyListener(new View.OnKeyListener() {\n                    public boolean onKey(View v, int keyCode, KeyEvent event) {\n                        // If the event is a key-down event on the \"enter\" button\n                        if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) {\n                          navigate(edittext.getText().toString());\n                          return true;\n                        }\n                        return false;\n                    }\n                });\n\n                // Close/Done button\n                ImageButton close = new ImageButton(cordova.getActivity());\n                RelativeLayout.LayoutParams closeLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);\n                closeLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);\n                close.setLayoutParams(closeLayoutParams);\n                forward.setContentDescription(\"Close Button\");\n                close.setId(Integer.valueOf(5));\n                int closeResId = activityRes.getIdentifier(\"ic_action_remove\", \"drawable\", cordova.getActivity().getPackageName());\n                Drawable closeIcon = activityRes.getDrawable(closeResId);\n                close.setBackground(null);\n                close.setImageDrawable(closeIcon);\n                close.setScaleType(ImageView.ScaleType.FIT_CENTER);\n                back.setPadding(0, this.dpToPixels(10), 0, this.dpToPixels(10));\n                close.getAdjustViewBounds();\n\n                close.setOnClickListener(new View.OnClickListener() {\n                    public void onClick(View v) {\n                        closeDialog();\n                    }\n                });\n\n                // WebView\n                inAppWebView = new WebView(cordova.getActivity());\n                inAppWebView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));\n                inAppWebView.setId(Integer.valueOf(6));\n                inAppWebView.setWebChromeClient(new InAppChromeClient(thatWebView));\n                WebViewClient client = new InAppBrowserClient(thatWebView, edittext);\n                inAppWebView.setWebViewClient(client);\n                WebSettings settings = inAppWebView.getSettings();\n                settings.setJavaScriptEnabled(true);\n                settings.setJavaScriptCanOpenWindowsAutomatically(true);\n                settings.setBuiltInZoomControls(showZoomControls);\n                settings.setPluginState(android.webkit.WebSettings.PluginState.ON);\n\n                if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {\n                    settings.setMediaPlaybackRequiresUserGesture(mediaPlaybackRequiresUserGesture);\n                }\n\n                String overrideUserAgent = preferences.getString(\"OverrideUserAgent\", null);\n                String appendUserAgent = preferences.getString(\"AppendUserAgent\", null);\n\n                if (overrideUserAgent != null) {\n                    settings.setUserAgentString(overrideUserAgent);\n                }\n                if (appendUserAgent != null) {\n                    settings.setUserAgentString(settings.getUserAgentString() + appendUserAgent);\n                }\n\n                //Toggle whether this is enabled or not!\n                Bundle appSettings = cordova.getActivity().getIntent().getExtras();\n                boolean enableDatabase = appSettings == null ? true : appSettings.getBoolean(\"InAppBrowserStorageEnabled\", true);\n                if (enableDatabase) {\n                    String databasePath = cordova.getActivity().getApplicationContext().getDir(\"inAppBrowserDB\", Context.MODE_PRIVATE).getPath();\n                    settings.setDatabasePath(databasePath);\n                    settings.setDatabaseEnabled(true);\n                }\n                settings.setDomStorageEnabled(true);\n\n                if (clearAllCache) {\n                    CookieManager.getInstance().removeAllCookie();\n                } else if (clearSessionCache) {\n                    CookieManager.getInstance().removeSessionCookie();\n                }\n\n                inAppWebView.loadUrl(url);\n                inAppWebView.setId(Integer.valueOf(6));\n                inAppWebView.getSettings().setLoadWithOverviewMode(true);\n                inAppWebView.getSettings().setUseWideViewPort(true);\n                inAppWebView.requestFocus();\n                inAppWebView.requestFocusFromTouch();\n\n                // Add the back and forward buttons to our action button container layout\n                actionButtonContainer.addView(back);\n                actionButtonContainer.addView(forward);\n\n                // Add the views to our toolbar\n                toolbar.addView(actionButtonContainer);\n                toolbar.addView(edittext);\n                toolbar.addView(close);\n\n                // Don't add the toolbar if its been disabled\n                if (getShowLocationBar()) {\n                    // Add our toolbar to our main view/layout\n                    main.addView(toolbar);\n                }\n\n                // Add our webview to our main view/layout\n                main.addView(inAppWebView);\n\n                WindowManager.LayoutParams lp = new WindowManager.LayoutParams();\n                lp.copyFrom(dialog.getWindow().getAttributes());\n                lp.width = WindowManager.LayoutParams.MATCH_PARENT;\n                lp.height = WindowManager.LayoutParams.MATCH_PARENT;\n\n                dialog.setContentView(main);\n                dialog.show();\n                dialog.getWindow().setAttributes(lp);\n                // the goal of openhidden is to load the url and not display it\n                // Show() needs to be called to cause the URL to be loaded\n                if(openWindowHidden) {\n                    dialog.hide();\n                }\n            }\n        };\n        this.cordova.getActivity().runOnUiThread(runnable);\n        return \"\";\n    }\n\n    /**\n     * Create a new plugin success result and send it back to JavaScript\n     *\n     * @param obj a JSONObject contain event payload information\n     */\n    private void sendUpdate(JSONObject obj, boolean keepCallback) {\n        sendUpdate(obj, keepCallback, PluginResult.Status.OK);\n    }\n\n    /**\n     * Create a new plugin result and send it back to JavaScript\n     *\n     * @param obj a JSONObject contain event payload information\n     * @param status the status code to return to the JavaScript environment\n     */\n    private void sendUpdate(JSONObject obj, boolean keepCallback, PluginResult.Status status) {\n        if (callbackContext != null) {\n            PluginResult result = new PluginResult(status, obj);\n            result.setKeepCallback(keepCallback);\n            callbackContext.sendPluginResult(result);\n            if (!keepCallback) {\n                callbackContext = null;\n            }\n        }\n    }\n\n    /**\n     * The webview client receives notifications about appView\n     */\n    public class InAppBrowserClient extends WebViewClient {\n        EditText edittext;\n        CordovaWebView webView;\n\n        /**\n         * Constructor.\n         *\n         * @param webView\n         * @param mEditText\n         */\n        public InAppBrowserClient(CordovaWebView webView, EditText mEditText) {\n            this.webView = webView;\n            this.edittext = mEditText;\n        }\n\n        /**\n         * Override the URL that should be loaded\n         *\n         * This handles a small subset of all the URIs that would be encountered.\n         *\n         * @param webView\n         * @param url\n         */\n        @Override\n        public boolean shouldOverrideUrlLoading(WebView webView, String url) {\n            if (url.startsWith(WebView.SCHEME_TEL)) {\n                try {\n                    Intent intent = new Intent(Intent.ACTION_DIAL);\n                    intent.setData(Uri.parse(url));\n                    cordova.getActivity().startActivity(intent);\n                    return true;\n                } catch (android.content.ActivityNotFoundException e) {\n                    LOG.e(LOG_TAG, \"Error dialing \" + url + \": \" + e.toString());\n                }\n            } else if (url.startsWith(\"geo:\") || url.startsWith(WebView.SCHEME_MAILTO) || url.startsWith(\"market:\")) {\n                try {\n                    Intent intent = new Intent(Intent.ACTION_VIEW);\n                    intent.setData(Uri.parse(url));\n                    cordova.getActivity().startActivity(intent);\n                    return true;\n                } catch (android.content.ActivityNotFoundException e) {\n                    LOG.e(LOG_TAG, \"Error with \" + url + \": \" + e.toString());\n                }\n            }\n            // If sms:5551212?body=This is the message\n            else if (url.startsWith(\"sms:\")) {\n                try {\n                    Intent intent = new Intent(Intent.ACTION_VIEW);\n\n                    // Get address\n                    String address = null;\n                    int parmIndex = url.indexOf('?');\n                    if (parmIndex == -1) {\n                        address = url.substring(4);\n                    } else {\n                        address = url.substring(4, parmIndex);\n\n                        // If body, then set sms body\n                        Uri uri = Uri.parse(url);\n                        String query = uri.getQuery();\n                        if (query != null) {\n                            if (query.startsWith(\"body=\")) {\n                                intent.putExtra(\"sms_body\", query.substring(5));\n                            }\n                        }\n                    }\n                    intent.setData(Uri.parse(\"sms:\" + address));\n                    intent.putExtra(\"address\", address);\n                    intent.setType(\"vnd.android-dir/mms-sms\");\n                    cordova.getActivity().startActivity(intent);\n                    return true;\n                } catch (android.content.ActivityNotFoundException e) {\n                    LOG.e(LOG_TAG, \"Error sending sms \" + url + \":\" + e.toString());\n                }\n            }\n            return false;\n        }\n\n\n        /*\n         * onPageStarted fires the LOAD_START_EVENT\n         *\n         * @param view\n         * @param url\n         * @param favicon\n         */\n        @Override\n        public void onPageStarted(WebView view, String url, Bitmap favicon) {\n            super.onPageStarted(view, url, favicon);\n            String newloc = \"\";\n            if (url.startsWith(\"http:\") || url.startsWith(\"https:\") || url.startsWith(\"file:\")) {\n                newloc = url;\n            }\n            else\n            {\n                // Assume that everything is HTTP at this point, because if we don't specify,\n                // it really should be.  Complain loudly about this!!!\n                LOG.e(LOG_TAG, \"Possible Uncaught/Unknown URI\");\n                newloc = \"http://\" + url;\n            }\n\n            // Update the UI if we haven't already\n            if (!newloc.equals(edittext.getText().toString())) {\n                edittext.setText(newloc);\n             }\n\n            try {\n                JSONObject obj = new JSONObject();\n                obj.put(\"type\", LOAD_START_EVENT);\n                obj.put(\"url\", newloc);\n                sendUpdate(obj, true);\n            } catch (JSONException ex) {\n                LOG.e(LOG_TAG, \"URI passed in has caused a JSON error.\");\n            }\n        }\n\n\n\n        public void onPageFinished(WebView view, String url) {\n            super.onPageFinished(view, url);\n\n            // CB-10395 InAppBrowser's WebView not storing cookies reliable to local device storage\n            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {\n                CookieManager.getInstance().flush();\n            } else {\n                CookieSyncManager.getInstance().sync();\n            }\n\n            try {\n                JSONObject obj = new JSONObject();\n                obj.put(\"type\", LOAD_STOP_EVENT);\n                obj.put(\"url\", url);\n\n                sendUpdate(obj, true);\n            } catch (JSONException ex) {\n                Log.d(LOG_TAG, \"Should never happen\");\n            }\n        }\n\n        public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {\n            super.onReceivedError(view, errorCode, description, failingUrl);\n\n            try {\n                JSONObject obj = new JSONObject();\n                obj.put(\"type\", LOAD_ERROR_EVENT);\n                obj.put(\"url\", failingUrl);\n                obj.put(\"code\", errorCode);\n                obj.put(\"message\", description);\n\n                sendUpdate(obj, true, PluginResult.Status.ERROR);\n            } catch (JSONException ex) {\n                Log.d(LOG_TAG, \"Should never happen\");\n            }\n        }\n\n        /**\n         * On received http auth request.\n         */\n        @Override\n        public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm) {\n\n            // Check if there is some plugin which can resolve this auth challenge\n            PluginManager pluginManager = null;\n            try {\n                Method gpm = webView.getClass().getMethod(\"getPluginManager\");\n                pluginManager = (PluginManager)gpm.invoke(webView);\n            } catch (NoSuchMethodException e) {\n            } catch (IllegalAccessException e) {\n            } catch (InvocationTargetException e) {\n            }\n\n            if (pluginManager == null) {\n                try {\n                    Field pmf = webView.getClass().getField(\"pluginManager\");\n                    pluginManager = (PluginManager)pmf.get(webView);\n                } catch (NoSuchFieldException e) {\n                } catch (IllegalAccessException e) {\n                }\n            }\n\n            if (pluginManager != null && pluginManager.onReceivedHttpAuthRequest(webView, new CordovaHttpAuthHandler(handler), host, realm)) {\n                return;\n            }\n\n            // By default handle 401 like we'd normally do!\n            super.onReceivedHttpAuthRequest(view, handler, host, realm);\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/src/android/InAppBrowserDialog.java",
    "content": "/*\n       Licensed to the Apache Software Foundation (ASF) under one\n       or more contributor license agreements.  See the NOTICE file\n       distributed with this work for additional information\n       regarding copyright ownership.  The ASF licenses this file\n       to you under the Apache License, Version 2.0 (the\n       \"License\"); you may not use this file except in compliance\n       with the License.  You may obtain a copy of the License at\n\n         http://www.apache.org/licenses/LICENSE-2.0\n\n       Unless required by applicable law or agreed to in writing,\n       software distributed under the License is distributed on an\n       \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n       KIND, either express or implied.  See the License for the\n       specific language governing permissions and limitations\n       under the License.\n*/\npackage org.apache.cordova.inappbrowser;\n\nimport android.app.AlertDialog;\nimport android.app.Dialog;\nimport android.content.Context;\nimport android.util.Log;\n\nimport org.json.JSONException;\nimport org.json.JSONObject;\n\n/**\n * Created by Oliver on 22/11/2013.\n */\npublic class InAppBrowserDialog extends Dialog {\n    Context context;\n    InAppBrowser inAppBrowser = null;\n\n    public InAppBrowserDialog(Context context, int theme) {\n        super(context, theme);\n        this.context = context;\n    }\n\n    public void setInAppBroswer(InAppBrowser browser) {\n        this.inAppBrowser = browser;\n    }\n\n    public void onBackPressed () {\n        if (this.inAppBrowser == null) {\n            this.dismiss();\n        } else {\n            // better to go through the in inAppBrowser\n            // because it does a clean up\n            if (this.inAppBrowser.hardwareBack() && this.inAppBrowser.canGoBack()) {\n                this.inAppBrowser.goBack();\n            }  else {\n                this.inAppBrowser.closeDialog();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/src/android/InAppChromeClient.java",
    "content": "/*\n       Licensed to the Apache Software Foundation (ASF) under one\n       or more contributor license agreements.  See the NOTICE file\n       distributed with this work for additional information\n       regarding copyright ownership.  The ASF licenses this file\n       to you under the Apache License, Version 2.0 (the\n       \"License\"); you may not use this file except in compliance\n       with the License.  You may obtain a copy of the License at\n\n         http://www.apache.org/licenses/LICENSE-2.0\n\n       Unless required by applicable law or agreed to in writing,\n       software distributed under the License is distributed on an\n       \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n       KIND, either express or implied.  See the License for the\n       specific language governing permissions and limitations\n       under the License.\n*/\npackage org.apache.cordova.inappbrowser;\n\nimport org.apache.cordova.CordovaWebView;\nimport org.apache.cordova.LOG;\nimport org.apache.cordova.PluginResult;\nimport org.json.JSONArray;\nimport org.json.JSONException;\n\nimport android.webkit.JsPromptResult;\nimport android.webkit.WebChromeClient;\nimport android.webkit.WebStorage;\nimport android.webkit.WebView;\nimport android.webkit.WebViewClient;\nimport android.webkit.GeolocationPermissions.Callback;\n\npublic class InAppChromeClient extends WebChromeClient {\n\n    private CordovaWebView webView;\n    private String LOG_TAG = \"InAppChromeClient\";\n    private long MAX_QUOTA = 100 * 1024 * 1024;\n\n    public InAppChromeClient(CordovaWebView webView) {\n        super();\n        this.webView = webView;\n    }\n    /**\n     * Handle database quota exceeded notification.\n     *\n     * @param url\n     * @param databaseIdentifier\n     * @param currentQuota\n     * @param estimatedSize\n     * @param totalUsedQuota\n     * @param quotaUpdater\n     */\n    @Override\n    public void onExceededDatabaseQuota(String url, String databaseIdentifier, long currentQuota, long estimatedSize,\n            long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater)\n    {\n        LOG.d(LOG_TAG, \"onExceededDatabaseQuota estimatedSize: %d  currentQuota: %d  totalUsedQuota: %d\", estimatedSize, currentQuota, totalUsedQuota);\n        quotaUpdater.updateQuota(MAX_QUOTA);\n    }\n\n    /**\n     * Instructs the client to show a prompt to ask the user to set the Geolocation permission state for the specified origin.\n     *\n     * @param origin\n     * @param callback\n     */\n    @Override\n    public void onGeolocationPermissionsShowPrompt(String origin, Callback callback) {\n        super.onGeolocationPermissionsShowPrompt(origin, callback);\n        callback.invoke(origin, true, false);\n    }\n\n    /**\n     * Tell the client to display a prompt dialog to the user.\n     * If the client returns true, WebView will assume that the client will\n     * handle the prompt dialog and call the appropriate JsPromptResult method.\n     *\n     * The prompt bridge provided for the InAppBrowser is capable of executing any\n     * oustanding callback belonging to the InAppBrowser plugin. Care has been\n     * taken that other callbacks cannot be triggered, and that no other code\n     * execution is possible.\n     *\n     * To trigger the bridge, the prompt default value should be of the form:\n     *\n     * gap-iab://<callbackId>\n     *\n     * where <callbackId> is the string id of the callback to trigger (something\n     * like \"InAppBrowser0123456789\")\n     *\n     * If present, the prompt message is expected to be a JSON-encoded value to\n     * pass to the callback. A JSON_EXCEPTION is returned if the JSON is invalid.\n     *\n     * @param view\n     * @param url\n     * @param message\n     * @param defaultValue\n     * @param result\n     */\n    @Override\n    public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {\n        // See if the prompt string uses the 'gap-iab' protocol. If so, the remainder should be the id of a callback to execute.\n        if (defaultValue != null && defaultValue.startsWith(\"gap\")) {\n            if(defaultValue.startsWith(\"gap-iab://\")) {\n                PluginResult scriptResult;\n                String scriptCallbackId = defaultValue.substring(10);\n                if (scriptCallbackId.startsWith(\"InAppBrowser\")) {\n                    if(message == null || message.length() == 0) {\n                        scriptResult = new PluginResult(PluginResult.Status.OK, new JSONArray());\n                    } else {\n                        try {\n                            scriptResult = new PluginResult(PluginResult.Status.OK, new JSONArray(message));\n                        } catch(JSONException e) {\n                            scriptResult = new PluginResult(PluginResult.Status.JSON_EXCEPTION, e.getMessage());\n                        }\n                    }\n                    this.webView.sendPluginResult(scriptResult, scriptCallbackId);\n                    result.confirm(\"\");\n                    return true;\n                }\n            }\n            else\n            {\n                // Anything else with a gap: prefix should get this message\n                LOG.w(LOG_TAG, \"InAppBrowser does not support Cordova API calls: \" + url + \" \" + defaultValue); \n                result.cancel();\n                return true;\n            }\n        }\n        return false;\n    }\n\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/src/blackberry10/README.md",
    "content": "<!---\n license: Licensed to the Apache Software Foundation (ASF) under one\n         or more contributor license agreements.  See the NOTICE file\n         distributed with this work for additional information\n         regarding copyright ownership.  The ASF licenses this file\n         to you under the Apache License, Version 2.0 (the\n         \"License\"); you may not use this file except in compliance\n         with the License.  You may obtain a copy of the License at\n\n           http://www.apache.org/licenses/LICENSE-2.0\n\n         Unless required by applicable law or agreed to in writing,\n         software distributed under the License is distributed on an\n         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n         KIND, either express or implied.  See the License for the\n         specific language governing permissions and limitations\n         under the License.\n-->\n# BlackBerry 10 In-App-Browser Plugin\n\nThe in app browser functionality is entirely contained within common js. There is no native implementation required.\nTo install this plugin, follow the [Command-line Interface Guide](http://cordova.apache.org/docs/en/edge/guide_cli_index.md.html#The%20Command-line%20Interface).\n\nIf you are not using the Cordova Command-line Interface, follow [Using Plugman to Manage Plugins](http://cordova.apache.org/docs/en/edge/guide_plugin_ref_plugman.md.html).\n./cordova-plugin-battery-status/README.md\n./cordova-plugin-camera/README.md\n./cordova-plugin-console/README.md\n./cordova-plugin-contacts/README.md\n./cordova-plugin-device/README.md\n./cordova-plugin-device-motion/README.md\n./cordova-plugin-device-orientation/README.md\n./cordova-plugin-device-orientation/src/blackberry10/README.md\n./cordova-plugin-file/README.md\n./cordova-plugin-file-transfer/README.md\n./cordova-plugin-geolocation/README.md\n./cordova-plugin-globalization/README.md\n./cordova-plugin-inappbrowser/README.md\n./cordova-plugin-inappbrowser/src/blackberry10/README.md\n./cordova-plugin-media/README.md\n./cordova-plugin-media-capture/README.md\n./cordova-plugin-network-information/README.md\n./cordova-plugin-splashscreen/README.md\n./cordova-plugin-vibration/README.md\n"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/src/blackberry10/doc/de/README.md",
    "content": "<!---\n license: Licensed to the Apache Software Foundation (ASF) under one\n         or more contributor license agreements.  See the NOTICE file\n         distributed with this work for additional information\n         regarding copyright ownership.  The ASF licenses this file\n         to you under the Apache License, Version 2.0 (the\n         \"License\"); you may not use this file except in compliance\n         with the License.  You may obtain a copy of the License at\n\n           http://www.apache.org/licenses/LICENSE-2.0\n\n         Unless required by applicable law or agreed to in writing,\n         software distributed under the License is distributed on an\n         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n         KIND, either express or implied.  See the License for the\n         specific language governing permissions and limitations\n         under the License.\n-->\n\n# BlackBerry 10-In-App-Browser-Plugin\n\nDie Funktionalität ist im app-Browser vollständig in gemeinsamen Js enthalten. Es gibt keine native Implementierung benötigt. Um dieses Plugin zu installieren, folgen Sie dem [Command-Line Interface Guide](http://cordova.apache.org/docs/en/edge/guide_cli_index.md.html#The%20Command-line%20Interface).\n\nWenn Sie nicht die Cordova-Befehlszeilenschnittstelle verwenden, folgen Sie [Verwenden Plugman zu Plugins verwalten](http://cordova.apache.org/docs/en/edge/guide_plugin_ref_plugman.md.html). ./cordova-plugin-battery-status/README.md ./cordova-plugin-camera/README.md ./cordova-plugin-console/README.md ./cordova-plugin-contacts/README.md ./cordova-plugin-device/README.md ./cordova-plugin-device-motion/README.md ./cordova-plugin-device-orientation/README.md ./cordova-plugin-device-orientation/src/blackberry10/README.md ./cordova-plugin-file/README.md ./cordova-plugin-file-transfer/README.md ./cordova-plugin-geolocation/README.md ./cordova-plugin-globalization/README.md ./cordova-plugin-inappbrowser/README.md ./cordova-plugin-inappbrowser/src/blackberry10/README.md ./cordova-plugin-media/README.md ./cordova-plugin-media-capture/README.md ./cordova-plugin-network-information/README.md ./cordova-plugin-splashscreen/README.md ./cordova-plugin-vibration/README.md"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/src/blackberry10/doc/es/README.md",
    "content": "<!---\n license: Licensed to the Apache Software Foundation (ASF) under one\n         or more contributor license agreements.  See the NOTICE file\n         distributed with this work for additional information\n         regarding copyright ownership.  The ASF licenses this file\n         to you under the Apache License, Version 2.0 (the\n         \"License\"); you may not use this file except in compliance\n         with the License.  You may obtain a copy of the License at\n\n           http://www.apache.org/licenses/LICENSE-2.0\n\n         Unless required by applicable law or agreed to in writing,\n         software distributed under the License is distributed on an\n         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n         KIND, either express or implied.  See the License for the\n         specific language governing permissions and limitations\n         under the License.\n-->\n\n# BlackBerry 10 In-App-Browser Plugin\n\nEl en el navegador de aplicación funcionalidad está enteramente dentro de js común. No hay ninguna aplicación nativa necesaria. Para instalar este plugin, siga la [Guía de la interfaz de línea de comandos](http://cordova.apache.org/docs/en/edge/guide_cli_index.md.html#The%20Command-line%20Interface).\n\nSi no utiliza la interfaz de línea de comandos de Cordova, siga [Usando Plugman para gestionar Plugins](http://cordova.apache.org/docs/en/edge/guide_plugin_ref_plugman.md.html). ./cordova-plugin-battery-status/README.md ./cordova-plugin-camera/README.md ./cordova-plugin-console/README.md ./cordova-plugin-contacts/README.md ./cordova-plugin-device/README.md ./cordova-plugin-device-motion/README.md ./cordova-plugin-device-orientation/README.md ./cordova-plugin-device-orientation/src/blackberry10/README.md ./cordova-plugin-file/README.md ./cordova-plugin-file-transfer/README.md ./cordova-plugin-geolocation/README.md ./cordova-plugin-globalization/README.md ./cordova-plugin-inappbrowser/README.md ./cordova-plugin-inappbrowser/src/blackberry10/README.md ./cordova-plugin-media/README.md ./cordova-plugin-media-capture/README.md ./cordova-plugin-network-information/README.md ./cordova-plugin-splashscreen/README.md ./cordova-plugin-vibration/README.md"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/src/blackberry10/doc/fr/README.md",
    "content": "<!---\n license: Licensed to the Apache Software Foundation (ASF) under one\n         or more contributor license agreements.  See the NOTICE file\n         distributed with this work for additional information\n         regarding copyright ownership.  The ASF licenses this file\n         to you under the Apache License, Version 2.0 (the\n         \"License\"); you may not use this file except in compliance\n         with the License.  You may obtain a copy of the License at\n\n           http://www.apache.org/licenses/LICENSE-2.0\n\n         Unless required by applicable law or agreed to in writing,\n         software distributed under the License is distributed on an\n         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n         KIND, either express or implied.  See the License for the\n         specific language governing permissions and limitations\n         under the License.\n-->\n\n# BlackBerry 10 In-App-Browser Plugin\n\nLe dans le navigateur de l'application, la fonctionnalité est entièrement contenue dans js commun. Il n'y a aucune implémentation native requise. Pour installer ce plugin, suivez le [Guide de l'Interface de ligne de commande](http://cordova.apache.org/docs/en/edge/guide_cli_index.md.html#The%20Command-line%20Interface).\n\nSi vous n'utilisez pas l'Interface de ligne de commande de Cordova, suivez [Les Plugman à l'aide à gérer les Plugins](http://cordova.apache.org/docs/en/edge/guide_plugin_ref_plugman.md.html). ./cordova-plugin-battery-status/README.md ./cordova-plugin-camera/README.md ./cordova-plugin-console/README.md ./cordova-plugin-contacts/README.md ./cordova-plugin-device/README.md ./cordova-plugin-device-motion/README.md ./cordova-plugin-device-orientation/README.md ./cordova-plugin-device-orientation/src/blackberry10/README.md ./cordova-plugin-file/README.md ./cordova-plugin-file-transfer/README.md ./cordova-plugin-geolocation/README.md ./cordova-plugin-globalization/README.md ./cordova-plugin-inappbrowser/README.md ./cordova-plugin-inappbrowser/src/blackberry10/README.md ./cordova-plugin-media/README.md ./cordova-plugin-media-capture/README.md ./cordova-plugin-network-information/README.md ./cordova-plugin-splashscreen/README.md ./cordova-plugin-vibration/README.md"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/src/blackberry10/doc/it/README.md",
    "content": "<!---\n license: Licensed to the Apache Software Foundation (ASF) under one\n         or more contributor license agreements.  See the NOTICE file\n         distributed with this work for additional information\n         regarding copyright ownership.  The ASF licenses this file\n         to you under the Apache License, Version 2.0 (the\n         \"License\"); you may not use this file except in compliance\n         with the License.  You may obtain a copy of the License at\n\n           http://www.apache.org/licenses/LICENSE-2.0\n\n         Unless required by applicable law or agreed to in writing,\n         software distributed under the License is distributed on an\n         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n         KIND, either express or implied.  See the License for the\n         specific language governing permissions and limitations\n         under the License.\n-->\n\n# BlackBerry 10 In-App-Browser Plugin\n\nIl browser app funzionalità è interamente contenuta nel comune js. Non esiste alcuna implementazione nativa richiesto. Per installare questo plugin, seguire la [Guida per l'interfaccia della riga di comando](http://cordova.apache.org/docs/en/edge/guide_cli_index.md.html#The%20Command-line%20Interface).\n\nSe non si utilizza l'interfaccia della riga di comando di Cordova, seguire [Utilizzando Plugman per gestire i plugin](http://cordova.apache.org/docs/en/edge/guide_plugin_ref_plugman.md.html). ./cordova-plugin-battery-status/README.md ./cordova-plugin-camera/README.md ./cordova-plugin-console/README.md ./cordova-plugin-contacts/README.md ./cordova-plugin-device/README.md ./cordova-plugin-device-motion/README.md ./cordova-plugin-device-orientation/README.md ./cordova-plugin-device-orientation/src/blackberry10/README.md ./cordova-plugin-file/README.md ./cordova-plugin-file-transfer/README.md ./cordova-plugin-geolocation/README.md ./cordova-plugin-globalization/README.md ./cordova-plugin-inappbrowser/README.md ./cordova-plugin-inappbrowser/src/blackberry10/README.md ./cordova-plugin-media/README.md ./cordova-plugin-media-capture/README.md ./cordova-plugin-network-information/README.md ./cordova-plugin-splashscreen/README.md ./cordova-plugin-vibration/README.md"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/src/blackberry10/doc/ja/README.md",
    "content": "<!---\n license: Licensed to the Apache Software Foundation (ASF) under one\n         or more contributor license agreements.  See the NOTICE file\n         distributed with this work for additional information\n         regarding copyright ownership.  The ASF licenses this file\n         to you under the Apache License, Version 2.0 (the\n         \"License\"); you may not use this file except in compliance\n         with the License.  You may obtain a copy of the License at\n\n           http://www.apache.org/licenses/LICENSE-2.0\n\n         Unless required by applicable law or agreed to in writing,\n         software distributed under the License is distributed on an\n         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n         KIND, either express or implied.  See the License for the\n         specific language governing permissions and limitations\n         under the License.\n-->\n\n# BlackBerry 10 In-App-Browser Plugin\n\nアプリケーション ブラウザーの機能は全く一般的な js に含まれています。 ネイティブ実装する必要はありません。 このプラグインをインストールするには[コマンド ライン インターフェイス ガイド](http://cordova.apache.org/docs/en/edge/guide_cli_index.md.html#The%20Command-line%20Interface).\n\nコルドバのコマンド ライン インターフェイスを使用していない場合は場合、[管理のプラグインを使用して Plugman](http://cordova.apache.org/docs/en/edge/guide_plugin_ref_plugman.md.html)に従ってください。 ./cordova-plugin-battery-status/README.md ./cordova-plugin-camera/README.md ./cordova-plugin-console/README.md ./cordova-plugin-contacts/README.md ./cordova-plugin-device/README.md ./cordova-plugin-device-motion/README.md ./cordova-plugin-device-orientation/README.md ./cordova-plugin-device-orientation/src/blackberry10/README.md ./cordova-plugin-file/README.md ./cordova-plugin-file-transfer/README.md ./cordova-plugin-geolocation/README.md ./cordova-plugin-globalization/README.md ./cordova-plugin-inappbrowser/README.md ./cordova-plugin-inappbrowser/src/blackberry10/README.md ./cordova-plugin-media/README.md ./cordova-plugin-media-capture/README.md ./cordova-plugin-network-information/README.md ./cordova-plugin-splashscreen/README.md ./cordova-plugin-vibration/README.md"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/src/blackberry10/doc/ko/README.md",
    "content": "<!---\n license: Licensed to the Apache Software Foundation (ASF) under one\n         or more contributor license agreements.  See the NOTICE file\n         distributed with this work for additional information\n         regarding copyright ownership.  The ASF licenses this file\n         to you under the Apache License, Version 2.0 (the\n         \"License\"); you may not use this file except in compliance\n         with the License.  You may obtain a copy of the License at\n\n           http://www.apache.org/licenses/LICENSE-2.0\n\n         Unless required by applicable law or agreed to in writing,\n         software distributed under the License is distributed on an\n         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n         KIND, either express or implied.  See the License for the\n         specific language governing permissions and limitations\n         under the License.\n-->\n\n# 블랙베리 10 애플 리 케이 션-브라우저 플러그인\n\n응용 프로그램 브라우저에서 기능은 완전히 포함 된 일반적인 js. 필요 없는 기본 구현이입니다. 이 플러그인을 설치 하려면 [명령줄 인터페이스 가이드](http://cordova.apache.org/docs/en/edge/guide_cli_index.md.html#The%20Command-line%20Interface) 를 따라합니다.\n\n코르도바 명령줄 인터페이스를 사용 하지 않는 경우 [관리 플러그인을 사용 하 여 Plugman](http://cordova.apache.org/docs/en/edge/guide_plugin_ref_plugman.md.html)를 따르십시오. ./cordova-plugin-battery-status/README.md ./cordova-plugin-camera/README.md ./cordova-plugin-console/README.md ./cordova-plugin-contacts/README.md ./cordova-plugin-device/README.md ./cordova-plugin-device-motion/README.md ./cordova-plugin-device-orientation/README.md ./cordova-plugin-device-orientation/src/blackberry10/README.md ./cordova-plugin-file/README.md ./cordova-plugin-file-transfer/README.md ./cordova-plugin-geolocation/README.md ./cordova-plugin-globalization/README.md ./cordova-plugin-inappbrowser/README.md ./cordova-plugin-inappbrowser/src/blackberry10/README.md ./cordova-plugin-media/README.md ./cordova-plugin-media-capture/README.md ./cordova-plugin-network-information/README.md ./cordova-plugin-splashscreen/README.md ./cordova-plugin-vibration/README.md"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/src/blackberry10/doc/pl/README.md",
    "content": "<!---\n license: Licensed to the Apache Software Foundation (ASF) under one\n         or more contributor license agreements.  See the NOTICE file\n         distributed with this work for additional information\n         regarding copyright ownership.  The ASF licenses this file\n         to you under the Apache License, Version 2.0 (the\n         \"License\"); you may not use this file except in compliance\n         with the License.  You may obtain a copy of the License at\n\n           http://www.apache.org/licenses/LICENSE-2.0\n\n         Unless required by applicable law or agreed to in writing,\n         software distributed under the License is distributed on an\n         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n         KIND, either express or implied.  See the License for the\n         specific language governing permissions and limitations\n         under the License.\n-->\n\n# BlackBerry 10 In-App-Browser Plugin\n\nW aplikacji Przeglądarka funkcjonalność jest całkowicie zawarty w wspólnej js. Tam jest nie native wdrażania wymagane. Aby zainstalować ten plugin, następować po ten [Przewodnik interfejsu wiersza polecenia](http://cordova.apache.org/docs/en/edge/guide_cli_index.md.html#The%20Command-line%20Interface).\n\nJeśli nie używasz interfejsu wiersza polecenia Cordova, następować po [Przy użyciu Plugman do zarządzania wtyczki](http://cordova.apache.org/docs/en/edge/guide_plugin_ref_plugman.md.html). ./cordova-plugin-battery-status/README.md ./cordova-plugin-camera/README.md ./cordova-plugin-console/README.md ./cordova-plugin-contacts/README.md ./cordova-plugin-device/README.md ./cordova-plugin-device-motion/README.md ./cordova-plugin-device-orientation/README.md ./cordova-plugin-device-orientation/src/blackberry10/README.md ./cordova-plugin-file/README.md ./cordova-plugin-file-transfer/README.md ./cordova-plugin-geolocation/README.md ./cordova-plugin-globalization/README.md ./cordova-plugin-inappbrowser/README.md ./cordova-plugin-inappbrowser/src/blackberry10/README.md ./cordova-plugin-media/README.md ./cordova-plugin-media-capture/README.md ./cordova-plugin-network-information/README.md ./cordova-plugin-splashscreen/README.md ./cordova-plugin-vibration/README.md"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/src/blackberry10/doc/zh/README.md",
    "content": "<!---\n license: Licensed to the Apache Software Foundation (ASF) under one\n         or more contributor license agreements.  See the NOTICE file\n         distributed with this work for additional information\n         regarding copyright ownership.  The ASF licenses this file\n         to you under the Apache License, Version 2.0 (the\n         \"License\"); you may not use this file except in compliance\n         with the License.  You may obtain a copy of the License at\n\n           http://www.apache.org/licenses/LICENSE-2.0\n\n         Unless required by applicable law or agreed to in writing,\n         software distributed under the License is distributed on an\n         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n         KIND, either express or implied.  See the License for the\n         specific language governing permissions and limitations\n         under the License.\n-->\n\n# 黑莓 10 的應用程式瀏覽器外掛程式\n\n在應用程式瀏覽器功能完全包含在常見的 js。 還有沒有本機的實施所需。 若要安裝此外掛程式，請按照[命令列介面指南](http://cordova.apache.org/docs/en/edge/guide_cli_index.md.html#The%20Command-line%20Interface).\n\n如果你不使用的科爾多瓦命令列介面，請按照[使用 Plugman 管理外掛程式](http://cordova.apache.org/docs/en/edge/guide_plugin_ref_plugman.md.html)。 ./cordova-plugin-battery-status/README.md ./cordova-plugin-camera/README.md ./cordova-plugin-console/README.md ./cordova-plugin-contacts/README.md ./cordova-plugin-device/README.md ./cordova-plugin-device-motion/README.md ./cordova-plugin-device-orientation/README.md ./cordova-plugin-device-orientation/src/blackberry10/README.md ./cordova-plugin-file/README.md ./cordova-plugin-file-transfer/README.md ./cordova-plugin-geolocation/README.md ./cordova-plugin-globalization/README.md ./cordova-plugin-inappbrowser/README.md ./cordova-plugin-inappbrowser/src/blackberry10/README.md ./cordova-plugin-media/README.md ./cordova-plugin-media-capture/README.md ./cordova-plugin-network-information/README.md ./cordova-plugin-splashscreen/README.md ./cordova-plugin-vibration/README.md"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/src/browser/InAppBrowserProxy.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\nvar modulemapper = require('cordova/modulemapper');\n\nvar browserWrap,\n    popup,\n    navigationButtonsDiv,\n    navigationButtonsDivInner,\n    backButton,\n    forwardButton,\n    closeButton;\n\nfunction attachNavigationEvents(element, callback) {\n    var onError = function () {\n        callback({ type: \"loaderror\", url: this.contentWindow.location}, {keepCallback: true});\n    };\n\n    element.addEventListener(\"pageshow\", function () {\n        callback({ type: \"loadstart\", url: this.contentWindow.location}, {keepCallback: true});\n    });\n\n    element.addEventListener(\"load\", function () {\n        callback({ type: \"loadstop\", url: this.contentWindow.location}, {keepCallback: true});\n    });\n\n    element.addEventListener(\"error\", onError);\n    element.addEventListener(\"abort\", onError);\n}\n\nvar IAB = {\n    close: function (win, lose) {\n        if (browserWrap) {\n            if (win) win({ type: \"exit\" });\n\n            browserWrap.parentNode.removeChild(browserWrap);\n            browserWrap = null;\n            popup = null;\n        }\n    },\n\n    show: function (win, lose) {\n        if (browserWrap) {\n            browserWrap.style.display = \"block\";\n        }\n    },\n\n    open: function (win, lose, args) {\n        var strUrl = args[0],\n            target = args[1],\n            features = args[2];\n\n        if (target === \"_self\" || !target) {\n            window.location = strUrl;\n        } else if (target === \"_system\") {\n            modulemapper.getOriginalSymbol(window, 'window.open').call(window, strUrl, \"_blank\");\n        } else {\n            // \"_blank\" or anything else\n            if (!browserWrap) {\n                browserWrap = document.createElement(\"div\");\n                browserWrap.style.position = \"absolute\";\n                browserWrap.style.borderWidth = \"40px\";\n                browserWrap.style.width = \"calc(100% - 80px)\";\n                browserWrap.style.height = \"calc(100% - 80px)\";\n                browserWrap.style.borderStyle = \"solid\";\n                browserWrap.style.borderColor = \"rgba(0,0,0,0.25)\";\n\n                browserWrap.onclick = function () {\n                    setTimeout(function () {\n                        IAB.close(win);\n                    }, 0);\n                };\n\n                document.body.appendChild(browserWrap);\n            }\n\n            if (features.indexOf(\"hidden=yes\") !== -1) {\n                browserWrap.style.display = \"none\";\n            }\n\n            popup = document.createElement(\"iframe\");\n            popup.style.borderWidth = \"0px\";\n            popup.style.width = \"100%\";\n\n            browserWrap.appendChild(popup);\n\n            if (features.indexOf(\"location=yes\") !== -1 || features.indexOf(\"location\") === -1) {\n                popup.style.height = \"calc(100% - 60px)\";\n\n                navigationButtonsDiv = document.createElement(\"div\");\n                navigationButtonsDiv.style.height = \"60px\";\n                navigationButtonsDiv.style.backgroundColor = \"#404040\";\n                navigationButtonsDiv.style.zIndex = \"999\";\n                navigationButtonsDiv.onclick = function (e) {\n                    e.cancelBubble = true;\n                };\n\n                navigationButtonsDivInner = document.createElement(\"div\");\n                navigationButtonsDivInner.style.paddingTop = \"10px\";\n                navigationButtonsDivInner.style.height = \"50px\";\n                navigationButtonsDivInner.style.width = \"160px\";\n                navigationButtonsDivInner.style.margin = \"0 auto\";\n                navigationButtonsDivInner.style.backgroundColor = \"#404040\";\n                navigationButtonsDivInner.style.zIndex = \"999\";\n                navigationButtonsDivInner.onclick = function (e) {\n                    e.cancelBubble = true;\n                };\n\n\n                backButton = document.createElement(\"button\");\n                backButton.style.width = \"40px\";\n                backButton.style.height = \"40px\";\n                backButton.style.borderRadius = \"40px\";\n\n                backButton.innerHTML = \"←\";\n                backButton.addEventListener(\"click\", function (e) {\n                    if (popup.canGoBack)\n                        popup.goBack();\n                });\n\n                forwardButton = document.createElement(\"button\");\n                forwardButton.style.marginLeft = \"20px\";\n                forwardButton.style.width = \"40px\";\n                forwardButton.style.height = \"40px\";\n                forwardButton.style.borderRadius = \"40px\";\n\n                forwardButton.innerHTML = \"→\";\n                forwardButton.addEventListener(\"click\", function (e) {\n                    if (popup.canGoForward)\n                        popup.goForward();\n                });\n\n                closeButton = document.createElement(\"button\");\n                closeButton.style.marginLeft = \"20px\";\n                closeButton.style.width = \"40px\";\n                closeButton.style.height = \"40px\";\n                closeButton.style.borderRadius = \"40px\";\n\n                closeButton.innerHTML = \"✖\";\n                closeButton.addEventListener(\"click\", function (e) {\n                    setTimeout(function () {\n                        IAB.close(win);\n                    }, 0);\n                });\n\n                // iframe navigation is not yet supported\n                backButton.disabled = true;\n                forwardButton.disabled = true;\n\n                navigationButtonsDivInner.appendChild(backButton);\n                navigationButtonsDivInner.appendChild(forwardButton);\n                navigationButtonsDivInner.appendChild(closeButton);\n                navigationButtonsDiv.appendChild(navigationButtonsDivInner);\n\n                browserWrap.appendChild(navigationButtonsDiv);\n            } else {\n                popup.style.height = \"100%\";\n            }\n\n            // start listening for navigation events\n            attachNavigationEvents(popup, win);\n\n            popup.src = strUrl;\n        }\n    },\n\n    injectScriptCode: function (win, fail, args) {\n        var code = args[0],\n            hasCallback = args[1];\n\n        if (browserWrap && popup) {\n            try {\n                popup.contentWindow.eval(code);\n                if (hasCallback) {\n                    win([]);\n                }\n            } catch(e) {\n                console.error('Error occured while trying to injectScriptCode: ' + JSON.stringify(e));\n            }\n        }\n    },\n\n    injectScriptFile: function (win, fail, args) {\n        var msg = 'Browser cordova-plugin-inappbrowser injectScriptFile is not yet implemented';\n        console.warn(msg);\n        if (fail) {\n            fail(msg);\n        }\n    }, \n\n    injectStyleCode: function (win, fail, args) {\n        var msg = 'Browser cordova-plugin-inappbrowser injectStyleCode is not yet implemented';\n        console.warn(msg);\n        if (fail) {\n            fail(msg);\n        }\n    },\n\n    injectStyleFile: function (win, fail, args) {\n        var msg = 'Browser cordova-plugin-inappbrowser injectStyleFile is not yet implemented';\n        console.warn(msg);\n        if (fail) {\n            fail(msg);\n        }\n    }\n};\n\nmodule.exports = IAB;\n\nrequire(\"cordova/exec/proxy\").add(\"InAppBrowser\", module.exports);\n"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/src/firefoxos/InAppBrowserProxy.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n// https://developer.mozilla.org/en-US/docs/WebAPI/Browser\n\nvar modulemapper = require('cordova/modulemapper');\n\nvar origOpenFunc = modulemapper.getOriginalSymbol(window, 'window.open');\nvar browserWrap;\n\nvar IABExecs = {\n\n    close: function (win, lose) {\n        if (browserWrap) {\n            browserWrap.parentNode.removeChild(browserWrap);\n            browserWrap = null;\n            if (typeof(win) == \"function\") win({type:'exit'});\n        }\n    },\n\n    /*\n     * Reveal browser if opened hidden\n     */\n    show: function (win, lose) {\n        console.error('[FirefoxOS] show not implemented');\n    },\n\n    open: function (win, lose, args) {\n        var strUrl = args[0],\n            target = args[1],\n            features_string = args[2] || \"location=yes\", //location=yes is default\n            features = {};\n\n        var features_list = features_string.split(',');\n        features_list.forEach(function(feature) {\n            var tup = feature.split('=');\n            if (tup[1] == 'yes') {\n                tup[1] = true;\n            } else if (tup[1] == 'no') {\n                tup[1] = false;\n            } else {\n                var number = parseInt(tup[1]);\n                if (!isNaN(number)) {\n                    tup[1] = number;\n                }\n            }\n            features[tup[0]] = tup[1];\n        });\n\n        function updateIframeSizeNoLocation() {\n            browserWrap.style.width = window.innerWidth + 'px';\n            browserWrap.style.height = window.innerHeight + 'px';\n            browserWrap.style.zIndex = '999999999';\n            browserWrap.browser.style.height = (window.innerHeight - 60) + 'px';\n            browserWrap.browser.style.width = browserWrap.style.width;\n        }\n\n        if (target === '_system') {\n            origOpenFunc.apply(window, [strUrl, '_blank']);\n        } else if (target === '_blank') {\n            var browserElem = document.createElement('iframe');\n            browserElem.setAttribute('mozbrowser', true);\n            // make this loaded in its own child process\n            browserElem.setAttribute('remote', true);\n            browserElem.setAttribute('src', strUrl);\n            if (browserWrap) {\n                document.body.removeChild(browserWrap);\n            }\n            browserWrap = document.createElement('div');\n            // assign browser element to browserWrap for future reference\n            browserWrap.browser = browserElem;\n\n            browserWrap.classList.add('inAppBrowserWrap');\n            // position fixed so that it works even when page is scrolled\n            browserWrap.style.position = 'fixed';\n            browserElem.style.position = 'absolute';\n            browserElem.style.border = 0;\n            browserElem.style.top = '60px';\n            browserElem.style.left = '0px';\n            updateIframeSizeNoLocation();\n\n            var menu = document.createElement('menu');\n            menu.setAttribute('type', 'toolbar');\n            var close = document.createElement('li');\n            var back = document.createElement('li');\n            var forward = document.createElement('li');\n\n            close.appendChild(document.createTextNode('×'));\n            back.appendChild(document.createTextNode('<'));\n            forward.appendChild(document.createTextNode('>'));\n\n            close.classList.add('inAppBrowserClose');\n            back.classList.add('inAppBrowserBack');\n            forward.classList.add('inAppBrowserForward');\n\n            var checkForwardBackward = function () {\n                var backReq = browserElem.getCanGoBack();\n                backReq.onsuccess = function() {\n                    if (this.result) {\n                        back.classList.remove('disabled');\n                    } else {\n                        back.classList.add('disabled');\n                    }\n                };\n                var forwardReq = browserElem.getCanGoForward();\n                forwardReq.onsuccess = function() {\n                    if (this.result) {\n                        forward.classList.remove('disabled');\n                    } else {\n                        forward.classList.add('disabled');\n                    }\n                };\n            };\n\n            browserElem.addEventListener('mozbrowserloadend', checkForwardBackward);\n\n            close.addEventListener('click', function () {\n                setTimeout(function () {\n                    IABExecs.close(win, lose);\n                }, 0);\n            }, false);\n\n            back.addEventListener('click', function () {\n                browserElem.goBack();\n            }, false);\n\n            forward.addEventListener('click', function () {\n                browserElem.goForward();\n            }, false);\n\n            menu.appendChild(back);\n            menu.appendChild(forward);\n            menu.appendChild(close);\n\n            browserWrap.appendChild(menu);\n            browserWrap.appendChild(browserElem);\n            document.body.appendChild(browserWrap);\n\n            //we use mozbrowserlocationchange instead of mozbrowserloadstart to get the url\n            browserElem.addEventListener('mozbrowserlocationchange', function(e){\n                win({\n                    type:'loadstart',\n                    url : e.detail\n                });\n            }, false);\n            browserElem.addEventListener('mozbrowserloadend', function(e){\n                win({type:'loadstop'});\n            }, false);\n            browserElem.addEventListener('mozbrowsererror', function(e){\n                win({type:'loaderror'});\n            }, false);\n            browserElem.addEventListener('mozbrowserclose', function(e){\n                win({type:'exit'});\n            }, false);\n        } else {\n            window.location = strUrl;\n        }\n    },\n    injectScriptCode: function (code, bCB) {\n        console.error('[FirefoxOS] injectScriptCode not implemented');\n    },\n    injectScriptFile: function (file, bCB) {\n        console.error('[FirefoxOS] injectScriptFile not implemented');\n    }\n};\n\nmodule.exports = IABExecs;\n\nrequire('cordova/exec/proxy').add('InAppBrowser', module.exports);\n"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/src/ios/CDVInAppBrowser.h",
    "content": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements.  See the NOTICE file\n distributed with this work for additional information\n regarding copyright ownership.  The ASF licenses this file\n to you under the Apache License, Version 2.0 (the\n \"License\"); you may not use this file except in compliance\n with the License.  You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an\n \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n KIND, either express or implied.  See the License for the\n specific language governing permissions and limitations\n under the License.\n */\n\n#import <Cordova/CDVPlugin.h>\n#import <Cordova/CDVInvokedUrlCommand.h>\n#import <Cordova/CDVScreenOrientationDelegate.h>\n\n#ifdef __CORDOVA_4_0_0\n    #import <Cordova/CDVUIWebViewDelegate.h>\n#else\n    #import <Cordova/CDVWebViewDelegate.h>\n#endif\n\n@class CDVInAppBrowserViewController;\n\n@interface CDVInAppBrowser : CDVPlugin {\n}\n\n@property (nonatomic, retain) CDVInAppBrowserViewController* inAppBrowserViewController;\n@property (nonatomic, copy) NSString* callbackId;\n@property (nonatomic, copy) NSRegularExpression *callbackIdPattern;\n\n- (void)open:(CDVInvokedUrlCommand*)command;\n- (void)close:(CDVInvokedUrlCommand*)command;\n- (void)injectScriptCode:(CDVInvokedUrlCommand*)command;\n- (void)show:(CDVInvokedUrlCommand*)command;\n\n@end\n\n@interface CDVInAppBrowserOptions : NSObject {}\n\n@property (nonatomic, assign) BOOL location;\n@property (nonatomic, assign) BOOL toolbar;\n@property (nonatomic, copy) NSString* closebuttoncaption;\n@property (nonatomic, copy) NSString* toolbarposition;\n@property (nonatomic, assign) BOOL clearcache;\n@property (nonatomic, assign) BOOL clearsessioncache;\n\n@property (nonatomic, copy) NSString* presentationstyle;\n@property (nonatomic, copy) NSString* transitionstyle;\n\n@property (nonatomic, assign) BOOL enableviewportscale;\n@property (nonatomic, assign) BOOL mediaplaybackrequiresuseraction;\n@property (nonatomic, assign) BOOL allowinlinemediaplayback;\n@property (nonatomic, assign) BOOL keyboarddisplayrequiresuseraction;\n@property (nonatomic, assign) BOOL suppressesincrementalrendering;\n@property (nonatomic, assign) BOOL hidden;\n@property (nonatomic, assign) BOOL disallowoverscroll;\n\n+ (CDVInAppBrowserOptions*)parseOptions:(NSString*)options;\n\n@end\n\n@interface CDVInAppBrowserViewController : UIViewController <UIWebViewDelegate, CDVScreenOrientationDelegate>{\n    @private\n    NSString* _userAgent;\n    NSString* _prevUserAgent;\n    NSInteger _userAgentLockToken;\n    CDVInAppBrowserOptions *_browserOptions;\n    \n#ifdef __CORDOVA_4_0_0\n    CDVUIWebViewDelegate* _webViewDelegate;\n#else\n    CDVWebViewDelegate* _webViewDelegate;\n#endif\n    \n}\n\n@property (nonatomic, strong) IBOutlet UIWebView* webView;\n@property (nonatomic, strong) IBOutlet UIBarButtonItem* closeButton;\n@property (nonatomic, strong) IBOutlet UILabel* addressLabel;\n@property (nonatomic, strong) IBOutlet UIBarButtonItem* backButton;\n@property (nonatomic, strong) IBOutlet UIBarButtonItem* forwardButton;\n@property (nonatomic, strong) IBOutlet UIActivityIndicatorView* spinner;\n@property (nonatomic, strong) IBOutlet UIToolbar* toolbar;\n\n@property (nonatomic, weak) id <CDVScreenOrientationDelegate> orientationDelegate;\n@property (nonatomic, weak) CDVInAppBrowser* navigationDelegate;\n@property (nonatomic) NSURL* currentURL;\n\n- (void)close;\n- (void)navigateTo:(NSURL*)url;\n- (void)showLocationBar:(BOOL)show;\n- (void)showToolBar:(BOOL)show : (NSString *) toolbarPosition;\n- (void)setCloseButtonTitle:(NSString*)title;\n\n- (id)initWithUserAgent:(NSString*)userAgent prevUserAgent:(NSString*)prevUserAgent browserOptions: (CDVInAppBrowserOptions*) browserOptions;\n\n@end\n\n@interface CDVInAppBrowserNavigationController : UINavigationController\n\n@property (nonatomic, weak) id <CDVScreenOrientationDelegate> orientationDelegate;\n\n@end\n\n"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/src/ios/CDVInAppBrowser.m",
    "content": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements.  See the NOTICE file\n distributed with this work for additional information\n regarding copyright ownership.  The ASF licenses this file\n to you under the Apache License, Version 2.0 (the\n \"License\"); you may not use this file except in compliance\n with the License.  You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an\n \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n KIND, either express or implied.  See the License for the\n specific language governing permissions and limitations\n under the License.\n */\n\n#import \"CDVInAppBrowser.h\"\n#import <Cordova/CDVPluginResult.h>\n#import <Cordova/CDVUserAgentUtil.h>\n\n#define    kInAppBrowserTargetSelf @\"_self\"\n#define    kInAppBrowserTargetSystem @\"_system\"\n#define    kInAppBrowserTargetBlank @\"_blank\"\n\n#define    kInAppBrowserToolbarBarPositionBottom @\"bottom\"\n#define    kInAppBrowserToolbarBarPositionTop @\"top\"\n\n#define    TOOLBAR_HEIGHT 44.0\n#define    LOCATIONBAR_HEIGHT 21.0\n#define    FOOTER_HEIGHT ((TOOLBAR_HEIGHT) + (LOCATIONBAR_HEIGHT))\n\n#pragma mark CDVInAppBrowser\n\n@interface CDVInAppBrowser () {\n    NSInteger _previousStatusBarStyle;\n}\n@end\n\n@implementation CDVInAppBrowser\n\n- (void)pluginInitialize\n{\n    _previousStatusBarStyle = -1;\n    _callbackIdPattern = nil;\n}\n\n- (void)onReset\n{\n    [self close:nil];\n}\n\n- (void)close:(CDVInvokedUrlCommand*)command\n{\n    if (self.inAppBrowserViewController == nil) {\n        NSLog(@\"IAB.close() called but it was already closed.\");\n        return;\n    }\n    // Things are cleaned up in browserExit.\n    [self.inAppBrowserViewController close];\n}\n\n- (BOOL) isSystemUrl:(NSURL*)url\n{\n\tif ([[url host] isEqualToString:@\"itunes.apple.com\"]) {\n\t\treturn YES;\n\t}\n\n\treturn NO;\n}\n\n- (void)open:(CDVInvokedUrlCommand*)command\n{\n    CDVPluginResult* pluginResult;\n\n    NSString* url = [command argumentAtIndex:0];\n    NSString* target = [command argumentAtIndex:1 withDefault:kInAppBrowserTargetSelf];\n    NSString* options = [command argumentAtIndex:2 withDefault:@\"\" andClass:[NSString class]];\n\n    self.callbackId = command.callbackId;\n\n    if (url != nil) {\n#ifdef __CORDOVA_4_0_0\n        NSURL* baseUrl = [self.webViewEngine URL];\n#else\n        NSURL* baseUrl = [self.webView.request URL];\n#endif\n        NSURL* absoluteUrl = [[NSURL URLWithString:url relativeToURL:baseUrl] absoluteURL];\n\n        if ([self isSystemUrl:absoluteUrl]) {\n            target = kInAppBrowserTargetSystem;\n        }\n\n        if ([target isEqualToString:kInAppBrowserTargetSelf]) {\n            [self openInCordovaWebView:absoluteUrl withOptions:options];\n        } else if ([target isEqualToString:kInAppBrowserTargetSystem]) {\n            [self openInSystem:absoluteUrl];\n        } else { // _blank or anything else\n            [self openInInAppBrowser:absoluteUrl withOptions:options];\n        }\n\n        pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];\n    } else {\n        pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@\"incorrect number of arguments\"];\n    }\n\n    [pluginResult setKeepCallback:[NSNumber numberWithBool:YES]];\n    [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];\n}\n\n- (void)openInInAppBrowser:(NSURL*)url withOptions:(NSString*)options\n{\n    CDVInAppBrowserOptions* browserOptions = [CDVInAppBrowserOptions parseOptions:options];\n\n    if (browserOptions.clearcache) {\n        NSHTTPCookie *cookie;\n        NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];\n        for (cookie in [storage cookies])\n        {\n            if (![cookie.domain isEqual: @\".^filecookies^\"]) {\n                [storage deleteCookie:cookie];\n            }\n        }\n    }\n\n    if (browserOptions.clearsessioncache) {\n        NSHTTPCookie *cookie;\n        NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];\n        for (cookie in [storage cookies])\n        {\n            if (![cookie.domain isEqual: @\".^filecookies^\"] && cookie.isSessionOnly) {\n                [storage deleteCookie:cookie];\n            }\n        }\n    }\n\n    if (self.inAppBrowserViewController == nil) {\n        NSString* originalUA = [CDVUserAgentUtil originalUserAgent];\n        self.inAppBrowserViewController = [[CDVInAppBrowserViewController alloc] initWithUserAgent:originalUA prevUserAgent:[self.commandDelegate userAgent] browserOptions: browserOptions];\n        self.inAppBrowserViewController.navigationDelegate = self;\n\n        if ([self.viewController conformsToProtocol:@protocol(CDVScreenOrientationDelegate)]) {\n            self.inAppBrowserViewController.orientationDelegate = (UIViewController <CDVScreenOrientationDelegate>*)self.viewController;\n        }\n    }\n\n    [self.inAppBrowserViewController showLocationBar:browserOptions.location];\n    [self.inAppBrowserViewController showToolBar:browserOptions.toolbar :browserOptions.toolbarposition];\n    if (browserOptions.closebuttoncaption != nil) {\n        [self.inAppBrowserViewController setCloseButtonTitle:browserOptions.closebuttoncaption];\n    }\n    // Set Presentation Style\n    UIModalPresentationStyle presentationStyle = UIModalPresentationFullScreen; // default\n    if (browserOptions.presentationstyle != nil) {\n        if ([[browserOptions.presentationstyle lowercaseString] isEqualToString:@\"pagesheet\"]) {\n            presentationStyle = UIModalPresentationPageSheet;\n        } else if ([[browserOptions.presentationstyle lowercaseString] isEqualToString:@\"formsheet\"]) {\n            presentationStyle = UIModalPresentationFormSheet;\n        }\n    }\n    self.inAppBrowserViewController.modalPresentationStyle = presentationStyle;\n\n    // Set Transition Style\n    UIModalTransitionStyle transitionStyle = UIModalTransitionStyleCoverVertical; // default\n    if (browserOptions.transitionstyle != nil) {\n        if ([[browserOptions.transitionstyle lowercaseString] isEqualToString:@\"fliphorizontal\"]) {\n            transitionStyle = UIModalTransitionStyleFlipHorizontal;\n        } else if ([[browserOptions.transitionstyle lowercaseString] isEqualToString:@\"crossdissolve\"]) {\n            transitionStyle = UIModalTransitionStyleCrossDissolve;\n        }\n    }\n    self.inAppBrowserViewController.modalTransitionStyle = transitionStyle;\n\n    // prevent webView from bouncing\n    if (browserOptions.disallowoverscroll) {\n        if ([self.inAppBrowserViewController.webView respondsToSelector:@selector(scrollView)]) {\n            ((UIScrollView*)[self.inAppBrowserViewController.webView scrollView]).bounces = NO;\n        } else {\n            for (id subview in self.inAppBrowserViewController.webView.subviews) {\n                if ([[subview class] isSubclassOfClass:[UIScrollView class]]) {\n                    ((UIScrollView*)subview).bounces = NO;\n                }\n            }\n        }\n    }\n\n    // UIWebView options\n    self.inAppBrowserViewController.webView.scalesPageToFit = browserOptions.enableviewportscale;\n    self.inAppBrowserViewController.webView.mediaPlaybackRequiresUserAction = browserOptions.mediaplaybackrequiresuseraction;\n    self.inAppBrowserViewController.webView.allowsInlineMediaPlayback = browserOptions.allowinlinemediaplayback;\n    if (IsAtLeastiOSVersion(@\"6.0\")) {\n        self.inAppBrowserViewController.webView.keyboardDisplayRequiresUserAction = browserOptions.keyboarddisplayrequiresuseraction;\n        self.inAppBrowserViewController.webView.suppressesIncrementalRendering = browserOptions.suppressesincrementalrendering;\n    }\n\n    [self.inAppBrowserViewController navigateTo:url];\n    if (!browserOptions.hidden) {\n        [self show:nil];\n    }\n}\n\n- (void)show:(CDVInvokedUrlCommand*)command\n{\n    if (self.inAppBrowserViewController == nil) {\n        NSLog(@\"Tried to show IAB after it was closed.\");\n        return;\n    }\n    if (_previousStatusBarStyle != -1) {\n        NSLog(@\"Tried to show IAB while already shown\");\n        return;\n    }\n\n    _previousStatusBarStyle = [UIApplication sharedApplication].statusBarStyle;\n\n    __block CDVInAppBrowserNavigationController* nav = [[CDVInAppBrowserNavigationController alloc]\n                                   initWithRootViewController:self.inAppBrowserViewController];\n    nav.orientationDelegate = self.inAppBrowserViewController;\n    nav.navigationBarHidden = YES;\n\n    __weak CDVInAppBrowser* weakSelf = self;\n\n    // Run later to avoid the \"took a long time\" log message.\n    dispatch_async(dispatch_get_main_queue(), ^{\n        if (weakSelf.inAppBrowserViewController != nil) {\n            [weakSelf.viewController presentViewController:nav animated:YES completion:nil];\n        }\n    });\n}\n\n- (void)openInCordovaWebView:(NSURL*)url withOptions:(NSString*)options\n{\n    NSURLRequest* request = [NSURLRequest requestWithURL:url];\n\n#ifdef __CORDOVA_4_0_0\n    // the webview engine itself will filter for this according to <allow-navigation> policy\n    // in config.xml for cordova-ios-4.0\n    [self.webViewEngine loadRequest:request];\n#else\n    if ([self.commandDelegate URLIsWhitelisted:url]) {\n        [self.webView loadRequest:request];\n    } else { // this assumes the InAppBrowser can be excepted from the white-list\n        [self openInInAppBrowser:url withOptions:options];\n    }\n#endif\n}\n\n- (void)openInSystem:(NSURL*)url\n{\n    if ([[UIApplication sharedApplication] canOpenURL:url]) {\n        [[UIApplication sharedApplication] openURL:url];\n    } else { // handle any custom schemes to plugins\n        [[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:CDVPluginHandleOpenURLNotification object:url]];\n    }\n}\n\n// This is a helper method for the inject{Script|Style}{Code|File} API calls, which\n// provides a consistent method for injecting JavaScript code into the document.\n//\n// If a wrapper string is supplied, then the source string will be JSON-encoded (adding\n// quotes) and wrapped using string formatting. (The wrapper string should have a single\n// '%@' marker).\n//\n// If no wrapper is supplied, then the source string is executed directly.\n\n- (void)injectDeferredObject:(NSString*)source withWrapper:(NSString*)jsWrapper\n{\n    // Ensure an iframe bridge is created to communicate with the CDVInAppBrowserViewController\n    [self.inAppBrowserViewController.webView stringByEvaluatingJavaScriptFromString:@\"(function(d){_cdvIframeBridge=d.getElementById('_cdvIframeBridge');if(!_cdvIframeBridge) {var e = _cdvIframeBridge = d.createElement('iframe');e.id='_cdvIframeBridge'; e.style.display='none';d.body.appendChild(e);}})(document)\"];\n\n    if (jsWrapper != nil) {\n        NSData* jsonData = [NSJSONSerialization dataWithJSONObject:@[source] options:0 error:nil];\n        NSString* sourceArrayString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];\n        if (sourceArrayString) {\n            NSString* sourceString = [sourceArrayString substringWithRange:NSMakeRange(1, [sourceArrayString length] - 2)];\n            NSString* jsToInject = [NSString stringWithFormat:jsWrapper, sourceString];\n            [self.inAppBrowserViewController.webView stringByEvaluatingJavaScriptFromString:jsToInject];\n        }\n    } else {\n        [self.inAppBrowserViewController.webView stringByEvaluatingJavaScriptFromString:source];\n    }\n}\n\n- (void)injectScriptCode:(CDVInvokedUrlCommand*)command\n{\n    NSString* jsWrapper = nil;\n\n    if ((command.callbackId != nil) && ![command.callbackId isEqualToString:@\"INVALID\"]) {\n        jsWrapper = [NSString stringWithFormat:@\"_cdvIframeBridge.src='gap-iab://%@/'+encodeURIComponent(JSON.stringify([eval(%%@)]));\", command.callbackId];\n    }\n    [self injectDeferredObject:[command argumentAtIndex:0] withWrapper:jsWrapper];\n}\n\n- (void)injectScriptFile:(CDVInvokedUrlCommand*)command\n{\n    NSString* jsWrapper;\n\n    if ((command.callbackId != nil) && ![command.callbackId isEqualToString:@\"INVALID\"]) {\n        jsWrapper = [NSString stringWithFormat:@\"(function(d) { var c = d.createElement('script'); c.src = %%@; c.onload = function() { _cdvIframeBridge.src='gap-iab://%@'; }; d.body.appendChild(c); })(document)\", command.callbackId];\n    } else {\n        jsWrapper = @\"(function(d) { var c = d.createElement('script'); c.src = %@; d.body.appendChild(c); })(document)\";\n    }\n    [self injectDeferredObject:[command argumentAtIndex:0] withWrapper:jsWrapper];\n}\n\n- (void)injectStyleCode:(CDVInvokedUrlCommand*)command\n{\n    NSString* jsWrapper;\n\n    if ((command.callbackId != nil) && ![command.callbackId isEqualToString:@\"INVALID\"]) {\n        jsWrapper = [NSString stringWithFormat:@\"(function(d) { var c = d.createElement('style'); c.innerHTML = %%@; c.onload = function() { _cdvIframeBridge.src='gap-iab://%@'; }; d.body.appendChild(c); })(document)\", command.callbackId];\n    } else {\n        jsWrapper = @\"(function(d) { var c = d.createElement('style'); c.innerHTML = %@; d.body.appendChild(c); })(document)\";\n    }\n    [self injectDeferredObject:[command argumentAtIndex:0] withWrapper:jsWrapper];\n}\n\n- (void)injectStyleFile:(CDVInvokedUrlCommand*)command\n{\n    NSString* jsWrapper;\n\n    if ((command.callbackId != nil) && ![command.callbackId isEqualToString:@\"INVALID\"]) {\n        jsWrapper = [NSString stringWithFormat:@\"(function(d) { var c = d.createElement('link'); c.rel='stylesheet'; c.type='text/css'; c.href = %%@; c.onload = function() { _cdvIframeBridge.src='gap-iab://%@'; }; d.body.appendChild(c); })(document)\", command.callbackId];\n    } else {\n        jsWrapper = @\"(function(d) { var c = d.createElement('link'); c.rel='stylesheet', c.type='text/css'; c.href = %@; d.body.appendChild(c); })(document)\";\n    }\n    [self injectDeferredObject:[command argumentAtIndex:0] withWrapper:jsWrapper];\n}\n\n- (BOOL)isValidCallbackId:(NSString *)callbackId\n{\n    NSError *err = nil;\n    // Initialize on first use\n    if (self.callbackIdPattern == nil) {\n        self.callbackIdPattern = [NSRegularExpression regularExpressionWithPattern:@\"^InAppBrowser[0-9]{1,10}$\" options:0 error:&err];\n        if (err != nil) {\n            // Couldn't initialize Regex; No is safer than Yes.\n            return NO;\n        }\n    }\n    if ([self.callbackIdPattern firstMatchInString:callbackId options:0 range:NSMakeRange(0, [callbackId length])]) {\n        return YES;\n    }\n    return NO;\n}\n\n/**\n * The iframe bridge provided for the InAppBrowser is capable of executing any oustanding callback belonging\n * to the InAppBrowser plugin. Care has been taken that other callbacks cannot be triggered, and that no\n * other code execution is possible.\n *\n * To trigger the bridge, the iframe (or any other resource) should attempt to load a url of the form:\n *\n * gap-iab://<callbackId>/<arguments>\n *\n * where <callbackId> is the string id of the callback to trigger (something like \"InAppBrowser0123456789\")\n *\n * If present, the path component of the special gap-iab:// url is expected to be a URL-escaped JSON-encoded\n * value to pass to the callback. [NSURL path] should take care of the URL-unescaping, and a JSON_EXCEPTION\n * is returned if the JSON is invalid.\n */\n- (BOOL)webView:(UIWebView*)theWebView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType\n{\n    NSURL* url = request.URL;\n    BOOL isTopLevelNavigation = [request.URL isEqual:[request mainDocumentURL]];\n\n    // See if the url uses the 'gap-iab' protocol. If so, the host should be the id of a callback to execute,\n    // and the path, if present, should be a JSON-encoded value to pass to the callback.\n    if ([[url scheme] isEqualToString:@\"gap-iab\"]) {\n        NSString* scriptCallbackId = [url host];\n        CDVPluginResult* pluginResult = nil;\n\n        if ([self isValidCallbackId:scriptCallbackId]) {\n            NSString* scriptResult = [url path];\n            NSError* __autoreleasing error = nil;\n\n            // The message should be a JSON-encoded array of the result of the script which executed.\n            if ((scriptResult != nil) && ([scriptResult length] > 1)) {\n                scriptResult = [scriptResult substringFromIndex:1];\n                NSData* decodedResult = [NSJSONSerialization JSONObjectWithData:[scriptResult dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:&error];\n                if ((error == nil) && [decodedResult isKindOfClass:[NSArray class]]) {\n                    pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsArray:(NSArray*)decodedResult];\n                } else {\n                    pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_JSON_EXCEPTION];\n                }\n            } else {\n                pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsArray:@[]];\n            }\n            [self.commandDelegate sendPluginResult:pluginResult callbackId:scriptCallbackId];\n            return NO;\n        }\n    } \n    //if is an app store link, let the system handle it, otherwise it fails to load it\n    else if ([[ url scheme] isEqualToString:@\"itms-appss\"] || [[ url scheme] isEqualToString:@\"itms-apps\"]) {\n        [theWebView stopLoading];\n        [self openInSystem:url];\n        return NO;\n    }\n    else if ((self.callbackId != nil) && isTopLevelNavigation) {\n        // Send a loadstart event for each top-level navigation (includes redirects).\n        CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK\n                                                      messageAsDictionary:@{@\"type\":@\"loadstart\", @\"url\":[url absoluteString]}];\n        [pluginResult setKeepCallback:[NSNumber numberWithBool:YES]];\n\n        [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];\n    }\n\n    return YES;\n}\n\n- (void)webViewDidStartLoad:(UIWebView*)theWebView\n{\n}\n\n- (void)webViewDidFinishLoad:(UIWebView*)theWebView\n{\n    if (self.callbackId != nil) {\n        // TODO: It would be more useful to return the URL the page is actually on (e.g. if it's been redirected).\n        NSString* url = [self.inAppBrowserViewController.currentURL absoluteString];\n        CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK\n                                                      messageAsDictionary:@{@\"type\":@\"loadstop\", @\"url\":url}];\n        [pluginResult setKeepCallback:[NSNumber numberWithBool:YES]];\n\n        [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];\n    }\n}\n\n- (void)webView:(UIWebView*)theWebView didFailLoadWithError:(NSError*)error\n{\n    if (self.callbackId != nil) {\n        NSString* url = [self.inAppBrowserViewController.currentURL absoluteString];\n        CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR\n                                                      messageAsDictionary:@{@\"type\":@\"loaderror\", @\"url\":url, @\"code\": [NSNumber numberWithInteger:error.code], @\"message\": error.localizedDescription}];\n        [pluginResult setKeepCallback:[NSNumber numberWithBool:YES]];\n\n        [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];\n    }\n}\n\n- (void)browserExit\n{\n    if (self.callbackId != nil) {\n        CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK\n                                                      messageAsDictionary:@{@\"type\":@\"exit\"}];\n        [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];\n        self.callbackId = nil;\n    }\n    // Set navigationDelegate to nil to ensure no callbacks are received from it.\n    self.inAppBrowserViewController.navigationDelegate = nil;\n    // Don't recycle the ViewController since it may be consuming a lot of memory.\n    // Also - this is required for the PDF/User-Agent bug work-around.\n    self.inAppBrowserViewController = nil;\n\n    if (IsAtLeastiOSVersion(@\"7.0\")) {\n        if (_previousStatusBarStyle != -1) {\n            [[UIApplication sharedApplication] setStatusBarStyle:_previousStatusBarStyle];\n        }\n    }\n\n    _previousStatusBarStyle = -1; // this value was reset before reapplying it. caused statusbar to stay black on ios7\n}\n\n@end\n\n#pragma mark CDVInAppBrowserViewController\n\n@implementation CDVInAppBrowserViewController\n\n@synthesize currentURL;\n\n- (id)initWithUserAgent:(NSString*)userAgent prevUserAgent:(NSString*)prevUserAgent browserOptions: (CDVInAppBrowserOptions*) browserOptions\n{\n    self = [super init];\n    if (self != nil) {\n        _userAgent = userAgent;\n        _prevUserAgent = prevUserAgent;\n        _browserOptions = browserOptions;\n#ifdef __CORDOVA_4_0_0\n        _webViewDelegate = [[CDVUIWebViewDelegate alloc] initWithDelegate:self];\n#else\n        _webViewDelegate = [[CDVWebViewDelegate alloc] initWithDelegate:self];\n#endif\n        \n        [self createViews];\n    }\n\n    return self;\n}\n\n// Prevent crashes on closing windows\n-(void)dealloc {\n   self.webView.delegate = nil;\n}\n\n- (void)createViews\n{\n    // We create the views in code for primarily for ease of upgrades and not requiring an external .xib to be included\n\n    CGRect webViewBounds = self.view.bounds;\n    BOOL toolbarIsAtBottom = ![_browserOptions.toolbarposition isEqualToString:kInAppBrowserToolbarBarPositionTop];\n    webViewBounds.size.height -= _browserOptions.location ? FOOTER_HEIGHT : TOOLBAR_HEIGHT;\n    self.webView = [[UIWebView alloc] initWithFrame:webViewBounds];\n\n    self.webView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);\n\n    [self.view addSubview:self.webView];\n    [self.view sendSubviewToBack:self.webView];\n\n    self.webView.delegate = _webViewDelegate;\n    self.webView.backgroundColor = [UIColor whiteColor];\n\n    self.webView.clearsContextBeforeDrawing = YES;\n    self.webView.clipsToBounds = YES;\n    self.webView.contentMode = UIViewContentModeScaleToFill;\n    self.webView.multipleTouchEnabled = YES;\n    self.webView.opaque = YES;\n    self.webView.scalesPageToFit = NO;\n    self.webView.userInteractionEnabled = YES;\n\n    self.spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];\n    self.spinner.alpha = 1.000;\n    self.spinner.autoresizesSubviews = YES;\n    self.spinner.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin);\n    self.spinner.clearsContextBeforeDrawing = NO;\n    self.spinner.clipsToBounds = NO;\n    self.spinner.contentMode = UIViewContentModeScaleToFill;\n    self.spinner.frame = CGRectMake(CGRectGetMidX(self.webView.frame), CGRectGetMidY(self.webView.frame), 20.0, 20.0);\n    self.spinner.hidden = NO;\n    self.spinner.hidesWhenStopped = YES;\n    self.spinner.multipleTouchEnabled = NO;\n    self.spinner.opaque = NO;\n    self.spinner.userInteractionEnabled = NO;\n    [self.spinner stopAnimating];\n\n    self.closeButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(close)];\n    self.closeButton.enabled = YES;\n\n    UIBarButtonItem* flexibleSpaceButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];\n\n    UIBarButtonItem* fixedSpaceButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];\n    fixedSpaceButton.width = 20;\n\n    float toolbarY = toolbarIsAtBottom ? self.view.bounds.size.height - TOOLBAR_HEIGHT : 0.0;\n    CGRect toolbarFrame = CGRectMake(0.0, toolbarY, self.view.bounds.size.width, TOOLBAR_HEIGHT);\n\n    self.toolbar = [[UIToolbar alloc] initWithFrame:toolbarFrame];\n    self.toolbar.alpha = 1.000;\n    self.toolbar.autoresizesSubviews = YES;\n    self.toolbar.autoresizingMask = toolbarIsAtBottom ? (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin) : UIViewAutoresizingFlexibleWidth;\n    self.toolbar.barStyle = UIBarStyleBlackOpaque;\n    self.toolbar.clearsContextBeforeDrawing = NO;\n    self.toolbar.clipsToBounds = NO;\n    self.toolbar.contentMode = UIViewContentModeScaleToFill;\n    self.toolbar.hidden = NO;\n    self.toolbar.multipleTouchEnabled = NO;\n    self.toolbar.opaque = NO;\n    self.toolbar.userInteractionEnabled = YES;\n\n    CGFloat labelInset = 5.0;\n    float locationBarY = toolbarIsAtBottom ? self.view.bounds.size.height - FOOTER_HEIGHT : self.view.bounds.size.height - LOCATIONBAR_HEIGHT;\n\n    self.addressLabel = [[UILabel alloc] initWithFrame:CGRectMake(labelInset, locationBarY, self.view.bounds.size.width - labelInset, LOCATIONBAR_HEIGHT)];\n    self.addressLabel.adjustsFontSizeToFitWidth = NO;\n    self.addressLabel.alpha = 1.000;\n    self.addressLabel.autoresizesSubviews = YES;\n    self.addressLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin;\n    self.addressLabel.backgroundColor = [UIColor clearColor];\n    self.addressLabel.baselineAdjustment = UIBaselineAdjustmentAlignCenters;\n    self.addressLabel.clearsContextBeforeDrawing = YES;\n    self.addressLabel.clipsToBounds = YES;\n    self.addressLabel.contentMode = UIViewContentModeScaleToFill;\n    self.addressLabel.enabled = YES;\n    self.addressLabel.hidden = NO;\n    self.addressLabel.lineBreakMode = NSLineBreakByTruncatingTail;\n\n    if ([self.addressLabel respondsToSelector:NSSelectorFromString(@\"setMinimumScaleFactor:\")]) {\n        [self.addressLabel setValue:@(10.0/[UIFont labelFontSize]) forKey:@\"minimumScaleFactor\"];\n    } else if ([self.addressLabel respondsToSelector:NSSelectorFromString(@\"setMinimumFontSize:\")]) {\n        [self.addressLabel setValue:@(10.0) forKey:@\"minimumFontSize\"];\n    }\n\n    self.addressLabel.multipleTouchEnabled = NO;\n    self.addressLabel.numberOfLines = 1;\n    self.addressLabel.opaque = NO;\n    self.addressLabel.shadowOffset = CGSizeMake(0.0, -1.0);\n    self.addressLabel.text = NSLocalizedString(@\"Loading...\", nil);\n    self.addressLabel.textAlignment = NSTextAlignmentLeft;\n    self.addressLabel.textColor = [UIColor colorWithWhite:1.000 alpha:1.000];\n    self.addressLabel.userInteractionEnabled = NO;\n\n    NSString* frontArrowString = NSLocalizedString(@\"►\", nil); // create arrow from Unicode char\n    self.forwardButton = [[UIBarButtonItem alloc] initWithTitle:frontArrowString style:UIBarButtonItemStylePlain target:self action:@selector(goForward:)];\n    self.forwardButton.enabled = YES;\n    self.forwardButton.imageInsets = UIEdgeInsetsZero;\n\n    NSString* backArrowString = NSLocalizedString(@\"◄\", nil); // create arrow from Unicode char\n    self.backButton = [[UIBarButtonItem alloc] initWithTitle:backArrowString style:UIBarButtonItemStylePlain target:self action:@selector(goBack:)];\n    self.backButton.enabled = YES;\n    self.backButton.imageInsets = UIEdgeInsetsZero;\n\n    [self.toolbar setItems:@[self.closeButton, flexibleSpaceButton, self.backButton, fixedSpaceButton, self.forwardButton]];\n\n    self.view.backgroundColor = [UIColor grayColor];\n    [self.view addSubview:self.toolbar];\n    [self.view addSubview:self.addressLabel];\n    [self.view addSubview:self.spinner];\n}\n\n- (void) setWebViewFrame : (CGRect) frame {\n    NSLog(@\"Setting the WebView's frame to %@\", NSStringFromCGRect(frame));\n    [self.webView setFrame:frame];\n}\n\n- (void)setCloseButtonTitle:(NSString*)title\n{\n    // the advantage of using UIBarButtonSystemItemDone is the system will localize it for you automatically\n    // but, if you want to set this yourself, knock yourself out (we can't set the title for a system Done button, so we have to create a new one)\n    self.closeButton = nil;\n    self.closeButton = [[UIBarButtonItem alloc] initWithTitle:title style:UIBarButtonItemStyleBordered target:self action:@selector(close)];\n    self.closeButton.enabled = YES;\n    self.closeButton.tintColor = [UIColor colorWithRed:60.0 / 255.0 green:136.0 / 255.0 blue:230.0 / 255.0 alpha:1];\n\n    NSMutableArray* items = [self.toolbar.items mutableCopy];\n    [items replaceObjectAtIndex:0 withObject:self.closeButton];\n    [self.toolbar setItems:items];\n}\n\n- (void)showLocationBar:(BOOL)show\n{\n    CGRect locationbarFrame = self.addressLabel.frame;\n\n    BOOL toolbarVisible = !self.toolbar.hidden;\n\n    // prevent double show/hide\n    if (show == !(self.addressLabel.hidden)) {\n        return;\n    }\n\n    if (show) {\n        self.addressLabel.hidden = NO;\n\n        if (toolbarVisible) {\n            // toolBar at the bottom, leave as is\n            // put locationBar on top of the toolBar\n\n            CGRect webViewBounds = self.view.bounds;\n            webViewBounds.size.height -= FOOTER_HEIGHT;\n            [self setWebViewFrame:webViewBounds];\n\n            locationbarFrame.origin.y = webViewBounds.size.height;\n            self.addressLabel.frame = locationbarFrame;\n        } else {\n            // no toolBar, so put locationBar at the bottom\n\n            CGRect webViewBounds = self.view.bounds;\n            webViewBounds.size.height -= LOCATIONBAR_HEIGHT;\n            [self setWebViewFrame:webViewBounds];\n\n            locationbarFrame.origin.y = webViewBounds.size.height;\n            self.addressLabel.frame = locationbarFrame;\n        }\n    } else {\n        self.addressLabel.hidden = YES;\n\n        if (toolbarVisible) {\n            // locationBar is on top of toolBar, hide locationBar\n\n            // webView take up whole height less toolBar height\n            CGRect webViewBounds = self.view.bounds;\n            webViewBounds.size.height -= TOOLBAR_HEIGHT;\n            [self setWebViewFrame:webViewBounds];\n        } else {\n            // no toolBar, expand webView to screen dimensions\n            [self setWebViewFrame:self.view.bounds];\n        }\n    }\n}\n\n- (void)showToolBar:(BOOL)show : (NSString *) toolbarPosition\n{\n    CGRect toolbarFrame = self.toolbar.frame;\n    CGRect locationbarFrame = self.addressLabel.frame;\n\n    BOOL locationbarVisible = !self.addressLabel.hidden;\n\n    // prevent double show/hide\n    if (show == !(self.toolbar.hidden)) {\n        return;\n    }\n\n    if (show) {\n        self.toolbar.hidden = NO;\n        CGRect webViewBounds = self.view.bounds;\n\n        if (locationbarVisible) {\n            // locationBar at the bottom, move locationBar up\n            // put toolBar at the bottom\n            webViewBounds.size.height -= FOOTER_HEIGHT;\n            locationbarFrame.origin.y = webViewBounds.size.height;\n            self.addressLabel.frame = locationbarFrame;\n            self.toolbar.frame = toolbarFrame;\n        } else {\n            // no locationBar, so put toolBar at the bottom\n            CGRect webViewBounds = self.view.bounds;\n            webViewBounds.size.height -= TOOLBAR_HEIGHT;\n            self.toolbar.frame = toolbarFrame;\n        }\n\n        if ([toolbarPosition isEqualToString:kInAppBrowserToolbarBarPositionTop]) {\n            toolbarFrame.origin.y = 0;\n            webViewBounds.origin.y += toolbarFrame.size.height;\n            [self setWebViewFrame:webViewBounds];\n        } else {\n            toolbarFrame.origin.y = (webViewBounds.size.height + LOCATIONBAR_HEIGHT);\n        }\n        [self setWebViewFrame:webViewBounds];\n\n    } else {\n        self.toolbar.hidden = YES;\n\n        if (locationbarVisible) {\n            // locationBar is on top of toolBar, hide toolBar\n            // put locationBar at the bottom\n\n            // webView take up whole height less locationBar height\n            CGRect webViewBounds = self.view.bounds;\n            webViewBounds.size.height -= LOCATIONBAR_HEIGHT;\n            [self setWebViewFrame:webViewBounds];\n\n            // move locationBar down\n            locationbarFrame.origin.y = webViewBounds.size.height;\n            self.addressLabel.frame = locationbarFrame;\n        } else {\n            // no locationBar, expand webView to screen dimensions\n            [self setWebViewFrame:self.view.bounds];\n        }\n    }\n}\n\n- (void)viewDidLoad\n{\n    [super viewDidLoad];\n}\n\n- (void)viewDidUnload\n{\n    [self.webView loadHTMLString:nil baseURL:nil];\n    [CDVUserAgentUtil releaseLock:&_userAgentLockToken];\n    [super viewDidUnload];\n}\n\n- (UIStatusBarStyle)preferredStatusBarStyle\n{\n    return UIStatusBarStyleDefault;\n}\n\n- (BOOL)prefersStatusBarHidden {\n    return NO;\n}\n\n- (void)close\n{\n    [CDVUserAgentUtil releaseLock:&_userAgentLockToken];\n    self.currentURL = nil;\n\n    if ((self.navigationDelegate != nil) && [self.navigationDelegate respondsToSelector:@selector(browserExit)]) {\n        [self.navigationDelegate browserExit];\n    }\n\n    __weak UIViewController* weakSelf = self;\n\n    // Run later to avoid the \"took a long time\" log message.\n    dispatch_async(dispatch_get_main_queue(), ^{\n        if ([weakSelf respondsToSelector:@selector(presentingViewController)]) {\n            [[weakSelf presentingViewController] dismissViewControllerAnimated:YES completion:nil];\n        } else {\n            [[weakSelf parentViewController] dismissViewControllerAnimated:YES completion:nil];\n        }\n    });\n}\n\n- (void)navigateTo:(NSURL*)url\n{\n    NSURLRequest* request = [NSURLRequest requestWithURL:url];\n\n    if (_userAgentLockToken != 0) {\n        [self.webView loadRequest:request];\n    } else {\n        __weak CDVInAppBrowserViewController* weakSelf = self;\n        [CDVUserAgentUtil acquireLock:^(NSInteger lockToken) {\n            _userAgentLockToken = lockToken;\n            [CDVUserAgentUtil setUserAgent:_userAgent lockToken:lockToken];\n            [weakSelf.webView loadRequest:request];\n        }];\n    }\n}\n\n- (void)goBack:(id)sender\n{\n    [self.webView goBack];\n}\n\n- (void)goForward:(id)sender\n{\n    [self.webView goForward];\n}\n\n- (void)viewWillAppear:(BOOL)animated\n{\n    if (IsAtLeastiOSVersion(@\"7.0\")) {\n        [[UIApplication sharedApplication] setStatusBarStyle:[self preferredStatusBarStyle]];\n    }\n    [self rePositionViews];\n\n    [super viewWillAppear:animated];\n}\n\n//\n// On iOS 7 the status bar is part of the view's dimensions, therefore it's height has to be taken into account.\n// The height of it could be hardcoded as 20 pixels, but that would assume that the upcoming releases of iOS won't\n// change that value.\n//\n- (float) getStatusBarOffset {\n    CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];\n    float statusBarOffset = IsAtLeastiOSVersion(@\"7.0\") ? MIN(statusBarFrame.size.width, statusBarFrame.size.height) : 0.0;\n    return statusBarOffset;\n}\n\n- (void) rePositionViews {\n    if ([_browserOptions.toolbarposition isEqualToString:kInAppBrowserToolbarBarPositionTop]) {\n        [self.webView setFrame:CGRectMake(self.webView.frame.origin.x, TOOLBAR_HEIGHT, self.webView.frame.size.width, self.webView.frame.size.height)];\n        [self.toolbar setFrame:CGRectMake(self.toolbar.frame.origin.x, [self getStatusBarOffset], self.toolbar.frame.size.width, self.toolbar.frame.size.height)];\n    }\n}\n\n#pragma mark UIWebViewDelegate\n\n- (void)webViewDidStartLoad:(UIWebView*)theWebView\n{\n    // loading url, start spinner, update back/forward\n\n    self.addressLabel.text = NSLocalizedString(@\"Loading...\", nil);\n    self.backButton.enabled = theWebView.canGoBack;\n    self.forwardButton.enabled = theWebView.canGoForward;\n\n    [self.spinner startAnimating];\n\n    return [self.navigationDelegate webViewDidStartLoad:theWebView];\n}\n\n- (BOOL)webView:(UIWebView*)theWebView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType\n{\n    BOOL isTopLevelNavigation = [request.URL isEqual:[request mainDocumentURL]];\n\n    if (isTopLevelNavigation) {\n        self.currentURL = request.URL;\n    }\n    return [self.navigationDelegate webView:theWebView shouldStartLoadWithRequest:request navigationType:navigationType];\n}\n\n- (void)webViewDidFinishLoad:(UIWebView*)theWebView\n{\n    // update url, stop spinner, update back/forward\n\n    self.addressLabel.text = [self.currentURL absoluteString];\n    self.backButton.enabled = theWebView.canGoBack;\n    self.forwardButton.enabled = theWebView.canGoForward;\n\n    [self.spinner stopAnimating];\n\n    // Work around a bug where the first time a PDF is opened, all UIWebViews\n    // reload their User-Agent from NSUserDefaults.\n    // This work-around makes the following assumptions:\n    // 1. The app has only a single Cordova Webview. If not, then the app should\n    //    take it upon themselves to load a PDF in the background as a part of\n    //    their start-up flow.\n    // 2. That the PDF does not require any additional network requests. We change\n    //    the user-agent here back to that of the CDVViewController, so requests\n    //    from it must pass through its white-list. This *does* break PDFs that\n    //    contain links to other remote PDF/websites.\n    // More info at https://issues.apache.org/jira/browse/CB-2225\n    BOOL isPDF = [@\"true\" isEqualToString :[theWebView stringByEvaluatingJavaScriptFromString:@\"document.body==null\"]];\n    if (isPDF) {\n        [CDVUserAgentUtil setUserAgent:_prevUserAgent lockToken:_userAgentLockToken];\n    }\n\n    [self.navigationDelegate webViewDidFinishLoad:theWebView];\n}\n\n- (void)webView:(UIWebView*)theWebView didFailLoadWithError:(NSError*)error\n{\n    // log fail message, stop spinner, update back/forward\n    NSLog(@\"webView:didFailLoadWithError - %ld: %@\", (long)error.code, [error localizedDescription]);\n\n    self.backButton.enabled = theWebView.canGoBack;\n    self.forwardButton.enabled = theWebView.canGoForward;\n    [self.spinner stopAnimating];\n\n    self.addressLabel.text = NSLocalizedString(@\"Load Error\", nil);\n\n    [self.navigationDelegate webView:theWebView didFailLoadWithError:error];\n}\n\n#pragma mark CDVScreenOrientationDelegate\n\n- (BOOL)shouldAutorotate\n{\n    if ((self.orientationDelegate != nil) && [self.orientationDelegate respondsToSelector:@selector(shouldAutorotate)]) {\n        return [self.orientationDelegate shouldAutorotate];\n    }\n    return YES;\n}\n\n- (NSUInteger)supportedInterfaceOrientations\n{\n    if ((self.orientationDelegate != nil) && [self.orientationDelegate respondsToSelector:@selector(supportedInterfaceOrientations)]) {\n        return [self.orientationDelegate supportedInterfaceOrientations];\n    }\n\n    return 1 << UIInterfaceOrientationPortrait;\n}\n\n- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation\n{\n    if ((self.orientationDelegate != nil) && [self.orientationDelegate respondsToSelector:@selector(shouldAutorotateToInterfaceOrientation:)]) {\n        return [self.orientationDelegate shouldAutorotateToInterfaceOrientation:interfaceOrientation];\n    }\n\n    return YES;\n}\n\n@end\n\n@implementation CDVInAppBrowserOptions\n\n- (id)init\n{\n    if (self = [super init]) {\n        // default values\n        self.location = YES;\n        self.toolbar = YES;\n        self.closebuttoncaption = nil;\n        self.toolbarposition = kInAppBrowserToolbarBarPositionBottom;\n        self.clearcache = NO;\n        self.clearsessioncache = NO;\n\n        self.enableviewportscale = NO;\n        self.mediaplaybackrequiresuseraction = NO;\n        self.allowinlinemediaplayback = NO;\n        self.keyboarddisplayrequiresuseraction = YES;\n        self.suppressesincrementalrendering = NO;\n        self.hidden = NO;\n        self.disallowoverscroll = NO;\n    }\n\n    return self;\n}\n\n+ (CDVInAppBrowserOptions*)parseOptions:(NSString*)options\n{\n    CDVInAppBrowserOptions* obj = [[CDVInAppBrowserOptions alloc] init];\n\n    // NOTE: this parsing does not handle quotes within values\n    NSArray* pairs = [options componentsSeparatedByString:@\",\"];\n\n    // parse keys and values, set the properties\n    for (NSString* pair in pairs) {\n        NSArray* keyvalue = [pair componentsSeparatedByString:@\"=\"];\n\n        if ([keyvalue count] == 2) {\n            NSString* key = [[keyvalue objectAtIndex:0] lowercaseString];\n            NSString* value = [keyvalue objectAtIndex:1];\n            NSString* value_lc = [value lowercaseString];\n\n            BOOL isBoolean = [value_lc isEqualToString:@\"yes\"] || [value_lc isEqualToString:@\"no\"];\n            NSNumberFormatter* numberFormatter = [[NSNumberFormatter alloc] init];\n            [numberFormatter setAllowsFloats:YES];\n            BOOL isNumber = [numberFormatter numberFromString:value_lc] != nil;\n\n            // set the property according to the key name\n            if ([obj respondsToSelector:NSSelectorFromString(key)]) {\n                if (isNumber) {\n                    [obj setValue:[numberFormatter numberFromString:value_lc] forKey:key];\n                } else if (isBoolean) {\n                    [obj setValue:[NSNumber numberWithBool:[value_lc isEqualToString:@\"yes\"]] forKey:key];\n                } else {\n                    [obj setValue:value forKey:key];\n                }\n            }\n        }\n    }\n\n    return obj;\n}\n\n@end\n\n@implementation CDVInAppBrowserNavigationController : UINavigationController\n\n- (void) dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion {\n    if ( self.presentedViewController) {\n        [super dismissViewControllerAnimated:flag completion:completion];\n    }\n}\n\n- (void) viewDidLoad {\n\n    CGRect frame = [UIApplication sharedApplication].statusBarFrame;\n\n    // simplified from: http://stackoverflow.com/a/25669695/219684\n\n    UIToolbar* bgToolbar = [[UIToolbar alloc] initWithFrame:[self invertFrameIfNeeded:frame]];\n    bgToolbar.barStyle = UIBarStyleDefault;\n    [bgToolbar setAutoresizingMask:UIViewAutoresizingFlexibleWidth];\n    [self.view addSubview:bgToolbar];\n\n    [super viewDidLoad];\n}\n\n- (CGRect) invertFrameIfNeeded:(CGRect)rect {\n    // We need to invert since on iOS 7 frames are always in Portrait context\n    if (!IsAtLeastiOSVersion(@\"8.0\")) {\n        if (UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) {\n            CGFloat temp = rect.size.width;\n            rect.size.width = rect.size.height;\n            rect.size.height = temp;\n        }\n        rect.origin = CGPointZero;\n    }\n    return rect;\n}\n\n#pragma mark CDVScreenOrientationDelegate\n\n- (BOOL)shouldAutorotate\n{\n    if ((self.orientationDelegate != nil) && [self.orientationDelegate respondsToSelector:@selector(shouldAutorotate)]) {\n        return [self.orientationDelegate shouldAutorotate];\n    }\n    return YES;\n}\n\n- (NSUInteger)supportedInterfaceOrientations\n{\n    if ((self.orientationDelegate != nil) && [self.orientationDelegate respondsToSelector:@selector(supportedInterfaceOrientations)]) {\n        return [self.orientationDelegate supportedInterfaceOrientations];\n    }\n\n    return 1 << UIInterfaceOrientationPortrait;\n}\n\n- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation\n{\n    if ((self.orientationDelegate != nil) && [self.orientationDelegate respondsToSelector:@selector(shouldAutorotateToInterfaceOrientation:)]) {\n        return [self.orientationDelegate shouldAutorotateToInterfaceOrientation:interfaceOrientation];\n    }\n\n    return YES;\n}\n\n\n@end\n\n"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/src/ubuntu/InAppBrowser.qml",
    "content": "/*\n *\n * Copyright 2013 Canonical Ltd.\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\nimport QtQuick 2.0\nimport Ubuntu.Components.Popups 0.1\nimport Ubuntu.Components 0.1\nimport com.canonical.Oxide 1.0\n\nRectangle {\n    anchors.fill: parent\n    id: inappbrowser\n    property string url1\n    Rectangle {\n        border.color: \"black\"\n        width: parent.width\n        height: urlEntry.height\n        color: \"gray\"\n        TextInput {\n            id: urlEntry\n            width: parent.width - closeButton.width\n            text: url1\n            activeFocusOnPress: false\n        }\n        Image {\n            id: closeButton\n            width: height\n            x: parent.width - width\n            height: parent.height\n            source: \"close.png\"\n            MouseArea {\n                anchors.fill: parent\n                onClicked: {\n                    root.exec(\"InAppBrowser\", \"close\", [0, 0])\n                }\n            }\n        }\n    }\n\n    property string usContext: \"oxide://main-world/2\"\n\n    function executeJS(scId, code) {\n        var req = _view.rootFrame.sendMessage(usContext, \"EXECUTE\", {code: code});\n\n        req.onreply = function(response) {\n            var code = 'cordova.callback(' + scId + ', JSON.parse(\\'' + JSON.stringify(response.result) + '\\'))';\n            console.warn(code);\n            cordova.javaScriptExecNeeded(code);\n        console.warn(\"RESP:\" + JSON.stringify(response));\n        };\n    }\n\n    WebView {\n        width: parent.width\n        y: urlEntry.height\n        height: parent.height - y\n        url: url1\n        id: _view\n        onLoadingStateChanged: {\n            root.exec(\"InAppBrowser\", \"loadFinished\", [_view.loading])\n        }\n        context: WebContext {\n            id: webcontext\n\n            userScripts: [\n                UserScript {\n                    context: usContext\n                    emulateGreasemonkey: true\n                    url: \"InAppBrowser_escapeScript.js\"\n                }\n            ]\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/src/ubuntu/InAppBrowser_escapeScript.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/* jshint -W061 */\n/* global oxide */\n\noxide.addMessageHandler(\"EXECUTE\", function(msg) {\n    var code = msg.args.code;\n    try {\n        msg.reply({result: eval(code)});\n    } catch(e) {\n        msg.error(\"Code threw exception: \\\"\" + e + \"\\\"\");\n    }\n});\n"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/src/ubuntu/inappbrowser.cpp",
    "content": "/*\n *\n * Copyright 2013 Canonical Ltd.\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n#include <QQuickView>\n#include <QQuickItem>\n\n#include \"inappbrowser.h\"\n#include <cordova.h>\n\nInappbrowser::Inappbrowser(Cordova *cordova): CPlugin(cordova), _eventCb(0) {\n}\n\nconst char code[] = \"\\\nvar component;                                                          \\\nfunction createObject() {                                               \\\n    component = Qt.createComponent(%1);                                 \\\n    if (component.status == Component.Ready)                            \\\n        finishCreation();                                               \\\n    else                                                                \\\n        component.statusChanged.connect(finishCreation);                \\\n}                                                                       \\\nfunction finishCreation() {                                             \\\n    CordovaWrapper.global.inappbrowser = component.createObject(root,   \\\n        {root: root, cordova: cordova, url1: %2});                      \\\n}                                                                       \\\ncreateObject()\";\n\nconst char EXIT_EVENT[] = \"{type: 'exit'}\";\nconst char LOADSTART_EVENT[] = \"{type: 'loadstart'}\";\nconst char LOADSTOP_EVENT[] = \"{type: 'loadstop'}\";\nconst char LOADERROR_EVENT[] = \"{type: 'loaderror'}\";\n\nvoid Inappbrowser::open(int cb, int, const QString &url, const QString &, const QString &) {\n    assert(_eventCb == 0);\n\n    _eventCb = cb;\n\n    QString path = m_cordova->get_app_dir() + \"/../qml/InAppBrowser.qml\";\n    QString qml = QString(code)\n      .arg(CordovaInternal::format(path)).arg(CordovaInternal::format(url));\n    m_cordova->execQML(qml);\n}\n\nvoid Inappbrowser::show(int, int) {\n    m_cordova->execQML(\"CordovaWrapper.global.inappbrowser.visible = true\");\n}\n\nvoid Inappbrowser::close(int, int) {\n    m_cordova->execQML(\"CordovaWrapper.global.inappbrowser.destroy()\");\n    this->callbackWithoutRemove(_eventCb, EXIT_EVENT);\n    _eventCb = 0;\n}\n\nvoid Inappbrowser::injectStyleFile(int scId, int ecId, const QString& src, bool b) {\n    QString code(\"(function(d) { var c = d.createElement('link'); c.rel='stylesheet'; c.type='text/css'; c.href = %1; d.head.appendChild(c);})(document)\");\n    code = code.arg(CordovaInternal::format(src));\n\n    injectScriptCode(scId, ecId, code, b);\n}\n\nvoid Inappbrowser::injectStyleCode(int scId, int ecId, const QString& src, bool b) {\n    QString code(\"(function(d) { var c = d.createElement('style'); c.innerHTML = %1; d.body.appendChild(c); })(document)\");\n    code = code.arg(CordovaInternal::format(src));\n\n    injectScriptCode(scId, ecId, code, b);\n}\n\nvoid Inappbrowser::injectScriptFile(int scId, int ecId, const QString& src, bool b) {\n    QString code(\"(function(d) { var c = d.createElement('script'); c.src = %1; d.body.appendChild(c);})(document)\");\n    code = code.arg(CordovaInternal::format(src));\n\n    injectScriptCode(scId, ecId, code, b);\n}\n\nvoid Inappbrowser::injectScriptCode(int scId, int, const QString& code, bool) {\n    m_cordova->execQML(QString(\"CordovaWrapper.global.inappbrowser.executeJS(%2, %1)\").arg(CordovaInternal::format(code)).arg(scId));\n}\n\nvoid Inappbrowser::loadFinished(bool status) {\n    if (!status) {\n        this->callbackWithoutRemove(_eventCb, LOADSTOP_EVENT);\n    } else {\n        this->callbackWithoutRemove(_eventCb, LOADSTART_EVENT);\n    }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/src/ubuntu/inappbrowser.h",
    "content": "/*\n *\n * Copyright 2013 Canonical Ltd.\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n#ifndef INAPPBROWSER_H\n#define INAPPBROWSER_H\n\n#include <QtCore>\n#include <cplugin.h>\n\nclass Inappbrowser: public CPlugin {\n    Q_OBJECT\npublic:\n    Inappbrowser(Cordova *cordova);\n\n    virtual const QString fullName() override {\n        return Inappbrowser::fullID();\n    }\n\n    virtual const QString shortName() override {\n        return \"InAppBrowser\";\n    }\n\n    static const QString fullID() {\n        return \"InAppBrowser\";\n    }\n\npublic slots:\n    void open(int cb, int, const QString &url, const QString &windowName, const QString &windowFeatures);\n    void show(int, int);\n    void close(int, int);\n    void injectStyleFile(int cb, int, const QString&, bool);\n    void injectStyleCode(int cb, int, const QString&, bool);\n    void injectScriptFile(int cb, int, const QString&, bool);\n    void injectScriptCode(int cb, int, const QString&, bool);\n\n    void loadFinished(bool status);\n\nprivate:\n    int _eventCb;\n};\n\n#endif\n"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/src/windows/InAppBrowserProxy.js",
    "content": "﻿/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/* jslint sloppy:true */\n/* global Windows:true, setImmediate */\n\nvar cordova = require('cordova'),\n    urlutil = require('cordova/urlutil');\n\nvar browserWrap,\n    popup,\n    navigationButtonsDiv,\n    navigationButtonsDivInner,\n    backButton,\n    forwardButton,\n    closeButton,\n    bodyOverflowStyle,\n    navigationEventsCallback;\n\n// x-ms-webview is available starting from Windows 8.1 (platformId is 'windows')\n// http://msdn.microsoft.com/en-us/library/windows/apps/dn301831.aspx\nvar isWebViewAvailable = cordova.platformId === 'windows';\n\nfunction attachNavigationEvents(element, callback) {\n    if (isWebViewAvailable) {\n        element.addEventListener(\"MSWebViewNavigationStarting\", function (e) {\n            callback({ type: \"loadstart\", url: e.uri}, {keepCallback: true} );\n        });\n\n        element.addEventListener(\"MSWebViewNavigationCompleted\", function (e) {\n            if (e.isSuccess) {\n                callback({ type: \"loadstop\", url: e.uri }, { keepCallback: true });\n            } else {\n                callback({ type: \"loaderror\", url: e.uri, code: e.webErrorStatus, message: \"Navigation failed with error code \" + e.webErrorStatus}, { keepCallback: true });\n            }\n        });\n\n        element.addEventListener(\"MSWebViewUnviewableContentIdentified\", function (e) {\n            // WebView found the content to be not HTML.\n            // http://msdn.microsoft.com/en-us/library/windows/apps/dn609716.aspx\n            callback({ type: \"loaderror\", url: e.uri, code: e.webErrorStatus, message: \"Navigation failed with error code \" + e.webErrorStatus}, { keepCallback: true });\n        });\n\n        element.addEventListener(\"MSWebViewContentLoading\", function (e) {\n            if (navigationButtonsDiv && popup) {\n                if (popup.canGoBack) {\n                    backButton.removeAttribute(\"disabled\");\n                } else {\n                    backButton.setAttribute(\"disabled\", \"true\");\n                }\n\n                if (popup.canGoForward) {\n                    forwardButton.removeAttribute(\"disabled\");\n                } else {\n                    forwardButton.setAttribute(\"disabled\", \"true\");\n                }\n            }\n        });\n    } else {\n        var onError = function () {\n            callback({ type: \"loaderror\", url: this.contentWindow.location}, {keepCallback: true});\n        };\n\n        element.addEventListener(\"unload\", function () {\n            callback({ type: \"loadstart\", url: this.contentWindow.location}, {keepCallback: true});\n        });\n\n        element.addEventListener(\"load\", function () {\n            callback({ type: \"loadstop\", url: this.contentWindow.location}, {keepCallback: true});\n        });\n\n        element.addEventListener(\"error\", onError);\n        element.addEventListener(\"abort\", onError);\n    }\n}\n\nvar IAB = {\n    close: function (win, lose) {\n        setImmediate(function () {\n            if (browserWrap) {\n                if (navigationEventsCallback) {\n                    navigationEventsCallback({ type: \"exit\" });\n                }\n\n                browserWrap.parentNode.removeChild(browserWrap);\n                // Reset body overflow style to initial value\n                document.body.style.msOverflowStyle = bodyOverflowStyle;\n                browserWrap = null;\n                popup = null;\n            }\n        });\n    },\n    show: function (win, lose) {\n        setImmediate(function () {\n            if (browserWrap) {\n                browserWrap.style.display = \"block\";\n            }\n        });\n    },\n    open: function (win, lose, args) {\n        // make function async so that we can add navigation events handlers before view is loaded and navigation occured\n        setImmediate(function () {\n            var strUrl = args[0],\n                target = args[1],\n                features = args[2],\n                url;\n\n            navigationEventsCallback = win;\n\n            if (target === \"_system\") {\n                url = new Windows.Foundation.Uri(strUrl);\n                Windows.System.Launcher.launchUriAsync(url);\n            } else if (target === \"_self\" || !target) {\n                window.location = strUrl;\n            } else {\n                // \"_blank\" or anything else\n                if (!browserWrap) {\n                    var browserWrapStyle = document.createElement('link');\n                    browserWrapStyle.rel = \"stylesheet\";\n                    browserWrapStyle.type = \"text/css\";\n                    browserWrapStyle.href = urlutil.makeAbsolute(\"/www/css/inappbrowser.css\");\n\n                    document.head.appendChild(browserWrapStyle);\n\n                    browserWrap = document.createElement(\"div\");\n                    browserWrap.className = \"inAppBrowserWrap\";\n\n                    if (features.indexOf(\"fullscreen=yes\") > -1) {\n                        browserWrap.classList.add(\"inAppBrowserWrapFullscreen\");\n                    }\n\n                    // Save body overflow style to be able to reset it back later\n                    bodyOverflowStyle = document.body.style.msOverflowStyle;\n\n                    browserWrap.onclick = function () {\n                        setTimeout(function () {\n                            IAB.close(navigationEventsCallback);\n                        }, 0);\n                    };\n\n                    document.body.appendChild(browserWrap);\n                    // Hide scrollbars for the whole body while inappbrowser's window is open\n                    document.body.style.msOverflowStyle = \"none\";\n                }\n\n                if (features.indexOf(\"hidden=yes\") !== -1) {\n                    browserWrap.style.display = \"none\";\n                }\n\n                popup = document.createElement(isWebViewAvailable ? \"x-ms-webview\" : \"iframe\");\n                if (popup instanceof HTMLIFrameElement) {\n                    // For iframe we need to override bacground color of parent element here\n                    // otherwise pages without background color set will have transparent background\n                    popup.style.backgroundColor = \"white\";\n                }\n                popup.style.borderWidth = \"0px\";\n                popup.style.width = \"100%\";\n\n                browserWrap.appendChild(popup);\n\n                if (features.indexOf(\"location=yes\") !== -1 || features.indexOf(\"location\") === -1) {\n                    popup.style.height = \"calc(100% - 70px)\";\n\n                    navigationButtonsDiv = document.createElement(\"div\");\n                    navigationButtonsDiv.className = \"inappbrowser-app-bar\";\n                    navigationButtonsDiv.onclick = function (e) {\n                        e.cancelBubble = true;\n                    };\n\n                    navigationButtonsDivInner = document.createElement(\"div\");\n                    navigationButtonsDivInner.className = \"inappbrowser-app-bar-inner\";\n                    navigationButtonsDivInner.onclick = function (e) {\n                        e.cancelBubble = true;\n                    };\n\n                    backButton = document.createElement(\"div\");\n                    backButton.innerText = \"back\";\n                    backButton.className = \"app-bar-action action-back\";\n                    backButton.addEventListener(\"click\", function (e) {\n                        if (popup.canGoBack)\n                            popup.goBack();\n                    });\n\n                    forwardButton = document.createElement(\"div\");\n                    forwardButton.innerText = \"forward\";\n                    forwardButton.className = \"app-bar-action action-forward\";\n                    forwardButton.addEventListener(\"click\", function (e) {\n                        if (popup.canGoForward)\n                            popup.goForward();\n                    });\n\n                    closeButton = document.createElement(\"div\");\n                    closeButton.innerText = \"close\";\n                    closeButton.className = \"app-bar-action action-close\";\n                    closeButton.addEventListener(\"click\", function (e) {\n                        setTimeout(function () {\n                            IAB.close(navigationEventsCallback);\n                        }, 0);\n                    });\n\n                    if (!isWebViewAvailable) {\n                        // iframe navigation is not yet supported\n                        backButton.setAttribute(\"disabled\", \"true\");\n                        forwardButton.setAttribute(\"disabled\", \"true\");\n                    }\n\n                    navigationButtonsDivInner.appendChild(backButton);\n                    navigationButtonsDivInner.appendChild(forwardButton);\n                    navigationButtonsDivInner.appendChild(closeButton);\n                    navigationButtonsDiv.appendChild(navigationButtonsDivInner);\n\n                    browserWrap.appendChild(navigationButtonsDiv);\n                } else {\n                    popup.style.height = \"100%\";\n                }\n\n                // start listening for navigation events\n                attachNavigationEvents(popup, navigationEventsCallback);\n\n                if (isWebViewAvailable) {\n                    strUrl = strUrl.replace(\"ms-appx://\", \"ms-appx-web://\");\n                }\n                popup.src = strUrl;\n            }\n        });\n    },\n\n    injectScriptCode: function (win, fail, args) {\n        setImmediate(function () {\n            var code = args[0],\n                hasCallback = args[1];\n\n            if (isWebViewAvailable && browserWrap && popup) {\n                var op = popup.invokeScriptAsync(\"eval\", code);\n                op.oncomplete = function (e) {\n                    if (hasCallback) {\n                        // return null if event target is unavailable by some reason\n                        var result = (e && e.target) ? [e.target.result] : [null];\n                        win(result);\n                    }\n                };\n                op.onerror = function () { };\n                op.start();\n            }\n        });\n    },\n\n    injectScriptFile: function (win, fail, args) {\n        setImmediate(function () {\n            var filePath = args[0],\n                hasCallback = args[1];\n\n            if (!!filePath) {\n                filePath = urlutil.makeAbsolute(filePath);\n            }\n\n            if (isWebViewAvailable && browserWrap && popup) {\n                var uri = new Windows.Foundation.Uri(filePath);\n                Windows.Storage.StorageFile.getFileFromApplicationUriAsync(uri).done(function (file) {\n                    Windows.Storage.FileIO.readTextAsync(file).done(function (code) {\n                        var op = popup.invokeScriptAsync(\"eval\", code);\n                        op.oncomplete = function(e) {\n                            if (hasCallback) {\n                                var result = [e.target.result];\n                                win(result);\n                            }\n                        };\n                        op.onerror = function () { };\n                        op.start();\n                    });\n                });\n            }\n        });\n    },\n\n    injectStyleCode: function (win, fail, args) {\n        setImmediate(function () {\n            var code = args[0],\n                hasCallback = args[1];\n\n            if (isWebViewAvailable && browserWrap && popup) {\n                injectCSS(popup, code, hasCallback && win);\n            }\n        });\n    },\n\n    injectStyleFile: function (win, fail, args) {\n        setImmediate(function () {\n            var filePath = args[0],\n                hasCallback = args[1];\n\n            filePath = filePath && urlutil.makeAbsolute(filePath);\n\n            if (isWebViewAvailable && browserWrap && popup) {\n                var uri = new Windows.Foundation.Uri(filePath);\n                Windows.Storage.StorageFile.getFileFromApplicationUriAsync(uri).then(function (file) {\n                    return Windows.Storage.FileIO.readTextAsync(file);\n                }).done(function (code) {\n                    injectCSS(popup, code, hasCallback && win);\n                }, function () {\n                    // no-op, just catch an error\n                });\n            }\n        });\n    }\n};\n\nfunction injectCSS (webView, cssCode, callback) {\n    // This will automatically escape all thing that we need (quotes, slashes, etc.)\n    var escapedCode = JSON.stringify(cssCode);\n    var evalWrapper = \"(function(d){var c=d.createElement('style');c.innerHTML=%s;d.head.appendChild(c);})(document)\"\n        .replace('%s', escapedCode);\n\n    var op = webView.invokeScriptAsync(\"eval\", evalWrapper);\n    op.oncomplete = function() {\n        if (callback) {\n            callback([]);\n        }\n    };\n    op.onerror = function () { };\n    op.start();\n}\n\nmodule.exports = IAB;\n\nrequire(\"cordova/exec/proxy\").add(\"InAppBrowser\", module.exports);\n"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/src/wp/InAppBrowser.cs",
    "content": "﻿/*\n\tLicensed under the Apache License, Version 2.0 (the \"License\");\n\tyou may not use this file except in compliance with the License.\n\tYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\n\tUnless required by applicable law or agreed to in writing, software\n\tdistributed under the License is distributed on an \"AS IS\" BASIS,\n\tWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n\tSee the License for the specific language governing permissions and\n\tlimitations under the License.\n*/\n\nusing System;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Runtime.Serialization;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Media;\nusing Microsoft.Phone.Controls;\nusing Microsoft.Phone.Shell;\n\n#if WP8\nusing System.Threading.Tasks;\nusing Windows.ApplicationModel;\nusing Windows.Storage;\nusing Windows.System;\n\n//Use alias in case Cordova File Plugin is enabled. Then the File class will be declared in both and error will occur.\nusing IOFile = System.IO.File;\n#else\nusing Microsoft.Phone.Tasks;\n#endif\n\nnamespace WPCordovaClassLib.Cordova.Commands\n{\n    [DataContract]\n    public class BrowserOptions\n    {\n        [DataMember]\n        public string url;\n\n        [DataMember]\n        public bool isGeolocationEnabled;\n    }\n\n    public class InAppBrowser : BaseCommand\n    {\n\n        private static WebBrowser browser;\n        private static ApplicationBarIconButton backButton;\n        private static ApplicationBarIconButton fwdButton;\n\n        protected ApplicationBar AppBar;\n\n        protected bool ShowLocation {get;set;}\n        protected bool StartHidden  {get;set;}\n\n        protected string NavigationCallbackId { get; set; }\n\n        public void open(string options)\n        {\n            // reset defaults on ShowLocation + StartHidden features \n            ShowLocation = true;\n            StartHidden = false;\n\n            string[] args = JSON.JsonHelper.Deserialize<string[]>(options);\n            //BrowserOptions opts = JSON.JsonHelper.Deserialize<BrowserOptions>(options);\n            string urlLoc = args[0];\n            string target = args[1];\n            string featString = args[2];\n            this.NavigationCallbackId = args[3];\n\n            if (!string.IsNullOrEmpty(featString))\n            {\n                string[] features = featString.Split(',');\n                foreach (string str in features)\n                {\n                    try\n                    {\n                        string[] split = str.Split('=');\n                        switch (split[0])\n                        {\n                            case \"location\":\n                                ShowLocation = split[1].StartsWith(\"yes\", StringComparison.OrdinalIgnoreCase);\n                                break;\n                            case \"hidden\":\n                                StartHidden = split[1].StartsWith(\"yes\", StringComparison.OrdinalIgnoreCase);\n                                break;\n                        }\n                    }\n                    catch (Exception)\n                    {\n                        // some sort of invalid param was passed, moving on ...\n                    }\n                }\n            }\n            /*\n                _self - opens in the Cordova WebView if url is in the white-list, else it opens in the InAppBrowser \n                _blank - always open in the InAppBrowser \n                _system - always open in the system web browser \n            */\n            switch (target)\n            {\n                case \"_blank\":\n                    ShowInAppBrowser(urlLoc);\n                    break;\n                case \"_self\":\n                    ShowCordovaBrowser(urlLoc);\n                    break;\n                case \"_system\":\n                    ShowSystemBrowser(urlLoc);\n                    break;\n            }\n        }\n\n        public void show(string options)\n        {\n            string[] args = JSON.JsonHelper.Deserialize<string[]>(options);\n\n\n            if (browser != null)\n            {\n                Deployment.Current.Dispatcher.BeginInvoke(() =>\n                {\n                    browser.Visibility = Visibility.Visible;\n                    AppBar.IsVisible = true;\n                });\n            }\n        }\n\n        public void injectScriptCode(string options)\n        {\n            string[] args = JSON.JsonHelper.Deserialize<string[]>(options);\n\n            bool bCallback = false;\n            if (bool.TryParse(args[1], out bCallback)) { };\n\n            string callbackId = args[2];\n\n            if (browser != null)\n            {\n                Deployment.Current.Dispatcher.BeginInvoke(() =>\n                {\n                    var res = browser.InvokeScript(\"eval\", new string[] { args[0] });\n\n                    if (bCallback)\n                    {\n                        PluginResult result = new PluginResult(PluginResult.Status.OK, res.ToString());\n                        result.KeepCallback = false;\n                        this.DispatchCommandResult(result);\n                    }\n\n                });\n            }\n        }\n\n        public void injectScriptFile(string options)\n        {\n            Debug.WriteLine(\"Error : Windows Phone cordova-plugin-inappbrowser does not currently support executeScript\");\n            string[] args = JSON.JsonHelper.Deserialize<string[]>(options);\n            // throw new NotImplementedException(\"Windows Phone does not currently support 'executeScript'\");\n        }\n\n        public void injectStyleCode(string options)\n        {\n            Debug.WriteLine(\"Error : Windows Phone cordova-plugin-inappbrowser does not currently support insertCSS\");\n            return;\n\n            //string[] args = JSON.JsonHelper.Deserialize<string[]>(options);\n            //bool bCallback = false;\n            //if (bool.TryParse(args[1], out bCallback)) { };\n\n            //string callbackId = args[2];\n\n            //if (browser != null)\n            //{\n                //Deployment.Current.Dispatcher.BeginInvoke(() =>\n                //{\n                //    if (bCallback)\n                //    {\n                //        string cssInsertString = \"try{(function(doc){var c = '<style>body{background-color:#ffff00;}</style>'; doc.head.innerHTML += c;})(document);}catch(ex){alert('oops : ' + ex.message);}\";\n                //        //cssInsertString = cssInsertString.Replace(\"_VALUE_\", args[0]);\n                //        Debug.WriteLine(\"cssInsertString = \" + cssInsertString);\n                //        var res = browser.InvokeScript(\"eval\", new string[] { cssInsertString });\n                //        if (bCallback)\n                //        {\n                //            PluginResult result = new PluginResult(PluginResult.Status.OK, res.ToString());\n                //            result.KeepCallback = false;\n                //            this.DispatchCommandResult(result);\n                //        }\n                //    }\n\n                //});\n            //}\n        }\n\n        public void injectStyleFile(string options)\n        {\n            Debug.WriteLine(\"Error : Windows Phone cordova-plugin-inappbrowser does not currently support insertCSS\");\n            return;\n\n            //string[] args = JSON.JsonHelper.Deserialize<string[]>(options);\n            //throw new NotImplementedException(\"Windows Phone does not currently support 'insertCSS'\");\n        }\n\n        private void ShowCordovaBrowser(string url)\n        {\n            Uri loc = new Uri(url, UriKind.RelativeOrAbsolute);\n            Deployment.Current.Dispatcher.BeginInvoke(() =>\n            {\n                PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;\n                if (frame != null)\n                {\n                    PhoneApplicationPage page = frame.Content as PhoneApplicationPage;\n                    if (page != null)\n                    {\n                        CordovaView cView = page.FindName(\"CordovaView\") as CordovaView;\n                        if (cView != null)\n                        {\n                            WebBrowser br = cView.Browser;\n                            br.Navigate2(loc);\n                        }\n                    }\n\n                }\n            });\n        }\n\n#if WP8\n        private async void ShowSystemBrowser(string url)\n        {\n            var pathUri = new Uri(url, UriKind.Absolute);\n            if (pathUri.Scheme == Uri.UriSchemeHttp || pathUri.Scheme == Uri.UriSchemeHttps)\n            {\n                await Launcher.LaunchUriAsync(pathUri);\n                return;\n            }\n\n            var file = await GetFile(pathUri.AbsolutePath.Replace('/', Path.DirectorySeparatorChar));\n            if (file != null)\n            {\n                await Launcher.LaunchFileAsync(file);\n            }\n            else\n            {\n                Debug.WriteLine(\"File not found.\");\n            }\n        }\n\n        private async Task<StorageFile> GetFile(string fileName)\n        {\n            //first try to get the file from the isolated storage\n            var localFolder = ApplicationData.Current.LocalFolder;\n            if (IOFile.Exists(Path.Combine(localFolder.Path, fileName)))\n            {\n                return await localFolder.GetFileAsync(fileName);\n            }\n\n            //if file is not found try to get it from the xap\n            var filePath = Path.Combine(Package.Current.InstalledLocation.Path, fileName);\n            if (IOFile.Exists(filePath))\n            {\n                return await StorageFile.GetFileFromPathAsync(filePath);\n            }\n\n            return null;\n        }\n#else\n        private void ShowSystemBrowser(string url)\n        {\n            WebBrowserTask webBrowserTask = new WebBrowserTask();\n            webBrowserTask.Uri = new Uri(url, UriKind.Absolute);\n            webBrowserTask.Show();\n        }\n#endif\n\n        private void ShowInAppBrowser(string url)\n        {\n            Uri loc = new Uri(url, UriKind.RelativeOrAbsolute);\n\n            Deployment.Current.Dispatcher.BeginInvoke(() =>\n            {\n                if (browser != null)\n                {\n                    //browser.IsGeolocationEnabled = opts.isGeolocationEnabled;\n                    browser.Navigate2(loc);\n                }\n                else\n                {\n                    PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;\n                    if (frame != null)\n                    {\n                        PhoneApplicationPage page = frame.Content as PhoneApplicationPage;\n\n                        string baseImageUrl = \"Images/\";\n\n                        if (page != null)\n                        {\n                            Grid grid = page.FindName(\"LayoutRoot\") as Grid;\n                            if (grid != null)\n                            {\n                                browser = new WebBrowser();\n                                browser.IsScriptEnabled = true;\n                                browser.LoadCompleted += new System.Windows.Navigation.LoadCompletedEventHandler(browser_LoadCompleted);\n\n                                browser.Navigating += new EventHandler<NavigatingEventArgs>(browser_Navigating);\n                                browser.NavigationFailed += new System.Windows.Navigation.NavigationFailedEventHandler(browser_NavigationFailed);\n                                browser.Navigated += new EventHandler<System.Windows.Navigation.NavigationEventArgs>(browser_Navigated);\n                                browser.Navigate2(loc);\n\n                                if (StartHidden)\n                                {\n                                    browser.Visibility = Visibility.Collapsed;\n                                }\n\n                                //browser.IsGeolocationEnabled = opts.isGeolocationEnabled;\n                                grid.Children.Add(browser);\n                            }\n\n                            ApplicationBar bar = new ApplicationBar();\n                            bar.BackgroundColor = Colors.Gray;\n                            bar.IsMenuEnabled = false;\n\n                            backButton = new ApplicationBarIconButton();\n                            backButton.Text = \"Back\";\n\n                            backButton.IconUri = new Uri(baseImageUrl + \"appbar.back.rest.png\", UriKind.Relative);\n                            backButton.Click += new EventHandler(backButton_Click);\n                            bar.Buttons.Add(backButton);\n\n\n                            fwdButton = new ApplicationBarIconButton();\n                            fwdButton.Text = \"Forward\";\n                            fwdButton.IconUri = new Uri(baseImageUrl + \"appbar.next.rest.png\", UriKind.Relative);\n                            fwdButton.Click += new EventHandler(fwdButton_Click);\n                            bar.Buttons.Add(fwdButton);\n\n                            ApplicationBarIconButton closeBtn = new ApplicationBarIconButton();\n                            closeBtn.Text = \"Close\";\n                            closeBtn.IconUri = new Uri(baseImageUrl + \"appbar.close.rest.png\", UriKind.Relative);\n                            closeBtn.Click += new EventHandler(closeBtn_Click);\n                            bar.Buttons.Add(closeBtn);\n\n                            page.ApplicationBar = bar;\n                            bar.IsVisible = !StartHidden;\n                            AppBar = bar;\n\n                            page.BackKeyPress += page_BackKeyPress;\n\n                        }\n\n                    }\n                }\n            });\n        }\n\n        void page_BackKeyPress(object sender, System.ComponentModel.CancelEventArgs e)\n        {\n#if WP8\n            if (browser.CanGoBack)\n            {\n                browser.GoBack();\n            }\n            else\n            {\n                close();\n            }\n            e.Cancel = true;\n#else\n                    browser.InvokeScript(\"execScript\", \"history.back();\");\n#endif\n        }\n\n        void browser_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)\n        {\n\n        }\n\n        void fwdButton_Click(object sender, EventArgs e)\n        {\n            if (browser != null)\n            {\n                try\n                {\n#if WP8\n                    browser.GoForward();\n#else\n                    browser.InvokeScript(\"execScript\", \"history.forward();\");\n#endif\n                }\n                catch (Exception)\n                {\n\n                }\n            }\n        }\n\n        void backButton_Click(object sender, EventArgs e)\n        {\n            if (browser != null)\n            {\n                try\n                {\n#if WP8\n                    browser.GoBack();\n#else\n                    browser.InvokeScript(\"execScript\", \"history.back();\");\n#endif\n                }\n                catch (Exception)\n                {\n\n                }\n            }\n        }\n\n        void closeBtn_Click(object sender, EventArgs e)\n        {\n            this.close();\n        }\n\n\n        public void close(string options = \"\")\n        {\n            if (browser != null)\n            {\n                Deployment.Current.Dispatcher.BeginInvoke(() =>\n                {\n                    PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;\n                    if (frame != null)\n                    {\n                        PhoneApplicationPage page = frame.Content as PhoneApplicationPage;\n                        if (page != null)\n                        {\n                            Grid grid = page.FindName(\"LayoutRoot\") as Grid;\n                            if (grid != null)\n                            {\n                                grid.Children.Remove(browser);\n                            }\n                            page.ApplicationBar = null;\n                            page.BackKeyPress -= page_BackKeyPress;\n                        }\n                    }\n                   \n                    browser = null;\n                    string message = \"{\\\"type\\\":\\\"exit\\\"}\";\n                    PluginResult result = new PluginResult(PluginResult.Status.OK, message);\n                    result.KeepCallback = false;\n                    this.DispatchCommandResult(result, NavigationCallbackId);\n                });\n            }\n        }\n\n        void browser_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)\n        {\n#if WP8\n            if (browser != null)\n            {\n                backButton.IsEnabled = browser.CanGoBack;\n                fwdButton.IsEnabled = browser.CanGoForward;\n\n            }\n#endif\n            string message = \"{\\\"type\\\":\\\"loadstop\\\", \\\"url\\\":\\\"\" + e.Uri.OriginalString + \"\\\"}\";\n            PluginResult result = new PluginResult(PluginResult.Status.OK, message);\n            result.KeepCallback = true;\n            this.DispatchCommandResult(result, NavigationCallbackId);\n        }\n\n        void browser_NavigationFailed(object sender, System.Windows.Navigation.NavigationFailedEventArgs e)\n        {\n            string message = \"{\\\"type\\\":\\\"error\\\",\\\"url\\\":\\\"\" + e.Uri.OriginalString + \"\\\"}\";\n            PluginResult result = new PluginResult(PluginResult.Status.ERROR, message);\n            result.KeepCallback = true;\n            this.DispatchCommandResult(result, NavigationCallbackId);\n        }\n\n        void browser_Navigating(object sender, NavigatingEventArgs e)\n        {\n            string message = \"{\\\"type\\\":\\\"loadstart\\\",\\\"url\\\":\\\"\" + e.Uri.OriginalString + \"\\\"}\";\n            PluginResult result = new PluginResult(PluginResult.Status.OK, message);\n            result.KeepCallback = true;\n            this.DispatchCommandResult(result, NavigationCallbackId);\n        }\n\n    }\n\n    internal static class WebBrowserExtensions\n    {\n        /// <summary>\n        /// Improved method to initiate request to the provided URI. Supports 'data:text/html' urls. \n        /// </summary>\n        /// <param name=\"browser\">The browser instance</param>\n        /// <param name=\"uri\">The requested uri</param>\n        internal static void Navigate2(this WebBrowser browser, Uri uri)\n        {\n            // IE10 does not support data uri so we use NavigateToString method instead\n            if (uri.Scheme == \"data\")\n            {\n                // we should remove the scheme identifier and unescape the uri\n                string uriString = Uri.UnescapeDataString(uri.AbsoluteUri);\n                // format is 'data:text/html, ...'\n                string html = new System.Text.RegularExpressions.Regex(\"^data:text/html,\").Replace(uriString, \"\");\n                browser.NavigateToString(html);\n            }\n            else \n            {\n                browser.Navigate(uri);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/tests/plugin.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  Licensed to the Apache Software Foundation (ASF) under one\n  or more contributor license agreements.  See the NOTICE file\n  distributed with this work for additional information\n  regarding copyright ownership.  The ASF licenses this file\n  to you under the Apache License, Version 2.0 (the\n  \"License\"); you may not use this file except in compliance\n  with the License.  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing,\n  software distributed under the License is distributed on an\n  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n  KIND, either express or implied.  See the License for the\n  specific language governing permissions and limitations\n  under the License.\n-->\n\n<plugin xmlns=\"http://apache.org/cordova/ns/plugins/1.0\"\n    id=\"cordova-plugin-inappbrowser-tests\"\n    version=\"1.4.0\">\n    <name>Cordova InAppBrowser Plugin Tests</name>\n    <license>Apache 2.0</license>\n\n    <dependency id=\"cordova-plugin-dialogs\" />\n\n    <js-module src=\"tests.js\" name=\"tests\">\n    </js-module>\n\n    <asset src=\"resources\" target=\"cdvtests/iab-resources\" />\n</plugin>\n"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/tests/resources/inject.css",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n*/\n#style-update-file {\n    display: block !important;\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/tests/resources/inject.html",
    "content": "<!DOCTYPE html>\n<!--\n\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements.  See the NOTICE file\n distributed with this work for additional information\n regarding copyright ownership.  The ASF licenses this file\n to you under the Apache License, Version 2.0 (the\n \"License\"); you may not use this file except in compliance\n with the License.  You may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an\n \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n KIND, either express or implied.  See the License for the\n specific language governing permissions and limitations\n under the License.\n\n-->\n\n\n<html>\n  <head>\n    <meta name=\"viewport\" content=\"width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0\" />\n    <meta http-equiv=\"Content-type\" content=\"text/html; charset=utf-8\"> <!-- ISO-8859-1 -->\n    <title>Cordova Mobile Spec</title>\n    <link rel=\"stylesheet\" href=\"../../master.css\" type=\"text/css\" media=\"screen\" title=\"no title\" charset=\"utf-8\">\n  </head>\n  <body id=\"stage\" class=\"theme\">\n    <h1 id=\"header\">InAppBrowser - Script / Style Injection Test</h1>\n    <h2 id=\"style-update-file\" style=\"display:none\">Style updated from file</h2>\n    <h2 id=\"style-update-literal\" style=\"display:none\">Style updated from literal</h2>\n    <div>User-Agent: <cite id=\"u-a\"></cite></div>\n  </body>\n  <script>\n      function updateUserAgent() {\n          document.getElementById(\"u-a\").textContent = navigator.userAgent;\n      }\n      updateUserAgent();\n      window.setInterval(updateUserAgent, 1500);\n  </script>\n</html>\n"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/tests/resources/inject.js",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n*/\nvar d = document.getElementById(\"header\");\nd.innerHTML = \"Script file successfully injected\";\n"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/tests/resources/local.html",
    "content": "<!DOCTYPE html>\n<!--\n\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements.  See the NOTICE file\n distributed with this work for additional information\n regarding copyright ownership.  The ASF licenses this file\n to you under the Apache License, Version 2.0 (the\n \"License\"); you may not use this file except in compliance\n with the License.  You may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an\n \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n KIND, either express or implied.  See the License for the\n specific language governing permissions and limitations\n under the License.\n\n-->\n\n\n<html>\n  <head>\n    <meta name=\"viewport\" content=\"width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0\" />\n    <meta http-equiv=\"Content-type\" content=\"text/html; charset=utf-8\"> <!-- ISO-8859-1 -->\n    <title>IAB test page</title>\n    <script type=\"text/javascript\" charset=\"utf-8\" src=\"../../cordova-incl.js\"></script>\n    <script type=\"text/javascript\" charset=\"utf-8\">\n      function onDeviceReady() {\n          document.getElementById(\"hint\").textContent = \"Running CordovaWebView, deviceVersion=\" + device.version + \", no toolbar should be present, Back link should work, logcat should NOT have failed 'gap:' calls.\";\n      }\n      document.addEventListener(\"deviceready\", onDeviceReady, false);\n    </script>\n    <style>\n        body {background-color: #ffffff;}\n    </style>\n  </head>\n  <body id=\"stage\" class=\"theme\">\n    <h1>Local URL</h1>\n    <div id=\"info\">\n        You have successfully loaded a local URL:\n        <script>document.write(location.href)</script>\n    </div>\n    <hr />\n    <div>User-Agent = <span id=\"u-a\"></span></div>\n    <hr />\n    <div id=\"hint\">Likely running inAppBrowser: Device version from Cordova=not found, Back link should not work, toolbar may be present, logcat should show failed 'gap:' calls.</div>\n    <hr />\n    <div><a href=\"http://www.google.com\">Visit Google</a> (whitelisted)</div>\n    <div><a href=\"http://www.yahoo.com\">Visit Yahoo</a> (not whitelisted)</div>\n    <div><a href=\"http://www.stluciadance.com/prospectus_file/sample.pdf\">Check out my remote PDF</a></div>\n    <div><a href=\"local.pdf\">Check out my local PDF</a></div>\n    <p /><a href=\"javascript:;\" onclick=\"history.back();\">Back</a>\n    <p />\n    <a name=\"anchor2\"></a>\n    <div style=\"height: 1000px;border:1px solid red;\">tall div with border</div>\n  </body>\n  <script>\n      function updateUserAgent() {\n          document.getElementById(\"u-a\").textContent = navigator.userAgent;\n      }\n      updateUserAgent();\n      window.setInterval(updateUserAgent, 1500);\n  </script>\n</html>\n"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/tests/resources/video.html",
    "content": "<!DOCTYPE html>\n<!--\n\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements.  See the NOTICE file\n distributed with this work for additional information\n regarding copyright ownership.  The ASF licenses this file\n to you under the Apache License, Version 2.0 (the\n \"License\"); you may not use this file except in compliance\n with the License.  You may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an\n \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n KIND, either express or implied.  See the License for the\n specific language governing permissions and limitations\n under the License.\n\n-->\n\n\n<html>\n  <head>\n    <meta name=\"viewport\" content=\"width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0\" />\n    <meta http-equiv=\"Content-type\" content=\"text/html; charset=utf-8\"> <!-- ISO-8859-1 -->\n    <title>Cordova Mobile Spec</title>\n\n  </head>\n  <body>\n    <video width=100% height=100% id=\"player\">\n      <source src=\"http://m.comptoir-info.com/app/beta/sample.mp4\">\n      <meta property=\"og:video:secure_url\" content=\"http://m.comptoir-info.com/app/beta/sample.mp4\">\n      <meta property=\"og:video:type\" content=\"video/mp4\">\n    </video>\n    <div>\n      <button onclick=\"document.getElementById('player').play()\"> play </button>\n      <button onclick=\"document.getElementById('player').pause()\"> pause </button>\n    </div>\n    <script>\n      document.getElementById('player').play();\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/tests/tests.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/* jshint jasmine: true */\n/* global MSApp */\n\nvar cordova = require('cordova');\nvar isWindows = cordova.platformId == 'windows';\n\nwindow.alert = window.alert || navigator.notification.alert;\n\nexports.defineAutoTests = function () {\n\n    describe('cordova.InAppBrowser', function () {\n\n        it(\"inappbrowser.spec.1 should exist\", function () {\n            expect(cordova.InAppBrowser).toBeDefined();\n        });\n\n        it(\"inappbrowser.spec.2 should contain open function\", function () {\n            expect(cordova.InAppBrowser.open).toBeDefined();\n            expect(cordova.InAppBrowser.open).toEqual(jasmine.any(Function));\n        });\n    });\n\n    describe('open method', function () {\n\n        var iabInstance;\n        var originalTimeout;\n        var url = 'https://dist.apache.org/repos/dist/dev/cordova/';\n        var badUrl = 'http://bad-uri/';\n\n        beforeEach(function () {\n            // increase timeout to ensure test url could be loaded within test time\n            originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;\n            jasmine.DEFAULT_TIMEOUT_INTERVAL = 30000;\n\n            iabInstance = null;\n        });\n\n        afterEach(function (done) {\n            // restore original timeout\n            jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout;\n\n            if (iabInstance !== null && iabInstance.close) {\n                iabInstance.close();\n            }\n            iabInstance = null;\n            // add some extra time so that iab dialog is closed\n            setTimeout(done, 2000);\n        });\n\n        function verifyEvent(evt, type) {\n            expect(evt).toBeDefined();\n            expect(evt.type).toEqual(type);\n            if (type !== 'exit') { // `exit` event does not have url field\n                expect(evt.url).toEqual(url);\n            }\n        }\n\n        function verifyLoadErrorEvent(evt) {\n            expect(evt).toBeDefined();\n            expect(evt.type).toEqual('loaderror');\n            expect(evt.url).toEqual(badUrl);\n            expect(evt.code).toEqual(jasmine.any(Number));\n            expect(evt.message).toEqual(jasmine.any(String));\n        }\n\n        it(\"inappbrowser.spec.3 should retun InAppBrowser instance with required methods\", function () {\n            iabInstance = cordova.InAppBrowser.open(url, '_blank');\n\n            expect(iabInstance).toBeDefined();\n\n            expect(iabInstance.addEventListener).toEqual(jasmine.any(Function));\n            expect(iabInstance.removeEventListener).toEqual(jasmine.any(Function));\n            expect(iabInstance.close).toEqual(jasmine.any(Function));\n            expect(iabInstance.show).toEqual(jasmine.any(Function));\n            expect(iabInstance.executeScript).toEqual(jasmine.any(Function));\n            expect(iabInstance.insertCSS).toEqual(jasmine.any(Function));\n        });\n\n        it(\"inappbrowser.spec.4 should support loadstart and loadstop events\", function (done) {\n            var onLoadStart = jasmine.createSpy('loadstart event callback').and.callFake(function (evt) {\n                verifyEvent(evt, 'loadstart');\n            });\n\n            iabInstance = cordova.InAppBrowser.open(url, '_blank');\n            iabInstance.addEventListener('loadstart', onLoadStart);\n            iabInstance.addEventListener('loadstop', function (evt) {\n                verifyEvent(evt, 'loadstop');\n                expect(onLoadStart).toHaveBeenCalled();\n                done();\n            });\n        });\n\n        it(\"inappbrowser.spec.5 should support exit event\", function (done) {\n            iabInstance = cordova.InAppBrowser.open(url, '_blank');\n            iabInstance.addEventListener('exit', function (evt) {\n                verifyEvent(evt, 'exit');\n                done();\n            });\n            iabInstance.close();\n            iabInstance = null;\n        });\n\n        it(\"inappbrowser.spec.6 should support loaderror event\", function (done) {\n            iabInstance = cordova.InAppBrowser.open(badUrl, '_blank');\n            iabInstance.addEventListener('loaderror', function (evt) {\n                verifyLoadErrorEvent(evt);\n                done();\n            });\n        });\n    });\n};\n\nexports.defineManualTests = function (contentEl, createActionButton) {\n\n    function doOpen(url, target, params, numExpectedRedirects, useWindowOpen) {\n        numExpectedRedirects = numExpectedRedirects || 0;\n        useWindowOpen = useWindowOpen || false;\n        console.log(\"Opening \" + url);\n\n        var counts;\n        var lastLoadStartURL;\n        var wasReset = false;\n        function reset() {\n            counts = {\n                'loaderror': 0,\n                'loadstart': 0,\n                'loadstop': 0,\n                'exit': 0\n            };\n            lastLoadStartURL = '';\n        }\n        reset();\n\n        var iab;\n        var callbacks = {\n            loaderror: logEvent,\n            loadstart: logEvent,\n            loadstop: logEvent,\n            exit: logEvent\n        };\n        if (useWindowOpen) {\n            console.log('Use window.open() for url');\n            iab = window.open(url, target, params, callbacks);\n        }\n        else {\n            iab = cordova.InAppBrowser.open(url, target, params, callbacks);\n        }\n        if (!iab) {\n            alert('open returned ' + iab);\n            return;\n        }\n\n        function logEvent(e) {\n            console.log('IAB event=' + JSON.stringify(e));\n            counts[e.type]++;\n            // Verify that event.url gets updated on redirects.\n            if (e.type == 'loadstart') {\n                if (e.url == lastLoadStartURL) {\n                    alert('Unexpected: loadstart fired multiple times for the same URL.');\n                }\n                lastLoadStartURL = e.url;\n            }\n            // Verify the right number of loadstart events were fired.\n            if (e.type == 'loadstop' || e.type == 'loaderror') {\n                if (e.url != lastLoadStartURL) {\n                    alert('Unexpected: ' + e.type + ' event.url != loadstart\\'s event.url');\n                }\n                if (numExpectedRedirects === 0 && counts.loadstart !== 1) {\n                    // Do allow a loaderror without a loadstart (e.g. in the case of an invalid URL).\n                    if (!(e.type == 'loaderror' && counts.loadstart === 0)) {\n                        alert('Unexpected: got multiple loadstart events. (' + counts.loadstart + ')');\n                    }\n                } else if (numExpectedRedirects > 0 && counts.loadstart < (numExpectedRedirects + 1)) {\n                    alert('Unexpected: should have got at least ' + (numExpectedRedirects + 1) + ' loadstart events, but got ' + counts.loadstart);\n                }\n                wasReset = true;\n                numExpectedRedirects = 0;\n                reset();\n            }\n            // Verify that loadend / loaderror was called.\n            if (e.type == 'exit') {\n                var numStopEvents = counts.loadstop + counts.loaderror;\n                if (numStopEvents === 0 && !wasReset) {\n                    alert('Unexpected: browser closed without a loadstop or loaderror.');\n                } else if (numStopEvents > 1) {\n                    alert('Unexpected: got multiple loadstop/loaderror events.');\n                }\n            }\n        }\n\n        return iab;\n    }\n\n    function doHookOpen(url, target, params, numExpectedRedirects) {\n        var originalFunc = window.open;\n        var wasClobbered = window.hasOwnProperty('open');\n        window.open = cordova.InAppBrowser.open;\n\n        try {\n            doOpen(url, target, params, numExpectedRedirects, true);\n        }\n        finally {\n            if (wasClobbered) {\n                window.open = originalFunc;\n            }\n            else {\n              console.log('just delete, to restore open from prototype');\n                delete window.open;\n            }\n        }\n    }\n\n    function openWithStyle(url, cssUrl, useCallback) {\n        var iab = doOpen(url, '_blank', 'location=yes');\n        var callback = function (results) {\n            if (results && results.length === 0) {\n                alert('Results verified');\n            } else {\n                console.log(results);\n                alert('Got: ' + typeof (results) + '\\n' + JSON.stringify(results));\n            }\n        };\n        if (cssUrl) {\n            iab.addEventListener('loadstop', function (event) {\n                iab.insertCSS({ file: cssUrl }, useCallback && callback);\n            });\n        } else {\n            iab.addEventListener('loadstop', function (event) {\n                iab.insertCSS({ code: '#style-update-literal { \\ndisplay: block !important; \\n}' },\n                              useCallback && callback);\n            });\n        }\n    }\n\n    function openWithScript(url, jsUrl, useCallback) {\n        var iab = doOpen(url, '_blank', 'location=yes');\n        if (jsUrl) {\n            iab.addEventListener('loadstop', function (event) {\n                iab.executeScript({ file: jsUrl }, useCallback && function (results) {\n                    if (results && results.length === 0) {\n                        alert('Results verified');\n                    } else {\n                        console.log(results);\n                        alert('Got: ' + typeof (results) + '\\n' + JSON.stringify(results));\n                    }\n                });\n            });\n        } else {\n            iab.addEventListener('loadstop', function (event) {\n                var code = '(function(){\\n' +\n                  '    var header = document.getElementById(\"header\");\\n' +\n                  '    header.innerHTML = \"Script literal successfully injected\";\\n' +\n                  '    return \"abc\";\\n' +\n                  '})()';\n                iab.executeScript({ code: code }, useCallback && function (results) {\n                    if (results && results.length === 1 && results[0] === 'abc') {\n                        alert('Results verified');\n                    } else {\n                        console.log(results);\n                        alert('Got: ' + typeof (results) + '\\n' + JSON.stringify(results));\n                    }\n                });\n            });\n        }\n    }\n    var hiddenwnd = null;\n    var loadlistener = function (event) { alert('background window loaded '); };\n    function openHidden(url, startHidden) {\n        var shopt = (startHidden) ? 'hidden=yes' : '';\n        hiddenwnd = cordova.InAppBrowser.open(url, 'random_string', shopt);\n        if (!hiddenwnd) {\n            alert('cordova.InAppBrowser.open returned ' + hiddenwnd);\n            return;\n        }\n        if (startHidden) hiddenwnd.addEventListener('loadstop', loadlistener);\n    }\n    function showHidden() {\n        if (!!hiddenwnd) {\n            hiddenwnd.show();\n        }\n    }\n    function closeHidden() {\n        if (!!hiddenwnd) {\n            hiddenwnd.removeEventListener('loadstop', loadlistener);\n            hiddenwnd.close();\n            hiddenwnd = null;\n        }\n    }\n\n    var info_div = '<h1>InAppBrowser</h1>' +\n        '<div id=\"info\">' +\n        'Make sure http://cordova.apache.org and http://google.co.uk and https://www.google.co.uk are white listed. </br>' +\n        'Make sure http://www.apple.com is not in the white list.</br>' +\n        'In iOS, starred <span style=\"vertical-align:super\">*</span> tests will put the app in a state with no way to return. </br>' +\n        '<h4>User-Agent: <span id=\"user-agent\"> </span></hr>' +\n        '</div>';\n\n    var local_tests = '<h1>Local URL</h1>' +\n        '<div id=\"openLocal\"></div>' +\n        'Expected result: opens successfully in CordovaWebView.' +\n        '<p/> <div id=\"openLocalHook\"></div>' +\n        'Expected result: opens successfully in CordovaWebView (using hook of window.open()).' +\n        '<p/> <div id=\"openLocalSelf\"></div>' +\n        'Expected result: opens successfully in CordovaWebView.' +\n        '<p/> <div id=\"openLocalSystem\"></div>' +\n        'Expected result: fails to open' +\n        '<p/> <div id=\"openLocalBlank\"></div>' +\n        'Expected result: opens successfully in InAppBrowser with locationBar at top.' +\n        '<p/> <div id=\"openLocalRandomNoLocation\"></div>' +\n        'Expected result: opens successfully in InAppBrowser without locationBar.' +\n        '<p/> <div id=\"openLocalRandomToolBarBottom\"></div>' +\n        'Expected result: opens successfully in InAppBrowser with locationBar. On iOS the toolbar is at the bottom.' +\n        '<p/> <div id=\"openLocalRandomToolBarTop\"></div>' +\n        'Expected result: opens successfully in InAppBrowser with locationBar. On iOS the toolbar is at the top.' +\n        '<p/><div id=\"openLocalRandomToolBarTopNoLocation\"></div>' +\n        'Expected result: open successfully in InAppBrowser with no locationBar. On iOS the toolbar is at the top.';\n\n    var white_listed_tests = '<h1>White Listed URL</h1>' +\n        '<div id=\"openWhiteListed\"></div>' +\n        'Expected result: open successfully in CordovaWebView to cordova.apache.org' +\n        '<p/> <div id=\"openWhiteListedHook\"></div>' +\n        'Expected result: open successfully in CordovaWebView to cordova.apache.org (using hook of window.open())' +\n        '<p/> <div id=\"openWhiteListedSelf\"></div>' +\n        'Expected result: open successfully in CordovaWebView to cordova.apache.org' +\n        '<p/> <div id=\"openWhiteListedSystem\"></div>' +\n        'Expected result: open successfully in system browser to cordova.apache.org' +\n        '<p/> <div id=\"openWhiteListedBlank\"></div>' +\n        'Expected result: open successfully in InAppBrowser to cordova.apache.org' +\n        '<p/> <div id=\"openWhiteListedRandom\"></div>' +\n        'Expected result: open successfully in InAppBrowser to cordova.apache.org' +\n        '<p/> <div id=\"openWhiteListedRandomNoLocation\"></div>' +\n        'Expected result: open successfully in InAppBrowser to cordova.apache.org with no location bar.';\n\n    var non_white_listed_tests = '<h1>Non White Listed URL</h1>' +\n        '<div id=\"openNonWhiteListed\"></div>' +\n        'Expected result: open successfully in InAppBrowser to apple.com.' +\n        '<p/> <div id=\"openNonWhiteListedHook\"></div>' +\n        'Expected result: open successfully in InAppBrowser to apple.com (using hook of window.open()).' +\n        '<p/> <div id=\"openNonWhiteListedSelf\"></div>' +\n        'Expected result: open successfully in InAppBrowser to apple.com (_self enforces whitelist).' +\n        '<p/> <div id=\"openNonWhiteListedSystem\"></div>' +\n        'Expected result: open successfully in system browser to apple.com.' +\n        '<p/> <div id=\"openNonWhiteListedBlank\"></div>' +\n        'Expected result: open successfully in InAppBrowser to apple.com.' +\n        '<p/> <div id=\"openNonWhiteListedRandom\"></div>' +\n        'Expected result: open successfully in InAppBrowser to apple.com.' +\n        '<p/> <div id=\"openNonWhiteListedRandomNoLocation\"></div>' +\n        'Expected result: open successfully in InAppBrowser to apple.com without locationBar.';\n\n    var page_with_redirects_tests = '<h1>Page with redirect</h1>' +\n        '<div id=\"openRedirect301\"></div>' +\n        'Expected result: should 301 and open successfully in InAppBrowser to https://www.google.co.uk.' +\n        '<p/> <div id=\"openRedirect302\"></div>' +\n        'Expected result: should 302 and open successfully in InAppBrowser to www.zhihu.com/answer/16714076.';\n\n    var pdf_url_tests = '<h1>PDF URL</h1>' +\n        '<div id=\"openPDF\"></div>' +\n        'Expected result: InAppBrowser opens. PDF should render on iOS.' +\n        '<p/> <div id=\"openPDFBlank\"></div>' +\n        'Expected result: InAppBrowser opens. PDF should render on iOS.';\n\n    var invalid_url_tests = '<h1>Invalid URL</h1>' +\n        '<div id=\"openInvalidScheme\"></div>' +\n        'Expected result: fail to load in InAppBrowser.' +\n        '<p/> <div id=\"openInvalidHost\"></div>' +\n        'Expected result: fail to load in InAppBrowser.' +\n        '<p/> <div id=\"openInvalidMissing\"></div>' +\n        'Expected result: fail to load in InAppBrowser (404).';\n\n    var css_js_injection_tests = '<h1>CSS / JS Injection</h1>' +\n        '<div id=\"openOriginalDocument\"></div>' +\n        'Expected result: open successfully in InAppBrowser without text \"Style updated from...\"' +\n        '<p/> <div id=\"openCSSInjection\"></div>' +\n        'Expected result: open successfully in InAppBrowser with \"Style updated from file\".' +\n        '<p/> <div id=\"openCSSInjectionCallback\"></div>' +\n        'Expected result: open successfully in InAppBrowser with \"Style updated from file\", and alert dialog with text \"Results verified\".' +\n        '<p/> <div id=\"openCSSLiteralInjection\"></div>' +\n        'Expected result: open successfully in InAppBrowser with \"Style updated from literal\".' +\n        '<p/> <div id=\"openCSSLiteralInjectionCallback\"></div>' +\n        'Expected result: open successfully in InAppBrowser with \"Style updated from literal\", and alert dialog with text \"Results verified\".' +\n        '<p/> <div id=\"openScriptInjection\"></div>' +\n        'Expected result: open successfully in InAppBrowser with text \"Script file successfully injected\".' +\n        '<p/> <div id=\"openScriptInjectionCallback\"></div>' +\n        'Expected result: open successfully in InAppBrowser with text \"Script file successfully injected\" and alert dialog with the text \"Results verified\".' +\n        '<p/> <div id=\"openScriptLiteralInjection\"></div>' +\n        'Expected result: open successfully in InAppBrowser with the text \"Script literal successfully injected\" .' +\n        '<p/> <div id=\"openScriptLiteralInjectionCallback\"></div>' +\n        'Expected result: open successfully in InAppBrowser with the text \"Script literal successfully injected\" and alert dialog with the text \"Results verified\".';\n\n    var open_hidden_tests = '<h1>Open Hidden </h1>' +\n        '<div id=\"openHidden\"></div>' +\n        'Expected result: no additional browser window. Alert appears with the text \"background window loaded\".' +\n        '<p/> <div id=\"showHidden\"></div>' +\n        'Expected result: after first clicking on previous test \"create hidden\", open successfully in InAppBrowser to https://www.google.co.uk.' +\n        '<p/> <div id=\"closeHidden\"></div>' +\n        'Expected result: no output. But click on \"show hidden\" again and nothing should be shown.' +\n        '<p/> <div id=\"openHiddenShow\"></div>' +\n        'Expected result: open successfully in InAppBrowser to https://www.google.co.uk';\n\n    var clearing_cache_tests = '<h1>Clearing Cache</h1>' +\n        '<div id=\"openClearCache\"></div>' +\n        'Expected result: ?' +\n        '<p/> <div id=\"openClearSessionCache\"></div>' +\n        'Expected result: ?';\n\n    var video_tag_tests = '<h1>Video tag</h1>' +\n        '<div id=\"openRemoteVideo\"></div>' +\n        'Expected result: open successfully in InAppBrowser with an embedded video plays automatically on iOS and Android.' +\n        '<div id=\"openRemoteNeedUserNoVideo\"></div>' +\n        'Expected result: open successfully in InAppBrowser with an embedded video plays automatically on iOS and Android.' +\n        '<div id=\"openRemoteNeedUserYesVideo\"></div>' +\n        'Expected result: open successfully in InAppBrowser with an embedded video does not play automatically on iOS and Android but rather works after clicking the \"play\" button.';\n\n    var local_with_anchor_tag_tests = '<h1>Local with anchor tag</h1>' +\n        '<div id=\"openAnchor1\"></div>' +\n        'Expected result: open successfully in InAppBrowser to the local page, scrolled to the top as normal.' +\n        '<p/> <div id=\"openAnchor2\"></div>' +\n        'Expected result: open successfully in InAppBrowser to the local page, scrolled to the beginning of the tall div with border.';\n\n    // CB-7490 We need to wrap this code due to Windows security restrictions\n    // see http://msdn.microsoft.com/en-us/library/windows/apps/hh465380.aspx#differences for details\n    if (window.MSApp && window.MSApp.execUnsafeLocalFunction) {\n        MSApp.execUnsafeLocalFunction(function() {\n            contentEl.innerHTML = info_div + local_tests + white_listed_tests + non_white_listed_tests + page_with_redirects_tests + pdf_url_tests + invalid_url_tests +\n                css_js_injection_tests + open_hidden_tests + clearing_cache_tests + video_tag_tests + local_with_anchor_tag_tests;\n        });\n    } else {\n        contentEl.innerHTML = info_div + local_tests + white_listed_tests + non_white_listed_tests + page_with_redirects_tests + pdf_url_tests + invalid_url_tests +\n            css_js_injection_tests + open_hidden_tests + clearing_cache_tests + video_tag_tests + local_with_anchor_tag_tests;\n    }\n\n    document.getElementById(\"user-agent\").textContent = navigator.userAgent;\n\n    // we are already in cdvtests directory\n    var basePath = 'iab-resources/';\n    var localhtml = basePath + 'local.html',\n        localpdf = basePath + 'local.pdf',\n        injecthtml = basePath + 'inject.html',\n        injectjs = isWindows ? basePath + 'inject.js' : 'inject.js',\n        injectcss = isWindows ? basePath + 'inject.css' : 'inject.css',\n        videohtml = basePath + 'video.html';\n\n    //Local\n    createActionButton('target=Default', function () {\n        doOpen(localhtml);\n    }, 'openLocal');\n    createActionButton('target=Default (window.open)', function () {\n        doHookOpen(localhtml);\n    }, 'openLocalHook');\n    createActionButton('target=_self', function () {\n        doOpen(localhtml, '_self');\n    }, 'openLocalSelf');\n    createActionButton('target=_system', function () {\n        doOpen(localhtml, '_system');\n    }, 'openLocalSystem');\n    createActionButton('target=_blank', function () {\n        doOpen(localhtml, '_blank');\n    }, 'openLocalBlank');\n    createActionButton('target=Random, location=no, disallowoverscroll=yes', function () {\n        doOpen(localhtml, 'random_string', 'location=no, disallowoverscroll=yes');\n    }, 'openLocalRandomNoLocation');\n    createActionButton('target=Random, toolbarposition=bottom', function () {\n        doOpen(localhtml, 'random_string', 'toolbarposition=bottom');\n    }, 'openLocalRandomToolBarBottom');\n    createActionButton('target=Random, toolbarposition=top', function () {\n        doOpen(localhtml, 'random_string', 'toolbarposition=top');\n    }, 'openLocalRandomToolBarTop');\n    createActionButton('target=Random, toolbarposition=top, location=no', function () {\n        doOpen(localhtml, 'random_string', 'toolbarposition=top,location=no');\n    }, 'openLocalRandomToolBarTopNoLocation');\n\n    //White Listed\n    createActionButton('* target=Default', function () {\n        doOpen('http://cordova.apache.org');\n    }, 'openWhiteListed');\n    createActionButton('* target=Default (window.open)', function () {\n        doHookOpen('http://cordova.apache.org');\n    }, 'openWhiteListedHook');\n    createActionButton('* target=_self', function () {\n        doOpen('http://cordova.apache.org', '_self');\n    }, 'openWhiteListedSelf');\n    createActionButton('target=_system', function () {\n        doOpen('http://cordova.apache.org', '_system');\n    }, 'openWhiteListedSystem');\n    createActionButton('target=_blank', function () {\n        doOpen('http://cordova.apache.org', '_blank');\n    }, 'openWhiteListedBlank');\n    createActionButton('target=Random', function () {\n        doOpen('http://cordova.apache.org', 'random_string');\n    }, 'openWhiteListedRandom');\n    createActionButton('* target=Random, no location bar', function () {\n        doOpen('http://cordova.apache.org', 'random_string', 'location=no');\n    }, 'openWhiteListedRandomNoLocation');\n\n    //Non White Listed\n    createActionButton('target=Default', function () {\n        doOpen('http://www.apple.com');\n    }, 'openNonWhiteListed');\n    createActionButton('target=Default (window.open)', function () {\n        doHookOpen('http://www.apple.com');\n    }, 'openNonWhiteListedHook');\n    createActionButton('target=_self', function () {\n        doOpen('http://www.apple.com', '_self');\n    }, 'openNonWhiteListedSelf');\n    createActionButton('target=_system', function () {\n        doOpen('http://www.apple.com', '_system');\n    }, 'openNonWhiteListedSystem');\n    createActionButton('target=_blank', function () {\n        doOpen('http://www.apple.com', '_blank');\n    }, 'openNonWhiteListedBlank');\n    createActionButton('target=Random', function () {\n        doOpen('http://www.apple.com', 'random_string');\n    }, 'openNonWhiteListedRandom');\n    createActionButton('* target=Random, no location bar', function () {\n        doOpen('http://www.apple.com', 'random_string', 'location=no');\n    }, 'openNonWhiteListedRandomNoLocation');\n\n    //Page with redirect\n    createActionButton('http://google.co.uk', function () {\n        doOpen('http://google.co.uk', 'random_string', '', 1);\n    }, 'openRedirect301');\n    createActionButton('http://goo.gl/pUFqg', function () {\n        doOpen('http://goo.gl/pUFqg', 'random_string', '', 2);\n    }, 'openRedirect302');\n\n    //PDF URL\n    createActionButton('Remote URL', function () {\n        doOpen('http://www.stluciadance.com/prospectus_file/sample.pdf');\n    }, 'openPDF');\n    createActionButton('Local URL', function () {\n        doOpen(localpdf, '_blank');\n    }, 'openPDFBlank');\n\n    //Invalid URL\n    createActionButton('Invalid Scheme', function () {\n        doOpen('x-ttp://www.invalid.com/', '_blank');\n    }, 'openInvalidScheme');\n    createActionButton('Invalid Host', function () {\n        doOpen('http://www.inv;alid.com/', '_blank');\n    }, 'openInvalidHost');\n    createActionButton('Missing Local File', function () {\n        doOpen('nonexistent.html', '_blank');\n    }, 'openInvalidMissing');\n\n    //CSS / JS injection\n    createActionButton('Original Document', function () {\n        doOpen(injecthtml, '_blank');\n    }, 'openOriginalDocument');\n    createActionButton('CSS File Injection', function () {\n        openWithStyle(injecthtml, injectcss);\n    }, 'openCSSInjection');\n    createActionButton('CSS File Injection (callback)', function () {\n        openWithStyle(injecthtml, injectcss, true);\n    }, 'openCSSInjectionCallback');\n    createActionButton('CSS Literal Injection', function () {\n        openWithStyle(injecthtml);\n    }, 'openCSSLiteralInjection');\n    createActionButton('CSS Literal Injection (callback)', function () {\n        openWithStyle(injecthtml, null, true);\n    }, 'openCSSLiteralInjectionCallback');\n    createActionButton('Script File Injection', function () {\n        openWithScript(injecthtml, injectjs);\n    }, 'openScriptInjection');\n    createActionButton('Script File Injection (callback)', function () {\n        openWithScript(injecthtml, injectjs, true);\n    }, 'openScriptInjectionCallback');\n    createActionButton('Script Literal Injection', function () {\n        openWithScript(injecthtml);\n    }, 'openScriptLiteralInjection');\n    createActionButton('Script Literal Injection (callback)', function () {\n        openWithScript(injecthtml, null, true);\n    }, 'openScriptLiteralInjectionCallback');\n\n    //Open hidden\n    createActionButton('Create Hidden', function () {\n        openHidden('https://www.google.co.uk', true);\n    }, 'openHidden');\n    createActionButton('Show Hidden', function () {\n        showHidden();\n    }, 'showHidden');\n    createActionButton('Close Hidden', function () {\n        closeHidden();\n    }, 'closeHidden');\n    createActionButton('google.co.uk Not Hidden', function () {\n        openHidden('https://www.google.co.uk', false);\n    }, 'openHiddenShow');\n\n    //Clearing cache\n    createActionButton('Clear Browser Cache', function () {\n        doOpen('https://www.google.co.uk', '_blank', 'clearcache=yes');\n    }, 'openClearCache');\n    createActionButton('Clear Session Cache', function () {\n        doOpen('https://www.google.co.uk', '_blank', 'clearsessioncache=yes');\n    }, 'openClearSessionCache');\n\n    //Video tag\n    createActionButton('Remote Video', function () {\n        doOpen(videohtml, '_blank');\n    }, 'openRemoteVideo');\n    createActionButton('Remote Need User No Video', function () {\n        doOpen(videohtml, '_blank', 'mediaPlaybackRequiresUserAction=no');\n    }, 'openRemoteNeedUserNoVideo');\n    createActionButton('Remote Need User Yes Video', function () {\n        doOpen(videohtml, '_blank', 'mediaPlaybackRequiresUserAction=yes');\n    }, 'openRemoteNeedUserYesVideo');\n\n    //Local With Anchor Tag\n    createActionButton('Anchor1', function () {\n        doOpen(localhtml + '#bogusanchor', '_blank');\n    }, 'openAnchor1');\n    createActionButton('Anchor2', function () {\n        doOpen(localhtml + '#anchor2', '_blank');\n    }, 'openAnchor2');\n};\n"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/www/inappbrowser.css",
    "content": "﻿/*\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\n.inAppBrowserWrap {\n    margin: 0;\n    padding: 0;\n    outline: 0;\n    font-size: 100%;\n    vertical-align: baseline;\n    background: 0 0;\n    position: fixed;\n    top: 0;\n    left: 0;\n    width: 100%;\n    height: 100%;\n    z-index: 9999999;\n    box-sizing: border-box;\n    border: 40px solid #bfbfbf;\n    border: 40px solid rgba(0, 0, 0, 0.25);\n}\n\n.inAppBrowserWrapFullscreen {\n    border: 0;\n}\n\n.inappbrowser-app-bar {\n    height: 70px;\n    background-color: #404040;\n    z-index: 9999999;\n}\n\n.inappbrowser-app-bar-inner {\n    padding-top: 10px;\n    height: 60px;\n    width: 155px;\n    margin: 0 auto;\n    background-color: #404040;\n    z-index: 9999999;\n}\n\n.app-bar-action {\n    width: auto;\n    height: 40px;\n    margin-left: 20px;\n    font-family: \"Segoe UI Symbol\";\n    float: left;\n    color: white;\n    font-size: 12px;\n    text-transform: lowercase;\n    text-align: center;\n    cursor: default;\n}\n\n.app-bar-action[disabled] {\n    color: gray;\n    /*disable click*/\n    pointer-events: none;\n}\n\n.app-bar-action::before {\n    font-size: 28px;\n    display: block;\n    height: 36px;\n}\n\n/* Back */\n.action-back { \n    margin-left: 0px;\n}\n\n.action-back::before {\n    content: \"\\E0BA\";\n}\n\n.action-back:not([disabled]):hover::before {\n    content: \"\\E0B3\";\n}\n\n/* Forward */\n.action-forward::before {\n    content: \"\\E0AC\";\n}\n\n.action-forward:not([disabled]):hover::before {\n    content: \"\\E0AF\";\n}\n\n/* Close */\n.action-close::before {\n    content: \"\\E0C7\";\n    /* close icon is larger so we re-size it to fit other icons */\n    font-size: 20px;\n    line-height: 40px;\n}\n\n.action-close:not([disabled]):hover::before {\n    content: \"\\E0CA\";\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/www/inappbrowser.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n(function() {\n    // special patch to correctly work on Ripple emulator (CB-9760)\n    if (window.parent && !!window.parent.ripple) { // https://gist.github.com/triceam/4658021\n        module.exports = window.open.bind(window); // fallback to default window.open behaviour\n        return;\n    }\n\n    var exec = require('cordova/exec');\n    var channel = require('cordova/channel');\n    var modulemapper = require('cordova/modulemapper');\n    var urlutil = require('cordova/urlutil');\n\n    function InAppBrowser() {\n       this.channels = {\n            'loadstart': channel.create('loadstart'),\n            'loadstop' : channel.create('loadstop'),\n            'loaderror' : channel.create('loaderror'),\n            'exit' : channel.create('exit')\n       };\n    }\n\n    InAppBrowser.prototype = {\n        _eventHandler: function (event) {\n            if (event && (event.type in this.channels)) {\n                this.channels[event.type].fire(event);\n            }\n        },\n        close: function (eventname) {\n            exec(null, null, \"InAppBrowser\", \"close\", []);\n        },\n        show: function (eventname) {\n          exec(null, null, \"InAppBrowser\", \"show\", []);\n        },\n        addEventListener: function (eventname,f) {\n            if (eventname in this.channels) {\n                this.channels[eventname].subscribe(f);\n            }\n        },\n        removeEventListener: function(eventname, f) {\n            if (eventname in this.channels) {\n                this.channels[eventname].unsubscribe(f);\n            }\n        },\n\n        executeScript: function(injectDetails, cb) {\n            if (injectDetails.code) {\n                exec(cb, null, \"InAppBrowser\", \"injectScriptCode\", [injectDetails.code, !!cb]);\n            } else if (injectDetails.file) {\n                exec(cb, null, \"InAppBrowser\", \"injectScriptFile\", [injectDetails.file, !!cb]);\n            } else {\n                throw new Error('executeScript requires exactly one of code or file to be specified');\n            }\n        },\n\n        insertCSS: function(injectDetails, cb) {\n            if (injectDetails.code) {\n                exec(cb, null, \"InAppBrowser\", \"injectStyleCode\", [injectDetails.code, !!cb]);\n            } else if (injectDetails.file) {\n                exec(cb, null, \"InAppBrowser\", \"injectStyleFile\", [injectDetails.file, !!cb]);\n            } else {\n                throw new Error('insertCSS requires exactly one of code or file to be specified');\n            }\n        }\n    };\n\n    module.exports = function(strUrl, strWindowName, strWindowFeatures, callbacks) {\n        // Don't catch calls that write to existing frames (e.g. named iframes).\n        if (window.frames && window.frames[strWindowName]) {\n            var origOpenFunc = modulemapper.getOriginalSymbol(window, 'open');\n            return origOpenFunc.apply(window, arguments);\n        }\n\n        strUrl = urlutil.makeAbsolute(strUrl);\n        var iab = new InAppBrowser();\n\n        callbacks = callbacks || {};\n        for (var callbackName in callbacks) {\n            iab.addEventListener(callbackName, callbacks[callbackName]);\n        }\n\n        var cb = function(eventname) {\n           iab._eventHandler(eventname);\n        };\n\n        strWindowFeatures = strWindowFeatures || \"\";\n\n        exec(cb, cb, \"InAppBrowser\", \"open\", [strUrl, strWindowName, strWindowFeatures]);\n        return iab;\n    };\n})();\n"
  },
  {
    "path": "plugins/cordova-plugin-inappbrowser/www/windows8/InAppBrowserProxy.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n */\n\n/*jslint sloppy:true */\n/*global Windows:true, require, document, setTimeout, window, module */\n\nvar browserWrap;\n\nvar IAB = {\n\n    close: function (win, lose) {\n        if (browserWrap) {\n            browserWrap.parentNode.removeChild(browserWrap);\n            browserWrap = null;\n        }\n    },\n    show: function (win, lose) {\n        /* empty block, ran out of bacon?\n         if (browserWrap) {\n\n         }*/\n    },\n    open: function (win, lose, args) {\n        var strUrl = args[0],\n            target = args[1],\n            url,\n            elem;\n\n        if (target === \"_system\") {\n            url = new Windows.Foundation.Uri(strUrl);\n            Windows.System.Launcher.launchUriAsync(url);\n        } else if (target === \"_blank\") {\n            if (!browserWrap) {\n                browserWrap = document.createElement(\"div\");\n                browserWrap.style.position = \"absolute\";\n                browserWrap.style.width = (window.innerWidth - 80) + \"px\";\n                browserWrap.style.height = (window.innerHeight - 80) + \"px\";\n                browserWrap.style.borderWidth = \"40px\";\n                browserWrap.style.borderStyle = \"solid\";\n                browserWrap.style.borderColor = \"rgba(0,0,0,0.25)\";\n                browserWrap.style.zIndex = \"9999999\";\n\n                browserWrap.onclick = function () {\n                    setTimeout(function () {\n                        IAB.close();\n                    }, 0);\n                };\n\n                document.body.appendChild(browserWrap);\n            }\n            var localFile = (strUrl.indexOf('ms-appdata:///') > -1);\n            if (localFile) {\n                elem = document.createElement(\"x-ms-webview\");\n                elem.style.width = (window.innerWidth - 80) + \"px\";\n                elem.style.height = (window.innerHeight - 80) + \"px\";\n                elem.style.borderWidth = \"0px\";\n                elem.name = \"targetFrame\";\n                elem.src = strUrl;\n\n                window.addEventListener(\"resize\", function () {\n                    if (browserWrap && elem) {\n                        elem.style.width = (window.innerWidth - 80) + \"px\";\n                        elem.style.height = (window.innerHeight - 80) + \"px\";\n                    }\n                });\n\n            } else {\n                elem = document.createElement(\"iframe\");\n                elem.style.width = (window.innerWidth - 80) + \"px\";\n                elem.style.height = (window.innerHeight - 80) + \"px\";\n                elem.style.borderWidth = \"0px\";\n                elem.name = \"targetFrame\";\n                elem.src = strUrl;\n\n\n                window.addEventListener(\"resize\", function () {\n                    if (browserWrap && elem) {\n                        elem.style.width = (window.innerWidth - 80) + \"px\";\n                        elem.style.height = (window.innerHeight - 80) + \"px\";\n                    }\n                });\n            }\n\n            browserWrap.appendChild(elem);\n        } else {\n            window.location = strUrl;\n        }\n\n        //var object = new WinJS.UI.HtmlControl(elem, { uri: strUrl });\n\n    },\n\n    injectScriptCode: function (code, bCB) {\n\n        // \"(function(d) { var c = d.createElement('script'); c.src = %@; d.body.appendChild(c); })(document)\"\n    },\n\n    injectScriptFile: function (file, bCB) {\n\n    }\n};\n\nmodule.exports = IAB;\n\n\nrequire(\"cordova/exec/proxy\").add(\"InAppBrowser\", module.exports);\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/CONTRIBUTING.md",
    "content": "<!--\n#\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#  KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n#\n-->\n\n# Contributing to Apache Cordova\n\nAnyone can contribute to Cordova. And we need your contributions.\n\nThere are multiple ways to contribute: report bugs, improve the docs, and\ncontribute code.\n\nFor instructions on this, start with the \n[contribution overview](http://cordova.apache.org/#contribute).\n\nThe details are explained there, but the important items are:\n - Sign and submit an Apache ICLA (Contributor License Agreement).\n - Have a Jira issue open that corresponds to your contribution.\n - Run the tests so your patch doesn't break existing functionality.\n\nWe look forward to your contributions!\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License."
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/NOTICE",
    "content": "Apache Cordova\nCopyright 2012 The Apache Software Foundation\n\nThis product includes software developed at\nThe Apache Software Foundation (http://www.apache.org/).\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-splashscreen\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-splashscreen.svg)](https://travis-ci.org/apache/cordova-plugin-splashscreen)\n\nThis plugin displays and hides a splash screen during application launch.\n\n## Installation \n\n    // npm hosted (new) id\n    cordova plugin add cordova-plugin-splashscreen\n    // you may also install directly from this repo\n    cordova plugin add https://github.com/apache/cordova-plugin-splashscreen.git\n\n## Supported Platforms\n\n- Amazon Fire OS\n- Android\n- BlackBerry 10\n- iOS\n- Windows Phone 7 and 8\n- Windows 8\n- Windows\n- Browser\n\n\n## Methods\n\n- splashscreen.show\n- splashscreen.hide\n\n### Android Quirks\n\nIn your `config.xml`, you need to add the following preferences:\n\n    <preference name=\"SplashScreen\" value=\"foo\" />\n    <preference name=\"SplashScreenDelay\" value=\"10000\" />\n    <preference name=\"SplashMaintainAspectRatio\" value=\"true|false\" />\n\nWhere foo is the name of the splashscreen file, preferably a 9 patch file. Make sure to add your splashcreen files to your res/xml directory under the appropriate folders. The second parameter represents how long the splashscreen will appear in milliseconds. It defaults to 3000 ms. See [Icons and Splash Screens](http://cordova.apache.org/docs/en/edge/config_ref_images.md.html)\nfor more information.\n\n\"SplashMaintainAspectRatio\" preference is optional. If set to true, splash screen drawable is not stretched to fit screen, but instead simply \"covers\" the screen, like CSS \"background-size:cover\". This is very useful when splash screen images cannot be distorted in any way, for example when they contain scenery or text. This setting works best with images that have large margins (safe areas) that can be safely cropped on screens with different aspect ratios.\n\nThe plugin reloads splash drawable whenever orientation changes, so you can specify different drawables for portrait and landscape orientations.\n\n### Browser Quirks\n\nYou can use the following preferences in your `config.xml`:\n\n    <platform name=\"browser\">\n        <preference name=\"SplashScreen\" value=\"images/browser/splashscreen.jpg\" /> <!-- defaults to \"img/logo.png\" -->\n        <preference name=\"SplashScreenDelay\" value=\"10000\" /> <!-- defaults to \"3000\" -->\n        <preference name=\"SplashScreenBackgroundColor\" value=\"green\" /> <!-- defaults to \"#464646\" -->\n        <preference name=\"ShowSplashScreen\" value=\"false\" /> <!-- defaults to \"true\" -->\n        <preference name=\"SplashScreenWidth\" value=\"600\" /> <!-- defaults to \"170\" -->\n        <preference name=\"SplashScreenHeight\" value=\"300\" /> <!-- defaults to \"200\" -->\n    </platform>\n\n\n### iOS Quirks\n\n- `FadeSplashScreen` (boolean, defaults to `true`): Set to `false` to\n  prevent the splash screen from fading in and out when its display\n  state changes.\n\n        <preference name=\"FadeSplashScreen\" value=\"false\"/>\n\n- `FadeSplashScreenDuration` (float, defaults to `2`): Specifies the\n  number of seconds for the splash screen fade effect to execute.\n\n        <preference name=\"FadeSplashScreenDuration\" value=\"4\"/>\n\n- `ShowSplashScreenSpinner` (boolean, defaults to `true`): Set to `false`\n  to hide the splash-screen spinner.\n\n        <preference name=\"ShowSplashScreenSpinner\" value=\"false\"/>\n\n## splashscreen.hide\n\nDismiss the splash screen.\n\n    navigator.splashscreen.hide();\n\n\n### BlackBerry 10, WP8, iOS Quirk\n\nThe `config.xml` file's `AutoHideSplashScreen` setting must be\n`false`. To delay hiding the splash screen for two seconds, add a\ntimer such as the following in the `deviceready` event handler:\n\n        setTimeout(function() {\n            navigator.splashscreen.hide();\n        }, 2000);\n\n## splashscreen.show\n\nDisplays the splash screen.\n\n    navigator.splashscreen.show();\n\n\nYour application cannot call `navigator.splashscreen.show()` until the app has\nstarted and the `deviceready` event has fired. But since typically the splash\nscreen is meant to be visible before your app has started, that would seem to\ndefeat the purpose of the splash screen.  Providing some configuration in\n`config.xml` will automatically `show` the splash screen immediately after your\napp launch and before it has fully started and received the `deviceready`\nevent. See [Icons and Splash Screens](http://cordova.apache.org/docs/en/edge/config_ref_images.md.html)\nfor more information on doing this configuration. For this reason, it is\nunlikely you need to call `navigator.splashscreen.show()` to make the splash\nscreen visible for app startup.\n\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/RELEASENOTES.md",
    "content": "<!--\n#\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n# \n# http://www.apache.org/licenses/LICENSE-2.0\n# \n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#  KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n#\n-->\n# Release Notes\n\n### 0.2.2 (Sept 25, 2013)\n* CB-4889 bumping&resetting version\n* CB-4889 renaming org.apache.cordova.core.splashscreen to org.apache.cordova.splashscreen\n* Rename CHANGELOG.md -> RELEASENOTES.md\n* [CB-4806] Update splashscreen image bounds for iOS 7\n* [CB-4752] Incremented plugin version on dev branch.\n\n### 0.2.3 (Oct 9, 2013)\n* [CB-4806] Re-fix Update splashscreen image bounds for iOS 7\n* [CB-4934] plugin-splashscreen should not show by default on Windows8\n* [CB-4929] plugin-splashscreen not loading proxy windows8\n* [CB-4915] Incremented plugin version on dev branch.\n\n### 0.2.4 (Oct 28, 2013)\n* CB-5128: add repo + issue tag to plugin.xml for splashscreen plugin\n* [CB-5010] Incremented plugin version on dev branch.\n\n### 0.2.5 (Dec 4, 2013)\n* add ubuntu platform\n* Added amazon-fireos platform. Change to use amazon-fireos as a platform if the user agent string contains 'cordova-amazon-fireos'\n* CB-5124 - Remove splashscreen config.xml values from iOS Configuration Docs, move to plugin docs\n\n### 0.2.6 (Jan 02, 2014)\n* CB-5658 Add doc/index.md for Splashscreen plugin\n* Handle error when splash image is missing.\n\n### 0.2.7 (Feb 05, 2014)\n* [CB-3562] Fix aspect ratio on landscape-only iPhone applications\n* CB-4051 fix for splashscreen rotation problem\n\n### 0.3.0 (Apr 17, 2014)\n* Add Tizen support to plugin\n* CB-6422: [windows8] use cordova/exec/proxy\n* CB-4051: [ios] - Re-fix - Splashscreen rotation problem (closes #13)\n* CB-6460: Update license headers\n* CB-6465: Add license headers to Tizen code\n* Add NOTICE file\n\n### 0.3.1 (Jun 05, 2014)\n* documentation translation: cordova-plugin-splashscreen\n* Lisa testing pulling in plugins for plugin: cordova-plugin-splashscreen\n* Lisa testing pulling in plugins for plugin: cordova-plugin-splashscreen\n* Lisa testing pulling in plugins for plugin: cordova-plugin-splashscreen\n* Lisa testing pulling in plugins for plugin: cordova-plugin-splashscreen\n* CB-6810 Add license to CONTRIBUTING.md\n* [wp8] updated quirk for  and combined iOS,WP8,BB10 quirks as they are all the same\n* [wp] implemented OnInit so splash screen can be shown before cordova page is loaded\n* [wp] plugin must be autoloaded for AutoHideSplashScreen preference to work\n* CB-6483 Use splash screen image from manifest on Windows8\n* CB-6491 add CONTRIBUTING.md\n* Revert \"Merge branch 'tizen' of http://github.com/siovene/cordova-plugin-splashscreen\"\n\n### 0.3.2 (Aug 06, 2014)\n* CB-6127 Updated translations for docs\n* CB-7041 ios: Fix image filename logic when setting the iPad splash screen\n* fixes Splashscreen crash on WP8\n* Remove outdated doc\n\n### 0.3.3 (Sep 17, 2014)\n* CB-7249 cordova-plugin-splashscreen documentation translation\n* Renamed test dir, added nested plugin.xml\n* added documentation for manual tests\n* CB-7196 port splashscreen tests to framework\n\n### 0.3.4 (Oct 03, 2014)\n* Finalized iOS splash screen (image name) tests. 176 tests in all, 44 for each type of device (iPad, iPhone, iPhone5, iPhone6, iPhone 6 Plus).\n* CB-7633 - (Re-fix based on updated unit tests) iPhone 6 Plus support\n* Updated iOS tests for locked orientations\n* Added more iOS splash screen tests.\n* CB-7633 - Add support for iPhone 6/6+\n* Added failing iPhone 6/6 Plus tests.\n* Added 'npm test'\n* CB-7663 - iOS unit tests for splash screen\n* Properly formatted splashscreen preference docs.\n\n### 0.3.5 (Dec 02, 2014)\n* CB-7204 - Race condition when hiding and showing spinner (closes #21)\n* CB-7700 cordova-plugin-splashscreen documentation translation: cordova-plugin-splashscreen\n\n### 1.0.0 (Feb 04, 2015)\n* CB-8351 ios: Stop using deprecated IsIpad macro\n* CB-3679 Add engine tag for Android >= 3.6.0 due to use of `preferences`\n* CB-3679 Make SplashScreen plugin compatible with cordova-android@4.0.x\n\n### 2.0.0 (Apr 15, 2015)\n* give users a way to install the bleeding edge.\n* CB-8746 gave plugin major version bump\n* CB-8797 - Splashscreen preferences FadeSplashScreenDuration and FadeSplashScreen (iOS) are missing\n* CB-8836 - Crashes after animating splashscreen\n* CB-8753 android: Fix missing import in previous commit\n* CB-8753 android: Adds `SplashMaintainAspectRatio` preference (close #43)\n* CB-8683 changed plugin-id to pacakge-name\n* CB-8653 properly updated translated docs to use new id\n* CB-8653 updated translated docs to use new id\n* CB-8345 Make default for splashscreen resource \"screen\" (which is what template and CLI assume it to be)\n* Revert \"CB-8345 android: Make \"splash\" the default resource ID instead of null\"\n* Use TRAVIS_BUILD_DIR, install paramedic by npm\n* CB-8345 android: Make \"splash\" the default resource ID instead of null\n* docs: added Windows to supported platforms\n* CB-7964 Add cordova-plugin-splashscreen support for browser platform\n* CB-8653 Updated Readme\n* [wp8] oops, Added back config parse result checks\n* [WP8] code cleanup, minor refactors, comments to clarify some stuff.\n* Extend WP8 Splash Screen to respect SplashScreen and SplashScreenDelay preferences from config file\n* CB-8574 Integrate TravisCI\n* CB-8438 cordova-plugin-splashscreen documentation translation: cordova-plugin-splashscreen\n* CB-8538 Added package.json file\n* CB-8397 Add support to 'windows' for showing the Windows Phone splashscreen\n\n### 2.1.0 (Jun 17, 2015)\n* added missing license headers\n* CB-9128 cordova-plugin-splashscreen documentation translation: cordova-plugin-splashscreen\n* fix npm md issue\n* Fixed iOS unit tests.\n* CB-3562: Disable screen rotation for iPhone when splash screen is shown. (closes #47)\n* CB-8988: Fix rotation on iOS/iPad (closes #46)\n* CB-8904: Don't reset the static variable when it's destroyed, otherwise we might as well just have a member variable\n* Removed wp7 from plugin.xml and package.json\n* CB-8750 [wp8]: Rewrite resoultion helper\n* CB-8750 [wp8]: Allow resolution-specific splashscreen images\n* CB-8758 [wp8]: UnauthorizedAccessException on hide()\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/doc/de/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-splashscreen\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-splashscreen.svg)](https://travis-ci.org/apache/cordova-plugin-splashscreen)\n\nDieses Plugin zeigt und verbirgt einen Splash-Screen beim Start der Anwendung.\n\n## Installation\n\n    // npm hosted (new) id\n    cordova plugin add cordova-plugin-splashscreen\n    // you may also install directly from this repo\n    cordova plugin add https://github.com/apache/cordova-plugin-splashscreen.git\n    \n\n## Unterstützte Plattformen\n\n  * Amazon Fire OS\n  * Android\n  * BlackBerry 10\n  * iOS\n  * Windows Phone 7 und 8\n  * Windows 8\n  * Windows\n  * Browser\n\n## Methoden\n\n  * SplashScreen.Show\n  * SplashScreen.Hide\n\n### Android Eigenarten\n\nSie müssen in Ihrem `\"config.xml\"`fügen Sie die folgenden Einstellungen:\n\n    <preference name=\"SplashScreen\" value=\"foo\" />\n    <preference name=\"SplashScreenDelay\" value=\"10000\" />\n    <preference name=\"SplashMaintainAspectRatio\" value=\"true|false\" />\n    \n\nWo Foo ist der Name der Datei Splashscreen, vorzugsweise eine 9-Patch-Datei. Stellen Sie sicher, Splashcreen Dateien zu Ihrem res/xml-Verzeichnis unter den entsprechenden Ordnern hinzuzufügen. Der zweite Parameter stellt dar, wie lange das Splashscreen in Millisekunden angezeigt werden. Es wird standardmäßig auf 3000 ms. Weitere Informationen finden Sie unter [Symbole und Splash-Screens](http://cordova.apache.org/docs/en/edge/config_ref_images.md.html).\n\n\"SplashMaintainAspectRatio\" Präferenz ist optional. Wenn wahr, Splash-Screen zeichenbaren nicht gestreckt wird, um den Bildschirm passen, sondern stattdessen einfach \"\" den Bildschirm, wie CSS abdeckt \"Hintergrund-Größe: Schutz vor\". Dies ist sehr nützlich, wenn Splash-Bildschirm Bilder können nicht, in keiner Weise, zum Beispiel verzerrt werden wenn sie Landschaft oder Text enthalten. Diese Einstellung funktioniert am besten mit Bildern, die große Margen (sichere Bereiche) haben, die sicher auf Bildschirme mit unterschiedlichen Seitenverhältnissen zugeschnitten werden können.\n\nDas Plugin lädt platsch zeichenbaren wenn Ausrichtung ändert, sodass Sie verschiedene Drawables für hoch- und Querformat Ausrichtungen angeben können.\n\n### Browser-Eigenheiten\n\nIn Ihrem `\"config.xml\"`können Sie die folgenden Einstellungen:\n\n    <platform name=\"browser\">\n        <preference name=\"SplashScreen\" value=\"images/browser/splashscreen.jpg\" /> <!-- defaults to \"img/logo.png\" -->\n        <preference name=\"SplashScreenDelay\" value=\"10000\" /> <!-- defaults to \"3000\" -->\n        <preference name=\"SplashScreenBackgroundColor\" value=\"green\" /> <!-- defaults to \"#464646\" -->\n        <preference name=\"ShowSplashScreen\" value=\"false\" /> <!-- defaults to \"true\" -->\n        <preference name=\"SplashScreenWidth\" value=\"600\" /> <!-- defaults to \"170\" -->\n        <preference name=\"SplashScreenHeight\" value=\"300\" /> <!-- defaults to \"200\" -->\n    </platform>\n    \n\n### iOS Macken\n\n  * `FadeSplashScreen` (Boolean, standardmäßig auf `true festgelegt`): um zu verhindern, dass den Begrüßungsbildschirm ein-und ausblenden bei ihrer Anzeige Statusänderungen auf `false` festgelegt.\n    \n        <preference name=\"FadeSplashScreen\" value=\"false\"/>\n        \n\n  * `FadeSplashScreenDuration` (float, Standardwert ist `2`): gibt die Anzahl der Sekunden für den Begrüßungsbildschirm fade Effekt ausgeführt.\n    \n        <preference name=\"FadeSplashScreenDuration\" value=\"4\"/>\n        \n\n  * `ShowSplashScreenSpinner` (Boolean, standardmäßig auf `true festgelegt`): auf `false` festgelegt wird, um den Begrüßungsbildschirm Spinner auszublenden.\n    \n        <preference name=\"ShowSplashScreenSpinner\" value=\"false\"/>\n        \n\n## SplashScreen.Hide\n\nSchließen Sie den Splash-Screen.\n\n    navigator.splashscreen.hide();\n    \n\n### BlackBerry 10, WP8, iOS Eigenarten\n\nDie Datei `config.xml` `AutoHideSplashScreen` Einstellung muss `false` sein. Verstecken des Begrüßungsbildschirms für zwei Sekunden Verzögerung, fügen Sie einen Timer wie die folgende in der `deviceready`-Ereignishandler:\n\n        setTimeout(function() {\n            navigator.splashscreen.hide();\n        }, 2000);\n    \n\n## SplashScreen.Show\n\nZeigt den Begrüßungsbildschirm.\n\n    navigator.splashscreen.show();\n    \n\nIhre Anwendung kann nicht `navigator.splashscreen.show()` aufrufen, bis die app begonnen hat und das `deviceready`-Ereignis ausgelöst hat. Aber da in der Regel der Splash-Screen soll sichtbar sein, bevor die Anwendung gestartet wurde, scheint die Niederlage der Zweck des Begrüßungsbildschirms. Somit einige Konfiguration in der Datei `config.xml` werden automatisch die Splash `show` sofort nach Ihrer app-Start und Bildschirm bevor es voll begonnen hat, und das `deviceready`-Ereignis empfangen. Weitere Informationen zu dieser Konfiguration finden Sie unter [Symbole und Splash-Screens](http://cordova.apache.org/docs/en/edge/config_ref_images.md.html). Aus diesem Grund ist es unwahrscheinlich, dass Sie `navigator.splashscreen.show()` damit den Splash-Screen sichtbar ist für app-Start aufrufen müssen."
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/doc/de/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-splashscreen\n\nDieses Plugin zeigt und verbirgt einen Splash-Screen beim Start der Anwendung.\n\n## Installation\n\n    cordova plugin add cordova-plugin-splashscreen\n    \n\n## Unterstützte Plattformen\n\n*   Amazon Fire OS\n*   Android\n*   BlackBerry 10\n*   iOS\n*   Windows Phone 7 und 8\n*   Windows 8\n\n## Methoden\n\n*   SplashScreen.Show\n*   SplashScreen.Hide\n\n### Android Eigenarten\n\nSie müssen in der config.xml folgende Einstellungen vornehmen:\n\n    <preference name=\"SplashScreen\" value=\"foo\" />\n    <preference name=\"SplashScreenDelay\" value=\"10000\" />\n    \n\nWo Foo ist der Name der Datei Splashscreen, vorzugsweise eine 9-Patch-Datei. Stellen Sie sicher, Splashcreen Dateien zu Ihrem res/xml-Verzeichnis unter den entsprechenden Ordnern hinzuzufügen. Der zweite Parameter stellt dar, wie lange das Splashscreen in Millisekunden angezeigt werden. Es wird standardmäßig auf 3000 ms. Weitere Informationen finden Sie unter [Symbole und Splash-Screens][1].\n\n [1]: http://cordova.apache.org/docs/en/edge/config_ref_images.md.html\n\n## SplashScreen.Hide\n\nSchließen Sie den Splash-Screen.\n\n    navigator.splashscreen.hide();\n    \n\n### BlackBerry 10, WP8, iOS Eigenarten\n\nDie Datei `config.xml` `AutoHideSplashScreen` Einstellung muss `false` sein. Verstecken des Begrüßungsbildschirms für zwei Sekunden Verzögerung, fügen Sie einen Timer wie die folgende in der `deviceready`-Ereignishandler:\n\n        setTimeout(function() {\n            navigator.splashscreen.hide();\n        }, 2000);\n    \n\n## SplashScreen.Show\n\nZeigt den Begrüßungsbildschirm.\n\n    navigator.splashscreen.show();\n    \n\nIhre Anwendung kann nicht `navigator.splashscreen.show()` aufrufen, bis die app begonnen hat und das `deviceready`-Ereignis ausgelöst hat. Aber da in der Regel der Splash-Screen soll sichtbar sein, bevor die Anwendung gestartet wurde, scheint die Niederlage der Zweck des Begrüßungsbildschirms. Somit einige Konfiguration in der Datei `config.xml` werden automatisch die Splash `show` sofort nach Ihrer app-Start und Bildschirm bevor es voll begonnen hat, und das `deviceready`-Ereignis empfangen. Weitere Informationen zu dieser Konfiguration finden Sie unter [Symbole und Splash-Screens][1]. Aus diesem Grund ist es unwahrscheinlich, dass Sie `navigator.splashscreen.show()` damit den Splash-Screen sichtbar ist für app-Start aufrufen müssen.\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/doc/es/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-splashscreen\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-splashscreen.svg)](https://travis-ci.org/apache/cordova-plugin-splashscreen)\n\nEste plugin muestra y esconde una pantalla de bienvenida durante el inicio de la aplicación.\n\n## Instalación\n\n    // npm hosted (new) id\n    cordova plugin add cordova-plugin-splashscreen\n    // you may also install directly from this repo\n    cordova plugin add https://github.com/apache/cordova-plugin-splashscreen.git\n    \n\n## Plataformas soportadas\n\n  * Amazon fire OS\n  * Android\n  * BlackBerry 10\n  * iOS\n  * Windows Phone 7 y 8\n  * Windows 8\n  * Windows\n  * Explorador\n\n## Métodos\n\n  * splashscreen.show\n  * splashscreen.hide\n\n### Rarezas Android\n\nEn el `archivo config.xml`, es necesario agregar las siguientes preferencias:\n\n    <preference name=\"SplashScreen\" value=\"foo\" />\n    <preference name=\"SplashScreenDelay\" value=\"10000\" />\n    <preference name=\"SplashMaintainAspectRatio\" value=\"true|false\" />\n    \n\nDonde foo es el nombre del archivo splashscreen, preferiblemente un archivo de 9 parche. Asegúrese de agregar tus archivos splashcreen en tu directorio res/xml bajo las carpetas apropiadas. El segundo parámetro representa cuánto aparecerán el splashscreen en milisegundos. Valor predeterminado es ms 3000. Ver [los iconos y salpicadura pantallas](http://cordova.apache.org/docs/en/edge/config_ref_images.md.html) para obtener más información.\n\nPreferencia \"SplashMaintainAspectRatio\" es opcional. Si establece en true, pantalla dibujable no es estirado para caber la pantalla, pero en su lugar simplemente \"cover\" la pantalla, como CSS \"background-size: cover\". Esto es muy útil cuando las imágenes de pantallas splash no distorsionadas de cualquier manera, por ejemplo cuando contienen texto o paisaje. Esta opción funciona mejor con imágenes que tienen bordes grandes (zonas seguras) que pueden ser recortadas con seguridad en pantallas con diferentes relaciones de aspecto.\n\nEl plugin recarga splash dibujable cuando cambia de orientación, por lo que puede especificar diferente dibujo para orientaciones vertical y horizontal.\n\n### Navegador rarezas\n\nPuede utilizar las siguientes preferencias en el `archivo config.xml`:\n\n    <platform name=\"browser\">\n        <preference name=\"SplashScreen\" value=\"images/browser/splashscreen.jpg\" /> <!-- defaults to \"img/logo.png\" -->\n        <preference name=\"SplashScreenDelay\" value=\"10000\" /> <!-- defaults to \"3000\" -->\n        <preference name=\"SplashScreenBackgroundColor\" value=\"green\" /> <!-- defaults to \"#464646\" -->\n        <preference name=\"ShowSplashScreen\" value=\"false\" /> <!-- defaults to \"true\" -->\n        <preference name=\"SplashScreenWidth\" value=\"600\" /> <!-- defaults to \"170\" -->\n        <preference name=\"SplashScreenHeight\" value=\"300\" /> <!-- defaults to \"200\" -->\n    </platform>\n    \n\n### iOS rarezas\n\n  * `FadeSplashScreen` (booleano, por defecto `true`): establecida en `false` para evitar que la pantalla de bienvenida de descolorarse adentro y hacia fuera cuando cambia su estado de presentación.\n    \n        <preference name=\"FadeSplashScreen\" value=\"false\"/>\n        \n\n  * `FadeSplashScreenDuration` (float, por defecto es `2`): especifica el número de segundos para que la pantalla se descolora efecto para ejecutar.\n    \n        <preference name=\"FadeSplashScreenDuration\" value=\"4\"/>\n        \n\n  * `ShowSplashScreenSpinner` (booleano, por defecto `true`): establecida en `false` para ocultar la ruleta de la pantalla de bienvenida.\n    \n        <preference name=\"ShowSplashScreenSpinner\" value=\"false\"/>\n        \n\n## splashscreen.hide\n\nDespedir a la pantalla de bienvenida.\n\n    navigator.splashscreen.hide();\n    \n\n### BlackBerry 10, WP8, iOS Quirk\n\nEl `config.xml` del archivo `AutoHideSplashScreen` la configuración debe ser `false` . Para retrasar oculta la pantalla splash durante dos segundos, agregue un temporizador como la siguiente en el `deviceready` controlador de eventos:\n\n        setTimeout(function() {\n            navigator.splashscreen.hide();\n        }, 2000);\n    \n\n## splashscreen.show\n\nMuestra la pantalla de bienvenida.\n\n    navigator.splashscreen.show();\n    \n\nLa aplicación no se puede llamar `navigator.splashscreen.show()` hasta que haya iniciado la aplicación y el `deviceready` evento ha despedido. Pero puesto que normalmente la pantalla está destinada a ser visible antes de que comience su aplicación, que parecería que el propósito de la pantalla de bienvenida. Proporcionar cierta configuración en `config.xml` automáticamente `show` la pantalla de presentación inmediatamente después de su lanzamiento de la aplicación y antes de ser completamente ha iniciado y recibió el `deviceready` evento. Ver [los iconos y salpicadura pantallas](http://cordova.apache.org/docs/en/edge/config_ref_images.md.html) para obtener más información sobre haciendo esta configuración. Por esta razón, es poco probable que necesitas llamar a `navigator.splashscreen.show()` para hacer la pantalla visible para el inicio de la aplicación."
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/doc/es/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-splashscreen\n\nEste plugin muestra y esconde una pantalla de bienvenida durante el inicio de la aplicación.\n\n## Instalación\n\n    cordova plugin add cordova-plugin-splashscreen\n    \n\n## Plataformas soportadas\n\n*   Amazon fire OS\n*   Android\n*   BlackBerry 10\n*   iOS\n*   Windows Phone 7 y 8\n*   Windows 8\n\n## Métodos\n\n*   splashscreen.show\n*   splashscreen.hide\n\n### Rarezas Android\n\nEn el archivo config.xml, tienes que añadir las siguientes preferencias:\n\n    < nombre de preferencia = \"SplashScreen\" value = \"foo\" / >< nombre de preferencia = \"SplashScreenDelay\" value = \"10000\" / >\n    \n\nDonde foo es el nombre del archivo splashscreen, preferiblemente un archivo de 9 parche. Asegúrese de agregar tus archivos splashcreen en tu directorio res/xml bajo las carpetas apropiadas. El segundo parámetro representa cuánto aparecerán el splashscreen en milisegundos. Valor predeterminado es ms 3000. Ver [los iconos y salpicadura pantallas][1] para obtener más información.\n\n [1]: http://cordova.apache.org/docs/en/edge/config_ref_images.md.html\n\n## splashscreen.hide\n\nDespedir a la pantalla de bienvenida.\n\n    Navigator.SplashScreen.Hide();\n    \n\n### BlackBerry 10, WP8, iOS Quirk\n\nEl `config.xml` del archivo `AutoHideSplashScreen` la configuración debe ser `false` . Para retrasar oculta la pantalla splash durante dos segundos, agregue un temporizador como la siguiente en el `deviceready` controlador de eventos:\n\n        setTimeout(function() {navigator.splashscreen.hide();\n        }, 2000);\n    \n\n## splashscreen.show\n\nMuestra la pantalla de bienvenida.\n\n    Navigator.SplashScreen.Show();\n    \n\nLa aplicación no se puede llamar `navigator.splashscreen.show()` hasta que haya iniciado la aplicación y el `deviceready` evento ha despedido. Pero puesto que normalmente la pantalla está destinada a ser visible antes de que comience su aplicación, que parecería que el propósito de la pantalla de bienvenida. Proporcionar cierta configuración en `config.xml` automáticamente `show` la pantalla de presentación inmediatamente después de su lanzamiento de la aplicación y antes de ser completamente ha iniciado y recibió el `deviceready` evento. Ver [los iconos y salpicadura pantallas][1] para obtener más información sobre haciendo esta configuración. Por esta razón, es poco probable que necesitas llamar a `navigator.splashscreen.show()` para hacer la pantalla visible para el inicio de la aplicación.\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/doc/fr/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-splashscreen\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-splashscreen.svg)](https://travis-ci.org/apache/cordova-plugin-splashscreen)\n\nCe plugin affiche et masque un écran de démarrage lors du lancement de l'application.\n\n## Installation\n\n    // npm hosted (new) id\n    cordova plugin add cordova-plugin-splashscreen\n    // you may also install directly from this repo\n    cordova plugin add https://github.com/apache/cordova-plugin-splashscreen.git\n    \n\n## Plates-formes supportées\n\n  * Amazon Fire OS\n  * Android\n  * BlackBerry 10\n  * iOS\n  * Windows Phone 7 et 8\n  * Windows 8\n  * Windows\n  * Navigateur\n\n## Méthodes\n\n  * splashscreen.Show\n  * splashscreen.Hide\n\n### Quirks Android\n\nDans votre `fichier config.xml`, vous devez ajouter les préférences suivantes :\n\n    <preference name=\"SplashScreen\" value=\"foo\" />\n    <preference name=\"SplashScreenDelay\" value=\"10000\" />\n    <preference name=\"SplashMaintainAspectRatio\" value=\"true|false\" />\n    \n\nOù foo est le nom du fichier splashscreen, préférablement un fichier de 9 correctif. Assurez-vous d'ajouter vos fichiers splashcreen dans votre répertoire res/xml dans les dossiers appropriés. Le deuxième paramètre représente combien de temps le splashscreen apparaîtra en millisecondes. Il est par défaut à 3000 ms. Pour plus d'informations, consultez [icônes et écrans de démarrage](http://cordova.apache.org/docs/en/edge/config_ref_images.md.html).\n\nPréférence de « SplashMaintainAspectRatio » est facultative. Si défini à true, écran de démarrage drawable n'est pas étirée pour s'adapter écran, mais plutôt simplement « couvre » l'écran, comme CSS \"fond-taille : couverture\". Ceci est très utile lorsque images écran de démarrage ne peut pas être déformées en quelque sorte, par exemple lorsqu'ils contiennent des décors ou texte. Ce paramètre fonctionne mieux avec des images qui ont des marges importantes (zones de sécurité) qui peuvent être recadrées en toute sécurité sur les écrans avec des proportions différentes.\n\nLe plugin recharge splash drawable chaque fois que l'orientation change, donc vous pouvez spécifier différents drawables pour les orientations portrait et paysage.\n\n### Bizarreries navigateur\n\nVous pouvez utiliser les préférences suivantes dans votre `fichier config.xml`:\n\n    <platform name=\"browser\">\n        <preference name=\"SplashScreen\" value=\"images/browser/splashscreen.jpg\" /> <!-- defaults to \"img/logo.png\" -->\n        <preference name=\"SplashScreenDelay\" value=\"10000\" /> <!-- defaults to \"3000\" -->\n        <preference name=\"SplashScreenBackgroundColor\" value=\"green\" /> <!-- defaults to \"#464646\" -->\n        <preference name=\"ShowSplashScreen\" value=\"false\" /> <!-- defaults to \"true\" -->\n        <preference name=\"SplashScreenWidth\" value=\"600\" /> <!-- defaults to \"170\" -->\n        <preference name=\"SplashScreenHeight\" value=\"300\" /> <!-- defaults to \"200\" -->\n    </platform>\n    \n\n### Notes au sujet d'iOS\n\n  * `FadeSplashScreen` (boolean, par défaut est `true`): la valeur `false` pour empêcher l'écran de démarrage de fading in et out lorsque son état d'affichage est modifié.\n    \n        <preference name=\"FadeSplashScreen\" value=\"false\"/>\n        \n\n  * `FadeSplashScreenDuration` (float, la valeur par défaut `2`): spécifie le nombre de secondes que l'écran de démarrage s'estomper l'effet d'exécuter.\n    \n        <preference name=\"FadeSplashScreenDuration\" value=\"4\"/>\n        \n\n  * `ShowSplashScreenSpinner` (boolean, par défaut est `true`): la valeur `false` pour masquer le cône de l'écran de démarrage.\n    \n        <preference name=\"ShowSplashScreenSpinner\" value=\"false\"/>\n        \n\n## splashscreen.Hide\n\nFaire disparaître de l'écran de démarrage.\n\n    navigator.splashscreen.hide();\n    \n\n### BlackBerry 10, WP8, iOS Quirk\n\nParamètre `AutoHideSplashScreen` du fichier `config.xml` doit avoir la valeur `false`. Pour retarder la cacher l'écran de démarrage pendant deux secondes, ajouter un minuteur semblable à la suivante dans le gestionnaire d'événements `deviceready` :\n\n        setTimeout(function() {\n            navigator.splashscreen.hide();\n        }, 2000);\n    \n\n## splashscreen.Show\n\nAffiche l'écran de démarrage.\n\n    navigator.splashscreen.show();\n    \n\nVotre application ne peut pas appeler `navigator.splashscreen.show()` jusqu'à ce que l'application a commencé et l'événement `deviceready` est déclenché. Mais puisqu'en général, l'écran de démarrage est destiné à être visible avant que votre application a commencé, qui semblerait à l'encontre des objectifs de l'écran de démarrage. Fournir une configuration dans le fichier `config.xml` automatiquement `show` le splash projettera immédiatement après votre lancement de l'app et avant qu'il a complètement démarré et a reçu l'événement `deviceready`. Voir les [icônes et les écrans de démarrage](http://cordova.apache.org/docs/en/edge/config_ref_images.md.html) pour plus d'informations sur la conduite de cette configuration. Pour cette raison, il est peu probable que vous devez appeler `navigator.splashscreen.show()` pour rendre l'écran de démarrage visible pour le démarrage de l'application."
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/doc/fr/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-splashscreen\n\nCe plugin affiche et masque un écran de démarrage lors du lancement de l'application.\n\n## Installation\n\n    cordova plugin add cordova-plugin-splashscreen\n    \n\n## Plates-formes prises en charge\n\n*   Amazon Fire OS\n*   Android\n*   BlackBerry 10\n*   iOS\n*   Windows Phone 7 et 8\n*   Windows 8\n\n## Méthodes\n\n*   splashscreen.Show\n*   splashscreen.Hide\n\n### Quirks Android\n\nDans votre fichier config.xml, vous devez ajouter les préférences suivantes :\n\n    <preference name=\"SplashScreen\" value=\"foo\" />\n    <preference name=\"SplashScreenDelay\" value=\"10000\" />\n    \n\nOù foo est le nom du fichier splashscreen, préférablement un fichier de 9 correctif. Assurez-vous d'ajouter vos fichiers splashcreen dans votre répertoire res/xml dans les dossiers appropriés. Le deuxième paramètre représente combien de temps le splashscreen apparaîtra en millisecondes. Il est par défaut à 3000 ms. Pour plus d'informations, consultez [icônes et écrans de démarrage][1].\n\n [1]: http://cordova.apache.org/docs/en/edge/config_ref_images.md.html\n\n## splashscreen.Hide\n\nFaire disparaître de l'écran de démarrage.\n\n    navigator.splashscreen.hide();\n    \n\n### BlackBerry 10, WP8, iOS Quirk\n\nParamètre `AutoHideSplashScreen` du fichier `config.xml` doit avoir la valeur `false`. Pour retarder la cacher l'écran de démarrage pendant deux secondes, ajouter un minuteur semblable à la suivante dans le gestionnaire d'événements `deviceready` :\n\n        setTimeout(function() {\n            navigator.splashscreen.hide();\n        }, 2000);\n    \n\n## splashscreen.Show\n\nAffiche l'écran de démarrage.\n\n    navigator.splashscreen.show();\n    \n\nVotre application ne peut pas appeler `navigator.splashscreen.show()` jusqu'à ce que l'application a commencé et l'événement `deviceready` est déclenché. Mais puisqu'en général, l'écran de démarrage est destiné à être visible avant que votre application a commencé, qui semblerait à l'encontre des objectifs de l'écran de démarrage. Fournir une configuration dans le fichier `config.xml` automatiquement `show` le splash projettera immédiatement après votre lancement de l'app et avant qu'il a complètement démarré et a reçu l'événement `deviceready`. Voir les [icônes et les écrans de démarrage][1] pour plus d'informations sur la conduite de cette configuration. Pour cette raison, il est peu probable que vous devez appeler `navigator.splashscreen.show()` pour rendre l'écran de démarrage visible pour le démarrage de l'application.\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/doc/it/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-splashscreen\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-splashscreen.svg)](https://travis-ci.org/apache/cordova-plugin-splashscreen)\n\nQuesto plugin Visualizza e nasconde una schermata iniziale durante l'avvio dell'applicazione.\n\n## Installazione\n\n    // npm hosted (new) id\n    cordova plugin add cordova-plugin-splashscreen\n    // you may also install directly from this repo\n    cordova plugin add https://github.com/apache/cordova-plugin-splashscreen.git\n    \n\n## Piattaforme supportate\n\n  * Amazon fuoco OS\n  * Android\n  * BlackBerry 10\n  * iOS\n  * Windows Phone 7 e 8\n  * Windows 8\n  * Windows\n  * Browser\n\n## Metodi\n\n  * splashscreen\n  * splashscreen.Hide\n\n### Stranezze Android\n\nNel vostro `config. XML`, è necessario aggiungere le seguenti preferenze:\n\n    <preference name=\"SplashScreen\" value=\"foo\" />\n    <preference name=\"SplashScreenDelay\" value=\"10000\" />\n    <preference name=\"SplashMaintainAspectRatio\" value=\"true|false\" />\n    \n\nDove foo è il nome del file splashscreen, preferibilmente un file 9 patch. Assicurati di aggiungere i tuoi file splashcreen res/xml nella directory sotto cartelle appropriate. Il secondo parametro rappresenta quanto tempo lo splashscreen apparirà in millisecondi. Il valore predefinito è 3000 ms. Per ulteriori informazioni, vedere [icone e schermate iniziali](http://cordova.apache.org/docs/en/edge/config_ref_images.md.html).\n\n\"SplashMaintainAspectRatio\" preferenza è facoltativo. Se impostato su true, schermata iniziale drawable non viene adattata per misura lo schermo, ma invece semplicemente \"copre\" lo schermo, come CSS \"sfondo-dimensione: copertina\". Questo è molto utile quando immagini schermata iniziale non possono essere distorta in qualche modo, per esempio quando contengono testo o scenario. Questa impostazione funziona meglio con immagini che hanno grandi margini (zone sicure) che possono essere ritagliati in modo sicuro su schermi con proporzioni diverse.\n\nIl plugin viene ricaricata splash drawable ogni volta che cambia orientamento, è possibile specificare diversi parte per orientamento verticale e orizzontale.\n\n### Stranezze browser\n\nNel vostro `config. XML`, è possibile utilizzare le seguenti preferenze:\n\n    <platform name=\"browser\">\n        <preference name=\"SplashScreen\" value=\"images/browser/splashscreen.jpg\" /> <!-- defaults to \"img/logo.png\" -->\n        <preference name=\"SplashScreenDelay\" value=\"10000\" /> <!-- defaults to \"3000\" -->\n        <preference name=\"SplashScreenBackgroundColor\" value=\"green\" /> <!-- defaults to \"#464646\" -->\n        <preference name=\"ShowSplashScreen\" value=\"false\" /> <!-- defaults to \"true\" -->\n        <preference name=\"SplashScreenWidth\" value=\"600\" /> <!-- defaults to \"170\" -->\n        <preference name=\"SplashScreenHeight\" value=\"300\" /> <!-- defaults to \"200\" -->\n    </platform>\n    \n\n### iOS stranezze\n\n  * `FadeSplashScreen` (boolean, impostazioni predefinite a `true`): impostare su `false` per impedire che la schermata iniziale e scompaiono quando cambia il relativo stato di visualizzazione.\n    \n        <preference name=\"FadeSplashScreen\" value=\"false\"/>\n        \n\n  * `FadeSplashScreenDuration` (float, il valore predefinito è `2`): specifica il numero di secondi per la schermata iniziale dissolvenza effetto da eseguire.\n    \n        <preference name=\"FadeSplashScreenDuration\" value=\"4\"/>\n        \n\n  * `ShowSplashScreenSpinner` (boolean, impostazioni predefinite a `true`): impostare su `false` per nascondere la filatrice schermata iniziale.\n    \n        <preference name=\"ShowSplashScreenSpinner\" value=\"false\"/>\n        \n\n## splashscreen.Hide\n\nRespingere la schermata iniziale.\n\n    navigator.splashscreen.hide();\n    \n\n### BlackBerry 10, WP8, iOS Quirk\n\nImpostazione `AutoHideSplashScreen` del file `config.xml` deve essere `false`. Per ritardare nascondendo la schermata iniziale per due secondi, aggiungere un timer ad esempio nel gestore eventi `deviceready`:\n\n        setTimeout(function() {\n            navigator.splashscreen.hide();\n        }, 2000);\n    \n\n## splashscreen\n\nVisualizza la schermata iniziale.\n\n    navigator.splashscreen.show();\n    \n\nL'applicazione non può chiamare `navigator.splashscreen.show()` fino a quando l'app ha iniziato e ha generato l'evento `deviceready`. Ma poiché in genere la schermata iniziale è destinata ad essere visibile prima app ha iniziato, che sembrerebbe per sconfiggere lo scopo della schermata iniziale. Fornendo qualche configurazione nel `file config.xml` sarà automaticamente `show` il tonfo schermo subito dopo il lancio dell'app e prima che completamente ha iniziato e ha ricevuto l'evento `deviceready`. Per ulteriori informazioni su facendo questa configurazione, vedere [icone e schermate iniziali](http://cordova.apache.org/docs/en/edge/config_ref_images.md.html). Per questo motivo, è improbabile che dovete chiamare `navigator.splashscreen.show()` per rendere la schermata visibile per avvio di app."
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/doc/it/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-splashscreen\n\nQuesto plugin Visualizza e nasconde una schermata iniziale durante l'avvio dell'applicazione.\n\n## Installazione\n\n    cordova plugin add cordova-plugin-splashscreen\n    \n\n## Piattaforme supportate\n\n*   Amazon fuoco OS\n*   Android\n*   BlackBerry 10\n*   iOS\n*   Windows Phone 7 e 8\n*   Windows 8\n\n## Metodi\n\n*   splashscreen\n*   splashscreen.Hide\n\n### Stranezze Android\n\nNel vostro config. xml, è necessario aggiungere le seguenti preferenze:\n\n    <preference name=\"SplashScreen\" value=\"foo\" />\n    <preference name=\"SplashScreenDelay\" value=\"10000\" />\n    \n\nDove foo è il nome del file splashscreen, preferibilmente un file 9 patch. Assicurati di aggiungere i tuoi file splashcreen res/xml nella directory sotto cartelle appropriate. Il secondo parametro rappresenta quanto tempo lo splashscreen apparirà in millisecondi. Il valore predefinito è 3000 ms. Per ulteriori informazioni, vedere [icone e schermate iniziali][1].\n\n [1]: http://cordova.apache.org/docs/en/edge/config_ref_images.md.html\n\n## splashscreen.Hide\n\nRespingere la schermata iniziale.\n\n    navigator.splashscreen.hide();\n    \n\n### BlackBerry 10, WP8, iOS Quirk\n\nImpostazione `AutoHideSplashScreen` del file `config.xml` deve essere `false`. Per ritardare nascondendo la schermata iniziale per due secondi, aggiungere un timer ad esempio nel gestore eventi `deviceready`:\n\n        setTimeout(function() {\n            navigator.splashscreen.hide();\n        }, 2000);\n    \n\n## splashscreen\n\nVisualizza la schermata iniziale.\n\n    navigator.splashscreen.show();\n    \n\nL'applicazione non può chiamare `navigator.splashscreen.show()` fino a quando l'app ha iniziato e ha generato l'evento `deviceready`. Ma poiché in genere la schermata iniziale è destinata ad essere visibile prima app ha iniziato, che sembrerebbe per sconfiggere lo scopo della schermata iniziale. Fornendo qualche configurazione nel `file config.xml` sarà automaticamente `show` il tonfo schermo subito dopo il lancio dell'app e prima che completamente ha iniziato e ha ricevuto l'evento `deviceready`. Per ulteriori informazioni su facendo questa configurazione, vedere [icone e schermate iniziali][1]. Per questo motivo, è improbabile che dovete chiamare `navigator.splashscreen.show()` per rendere la schermata visibile per avvio di app.\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/doc/ja/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-splashscreen\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-splashscreen.svg)](https://travis-ci.org/apache/cordova-plugin-splashscreen)\n\nこのプラグインが表示され、アプリケーションの起動中にスプラッシュ スクリーンを非表示にします。\n\n## インストール\n\n    // npm hosted (new) id\n    cordova plugin add cordova-plugin-splashscreen\n    // you may also install directly from this repo\n    cordova plugin add https://github.com/apache/cordova-plugin-splashscreen.git\n    \n\n## サポートされているプラットフォーム\n\n  * アマゾン火 OS\n  * アンドロイド\n  * ブラックベリー 10\n  * iOS\n  * Windows Phone 7 と 8\n  * Windows 8\n  * Windows\n  * ブラウザー\n\n## メソッド\n\n  * splashscreen.show\n  * splashscreen.hide\n\n### Android の癖\n\nあなたの`config.xml`内の次の設定を追加する必要があります。\n\n    <preference name=\"SplashScreen\" value=\"foo\" />\n    <preference name=\"SplashScreenDelay\" value=\"10000\" />\n    <preference name=\"SplashMaintainAspectRatio\" value=\"true|false\" />\n    \n\nFoo ができれば 9 パッチファイル splashscreen ファイルの名前です。 解像度/xml ディレクトリの適切なフォルダーの下に splashcreen ファイルを追加することを確認します。 2 番目のパラメーターは、スプラッシュ ・ スクリーンがの表示時間 (ミリ秒単位) を表します。 デフォルトでは 3000 ミリ秒です。 詳細については、[アイコンとスプラッシュ画面](http://cordova.apache.org/docs/en/edge/config_ref_images.md.html) を参照してください。\n\n\"SplashMaintainAspectRatio\"の設定はオプションです。 True の場合、スプラッシュ画面描画に設定画面を埋めるために拡大されませんが、代わりに単に「カバー」画面では、CSS のような場合「背景-サイズ: カバー」. これは、たとえば風景またはテキストが含まれている場合、任意の方法でスプラッシュ画面画像が歪むことができない非常に便利です。 この設定は、画面と異なる縦横比で安全にトリミングすることができます大規模なマージン (安全な地域) の画像に適しています。\n\n縦長と横長の異なるドロウアブルを指定できるように、プラグインは向きを変更するたびにスプラッシュ ドロウアブルをリロードします。\n\n### ブラウザーの癖\n\nあなたの`config.xml`で次の設定を使用できます。\n\n    <platform name=\"browser\">\n        <preference name=\"SplashScreen\" value=\"images/browser/splashscreen.jpg\" /> <!-- defaults to \"img/logo.png\" -->\n        <preference name=\"SplashScreenDelay\" value=\"10000\" /> <!-- defaults to \"3000\" -->\n        <preference name=\"SplashScreenBackgroundColor\" value=\"green\" /> <!-- defaults to \"#464646\" -->\n        <preference name=\"ShowSplashScreen\" value=\"false\" /> <!-- defaults to \"true\" -->\n        <preference name=\"SplashScreenWidth\" value=\"600\" /> <!-- defaults to \"170\" -->\n        <preference name=\"SplashScreenHeight\" value=\"300\" /> <!-- defaults to \"200\" -->\n    </platform>\n    \n\n### iOS の癖\n\n  * `FadeSplashScreen`(ブール値、既定で [ `true`): スプラッシュ画面がフェードインとフェードアウトの表示状態が変更されたときすることを防ぐために`false`に設定します。\n    \n        <preference name=\"FadeSplashScreen\" value=\"false\"/>\n        \n\n  * `FadeSplashScreenDuration`(float, デフォルトは`2`): スプラッシュ画面の秒数のフェードを実行する効果を指定します。\n    \n        <preference name=\"FadeSplashScreenDuration\" value=\"4\"/>\n        \n\n  * `ShowSplashScreenSpinner`(ブール値、既定で [ `true`): スプラッシュ スクリーン スピナーを非表示にするを`false`に設定します。\n    \n        <preference name=\"ShowSplashScreenSpinner\" value=\"false\"/>\n        \n\n## splashscreen.hide\n\nスプラッシュ スクリーンを閉じます。\n\n    navigator.splashscreen.hide();\n    \n\n### ブラックベリー 10、WP8、iOS の気まぐれ\n\n`config.xml` ファイルの `AutoHideSplashScreen` の設定は `false` である必要があります。 遅延を 2 秒間スプラッシュ スクリーンを非表示に `deviceready` イベント ハンドラーで、次のようタイマーを追加します。\n\n        setTimeout(function() {\n            navigator.splashscreen.hide();\n        }, 2000);\n    \n\n## splashscreen.show\n\nスプラッシュ画面が表示されます。\n\n    navigator.splashscreen.show();\n    \n\nアプリが開始され、`deviceready` イベントが発生するまで、アプリケーションは `navigator.splashscreen.show()` を呼び出すことはできません。 しかし、以来、通常スプラッシュ画面アプリ開始前に表示するものですと思われる、スプラッシュ スクリーンの目的の敗北します。 `config.xml` にいくつかの構成を提供するは自動的に `表示` スプラッシュ画面、アプリを起動後すぐに、それが完全に起動し、`deviceready` イベントを受信する前に。 詳細についてはこの構成を行うには、[アイコンとスプラッシュ画面](http://cordova.apache.org/docs/en/edge/config_ref_images.md.html) を参照してください。 この理由のためにアプリ起動時のスプラッシュ スクリーンを確認 `navigator.splashscreen.show()` をコールする必要がある可能性が高いです。"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/doc/ja/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-splashscreen\n\nこのプラグインが表示され、アプリケーションの起動中にスプラッシュ スクリーンを非表示にします。\n\n## インストール\n\n    cordova plugin add cordova-plugin-splashscreen\n    \n\n## サポートされているプラットフォーム\n\n*   アマゾン火 OS\n*   アンドロイド\n*   ブラックベリー 10\n*   iOS\n*   Windows Phone 7 と 8\n*   Windows 8\n\n## メソッド\n\n*   splashscreen.show\n*   splashscreen.hide\n\n### Android の癖\n\nあなたの config.xml を以下の設定を追加する必要があります。\n\n    <preference name=\"SplashScreen\" value=\"foo\" />\n    <preference name=\"SplashScreenDelay\" value=\"10000\" />\n    \n\nFoo ができれば 9 パッチファイル splashscreen ファイルの名前です。 解像度/xml ディレクトリの適切なフォルダーの下に splashcreen ファイルを追加することを確認します。 2 番目のパラメーターは、スプラッシュ ・ スクリーンがの表示時間 (ミリ秒単位) を表します。 デフォルトでは 3000 ミリ秒です。 詳細については、[アイコンとスプラッシュ画面][1] を参照してください。\n\n [1]: http://cordova.apache.org/docs/en/edge/config_ref_images.md.html\n\n## splashscreen.hide\n\nスプラッシュ スクリーンを閉じます。\n\n    navigator.splashscreen.hide();\n    \n\n### ブラックベリー 10、WP8、iOS の気まぐれ\n\n`config.xml` ファイルの `AutoHideSplashScreen` の設定は `false` である必要があります。 遅延を 2 秒間スプラッシュ スクリーンを非表示に `deviceready` イベント ハンドラーで、次のようタイマーを追加します。\n\n        setTimeout(function() {\n            navigator.splashscreen.hide();\n        }, 2000);\n    \n\n## splashscreen.show\n\nスプラッシュ画面が表示されます。\n\n    navigator.splashscreen.show();\n    \n\nアプリが開始され、`deviceready` イベントが発生するまで、アプリケーションは `navigator.splashscreen.show()` を呼び出すことはできません。 しかし、以来、通常スプラッシュ画面アプリ開始前に表示するものですと思われる、スプラッシュ スクリーンの目的の敗北します。 `config.xml` にいくつかの構成を提供するは自動的に `表示` スプラッシュ画面、アプリを起動後すぐに、それが完全に起動し、`deviceready` イベントを受信する前に。 詳細についてはこの構成を行うには、[アイコンとスプラッシュ画面][1] を参照してください。 この理由のためにアプリ起動時のスプラッシュ スクリーンを確認 `navigator.splashscreen.show()` をコールする必要がある可能性が高いです。\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/doc/ko/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-splashscreen\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-splashscreen.svg)](https://travis-ci.org/apache/cordova-plugin-splashscreen)\n\n이 플러그인은 표시 하 고 응용 프로그램 실행 하는 동안 시작 화면을 숨깁니다.\n\n## 설치\n\n    // npm hosted (new) id\n    cordova plugin add cordova-plugin-splashscreen\n    // you may also install directly from this repo\n    cordova plugin add https://github.com/apache/cordova-plugin-splashscreen.git\n    \n\n## 지원 되는 플랫폼\n\n  * 아마존 화재 운영 체제\n  * 안 드 로이드\n  * 블랙베리 10\n  * iOS\n  * Windows Phone 7과 8\n  * 윈도우 8\n  * 윈도우\n  * 브라우저\n\n## 메서드\n\n  * splashscreen.show\n  * splashscreen.hide\n\n### 안 드 로이드 단점\n\n`Config.xml`에 다음 환경 설정에 추가 해야 합니다.\n\n    <preference name=\"SplashScreen\" value=\"foo\" />\n    <preference name=\"SplashScreenDelay\" value=\"10000\" />\n    <preference name=\"SplashMaintainAspectRatio\" value=\"true|false\" />\n    \n\n여기서 foo splashscreen 파일, 선호 9 패치 파일의 이름입니다. 적절 한 폴더 아래 res/xml 디렉토리에 splashcreen 파일을 추가 해야 합니다. 두 번째 매개 변수는 splashscreen 얼마나 밀리초 단위로 표시 됩니다 나타냅니다. 3000 ms 기본값으로 사용 됩니다. 자세한 내용은 [아이콘 및 시작 화면을](http://cordova.apache.org/docs/en/edge/config_ref_images.md.html) 참조 하십시오.\n\n\"SplashMaintainAspectRatio\" 취향은 선택 사항입니다. Drawable, 시작 화면 설정 화면에 맞게 확장 되지 하지만 대신 단순히 \"커버\" CSS 같은 화면 \"배경-크기: 덮개\". 시작 화면 이미지 예: 풍경 또는 텍스트를 포함 하는 경우 어떤 식으로든에서 왜곡 될 수 없는 경우에 매우 유용 합니다. 이 설정은 큰 여백 (안전 지역) 안전 하 게 다른 종횡비와 화면에 자를 수 있는 이미지에 가장 적합 합니다.\n\n플러그인 다시 로드 스플래시 drawable 방향이 변경 될 때마다 세로 및 가로 방향에 대 한 다른 drawables를 지정할 수 있도록 합니다.\n\n### 브라우저 만지면\n\n`Config.xml`에 다음 기본 설정을 사용할 수 있습니다.\n\n    <platform name=\"browser\">\n        <preference name=\"SplashScreen\" value=\"images/browser/splashscreen.jpg\" /> <!-- defaults to \"img/logo.png\" -->\n        <preference name=\"SplashScreenDelay\" value=\"10000\" /> <!-- defaults to \"3000\" -->\n        <preference name=\"SplashScreenBackgroundColor\" value=\"green\" /> <!-- defaults to \"#464646\" -->\n        <preference name=\"ShowSplashScreen\" value=\"false\" /> <!-- defaults to \"true\" -->\n        <preference name=\"SplashScreenWidth\" value=\"600\" /> <!-- defaults to \"170\" -->\n        <preference name=\"SplashScreenHeight\" value=\"300\" /> <!-- defaults to \"200\" -->\n    </platform>\n    \n\n### iOS 단점\n\n  * `FadeSplashScreen` (부울 `true`로 기본값): 시작 화면 표시 상태로 변경 될 때 밖으로 퇴색 하지 않도록 하려면 `false` 로 설정.\n    \n        <preference name=\"FadeSplashScreen\" value=\"false\"/>\n        \n\n  * `FadeSplashScreenDuration` (부동, `2`기본값): 시작 화면에 대 한 초 페이드 효과를 실행 하는 지정 합니다.\n    \n        <preference name=\"FadeSplashScreenDuration\" value=\"4\"/>\n        \n\n  * `ShowSplashScreenSpinner` (부울 `true`로 기본값): 스플래시 화면 회전자를 숨기려면 `false` 로 설정.\n    \n        <preference name=\"ShowSplashScreenSpinner\" value=\"false\"/>\n        \n\n## splashscreen.hide\n\n시작 화면을 닫습니다.\n\n    navigator.splashscreen.hide();\n    \n\n### 블랙베리 10, WP8, iOS 특질\n\n`config.xml` 파일의 `AutoHideSplashScreen` 설정을 `false` 여야 합니다. 2 초 동안 시작 화면을 숨기고 지연, `deviceready` 이벤트 처리기에서 다음과 같은 타이머를 추가:\n\n        setTimeout(function() {\n            navigator.splashscreen.hide();\n        }, 2000);\n    \n\n## splashscreen.show\n\n시작 화면을 표시합니다.\n\n    navigator.splashscreen.show();\n    \n\n응용 프로그램 시작 및 `deviceready` 이벤트는 발생 될 때까지 응용 프로그램이 `navigator.splashscreen.show()`을 호출할 수 없습니다. 하지만 그 스플래시 스크린의 목적 것 같다 일반적으로 시작 화면이 당신의 애플 리 케이 션 시작 하기 전에 표시 될 운명이 다, 이후. `config.xml에서` 몇 가지 구성을 제공 하 자동으로 스플래시 `표시` 화면 애플 리 케이 션 출시 직후와 그것은 완벽 하 게 시작 하 고 `deviceready` 이벤트를 받은 전에. 이 구성 하 고 자세한 내용은 [아이콘 및 시작 화면을](http://cordova.apache.org/docs/en/edge/config_ref_images.md.html) 참조 하십시오. 이러한 이유로, 그것은 가능성이 시작 화면은 응용 프로그램 시작에 대 한 표시 되도록 `navigator.splashscreen.show()`를 호출 해야입니다."
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/doc/ko/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-splashscreen\n\n이 플러그인은 표시 하 고 응용 프로그램 실행 하는 동안 시작 화면을 숨깁니다.\n\n## 설치\n\n    cordova plugin add cordova-plugin-splashscreen\n    \n\n## 지원 되는 플랫폼\n\n*   아마존 화재 운영 체제\n*   안 드 로이드\n*   블랙베리 10\n*   iOS\n*   Windows Phone 7과 8\n*   윈도우 8\n\n## 메서드\n\n*   splashscreen.show\n*   splashscreen.hide\n\n### 안 드 로이드 단점\n\n당신의 config.xml에 다음 환경 설정에 추가 해야 합니다.\n\n    <preference name=\"SplashScreen\" value=\"foo\" />\n    <preference name=\"SplashScreenDelay\" value=\"10000\" />\n    \n\n여기서 foo splashscreen 파일, 선호 9 패치 파일의 이름입니다. 적절 한 폴더 아래 res/xml 디렉토리에 splashcreen 파일을 추가 해야 합니다. 두 번째 매개 변수는 splashscreen 얼마나 밀리초 단위로 표시 됩니다 나타냅니다. 3000 ms 기본값으로 사용 됩니다. 자세한 내용은 [아이콘 및 시작 화면을][1] 참조 하십시오.\n\n [1]: http://cordova.apache.org/docs/en/edge/config_ref_images.md.html\n\n## splashscreen.hide\n\n시작 화면을 닫습니다.\n\n    navigator.splashscreen.hide();\n    \n\n### 블랙베리 10, WP8, iOS 특질\n\n`config.xml` 파일의 `AutoHideSplashScreen` 설정을 `false` 여야 합니다. 2 초 동안 시작 화면을 숨기고 지연, `deviceready` 이벤트 처리기에서 다음과 같은 타이머를 추가:\n\n        setTimeout(function() {\n            navigator.splashscreen.hide();\n        }, 2000);\n    \n\n## splashscreen.show\n\n시작 화면을 표시합니다.\n\n    navigator.splashscreen.show();\n    \n\n응용 프로그램 시작 및 `deviceready` 이벤트는 발생 될 때까지 응용 프로그램이 `navigator.splashscreen.show()`을 호출할 수 없습니다. 하지만 그 스플래시 스크린의 목적 것 같다 일반적으로 시작 화면이 당신의 애플 리 케이 션 시작 하기 전에 표시 될 운명이 다, 이후. `config.xml에서` 몇 가지 구성을 제공 하 자동으로 스플래시 `표시` 화면 애플 리 케이 션 출시 직후와 그것은 완벽 하 게 시작 하 고 `deviceready` 이벤트를 받은 전에. 이 구성 하 고 자세한 내용은 [아이콘 및 시작 화면을][1] 참조 하십시오. 이러한 이유로, 그것은 가능성이 시작 화면은 응용 프로그램 시작에 대 한 표시 되도록 `navigator.splashscreen.show()`를 호출 해야입니다.\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/doc/pl/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-splashscreen\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-splashscreen.svg)](https://travis-ci.org/apache/cordova-plugin-splashscreen)\n\nTen plugin wyświetla i ukrywa ekran powitalny podczas uruchamiania aplikacji.\n\n## Instalacja\n\n    // npm hosted (new) id\n    cordova plugin add cordova-plugin-splashscreen\n    // you may also install directly from this repo\n    cordova plugin add https://github.com/apache/cordova-plugin-splashscreen.git\n    \n\n## Obsługiwane platformy\n\n  * Amazon Fire OS\n  * Android\n  * BlackBerry 10\n  * iOS\n  * Windows Phone 7 i 8\n  * Windows 8\n  * Windows\n  * Przeglądarka\n\n## Metody\n\n  * splashscreen.show\n  * splashscreen.Hide\n\n### Dziwactwa Androida\n\nW pliku `config.xml`musisz dodać następujące preferencje:\n\n    <preference name=\"SplashScreen\" value=\"foo\" />\n    <preference name=\"SplashScreenDelay\" value=\"10000\" />\n    <preference name=\"SplashMaintainAspectRatio\" value=\"true|false\" />\n    \n\nGdzie foo jest nazwą pliku ekranu powitalnego, najlepiej 9 łatce. Upewnij się dodać pliki splashcreen do katalogu res/xml w odpowiednich folderach. Drugi parametr reprezentuje, jak długo ekranu powitalnego pojawi się w milisekundach. Domyślnie 3000 ms. Aby uzyskać więcej informacji, zobacz [ikony i ekrany powitalne w aplikacjach](http://cordova.apache.org/docs/en/edge/config_ref_images.md.html).\n\n\"SplashMaintainAspectRatio\" preferencji jest opcjonalne. Jeśli zestaw na wartość true, ekran powitalny dolarowe nie jest rozciągnięty do ekranów, ale zamiast po prostu \"obejmuje\" ekranu, jak CSS \"tło-rozmiar: okładka\". Jest to bardzo przydatne, kiedy opryskać tęcza obrazy nie zniekształcony w jakikolwiek sposób, na przykład, gdy zawierają one dekoracje lub tekst. To ustawienie działa najlepiej z obrazów, które mają duże marginesy (bezpiecznych obszarów), które mogą być bezpiecznie przycięte na ekrany z różnych proporcji.\n\nPlugin ładuje rozchlapać dolarowe, gdy zmienia orientację, tak można określić różnych drawables do orientacji pionowej i poziomej.\n\n### Quirks przeglądarki\n\nW pliku `config.xml`można użyć następujące preferencje:\n\n    <platform name=\"browser\">\n        <preference name=\"SplashScreen\" value=\"images/browser/splashscreen.jpg\" /> <!-- defaults to \"img/logo.png\" -->\n        <preference name=\"SplashScreenDelay\" value=\"10000\" /> <!-- defaults to \"3000\" -->\n        <preference name=\"SplashScreenBackgroundColor\" value=\"green\" /> <!-- defaults to \"#464646\" -->\n        <preference name=\"ShowSplashScreen\" value=\"false\" /> <!-- defaults to \"true\" -->\n        <preference name=\"SplashScreenWidth\" value=\"600\" /> <!-- defaults to \"170\" -->\n        <preference name=\"SplashScreenHeight\" value=\"300\" /> <!-- defaults to \"200\" -->\n    </platform>\n    \n\n### Dziwactwa iOS\n\n  * `FadeSplashScreen` (wartość logiczna, domyślnie `true`): zestaw na `false` , aby zapobiec Znikająca i odkładane po zmianie stanu wyświetlania ekranu powitalnego.\n    \n        <preference name=\"FadeSplashScreen\" value=\"false\"/>\n        \n\n  * `FadeSplashScreenDuration` (float, domyślnie `2`): określa liczbę sekund dla ekranu powitalnego zanikanie efekt do wykonać.\n    \n        <preference name=\"FadeSplashScreenDuration\" value=\"4\"/>\n        \n\n  * `ShowSplashScreenSpinner` (wartość logiczna, domyślnie `true`): zestaw na `false` , aby ukryć pokrętła ekran powitalny.\n    \n        <preference name=\"ShowSplashScreenSpinner\" value=\"false\"/>\n        \n\n## splashscreen.Hide\n\nOdrzucić ten opryskaæ têcza.\n\n    navigator.splashscreen.hide();\n    \n\n### Jeżyna 10, WP8, iOS dziwactwo\n\nPlik `config.xml` `AutoHideSplashScreen` ustawienie musi być `false`. Opóźnienia, ukrywanie ekranu powitalnego przez dwie sekundy, dodać timer następujących w `deviceready` obsługa zdarzeń:\n\n        setTimeout(function() {\n            navigator.splashscreen.hide();\n        }, 2000);\n    \n\n## splashscreen.show\n\nWyświetla ekran powitalny.\n\n    navigator.splashscreen.show();\n    \n\nAplikacja nie można wywołać `navigator.splashscreen.show()`, aż aplikacja została uruchomiona i zdarzenie `deviceready` został zwolniony. Ale ponieważ zazwyczaj opryskać tęcza ma być widoczne przed rozpoczęciem aplikacji, wydaje się sprzeczne z celem ekranu powitalnego. Dostarczanie niektórych konfiguracji w `pliku config.xml` będzie automatycznie `show` splash na ekranie natychmiast po uruchomienie aplikacji i przed pełni rozpoczął i odebrał zdarzenie `deviceready`. Aby uzyskać więcej informacji na robienie tej konfiguracji, zobacz [ikony i ekrany powitalne w aplikacjach](http://cordova.apache.org/docs/en/edge/config_ref_images.md.html). Z tego powodu jest mało prawdopodobne, należy zadzwonić `navigator.splashscreen.show()`, aby wyświetlić ekran powitalny dla uruchamiania aplikacji."
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/doc/pl/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-splashscreen\n\nTen plugin wyświetla i ukrywa ekran powitalny podczas uruchamiania aplikacji.\n\n## Instalacja\n\n    cordova plugin add cordova-plugin-splashscreen\n    \n\n## Obsługiwane platformy\n\n*   Amazon Fire OS\n*   Android\n*   BlackBerry 10\n*   iOS\n*   Windows Phone 7 i 8\n*   Windows 8\n\n## Metody\n\n*   splashscreen.show\n*   splashscreen.Hide\n\n### Dziwactwa Androida\n\nW pliku config.xml musisz dodać następujące preferencje:\n\n    <preference name=\"SplashScreen\" value=\"foo\" />\n    <preference name=\"SplashScreenDelay\" value=\"10000\" />\n    \n\nGdzie foo jest nazwą pliku ekranu powitalnego, najlepiej 9 łatce. Upewnij się dodać pliki splashcreen do katalogu res/xml w odpowiednich folderach. Drugi parametr reprezentuje, jak długo ekranu powitalnego pojawi się w milisekundach. Domyślnie 3000 ms. Aby uzyskać więcej informacji, zobacz [ikony i ekrany powitalne w aplikacjach][1].\n\n [1]: http://cordova.apache.org/docs/en/edge/config_ref_images.md.html\n\n## splashscreen.Hide\n\nOdrzucić ten opryskaæ têcza.\n\n    navigator.splashscreen.hide();\n    \n\n### Jeżyna 10, WP8, iOS dziwactwo\n\nPlik `config.xml` `AutoHideSplashScreen` ustawienie musi być `false`. Opóźnienia, ukrywanie ekranu powitalnego przez dwie sekundy, dodać timer następujących w `deviceready` obsługa zdarzeń:\n\n        setTimeout(function() {\n            navigator.splashscreen.hide();\n        }, 2000);\n    \n\n## splashscreen.show\n\nWyświetla ekran powitalny.\n\n    navigator.splashscreen.show();\n    \n\nAplikacja nie można wywołać `navigator.splashscreen.show()`, aż aplikacja została uruchomiona i zdarzenie `deviceready` został zwolniony. Ale ponieważ zazwyczaj opryskać tęcza ma być widoczne przed rozpoczęciem aplikacji, wydaje się sprzeczne z celem ekranu powitalnego. Dostarczanie niektórych konfiguracji w `pliku config.xml` będzie automatycznie `show` splash na ekranie natychmiast po uruchomienie aplikacji i przed pełni rozpoczął i odebrał zdarzenie `deviceready`. Aby uzyskać więcej informacji na robienie tej konfiguracji, zobacz [ikony i ekrany powitalne w aplikacjach][1]. Z tego powodu jest mało prawdopodobne, należy zadzwonić `navigator.splashscreen.show()`, aby wyświetlić ekran powitalny dla uruchamiania aplikacji.\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/doc/ru/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-splashscreen\n\nЭтот плагин отображает и скрывает экран-заставку при запуске приложения.\n\n## Установка\n\n    cordova plugin add cordova-plugin-splashscreen\n    \n\n## Поддерживаемые платформы\n\n*   Amazon Fire OS\n*   Android\n*   BlackBerry 10\n*   iOS\n*   Windows Phone 7 и 8\n*   Windows 8\n\n## Методы\n\n*   splashscreen.show\n*   splashscreen.hide\n\n### Особенности Android\n\nВ вашем файле config.xml необходимо добавить следующие настройки:\n\n`<preference name=\"SplashScreen\" value=\"foo\" />` `<preference name=\"SplashScreenDelay\" value=\"10000\" />`\n\nГде foo это имя файла splashscreen, желательно 9 заплатку. Убедитесь в том добавить ваши splashcreen файлы в папку res/xml в соответствующие папки. Второй параметр представляет, как долго splashscreen появится в миллисекундах. По умолчанию он 3000 МС. Увидеть [иконки и заставки][1] для получения дополнительной информации.\n\n [1]: http://cordova.apache.org/docs/en/edge/config_ref_images.md.html\n\n## splashscreen.hide\n\nЗакройте экран-заставка.\n\n    Navigator.SplashScreen.Hide();\n    \n\n### Особенности BlackBerry 10, WP8, iOS\n\n`config.xml`Файла `AutoHideSplashScreen` должен быть `false` . Для задержки скрытия заставки на две секунды, добавить таймер, например в `deviceready` обработчик событий:\n\n        setTimeout(function() {navigator.splashscreen.hide();\n        }, 2000);\n    \n\n## splashscreen.show\n\nОтображает экран-заставку.\n\n    Navigator.SplashScreen.Show();\n    \n\nВаше приложение не может вызвать `navigator.splashscreen.show()` до тех пор, пока приложение началась и `deviceready` событие инициировано. Но поскольку обычно экран-заставка должен быть видимым до начала вашего приложения, что казалось бы поражение цели экрана-заставки. Предоставление некоторых конфигурации в `config.xml` будет автоматически `show` экран-заставку сразу же после запуска вашего приложения и перед его полностью запущен и получил `deviceready` событие. Увидеть [иконки и заставки][1] для получения дополнительной информации на делать этой конфигурации. По этой причине маловероятно, вам нужно вызвать `navigator.splashscreen.show()` для отображения экрана-заставки для запуска приложения.\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/doc/zh/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-splashscreen\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-splashscreen.svg)](https://travis-ci.org/apache/cordova-plugin-splashscreen)\n\n這個外掛程式顯示和隱藏在應用程式啟動期間的初始螢幕。\n\n## 安裝\n\n    // npm hosted (new) id\n    cordova plugin add cordova-plugin-splashscreen\n    // you may also install directly from this repo\n    cordova plugin add https://github.com/apache/cordova-plugin-splashscreen.git\n    \n\n## 支援的平臺\n\n  * 亞馬遜火 OS\n  * Android 系統\n  * 黑莓 10\n  * iOS\n  * Windows Phone 7 和 8\n  * Windows 8\n  * Windows\n  * 瀏覽器\n\n## 方法\n\n  * splashscreen.show\n  * splashscreen.hide\n\n### Android 的怪癖\n\n在你的`config.xml`，您需要添加以下優惠:\n\n    <preference name=\"SplashScreen\" value=\"foo\" />\n    <preference name=\"SplashScreenDelay\" value=\"10000\" />\n    <preference name=\"SplashMaintainAspectRatio\" value=\"true|false\" />\n    \n\n美孚在哪裡閃屏檔，最好是 9 修補程式檔的名稱。 請確保您的 splashcreen 檔添加到 res/xml 目錄下相應的資料夾。 第二個參數表示多久閃屏會顯示以毫秒為單位。 它將預設為 3000 毫秒。 有關更多資訊，請參見 [圖示和啟動畫面](http://cordova.apache.org/docs/en/edge/config_ref_images.md.html)。\n\n\"SplashMaintainAspectRatio\"首選項是可選的。 如果設置為 true，可繪製的初始螢幕不會拉伸以適合螢幕，但相反只是\"覆蓋\"螢幕，像 CSS\"背景-大小: 蓋\"。 這是非常有用的不能以任何方式，例如當他們包含文本或風景畸變閃屏圖像時。 此設置適用于有大利潤 (安全區)，可以安全地裁剪不同長寬比與螢幕上的圖像。\n\n該外掛程式重新載入初始可繪製只要方向發生變化，所以您可以指定不同的畫板為縱向和橫向方向。\n\n### 瀏覽器的怪癖\n\n你可以用你的`config.xml`下列優先選項:\n\n    <platform name=\"browser\">\n        <preference name=\"SplashScreen\" value=\"images/browser/splashscreen.jpg\" /> <!-- defaults to \"img/logo.png\" -->\n        <preference name=\"SplashScreenDelay\" value=\"10000\" /> <!-- defaults to \"3000\" -->\n        <preference name=\"SplashScreenBackgroundColor\" value=\"green\" /> <!-- defaults to \"#464646\" -->\n        <preference name=\"ShowSplashScreen\" value=\"false\" /> <!-- defaults to \"true\" -->\n        <preference name=\"SplashScreenWidth\" value=\"600\" /> <!-- defaults to \"170\" -->\n        <preference name=\"SplashScreenHeight\" value=\"300\" /> <!-- defaults to \"200\" -->\n    </platform>\n    \n\n### iOS 的怪癖\n\n  * `FadeSplashScreen`(預設為`true`的布林值): 設置為`false` ，以防止出現閃屏衰落和退出其顯示狀態發生變化時。\n    \n        <preference name=\"FadeSplashScreen\" value=\"false\"/>\n        \n\n  * `FadeSplashScreenDuration`(float，預設為`2`): 指定的閃屏秒數淡出效果來執行。\n    \n        <preference name=\"FadeSplashScreenDuration\" value=\"4\"/>\n        \n\n  * `ShowSplashScreenSpinner`(boolean, `true`的布林值): 設置為`false`來隱藏初始螢幕微調框。\n    \n        <preference name=\"ShowSplashScreenSpinner\" value=\"false\"/>\n        \n\n## splashscreen.hide\n\n解雇的閃屏。\n\n    navigator.splashscreen.hide();\n    \n\n### 黑莓 10，WP8，iOS 怪癖\n\n`config.xml` 檔 `AutoHideSplashScreen` 設置必須是 `假` 的。 若要延遲兩秒鐘隱藏的閃屏，`deviceready` 事件處理常式中添加一個計時器，如下所示：\n\n        setTimeout(function() {\n            navigator.splashscreen.hide();\n        }, 2000);\n    \n\n## splashscreen.show\n\n顯示初始螢幕。\n\n    navigator.splashscreen.show();\n    \n\n您的應用程式無法調用 `navigator.splashscreen.show()`，直到該應用程式已啟動，且觸發了 `deviceready` 事件。 但是，由於通常的閃屏為了是可見的在您的應用程式啟動之前，這似乎會打敗閃屏的目的。 提供一些配置在 `config.xml` 中的會自動 `show` 初始螢幕您的應用程式啟動後立即和之前它已經完全起步並收到 `deviceready` 事件。 做這種配置的詳細資訊，請參閱 [圖示和啟動畫面](http://cordova.apache.org/docs/en/edge/config_ref_images.md.html)。 出於此原因，不太可能您需要調用 `navigator.splashscreen.show()`，使初始螢幕可見為應用程式啟動。"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/doc/zh/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-splashscreen\n\n這個外掛程式顯示和隱藏在應用程式啟動期間的初始螢幕。\n\n## 安裝\n\n    cordova plugin add cordova-plugin-splashscreen\n    \n\n## 支援的平臺\n\n*   亞馬遜火 OS\n*   Android 系統\n*   黑莓 10\n*   iOS\n*   Windows Phone 7 和 8\n*   Windows 8\n\n## 方法\n\n*   splashscreen.show\n*   splashscreen.hide\n\n### Android 的怪癖\n\n在你的 config.xml，您需要添加以下優惠：\n\n    <preference name=\"SplashScreen\" value=\"foo\" />\n    <preference name=\"SplashScreenDelay\" value=\"10000\" />\n    \n\n美孚在哪裡閃屏檔，最好是 9 修補程式檔的名稱。 請確保您的 splashcreen 檔添加到 res/xml 目錄下相應的資料夾。 第二個參數表示多久閃屏會顯示以毫秒為單位。 它將預設為 3000 毫秒。 有關更多資訊，請參見 [圖示和啟動畫面][1]。\n\n [1]: http://cordova.apache.org/docs/en/edge/config_ref_images.md.html\n\n## splashscreen.hide\n\n解雇的閃屏。\n\n    navigator.splashscreen.hide();\n    \n\n### 黑莓 10，WP8，iOS 怪癖\n\n`config.xml` 檔 `AutoHideSplashScreen` 設置必須是 `假` 的。 若要延遲兩秒鐘隱藏的閃屏，`deviceready` 事件處理常式中添加一個計時器，如下所示：\n\n        setTimeout(function() {\n            navigator.splashscreen.hide();\n        }, 2000);\n    \n\n## splashscreen.show\n\n顯示初始螢幕。\n\n    navigator.splashscreen.show();\n    \n\n您的應用程式無法調用 `navigator.splashscreen.show()`，直到該應用程式已啟動，且觸發了 `deviceready` 事件。 但是，由於通常的閃屏為了是可見的在您的應用程式啟動之前，這似乎會打敗閃屏的目的。 提供一些配置在 `config.xml` 中的會自動 `show` 初始螢幕您的應用程式啟動後立即和之前它已經完全起步並收到 `deviceready` 事件。 做這種配置的詳細資訊，請參閱 [圖示和啟動畫面][1]。 出於此原因，不太可能您需要調用 `navigator.splashscreen.show()`，使初始螢幕可見為應用程式啟動。\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/package.json",
    "content": "{\n  \"name\": \"cordova-plugin-splashscreen\",\n  \"version\": \"2.1.0\",\n  \"description\": \"Cordova Splashscreen Plugin\",\n  \"cordova\": {\n    \"id\": \"cordova-plugin-splashscreen\",\n    \"platforms\": [\n      \"android\",\n      \"amazon-fireos\",\n      \"ubuntu\",\n      \"ios\",\n      \"blackberry10\",\n      \"wp8\",\n      \"windows8\",\n      \"windows\",\n      \"tizen\"\n    ]\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/apache/cordova-plugin-splashscreen\"\n  },\n  \"keywords\": [\n    \"cordova\",\n    \"splashscreen\",\n    \"ecosystem:cordova\",\n    \"cordova-android\",\n    \"cordova-amazon-fireos\",\n    \"cordova-ubuntu\",\n    \"cordova-ios\",\n    \"cordova-blackberry10\",\n    \"cordova-wp8\",\n    \"cordova-windows8\",\n    \"cordova-windows\",\n    \"cordova-tizen\"\n  ],\n  \"engines\": [\n    {\n      \"name\": \"cordova-android\",\n      \"version\": \">=3.6.0\"\n    }\n  ],\n  \"author\": \"Apache Software Foundation\",\n  \"license\": \"Apache 2.0\"\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/plugin.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  Licensed to the Apache Software Foundation (ASF) under one\n  or more contributor license agreements.  See the NOTICE file\n  distributed with this work for additional information\n  regarding copyright ownership.  The ASF licenses this file\n  to you under the Apache License, Version 2.0 (the\n  \"License\"); you may not use this file except in compliance\n  with the License.  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing,\n  software distributed under the License is distributed on an\n  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n  KIND, either express or implied.  See the License for the\n  specific language governing permissions and limitations\n  under the License.\n-->\n\n<plugin xmlns=\"http://apache.org/cordova/ns/plugins/1.0\"\n           id=\"cordova-plugin-splashscreen\"\n      version=\"2.1.0\">\n    <name>Splashscreen</name>\n    <description>Cordova Splashscreen Plugin</description>\n    <license>Apache 2.0</license>\n    <keywords>cordova,splashscreen</keywords>\n    <repo>https://git-wip-us.apache.org/repos/asf/cordova-plugin-splashscreen.git</repo>\n    <issue>https://issues.apache.org/jira/browse/CB/component/12320653</issue>\n\n    <engines>\n        <engine name=\"cordova-android\" version=\">=3.6.0\" /><!-- Requires CordovaPlugin.preferences -->\n    </engines>\n\n    <js-module src=\"www/splashscreen.js\" name=\"SplashScreen\">\n        <clobbers target=\"navigator.splashscreen\" />\n    </js-module>\n\n    <!-- android -->\n    <platform name=\"android\">\n        <config-file target=\"res/xml/config.xml\" parent=\"/*\">\n            <feature name=\"SplashScreen\">\n                <param name=\"android-package\" value=\"org.apache.cordova.splashscreen.SplashScreen\"/>\n                <param name=\"onload\" value=\"true\"/>\n            </feature>\n        </config-file>\n\n        <source-file src=\"src/android/SplashScreen.java\" target-dir=\"src/org/apache/cordova/splashscreen\" />\n    </platform>\n\n    <!-- amazon-fireos -->\n    <platform name=\"amazon-fireos\">\n        <config-file target=\"res/xml/config.xml\" parent=\"/*\">\n            <feature name=\"SplashScreen\">\n            <param name=\"android-package\" value=\"org.apache.cordova.splashscreen.SplashScreen\"/>\n            </feature>\n        </config-file>\n\n        <source-file src=\"src/android/SplashScreen.java\" target-dir=\"src/org/apache/cordova/splashscreen\" />\n    </platform>\n\n    <!-- ubuntu -->\n    <platform name=\"ubuntu\">\n        <header-file src=\"src/ubuntu/splashscreen.h\" />\n        <source-file src=\"src/ubuntu/splashscreen.cpp\" />\n    </platform>\n\n    <!-- ios -->\n    <platform name=\"ios\">\n        <config-file target=\"config.xml\" parent=\"/*\">\n\t\t    <feature name=\"SplashScreen\">\n\t\t\t    <param name=\"ios-package\" value=\"CDVSplashScreen\"/>\n\t\t\t    <param name=\"onload\" value=\"true\"/>\n\t\t    </feature>\n        </config-file>\n\n        <header-file src=\"src/ios/CDVSplashScreen.h\" />\n        <source-file src=\"src/ios/CDVSplashScreen.m\" />\n        <header-file src=\"src/ios/CDVViewController+SplashScreen.h\" />\n        <source-file src=\"src/ios/CDVViewController+SplashScreen.m\" />\n\n\t    <framework src=\"CoreGraphics.framework\" />\n    </platform>\n\n    <!-- blackberry10 -->\n    <platform name=\"blackberry10\">\n        <source-file src=\"src/blackberry10/index.js\" target-dir=\"SplashScreen\" />\n        <config-file target=\"www/config.xml\" parent=\"/widget\">\n            <feature name=\"SplashScreen\" value=\"SplashScreen\"/>\n        </config-file>\n    </platform>\n\n    <!-- wp8 -->\n    <platform name=\"wp8\">\n        <config-file target=\"config.xml\" parent=\"/*\">\n            <feature name=\"SplashScreen\">\n                <param name=\"wp-package\" value=\"SplashScreen\"/>\n                <param name=\"onload\" value=\"true\"/>\n            </feature>\n        </config-file>\n\n        <source-file src=\"src/wp/SplashScreen.cs\" />\n        <source-file src=\"src/wp/ResolutionHelper.cs\" />\n\n    </platform>\n\n    <!-- windows8 -->\n    <platform name=\"windows8\">\n        <js-module src=\"www/windows/SplashScreenProxy.js\" name=\"SplashScreenProxy\">\n            <merges target=\"\" />\n        </js-module>\n    </platform>\n\n    <!-- windows -->\n    <platform name=\"windows\">\n        <js-module src=\"www/windows/SplashScreenProxy.js\" name=\"SplashScreenProxy\">\n            <merges target=\"\" />\n        </js-module>\n    </platform>\n\n    <!-- tizen -->\n    <platform name=\"tizen\">\n        <js-module src=\"src/tizen/SplashScreenProxy.js\" name=\"SplashScreenProxy\">\n            <runs />\n        </js-module>\n    </platform>\n\n    <!-- browser -->\n    <platform name=\"browser\">\n        <js-module src=\"src/browser/SplashScreenProxy.js\" name=\"SplashScreenProxy\">\n            <runs />\n        </js-module>\n    </platform>\n</plugin>\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/src/android/SplashScreen.java",
    "content": "/*\n       Licensed to the Apache Software Foundation (ASF) under one\n       or more contributor license agreements.  See the NOTICE file\n       distributed with this work for additional information\n       regarding copyright ownership.  The ASF licenses this file\n       to you under the Apache License, Version 2.0 (the\n       \"License\"); you may not use this file except in compliance\n       with the License.  You may obtain a copy of the License at\n\n         http://www.apache.org/licenses/LICENSE-2.0\n\n       Unless required by applicable law or agreed to in writing,\n       software distributed under the License is distributed on an\n       \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n       KIND, either express or implied.  See the License for the\n       specific language governing permissions and limitations\n       under the License.\n*/\n\npackage org.apache.cordova.splashscreen;\n\nimport android.app.Dialog;\nimport android.app.ProgressDialog;\nimport android.content.Context;\nimport android.content.DialogInterface;\nimport android.content.res.Configuration;\nimport android.graphics.Color;\nimport android.os.Handler;\nimport android.view.Display;\nimport android.view.View;\nimport android.view.ViewGroup.LayoutParams;\nimport android.view.WindowManager;\nimport android.widget.ImageView;\nimport android.widget.LinearLayout;\n\nimport org.apache.cordova.CallbackContext;\nimport org.apache.cordova.CordovaPlugin;\nimport org.apache.cordova.CordovaWebView;\nimport org.json.JSONArray;\nimport org.json.JSONException;\n\npublic class SplashScreen extends CordovaPlugin {\n    private static final String LOG_TAG = \"SplashScreen\";\n    // Cordova 3.x.x has a copy of this plugin bundled with it (SplashScreenInternal.java).\n    // Enable functionality only if running on 4.x.x.\n    private static final boolean HAS_BUILT_IN_SPLASH_SCREEN = Integer.valueOf(CordovaWebView.CORDOVA_VERSION.split(\"\\\\.\")[0]) < 4;\n    private static Dialog splashDialog;\n    private static ProgressDialog spinnerDialog;\n    private static boolean firstShow = true;\n\n    /**\n     * Displays the splash drawable.\n     */\n    private ImageView splashImageView;\n\n    /**\n     * Remember last device orientation to detect orientation changes.\n     */\n    private int orientation;\n\n    // Helper to be compile-time compatible with both Cordova 3.x and 4.x.\n    private View getView() {\n        try {\n            return (View)webView.getClass().getMethod(\"getView\").invoke(webView);\n        } catch (Exception e) {\n            return (View)webView;\n        }\n    }\n\n    @Override\n    protected void pluginInitialize() {\n        if (HAS_BUILT_IN_SPLASH_SCREEN || !firstShow) {\n            return;\n        }\n        // Make WebView invisible while loading URL\n        getView().setVisibility(View.INVISIBLE);\n        int drawableId = preferences.getInteger(\"SplashDrawableId\", 0);\n        if (drawableId == 0) {\n            String splashResource = preferences.getString(\"SplashScreen\", \"screen\");\n            if (splashResource != null) {\n                drawableId = cordova.getActivity().getResources().getIdentifier(splashResource, \"drawable\", cordova.getActivity().getClass().getPackage().getName());\n                if (drawableId == 0) {\n                    drawableId = cordova.getActivity().getResources().getIdentifier(splashResource, \"drawable\", cordova.getActivity().getPackageName());\n                }\n                preferences.set(\"SplashDrawableId\", drawableId);\n            }\n        }\n\n        // Save initial orientation.\n        orientation = cordova.getActivity().getResources().getConfiguration().orientation;\n\n        firstShow = false;\n        loadSpinner();\n        showSplashScreen(true);\n    }\n\n    /**\n     * Shorter way to check value of \"SplashMaintainAspectRatio\" preference.\n     */\n    private boolean isMaintainAspectRatio () {\n        return preferences.getBoolean(\"SplashMaintainAspectRatio\", false);\n    }\n\n    @Override\n    public void onPause(boolean multitasking) {\n        if (HAS_BUILT_IN_SPLASH_SCREEN) {\n            return;\n        }\n        // hide the splash screen to avoid leaking a window\n        this.removeSplashScreen();\n    }\n\n    @Override\n    public void onDestroy() {\n        if (HAS_BUILT_IN_SPLASH_SCREEN) {\n            return;\n        }\n        // hide the splash screen to avoid leaking a window\n        this.removeSplashScreen();\n        // If we set this to true onDestroy, we lose track when we go from page to page!\n        //firstShow = true;\n    }\n\n    @Override\n    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {\n        if (action.equals(\"hide\")) {\n            cordova.getActivity().runOnUiThread(new Runnable() {\n                public void run() {\n                    webView.postMessage(\"splashscreen\", \"hide\");\n                }\n            });\n        } else if (action.equals(\"show\")) {\n            cordova.getActivity().runOnUiThread(new Runnable() {\n                public void run() {\n                    webView.postMessage(\"splashscreen\", \"show\");\n                }\n            });\n        } else if (action.equals(\"spinnerStart\")) {\n            if (!HAS_BUILT_IN_SPLASH_SCREEN) {\n                final String title = args.getString(0);\n                final String message = args.getString(1);\n                cordova.getActivity().runOnUiThread(new Runnable() {\n                    public void run() {\n                        spinnerStart(title, message);\n                    }\n                });\n            }\n        } else {\n            return false;\n        }\n\n        callbackContext.success();\n        return true;\n    }\n\n    @Override\n    public Object onMessage(String id, Object data) {\n        if (HAS_BUILT_IN_SPLASH_SCREEN) {\n            return null;\n        }\n        if (\"splashscreen\".equals(id)) {\n            if (\"hide\".equals(data.toString())) {\n                this.removeSplashScreen();\n            } else {\n                this.showSplashScreen(false);\n            }\n        } else if (\"spinner\".equals(id)) {\n            if (\"stop\".equals(data.toString())) {\n                this.spinnerStop();\n                getView().setVisibility(View.VISIBLE);\n            }\n        } else if (\"onReceivedError\".equals(id)) {\n            spinnerStop();\n        }\n        return null;\n    }\n\n    // Don't add @Override so that plugin still compiles on 3.x.x for a while\n    public void onConfigurationChanged(Configuration newConfig) {\n        if (newConfig.orientation != orientation) {\n            orientation = newConfig.orientation;\n\n            // Splash drawable may change with orientation, so reload it.\n            if (splashImageView != null) {\n                int drawableId = preferences.getInteger(\"SplashDrawableId\", 0);\n                if (drawableId != 0) {\n                    splashImageView.setImageDrawable(cordova.getActivity().getResources().getDrawable(drawableId));\n                }\n            }\n        }\n    }\n\n    private void removeSplashScreen() {\n        cordova.getActivity().runOnUiThread(new Runnable() {\n            public void run() {\n                if (splashDialog != null && splashDialog.isShowing()) {\n                    splashDialog.dismiss();\n                    splashDialog = null;\n                    splashImageView = null;\n                }\n            }\n        });\n    }\n\n    /**\n     * Shows the splash screen over the full Activity\n     */\n    @SuppressWarnings(\"deprecation\")\n    private void showSplashScreen(final boolean hideAfterDelay) {\n        final int splashscreenTime = preferences.getInteger(\"SplashScreenDelay\", 3000);\n        final int drawableId = preferences.getInteger(\"SplashDrawableId\", 0);\n\n        // If the splash dialog is showing don't try to show it again\n        if (splashDialog != null && splashDialog.isShowing()) {\n            return;\n        }\n        if (drawableId == 0 || (splashscreenTime <= 0 && hideAfterDelay)) {\n            return;\n        }\n\n        cordova.getActivity().runOnUiThread(new Runnable() {\n            public void run() {\n                // Get reference to display\n                Display display = cordova.getActivity().getWindowManager().getDefaultDisplay();\n                Context context = webView.getContext();\n\n                // Use an ImageView to render the image because of its flexible scaling options.\n                splashImageView = new ImageView(context);\n                splashImageView.setImageResource(drawableId);\n                LayoutParams layoutParams = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);\n                splashImageView.setLayoutParams(layoutParams);\n\n                splashImageView.setMinimumHeight(display.getHeight());\n                splashImageView.setMinimumWidth(display.getWidth());\n\n                // TODO: Use the background color of the webView's parent instead of using the preference.\n                splashImageView.setBackgroundColor(preferences.getInteger(\"backgroundColor\", Color.BLACK));\n\n                if (isMaintainAspectRatio()) {\n                    // CENTER_CROP scale mode is equivalent to CSS \"background-size:cover\"\n                    splashImageView.setScaleType(ImageView.ScaleType.CENTER_CROP);\n                }\n                else {\n                    // FIT_XY scales image non-uniformly to fit into image view.\n                    splashImageView.setScaleType(ImageView.ScaleType.FIT_XY);\n                }\n\n                // Create and show the dialog\n                splashDialog = new Dialog(context, android.R.style.Theme_Translucent_NoTitleBar);\n                // check to see if the splash screen should be full screen\n                if ((cordova.getActivity().getWindow().getAttributes().flags & WindowManager.LayoutParams.FLAG_FULLSCREEN)\n                        == WindowManager.LayoutParams.FLAG_FULLSCREEN) {\n                    splashDialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,\n                            WindowManager.LayoutParams.FLAG_FULLSCREEN);\n                }\n                splashDialog.setContentView(splashImageView);\n                splashDialog.setCancelable(false);\n                splashDialog.show();\n\n                // Set Runnable to remove splash screen just in case\n                if (hideAfterDelay) {\n                    final Handler handler = new Handler();\n                    handler.postDelayed(new Runnable() {\n                        public void run() {\n                            removeSplashScreen();\n                        }\n                    }, splashscreenTime);\n                }\n            }\n        });\n    }\n\n    /*\n     * Load the spinner\n     */\n    private void loadSpinner() {\n        // If loadingDialog property, then show the App loading dialog for first page of app\n        String loading = null;\n        if (webView.canGoBack()) {\n            loading = preferences.getString(\"LoadingDialog\", null);\n        }\n        else {\n            loading = preferences.getString(\"LoadingPageDialog\", null);\n        }\n        if (loading != null) {\n            String title = \"\";\n            String message = \"Loading Application...\";\n\n            if (loading.length() > 0) {\n                int comma = loading.indexOf(',');\n                if (comma > 0) {\n                    title = loading.substring(0, comma);\n                    message = loading.substring(comma + 1);\n                }\n                else {\n                    title = \"\";\n                    message = loading;\n                }\n            }\n            spinnerStart(title, message);\n        }\n    }\n\n    private void spinnerStart(final String title, final String message) {\n        cordova.getActivity().runOnUiThread(new Runnable() {\n            public void run() {\n                spinnerStop();\n                spinnerDialog = ProgressDialog.show(webView.getContext(), title, message, true, true,\n                        new DialogInterface.OnCancelListener() {\n                            public void onCancel(DialogInterface dialog) {\n                                spinnerDialog = null;\n                            }\n                        });\n            }\n        });\n    }\n\n    private void spinnerStop() {\n        cordova.getActivity().runOnUiThread(new Runnable() {\n            public void run() {\n                if (spinnerDialog != null && spinnerDialog.isShowing()) {\n                    spinnerDialog.dismiss();\n                    spinnerDialog = null;\n                }\n            }\n        });\n    }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/src/blackberry10/index.js",
    "content": "/*\n * Copyright 2013 Research In Motion Limited.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nmodule.exports = {\n    show: function (success, fail, args, env) {\n        var result = new PluginResult(args, env);\n        result.error(\"Not supported on platform\", false);\n    },\n\n    hide: function (success, fail, args, env) {\n        var result = new PluginResult(args, env);\n        window.qnx.webplatform.getApplication().windowVisible = true;\n        result.ok(undefined, false);\n    }\n};\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/src/browser/SplashScreenProxy.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n// Default parameter values including image size can be changed in `config.xml`\nvar splashImageWidth = 170;\nvar splashImageHeight = 200;\nvar position = { x: 0, y: 0, width: splashImageWidth, height: splashImageHeight }; \nvar splash = null; //\nvar localSplash; // the image to display\nvar localSplashImage;\nvar bgColor = \"#464646\";\nvar imageSrc = 'img/logo.png';\nvar splashScreenDelay = 3000; // in milliseconds\nvar showSplashScreen = true; // show splashcreen by default\nvar configHelper = cordova.require('cordova/confighelper');\n\nfunction updateImageLocation() {\n    position.width = Math.min(splashImageWidth, window.innerWidth);\n    position.height = position.width * (splashImageHeight / splashImageWidth);\n\n    localSplash.style.width = window.innerWidth + \"px\";\n    localSplash.style.height = window.innerHeight + \"px\";\n    localSplash.style.top = \"0px\";\n    localSplash.style.left = \"0px\";\n\n    localSplashImage.style.top = \"50%\";\n    localSplashImage.style.left = \"50%\";\n    localSplashImage.style.height = position.height + \"px\";\n    localSplashImage.style.width = position.width + \"px\";\n    localSplashImage.style.marginTop = (-position.height / 2) + \"px\";\n    localSplashImage.style.marginLeft = (-position.width / 2) + \"px\";\n}\n\nfunction onResize() {\n    updateImageLocation();\n}\n\nvar SplashScreen = {\n    setBGColor: function (cssBGColor) {\n        bgColor = cssBGColor;\n        if (localSplash) {\n            localSplash.style.backgroundColor = bgColor;\n        }\n    },\n    show: function () {\n        if(!localSplash) {\n            window.addEventListener(\"resize\", onResize, false);\n            localSplash = document.createElement(\"div\");\n            localSplash.style.backgroundColor = bgColor;\n            localSplash.style.position = \"absolute\";\n\n            localSplashImage = document.createElement(\"img\");\n            localSplashImage.src = imageSrc;\n            localSplashImage.style.position = \"absolute\";\n\n            updateImageLocation();\n\n            localSplash.appendChild(localSplashImage);\n            document.body.appendChild(localSplash);\n        }\n    },\n    hide: function () {\n        if(localSplash) {\n            window.removeEventListener(\"resize\", onResize, false);\n            document.body.removeChild(localSplash);\n            localSplash = null;\n        }\n    }\n};\n\n/**\n * Reads preferences via ConfigHelper and substitutes default parameters.\n */\nfunction readPreferencesFromCfg(cfg) {\n    try {\n        var value = cfg.getPreferenceValue('ShowSplashScreen');\n        if(typeof value != 'undefined') {\n            showSplashScreen = value === 'true';\n        }\n\n        splashScreenDelay = cfg.getPreferenceValue('SplashScreenDelay') || splashScreenDelay;\n        imageSrc = cfg.getPreferenceValue('SplashScreen') || imageSrc;\n        bgColor = cfg.getPreferenceValue('SplashScreenBackgroundColor') || bgColor;\n        splashImageWidth = cfg.getPreferenceValue('SplashScreenWidth') || splashImageWidth;\n        splashImageHeight = cfg.getPreferenceValue('SplashScreenHeight') || splashImageHeight;\n    } catch(e) {\n        var msg = '[Browser][SplashScreen] Error occured on loading preferences from config.xml: ' + JSON.stringify(e);\n        console.error(msg);\n        error(msg);\n    }\n}\n\n/**\n * Shows and hides splashscreen if it is enabled, with a delay according the current preferences.\n */\nfunction showAndHide() {\n    if(showSplashScreen) {\n        SplashScreen.show();\n\n        window.setTimeout(function() {\n            SplashScreen.hide();\n        }, splashScreenDelay);\n    }\n}\n\n/**\n * Tries to read config.xml and override default properties and then shows and hides splashcreen if it is enabled.\n */\n(function initAndShow() {\n    configHelper.readConfig(function(config) {\n        readPreferencesFromCfg(config);\n        showAndHide();\n    }, function(err) {\n        console.error(err);\n    });\n})();\n\nmodule.exports = SplashScreen;\n\nrequire(\"cordova/exec/proxy\").add(\"SplashScreen\", SplashScreen);\n\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/src/ios/CDVSplashScreen.h",
    "content": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements.  See the NOTICE file\n distributed with this work for additional information\n regarding copyright ownership.  The ASF licenses this file\n to you under the Apache License, Version 2.0 (the\n \"License\"); you may not use this file except in compliance\n with the License.  You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an\n \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n KIND, either express or implied.  See the License for the\n specific language governing permissions and limitations\n under the License.\n */\n\n#import <Foundation/Foundation.h>\n#import <Cordova/CDVPlugin.h>\n\ntypedef struct {\n    BOOL iPhone;\n    BOOL iPad;\n    BOOL iPhone5;\n    BOOL iPhone6;\n    BOOL iPhone6Plus;\n    BOOL retina;\n    \n} CDV_iOSDevice;\n\n@interface CDVSplashScreen : CDVPlugin {\n    UIActivityIndicatorView* _activityView;\n    UIImageView* _imageView;\n    NSString* _curImageName;\n    BOOL _visible;\n}\n\n- (void)show:(CDVInvokedUrlCommand*)command;\n- (void)hide:(CDVInvokedUrlCommand*)command;\n\n@end\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/src/ios/CDVSplashScreen.m",
    "content": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements.  See the NOTICE file\n distributed with this work for additional information\n regarding copyright ownership.  The ASF licenses this file\n to you under the Apache License, Version 2.0 (the\n \"License\"); you may not use this file except in compliance\n with the License.  You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an\n \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n KIND, either express or implied.  See the License for the\n specific language governing permissions and limitations\n under the License.\n */\n\n#import \"CDVSplashScreen.h\"\n#import <Cordova/CDVViewController.h>\n#import <Cordova/CDVScreenOrientationDelegate.h>\n#import \"CDVViewController+SplashScreen.h\"\n\n#define kSplashScreenDurationDefault 0.25f\n\n\n@implementation CDVSplashScreen\n\n- (void)pluginInitialize\n{\n    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pageDidLoad) name:CDVPageDidLoadNotification object:self.webView];\n\n    [self setVisible:YES];\n}\n\n- (void)show:(CDVInvokedUrlCommand*)command\n{\n    [self setVisible:YES];\n}\n\n- (void)hide:(CDVInvokedUrlCommand*)command\n{\n    [self setVisible:NO];\n}\n\n- (void)pageDidLoad\n{\n    id autoHideSplashScreenValue = [self.commandDelegate.settings objectForKey:[@\"AutoHideSplashScreen\" lowercaseString]];\n\n    // if value is missing, default to yes\n    if ((autoHideSplashScreenValue == nil) || [autoHideSplashScreenValue boolValue]) {\n        [self setVisible:NO];\n    }\n}\n\n- (void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary*)change context:(void*)context\n{\n    [self updateImage];\n}\n\n- (void)createViews\n{\n    /*\n     * The Activity View is the top spinning throbber in the status/battery bar. We init it with the default Grey Style.\n     *\n     *     whiteLarge = UIActivityIndicatorViewStyleWhiteLarge\n     *     white      = UIActivityIndicatorViewStyleWhite\n     *     gray       = UIActivityIndicatorViewStyleGray\n     *\n     */\n\n    // Determine whether rotation should be enabled for this device\n    // Per iOS HIG, landscape is only supported on iPad and iPhone 6+\n    CDV_iOSDevice device = [self getCurrentDevice];\n    BOOL autorotateValue = (device.iPad || device.iPhone6Plus) ?\n        [(CDVViewController *)self.viewController shouldAutorotateDefaultValue] :\n        NO;\n    \n    [(CDVViewController *)self.viewController setEnabledAutorotation:autorotateValue];\n\n    NSString* topActivityIndicator = [self.commandDelegate.settings objectForKey:[@\"TopActivityIndicator\" lowercaseString]];\n    UIActivityIndicatorViewStyle topActivityIndicatorStyle = UIActivityIndicatorViewStyleGray;\n\n    if ([topActivityIndicator isEqualToString:@\"whiteLarge\"]) {\n        topActivityIndicatorStyle = UIActivityIndicatorViewStyleWhiteLarge;\n    } else if ([topActivityIndicator isEqualToString:@\"white\"]) {\n        topActivityIndicatorStyle = UIActivityIndicatorViewStyleWhite;\n    } else if ([topActivityIndicator isEqualToString:@\"gray\"]) {\n        topActivityIndicatorStyle = UIActivityIndicatorViewStyleGray;\n    }\n\n    UIView* parentView = self.viewController.view;\n    parentView.userInteractionEnabled = NO;  // disable user interaction while splashscreen is shown\n    _activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:topActivityIndicatorStyle];\n    _activityView.center = CGPointMake(parentView.bounds.size.width / 2, parentView.bounds.size.height / 2);\n    _activityView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin\n        | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin;\n    [_activityView startAnimating];\n\n    // Set the frame & image later.\n    _imageView = [[UIImageView alloc] init];\n    [parentView addSubview:_imageView];\n\n    id showSplashScreenSpinnerValue = [self.commandDelegate.settings objectForKey:[@\"ShowSplashScreenSpinner\" lowercaseString]];\n    // backwards compatibility - if key is missing, default to true\n    if ((showSplashScreenSpinnerValue == nil) || [showSplashScreenSpinnerValue boolValue]) {\n        [parentView addSubview:_activityView];\n    }\n\n    // Frame is required when launching in portrait mode.\n    // Bounds for landscape since it captures the rotation.\n    [parentView addObserver:self forKeyPath:@\"frame\" options:0 context:nil];\n    [parentView addObserver:self forKeyPath:@\"bounds\" options:0 context:nil];\n\n    [self updateImage];\n}\n\n- (void)destroyViews\n{\n    [(CDVViewController *)self.viewController setEnabledAutorotation:[(CDVViewController *)self.viewController shouldAutorotateDefaultValue]];\n\n    [_imageView removeFromSuperview];\n    [_activityView removeFromSuperview];\n    _imageView = nil;\n    _activityView = nil;\n    _curImageName = nil;\n\n    self.viewController.view.userInteractionEnabled = YES;  // re-enable user interaction upon completion\n    [self.viewController.view removeObserver:self forKeyPath:@\"frame\"];\n    [self.viewController.view removeObserver:self forKeyPath:@\"bounds\"];\n}\n\n- (CDV_iOSDevice) getCurrentDevice\n{\n    CDV_iOSDevice device;\n    \n    UIScreen* mainScreen = [UIScreen mainScreen];\n    CGFloat mainScreenHeight = mainScreen.bounds.size.height;\n    CGFloat mainScreenWidth = mainScreen.bounds.size.width;\n    \n    int limit = MAX(mainScreenHeight,mainScreenWidth);\n    \n    device.iPad = (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);\n    device.iPhone = (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone);\n    device.retina = ([mainScreen scale] == 2.0);\n    device.iPhone5 = (device.iPhone && limit == 568.0);\n    // note these below is not a true device detect, for example if you are on an\n    // iPhone 6/6+ but the app is scaled it will prob set iPhone5 as true, but\n    // this is appropriate for detecting the runtime screen environment\n    device.iPhone6 = (device.iPhone && limit == 667.0);\n    device.iPhone6Plus = (device.iPhone && limit == 736.0);\n    \n    return device;\n}\n\n- (NSString*)getImageName:(UIInterfaceOrientation)currentOrientation delegate:(id<CDVScreenOrientationDelegate>)orientationDelegate device:(CDV_iOSDevice)device\n{\n    // Use UILaunchImageFile if specified in plist.  Otherwise, use Default.\n    NSString* imageName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@\"UILaunchImageFile\"];\n    \n    NSUInteger supportedOrientations = [orientationDelegate supportedInterfaceOrientations];\n    \n    // Checks to see if the developer has locked the orientation to use only one of Portrait or Landscape\n    BOOL supportsLandscape = (supportedOrientations & UIInterfaceOrientationMaskLandscape);\n    BOOL supportsPortrait = (supportedOrientations & UIInterfaceOrientationMaskPortrait || supportedOrientations & UIInterfaceOrientationMaskPortraitUpsideDown);\n    // this means there are no mixed orientations in there\n    BOOL isOrientationLocked = !(supportsPortrait && supportsLandscape);\n    \n    if (imageName) {\n        imageName = [imageName stringByDeletingPathExtension];\n    } else {\n        imageName = @\"Default\";\n    }\n    \n    if (device.iPhone5) { // does not support landscape\n        imageName = [imageName stringByAppendingString:@\"-568h\"];\n    } else if (device.iPhone6) { // does not support landscape\n        imageName = [imageName stringByAppendingString:@\"-667h\"];\n    } else if (device.iPhone6Plus) { // supports landscape\n        if (isOrientationLocked) {\n            imageName = [imageName stringByAppendingString:(supportsLandscape ? @\"-Landscape\" : @\"\")];\n        } else {\n            switch (currentOrientation) {\n                case UIInterfaceOrientationLandscapeLeft:\n                case UIInterfaceOrientationLandscapeRight:\n                        imageName = [imageName stringByAppendingString:@\"-Landscape\"];\n                    break;\n                default:\n                    break;\n            }\n        }\n        imageName = [imageName stringByAppendingString:@\"-736h\"];\n\n    } else if (device.iPad) { // supports landscape\n        if (isOrientationLocked) {\n            imageName = [imageName stringByAppendingString:(supportsLandscape ? @\"-Landscape\" : @\"-Portrait\")];\n        } else {\n            switch (currentOrientation) {\n                case UIInterfaceOrientationLandscapeLeft:\n                case UIInterfaceOrientationLandscapeRight:\n                    imageName = [imageName stringByAppendingString:@\"-Landscape\"];\n                    break;\n                    \n                case UIInterfaceOrientationPortrait:\n                case UIInterfaceOrientationPortraitUpsideDown:\n                default:\n                    imageName = [imageName stringByAppendingString:@\"-Portrait\"];\n                    break;\n            }\n        }\n    }\n    \n    return imageName;\n}\n\n// Sets the view's frame and image.\n- (void)updateImage\n{\n    NSString* imageName = [self getImageName:[[UIApplication sharedApplication] statusBarOrientation] delegate:(id<CDVScreenOrientationDelegate>)self.viewController device:[self getCurrentDevice]];\n\n    if (![imageName isEqualToString:_curImageName]) {\n        UIImage* img = [UIImage imageNamed:imageName];\n        _imageView.image = img;\n        _curImageName = imageName;\n    }\n\n    // Check that splash screen's image exists before updating bounds\n    if (_imageView.image) {\n        [self updateBounds];\n    } else {\n        NSLog(@\"WARNING: The splashscreen image named %@ was not found\", imageName);\n    }\n}\n\n- (void)updateBounds\n{\n    UIImage* img = _imageView.image;\n    CGRect imgBounds = (img) ? CGRectMake(0, 0, img.size.width, img.size.height) : CGRectZero;\n\n    CGSize screenSize = [self.viewController.view convertRect:[UIScreen mainScreen].bounds fromView:nil].size;\n    UIInterfaceOrientation orientation = self.viewController.interfaceOrientation;\n    CGAffineTransform imgTransform = CGAffineTransformIdentity;\n\n    /* If and only if an iPhone application is landscape-only as per\n     * UISupportedInterfaceOrientations, the view controller's orientation is\n     * landscape. In this case the image must be rotated in order to appear\n     * correctly.\n     */\n    BOOL isIPad = [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad;\n    if (UIInterfaceOrientationIsLandscape(orientation) && !isIPad) {\n        imgTransform = CGAffineTransformMakeRotation(M_PI / 2);\n        imgBounds.size = CGSizeMake(imgBounds.size.height, imgBounds.size.width);\n    }\n\n    // There's a special case when the image is the size of the screen.\n    if (CGSizeEqualToSize(screenSize, imgBounds.size)) {\n        CGRect statusFrame = [self.viewController.view convertRect:[UIApplication sharedApplication].statusBarFrame fromView:nil];\n        if (!(IsAtLeastiOSVersion(@\"7.0\"))) {\n            imgBounds.origin.y -= statusFrame.size.height;\n        }\n    } else if (imgBounds.size.width > 0) {\n        CGRect viewBounds = self.viewController.view.bounds;\n        CGFloat imgAspect = imgBounds.size.width / imgBounds.size.height;\n        CGFloat viewAspect = viewBounds.size.width / viewBounds.size.height;\n        // This matches the behaviour of the native splash screen.\n        CGFloat ratio;\n        if (viewAspect > imgAspect) {\n            ratio = viewBounds.size.width / imgBounds.size.width;\n        } else {\n            ratio = viewBounds.size.height / imgBounds.size.height;\n        }\n        imgBounds.size.height *= ratio;\n        imgBounds.size.width *= ratio;\n    }\n\n    _imageView.transform = imgTransform;\n    _imageView.frame = imgBounds;\n}\n\n- (void)setVisible:(BOOL)visible\n{\n    if (visible == _visible) {\n        return;\n    }\n    _visible = visible;\n\n    id fadeSplashScreenValue = [self.commandDelegate.settings objectForKey:[@\"FadeSplashScreen\" lowercaseString]];\n    id fadeSplashScreenDuration = [self.commandDelegate.settings objectForKey:[@\"FadeSplashScreenDuration\" lowercaseString]];\n\n    float fadeDuration = fadeSplashScreenDuration == nil ? kSplashScreenDurationDefault : [fadeSplashScreenDuration floatValue];\n\n    if ((fadeSplashScreenValue == nil) || ![fadeSplashScreenValue boolValue]) {\n        fadeDuration = 0;\n    }\n\n    // Never animate the showing of the splash screen.\n    if (visible) {\n        if (_imageView == nil) {\n            [self createViews];\n        }\n    } else if (fadeDuration == 0) {\n        [self destroyViews];\n    } else {\n      __weak __typeof(self) weakSelf = self;\n\n      [UIView transitionWithView:self.viewController.view\n                        duration:fadeDuration\n                         options:UIViewAnimationOptionTransitionNone\n                      animations:^(void) {\n                          __typeof(self) strongSelf = weakSelf;\n                          if (strongSelf != nil) {\n                              dispatch_async(dispatch_get_main_queue(), ^{\n                                      [strongSelf->_activityView setAlpha:0];\n                                      [strongSelf->_imageView setAlpha:0];\n                              });\n                          }\n                      }\n                      completion:^(BOOL finished) {\n                          if (finished) {\n                              dispatch_async(dispatch_get_main_queue(), ^{\n                                      [weakSelf destroyViews];\n                              });\n                          }\n                      }\n      ];      \n    }\n}\n\n@end\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/src/ios/CDVViewController+SplashScreen.h",
    "content": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements.  See the NOTICE file\n distributed with this work for additional information\n regarding copyright ownership.  The ASF licenses this file\n to you under the Apache License, Version 2.0 (the\n \"License\"); you may not use this file except in compliance\n with the License.  You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an\n \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n KIND, either express or implied.  See the License for the\n specific language governing permissions and limitations\n under the License.\n */\n\n#import <Cordova/CDVViewController.h>\n\n@interface CDVViewController (SplashScreen)\n\n@property (nonatomic, assign) BOOL enabledAutorotation;\n@property (nonatomic, readonly) BOOL shouldAutorotateDefaultValue;\n\n\n@end\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/src/ios/CDVViewController+SplashScreen.m",
    "content": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements.  See the NOTICE file\n distributed with this work for additional information\n regarding copyright ownership.  The ASF licenses this file\n to you under the Apache License, Version 2.0 (the\n \"License\"); you may not use this file except in compliance\n with the License.  You may obtain a copy of the License at\n \n http://www.apache.org/licenses/LICENSE-2.0\n \n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an\n \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n KIND, either express or implied.  See the License for the\n specific language governing permissions and limitations\n under the License.\n */\n\n#import \"CDVViewController+SplashScreen.h\"\n#import <objc/runtime.h>\n\n@implementation CDVViewController (SplashScreen)\n\n@dynamic enabledAutorotation;\n\n- (void)setEnabledAutorotation:(BOOL)value\n{\n    objc_setAssociatedObject(self,\n                             @selector(enabledAutorotation),\n                             [NSNumber numberWithBool:value],\n                             OBJC_ASSOCIATION_RETAIN_NONATOMIC);\n}\n\n- (BOOL)enabledAutorotation\n{\n    NSNumber *number =  (NSNumber *)objc_getAssociatedObject(self, @selector(enabledAutorotation));\n    return [number boolValue];\n}\n\n+ (void)load\n{\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        Class class = [self class];\n        \n        SEL originalSelector = @selector(shouldAutorotate);\n        SEL swizzledSelector = @selector(splash_shouldAutorotate);\n        \n        Method originalMethod = class_getInstanceMethod(class, originalSelector);\n        Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);\n        \n        BOOL didAddMethod = class_addMethod(class,\n                                            originalSelector,\n                                            method_getImplementation(swizzledMethod),\n                                            method_getTypeEncoding(swizzledMethod));\n        \n        if (didAddMethod) {\n            class_replaceMethod(class,\n                                swizzledSelector,\n                                method_getImplementation(originalMethod),\n                                method_getTypeEncoding(originalMethod));\n        } else {\n            method_exchangeImplementations(originalMethod, swizzledMethod);\n        }\n    });\n}\n\n#pragma mark - Method Swizzling\n\n- (BOOL)splash_shouldAutorotate\n{\n    return self.enabledAutorotation;\n}\n\n\n- (BOOL)shouldAutorotateDefaultValue\n{\n    return [self splash_shouldAutorotate];\n}\n\n@end\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/src/tizen/SplashScreenProxy.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n( function() {\n\nwin = null;\n\nmodule.exports = {\n    show: function() {\n        if ( win === null ) {\n            win = window.open('splashscreen.html');\n        }\n    },\n\n    hide: function() {\n        if ( win !== null ) {\n            win.close();\n            win = null;\n        }\n    }\n};\n\nrequire(\"cordova/tizen/commandProxy\").add(\"SplashScreen\", module.exports);\n\n})();\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/src/ubuntu/splashscreen.cpp",
    "content": "/*\n *\n * Copyright 2013 Canonical Ltd.\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n#include <QQuickItem>\n\n#include \"splashscreen.h\"\n#include <cordova.h>\n\n#define SPLASHSCREEN_STATE_NAME \"splashscreen\"\n\nSplashscreen::Splashscreen(Cordova *cordova): CPlugin(cordova) {\n}\n\nvoid Splashscreen::show(int, int) {\n    m_cordova->rootObject()->setProperty(\"splashscreenPath\", m_cordova->getSplashscreenPath());\n\n    m_cordova->pushViewState(SPLASHSCREEN_STATE_NAME);\n}\n\nvoid Splashscreen::hide(int, int) {\n    m_cordova->popViewState(SPLASHSCREEN_STATE_NAME);\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/src/ubuntu/splashscreen.h",
    "content": "/*\n *\n * Copyright 2013 Canonical Ltd.\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n#ifndef SPLASHSCREEN_H\n#define SPLASHSCREEN_H\n\n#include <QtCore>\n#include <cplugin.h>\n\nclass Splashscreen: public CPlugin {\n    Q_OBJECT\npublic:\n    explicit Splashscreen(Cordova *cordova);\n\n    virtual const QString fullName() override {\n        return Splashscreen::fullID();\n    }\n\n    virtual const QString shortName() override {\n        return \"SplashScreen\";\n    }\n\n    static const QString fullID() {\n        return \"SplashScreen\";\n    }\n\npublic slots:\n    void show(int, int);\n    void hide(int, int);\n};\n\n#endif // SPLASHSCREEN_H\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/src/wp/ResolutionHelper.cs",
    "content": "/*\n    Licensed under the Apache License, Version 2.0 (the \"License\");\n    you may not use this file except in compliance with the License.\n    You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing, software\n    distributed under the License is distributed on an \"AS IS\" BASIS,\n    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n    See the License for the specific language governing permissions and\n    limitations under the License.\n*/\n\nusing Microsoft.Phone.Info;\nusing System;\nusing System.Windows;\n\nnamespace WPCordovaClassLib.Cordova.Commands\n{\n    public enum Resolutions { WVGA, WXGA, HD };\n\n    public static class ResolutionHelper\n    { \n       public static Resolutions CurrentResolution\n        {\n            get\n            {\n                switch (Application.Current.Host.Content.ScaleFactor) \n                {\n                    case 100: return Resolutions.WVGA;\n                    case 160: return Resolutions.WXGA;\n                    case 150: return Resolutions.HD;\n                }\n                throw new InvalidOperationException(\"Unknown resolution\");\n            }\n        }\n    }\n}"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/src/wp/SplashScreen.cs",
    "content": "/*\n    Licensed under the Apache License, Version 2.0 (the \"License\");\n    you may not use this file except in compliance with the License.\n    You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing, software\n    distributed under the License is distributed on an \"AS IS\" BASIS,\n    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n    See the License for the specific language governing permissions and\n    limitations under the License.\n*/\n\nusing System;\nusing System.Net;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Documents;\nusing System.Windows.Ink;\nusing System.Windows.Input;\nusing System.Windows.Media;\nusing System.Windows.Media.Animation;\nusing System.Windows.Shapes;\nusing Microsoft.Phone.Info;\nusing System.Windows.Controls.Primitives;\nusing System.Diagnostics;\nusing System.Windows.Media.Imaging;\nusing System.Windows.Resources;\nusing System.IO;\nusing System.Xml.Linq;\nusing System.Linq;\nusing System.Windows.Threading;\n\nnamespace WPCordovaClassLib.Cordova.Commands\n{\n    /// <summary>\n    /// Listens for changes to the state of the battery on the device.\n    /// Currently only the \"isPlugged\" parameter available via native APIs.\n    /// </summary>\n    public class SplashScreen : BaseCommand\n    {\n        private Popup popup;\n\n        // Time until we dismiss the splashscreen\n        private int prefDelay = 3000;\n\n        // Whether we hide it by default\n        private bool prefAutoHide = true;\n\n        // Path to image to use\n        private string prefImagePath = \"SplashScreenImage.jpg\";\n\n        // static because autodismiss is only ever applied once, at app launch\n        // subsequent page loads should not cause the SplashScreen to be shown.\n        private static bool WasShown = false;\n\n        public SplashScreen()\n        {\n            LoadConfigPrefs();\n\n            Image SplashScreen = new Image()\n            {\n                Height = Application.Current.Host.Content.ActualHeight,\n                Width = Application.Current.Host.Content.ActualWidth,\n                Stretch = Stretch.Fill\n            };\n\n            var imageResource = GetSplashScreenImageResource();\n            if (imageResource != null)\n            {\n                BitmapImage splash_image = new BitmapImage();\n                splash_image.SetSource(imageResource.Stream);\n                SplashScreen.Source = splash_image;\n            }\n\n            // Instansiate the popup and set the Child property of Popup to SplashScreen\n            popup = new Popup() { IsOpen = false,\n                                  Child = SplashScreen,\n                                  HorizontalAlignment = HorizontalAlignment.Stretch,\n                                  VerticalAlignment = VerticalAlignment.Center\n\n            };\n        }\n\n        public override void OnInit()\n        {\n            // we only want to autoload on the first page load.\n            // but OnInit is called for every page load.\n            if (!SplashScreen.WasShown)\n            {\n                SplashScreen.WasShown = true;\n                show();\n            }\n        }\n\n        private void LoadConfigPrefs()\n        {\n            StreamResourceInfo streamInfo = Application.GetResourceStream(new Uri(\"config.xml\", UriKind.Relative));\n            if (streamInfo != null)\n            {\n                using (StreamReader sr = new StreamReader(streamInfo.Stream))\n                {\n                    //This will Read Keys Collection for the xml file\n                    XDocument configFile = XDocument.Parse(sr.ReadToEnd());\n\n                    string configAutoHide = configFile.Descendants()\n                                        .Where(x => (string)x.Attribute(\"name\") == \"AutoHideSplashScreen\")\n                                        .Select(x => (string)x.Attribute(\"value\"))\n                                        .FirstOrDefault();\n\n                    bool bVal;\n                    prefAutoHide = bool.TryParse(configAutoHide, out bVal) ? bVal : prefAutoHide;\n\n                    string configDelay = configFile.Descendants()\n                                      .Where(x => (string)x.Attribute(\"name\") == \"SplashScreenDelay\")\n                                      .Select(x => (string)x.Attribute(\"value\"))\n                                      .FirstOrDefault();\n                    int nVal;\n                    prefDelay = int.TryParse(configDelay, out nVal) ? nVal : prefDelay;\n\n                    string configImage = configFile.Descendants()\n                                        .Where(x => (string)x.Attribute(\"name\") == \"SplashScreen\")\n                                        .Select(x => (string)x.Attribute(\"value\"))\n                                        .FirstOrDefault();\n\n                    if (!String.IsNullOrEmpty(configImage))\n                    {\n                        prefImagePath = configImage;\n                    }\n                }\n            }\n        }\n\n        private StreamResourceInfo GetSplashScreenImageResource()\n        {\n            // Get the base filename for the splash screen images\n            string imageName = System.IO.Path.GetFileNameWithoutExtension(prefImagePath);\n            Uri imageUri = null;\n            StreamResourceInfo imageResource = null;\n\n            // First, try to get a resolution-specific splashscreen\n            try\n            {\n                // Determine the device's resolution\n                switch (ResolutionHelper.CurrentResolution)\n                {\n                    case Resolutions.HD:\n                        imageUri = new Uri(imageName + \".screen-720p.jpg\", UriKind.Relative);\n                        break;\n\n                    case Resolutions.WVGA:\n                        imageUri = new Uri(imageName + \".screen-WVGA.jpg\", UriKind.Relative);\n                        break;\n\n                    case Resolutions.WXGA:\n                    default:\n                        imageUri = new Uri(imageName + \".screen-WXGA.jpg\", UriKind.Relative);\n                        break;\n                }\n\n                imageResource = Application.GetResourceStream(imageUri);\n            }\n            catch (Exception)\n            {\n                // It's OK if we didn't get a resolution-specific image\n            }\n\n            // Fallback to the default image name without decoration\n            if (imageResource == null)\n            {\n                imageUri = new Uri(prefImagePath, UriKind.Relative);\n                imageResource = Application.GetResourceStream(imageUri);\n            }\n\n            if (imageUri != null) Debug.WriteLine(\"INFO :: SplashScreen: using image {0}\", imageUri.OriginalString);\n\n            return imageResource;\n        }\n\n        public void show(string options = null)\n        {\n            Deployment.Current.Dispatcher.BeginInvoke(() =>\n            {\n                if (!popup.IsOpen)\n                {\n                    popup.Child.Opacity = 0;\n\n                    Storyboard story = new Storyboard();\n                    DoubleAnimation animation = new DoubleAnimation()\n                                                    {\n                                                        From = 0.0,\n                                                        To = 1.0,\n                                                        Duration = new Duration(TimeSpan.FromSeconds(0.2))\n                                                    };\n\n                    Storyboard.SetTarget(animation, popup.Child);\n                    Storyboard.SetTargetProperty(animation, new PropertyPath(\"Opacity\"));\n                    story.Children.Add(animation);\n\n                    story.Begin();\n\n                    popup.IsOpen = true;\n\n                    if (prefAutoHide)\n                    {\n                        StartAutoHideTimer();\n                    }\n                }\n            });\n        }\n\n        public void hide(string options = null)\n        {\n            Deployment.Current.Dispatcher.BeginInvoke(() =>\n            {\n                if (popup.IsOpen)\n                {\n                    popup.Child.Opacity = 1.0;\n\n                    Storyboard story = new Storyboard();\n                    DoubleAnimation animation = new DoubleAnimation()\n                                                    {\n                                                        From = 1.0,\n                                                        To = 0.0,\n                                                        Duration = new Duration(TimeSpan.FromSeconds(0.4))\n                                                    };\n\n                    Storyboard.SetTarget(animation, popup.Child);\n                    Storyboard.SetTargetProperty(animation, new PropertyPath(\"Opacity\"));\n                    story.Children.Add(animation);\n                    story.Completed += (object sender, EventArgs e) =>\n                    {\n                        popup.IsOpen = false;\n                    };\n                    story.Begin();\n                }\n            });\n        }\n\n        private void StartAutoHideTimer()\n        {\n            var timer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(prefDelay) };\n            timer.Tick += (object sender, EventArgs e) =>\n            {\n                hide();\n                timer.Stop();\n            };\n            timer.Start();\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest/.npmignore",
    "content": "build"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest/CDVSplashScreenLibTests/ImageNameTest.m",
    "content": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements.  See the NOTICE file\n distributed with this work for additional information\n regarding copyright ownership.  The ASF licenses this file\n to you under the Apache License, Version 2.0 (the\n \"License\"); you may not use this file except in compliance\n with the License.  You may obtain a copy of the License at\n \n http://www.apache.org/licenses/LICENSE-2.0\n \n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an\n \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n KIND, either express or implied.  See the License for the\n specific language governing permissions and limitations\n under the License.\n */\n\n#import <UIKit/UIKit.h>\n#import <XCTest/XCTest.h>\n#import <Cordova/CDVScreenOrientationDelegate.h>\n#import \"CDVSplashScreen.h\"\n#import \"ImageNameTestDelegates.h\"\n\nconst CDV_iOSDevice CDV_iOSDeviceZero = { 0, 0, 0, 0, 0, 0 };\n\n@interface ImageNameTest : XCTestCase\n\n@property (nonatomic, strong) CDVSplashScreen* plugin;\n\n@end\n\n@interface CDVSplashScreen ()\n\n// expose private interface\n- (NSString*)getImageName:(UIInterfaceOrientation)currentOrientation delegate:(id<CDVScreenOrientationDelegate>)orientationDelegate device:(CDV_iOSDevice)device;\n\n@end\n\n@implementation ImageNameTest\n\n- (void)setUp {\n    [super setUp];\n    // Put setup code here. This method is called before the invocation of each test method in the class.\n    \n    self.plugin = [[CDVSplashScreen alloc] init];\n}\n\n- (void)tearDown {\n    // Put teardown code here. This method is called after the invocation of each test method in the class.\n    [super tearDown];\n}\n\n- (void) orientationHelper:(id<CDVScreenOrientationDelegate>)delegate expectedImageNameDictionary:(NSDictionary*)expectedImageNameDictionary device:(CDV_iOSDevice)device{\n    \n    NSString* name = nil;\n    NSString* expectedImageName = nil;\n    UIInterfaceOrientation currentOrientation;\n    NSString* deviceName = device.iPad? @\"iPad\" : device.iPhone6Plus? @\"iPhone6Plus\": device.iPhone6? @\"iPhone6\": device.iPhone5? @\"iPhone5\" : @\"iPhone\";\n    \n    // LandscapeLeft, should always return expectedImageName\n    currentOrientation = UIInterfaceOrientationLandscapeLeft;\n    name = [self.plugin getImageName:currentOrientation delegate:delegate device:device];\n    expectedImageName = [expectedImageNameDictionary objectForKey:@\"landscapeLeft\"];\n    XCTAssertTrue([expectedImageName isEqualToString:name], @\"%@ - %@ failed (%@)\", @\"Landscape\", deviceName, name);\n    \n    // LandscapeRight - should always return expectedImageName\n    currentOrientation = UIInterfaceOrientationLandscapeRight;\n    name = [self.plugin getImageName:currentOrientation delegate:delegate device:device];\n    expectedImageName = [expectedImageNameDictionary objectForKey:@\"landscapeRight\"];\n    XCTAssertTrue([expectedImageName isEqualToString:name], @\"%@ - %@ failed (%@)\", @\"Landscape\", deviceName, name);\n    \n    // Portrait - should always return expectedImageName\n    currentOrientation = UIInterfaceOrientationPortrait;\n    name = [self.plugin getImageName:currentOrientation delegate:delegate device:device];\n    expectedImageName = [expectedImageNameDictionary objectForKey:@\"portrait\"];\n    XCTAssertTrue([expectedImageName isEqualToString:name], @\"%@ - %@ failed (%@)\", @\"Portrait\", deviceName, name);\n    \n    // PortraitUpsideDown - should always return expectedImageName\n    currentOrientation = UIInterfaceOrientationPortraitUpsideDown;\n    name = [self.plugin getImageName:currentOrientation delegate:delegate device:device];\n    expectedImageName = [expectedImageNameDictionary objectForKey:@\"portraitUpsideDown\"];\n    XCTAssertTrue([expectedImageName isEqualToString:name], @\"%@ - %@ failed (%@)\", @\"Portrait\", deviceName, name);\n}\n\n- (void)testiPadOrientation {\n    \n    CDV_iOSDevice device = CDV_iOSDeviceZero;\n    device.iPad = YES;\n    \n    // One orientation\n    \n    PortraitOnly* delegate = [[PortraitOnly alloc] init];\n    [self orientationHelper:delegate expectedImageNameDictionary:@{\n                                                                    @\"landscapeLeft\" : @\"Default-Portrait\",\n                                                                    @\"landscapeRight\" : @\"Default-Portrait\",\n                                                                    @\"portrait\" : @\"Default-Portrait\",\n                                                                    @\"portraitUpsideDown\" : @\"Default-Portrait\"\n                                                                    }\n                     device:device];\n    \n    PortraitUpsideDownOnly* delegate2 = [[PortraitUpsideDownOnly alloc] init];\n    [self orientationHelper:delegate2 expectedImageNameDictionary:@{\n                                                                   @\"landscapeLeft\" : @\"Default-Portrait\",\n                                                                   @\"landscapeRight\" : @\"Default-Portrait\",\n                                                                   @\"portrait\" : @\"Default-Portrait\",\n                                                                   @\"portraitUpsideDown\" : @\"Default-Portrait\"\n                                                                   }\n                     device:device];\n    \n    LandscapeLeftOnly* delegate3 = [[LandscapeLeftOnly alloc] init];\n    [self orientationHelper:delegate3 expectedImageNameDictionary:@{\n                                                                   @\"landscapeLeft\" : @\"Default-Landscape\",\n                                                                   @\"landscapeRight\" : @\"Default-Landscape\",\n                                                                   @\"portrait\" : @\"Default-Landscape\",\n                                                                   @\"portraitUpsideDown\" : @\"Default-Landscape\"\n                                                                   }\n                     device:device];\n    \n    LandscapeRightOnly* delegate4 = [[LandscapeRightOnly alloc] init];\n    [self orientationHelper:delegate4 expectedImageNameDictionary:@{\n                                                                    @\"landscapeLeft\" : @\"Default-Landscape\",\n                                                                    @\"landscapeRight\" : @\"Default-Landscape\",\n                                                                    @\"portrait\" : @\"Default-Landscape\",\n                                                                    @\"portraitUpsideDown\" : @\"Default-Landscape\"\n                                                                    }\n                     device:device];\n\n    // All Portrait\n\n    AllPortraitOnly* delegate5 = [[AllPortraitOnly alloc] init];\n    [self orientationHelper:delegate5 expectedImageNameDictionary:@{\n                                                                    @\"landscapeLeft\" : @\"Default-Portrait\",\n                                                                    @\"landscapeRight\" : @\"Default-Portrait\",\n                                                                    @\"portrait\" : @\"Default-Portrait\",\n                                                                    @\"portraitUpsideDown\" : @\"Default-Portrait\"\n                                                                    }\n                     device:device];\n\n    // All Landscape\n    \n    AllLandscapeOnly* delegate6 = [[AllLandscapeOnly alloc] init];\n    [self orientationHelper:delegate6 expectedImageNameDictionary:@{\n                                                                    @\"landscapeLeft\" : @\"Default-Landscape\",\n                                                                    @\"landscapeRight\" : @\"Default-Landscape\",\n                                                                    @\"portrait\" : @\"Default-Landscape\",\n                                                                    @\"portraitUpsideDown\" : @\"Default-Landscape\"\n                                                                    }\n                     device:device];\n    \n    \n    // All orientations\n    \n    AllOrientations* delegate7 = [[AllOrientations alloc] init];\n    [self orientationHelper:delegate7 expectedImageNameDictionary:@{\n                                                                    @\"landscapeLeft\" : @\"Default-Landscape\",\n                                                                    @\"landscapeRight\" : @\"Default-Landscape\",\n                                                                    @\"portrait\" : @\"Default-Portrait\",\n                                                                    @\"portraitUpsideDown\" : @\"Default-Portrait\"\n                                                                    }\n                     device:device];\n\n    // Portrait and Landscape Left\n    \n    PortraitAndLandscapeLeftOnly* delegate8 = [[PortraitAndLandscapeLeftOnly alloc] init];\n    [self orientationHelper:delegate8 expectedImageNameDictionary:@{\n                                                                    @\"landscapeLeft\" : @\"Default-Landscape\",\n                                                                    @\"landscapeRight\" : @\"Default-Landscape\",\n                                                                    @\"portrait\" : @\"Default-Portrait\",\n                                                                    @\"portraitUpsideDown\" : @\"Default-Portrait\"\n                                                                    }\n                     device:device];\n\n    // Portrait and Landscape Right\n    \n    PortraitAndLandscapeRightOnly* delegate9 = [[PortraitAndLandscapeRightOnly alloc] init];\n    [self orientationHelper:delegate9 expectedImageNameDictionary:@{\n                                                                    @\"landscapeLeft\" : @\"Default-Landscape\",\n                                                                    @\"landscapeRight\" : @\"Default-Landscape\",\n                                                                    @\"portrait\" : @\"Default-Portrait\",\n                                                                    @\"portraitUpsideDown\" : @\"Default-Portrait\"\n                                                                    }\n                     device:device];\n\n    // PortraitUpsideDown and Landscape Left\n    \n    PortraitUpsideDownAndLandscapeLeftOnly* delegate10 = [[PortraitUpsideDownAndLandscapeLeftOnly alloc] init];\n    [self orientationHelper:delegate10 expectedImageNameDictionary:@{\n                                                                    @\"landscapeLeft\" : @\"Default-Landscape\",\n                                                                    @\"landscapeRight\" : @\"Default-Landscape\",\n                                                                    @\"portrait\" : @\"Default-Portrait\",\n                                                                    @\"portraitUpsideDown\" : @\"Default-Portrait\"\n                                                                    }\n                     device:device];\n\n    // PortraitUpsideDown and Landscape Right\n    \n    PortraitUpsideDownAndLandscapeRightOnly* delegate11 = [[PortraitUpsideDownAndLandscapeRightOnly alloc] init];\n    [self orientationHelper:delegate11 expectedImageNameDictionary:@{\n                                                                     @\"landscapeLeft\" : @\"Default-Landscape\",\n                                                                     @\"landscapeRight\" : @\"Default-Landscape\",\n                                                                     @\"portrait\" : @\"Default-Portrait\",\n                                                                     @\"portraitUpsideDown\" : @\"Default-Portrait\"\n                                                                     }\n                     device:device];\n}\n\n- (void)testiPhoneOrientation {\n    \n    CDV_iOSDevice device = CDV_iOSDeviceZero;\n    device.iPhone = YES;\n    \n    // One orientation\n    \n    PortraitOnly* delegate = [[PortraitOnly alloc] init];\n    [self orientationHelper:delegate expectedImageNameDictionary:@{\n                                                                    @\"landscapeLeft\" : @\"Default\",\n                                                                    @\"landscapeRight\" : @\"Default\",\n                                                                    @\"portrait\" : @\"Default\",\n                                                                    @\"portraitUpsideDown\" : @\"Default\"\n                                                                    }\n                     device:device];\n    \n    PortraitUpsideDownOnly* delegate2 = [[PortraitUpsideDownOnly alloc] init];\n    [self orientationHelper:delegate2 expectedImageNameDictionary:@{\n                                                                    @\"landscapeLeft\" : @\"Default\",\n                                                                    @\"landscapeRight\" : @\"Default\",\n                                                                    @\"portrait\" : @\"Default\",\n                                                                    @\"portraitUpsideDown\" : @\"Default\"\n                                                                    }\n                     device:device];\n    \n    LandscapeLeftOnly* delegate3 = [[LandscapeLeftOnly alloc] init];\n    [self orientationHelper:delegate3 expectedImageNameDictionary:@{\n                                                                    @\"landscapeLeft\" : @\"Default\",\n                                                                    @\"landscapeRight\" : @\"Default\",\n                                                                    @\"portrait\" : @\"Default\",\n                                                                    @\"portraitUpsideDown\" : @\"Default\"\n                                                                    }\n                     device:device];\n    \n    LandscapeRightOnly* delegate4 = [[LandscapeRightOnly alloc] init];\n    [self orientationHelper:delegate4 expectedImageNameDictionary:@{\n                                                                    @\"landscapeLeft\" : @\"Default\",\n                                                                    @\"landscapeRight\" : @\"Default\",\n                                                                    @\"portrait\" : @\"Default\",\n                                                                    @\"portraitUpsideDown\" : @\"Default\"\n                                                                    }\n                     device:device];\n    \n    // All Portrait\n    \n    AllPortraitOnly* delegate5 = [[AllPortraitOnly alloc] init];\n    [self orientationHelper:delegate5 expectedImageNameDictionary:@{\n                                                                    @\"landscapeLeft\" : @\"Default\",\n                                                                    @\"landscapeRight\" : @\"Default\",\n                                                                    @\"portrait\" : @\"Default\",\n                                                                    @\"portraitUpsideDown\" : @\"Default\"\n                                                                    }\n                     device:device];\n    \n    // All Landscape\n    \n    AllLandscapeOnly* delegate6 = [[AllLandscapeOnly alloc] init];\n    [self orientationHelper:delegate6 expectedImageNameDictionary:@{\n                                                                    @\"landscapeLeft\" : @\"Default\",\n                                                                    @\"landscapeRight\" : @\"Default\",\n                                                                    @\"portrait\" : @\"Default\",\n                                                                    @\"portraitUpsideDown\" : @\"Default\"\n                                                                    }\n                     device:device];\n    \n    \n    // All orientations\n    \n    AllOrientations* delegate7 = [[AllOrientations alloc] init];\n    [self orientationHelper:delegate7 expectedImageNameDictionary:@{\n                                                                    @\"landscapeLeft\" : @\"Default\",\n                                                                    @\"landscapeRight\" : @\"Default\",\n                                                                    @\"portrait\" : @\"Default\",\n                                                                    @\"portraitUpsideDown\" : @\"Default\"\n                                                                    }\n                     device:device];\n    \n    // Portrait and Landscape Left\n    \n    PortraitAndLandscapeLeftOnly* delegate8 = [[PortraitAndLandscapeLeftOnly alloc] init];\n    [self orientationHelper:delegate8 expectedImageNameDictionary:@{\n                                                                    @\"landscapeLeft\" : @\"Default\",\n                                                                    @\"landscapeRight\" : @\"Default\",\n                                                                    @\"portrait\" : @\"Default\",\n                                                                    @\"portraitUpsideDown\" : @\"Default\"\n                                                                    }\n                     device:device];\n    \n    // Portrait and Landscape Right\n    \n    PortraitAndLandscapeRightOnly* delegate9 = [[PortraitAndLandscapeRightOnly alloc] init];\n    [self orientationHelper:delegate9 expectedImageNameDictionary:@{\n                                                                    @\"landscapeLeft\" : @\"Default\",\n                                                                    @\"landscapeRight\" : @\"Default\",\n                                                                    @\"portrait\" : @\"Default\",\n                                                                    @\"portraitUpsideDown\" : @\"Default\"\n                                                                    }\n                     device:device];\n    \n    // PortraitUpsideDown and Landscape Left\n    \n    PortraitUpsideDownAndLandscapeLeftOnly* delegate10 = [[PortraitUpsideDownAndLandscapeLeftOnly alloc] init];\n    [self orientationHelper:delegate10 expectedImageNameDictionary:@{\n                                                                     @\"landscapeLeft\" : @\"Default\",\n                                                                     @\"landscapeRight\" : @\"Default\",\n                                                                     @\"portrait\" : @\"Default\",\n                                                                     @\"portraitUpsideDown\" : @\"Default\"\n                                                                     }\n                     device:device];\n    \n    // PortraitUpsideDown and Landscape Right\n    \n    PortraitUpsideDownAndLandscapeRightOnly* delegate11 = [[PortraitUpsideDownAndLandscapeRightOnly alloc] init];\n    [self orientationHelper:delegate11 expectedImageNameDictionary:@{\n                                                                     @\"landscapeLeft\" : @\"Default\",\n                                                                     @\"landscapeRight\" : @\"Default\",\n                                                                     @\"portrait\" : @\"Default\",\n                                                                     @\"portraitUpsideDown\" : @\"Default\"\n                                                                     }\n                     device:device];\n}\n\n- (void)testiPhone5Orientation {\n    \n    CDV_iOSDevice device = CDV_iOSDeviceZero;\n    device.iPhone = YES;\n    device.iPhone5 = YES;\n    \n    // One orientation\n    \n    PortraitOnly* delegate = [[PortraitOnly alloc] init];\n    [self orientationHelper:delegate expectedImageNameDictionary:@{\n                                                                   @\"landscapeLeft\" : @\"Default-568h\",\n                                                                   @\"landscapeRight\" : @\"Default-568h\",\n                                                                   @\"portrait\" : @\"Default-568h\",\n                                                                   @\"portraitUpsideDown\" : @\"Default-568h\"\n                                                                   }\n                     device:device];\n    \n    PortraitUpsideDownOnly* delegate2 = [[PortraitUpsideDownOnly alloc] init];\n    [self orientationHelper:delegate2 expectedImageNameDictionary:@{\n                                                                    @\"landscapeLeft\" : @\"Default-568h\",\n                                                                    @\"landscapeRight\" : @\"Default-568h\",\n                                                                    @\"portrait\" : @\"Default-568h\",\n                                                                    @\"portraitUpsideDown\" : @\"Default-568h\"\n                                                                    }\n                     device:device];\n    \n    LandscapeLeftOnly* delegate3 = [[LandscapeLeftOnly alloc] init];\n    [self orientationHelper:delegate3 expectedImageNameDictionary:@{\n                                                                    @\"landscapeLeft\" : @\"Default-568h\",\n                                                                    @\"landscapeRight\" : @\"Default-568h\",\n                                                                    @\"portrait\" : @\"Default-568h\",\n                                                                    @\"portraitUpsideDown\" : @\"Default-568h\"\n                                                                    }\n                     device:device];\n    \n    LandscapeRightOnly* delegate4 = [[LandscapeRightOnly alloc] init];\n    [self orientationHelper:delegate4 expectedImageNameDictionary:@{\n                                                                    @\"landscapeLeft\" : @\"Default-568h\",\n                                                                    @\"landscapeRight\" : @\"Default-568h\",\n                                                                    @\"portrait\" : @\"Default-568h\",\n                                                                    @\"portraitUpsideDown\" : @\"Default-568h\"\n                                                                    }\n                     device:device];\n    \n    // All Portrait\n    \n    AllPortraitOnly* delegate5 = [[AllPortraitOnly alloc] init];\n    [self orientationHelper:delegate5 expectedImageNameDictionary:@{\n                                                                    @\"landscapeLeft\" : @\"Default-568h\",\n                                                                    @\"landscapeRight\" : @\"Default-568h\",\n                                                                    @\"portrait\" : @\"Default-568h\",\n                                                                    @\"portraitUpsideDown\" : @\"Default-568h\"\n                                                                    }\n                     device:device];\n    \n    // All Landscape\n    \n    AllLandscapeOnly* delegate6 = [[AllLandscapeOnly alloc] init];\n    [self orientationHelper:delegate6 expectedImageNameDictionary:@{\n                                                                    @\"landscapeLeft\" : @\"Default-568h\",\n                                                                    @\"landscapeRight\" : @\"Default-568h\",\n                                                                    @\"portrait\" : @\"Default-568h\",\n                                                                    @\"portraitUpsideDown\" : @\"Default-568h\"\n                                                                    }\n                     device:device];\n    \n    \n    // All orientations\n    \n    AllOrientations* delegate7 = [[AllOrientations alloc] init];\n    [self orientationHelper:delegate7 expectedImageNameDictionary:@{\n                                                                    @\"landscapeLeft\" : @\"Default-568h\",\n                                                                    @\"landscapeRight\" : @\"Default-568h\",\n                                                                    @\"portrait\" : @\"Default-568h\",\n                                                                    @\"portraitUpsideDown\" : @\"Default-568h\"\n                                                                    }\n                     device:device];\n    \n    // Portrait and Landscape Left\n    \n    PortraitAndLandscapeLeftOnly* delegate8 = [[PortraitAndLandscapeLeftOnly alloc] init];\n    [self orientationHelper:delegate8 expectedImageNameDictionary:@{\n                                                                    @\"landscapeLeft\" : @\"Default-568h\",\n                                                                    @\"landscapeRight\" : @\"Default-568h\",\n                                                                    @\"portrait\" : @\"Default-568h\",\n                                                                    @\"portraitUpsideDown\" : @\"Default-568h\"\n                                                                    }\n                     device:device];\n    \n    // Portrait and Landscape Right\n    \n    PortraitAndLandscapeRightOnly* delegate9 = [[PortraitAndLandscapeRightOnly alloc] init];\n    [self orientationHelper:delegate9 expectedImageNameDictionary:@{\n                                                                    @\"landscapeLeft\" : @\"Default-568h\",\n                                                                    @\"landscapeRight\" : @\"Default-568h\",\n                                                                    @\"portrait\" : @\"Default-568h\",\n                                                                    @\"portraitUpsideDown\" : @\"Default-568h\"\n                                                                    }\n                     device:device];\n    \n    // PortraitUpsideDown and Landscape Left\n    \n    PortraitUpsideDownAndLandscapeLeftOnly* delegate10 = [[PortraitUpsideDownAndLandscapeLeftOnly alloc] init];\n    [self orientationHelper:delegate10 expectedImageNameDictionary:@{\n                                                                     @\"landscapeLeft\" : @\"Default-568h\",\n                                                                     @\"landscapeRight\" : @\"Default-568h\",\n                                                                     @\"portrait\" : @\"Default-568h\",\n                                                                     @\"portraitUpsideDown\" : @\"Default-568h\"\n                                                                     }\n                     device:device];\n    \n    // PortraitUpsideDown and Landscape Right\n    \n    PortraitUpsideDownAndLandscapeRightOnly* delegate11 = [[PortraitUpsideDownAndLandscapeRightOnly alloc] init];\n    [self orientationHelper:delegate11 expectedImageNameDictionary:@{\n                                                                     @\"landscapeLeft\" : @\"Default-568h\",\n                                                                     @\"landscapeRight\" : @\"Default-568h\",\n                                                                     @\"portrait\" : @\"Default-568h\",\n                                                                     @\"portraitUpsideDown\" : @\"Default-568h\"\n                                                                     }\n                     device:device];\n}\n\n- (void)testiPhone6Orientation {\n    \n    CDV_iOSDevice device = CDV_iOSDeviceZero;\n    device.iPhone = YES;\n    device.iPhone6 = YES;\n    \n    // One orientation\n    \n    PortraitOnly* delegate = [[PortraitOnly alloc] init];\n    [self orientationHelper:delegate expectedImageNameDictionary:@{\n                                                                   @\"landscapeLeft\" : @\"Default-667h\",\n                                                                   @\"landscapeRight\" : @\"Default-667h\",\n                                                                   @\"portrait\" : @\"Default-667h\",\n                                                                   @\"portraitUpsideDown\" : @\"Default-667h\"\n                                                                   }\n                     device:device];\n    \n    PortraitUpsideDownOnly* delegate2 = [[PortraitUpsideDownOnly alloc] init];\n    [self orientationHelper:delegate2 expectedImageNameDictionary:@{\n                                                                    @\"landscapeLeft\" : @\"Default-667h\",\n                                                                    @\"landscapeRight\" : @\"Default-667h\",\n                                                                    @\"portrait\" : @\"Default-667h\",\n                                                                    @\"portraitUpsideDown\" : @\"Default-667h\"\n                                                                    }\n                     device:device];\n    \n    LandscapeLeftOnly* delegate3 = [[LandscapeLeftOnly alloc] init];\n    [self orientationHelper:delegate3 expectedImageNameDictionary:@{\n                                                                    @\"landscapeLeft\" : @\"Default-667h\",\n                                                                    @\"landscapeRight\" : @\"Default-667h\",\n                                                                    @\"portrait\" : @\"Default-667h\",\n                                                                    @\"portraitUpsideDown\" : @\"Default-667h\"\n                                                                    }\n                     device:device];\n    \n    LandscapeRightOnly* delegate4 = [[LandscapeRightOnly alloc] init];\n    [self orientationHelper:delegate4 expectedImageNameDictionary:@{\n                                                                    @\"landscapeLeft\" : @\"Default-667h\",\n                                                                    @\"landscapeRight\" : @\"Default-667h\",\n                                                                    @\"portrait\" : @\"Default-667h\",\n                                                                    @\"portraitUpsideDown\" : @\"Default-667h\"\n                                                                    }\n                     device:device];\n    \n    // All Portrait\n    \n    AllPortraitOnly* delegate5 = [[AllPortraitOnly alloc] init];\n    [self orientationHelper:delegate5 expectedImageNameDictionary:@{\n                                                                    @\"landscapeLeft\" : @\"Default-667h\",\n                                                                    @\"landscapeRight\" : @\"Default-667h\",\n                                                                    @\"portrait\" : @\"Default-667h\",\n                                                                    @\"portraitUpsideDown\" : @\"Default-667h\"\n                                                                    }\n                     device:device];\n    \n    // All Landscape\n    \n    AllLandscapeOnly* delegate6 = [[AllLandscapeOnly alloc] init];\n    [self orientationHelper:delegate6 expectedImageNameDictionary:@{\n                                                                    @\"landscapeLeft\" : @\"Default-667h\",\n                                                                    @\"landscapeRight\" : @\"Default-667h\",\n                                                                    @\"portrait\" : @\"Default-667h\",\n                                                                    @\"portraitUpsideDown\" : @\"Default-667h\"\n                                                                    }\n                     device:device];\n    \n    \n    // All orientations\n    \n    AllOrientations* delegate7 = [[AllOrientations alloc] init];\n    [self orientationHelper:delegate7 expectedImageNameDictionary:@{\n                                                                    @\"landscapeLeft\" : @\"Default-667h\",\n                                                                    @\"landscapeRight\" : @\"Default-667h\",\n                                                                    @\"portrait\" : @\"Default-667h\",\n                                                                    @\"portraitUpsideDown\" : @\"Default-667h\"\n                                                                    }\n                     device:device];\n    \n    // Portrait and Landscape Left\n    \n    PortraitAndLandscapeLeftOnly* delegate8 = [[PortraitAndLandscapeLeftOnly alloc] init];\n    [self orientationHelper:delegate8 expectedImageNameDictionary:@{\n                                                                    @\"landscapeLeft\" : @\"Default-667h\",\n                                                                    @\"landscapeRight\" : @\"Default-667h\",\n                                                                    @\"portrait\" : @\"Default-667h\",\n                                                                    @\"portraitUpsideDown\" : @\"Default-667h\"\n                                                                    }\n                     device:device];\n    \n    // Portrait and Landscape Right\n    \n    PortraitAndLandscapeRightOnly* delegate9 = [[PortraitAndLandscapeRightOnly alloc] init];\n    [self orientationHelper:delegate9 expectedImageNameDictionary:@{\n                                                                    @\"landscapeLeft\" : @\"Default-667h\",\n                                                                    @\"landscapeRight\" : @\"Default-667h\",\n                                                                    @\"portrait\" : @\"Default-667h\",\n                                                                    @\"portraitUpsideDown\" : @\"Default-667h\"\n                                                                    }\n                     device:device];\n    \n    // PortraitUpsideDown and Landscape Left\n    \n    PortraitUpsideDownAndLandscapeLeftOnly* delegate10 = [[PortraitUpsideDownAndLandscapeLeftOnly alloc] init];\n    [self orientationHelper:delegate10 expectedImageNameDictionary:@{\n                                                                     @\"landscapeLeft\" : @\"Default-667h\",\n                                                                     @\"landscapeRight\" : @\"Default-667h\",\n                                                                     @\"portrait\" : @\"Default-667h\",\n                                                                     @\"portraitUpsideDown\" : @\"Default-667h\"\n                                                                     }\n                     device:device];\n    \n    // PortraitUpsideDown and Landscape Right\n    \n    PortraitUpsideDownAndLandscapeRightOnly* delegate11 = [[PortraitUpsideDownAndLandscapeRightOnly alloc] init];\n    [self orientationHelper:delegate11 expectedImageNameDictionary:@{\n                                                                     @\"landscapeLeft\" : @\"Default-667h\",\n                                                                     @\"landscapeRight\" : @\"Default-667h\",\n                                                                     @\"portrait\" : @\"Default-667h\",\n                                                                     @\"portraitUpsideDown\" : @\"Default-667h\"\n                                                                     }\n                     device:device];\n}\n\n- (void)testiPhone6PlusOrientation {\n    \n    CDV_iOSDevice device = CDV_iOSDeviceZero;\n    device.iPhone = YES;\n    device.iPhone6Plus = YES;\n    \n    // One orientation\n    \n    PortraitOnly* delegate = [[PortraitOnly alloc] init];\n    [self orientationHelper:delegate expectedImageNameDictionary:@{\n                                                                   @\"landscapeLeft\" : @\"Default-736h\",\n                                                                   @\"landscapeRight\" : @\"Default-736h\",\n                                                                   @\"portrait\" : @\"Default-736h\",\n                                                                   @\"portraitUpsideDown\" : @\"Default-736h\"\n                                                                   }\n                     device:device];\n    \n    PortraitUpsideDownOnly* delegate2 = [[PortraitUpsideDownOnly alloc] init];\n    [self orientationHelper:delegate2 expectedImageNameDictionary:@{\n                                                                    @\"landscapeLeft\" : @\"Default-736h\",\n                                                                    @\"landscapeRight\" : @\"Default-736h\",\n                                                                    @\"portrait\" : @\"Default-736h\",\n                                                                    @\"portraitUpsideDown\" : @\"Default-736h\"\n                                                                    }\n                     device:device];\n    \n    LandscapeLeftOnly* delegate3 = [[LandscapeLeftOnly alloc] init];\n    [self orientationHelper:delegate3 expectedImageNameDictionary:@{\n                                                                    @\"landscapeLeft\" : @\"Default-Landscape-736h\",\n                                                                    @\"landscapeRight\" : @\"Default-Landscape-736h\",\n                                                                    @\"portrait\" : @\"Default-Landscape-736h\",\n                                                                    @\"portraitUpsideDown\" : @\"Default-Landscape-736h\"\n                                                                    }\n                     device:device];\n    \n    LandscapeRightOnly* delegate4 = [[LandscapeRightOnly alloc] init];\n    [self orientationHelper:delegate4 expectedImageNameDictionary:@{\n                                                                    @\"landscapeLeft\" : @\"Default-Landscape-736h\",\n                                                                    @\"landscapeRight\" : @\"Default-Landscape-736h\",\n                                                                    @\"portrait\" : @\"Default-Landscape-736h\",\n                                                                    @\"portraitUpsideDown\" : @\"Default-Landscape-736h\"\n                                                                    }\n                     device:device];\n    \n    // All Portrait\n    \n    AllPortraitOnly* delegate5 = [[AllPortraitOnly alloc] init];\n    [self orientationHelper:delegate5 expectedImageNameDictionary:@{\n                                                                    @\"landscapeLeft\" : @\"Default-736h\",\n                                                                    @\"landscapeRight\" : @\"Default-736h\",\n                                                                    @\"portrait\" : @\"Default-736h\",\n                                                                    @\"portraitUpsideDown\" : @\"Default-736h\"\n                                                                    }\n                     device:device];\n    \n    // All Landscape\n    \n    AllLandscapeOnly* delegate6 = [[AllLandscapeOnly alloc] init];\n    [self orientationHelper:delegate6 expectedImageNameDictionary:@{\n                                                                    @\"landscapeLeft\" : @\"Default-Landscape-736h\",\n                                                                    @\"landscapeRight\" : @\"Default-Landscape-736h\",\n                                                                    @\"portrait\" : @\"Default-Landscape-736h\",\n                                                                    @\"portraitUpsideDown\" : @\"Default-Landscape-736h\"\n                                                                    }\n                     device:device];\n    \n    \n    // All orientations\n    \n    AllOrientations* delegate7 = [[AllOrientations alloc] init];\n    [self orientationHelper:delegate7 expectedImageNameDictionary:@{\n                                                                    @\"landscapeLeft\" : @\"Default-Landscape-736h\",\n                                                                    @\"landscapeRight\" : @\"Default-Landscape-736h\",\n                                                                    @\"portrait\" : @\"Default-736h\",\n                                                                    @\"portraitUpsideDown\" : @\"Default-736h\"\n                                                                    }\n                     device:device];\n    \n    // Portrait and Landscape Left\n    \n    PortraitAndLandscapeLeftOnly* delegate8 = [[PortraitAndLandscapeLeftOnly alloc] init];\n    [self orientationHelper:delegate8 expectedImageNameDictionary:@{\n                                                                    @\"landscapeLeft\" : @\"Default-Landscape-736h\",\n                                                                    @\"landscapeRight\" : @\"Default-Landscape-736h\",\n                                                                    @\"portrait\" : @\"Default-736h\",\n                                                                    @\"portraitUpsideDown\" : @\"Default-736h\"\n                                                                    }\n                     device:device];\n    \n    // Portrait and Landscape Right\n    \n    PortraitAndLandscapeRightOnly* delegate9 = [[PortraitAndLandscapeRightOnly alloc] init];\n    [self orientationHelper:delegate9 expectedImageNameDictionary:@{\n                                                                    @\"landscapeLeft\" : @\"Default-Landscape-736h\",\n                                                                    @\"landscapeRight\" : @\"Default-Landscape-736h\",\n                                                                    @\"portrait\" : @\"Default-736h\",\n                                                                    @\"portraitUpsideDown\" : @\"Default-736h\"\n                                                                    }\n                     device:device];\n    \n    // PortraitUpsideDown and Landscape Left\n    \n    PortraitUpsideDownAndLandscapeLeftOnly* delegate10 = [[PortraitUpsideDownAndLandscapeLeftOnly alloc] init];\n    [self orientationHelper:delegate10 expectedImageNameDictionary:@{\n                                                                     @\"landscapeLeft\" : @\"Default-Landscape-736h\",\n                                                                     @\"landscapeRight\" : @\"Default-Landscape-736h\",\n                                                                     @\"portrait\" : @\"Default-736h\",\n                                                                     @\"portraitUpsideDown\" : @\"Default-736h\"\n                                                                     }\n                     device:device];\n    \n    // PortraitUpsideDown and Landscape Right\n    \n    PortraitUpsideDownAndLandscapeRightOnly* delegate11 = [[PortraitUpsideDownAndLandscapeRightOnly alloc] init];\n    [self orientationHelper:delegate11 expectedImageNameDictionary:@{\n                                                                     @\"landscapeLeft\" : @\"Default-Landscape-736h\",\n                                                                     @\"landscapeRight\" : @\"Default-Landscape-736h\",\n                                                                     @\"portrait\" : @\"Default-736h\",\n                                                                     @\"portraitUpsideDown\" : @\"Default-736h\"\n                                                                     }\n                     device:device];\n}\n\n\n\n@end\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest/CDVSplashScreenLibTests/ImageNameTestDelegates.h",
    "content": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements.  See the NOTICE file\n distributed with this work for additional information\n regarding copyright ownership.  The ASF licenses this file\n to you under the Apache License, Version 2.0 (the\n \"License\"); you may not use this file except in compliance\n with the License.  You may obtain a copy of the License at\n \n http://www.apache.org/licenses/LICENSE-2.0\n \n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an\n \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n KIND, either express or implied.  See the License for the\n specific language governing permissions and limitations\n under the License.\n */\n\n#import <Foundation/Foundation.h>\n#import <Cordova/CDVScreenOrientationDelegate.h>\n\n@interface PortraitOnly : NSObject <CDVScreenOrientationDelegate>\n@end\n\n@interface PortraitUpsideDownOnly : NSObject <CDVScreenOrientationDelegate>\n@end\n\n@interface AllPortraitOnly : NSObject <CDVScreenOrientationDelegate>\n@end\n\n\n@interface LandscapeLeftOnly : NSObject <CDVScreenOrientationDelegate>\n@end\n\n@interface LandscapeRightOnly : NSObject <CDVScreenOrientationDelegate>\n@end\n\n@interface AllLandscapeOnly : NSObject <CDVScreenOrientationDelegate>\n@end\n\n\n@interface AllOrientations : NSObject <CDVScreenOrientationDelegate>\n@end\n\n@interface PortraitAndLandscapeLeftOnly : NSObject <CDVScreenOrientationDelegate>\n@end\n\n@interface PortraitAndLandscapeRightOnly : NSObject <CDVScreenOrientationDelegate>\n@end\n\n@interface PortraitUpsideDownAndLandscapeLeftOnly : NSObject <CDVScreenOrientationDelegate>\n@end\n\n@interface PortraitUpsideDownAndLandscapeRightOnly : NSObject <CDVScreenOrientationDelegate>\n@end\n\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest/CDVSplashScreenLibTests/ImageNameTestDelegates.m",
    "content": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements.  See the NOTICE file\n distributed with this work for additional information\n regarding copyright ownership.  The ASF licenses this file\n to you under the Apache License, Version 2.0 (the\n \"License\"); you may not use this file except in compliance\n with the License.  You may obtain a copy of the License at\n \n http://www.apache.org/licenses/LICENSE-2.0\n \n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an\n \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n KIND, either express or implied.  See the License for the\n specific language governing permissions and limitations\n under the License.\n */\n\n#import <UIKit/UIKit.h>\n#import \"ImageNameTestDelegates.h\"\n\n@implementation PortraitOnly\n\n- (NSUInteger)supportedInterfaceOrientations {\n    return UIInterfaceOrientationMaskPortrait;\n}\n\n- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {\n    return [self supportedInterfaceOrientations] & (1 << interfaceOrientation) ;\n}\n\n- (BOOL)shouldAutorotate {\n    return YES;\n}\n\n@end\n\n@implementation PortraitUpsideDownOnly\n\n- (NSUInteger)supportedInterfaceOrientations {\n    return UIInterfaceOrientationMaskPortraitUpsideDown;\n}\n\n- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {\n    return [self supportedInterfaceOrientations] & (1 << interfaceOrientation) ;\n}\n\n- (BOOL)shouldAutorotate {\n    return YES;\n}\n\n@end\n\n@implementation AllPortraitOnly\n\n- (NSUInteger)supportedInterfaceOrientations {\n    return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;\n}\n\n- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {\n    return [self supportedInterfaceOrientations] & (1 << interfaceOrientation) ;\n}\n\n- (BOOL)shouldAutorotate {\n    return YES;\n}\n\n@end\n\n\n@implementation LandscapeLeftOnly\n\n- (NSUInteger)supportedInterfaceOrientations {\n    return UIInterfaceOrientationMaskLandscapeLeft;\n}\n\n- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {\n    return [self supportedInterfaceOrientations] & (1 << interfaceOrientation) ;\n}\n\n- (BOOL)shouldAutorotate {\n    return YES;\n}\n\n@end\n\n@implementation LandscapeRightOnly\n\n- (NSUInteger)supportedInterfaceOrientations {\n    return UIInterfaceOrientationMaskLandscapeRight;\n}\n\n- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {\n    return [self supportedInterfaceOrientations] & (1 << interfaceOrientation) ;\n}\n\n- (BOOL)shouldAutorotate {\n    return YES;\n}\n\n@end\n\n@implementation AllLandscapeOnly\n\n- (NSUInteger)supportedInterfaceOrientations {\n    return UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;\n}\n\n- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {\n    return [self supportedInterfaceOrientations] & (1 << interfaceOrientation) ;\n}\n\n- (BOOL)shouldAutorotate {\n    return YES;\n}\n\n@end\n\n\n@implementation AllOrientations\n\n- (NSUInteger)supportedInterfaceOrientations {\n    return UIInterfaceOrientationMaskAll;\n}\n\n- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {\n    return [self supportedInterfaceOrientations] & (1 << interfaceOrientation) ;\n}\n\n- (BOOL)shouldAutorotate {\n    return YES;\n}\n\n@end\n\n@implementation PortraitAndLandscapeLeftOnly\n\n- (NSUInteger)supportedInterfaceOrientations {\n    return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft;\n}\n\n- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {\n    return [self supportedInterfaceOrientations] & (1 << interfaceOrientation) ;\n}\n\n- (BOOL)shouldAutorotate {\n    return YES;\n}\n\n@end\n\n@implementation PortraitAndLandscapeRightOnly\n\n- (NSUInteger)supportedInterfaceOrientations {\n    return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeRight;\n}\n\n- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {\n    return [self supportedInterfaceOrientations] & (1 << interfaceOrientation) ;\n}\n\n- (BOOL)shouldAutorotate {\n    return YES;\n}\n\n@end\n\n@implementation PortraitUpsideDownAndLandscapeLeftOnly\n\n- (NSUInteger)supportedInterfaceOrientations {\n    return UIInterfaceOrientationMaskPortraitUpsideDown | UIInterfaceOrientationMaskLandscapeLeft;\n}\n\n- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {\n    return [self supportedInterfaceOrientations] & (1 << interfaceOrientation) ;\n}\n\n- (BOOL)shouldAutorotate {\n    return YES;\n}\n\n@end\n\n@implementation PortraitUpsideDownAndLandscapeRightOnly\n\n- (NSUInteger)supportedInterfaceOrientations {\n    return UIInterfaceOrientationMaskPortraitUpsideDown | UIInterfaceOrientationMaskLandscapeRight;\n}\n\n- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {\n    return [self supportedInterfaceOrientations] & (1 << interfaceOrientation) ;\n}\n\n- (BOOL)shouldAutorotate {\n    return YES;\n}\n\n@end\n\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest/CDVSplashScreenLibTests/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<!--\n#\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#  KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n#\n-->\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>en</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>org.apache.cordova.$(PRODUCT_NAME:rfc1034identifier)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>BNDL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest/CDVSplashScreenTest.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t7E9F51AB19DA10AE00DA31AC /* CDVSplashScreen.m in Sources */ = {isa = PBXBuildFile; fileRef = 7E9F51A919DA10AE00DA31AC /* CDVSplashScreen.m */; };\n\t\t7E9F51B119DA114400DA31AC /* ImageNameTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 7E9F51B019DA114400DA31AC /* ImageNameTest.m */; };\n\t\t7E9F51B319DA116500DA31AC /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7E9F51B219DA116500DA31AC /* Foundation.framework */; };\n\t\t7E9F51B519DA127E00DA31AC /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7E9F51B419DA127E00DA31AC /* UIKit.framework */; };\n\t\t7E9F51B819DA14FD00DA31AC /* ImageNameTestDelegates.m in Sources */ = {isa = PBXBuildFile; fileRef = 7E9F51B719DA14FD00DA31AC /* ImageNameTestDelegates.m */; };\n\t\t7E9F51B919DA1B1600DA31AC /* libCDVSplashScreenLib.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7E9F519519DA102000DA31AC /* libCDVSplashScreenLib.a */; };\n\t\t7E9F51BA19DA1B2000DA31AC /* libCordova.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7E9F519019DA0F8300DA31AC /* libCordova.a */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXContainerItemProxy section */\n\t\t7E9F518F19DA0F8300DA31AC /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 7E9F518B19DA0F8300DA31AC /* CordovaLib.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = 68A32D7114102E1C006B237C;\n\t\t\tremoteInfo = CordovaLib;\n\t\t};\n\t\t7E9F51AC19DA10DE00DA31AC /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 7E9F517219DA09CE00DA31AC /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 7E9F519419DA102000DA31AC;\n\t\t\tremoteInfo = CDVSplashScreenLib;\n\t\t};\n\t\t7E9F51AE19DA10E100DA31AC /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 7E9F518B19DA0F8300DA31AC /* CordovaLib.xcodeproj */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = D2AAC07D0554694100DB518D;\n\t\t\tremoteInfo = CordovaLib;\n\t\t};\n/* End PBXContainerItemProxy section */\n\n/* Begin PBXCopyFilesBuildPhase section */\n\t\t7E9F519319DA102000DA31AC /* CopyFiles */ = {\n\t\t\tisa = PBXCopyFilesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tdstPath = \"include/$(PRODUCT_NAME)\";\n\t\t\tdstSubfolderSpec = 16;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXCopyFilesBuildPhase section */\n\n/* Begin PBXFileReference section */\n\t\t7E9F518B19DA0F8300DA31AC /* CordovaLib.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = \"wrapper.pb-project\"; name = CordovaLib.xcodeproj; path = \"../node_modules/cordova-ios/CordovaLib/CordovaLib.xcodeproj\"; sourceTree = \"<group>\"; };\n\t\t7E9F519519DA102000DA31AC /* libCDVSplashScreenLib.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libCDVSplashScreenLib.a; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t7E9F519F19DA102000DA31AC /* CDVSplashScreenLibTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CDVSplashScreenLibTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t7E9F51A219DA102000DA31AC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\t7E9F51A919DA10AE00DA31AC /* CDVSplashScreen.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CDVSplashScreen.m; path = ../../../src/ios/CDVSplashScreen.m; sourceTree = SOURCE_ROOT; };\n\t\t7E9F51AA19DA10AE00DA31AC /* CDVSplashScreen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CDVSplashScreen.h; path = ../../../src/ios/CDVSplashScreen.h; sourceTree = SOURCE_ROOT; };\n\t\t7E9F51B019DA114400DA31AC /* ImageNameTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ImageNameTest.m; sourceTree = \"<group>\"; };\n\t\t7E9F51B219DA116500DA31AC /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };\n\t\t7E9F51B419DA127E00DA31AC /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.0.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; };\n\t\t7E9F51B619DA12C600DA31AC /* ImageNameTestDelegates.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageNameTestDelegates.h; sourceTree = \"<group>\"; };\n\t\t7E9F51B719DA14FD00DA31AC /* ImageNameTestDelegates.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ImageNameTestDelegates.m; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t7E9F519219DA102000DA31AC /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t7E9F519C19DA102000DA31AC /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t7E9F51BA19DA1B2000DA31AC /* libCordova.a in Frameworks */,\n\t\t\t\t7E9F51B919DA1B1600DA31AC /* libCDVSplashScreenLib.a in Frameworks */,\n\t\t\t\t7E9F51B519DA127E00DA31AC /* UIKit.framework in Frameworks */,\n\t\t\t\t7E9F51B319DA116500DA31AC /* Foundation.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\t7E9F517119DA09CE00DA31AC = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t7E9F51B419DA127E00DA31AC /* UIKit.framework */,\n\t\t\t\t7E9F51B219DA116500DA31AC /* Foundation.framework */,\n\t\t\t\t7E9F518B19DA0F8300DA31AC /* CordovaLib.xcodeproj */,\n\t\t\t\t7E9F519619DA102000DA31AC /* CDVSplashScreenLib */,\n\t\t\t\t7E9F51A019DA102000DA31AC /* CDVSplashScreenLibTests */,\n\t\t\t\t7E9F517D19DA0A0A00DA31AC /* Products */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t7E9F517D19DA0A0A00DA31AC /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t7E9F519519DA102000DA31AC /* libCDVSplashScreenLib.a */,\n\t\t\t\t7E9F519F19DA102000DA31AC /* CDVSplashScreenLibTests.xctest */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t7E9F518C19DA0F8300DA31AC /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t7E9F519019DA0F8300DA31AC /* libCordova.a */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t7E9F519619DA102000DA31AC /* CDVSplashScreenLib */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t7E9F51A919DA10AE00DA31AC /* CDVSplashScreen.m */,\n\t\t\t\t7E9F51AA19DA10AE00DA31AC /* CDVSplashScreen.h */,\n\t\t\t);\n\t\t\tpath = CDVSplashScreenLib;\n\t\t\tsourceTree = SOURCE_ROOT;\n\t\t};\n\t\t7E9F51A019DA102000DA31AC /* CDVSplashScreenLibTests */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t7E9F51A119DA102000DA31AC /* Supporting Files */,\n\t\t\t\t7E9F51B019DA114400DA31AC /* ImageNameTest.m */,\n\t\t\t\t7E9F51B619DA12C600DA31AC /* ImageNameTestDelegates.h */,\n\t\t\t\t7E9F51B719DA14FD00DA31AC /* ImageNameTestDelegates.m */,\n\t\t\t);\n\t\t\tpath = CDVSplashScreenLibTests;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t7E9F51A119DA102000DA31AC /* Supporting Files */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t7E9F51A219DA102000DA31AC /* Info.plist */,\n\t\t\t);\n\t\t\tname = \"Supporting Files\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\t7E9F519419DA102000DA31AC /* CDVSplashScreenLib */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 7E9F51A319DA102000DA31AC /* Build configuration list for PBXNativeTarget \"CDVSplashScreenLib\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t7E9F519119DA102000DA31AC /* Sources */,\n\t\t\t\t7E9F519219DA102000DA31AC /* Frameworks */,\n\t\t\t\t7E9F519319DA102000DA31AC /* CopyFiles */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = CDVSplashScreenLib;\n\t\t\tproductName = CDVSplashScreenLib;\n\t\t\tproductReference = 7E9F519519DA102000DA31AC /* libCDVSplashScreenLib.a */;\n\t\t\tproductType = \"com.apple.product-type.library.static\";\n\t\t};\n\t\t7E9F519E19DA102000DA31AC /* CDVSplashScreenLibTests */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 7E9F51A619DA102000DA31AC /* Build configuration list for PBXNativeTarget \"CDVSplashScreenLibTests\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t7E9F519B19DA102000DA31AC /* Sources */,\n\t\t\t\t7E9F519C19DA102000DA31AC /* Frameworks */,\n\t\t\t\t7E9F519D19DA102000DA31AC /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\t7E9F51AF19DA10E100DA31AC /* PBXTargetDependency */,\n\t\t\t\t7E9F51AD19DA10DE00DA31AC /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = CDVSplashScreenLibTests;\n\t\t\tproductName = CDVSplashScreenLibTests;\n\t\t\tproductReference = 7E9F519F19DA102000DA31AC /* CDVSplashScreenLibTests.xctest */;\n\t\t\tproductType = \"com.apple.product-type.bundle.unit-test\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t7E9F517219DA09CE00DA31AC /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastUpgradeCheck = 0600;\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\t7E9F519419DA102000DA31AC = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 6.0;\n\t\t\t\t\t};\n\t\t\t\t\t7E9F519E19DA102000DA31AC = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 6.0;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = 7E9F517519DA09CE00DA31AC /* Build configuration list for PBXProject \"CDVSplashScreenTest\" */;\n\t\t\tcompatibilityVersion = \"Xcode 3.2\";\n\t\t\tdevelopmentRegion = English;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t);\n\t\t\tmainGroup = 7E9F517119DA09CE00DA31AC;\n\t\t\tproductRefGroup = 7E9F517D19DA0A0A00DA31AC /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectReferences = (\n\t\t\t\t{\n\t\t\t\t\tProductGroup = 7E9F518C19DA0F8300DA31AC /* Products */;\n\t\t\t\t\tProjectRef = 7E9F518B19DA0F8300DA31AC /* CordovaLib.xcodeproj */;\n\t\t\t\t},\n\t\t\t);\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t7E9F519419DA102000DA31AC /* CDVSplashScreenLib */,\n\t\t\t\t7E9F519E19DA102000DA31AC /* CDVSplashScreenLibTests */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXReferenceProxy section */\n\t\t7E9F519019DA0F8300DA31AC /* libCordova.a */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = archive.ar;\n\t\t\tpath = libCordova.a;\n\t\t\tremoteRef = 7E9F518F19DA0F8300DA31AC /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n/* End PBXReferenceProxy section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\t7E9F519D19DA102000DA31AC /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t7E9F519119DA102000DA31AC /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t7E9F51AB19DA10AE00DA31AC /* CDVSplashScreen.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t7E9F519B19DA102000DA31AC /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t7E9F51B119DA114400DA31AC /* ImageNameTest.m in Sources */,\n\t\t\t\t7E9F51B819DA14FD00DA31AC /* ImageNameTestDelegates.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXTargetDependency section */\n\t\t7E9F51AD19DA10DE00DA31AC /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 7E9F519419DA102000DA31AC /* CDVSplashScreenLib */;\n\t\t\ttargetProxy = 7E9F51AC19DA10DE00DA31AC /* PBXContainerItemProxy */;\n\t\t};\n\t\t7E9F51AF19DA10E100DA31AC /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\tname = CordovaLib;\n\t\t\ttargetProxy = 7E9F51AE19DA10E100DA31AC /* PBXContainerItemProxy */;\n\t\t};\n/* End PBXTargetDependency section */\n\n/* Begin XCBuildConfiguration section */\n\t\t7E9F517619DA09CE00DA31AC /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t7E9F517719DA09CE00DA31AC /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t7E9F51A419DA102000DA31AC /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_SYMBOLS_PRIVATE_EXTERN = NO;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tHEADER_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"\\\"$(TARGET_BUILD_DIR)/usr/local/lib/include\\\"\",\n\t\t\t\t\t\"\\\"$(OBJROOT)/UninstalledProducts/include\\\"\",\n\t\t\t\t\t\"\\\"$(BUILT_PRODUCTS_DIR)\\\"\",\n\t\t\t\t);\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 8.0;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tOTHER_LDFLAGS = \"-ObjC\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t7E9F51A519DA102000DA31AC /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCOPY_PHASE_STRIP = YES;\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tHEADER_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"\\\"$(TARGET_BUILD_DIR)/usr/local/lib/include\\\"\",\n\t\t\t\t\t\"\\n\\\"$(OBJROOT)/UninstalledProducts/include\\\"\\n\\\"$(BUILT_PRODUCTS_DIR)\\\"\",\n\t\t\t\t);\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 8.0;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tOTHER_LDFLAGS = \"-ObjC\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t7E9F51A719DA102000DA31AC /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tFRAMEWORK_SEARCH_PATHS = (\n\t\t\t\t\t\"$(SDKROOT)/Developer/Library/Frameworks\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_SYMBOLS_PRIVATE_EXTERN = NO;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tINFOPLIST_FILE = CDVSplashScreenLibTests/Info.plist;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 8.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t7E9F51A819DA102000DA31AC /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCOPY_PHASE_STRIP = YES;\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tFRAMEWORK_SEARCH_PATHS = (\n\t\t\t\t\t\"$(SDKROOT)/Developer/Library/Frameworks\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tINFOPLIST_FILE = CDVSplashScreenLibTests/Info.plist;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 8.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t7E9F517519DA09CE00DA31AC /* Build configuration list for PBXProject \"CDVSplashScreenTest\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t7E9F517619DA09CE00DA31AC /* Debug */,\n\t\t\t\t7E9F517719DA09CE00DA31AC /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t7E9F51A319DA102000DA31AC /* Build configuration list for PBXNativeTarget \"CDVSplashScreenLib\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t7E9F51A419DA102000DA31AC /* Debug */,\n\t\t\t\t7E9F51A519DA102000DA31AC /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t7E9F51A619DA102000DA31AC /* Build configuration list for PBXNativeTarget \"CDVSplashScreenLibTests\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t7E9F51A719DA102000DA31AC /* Debug */,\n\t\t\t\t7E9F51A819DA102000DA31AC /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = 7E9F517219DA09CE00DA31AC /* Project object */;\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest/CDVSplashScreenTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"self:CDVSplashScreenTest.xcodeproj\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest/CDVSplashScreenTest.xcodeproj/xcshareddata/xcschemes/CDVSplashScreenLib.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"0600\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"7E9F519419DA102000DA31AC\"\n               BuildableName = \"libCDVSplashScreenLib.a\"\n               BlueprintName = \"CDVSplashScreenLib\"\n               ReferencedContainer = \"container:CDVSplashScreenTest.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      buildConfiguration = \"Debug\">\n      <Testables>\n      </Testables>\n   </TestAction>\n   <LaunchAction\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      buildConfiguration = \"Debug\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      allowLocationSimulation = \"YES\">\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"7E9F519419DA102000DA31AC\"\n            BuildableName = \"libCDVSplashScreenLib.a\"\n            BlueprintName = \"CDVSplashScreenLib\"\n            ReferencedContainer = \"container:CDVSplashScreenTest.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n      <AdditionalOptions>\n      </AdditionalOptions>\n   </LaunchAction>\n   <ProfileAction\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      buildConfiguration = \"Release\"\n      debugDocumentVersioning = \"YES\">\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"7E9F519419DA102000DA31AC\"\n            BuildableName = \"libCDVSplashScreenLib.a\"\n            BlueprintName = \"CDVSplashScreenLib\"\n            ReferencedContainer = \"container:CDVSplashScreenTest.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest/CDVSplashScreenTest.xcodeproj/xcshareddata/xcschemes/CDVSplashScreenLibTests.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"0600\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"NO\"\n            buildForArchiving = \"NO\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"7E9F519E19DA102000DA31AC\"\n               BuildableName = \"CDVSplashScreenLibTests.xctest\"\n               BlueprintName = \"CDVSplashScreenLibTests\"\n               ReferencedContainer = \"container:CDVSplashScreenTest.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      buildConfiguration = \"Debug\">\n      <Testables>\n         <TestableReference\n            skipped = \"NO\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"7E9F519E19DA102000DA31AC\"\n               BuildableName = \"CDVSplashScreenLibTests.xctest\"\n               BlueprintName = \"CDVSplashScreenLibTests\"\n               ReferencedContainer = \"container:CDVSplashScreenTest.xcodeproj\">\n            </BuildableReference>\n         </TestableReference>\n      </Testables>\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"7E9F519E19DA102000DA31AC\"\n            BuildableName = \"CDVSplashScreenLibTests.xctest\"\n            BlueprintName = \"CDVSplashScreenLibTests\"\n            ReferencedContainer = \"container:CDVSplashScreenTest.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n   </TestAction>\n   <LaunchAction\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      buildConfiguration = \"Debug\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      allowLocationSimulation = \"YES\">\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"7E9F519E19DA102000DA31AC\"\n            BuildableName = \"CDVSplashScreenLibTests.xctest\"\n            BlueprintName = \"CDVSplashScreenLibTests\"\n            ReferencedContainer = \"container:CDVSplashScreenTest.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n      <AdditionalOptions>\n      </AdditionalOptions>\n   </LaunchAction>\n   <ProfileAction\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      buildConfiguration = \"Release\"\n      debugDocumentVersioning = \"YES\">\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"7E9F519E19DA102000DA31AC\"\n            BuildableName = \"CDVSplashScreenLibTests.xctest\"\n            BlueprintName = \"CDVSplashScreenLibTests\"\n            ReferencedContainer = \"container:CDVSplashScreenTest.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"container:CDVSplashScreenTest/CDVSplashScreenTest.xcodeproj\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest.xcworkspace/xcshareddata/xcschemes/CordovaLib.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"0600\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"D2AAC07D0554694100DB518D\"\n               BuildableName = \"libCordova.a\"\n               BlueprintName = \"CordovaLib\"\n               ReferencedContainer = \"container:node_modules/cordova-ios/CordovaLib/CordovaLib.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      buildConfiguration = \"Debug\">\n      <Testables>\n      </Testables>\n   </TestAction>\n   <LaunchAction\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      buildConfiguration = \"Debug\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      allowLocationSimulation = \"YES\">\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"D2AAC07D0554694100DB518D\"\n            BuildableName = \"libCordova.a\"\n            BlueprintName = \"CordovaLib\"\n            ReferencedContainer = \"container:node_modules/cordova-ios/CordovaLib/CordovaLib.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n      <AdditionalOptions>\n      </AdditionalOptions>\n   </LaunchAction>\n   <ProfileAction\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      buildConfiguration = \"Release\"\n      debugDocumentVersioning = \"YES\">\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"D2AAC07D0554694100DB518D\"\n            BuildableName = \"libCordova.a\"\n            BlueprintName = \"CordovaLib\"\n            ReferencedContainer = \"container:node_modules/cordova-ios/CordovaLib/CordovaLib.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/tests/ios/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# iOS Tests for CDVSplashScreen\n\nYou need to install `node.js` to pull in `cordova-ios`.\n\nFirst install cordova-ios:\n\n    npm install\n\n... in the current folder.\n\n\n# Testing from Xcode\n\n1. Launch the `CDVSplashScreenTest.xcworkspace` file.\n2. Choose \"CDVSplashScreenLibTests\" from the scheme drop-down menu\n3. Click and hold on the `Play` button, and choose the `Wrench` icon to run the tests\n\n\n# Testing from the command line\n\n    npm test\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/tests/ios/doc/de/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# iOS-Tests für CDVSplashScreen\n\nSie müssen installieren `node.js` in `Cordova-Ios` zu ziehen.\n\nInstallieren Sie Cordova-Ios zum ersten Mal:\n\n    npm install\n    \n\n... im aktuellen Ordner.\n\n# Testen von Xcode\n\n  1. Starten Sie die Datei `CDVSplashScreenTest.xcworkspace` .\n  2. Wählen Sie im Dropdown-Schema \"CDVSplashScreenLibTests\"\n  3. Klicken Sie und halten Sie auf den `Play` -Button und wählen Sie das `Schraubenschlüssel` -Symbol zum Ausführen der tests\n\n# Tests von der Befehlszeile aus\n\n    npm test\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/tests/ios/doc/es/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# Pruebas de iOS para CDVSplashScreen\n\nNecesita instalar `node.js` en `Córdoba-ios`.\n\nPrimero instalar cordova-ios:\n\n    npm install\n    \n\n... en la carpeta actual.\n\n# Prueba de Xcode\n\n  1. Iniciar el archivo `CDVSplashScreenTest.xcworkspace` .\n  2. Elija \"CDVSplashScreenLibTests\" en el menú de lista desplegable esquema\n  3. Haga clic y mantenga el botón de `Play` y elegir el icono de `llave inglesa` para ejecutar las pruebas\n\n# Pruebas desde la línea de comandos\n\n    npm test\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/tests/ios/doc/fr/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# Tests d'iOS pour CDVSplashScreen\n\nVous devez installer `node.js` à `cordova-ios`.\n\nCommencez par installer cordova-ios :\n\n    npm install\n    \n\n... dans le dossier actuel.\n\n# Tests de Xcode\n\n  1. Lancez le fichier `CDVSplashScreenTest.xcworkspace` .\n  2. Choisissez « CDVSplashScreenLibTests » dans le menu déroulant de régime\n  3. Cliquez et maintenez sur la touche `Play` et cliquez sur l'icône de `clé` pour exécuter les tests\n\n# Test de la ligne de commande\n\n    npm test\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/tests/ios/doc/it/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# Test di iOS per CDVSplashScreen\n\nÈ necessario installare `node. js` per tirare in `cordova-ios`.\n\nIn primo luogo installare cordova-ios:\n\n    npm install\n    \n\n... nella cartella corrente.\n\n# Test da Xcode\n\n  1. Lanciare il file `CDVSplashScreenTest.xcworkspace` .\n  2. Scegli \"CDVSplashScreenLibTests\" dal menu a discesa Schema\n  3. Fare clic e tenere premuto il pulsante `Play` e scegliere l'icona della `chiave inglese` per eseguire i test\n\n# Test dalla riga di comando\n\n    npm test\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/tests/ios/doc/ja/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# CDVSplashScreen の iOS のテスト\n\n`Node.js` `コルドバ`ios をプルするをインストールする必要があります。.\n\nコルドバ ios をインストールします。\n\n    npm install\n    \n\n現在のフォルダーに.\n\n# Xcode からテスト\n\n  1. `CDVSplashScreenTest.xcworkspace`ファイルを起動します。\n  2. スキーム] ドロップダウン メニューから\"CDVSplashScreenLibTests\"を選択します。\n  3. クリックし、`再生`ボタンを押し、テストを実行する`レンチ`のアイコンを選択\n\n# コマンドラインからテスト\n\n    npm test\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/tests/ios/doc/ko/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# CDVSplashScreen에 대 한 iOS 테스트\n\n`Node.js` `코르도바` ios에서를 설치 해야.\n\n코르도바-ios를 설치 하는 첫번째는:\n\n    npm install\n    \n\n현재 폴더에....\n\n# Xcode에서 테스트\n\n  1. `CDVSplashScreenTest.xcworkspace` 파일을 시작 합니다.\n  2. 구성표 드롭 다운 메뉴에서 \"CDVSplashScreenLibTests\"를 선택\n  3. 클릭 하 고 `재생` 버튼에는 테스트를 실행 하려면 `공구 모양` 아이콘을 선택\n\n# 명령줄에서 테스트\n\n    npm test\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/tests/ios/doc/pl/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# iOS testy dla CDVSplashScreen\n\nMusisz zainstalować `node.js` ciągnąć w `cordova-ios`.\n\nNajpierw zainstalować cordova-ios:\n\n    npm install\n    \n\n... w folderze bieżącym.\n\n# Badania z Xcode\n\n  1. Uruchom plik `CDVSplashScreenTest.xcworkspace` .\n  2. Wybierz z menu rozwijanego systemu \"CDVSplashScreenLibTests\"\n  3. Kliknij i przytrzymaj przycisk `Play` i wybrać ikonę `klucz` do testów\n\n# Badania z wiersza polecenia\n\n    npm test\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/tests/ios/doc/zh/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# CDVSplashScreen 的 iOS 測試\n\n您需要安裝`node.js`拉`科爾多瓦 ios`中.\n\n第一次安裝科爾多瓦 ios:\n\n    npm install\n    \n\n在當前資料夾中。\n\n# 從 Xcode 測試\n\n  1. 啟動`CDVSplashScreenTest.xcworkspace`檔。\n  2. 從方案下拉式功能表中選擇\"CDVSplashScreenLibTests\"\n  3. 按一下並堅持`播放`按鈕，然後選擇要運行的測試的`扳手`圖示\n\n# 從命令列測試\n\n    npm test\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/tests/ios/package.json",
    "content": "{\n    \"name\": \"cordova-plugin-splashscreen-test-ios\",\n    \"version\": \"1.0.0\",\n    \"description\": \"iOS Unit Tests for Splashscreen Plugin\",\n    \"author\": \"Apache Software Foundation\",\n    \"license\": \"Apache Version 2.0\",\n    \"dependencies\": {\n        \"cordova-ios\": \"^3.6.0\"\n    },\n    \"scripts\": {\n        \"test\": \"xcodebuild test -workspace CDVSplashScreenTest.xcworkspace -scheme CDVSplashScreenLibTests -destination 'platform=iOS Simulator,name=iPhone 5' CONFIGURATION_BUILD_DIR='/tmp'\"\n    }    \n}"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/tests/plugin.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  Licensed to the Apache Software Foundation (ASF) under one\n  or more contributor license agreements.  See the NOTICE file\n  distributed with this work for additional information\n  regarding copyright ownership.  The ASF licenses this file\n  to you under the Apache License, Version 2.0 (the\n  \"License\"); you may not use this file except in compliance\n  with the License.  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing,\n  software distributed under the License is distributed on an\n  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n  KIND, either express or implied.  See the License for the\n  specific language governing permissions and limitations\n  under the License.\n-->\n\n<plugin xmlns=\"http://apache.org/cordova/ns/plugins/1.0\"\n    id=\"cordova-plugin-splashscreen-tests\"\n    version=\"2.1.0\">\n    <name>Cordova Splashscreen Plugin Tests</name>\n    <license>Apache 2.0</license>\n\n    <js-module src=\"tests.js\" name=\"tests\">\n    </js-module>\n</plugin>\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/tests/tests.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\nexports.defineAutoTest = function () {\n    describe('Splashscreen (cordova)', function () {\n        it(\"splashscreen.spec.1 should exist\", function () {\n            expect(navigator.splashscreen).toBeDefined();\n        });\n\n        it(\"splashscreen.spec.2 exec method should exist\", function () {\n            expect(navigator.splashscreen.show).toBeDefined();\n            expect(typeof navigator.splashscreen.show).toBe('function');\n        });\n\n        it(\"splashscreen.spec.3 exec method should exist\", function () {\n            expect(navigator.splashscreen.hide).toBeDefined();\n            expect(typeof navigator.splashscreen.hide).toBe('function');\n        });\n    });\n};\n\nexports.defineManualTests = function (contentEl, createActionButton) {\n    function showFor(duration) {\n        navigator.splashscreen.show();\n        window.setTimeout(function () {\n            navigator.splashscreen.hide();\n        }, 1000 * duration);\n    }\n\n    contentEl.innerHTML = '<h1>Splashscreen Tests</h1>' +\n        '<h3>Note for WP: AutoHideSplashScreen must be set to false in config.xml</h3>' +\n        '<div id=\"show1\"></div>' +\n        'Expected result: Will show the Cordova splashscreen for 1 second' +\n        '</p> <div id=\"show5\"></div>' +\n        'Expected result: Will show the Cordova splashscreen for 5 seconds';\n\n    createActionButton('Show for 1 second', function () {\n        showFor(1);\n    }, 'show1');\n\n    createActionButton('Show for 5 seconds', function () {\n        showFor(5);\n    }, 'show5');\n};\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/www/splashscreen.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\nvar exec = require('cordova/exec');\n\nvar splashscreen = {\n    show:function() {\n        exec(null, null, \"SplashScreen\", \"show\", []);\n    },\n    hide:function() {\n        exec(null, null, \"SplashScreen\", \"hide\", []);\n    }\n};\n\nmodule.exports = splashscreen;\n"
  },
  {
    "path": "plugins/cordova-plugin-splashscreen/www/windows/SplashScreenProxy.js",
    "content": "﻿/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n/*jslint sloppy:true */\n/*global Windows:true, require, module, window, document, WinJS */\n\nvar cordova = require('cordova'),\n    channel = require('cordova/channel');\n\nvar isPhone = (cordova.platformId == \"windows\") && WinJS.Utilities.isPhone;\nvar localSplash = null; \nvar bgColor = \"#464646\"; // default backgrond color; TDOO - read it from .appxmanifest\nvar splashImageSrc = isPhone ? \"ms-appx:///images/splashscreenphone.png\" : \"ms-appx:///images/splashscreen.png\";\n\nvar SplashScreen = {\n    setBGColor: function (cssBGColor) {\n        bgColor = cssBGColor;\n        if (localSplash) {\n            localSplash.style.backgroundColor = bgColor;\n        }\n    },\n    show: function () {\n        if (localSplash) {\n            return; // already showed\n        }\n\n        localSplash = document.createElement(\"div\");\n        localSplash.style.backgroundColor = bgColor;\n        localSplash.style.position = \"fixed\";\n        localSplash.style.top = \"0\";\n        localSplash.style.width = \"100%\";\n        localSplash.style.height = \"100%\";\n\n        localSplashImage = document.createElement(\"img\");\n        localSplashImage.src = splashImageSrc;\n        localSplashImage.style.maxWidth = \"100%\";\n        localSplashImage.style.maxHeight = \"100%\";\n        // center horizontally\n        localSplashImage.style.margin = \"0 auto\";\n        localSplashImage.style.display = \"block\";\n        // center vertically\n        localSplashImage.style.position = \"relative\";\n        localSplashImage.style.top = \"50%\";\n        localSplashImage.style.transform = \"translateY(-50%)\";\n\n        localSplash.appendChild(localSplashImage);\n        document.body.appendChild(localSplash);\n    },\n    hide: function () {\n        if (localSplash) {\n            document.body.removeChild(localSplash);\n            localSplash = null;\n        }\n    }\n};\n\nmodule.exports = SplashScreen;\n\nrequire(\"cordova/exec/proxy\").add(\"SplashScreen\", SplashScreen);\n"
  },
  {
    "path": "plugins/cordova-plugin-statusbar/CONTRIBUTING.md",
    "content": "<!--\n#\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#  KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n#\n-->\n\n# Contributing to Apache Cordova\n\nAnyone can contribute to Cordova. And we need your contributions.\n\nThere are multiple ways to contribute: report bugs, improve the docs, and\ncontribute code.\n\nFor instructions on this, start with the \n[contribution overview](http://cordova.apache.org/#contribute).\n\nThe details are explained there, but the important items are:\n - Sign and submit an Apache ICLA (Contributor License Agreement).\n - Have a Jira issue open that corresponds to your contribution.\n - Run the tests so your patch doesn't break existing functionality.\n\nWe look forward to your contributions!\n"
  },
  {
    "path": "plugins/cordova-plugin-statusbar/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License."
  },
  {
    "path": "plugins/cordova-plugin-statusbar/NOTICE",
    "content": "Apache Cordova\nCopyright 2012 The Apache Software Foundation\n\nThis product includes software developed at\nThe Apache Software Foundation (http://www.apache.org/).\n"
  },
  {
    "path": "plugins/cordova-plugin-statusbar/README.md",
    "content": "<!---\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-statusbar\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-statusbar.svg)](https://travis-ci.org/apache/cordova-plugin-statusbar)\n\nStatusBar\n======\n\n> The `StatusBar` object provides some functions to customize the iOS and Android StatusBar.\n\n\n## Installation\n\n    cordova plugin add cordova-plugin-statusbar\n\nPreferences\n-----------\n\n#### config.xml\n\n-  __StatusBarOverlaysWebView__ (boolean, defaults to true). On iOS 7, make the statusbar overlay or not overlay the WebView at startup.\n\n        <preference name=\"StatusBarOverlaysWebView\" value=\"true\" />\n\n- __StatusBarBackgroundColor__ (color hex string, defaults to #000000). On iOS 7 and Android 5, set the background color of the statusbar by a hex string (#RRGGBB) at startup.\n\n        <preference name=\"StatusBarBackgroundColor\" value=\"#000000\" />\n\n- __StatusBarStyle__ (status bar style, defaults to lightcontent). On iOS 7, set the status bar style. Available options default, lightcontent, blacktranslucent, blackopaque.\n\n        <preference name=\"StatusBarStyle\" value=\"lightcontent\" />\n\n### Android Quirks\nThe Android 5+ guidelines specify using a different color for the statusbar than your main app color (unlike the uniform statusbar color of many iOS 7+ apps), so you may want to set the statusbar color at runtime instead via `StatusBar.backgroundColorByHexString` or `StatusBar.backgroundColorByName`. One way to do that would be:\n```js\nif (cordova.platformId == 'android') {\n    StatusBar.backgroundColorByHexString(\"#333\");\n}\n```\n\nHiding at startup\n-----------\n\nDuring runtime you can use the StatusBar.hide function below, but if you want the StatusBar to be hidden at app startup, you must modify your app's Info.plist file.\n\nAdd/edit these two attributes if not present. Set **\"Status bar is initially hidden\"** to **\"YES\"** and set **\"View controller-based status bar appearance\"** to **\"NO\"**. If you edit it manually without Xcode, the keys and values are:\n\n\n\t<key>UIStatusBarHidden</key>\n\t<true/>\n\t<key>UIViewControllerBasedStatusBarAppearance</key>\n\t<false/>\n\n\nMethods\n-------\nThis plugin defines global `StatusBar` object.\n\nAlthough in the global scope, it is not available until after the `deviceready` event.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(StatusBar);\n    }\n\n- StatusBar.overlaysWebView\n- StatusBar.styleDefault\n- StatusBar.styleLightContent\n- StatusBar.styleBlackTranslucent\n- StatusBar.styleBlackOpaque\n- StatusBar.backgroundColorByName\n- StatusBar.backgroundColorByHexString\n- StatusBar.hide\n- StatusBar.show\n\nProperties\n--------\n\n- StatusBar.isVisible\n\nPermissions\n-----------\n\n#### config.xml\n\n            <feature name=\"StatusBar\">\n                <param name=\"ios-package\" value=\"CDVStatusBar\" onload=\"true\" />\n            </feature>\n\nStatusBar.overlaysWebView\n=================\n\nOn iOS 7, make the statusbar overlay or not overlay the WebView.\n\n    StatusBar.overlaysWebView(true);\n\nDescription\n-----------\n\nOn iOS 7, set to false to make the statusbar appear like iOS 6. Set the style and background color to suit using the other functions.\n\n\nSupported Platforms\n-------------------\n\n- iOS\n\nQuick Example\n-------------\n\n    StatusBar.overlaysWebView(true);\n    StatusBar.overlaysWebView(false);\n\nStatusBar.styleDefault\n=================\n\nUse the default statusbar (dark text, for light backgrounds).\n\n    StatusBar.styleDefault();\n\n\nSupported Platforms\n-------------------\n\n- iOS\n- Windows Phone 7\n- Windows Phone 8\n- Windows Phone 8.1\n\nStatusBar.styleLightContent\n=================\n\nUse the lightContent statusbar (light text, for dark backgrounds).\n\n    StatusBar.styleLightContent();\n\n\nSupported Platforms\n-------------------\n\n- iOS\n- Windows Phone 7\n- Windows Phone 8\n- Windows Phone 8.1\n\nStatusBar.styleBlackTranslucent\n=================\n\nUse the blackTranslucent statusbar (light text, for dark backgrounds).\n\n    StatusBar.styleBlackTranslucent();\n\n\nSupported Platforms\n-------------------\n\n- iOS\n- Windows Phone 7\n- Windows Phone 8\n- Windows Phone 8.1\n\nStatusBar.styleBlackOpaque\n=================\n\nUse the blackOpaque statusbar (light text, for dark backgrounds).\n\n    StatusBar.styleBlackOpaque();\n\n\nSupported Platforms\n-------------------\n\n- iOS\n- Windows Phone 7\n- Windows Phone 8\n- Windows Phone 8.1\n\n\nStatusBar.backgroundColorByName\n=================\n\nOn iOS 7, when you set StatusBar.statusBarOverlaysWebView to false, you can set the background color of the statusbar by color name.\n\n    StatusBar.backgroundColorByName(\"red\");\n\nSupported color names are:\n\n    black, darkGray, lightGray, white, gray, red, green, blue, cyan, yellow, magenta, orange, purple, brown\n\n\nSupported Platforms\n-------------------\n\n- iOS\n- Android 5+\n- Windows Phone 7\n- Windows Phone 8\n- Windows Phone 8.1\n\nStatusBar.backgroundColorByHexString\n=================\n\nSets the background color of the statusbar by a hex string.\n\n    StatusBar.backgroundColorByHexString(\"#C0C0C0\");\n\nCSS shorthand properties are also supported.\n\n    StatusBar.backgroundColorByHexString(\"#333\"); // => #333333\n    StatusBar.backgroundColorByHexString(\"#FAB\"); // => #FFAABB\n\nOn iOS 7, when you set StatusBar.statusBarOverlaysWebView to false, you can set the background color of the statusbar by a hex string (#RRGGBB).\n\nOn WP7 and WP8 you can also specify values as #AARRGGBB, where AA is an alpha value\n\nSupported Platforms\n-------------------\n\n- iOS\n- Android 5+\n- Windows Phone 7\n- Windows Phone 8\n- Windows Phone 8.1\n\nStatusBar.hide\n=================\n\nHide the statusbar.\n\n    StatusBar.hide();\n\n\nSupported Platforms\n-------------------\n\n- iOS\n- Android\n- Windows Phone 7\n- Windows Phone 8\n- Windows Phone 8.1\n\nStatusBar.show\n=================\n\nShows the statusbar.\n\n    StatusBar.show();\n\n\nSupported Platforms\n-------------------\n\n- iOS\n- Android\n- Windows Phone 7\n- Windows Phone 8\n- Windows Phone 8.1\n\n\nStatusBar.isVisible\n=================\n\nRead this property to see if the statusbar is visible or not.\n\n    if (StatusBar.isVisible) {\n    \t// do something\n    }\n\n\nSupported Platforms\n-------------------\n\n- iOS\n- Android\n- Windows Phone 7\n- Windows Phone 8\n- Windows Phone 8.1\n\n\n"
  },
  {
    "path": "plugins/cordova-plugin-statusbar/RELEASENOTES.md",
    "content": "<!--\n#\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n# \n# http://www.apache.org/licenses/LICENSE-2.0\n# \n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#  KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n#\n-->\n# Release Notes\n\n### 0.1.5 (Apr 17, 2014) (First release as a core Cordova Plugin)\n* CB-6316: Added README.md which point to the new location for docs\n* CB-6316: Added license header to the documentation. Added README.md which point to the new location for docs\n* CB-6316: Moved StatusBar plugin documentation to docs folder\n* CB-6314: [android] Add StatusBar.isVisible support to Android\n* CB-6460: Update license headers\n\n### 0.1.6 (Jun 05, 2014)\n* CB-6783 - added StatusBarStyle config preference,  updated docs (closes #9)\n* CB-6812 Add license\n* CB-6491 add CONTRIBUTING.md\n* CB-6264 minor formatting issue\n* Update docs with recent WP changes, remove 'clear' from the loist of named colors in documentation\n* CB-6513 - Statusbar plugin for Android is not compiling\n\n### 0.1.7 (Aug 06, 2014)\n* Add LICENSE and NOTICE\n* Update statusbar.js\n* Update backgroundColorByHexString function\n* ios: Use a persistent callbackId instead of calling sendJs\n* CB-6626 ios: Add a JS event for tapping on statusbar\n* ios: Fix hide to adjust webview's frame only when status bar is not overlaying webview\n* CB-6127 Updated translations for docs\n* android: Fix StatusBar.initialize() not running on UI thread\n\n### 0.1.8 (Sep 17, 2014)\n* CB-7549 [StatusBar][iOS 8] Landscape issue\n* CB-7486 Remove StatusBarBackgroundColor intial preference (black background) so background will be initially transparent\n* Renamed test dir, added nested plugin.xml\n* added documentation for manual tests, moved background color test below overlay test\n* CB-7195 ported statusbar tests to framework\n\n### 0.1.9 (Dec 02, 2014)\n* Fix onload attribute within <feature> to be a <param>\n* CB-8010 - Statusbar colour does not change to orange\n* added checks for running on windows when StatusBar is NOT available\n* CB-7986 Add cordova-plugin-statusbar support for **Windows Phone 8.1**\n* CB-7977 Mention `deviceready` in plugin docs\n* CB-7979 Each plugin doc should have a ## Installation section\n* Inserting leading space after # for consistency\n* CB-7549 - (Re-fix) `StatusBar` **iOS 8** Landscape issue (closes #15)\n* CB-7700 cordova-plugin-statusbar documentation translation: cordova-plugin-statusbar\n* CB-7571 Bump version of nested plugin to match parent plugin\n\n### 0.1.10 (Feb 04, 2015)\n* CB-8351 ios: Use argumentForIndex rather than NSArray extension\n\n### 1.0.0 (Apr 15, 2015)\n* CB-8746 gave plugin major version bump\n* CB-8683 changed plugin-id to pacakge-name\n* CB-8653 properly updated translated docs to use new id\n* CB-8653 updated translated docs to use new id\n* Use TRAVIS_BUILD_DIR, install paramedic by npm\n* CB-8653 Updated Readme\n* - Use StatusBarBackgroundColor instead of AndroidStatusBarBackgroundColor, and added a quirk to the readme.\n* - Add support for StatusBar.backgroundColorByHexString (and StatusBar.backgroundColorByName) on Android 5 and up\n* Allow setting the statusbar backgroundcolor on Android\n* CB-8575 Integrate TravisCI\n* CB-8438 cordova-plugin-statusbar documentation translation: cordova-plugin-statusbar\n* CB-8538 Added package.json file\n\n### 1.0.1 (Jun 17, 2015)\n* add auto-tests for basic api\n* CB-9180 Add correct supported check for Windows 8.1 desktop\n* CB-9128 cordova-plugin-statusbar documentation translation: cordova-plugin-statusbar\n* fix npm md issue\n"
  },
  {
    "path": "plugins/cordova-plugin-statusbar/doc/de/README.md",
    "content": "<!---\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-statusbar\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-statusbar.svg)](https://travis-ci.org/apache/cordova-plugin-statusbar)\n\n# StatusBar\n\n> Das `StatusBar` Objekt stellt einige Funktionen zum Anpassen des iOS und Android StatusBar.\n\n## Installation\n\n    cordova plugin add cordova-plugin-statusbar\n    \n\n## \"Einstellungen\"\n\n#### \"config.xml\"\n\n  * **StatusBarOverlaysWebView** (Boolean, der Standardwert ist True). Stellen Sie auf iOS 7 die Statusbar-Overlay oder keine Überlagerung der WebView beim Start.\n    \n        <preference name=\"StatusBarOverlaysWebView\" value=\"true\" />\n        \n\n  * **StatusBarBackgroundColor** (Farbe hex String, Standardwert ist #000000). Auf iOS legen 7 und Android 5, Sie die Hintergrundfarbe der Statusbar von eine hexadezimale Zeichenfolge (#RRGGBB) beim Start.\n    \n        <preference name=\"StatusBarBackgroundColor\" value=\"#000000\" />\n        \n\n  * **StatusBarStyle** (Status Bar-Stil, der Standardwert ist Lightcontent). Legen Sie auf iOS 7 den Status-Bar-Stil. Verfügbaren Optionen Standard, Lightcontent, Blacktranslucent, Blackopaque.\n    \n        <preference name=\"StatusBarStyle\" value=\"lightcontent\" />\n        \n\n### Android Eigenarten\n\nDie Android 5 + Leitlinien angeben, verwenden eine andere Farbe für die Statusbar als Ihre Hauptanwendung Farbe (anders als die einheitliche Statusbar Farbe viele iOS 7 + apps), so Sie die Statusbar Farbe zur Laufzeit statt über `StatusBar.backgroundColorByHexString` oder `StatusBar.backgroundColorByName`festzulegen möchten vielleicht. Eine Möglichkeit dazu wäre:\n\n```js\nif (cordova.platformId == 'android') {\n    StatusBar.backgroundColorByHexString(\"#333\");\n}\n```\n\n## Beim Start ausblenden\n\nWährend der Laufzeit können Sie die StatusBar.hide-Funktion unten, aber die StatusBar beim Start der app versteckt werden soll, müssen Sie Ihre app Info.plist Datei ändern.\n\nDiese beiden Attribute hinzufügen/bearbeiten, wenn nicht vorhanden. Legen Sie **\"Statusleiste ist anfangs ausgeblendet\"** auf **\"YES\"** und **\"View Controller-basierte Status Bar aussehen\"** auf **\"NO\"**. Wenn Sie es manuell ohne Xcode bearbeiten, werden die Schlüssel und Werte:\n\n    <key>UIStatusBarHidden</key>\n    <true/>\n    <key>UIViewControllerBasedStatusBarAppearance</key>\n    <false/>\n    \n\n## Methoden\n\nDieses Plugin wird globales `StatusBar`-Objekt definiert.\n\nObwohl im globalen Gültigkeitsbereich, steht es nicht bis nach dem `deviceready`-Ereignis.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(StatusBar);\n    }\n    \n\n  * StatusBar.overlaysWebView\n  * StatusBar.styleDefault\n  * StatusBar.styleLightContent\n  * StatusBar.styleBlackTranslucent\n  * StatusBar.styleBlackOpaque\n  * StatusBar.backgroundColorByName\n  * StatusBar.backgroundColorByHexString\n  * StatusBar.hide\n  * StatusBar.show\n\n## Eigenschaften\n\n  * StatusBar.isVisible\n\n## Berechtigungen\n\n#### \"config.xml\"\n\n            <feature name=\"StatusBar\">\n                <param name=\"ios-package\" value=\"CDVStatusBar\" onload=\"true\" />\n            </feature>\n    \n\n# StatusBar.overlaysWebView\n\nStellen Sie auf iOS 7 Statusbar überlagern oder nicht überlagert die WebView.\n\n    StatusBar.overlaysWebView(true);\n    \n\n## Beschreibung\n\nAuf iOS 7 zu der Statusbar wie iOS 6 erscheinen auf False festgelegt. Legen Sie die Stil und Hintergrund Farbe entsprechend mit den anderen Funktionen.\n\n## Unterstützte Plattformen\n\n  * iOS\n\n## Kurzes Beispiel\n\n    StatusBar.overlaysWebView(true);\n    StatusBar.overlaysWebView(false);\n    \n\n# StatusBar.styleDefault\n\nVerwenden Sie die Standard-Statusbar (dunkle Text, für helle Hintergründe).\n\n    StatusBar.styleDefault();\n    \n\n## Unterstützte Plattformen\n\n  * iOS\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone-8.1\n\n# StatusBar.styleLightContent\n\nVerwenden Sie die LightContent-Statusbar (heller Text, für dunkle Hintergründe).\n\n    StatusBar.styleLightContent();\n    \n\n## Unterstützte Plattformen\n\n  * iOS\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone-8.1\n\n# StatusBar.styleBlackTranslucent\n\nVerwenden Sie die BlackTranslucent-Statusbar (heller Text, für dunkle Hintergründe).\n\n    StatusBar.styleBlackTranslucent();\n    \n\n## Unterstützte Plattformen\n\n  * iOS\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone-8.1\n\n# StatusBar.styleBlackOpaque\n\nVerwenden Sie die BlackOpaque-Statusbar (heller Text, für dunkle Hintergründe).\n\n    StatusBar.styleBlackOpaque();\n    \n\n## Unterstützte Plattformen\n\n  * iOS\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone-8.1\n\n# StatusBar.backgroundColorByName\n\nAuf iOS 7 Wenn Sie StatusBar.statusBarOverlaysWebView auf False festlegen, können Sie die Hintergrundfarbe der Statusbar von Farbnamen festlegen.\n\n    StatusBar.backgroundColorByName(\"red\");\n    \n\nUnterstützte Farbnamen sind:\n\n    black, darkGray, lightGray, white, gray, red, green, blue, cyan, yellow, magenta, orange, purple, brown\n    \n\n## Unterstützte Plattformen\n\n  * iOS\n  * Android 5+\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone-8.1\n\n# StatusBar.backgroundColorByHexString\n\nLegt die Hintergrundfarbe der Statusbar von eine hexadezimale Zeichenfolge fest.\n\n    StatusBar.backgroundColorByHexString(\"#C0C0C0\");\n    \n\nCSS-Kurzschrift-Eigenschaften werden ebenfalls unterstützt.\n\n    StatusBar.backgroundColorByHexString(\"#333\"); // => #333333\n    StatusBar.backgroundColorByHexString(\"#FAB\"); // => #FFAABB\n    \n\nAuf iOS 7 Wenn Sie StatusBar.statusBarOverlaysWebView auf False festlegen, können Sie die Hintergrundfarbe der Statusbar von eine hexadezimale Zeichenfolge (#RRGGBB) festlegen.\n\nAuf WP7 und WP8 können Sie auch Werte wie #AARRGGBB, angeben wo AA einen alpha-Wert ist\n\n## Unterstützte Plattformen\n\n  * iOS\n  * Android 5+\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone-8.1\n\n# StatusBar.hide\n\nAusblenden der Statusleiste.\n\n    StatusBar.hide();\n    \n\n## Unterstützte Plattformen\n\n  * iOS\n  * Android\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone-8.1\n\n# StatusBar.show\n\nZeigt die Statusleiste.\n\n    StatusBar.show();\n    \n\n## Unterstützte Plattformen\n\n  * iOS\n  * Android\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone-8.1\n\n# StatusBar.isVisible\n\nLesen Sie diese Eigenschaft, um festzustellen, ob die Statusbar sichtbar oder nicht ist.\n\n    if (StatusBar.isVisible) {\n        // do something\n    }\n    \n\n## Unterstützte Plattformen\n\n  * iOS\n  * Android\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone-8.1"
  },
  {
    "path": "plugins/cordova-plugin-statusbar/doc/de/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-statusbar\n\n# StatusBar\n\n> Das `StatusBar` Objekt stellt einige Funktionen zum Anpassen des iOS und Android StatusBar.\n\n## Installation\n\n    cordova plugin add cordova-plugin-statusbar\n    \n\n## \"Einstellungen\"\n\n#### config.xml\n\n*   **StatusBarOverlaysWebView** (Boolean, der Standardwert ist True). Stellen Sie auf iOS 7 die Statusbar-Overlay oder keine Überlagerung der WebView beim Start.\n    \n        <preference name=\"StatusBarOverlaysWebView\" value=\"true\" />\n        \n\n*   **StatusBarBackgroundColor** (Farbe hex String, der Standardwert ist #000000). Legen Sie auf iOS 7 die Hintergrundfarbe der Statusbar von eine hexadezimale Zeichenfolge (#RRGGBB) beim Start.\n    \n        <preference name=\"StatusBarBackgroundColor\" value=\"#000000\" />\n        \n\n*   **StatusBarStyle** (Status Bar-Stil, der Standardwert ist Lightcontent). Legen Sie auf iOS 7 den Status-Bar-Stil. Verfügbaren Optionen Standard, Lightcontent, Blacktranslucent, Blackopaque.\n    \n        <preference name=\"StatusBarStyle\" value=\"lightcontent\" />\n        \n\n## Beim Start ausblenden\n\nWährend der Laufzeit können Sie die StatusBar.hide-Funktion unten, aber die StatusBar beim Start der app versteckt werden soll, müssen Sie Ihre app Info.plist Datei ändern.\n\nDiese beiden Attribute hinzufügen/bearbeiten, wenn nicht vorhanden. Legen Sie **\"Statusleiste ist anfangs ausgeblendet\"** auf **\"YES\"** und **\"View Controller-basierte Status Bar aussehen\"** auf **\"NO\"**. Wenn Sie es manuell ohne Xcode bearbeiten, werden die Schlüssel und Werte:\n\n    <key>UIStatusBarHidden</key>\n    <true/>\n    <key>UIViewControllerBasedStatusBarAppearance</key>\n    <false/>\n    \n\n## Methoden\n\nDieses Plugin wird globales `StatusBar`-Objekt definiert.\n\nObwohl im globalen Gültigkeitsbereich, steht es nicht bis nach dem `deviceready`-Ereignis.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(StatusBar);\n    }\n    \n\n*   StatusBar.overlaysWebView\n*   StatusBar.styleDefault\n*   StatusBar.styleLightContent\n*   StatusBar.styleBlackTranslucent\n*   StatusBar.styleBlackOpaque\n*   StatusBar.backgroundColorByName\n*   StatusBar.backgroundColorByHexString\n*   StatusBar.hide\n*   StatusBar.show\n\n## Eigenschaften\n\n*   StatusBar.isVisible\n\n## Berechtigungen\n\n#### config.xml\n\n            <feature name=\"StatusBar\">\n                <param name=\"ios-package\" value=\"CDVStatusBar\" onload=\"true\" />\n            </feature>\n    \n\n# StatusBar.overlaysWebView\n\nStellen Sie auf iOS 7 Statusbar überlagern oder nicht überlagert die WebView.\n\n    StatusBar.overlaysWebView(true);\n    \n\n## Beschreibung\n\nAuf iOS 7 zu der Statusbar wie iOS 6 erscheinen auf False festgelegt. Legen Sie die Stil und Hintergrund Farbe entsprechend mit den anderen Funktionen.\n\n## Unterstützte Plattformen\n\n*   iOS\n\n## Kurzes Beispiel\n\n    StatusBar.overlaysWebView(true);\n    StatusBar.overlaysWebView(false);\n    \n\n# StatusBar.styleDefault\n\nVerwenden Sie die Standard-Statusbar (dunkle Text, für helle Hintergründe).\n\n    StatusBar.styleDefault();\n    \n\n## Unterstützte Plattformen\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone-8.1\n\n# StatusBar.styleLightContent\n\nVerwenden Sie die LightContent-Statusbar (heller Text, für dunkle Hintergründe).\n\n    StatusBar.styleLightContent();\n    \n\n## Unterstützte Plattformen\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone-8.1\n\n# StatusBar.styleBlackTranslucent\n\nVerwenden Sie die BlackTranslucent-Statusbar (heller Text, für dunkle Hintergründe).\n\n    StatusBar.styleBlackTranslucent();\n    \n\n## Unterstützte Plattformen\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone-8.1\n\n# StatusBar.styleBlackOpaque\n\nVerwenden Sie die BlackOpaque-Statusbar (heller Text, für dunkle Hintergründe).\n\n    StatusBar.styleBlackOpaque();\n    \n\n## Unterstützte Plattformen\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone-8.1\n\n# StatusBar.backgroundColorByName\n\nAuf iOS 7 Wenn Sie StatusBar.statusBarOverlaysWebView auf False festlegen, können Sie die Hintergrundfarbe der Statusbar von Farbnamen festlegen.\n\n    StatusBar.backgroundColorByName(\"red\");\n    \n\nUnterstützte Farbnamen sind:\n\n    black, darkGray, lightGray, white, gray, red, green, blue, cyan, yellow, magenta, orange, purple, brown\n    \n\n## Unterstützte Plattformen\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone-8.1\n\n# StatusBar.backgroundColorByHexString\n\nLegt die Hintergrundfarbe der Statusbar von eine hexadezimale Zeichenfolge fest.\n\n    StatusBar.backgroundColorByHexString(\"#C0C0C0\");\n    \n\nCSS-Kurzschrift-Eigenschaften werden ebenfalls unterstützt.\n\n    StatusBar.backgroundColorByHexString(\"#333\"); // => #333333\n    StatusBar.backgroundColorByHexString(\"#FAB\"); // => #FFAABB\n    \n\nAuf iOS 7 Wenn Sie StatusBar.statusBarOverlaysWebView auf False festlegen, können Sie die Hintergrundfarbe der Statusbar von eine hexadezimale Zeichenfolge (#RRGGBB) festlegen.\n\nAuf WP7 und WP8 können Sie auch Werte wie #AARRGGBB, angeben wo AA einen alpha-Wert ist\n\n## Unterstützte Plattformen\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone-8.1\n\n# StatusBar.hide\n\nAusblenden der Statusleiste.\n\n    StatusBar.hide();\n    \n\n## Unterstützte Plattformen\n\n*   iOS\n*   Android\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone-8.1\n\n# StatusBar.show\n\nZeigt die Statusleiste.\n\n    StatusBar.show();\n    \n\n## Unterstützte Plattformen\n\n*   iOS\n*   Android\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone-8.1\n\n# StatusBar.isVisible\n\nLesen Sie diese Eigenschaft, um festzustellen, ob die Statusbar sichtbar oder nicht ist.\n\n    if (StatusBar.isVisible) {\n        // do something\n    }\n    \n\n## Unterstützte Plattformen\n\n*   iOS\n*   Android\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone-8.1\n"
  },
  {
    "path": "plugins/cordova-plugin-statusbar/doc/es/README.md",
    "content": "<!---\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-statusbar\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-statusbar.svg)](https://travis-ci.org/apache/cordova-plugin-statusbar)\n\n# StatusBar\n\n> El `StatusBar` objeto proporciona algunas funciones para personalizar el iOS y Android StatusBar.\n\n## Instalación\n\n    cordova plugin add cordova-plugin-statusbar\n    \n\n## Preferencias\n\n#### config.xml\n\n  * **StatusBarOverlaysWebView** (boolean, true por defecto). En iOS 7, hacer la superposición statusbar o no superponer la WebView al inicio.\n    \n        <preference name=\"StatusBarOverlaysWebView\" value=\"true\" />\n        \n\n  * **StatusBarBackgroundColor** (color hex string por defecto #000000). IOS 7 y 5 Android, configurar el color de fondo de la barra de estado por una cadena hexadecimal (#RRGGBB) en el arranque.\n    \n        <preference name=\"StatusBarBackgroundColor\" value=\"#000000\" />\n        \n\n  * **StatusBarStyle** (status bar estilo por defecto lightcontent). En iOS 7, definir el estilo de barra de estado. Por defecto las opciones disponibles, lightcontent, blacktranslucent, blackopaque.\n    \n        <preference name=\"StatusBarStyle\" value=\"lightcontent\" />\n        \n\n### Rarezas Android\n\nAndroid 5 + pautas especifican utilizando un color diferente para la barra de estado que la aplicación principal de color (a diferencia del color de barra de estado uniforme de muchas apps de iOS 7 +), por lo que puede establecer el color de la barra de estado en tiempo de ejecución en su lugar a través de `StatusBar.backgroundColorByHexString` o `StatusBar.backgroundColorByName`. Una forma de hacerlo sería:\n\n```js\nif (cordova.platformId == 'android') {\n    StatusBar.backgroundColorByHexString(\"#333\");\n}\n```\n\n## Escondido en el arranque\n\nDurante el tiempo de ejecución puede utilizar la función StatusBar.hide abajo, pero si quieres la barra de estado que está escondido en el inicio de la aplicación, se debe modificar el archivo Info.plist de su aplicación.\n\nAgregar/editar estos dos atributos si no está presente. Defina **\"inicialmente se esconde la barra de estado\"** a **\"YES\"** y **\"Aparición de vista basado en controlador estatus bar\"** a **\"NO\"**. Si se edita manualmente sin Xcode, las claves y valores son:\n\n    <key>UIStatusBarHidden</key>\n    <true/>\n    <key>UIViewControllerBasedStatusBarAppearance</key>\n    <false/>\n    \n\n## Métodos\n\nEste plugin define global `StatusBar` objeto.\n\nAunque en el ámbito global, no estará disponible hasta después de la `deviceready` evento.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(StatusBar);\n    }\n    \n\n  * StatusBar.overlaysWebView\n  * StatusBar.styleDefault\n  * StatusBar.styleLightContent\n  * StatusBar.styleBlackTranslucent\n  * StatusBar.styleBlackOpaque\n  * StatusBar.backgroundColorByName\n  * StatusBar.backgroundColorByHexString\n  * StatusBar.hide\n  * StatusBar.show\n\n## Propiedades\n\n  * StatusBar.isVisible\n\n## Permisos\n\n#### config.xml\n\n            <feature name=\"StatusBar\">\n                <param name=\"ios-package\" value=\"CDVStatusBar\" onload=\"true\" />\n            </feature>\n    \n\n# StatusBar.overlaysWebView\n\nEn iOS 7, hacer la barra de estado superposición o no superponer la vista Web.\n\n    StatusBar.overlaysWebView(true);\n    \n\n## Descripción\n\nEn iOS 7, establecida en false para que la barra de estado aparezca como iOS 6. Establece el color de fondo y estilo para utilizar las otras funciones.\n\n## Plataformas soportadas\n\n  * iOS\n\n## Ejemplo rápido\n\n    StatusBar.overlaysWebView(true);\n    StatusBar.overlaysWebView(false);\n    \n\n# StatusBar.styleDefault\n\nUtilice la barra de estado por defecto (texto oscuro, para fondos de luz).\n\n    StatusBar.styleDefault();\n    \n\n## Plataformas soportadas\n\n  * iOS\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.styleLightContent\n\nUtilice la barra de estado lightContent (texto ligero, para fondos oscuros).\n\n    StatusBar.styleLightContent();\n    \n\n## Plataformas soportadas\n\n  * iOS\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.styleBlackTranslucent\n\nUtilice la barra de estado blackTranslucent (texto ligero, para fondos oscuros).\n\n    StatusBar.styleBlackTranslucent();\n    \n\n## Plataformas soportadas\n\n  * iOS\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.styleBlackOpaque\n\nUtilice la barra de estado blackOpaque (texto ligero, para fondos oscuros).\n\n    StatusBar.styleBlackOpaque();\n    \n\n## Plataformas soportadas\n\n  * iOS\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.backgroundColorByName\n\nEn iOS 7, al establecer StatusBar.statusBarOverlaysWebView a false, se puede establecer el color de fondo de la barra de estado nombre del color.\n\n    StatusBar.backgroundColorByName(\"red\");\n    \n\nNombres de los colores admitidos son:\n\n    black, darkGray, lightGray, white, gray, red, green, blue, cyan, yellow, magenta, orange, purple, brown\n    \n\n## Plataformas soportadas\n\n  * iOS\n  * Android 5+\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.backgroundColorByHexString\n\nEstablece el color de fondo de la barra de estado por una cadena hexadecimal.\n\n    StatusBar.backgroundColorByHexString(\"#C0C0C0\");\n    \n\nPropiedades CSS abreviada también son compatibles.\n\n    StatusBar.backgroundColorByHexString(\"#333\"); // => #333333\n    StatusBar.backgroundColorByHexString(\"#FAB\"); // => #FFAABB\n    \n\nEn iOS 7, cuando se establece StatusBar.statusBarOverlaysWebView en false, se puede establecer el color de fondo de la barra de estado una cadena hexadecimal (#RRGGBB).\n\nEn WP7 y WP8 también puede especificar valores como #AARRGGBB, donde AA es un valor alfa\n\n## Plataformas soportadas\n\n  * iOS\n  * Android 5+\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.hide\n\nOcultar la barra de estado.\n\n    StatusBar.hide();\n    \n\n## Plataformas soportadas\n\n  * iOS\n  * Android\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.show\n\nMuestra la barra de estado.\n\n    StatusBar.show();\n    \n\n## Plataformas soportadas\n\n  * iOS\n  * Android\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.isVisible\n\nLea esta propiedad para ver si la barra de estado es visible o no.\n\n    if (StatusBar.isVisible) {\n        // do something\n    }\n    \n\n## Plataformas soportadas\n\n  * iOS\n  * Android\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1"
  },
  {
    "path": "plugins/cordova-plugin-statusbar/doc/es/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-statusbar\n\n# StatusBar\n\n> El `StatusBar` objeto proporciona algunas funciones para personalizar el iOS y Android StatusBar.\n\n## Instalación\n\n    Cordova plugin agregar cordova-plugin-statusbar\n    \n\n## Preferencias\n\n#### config.xml\n\n*   **StatusBarOverlaysWebView** (boolean, true por defecto). En iOS 7, hacer la superposición statusbar o no superponer la WebView al inicio.\n    \n        <preference name=\"StatusBarOverlaysWebView\" value=\"true\" />\n        \n\n*   **StatusBarBackgroundColor** (cadena hexadecimal color, #000000 por defecto). En iOS 7, establecer el color de fondo de la barra de estado por una cadena hexadecimal (#RRGGBB) en el arranque.\n    \n        <preference name=\"StatusBarBackgroundColor\" value=\"#000000\" />\n        \n\n*   **StatusBarStyle** (status bar estilo por defecto lightcontent). En iOS 7, definir el estilo de barra de estado. Por defecto las opciones disponibles, lightcontent, blacktranslucent, blackopaque.\n    \n        <preference name=\"StatusBarStyle\" value=\"lightcontent\" />\n        \n\n## Escondido en el arranque\n\nDurante el tiempo de ejecución puede utilizar la función StatusBar.hide abajo, pero si quieres la barra de estado que está escondido en el inicio de la aplicación, se debe modificar el archivo Info.plist de su aplicación.\n\nAgregar/editar estos dos atributos si no está presente. Defina **\"inicialmente se esconde la barra de estado\"** a **\"YES\"** y **\"Aparición de vista basado en controlador estatus bar\"** a **\"NO\"**. Si se edita manualmente sin Xcode, las claves y valores son:\n\n    < llave > UIStatusBarHidden < / key >< verdadero / >< llave > UIViewControllerBasedStatusBarAppearance < / key >< falso / >\n    \n\n## Métodos\n\nEste plugin define global `StatusBar` objeto.\n\nAunque en el ámbito global, no estará disponible hasta después de la `deviceready` evento.\n\n    document.addEventListener (\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {console.log(StatusBar)};\n    \n\n*   StatusBar.overlaysWebView\n*   StatusBar.styleDefault\n*   StatusBar.styleLightContent\n*   StatusBar.styleBlackTranslucent\n*   StatusBar.styleBlackOpaque\n*   StatusBar.backgroundColorByName\n*   StatusBar.backgroundColorByHexString\n*   StatusBar.hide\n*   StatusBar.show\n\n## Propiedades\n\n*   StatusBar.isVisible\n\n## Permisos\n\n#### config.xml\n\n            < nombre de la función = \"StatusBar\" >< nombre param = \"ios-paquete\" value = \"CDVStatusBar\" onload = \"true\" / >< / característica >\n    \n\n# StatusBar.overlaysWebView\n\nEn iOS 7, hacer la barra de estado superposición o no superponer la vista Web.\n\n    StatusBar.overlaysWebView(true);\n    \n\n## Descripción\n\nEn iOS 7, establecida en false para que la barra de estado aparezca como iOS 6. Establece el color de fondo y estilo para utilizar las otras funciones.\n\n## Plataformas soportadas\n\n*   iOS\n\n## Ejemplo rápido\n\n    StatusBar.overlaysWebView(true);\n    StatusBar.overlaysWebView(false);\n    \n\n# StatusBar.styleDefault\n\nUtilice la barra de estado por defecto (texto oscuro, para fondos de luz).\n\n    StatusBar.styleDefault();\n    \n\n## Plataformas soportadas\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.styleLightContent\n\nUtilice la barra de estado lightContent (texto ligero, para fondos oscuros).\n\n    StatusBar.styleLightContent();\n    \n\n## Plataformas soportadas\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.styleBlackTranslucent\n\nUtilice la barra de estado blackTranslucent (texto ligero, para fondos oscuros).\n\n    StatusBar.styleBlackTranslucent();\n    \n\n## Plataformas soportadas\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.styleBlackOpaque\n\nUtilice la barra de estado blackOpaque (texto ligero, para fondos oscuros).\n\n    StatusBar.styleBlackOpaque();\n    \n\n## Plataformas soportadas\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.backgroundColorByName\n\nEn iOS 7, al establecer StatusBar.statusBarOverlaysWebView a false, se puede establecer el color de fondo de la barra de estado nombre del color.\n\n    StatusBar.backgroundColorByName(\"red\");\n    \n\nNombres de los colores admitidos son:\n\n    negro, gris oscuro, lightGray, blanco, gris, rojo, verde, azul, cian, amarillo, magenta, naranja, púrpura, marrón\n    \n\n## Plataformas soportadas\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.backgroundColorByHexString\n\nEstablece el color de fondo de la barra de estado por una cadena hexadecimal.\n\n    StatusBar.backgroundColorByHexString(\"#C0C0C0\");\n    \n\nPropiedades CSS abreviada también son compatibles.\n\n    StatusBar.backgroundColorByHexString(\"#333\"); = > StatusBar.backgroundColorByHexString(\"#FAB\") #333333; = > #FFAABB\n    \n\nEn iOS 7, cuando se establece StatusBar.statusBarOverlaysWebView en false, se puede establecer el color de fondo de la barra de estado una cadena hexadecimal (#RRGGBB).\n\nEn WP7 y WP8 también puede especificar valores como #AARRGGBB, donde AA es un valor alfa\n\n## Plataformas soportadas\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.hide\n\nOcultar la barra de estado.\n\n    StatusBar.hide();\n    \n\n## Plataformas soportadas\n\n*   iOS\n*   Android\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.show\n\nMuestra la barra de estado.\n\n    StatusBar.show();\n    \n\n## Plataformas soportadas\n\n*   iOS\n*   Android\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.isVisible\n\nLea esta propiedad para ver si la barra de estado es visible o no.\n\n    Si (StatusBar.isVisible) {/ / hacer algo}\n    \n\n## Plataformas soportadas\n\n*   iOS\n*   Android\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n"
  },
  {
    "path": "plugins/cordova-plugin-statusbar/doc/fr/README.md",
    "content": "<!---\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-statusbar\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-statusbar.svg)](https://travis-ci.org/apache/cordova-plugin-statusbar)\n\n# StatusBar\n\n> Le `StatusBar` objet fournit quelques fonctions pour personnaliser les iOS et Android StatusBar.\n\n## Installation\n\n    cordova plugin add cordova-plugin-statusbar\n    \n\n## Préférences\n\n#### config.Xml\n\n  * **StatusBarOverlaysWebView** (boolean, la valeur par défaut true). Sur iOS 7, faire la superposition de statusbar ou pas superposition le WebView au démarrage.\n    \n        <preference name=\"StatusBarOverlaysWebView\" value=\"true\" />\n        \n\n  * **StatusBarBackgroundColor** (chaîne hexadécimale de couleur, par défaut, #000000). Sur iOS 7 et 5 Android, définir la couleur d'arrière-plan de la barre d'État par une chaîne hexadécimale (#RRGGBB) au démarrage.\n    \n        <preference name=\"StatusBarBackgroundColor\" value=\"#000000\" />\n        \n\n  * **StatusBarStyle** (style de barre de statut, par défaut, lightcontent). Sur iOS 7, définir le style de barre de statut. Par défaut les options disponibles, lightcontent, blacktranslucent, blackopaque.\n    \n        <preference name=\"StatusBarStyle\" value=\"lightcontent\" />\n        \n\n### Quirks Android\n\nLes lignes directrices 5 + Android spécifient à l'aide d'une couleur différente pour la barre d'État à votre application principale couleur (contrairement à la couleur uniforme statusbar de nombreuses applications iOS 7 +), donc vous pouvez définir la couleur de la barre d'état lors de l'exécution au lieu de cela via `StatusBar.backgroundColorByHexString` ou `StatusBar.backgroundColorByName`. Une façon de le faire serait :\n\n```js\nif (cordova.platformId == 'android') {\n    StatusBar.backgroundColorByHexString(\"#333\");\n}\n```\n\n## Cacher au démarrage\n\nPendant l'exécution, vous pouvez utiliser la fonction StatusBar.hide en bas, mais si vous souhaitez que la barre d'État pour être caché au démarrage de l'application, vous devez modifier le fichier Info.plist de votre application.\n\nAjouter/modifier ces deux attributs si n'est pas présent. **\"Barre d'État est initialement masqué\"** la valeur **\"** Yes\" et **\"À l'apparence vue sur contrôleur statut bar\"** la valeur **\"Non\"**. Si vous modifiez manuellement sans Xcode, les clés et les valeurs sont :\n\n    <key>UIStatusBarHidden</key>\n    <true/>\n    <key>UIViewControllerBasedStatusBarAppearance</key>\n    <false/>\n    \n\n## Méthodes\n\nCe plugin définit objet `StatusBar` global.\n\nBien que dans la portée globale, il n'est pas disponible jusqu'après la `deviceready` événement.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(StatusBar);\n    }\n    \n\n  * StatusBar.overlaysWebView\n  * StatusBar.styleDefault\n  * StatusBar.styleLightContent\n  * StatusBar.styleBlackTranslucent\n  * StatusBar.styleBlackOpaque\n  * StatusBar.backgroundColorByName\n  * StatusBar.backgroundColorByHexString\n  * StatusBar.hide\n  * StatusBar.show\n\n## Propriétés\n\n  * StatusBar.isVisible\n\n## Autorisations\n\n#### config.Xml\n\n            <feature name=\"StatusBar\">\n                <param name=\"ios-package\" value=\"CDVStatusBar\" onload=\"true\" />\n            </feature>\n    \n\n# StatusBar.overlaysWebView\n\nSur iOS 7, faire la statusbar superposition ou pas superposer le WebView.\n\n    StatusBar.overlaysWebView(true);\n    \n\n## Description\n\nSur iOS 7, la valeur false pour afficher la barre d'État comme iOS 6. Définissez la couleur de style et d'arrière-plan en fonction de l'utilisation des autres fonctions.\n\n## Plates-formes supportées\n\n  * iOS\n\n## Exemple court\n\n    StatusBar.overlaysWebView(true);\n    StatusBar.overlaysWebView(false);\n    \n\n# StatusBar.styleDefault\n\nUtilisez la barre de statut par défaut (texte sombre, pour les arrière-plans lumineux).\n\n    StatusBar.styleDefault();\n    \n\n## Plates-formes supportées\n\n  * iOS\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.styleLightContent\n\nUtilisez la barre d'État lightContent (texte clair, des arrière-plans sombres).\n\n    StatusBar.styleLightContent();\n    \n\n## Plates-formes supportées\n\n  * iOS\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.styleBlackTranslucent\n\nUtilisez la barre d'État blackTranslucent (texte clair, des arrière-plans sombres).\n\n    StatusBar.styleBlackTranslucent();\n    \n\n## Plates-formes supportées\n\n  * iOS\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.styleBlackOpaque\n\nUtilisez la barre d'État blackOpaque (texte clair, des arrière-plans sombres).\n\n    StatusBar.styleBlackOpaque();\n    \n\n## Plates-formes supportées\n\n  * iOS\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.backgroundColorByName\n\nSur iOS 7, lorsque vous définissez StatusBar.statusBarOverlaysWebView sur false, vous pouvez définir la couleur d'arrière-plan de la barre d'État par nom de couleur.\n\n    StatusBar.backgroundColorByName(\"red\");\n    \n\nLes noms de couleurs prises en charge sont :\n\n    black, darkGray, lightGray, white, gray, red, green, blue, cyan, yellow, magenta, orange, purple, brown\n    \n\n## Plates-formes supportées\n\n  * iOS\n  * Android 5+\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.backgroundColorByHexString\n\nDéfinit la couleur d'arrière-plan de la barre d'État par une chaîne hexadécimale.\n\n    StatusBar.backgroundColorByHexString(\"#C0C0C0\");\n    \n\nPropriétés de raccourci CSS sont également pris en charge.\n\n    StatusBar.backgroundColorByHexString(\"#333\"); // => #333333\n    StatusBar.backgroundColorByHexString(\"#FAB\"); // => #FFAABB\n    \n\nSur iOS 7, lorsque vous définissez StatusBar.statusBarOverlaysWebView sur false, vous pouvez définir la couleur d'arrière-plan de la barre d'État par une chaîne hexadécimale (#RRGGBB).\n\nSur WP7 et WP8, vous pouvez également spécifier des valeurs comme #AARRGGBB, où AA représente une valeur alpha\n\n## Plates-formes supportées\n\n  * iOS\n  * Android 5+\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.hide\n\nMasquer la barre d'État.\n\n    StatusBar.hide();\n    \n\n## Plates-formes supportées\n\n  * iOS\n  * Android\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.show\n\nAffiche la barre d'État.\n\n    StatusBar.show();\n    \n\n## Plates-formes supportées\n\n  * iOS\n  * Android\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.isVisible\n\nLire cette propriété afin de voir si la barre d'État est visible ou non.\n\n    if (StatusBar.isVisible) {\n        // do something\n    }\n    \n\n## Plates-formes supportées\n\n  * iOS\n  * Android\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1"
  },
  {
    "path": "plugins/cordova-plugin-statusbar/doc/fr/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-statusbar\n\n# StatusBar\n\n> Le `StatusBar` objet fournit quelques fonctions pour personnaliser les iOS et Android StatusBar.\n\n## Installation\n\n    cordova plugin add cordova-plugin-statusbar\n    \n\n## Préférences\n\n#### config.xml\n\n*   **StatusBarOverlaysWebView** (boolean, la valeur par défaut true). Sur iOS 7, faire la superposition de statusbar ou pas superposition le WebView au démarrage.\n    \n        <preference name=\"StatusBarOverlaysWebView\" value=\"true\" />\n        \n\n*   **StatusBarBackgroundColor** (chaîne hexadécimale de couleur, par défaut, #000000). Sur iOS 7, définir la couleur d'arrière-plan de la barre d'État par une chaîne hexadécimale (#RRGGBB) au démarrage.\n    \n        <preference name=\"StatusBarBackgroundColor\" value=\"#000000\" />\n        \n\n*   **StatusBarStyle** (style de barre de statut, par défaut, lightcontent). Sur iOS 7, définir le style de barre de statut. Par défaut les options disponibles, lightcontent, blacktranslucent, blackopaque.\n    \n        <preference name=\"StatusBarStyle\" value=\"lightcontent\" />\n        \n\n## Cacher au démarrage\n\nPendant l'exécution, vous pouvez utiliser la fonction StatusBar.hide en bas, mais si vous souhaitez que la barre d'État pour être caché au démarrage de l'application, vous devez modifier le fichier Info.plist de votre application.\n\nAjouter/modifier ces deux attributs si n'est pas présent. **\"Barre d'État est initialement masqué\"** la valeur **\"** Yes\" et **\"À l'apparence vue sur contrôleur statut bar\"** la valeur **\"Non\"**. Si vous modifiez manuellement sans Xcode, les clés et les valeurs sont :\n\n    <key>UIStatusBarHidden</key>\n    <true/>\n    <key>UIViewControllerBasedStatusBarAppearance</key>\n    <false/>\n    \n\n## Méthodes\n\nCe plugin définit objet `StatusBar` global.\n\nBien que dans la portée globale, il n'est pas disponible jusqu'après la `deviceready` événement.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(StatusBar);\n    }\n    \n\n*   StatusBar.overlaysWebView\n*   StatusBar.styleDefault\n*   StatusBar.styleLightContent\n*   StatusBar.styleBlackTranslucent\n*   StatusBar.styleBlackOpaque\n*   StatusBar.backgroundColorByName\n*   StatusBar.backgroundColorByHexString\n*   StatusBar.hide\n*   StatusBar.show\n\n## Propriétés\n\n*   StatusBar.isVisible\n\n## Autorisations\n\n#### config.xml\n\n            <feature name=\"StatusBar\">\n                <param name=\"ios-package\" value=\"CDVStatusBar\" onload=\"true\" />\n            </feature>\n    \n\n# StatusBar.overlaysWebView\n\nSur iOS 7, faire la statusbar superposition ou pas superposer le WebView.\n\n    StatusBar.overlaysWebView(true);\n    \n\n## Description\n\nSur iOS 7, la valeur false pour afficher la barre d'État comme iOS 6. Définissez la couleur de style et d'arrière-plan en fonction de l'utilisation des autres fonctions.\n\n## Plates-formes supportées\n\n*   iOS\n\n## Exemple court\n\n    StatusBar.overlaysWebView(true);\n    StatusBar.overlaysWebView(false);\n    \n\n# StatusBar.styleDefault\n\nUtilisez la barre de statut par défaut (texte sombre, pour les arrière-plans lumineux).\n\n    StatusBar.styleDefault();\n    \n\n## Plates-formes prises en charge\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.styleLightContent\n\nUtilisez la barre d'État lightContent (texte clair, des arrière-plans sombres).\n\n    StatusBar.styleLightContent();\n    \n\n## Plates-formes prises en charge\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.styleBlackTranslucent\n\nUtilisez la barre d'État blackTranslucent (texte clair, des arrière-plans sombres).\n\n    StatusBar.styleBlackTranslucent();\n    \n\n## Plates-formes prises en charge\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.styleBlackOpaque\n\nUtilisez la barre d'État blackOpaque (texte clair, des arrière-plans sombres).\n\n    StatusBar.styleBlackOpaque();\n    \n\n## Plates-formes prises en charge\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.backgroundColorByName\n\nSur iOS 7, lorsque vous définissez StatusBar.statusBarOverlaysWebView sur false, vous pouvez définir la couleur d'arrière-plan de la barre d'État par nom de couleur.\n\n    StatusBar.backgroundColorByName(\"red\");\n    \n\nLes noms de couleurs prises en charge sont :\n\n    black, darkGray, lightGray, white, gray, red, green, blue, cyan, yellow, magenta, orange, purple, brown\n    \n\n## Plates-formes prises en charge\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.backgroundColorByHexString\n\nDéfinit la couleur d'arrière-plan de la barre d'État par une chaîne hexadécimale.\n\n    StatusBar.backgroundColorByHexString(\"#C0C0C0\");\n    \n\nPropriétés de raccourci CSS sont également pris en charge.\n\n    StatusBar.backgroundColorByHexString(\"#333\"); // => #333333\n    StatusBar.backgroundColorByHexString(\"#FAB\"); // => #FFAABB\n    \n\nSur iOS 7, lorsque vous définissez StatusBar.statusBarOverlaysWebView sur false, vous pouvez définir la couleur d'arrière-plan de la barre d'État par une chaîne hexadécimale (#RRGGBB).\n\nSur WP7 et WP8, vous pouvez également spécifier des valeurs comme #AARRGGBB, où AA représente une valeur alpha\n\n## Plates-formes prises en charge\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.hide\n\nMasquer la barre d'État.\n\n    StatusBar.hide();\n    \n\n## Plates-formes prises en charge\n\n*   iOS\n*   Android\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.show\n\nAffiche la barre d'État.\n\n    StatusBar.show();\n    \n\n## Plates-formes prises en charge\n\n*   iOS\n*   Android\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.isVisible\n\nLire cette propriété afin de voir si la barre d'État est visible ou non.\n\n    if (StatusBar.isVisible) {\n        // do something\n    }\n    \n\n## Plates-formes supportées\n\n*   iOS\n*   Android\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n"
  },
  {
    "path": "plugins/cordova-plugin-statusbar/doc/it/README.md",
    "content": "<!---\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-statusbar\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-statusbar.svg)](https://travis-ci.org/apache/cordova-plugin-statusbar)\n\n# StatusBar\n\n> Il `StatusBar` oggetto fornisce alcune funzioni per personalizzare l'iOS e Android StatusBar.\n\n## Installazione\n\n    cordova plugin add cordova-plugin-statusbar\n    \n\n## Preferenze\n\n#### config. XML\n\n  * **StatusBarOverlaysWebView** (boolean, default è true). IOS 7, rendono la statusbar sovrapposizione o la non sovrapposizione WebView all'avvio.\n    \n        <preference name=\"StatusBarOverlaysWebView\" value=\"true\" />\n        \n\n  * **StatusBarBackgroundColor** (stringa esadecimale di colore, il valore predefinito è #000000). Su iOS 7 e 5 Android, è possibile impostare il colore di sfondo della barra di stato di una stringa esadecimale (#RRGGBB) all'avvio.\n    \n        <preference name=\"StatusBarBackgroundColor\" value=\"#000000\" />\n        \n\n  * **StatusBarStyle** (status bar in stile, default è lightcontent). IOS 7, impostare lo stile di barra di stato. Predefinita di opzioni disponibili, lightcontent, blacktranslucent, blackopaque.\n    \n        <preference name=\"StatusBarStyle\" value=\"lightcontent\" />\n        \n\n### Stranezze Android\n\nLe linee 5 + Android Guida specificano utilizzando un colore diverso per la barra di stato che l'app principale di colore (a differenza di colore uniforme statusbar di molte applicazioni di iOS 7 +), quindi si consiglia di impostare il colore della barra di stato in fase di esecuzione invece tramite `StatusBar.backgroundColorByHexString` o `StatusBar.backgroundColorByName`. Un modo per farlo sarebbe:\n\n```js\nif (cordova.platformId == 'android') {\n    StatusBar.backgroundColorByHexString(\"#333\");\n}\n```\n\n## Nascondendo all'avvio\n\nIn fase di esecuzione è possibile utilizzare la funzione di StatusBar.hide qui sotto, ma se si desidera che la barra di stato venga nascosta all'avvio di app, è necessario modificare il file info. plist dell'app.\n\nAggiungere o modificare questi due attributi, se non presente. Impostare la **\"barra di stato è inizialmente nascosto\"** a **\"YES\"** e **\"Aspetto di vista basati su controller status bar\"** a **\"NO\"**. Se si modifica manualmente senza Xcode, le chiavi e i valori sono:\n\n    <key>UIStatusBarHidden</key>\n    <true/>\n    <key>UIViewControllerBasedStatusBarAppearance</key>\n    <false/>\n    \n\n## Metodi\n\nQuesto plugin definisce globale oggetto `StatusBar`.\n\nAnche se in ambito globale, non è disponibile fino a dopo l'evento `deviceready`.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(StatusBar);\n    }\n    \n\n  * StatusBar.overlaysWebView\n  * StatusBar.styleDefault\n  * StatusBar.styleLightContent\n  * StatusBar.styleBlackTranslucent\n  * StatusBar.styleBlackOpaque\n  * StatusBar.backgroundColorByName\n  * StatusBar.backgroundColorByHexString\n  * StatusBar.hide\n  * StatusBar.show\n\n## Proprietà\n\n  * StatusBar.isVisible\n\n## Autorizzazioni\n\n#### config. XML\n\n            <feature name=\"StatusBar\">\n                <param name=\"ios-package\" value=\"CDVStatusBar\" onload=\"true\" />\n            </feature>\n    \n\n# StatusBar.overlaysWebView\n\nIOS 7, rendono la statusbar sovrapposizione o non sovrapporre WebView.\n\n    StatusBar.overlaysWebView(true);\n    \n\n## Descrizione\n\nIOS 7, impostato su false per rendere la barra di stato vengono visualizzati come iOS 6. Impostare il colore di sfondo e stile per soddisfare utilizzando altre funzioni.\n\n## Piattaforme supportate\n\n  * iOS\n\n## Esempio rapido\n\n    StatusBar.overlaysWebView(true);\n    StatusBar.overlaysWebView(false);\n    \n\n# StatusBar.styleDefault\n\nUtilizzare la barra di stato predefinito (testo scuro, per sfondi di luce).\n\n    StatusBar.styleDefault();\n    \n\n## Piattaforme supportate\n\n  * iOS\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.styleLightContent\n\nUtilizzare la barra di stato lightContent (testo in chiaro, per sfondi scuri).\n\n    StatusBar.styleLightContent();\n    \n\n## Piattaforme supportate\n\n  * iOS\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.styleBlackTranslucent\n\nUtilizzare la barra di stato blackTranslucent (testo in chiaro, per sfondi scuri).\n\n    StatusBar.styleBlackTranslucent();\n    \n\n## Piattaforme supportate\n\n  * iOS\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.styleBlackOpaque\n\nUtilizzare la barra di stato blackOpaque (testo in chiaro, per sfondi scuri).\n\n    StatusBar.styleBlackOpaque();\n    \n\n## Piattaforme supportate\n\n  * iOS\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.backgroundColorByName\n\nIOS 7, quando StatusBar.statusBarOverlaysWebView è impostata su false, è possibile impostare il colore di sfondo della barra di stato con il nome di colore.\n\n    StatusBar.backgroundColorByName(\"red\");\n    \n\nNomi di colore supportati sono:\n\n    black, darkGray, lightGray, white, gray, red, green, blue, cyan, yellow, magenta, orange, purple, brown\n    \n\n## Piattaforme supportate\n\n  * iOS\n  * Android 5+\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.backgroundColorByHexString\n\nImposta il colore di sfondo della barra di stato di una stringa esadecimale.\n\n    StatusBar.backgroundColorByHexString(\"#C0C0C0\");\n    \n\nProprietà di scrittura stenografica CSS sono supportati anche.\n\n    StatusBar.backgroundColorByHexString(\"#333\"); // => #333333\n    StatusBar.backgroundColorByHexString(\"#FAB\"); // => #FFAABB\n    \n\nIOS 7, quando StatusBar.statusBarOverlaysWebView è impostata su false, è possibile impostare il colore di sfondo della barra di stato di una stringa esadecimale (#RRGGBB).\n\nSu WP7 e WP8 è inoltre possibile specificare i valori come #AARRGGBB, dove AA è un valore alfa\n\n## Piattaforme supportate\n\n  * iOS\n  * Android 5+\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.hide\n\nNascondere la barra di stato.\n\n    StatusBar.hide();\n    \n\n## Piattaforme supportate\n\n  * iOS\n  * Android\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.show\n\nMostra la barra di stato.\n\n    StatusBar.show();\n    \n\n## Piattaforme supportate\n\n  * iOS\n  * Android\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.isVisible\n\nLeggere questa proprietà per vedere se la barra di stato è visibile o no.\n\n    if (StatusBar.isVisible) {\n        // do something\n    }\n    \n\n## Piattaforme supportate\n\n  * iOS\n  * Android\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1"
  },
  {
    "path": "plugins/cordova-plugin-statusbar/doc/it/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-statusbar\n\n# StatusBar\n\n> Il `StatusBar` oggetto fornisce alcune funzioni per personalizzare l'iOS e Android StatusBar.\n\n## Installazione\n\n    cordova plugin add cordova-plugin-statusbar\n    \n\n## Preferenze\n\n#### config.xml\n\n*   **StatusBarOverlaysWebView** (boolean, default è true). IOS 7, rendono la statusbar sovrapposizione o la non sovrapposizione WebView all'avvio.\n    \n        <preference name=\"StatusBarOverlaysWebView\" value=\"true\" />\n        \n\n*   **StatusBarBackgroundColor** (stringa esadecimale colore, predefinito è #000000). IOS 7, impostare il colore di sfondo della barra di stato di una stringa esadecimale (#RRGGBB) all'avvio.\n    \n        <preference name=\"StatusBarBackgroundColor\" value=\"#000000\" />\n        \n\n*   **StatusBarStyle** (status bar in stile, default è lightcontent). IOS 7, impostare lo stile di barra di stato. Predefinita di opzioni disponibili, lightcontent, blacktranslucent, blackopaque.\n    \n        <preference name=\"StatusBarStyle\" value=\"lightcontent\" />\n        \n\n## Nascondendo all'avvio\n\nIn fase di esecuzione è possibile utilizzare la funzione di StatusBar.hide qui sotto, ma se si desidera che la barra di stato venga nascosta all'avvio di app, è necessario modificare il file info. plist dell'app.\n\nAggiungere o modificare questi due attributi, se non presente. Impostare la **\"barra di stato è inizialmente nascosto\"** a **\"YES\"** e **\"Aspetto di vista basati su controller status bar\"** a **\"NO\"**. Se si modifica manualmente senza Xcode, le chiavi e i valori sono:\n\n    <key>UIStatusBarHidden</key>\n    <true/>\n    <key>UIViewControllerBasedStatusBarAppearance</key>\n    <false/>\n    \n\n## Metodi\n\nQuesto plugin definisce globale oggetto `StatusBar`.\n\nAnche se in ambito globale, non è disponibile fino a dopo l'evento `deviceready`.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(StatusBar);\n    }\n    \n\n*   StatusBar.overlaysWebView\n*   StatusBar.styleDefault\n*   StatusBar.styleLightContent\n*   StatusBar.styleBlackTranslucent\n*   StatusBar.styleBlackOpaque\n*   StatusBar.backgroundColorByName\n*   StatusBar.backgroundColorByHexString\n*   StatusBar.hide\n*   StatusBar.show\n\n## Proprietà\n\n*   StatusBar.isVisible\n\n## Autorizzazioni\n\n#### config.xml\n\n            <feature name=\"StatusBar\">\n                <param name=\"ios-package\" value=\"CDVStatusBar\" onload=\"true\" />\n            </feature>\n    \n\n# StatusBar.overlaysWebView\n\nIOS 7, rendono la statusbar sovrapposizione o non sovrapporre WebView.\n\n    StatusBar.overlaysWebView(true);\n    \n\n## Descrizione\n\nIOS 7, impostato su false per rendere la barra di stato vengono visualizzati come iOS 6. Impostare il colore di sfondo e stile per soddisfare utilizzando altre funzioni.\n\n## Piattaforme supportate\n\n*   iOS\n\n## Esempio rapido\n\n    StatusBar.overlaysWebView(true);\n    StatusBar.overlaysWebView(false);\n    \n\n# StatusBar.styleDefault\n\nUtilizzare la barra di stato predefinito (testo scuro, per sfondi di luce).\n\n    StatusBar.styleDefault();\n    \n\n## Piattaforme supportate\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.styleLightContent\n\nUtilizzare la barra di stato lightContent (testo in chiaro, per sfondi scuri).\n\n    StatusBar.styleLightContent();\n    \n\n## Piattaforme supportate\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.styleBlackTranslucent\n\nUtilizzare la barra di stato blackTranslucent (testo in chiaro, per sfondi scuri).\n\n    StatusBar.styleBlackTranslucent();\n    \n\n## Piattaforme supportate\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.styleBlackOpaque\n\nUtilizzare la barra di stato blackOpaque (testo in chiaro, per sfondi scuri).\n\n    StatusBar.styleBlackOpaque();\n    \n\n## Piattaforme supportate\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.backgroundColorByName\n\nIOS 7, quando StatusBar.statusBarOverlaysWebView è impostata su false, è possibile impostare il colore di sfondo della barra di stato con il nome di colore.\n\n    StatusBar.backgroundColorByName(\"red\");\n    \n\nNomi di colore supportati sono:\n\n    black, darkGray, lightGray, white, gray, red, green, blue, cyan, yellow, magenta, orange, purple, brown\n    \n\n## Piattaforme supportate\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.backgroundColorByHexString\n\nImposta il colore di sfondo della barra di stato di una stringa esadecimale.\n\n    StatusBar.backgroundColorByHexString(\"#C0C0C0\");\n    \n\nProprietà di scrittura stenografica CSS sono supportati anche.\n\n    StatusBar.backgroundColorByHexString(\"#333\"); // => #333333\n    StatusBar.backgroundColorByHexString(\"#FAB\"); // => #FFAABB\n    \n\nIOS 7, quando StatusBar.statusBarOverlaysWebView è impostata su false, è possibile impostare il colore di sfondo della barra di stato di una stringa esadecimale (#RRGGBB).\n\nSu WP7 e WP8 è inoltre possibile specificare i valori come #AARRGGBB, dove AA è un valore alfa\n\n## Piattaforme supportate\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.hide\n\nNascondere la barra di stato.\n\n    StatusBar.hide();\n    \n\n## Piattaforme supportate\n\n*   iOS\n*   Android\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.show\n\nMostra la barra di stato.\n\n    StatusBar.show();\n    \n\n## Piattaforme supportate\n\n*   iOS\n*   Android\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.isVisible\n\nLeggere questa proprietà per vedere se la barra di stato è visibile o no.\n\n    if (StatusBar.isVisible) {\n        // do something\n    }\n    \n\n## Piattaforme supportate\n\n*   iOS\n*   Android\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n"
  },
  {
    "path": "plugins/cordova-plugin-statusbar/doc/ja/README.md",
    "content": "<!---\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-statusbar\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-statusbar.svg)](https://travis-ci.org/apache/cordova-plugin-statusbar)\n\n# StatusBar\n\n> `StatusBar`オブジェクトは、iOS と Android ステータス バーをカスタマイズするいくつかの機能を提供します。\n\n## インストール\n\n    cordova plugin add cordova-plugin-statusbar\n    \n\n## 基本設定\n\n#### config.xml\n\n  * **StatusBarOverlaysWebView**(ブール値、デフォルトは true)。IOS 7、起動時にステータスバー オーバーレイまたはないオーバーレイ、WebView を作る。\n    \n        <preference name=\"StatusBarOverlaysWebView\" value=\"true\" />\n        \n\n  * **StatusBarBackgroundColor**(カラー 16 進文字列、既定値は #000000)。IOS 7 とアンドロイド 5、16 進文字列 (#RRGGBB) 起動時にステータスバーの背景色を設定します。\n    \n        <preference name=\"StatusBarBackgroundColor\" value=\"#000000\" />\n        \n\n  * **StatusBarStyle**(ステータス バーのスタイル、既定値は lightcontent)。Ios 7、ステータス バーのスタイルを設定します。使用可能なオプションのデフォルト、lightcontent、blacktranslucent、blackopaque。\n    \n        <preference name=\"StatusBarStyle\" value=\"lightcontent\" />\n        \n\n### Android の癖\n\nAndroid のガイドライン 5 + 指定メイン アプリよりもステータスバーの異なる色を使用して`StatusBar.backgroundColorByHexString`または`StatusBar.backgroundColorByName`経由で代わりに実行時にステータス バーの色を設定する場合がありますので (とは違って制服ステータスバー色多くの iOS 7 + アプリの) 色します。 それを行う方法の 1 つになります。\n\n```js\nif (cordova.platformId == 'android') {\n    StatusBar.backgroundColorByHexString(\"#333\");\n}\n```\n\n## 起動時に非表示\n\n実行時に下に、StatusBar.hide 関数を使用できますが、StatusBar アプリ起動時に非表示にする場合は、アプリの Info.plist ファイルを変更する必要があります。\n\nこれら 2 つの属性の追加/編集存在しない場合。 **「ステータス バーが非表示最初」** **\"YES\"**を設定し、 **「ビュー コント ローラー ベースのステータス バーの外観」** **\"NO\"**にします。 Xcode せず手動で編集する、キーと値は。\n\n    <key>UIStatusBarHidden</key>\n    <true/>\n    <key>UIViewControllerBasedStatusBarAppearance</key>\n    <false/>\n    \n\n## メソッド\n\nこのプラグインでは、グローバル `StatusBar` オブジェクトを定義します。\n\nグローバル スコープではあるがそれがないまで `deviceready` イベントの後です。\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(StatusBar);\n    }\n    \n\n  * StatusBar.overlaysWebView\n  * StatusBar.styleDefault\n  * StatusBar.styleLightContent\n  * StatusBar.styleBlackTranslucent\n  * StatusBar.styleBlackOpaque\n  * StatusBar.backgroundColorByName\n  * StatusBar.backgroundColorByHexString\n  * StatusBar.hide\n  * StatusBar.show\n\n## プロパティ\n\n  * StatusBar.isVisible\n\n## アクセス許可\n\n#### config.xml\n\n            <feature name=\"StatusBar\">\n                <param name=\"ios-package\" value=\"CDVStatusBar\" onload=\"true\" />\n            </feature>\n    \n\n# StatusBar.overlaysWebView\n\nIOS 7、statusbar オーバーレイまたはない WebView をオーバーレイします。\n\n    StatusBar.overlaysWebView(true);\n    \n\n## 解説\n\nIOS 7、iOS の 6 のように表示されるステータスバーを false に設定します。他の関数の使用に合わせてスタイルや背景色を設定します。\n\n## サポートされているプラットフォーム\n\n  * iOS\n\n## 簡単な例\n\n    StatusBar.overlaysWebView(true);\n    StatusBar.overlaysWebView(false);\n    \n\n# StatusBar.styleDefault\n\n既定ステータス バー (暗いテキスト、淡色の背景) を使用します。\n\n    StatusBar.styleDefault();\n    \n\n## サポートされているプラットフォーム\n\n  * iOS\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.styleLightContent\n\nLightContent ステータスバー (暗い背景の明るいテキスト） を使用します。\n\n    StatusBar.styleLightContent();\n    \n\n## サポートされているプラットフォーム\n\n  * iOS\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.styleBlackTranslucent\n\nBlackTranslucent ステータスバー (暗い背景の明るいテキスト） を使用します。\n\n    StatusBar.styleBlackTranslucent();\n    \n\n## サポートされているプラットフォーム\n\n  * iOS\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.styleBlackOpaque\n\nBlackOpaque ステータスバー (暗い背景の明るいテキスト） を使用します。\n\n    StatusBar.styleBlackOpaque();\n    \n\n## サポートされているプラットフォーム\n\n  * iOS\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.backgroundColorByName\n\nIos 7、StatusBar.statusBarOverlaysWebView を false に設定する場合はステータスバーの背景色の色の名前によって設定できます。\n\n    StatusBar.backgroundColorByName(\"red\");\n    \n\nサポートされている色の名前は次のとおりです。\n\n    black, darkGray, lightGray, white, gray, red, green, blue, cyan, yellow, magenta, orange, purple, brown\n    \n\n## サポートされているプラットフォーム\n\n  * iOS\n  * Android 5+\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.backgroundColorByHexString\n\n16 進文字列をステータス バーの背景色を設定します。\n\n    StatusBar.backgroundColorByHexString(\"#C0C0C0\");\n    \n\n速記の CSS プロパティもサポートされています。\n\n    StatusBar.backgroundColorByHexString(\"#333\"); // => #333333\n    StatusBar.backgroundColorByHexString(\"#FAB\"); // => #FFAABB\n    \n\nIos 7、StatusBar.statusBarOverlaysWebView を false に設定する場合はステータスバーの背景色を 16 進文字列 (#RRGGBB) で設定できます。\n\nWP7 と WP8 も指定できます値 #AARRGGBB, AA は、アルファ値として\n\n## サポートされているプラットフォーム\n\n  * iOS\n  * Android 5+\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.hide\n\nステータスバーを隠します。\n\n    StatusBar.hide();\n    \n\n## サポートされているプラットフォーム\n\n  * iOS\n  * アンドロイド\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.show\n\nステータス バーが表示されます。\n\n    StatusBar.show();\n    \n\n## サポートされているプラットフォーム\n\n  * iOS\n  * アンドロイド\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.isVisible\n\nこのプロパティ、ステータスバーが表示されるかどうかをお読みください。\n\n    if (StatusBar.isVisible) {\n        // do something\n    }\n    \n\n## サポートされているプラットフォーム\n\n  * iOS\n  * アンドロイド\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1"
  },
  {
    "path": "plugins/cordova-plugin-statusbar/doc/ja/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-statusbar\n\n# StatusBar\n\n> `StatusBar`オブジェクトは、iOS と Android ステータス バーをカスタマイズするいくつかの機能を提供します。\n\n## インストール\n\n    cordova plugin add cordova-plugin-statusbar\n    \n\n## 基本設定\n\n#### config.xml\n\n*   **StatusBarOverlaysWebView**(ブール値、デフォルトは true)。IOS 7、起動時にステータスバー オーバーレイまたはないオーバーレイ、WebView を作る。\n    \n        <preference name=\"StatusBarOverlaysWebView\" value=\"true\" />\n        \n\n*   **StatusBarBackgroundColor**（色 16 進文字列、デフォルトは ＃ 000000）。Ios 7、起動時に 16 進文字列 (#RRGGBB) でステータス バーの背景色を設定します。\n    \n        <preference name=\"StatusBarBackgroundColor\" value=\"#000000\" />\n        \n\n*   **StatusBarStyle**(ステータス バーのスタイル、既定値は lightcontent)。Ios 7、ステータス バーのスタイルを設定します。使用可能なオプションのデフォルト、lightcontent、blacktranslucent、blackopaque。\n    \n        <preference name=\"StatusBarStyle\" value=\"lightcontent\" />\n        \n\n## 起動時に非表示\n\n実行時に下に、StatusBar.hide 関数を使用できますが、StatusBar アプリ起動時に非表示にする場合は、アプリの Info.plist ファイルを変更する必要があります。\n\nこれら 2 つの属性の追加/編集存在しない場合。 **「ステータス バーが非表示最初」** **\"YES\"**を設定し、 **「ビュー コント ローラー ベースのステータス バーの外観」** **\"NO\"**にします。 Xcode せず手動で編集する、キーと値は。\n\n    <key>UIStatusBarHidden</key>\n    <true/>\n    <key>UIViewControllerBasedStatusBarAppearance</key>\n    <false/>\n    \n\n## メソッド\n\nこのプラグインでは、グローバル `StatusBar` オブジェクトを定義します。\n\nグローバル スコープではあるがそれがないまで `deviceready` イベントの後です。\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(StatusBar);\n    }\n    \n\n*   StatusBar.overlaysWebView\n*   StatusBar.styleDefault\n*   StatusBar.styleLightContent\n*   StatusBar.styleBlackTranslucent\n*   StatusBar.styleBlackOpaque\n*   StatusBar.backgroundColorByName\n*   StatusBar.backgroundColorByHexString\n*   StatusBar.hide\n*   StatusBar.show\n\n## プロパティ\n\n*   StatusBar.isVisible\n\n## アクセス許可\n\n#### config.xml\n\n            <feature name=\"StatusBar\">\n                <param name=\"ios-package\" value=\"CDVStatusBar\" onload=\"true\" />\n            </feature>\n    \n\n# StatusBar.overlaysWebView\n\nIOS 7、statusbar オーバーレイまたはない WebView をオーバーレイします。\n\n    StatusBar.overlaysWebView(true);\n    \n\n## 解説\n\nIOS 7、iOS の 6 のように表示されるステータスバーを false に設定します。他の関数の使用に合わせてスタイルや背景色を設定します。\n\n## サポートされているプラットフォーム\n\n*   iOS\n\n## 簡単な例\n\n    StatusBar.overlaysWebView(true);\n    StatusBar.overlaysWebView(false);\n    \n\n# StatusBar.styleDefault\n\n既定ステータス バー (暗いテキスト、淡色の背景) を使用します。\n\n    StatusBar.styleDefault();\n    \n\n## サポートされているプラットフォーム\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.styleLightContent\n\nLightContent ステータスバー (暗い背景の明るいテキスト） を使用します。\n\n    StatusBar.styleLightContent();\n    \n\n## サポートされているプラットフォーム\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.styleBlackTranslucent\n\nBlackTranslucent ステータスバー (暗い背景の明るいテキスト） を使用します。\n\n    StatusBar.styleBlackTranslucent();\n    \n\n## サポートされているプラットフォーム\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.styleBlackOpaque\n\nBlackOpaque ステータスバー (暗い背景の明るいテキスト） を使用します。\n\n    StatusBar.styleBlackOpaque();\n    \n\n## サポートされているプラットフォーム\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.backgroundColorByName\n\nIos 7、StatusBar.statusBarOverlaysWebView を false に設定する場合はステータスバーの背景色の色の名前によって設定できます。\n\n    StatusBar.backgroundColorByName(\"red\");\n    \n\nサポートされている色の名前は次のとおりです。\n\n    black, darkGray, lightGray, white, gray, red, green, blue, cyan, yellow, magenta, orange, purple, brown\n    \n\n## サポートされているプラットフォーム\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.backgroundColorByHexString\n\n16 進文字列をステータス バーの背景色を設定します。\n\n    StatusBar.backgroundColorByHexString(\"#C0C0C0\");\n    \n\n速記の CSS プロパティもサポートされています。\n\n    StatusBar.backgroundColorByHexString(\"#333\"); // => #333333\n    StatusBar.backgroundColorByHexString(\"#FAB\"); // => #FFAABB\n    \n\nIos 7、StatusBar.statusBarOverlaysWebView を false に設定する場合はステータスバーの背景色を 16 進文字列 (#RRGGBB) で設定できます。\n\nWP7 と WP8 も指定できます値 #AARRGGBB, AA は、アルファ値として\n\n## サポートされているプラットフォーム\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.hide\n\nステータスバーを隠します。\n\n    StatusBar.hide();\n    \n\n## サポートされているプラットフォーム\n\n*   iOS\n*   アンドロイド\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.show\n\nステータス バーが表示されます。\n\n    StatusBar.show();\n    \n\n## サポートされているプラットフォーム\n\n*   iOS\n*   アンドロイド\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.isVisible\n\nこのプロパティ、ステータスバーが表示されるかどうかをお読みください。\n\n    if (StatusBar.isVisible) {\n        // do something\n    }\n    \n\n## サポートされているプラットフォーム\n\n*   iOS\n*   アンドロイド\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n"
  },
  {
    "path": "plugins/cordova-plugin-statusbar/doc/ko/README.md",
    "content": "<!---\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-statusbar\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-statusbar.svg)](https://travis-ci.org/apache/cordova-plugin-statusbar)\n\n# StatusBar\n\n> `StatusBar`개체 iOS와 안 드 로이드 상태 표시줄을 사용자 지정 하려면 몇 가지 기능을 제공 합니다.\n\n## 설치\n\n    cordova plugin add cordova-plugin-statusbar\n    \n\n## 환경 설정\n\n#### config.xml\n\n  * **StatusBarOverlaysWebView** (boolean, 기본값: true)입니다. IOS 7, 시작 시 상태 표시줄 오버레이 또는 WebView 중첩 되지 확인 합니다.\n    \n        <preference name=\"StatusBarOverlaysWebView\" value=\"true\" />\n        \n\n  * **StatusBarBackgroundColor** (색상 16 진수 문자열 기본값: #000000). IOS에서 7과 안 드 로이드 5 시작 시 16 진수 문자열 (#RRGGBB) 상태 표시줄의 배경색을 설정 합니다.\n    \n        <preference name=\"StatusBarBackgroundColor\" value=\"#000000\" />\n        \n\n  * **StatusBarStyle** (상태 표시줄 스타일, 기본값: lightcontent). Ios 7, 상태 표시줄 스타일을 설정 합니다. 사용 가능한 옵션 기본, lightcontent, blacktranslucent, blackopaque.\n    \n        <preference name=\"StatusBarStyle\" value=\"lightcontent\" />\n        \n\n### 안 드 로이드 단점\n\n안 드 로이드 5 + 지침 보다 귀하의 주요 응용 프로그램 상태 표시줄에 대 한 다른 색을 사용 하 여 지정한 색상 (와 달리 균일 한 상태 표시줄의 색상 많은 iOS 7 + 애플 리 케이 션), `StatusBar.backgroundColorByHexString` 또는 `StatusBar.backgroundColorByName`를 통해 대신 런타임에 상태 표시줄 색을 설정 하고자 할 수 있습니다. 한 가지 방법은 일 것입니다.\n\n```js\nif (cordova.platformId == 'android') {\n    StatusBar.backgroundColorByHexString(\"#333\");\n}\n```\n\n## 시작 시 숨기기\n\n런타임 동안 아래의 StatusBar.hide 함수를 사용할 수 있습니다 하지만 당신이 원하는 응용 프로그램 시작 시 숨겨진 상태 표시줄, 응용 프로그램의 Info.plist 파일 수정 해야 합니다.\n\n추가 편집이 두 특성이 없는 경우. **\"상태 표시줄 처음 숨겨진\"** **\"YES\"** 로 설정 하 고 **\"뷰 컨트롤러 기반 상태 표시줄 모양\"** **\"NO\"**로 설정 합니다. Xcode, 열쇠 없이 수동으로 편집 하는 경우 값은:\n\n    <key>UIStatusBarHidden</key>\n    <true/>\n    <key>UIViewControllerBasedStatusBarAppearance</key>\n    <false/>\n    \n\n## 메서드\n\n이 플러그인 글로벌 `StatusBar` 개체를 정의합니다.\n\n전역 범위에 있지만 그것은 불가능까지 `deviceready` 이벤트 후.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(StatusBar);\n    }\n    \n\n  * StatusBar.overlaysWebView\n  * StatusBar.styleDefault\n  * StatusBar.styleLightContent\n  * StatusBar.styleBlackTranslucent\n  * StatusBar.styleBlackOpaque\n  * StatusBar.backgroundColorByName\n  * StatusBar.backgroundColorByHexString\n  * StatusBar.hide\n  * StatusBar.show\n\n## 속성\n\n  * StatusBar.isVisible\n\n## 사용 권한\n\n#### config.xml\n\n            <feature name=\"StatusBar\">\n                <param name=\"ios-package\" value=\"CDVStatusBar\" onload=\"true\" />\n            </feature>\n    \n\n# StatusBar.overlaysWebView\n\nIOS 7, 오버레이 또는 하지 WebView 중첩 상태 표시줄을 확인 합니다.\n\n    StatusBar.overlaysWebView(true);\n    \n\n## 설명\n\n7 iOS, iOS 6 처럼 나타나는 상태 표시줄을 false로 설정 합니다. 다른 함수를 사용 하 여에 맞게 스타일과 배경 색상을 설정 합니다.\n\n## 지원 되는 플랫폼\n\n  * iOS\n\n## 빠른 예제\n\n    StatusBar.overlaysWebView(true);\n    StatusBar.overlaysWebView(false);\n    \n\n# StatusBar.styleDefault\n\n기본 상태 표시줄 (어두운 텍스트, 밝은 배경에 대 한)를 사용 합니다.\n\n    StatusBar.styleDefault();\n    \n\n## 지원 되는 플랫폼\n\n  * iOS\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.styleLightContent\n\nLightContent 상태 표시줄 (어두운 배경에 대 한 가벼운 텍스트)을 사용 합니다.\n\n    StatusBar.styleLightContent();\n    \n\n## 지원 되는 플랫폼\n\n  * iOS\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.styleBlackTranslucent\n\nBlackTranslucent 상태 표시줄 (어두운 배경에 대 한 가벼운 텍스트)을 사용 합니다.\n\n    StatusBar.styleBlackTranslucent();\n    \n\n## 지원 되는 플랫폼\n\n  * iOS\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.styleBlackOpaque\n\nBlackOpaque 상태 표시줄 (어두운 배경에 대 한 가벼운 텍스트)을 사용 합니다.\n\n    StatusBar.styleBlackOpaque();\n    \n\n## 지원 되는 플랫폼\n\n  * iOS\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.backgroundColorByName\n\nIos 7, StatusBar.statusBarOverlaysWebView을 false로 설정 하면 설정할 수 있는 상태 표시줄의 배경색 색상 이름으로.\n\n    StatusBar.backgroundColorByName(\"red\");\n    \n\n지원 되는 색 이름입니다.\n\n    black, darkGray, lightGray, white, gray, red, green, blue, cyan, yellow, magenta, orange, purple, brown\n    \n\n## 지원 되는 플랫폼\n\n  * iOS\n  * Android 5+\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.backgroundColorByHexString\n\n16 진수 문자열 상태 표시줄의 배경색을 설정합니다.\n\n    StatusBar.backgroundColorByHexString(\"#C0C0C0\");\n    \n\nCSS 대표 속성 지원 됩니다.\n\n    StatusBar.backgroundColorByHexString(\"#333\"); // => #333333\n    StatusBar.backgroundColorByHexString(\"#FAB\"); // => #FFAABB\n    \n\nIos 7, StatusBar.statusBarOverlaysWebView을 false로 설정 하면 설정할 수 있는 상태 표시줄의 배경색 16 진수 문자열 (#RRGGBB)에 의해.\n\nWP7 및 WP8에 당신은 또한 #AARRGGBB, AA는 알파 값으로 값을 지정할 수 있습니다.\n\n## 지원 되는 플랫폼\n\n  * iOS\n  * Android 5+\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.hide\n\n숨기기 상태 표시줄.\n\n    StatusBar.hide();\n    \n\n## 지원 되는 플랫폼\n\n  * iOS\n  * 안 드 로이드\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.show\n\n상태 표시줄을 표시합니다.\n\n    StatusBar.show();\n    \n\n## 지원 되는 플랫폼\n\n  * iOS\n  * 안 드 로이드\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.isVisible\n\n이 속성을 상태 표시줄 표시 되는 경우 읽기.\n\n    if (StatusBar.isVisible) {\n        // do something\n    }\n    \n\n## 지원 되는 플랫폼\n\n  * iOS\n  * 안 드 로이드\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1"
  },
  {
    "path": "plugins/cordova-plugin-statusbar/doc/ko/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-statusbar\n\n# StatusBar\n\n> `StatusBar`개체 iOS와 안 드 로이드 상태 표시줄을 사용자 지정 하려면 몇 가지 기능을 제공 합니다.\n\n## 설치\n\n    cordova plugin add cordova-plugin-statusbar\n    \n\n## 환경 설정\n\n#### config.xml\n\n*   **StatusBarOverlaysWebView** (boolean, 기본값: true)입니다. IOS 7, 시작 시 상태 표시줄 오버레이 또는 WebView 중첩 되지 확인 합니다.\n    \n        <preference name=\"StatusBarOverlaysWebView\" value=\"true\" />\n        \n\n*   **StatusBarBackgroundColor** (색상 16 진수 문자열 기본값: #000000). Ios 7, 시작 시 16 진수 문자열 (#RRGGBB) 상태 표시줄의 배경색을 설정 합니다.\n    \n        <preference name=\"StatusBarBackgroundColor\" value=\"#000000\" />\n        \n\n*   **StatusBarStyle** (상태 표시줄 스타일, 기본값: lightcontent). Ios 7, 상태 표시줄 스타일을 설정 합니다. 사용 가능한 옵션 기본, lightcontent, blacktranslucent, blackopaque.\n    \n        <preference name=\"StatusBarStyle\" value=\"lightcontent\" />\n        \n\n## 시작 시 숨기기\n\n런타임 동안 아래의 StatusBar.hide 함수를 사용할 수 있습니다 하지만 당신이 원하는 응용 프로그램 시작 시 숨겨진 상태 표시줄, 응용 프로그램의 Info.plist 파일 수정 해야 합니다.\n\n추가 편집이 두 특성이 없는 경우. **\"상태 표시줄 처음 숨겨진\"** **\"YES\"** 로 설정 하 고 **\"뷰 컨트롤러 기반 상태 표시줄 모양\"** **\"NO\"**로 설정 합니다. Xcode, 열쇠 없이 수동으로 편집 하는 경우 값은:\n\n    <key>UIStatusBarHidden</key>\n    <true/>\n    <key>UIViewControllerBasedStatusBarAppearance</key>\n    <false/>\n    \n\n## 메서드\n\n이 플러그인 글로벌 `StatusBar` 개체를 정의합니다.\n\n전역 범위에 있지만 그것은 불가능까지 `deviceready` 이벤트 후.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(StatusBar);\n    }\n    \n\n*   StatusBar.overlaysWebView\n*   StatusBar.styleDefault\n*   StatusBar.styleLightContent\n*   StatusBar.styleBlackTranslucent\n*   StatusBar.styleBlackOpaque\n*   StatusBar.backgroundColorByName\n*   StatusBar.backgroundColorByHexString\n*   StatusBar.hide\n*   StatusBar.show\n\n## 속성\n\n*   StatusBar.isVisible\n\n## 사용 권한\n\n#### config.xml\n\n            <feature name=\"StatusBar\">\n                <param name=\"ios-package\" value=\"CDVStatusBar\" onload=\"true\" />\n            </feature>\n    \n\n# StatusBar.overlaysWebView\n\nIOS 7, 오버레이 또는 하지 WebView 중첩 상태 표시줄을 확인 합니다.\n\n    StatusBar.overlaysWebView(true);\n    \n\n## 설명\n\n7 iOS, iOS 6 처럼 나타나는 상태 표시줄을 false로 설정 합니다. 다른 함수를 사용 하 여에 맞게 스타일과 배경 색상을 설정 합니다.\n\n## 지원 되는 플랫폼\n\n*   iOS\n\n## 빠른 예제\n\n    StatusBar.overlaysWebView(true);\n    StatusBar.overlaysWebView(false);\n    \n\n# StatusBar.styleDefault\n\n기본 상태 표시줄 (어두운 텍스트, 밝은 배경에 대 한)를 사용 합니다.\n\n    StatusBar.styleDefault();\n    \n\n## 지원 되는 플랫폼\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.styleLightContent\n\nLightContent 상태 표시줄 (어두운 배경에 대 한 가벼운 텍스트)을 사용 합니다.\n\n    StatusBar.styleLightContent();\n    \n\n## 지원 되는 플랫폼\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.styleBlackTranslucent\n\nBlackTranslucent 상태 표시줄 (어두운 배경에 대 한 가벼운 텍스트)을 사용 합니다.\n\n    StatusBar.styleBlackTranslucent();\n    \n\n## 지원 되는 플랫폼\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.styleBlackOpaque\n\nBlackOpaque 상태 표시줄 (어두운 배경에 대 한 가벼운 텍스트)을 사용 합니다.\n\n    StatusBar.styleBlackOpaque();\n    \n\n## 지원 되는 플랫폼\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.backgroundColorByName\n\nIos 7, StatusBar.statusBarOverlaysWebView을 false로 설정 하면 설정할 수 있는 상태 표시줄의 배경색 색상 이름으로.\n\n    StatusBar.backgroundColorByName(\"red\");\n    \n\n지원 되는 색 이름입니다.\n\n    black, darkGray, lightGray, white, gray, red, green, blue, cyan, yellow, magenta, orange, purple, brown\n    \n\n## 지원 되는 플랫폼\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.backgroundColorByHexString\n\n16 진수 문자열 상태 표시줄의 배경색을 설정합니다.\n\n    StatusBar.backgroundColorByHexString(\"#C0C0C0\");\n    \n\nCSS 대표 속성 지원 됩니다.\n\n    StatusBar.backgroundColorByHexString(\"#333\"); // => #333333\n    StatusBar.backgroundColorByHexString(\"#FAB\"); // => #FFAABB\n    \n\nIos 7, StatusBar.statusBarOverlaysWebView을 false로 설정 하면 설정할 수 있는 상태 표시줄의 배경색 16 진수 문자열 (#RRGGBB)에 의해.\n\nWP7 및 WP8에 당신은 또한 #AARRGGBB, AA는 알파 값으로 값을 지정할 수 있습니다.\n\n## 지원 되는 플랫폼\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.hide\n\n숨기기 상태 표시줄.\n\n    StatusBar.hide();\n    \n\n## 지원 되는 플랫폼\n\n*   iOS\n*   안 드 로이드\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.show\n\n상태 표시줄을 표시합니다.\n\n    StatusBar.show();\n    \n\n## 지원 되는 플랫폼\n\n*   iOS\n*   안 드 로이드\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.isVisible\n\n이 속성을 상태 표시줄 표시 되는 경우 읽기.\n\n    if (StatusBar.isVisible) {\n        // do something\n    }\n    \n\n## 지원 되는 플랫폼\n\n*   iOS\n*   안 드 로이드\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n"
  },
  {
    "path": "plugins/cordova-plugin-statusbar/doc/pl/README.md",
    "content": "<!---\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-statusbar\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-statusbar.svg)](https://travis-ci.org/apache/cordova-plugin-statusbar)\n\n# StatusBar\n\n> `StatusBar`Obiekt zawiera kilka funkcji, aby dostosować iOS i Android StatusBar.\n\n## Instalacja\n\n    cordova plugin add cordova-plugin-statusbar\n    \n\n## Preferencje\n\n#### config.xml\n\n  * **StatusBarOverlaysWebView** (boolean, domyślnie na wartość true). Na iOS 7 zrobić nakładki stanu lub nie nakładki widoku sieci Web podczas uruchamiania.\n    \n        <preference name=\"StatusBarOverlaysWebView\" value=\"true\" />\n        \n\n  * **StatusBarBackgroundColor** (kolor ciąg szesnastkowy, domyślnie #000000). Na iOS 7 i Android 5 kolor tła stanu przez ciąg szesnastkowy (#RRGGBB) przy starcie systemu.\n    \n        <preference name=\"StatusBarBackgroundColor\" value=\"#000000\" />\n        \n\n  * **StatusBarStyle** (stan styl paska, domyślnie lightcontent.) Na iOS 7 ustawić styl paska stanu. Dostępne opcje domyślne, lightcontent, blacktranslucent, blackopaque.\n    \n        <preference name=\"StatusBarStyle\" value=\"lightcontent\" />\n        \n\n### Dziwactwa Androida\n\nAndroid 5 + wytyczne określają przy użyciu różnych kolorów statusbar niż główne aplikacji kolor (w przeciwieństwie do stanu jednolitych kolorów wiele aplikacje iOS 7 +), więc może chcesz ustawić kolor pasek stanu w czasie wykonywania zamiast za pośrednictwem `StatusBar.backgroundColorByHexString` lub `StatusBar.backgroundColorByName`. Jednym sposobem na to byłoby:\n\n```js\nif (cordova.platformId == 'android') {\n    StatusBar.backgroundColorByHexString(\"#333\");\n}\n```\n\n## Przy starcie\n\nPodczas uruchamiania można użyć funkcji StatusBar.hide poniżej, ale jeśli chcesz StatusBar ukryty w uruchamiania aplikacji, należy zmodyfikować plik Info.plist Twojej aplikacji.\n\nDodawanie/edycja tych dwóch atrybutów jeśli nie obecny. Ustawianie **\"pasek stanu jest początkowo ukryte\"** na **\"Tak\"** i **\"Oparte na kontroler stanu paska wygląd\"** na **\"Nie\"**. Jeśli możesz go edytować ręcznie bez Xcode, kluczy i wartości są:\n\n    <key>UIStatusBarHidden</key>\n    <true/>\n    <key>UIViewControllerBasedStatusBarAppearance</key>\n    <false/>\n    \n\n## Metody\n\nTen plugin definiuje obiekt globalny `StatusBar`.\n\nChociaż w globalnym zasięgu, to nie dostępne dopiero po `deviceready` imprezie.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(StatusBar);\n    }\n    \n\n  * StatusBar.overlaysWebView\n  * StatusBar.styleDefault\n  * StatusBar.styleLightContent\n  * StatusBar.styleBlackTranslucent\n  * StatusBar.styleBlackOpaque\n  * StatusBar.backgroundColorByName\n  * StatusBar.backgroundColorByHexString\n  * StatusBar.hide\n  * StatusBar.show\n\n## Właściwości\n\n  * StatusBar.isVisible\n\n## Uprawnienia\n\n#### config.xml\n\n            <feature name=\"StatusBar\">\n                <param name=\"ios-package\" value=\"CDVStatusBar\" onload=\"true\" />\n            </feature>\n    \n\n# StatusBar.overlaysWebView\n\nNa iOS 7 zrobić statusbar nakładki lub nie nakładka widoku sieci Web.\n\n    StatusBar.overlaysWebView(true);\n    \n\n## Opis\n\nNa iOS 7 zestaw do false, aby na pasku stanu pojawia się jak iOS 6. Ustaw kolor tła i styl do korzystania z innych funkcji.\n\n## Obsługiwane platformy\n\n  * iOS\n\n## Szybki przykład\n\n    StatusBar.overlaysWebView(true);\n    StatusBar.overlaysWebView(false);\n    \n\n# StatusBar.styleDefault\n\nUżyj domyślnego stanu (ciemny tekst, teł światła).\n\n    StatusBar.styleDefault();\n    \n\n## Obsługiwane platformy\n\n  * iOS\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.styleLightContent\n\nUżyj lightContent stanu (światło tekst, ciemne tło).\n\n    StatusBar.styleLightContent();\n    \n\n## Obsługiwane platformy\n\n  * iOS\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.styleBlackTranslucent\n\nUżyj blackTranslucent stanu (światło tekst, ciemne tło).\n\n    StatusBar.styleBlackTranslucent();\n    \n\n## Obsługiwane platformy\n\n  * iOS\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.styleBlackOpaque\n\nUżyj blackOpaque stanu (światło tekst, ciemne tło).\n\n    StatusBar.styleBlackOpaque();\n    \n\n## Obsługiwane platformy\n\n  * iOS\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.backgroundColorByName\n\nNa iOS 7 gdy zostanie ustawiona wartość false, StatusBar.statusBarOverlaysWebView można ustawić kolor tła stanu przez nazwę koloru.\n\n    StatusBar.backgroundColorByName(\"red\");\n    \n\nNazwy kolorów obsługiwane są:\n\n    black, darkGray, lightGray, white, gray, red, green, blue, cyan, yellow, magenta, orange, purple, brown\n    \n\n## Obsługiwane platformy\n\n  * iOS\n  * Android 5+\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.backgroundColorByHexString\n\nUstawia kolor tła stanu przez ciąg szesnastkowy.\n\n    StatusBar.backgroundColorByHexString(\"#C0C0C0\");\n    \n\nObsługiwane są również właściwości CSS.\n\n    StatusBar.backgroundColorByHexString(\"#333\"); // => #333333\n    StatusBar.backgroundColorByHexString(\"#FAB\"); // => #FFAABB\n    \n\nNa iOS 7 gdy zostanie ustawiona wartość false, StatusBar.statusBarOverlaysWebView można ustawić kolor tła stanu przez ciąg szesnastkowy (#RRGGBB).\n\nNa WP7 i WP8 można również określić wartości jako #AARRGGBB, gdzie AA jest wartością alfa\n\n## Obsługiwane platformy\n\n  * iOS\n  * Android 5+\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.hide\n\nUkryj pasek stanu.\n\n    StatusBar.hide();\n    \n\n## Obsługiwane platformy\n\n  * iOS\n  * Android\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.show\n\nPokazuje pasek stanu.\n\n    StatusBar.show();\n    \n\n## Obsługiwane platformy\n\n  * iOS\n  * Android\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.isVisible\n\nCzytać tej właściwość, aby sprawdzić, czy stanu jest widoczne lub nie.\n\n    if (StatusBar.isVisible) {\n        // do something\n    }\n    \n\n## Obsługiwane platformy\n\n  * iOS\n  * Android\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1"
  },
  {
    "path": "plugins/cordova-plugin-statusbar/doc/pl/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-statusbar\n\n# StatusBar\n\n> `StatusBar`Obiekt zawiera kilka funkcji, aby dostosować iOS i Android StatusBar.\n\n## Instalacja\n\n    cordova plugin add cordova-plugin-statusbar\n    \n\n## Preferencje\n\n#### config.xml\n\n*   **StatusBarOverlaysWebView** (boolean, domyślnie na wartość true). Na iOS 7 zrobić nakładki stanu lub nie nakładki widoku sieci Web podczas uruchamiania.\n    \n        <preference name=\"StatusBarOverlaysWebView\" value=\"true\" />\n        \n\n*   **StatusBarBackgroundColor** (kolor szesnastkowy ciąg, domyślnie #000000). Na iOS 7 ustawić kolor tła stanu przez ciąg szesnastkowy (#RRGGBB) przy starcie systemu.\n    \n        <preference name=\"StatusBarBackgroundColor\" value=\"#000000\" />\n        \n\n*   **StatusBarStyle** (stan styl paska, domyślnie lightcontent.) Na iOS 7 ustawić styl paska stanu. Dostępne opcje domyślne, lightcontent, blacktranslucent, blackopaque.\n    \n        <preference name=\"StatusBarStyle\" value=\"lightcontent\" />\n        \n\n## Przy starcie\n\nPodczas uruchamiania można użyć funkcji StatusBar.hide poniżej, ale jeśli chcesz StatusBar ukryty w uruchamiania aplikacji, należy zmodyfikować plik Info.plist Twojej aplikacji.\n\nDodawanie/edycja tych dwóch atrybutów jeśli nie obecny. Ustawianie **\"pasek stanu jest początkowo ukryte\"** na **\"Tak\"** i **\"Oparte na kontroler stanu paska wygląd\"** na **\"Nie\"**. Jeśli możesz go edytować ręcznie bez Xcode, kluczy i wartości są:\n\n    <key>UIStatusBarHidden</key>\n    <true/>\n    <key>UIViewControllerBasedStatusBarAppearance</key>\n    <false/>\n    \n\n## Metody\n\nTen plugin definiuje obiekt globalny `StatusBar`.\n\nChociaż w globalnym zasięgu, to nie dostępne dopiero po `deviceready` imprezie.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(StatusBar);\n    }\n    \n\n*   StatusBar.overlaysWebView\n*   StatusBar.styleDefault\n*   StatusBar.styleLightContent\n*   StatusBar.styleBlackTranslucent\n*   StatusBar.styleBlackOpaque\n*   StatusBar.backgroundColorByName\n*   StatusBar.backgroundColorByHexString\n*   StatusBar.hide\n*   StatusBar.show\n\n## Właściwości\n\n*   StatusBar.isVisible\n\n## Uprawnienia\n\n#### config.xml\n\n            <feature name=\"StatusBar\">\n                <param name=\"ios-package\" value=\"CDVStatusBar\" onload=\"true\" />\n            </feature>\n    \n\n# StatusBar.overlaysWebView\n\nNa iOS 7 zrobić statusbar nakładki lub nie nakładka widoku sieci Web.\n\n    StatusBar.overlaysWebView(true);\n    \n\n## Opis\n\nNa iOS 7 zestaw do false, aby na pasku stanu pojawia się jak iOS 6. Ustaw kolor tła i styl do korzystania z innych funkcji.\n\n## Obsługiwane platformy\n\n*   iOS\n\n## Szybki przykład\n\n    StatusBar.overlaysWebView(true);\n    StatusBar.overlaysWebView(false);\n    \n\n# StatusBar.styleDefault\n\nUżyj domyślnego stanu (ciemny tekst, teł światła).\n\n    StatusBar.styleDefault();\n    \n\n## Obsługiwane platformy\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.styleLightContent\n\nUżyj lightContent stanu (światło tekst, ciemne tło).\n\n    StatusBar.styleLightContent();\n    \n\n## Obsługiwane platformy\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.styleBlackTranslucent\n\nUżyj blackTranslucent stanu (światło tekst, ciemne tło).\n\n    StatusBar.styleBlackTranslucent();\n    \n\n## Obsługiwane platformy\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.styleBlackOpaque\n\nUżyj blackOpaque stanu (światło tekst, ciemne tło).\n\n    StatusBar.styleBlackOpaque();\n    \n\n## Obsługiwane platformy\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.backgroundColorByName\n\nNa iOS 7 gdy zostanie ustawiona wartość false, StatusBar.statusBarOverlaysWebView można ustawić kolor tła stanu przez nazwę koloru.\n\n    StatusBar.backgroundColorByName(\"red\");\n    \n\nNazwy kolorów obsługiwane są:\n\n    black, darkGray, lightGray, white, gray, red, green, blue, cyan, yellow, magenta, orange, purple, brown\n    \n\n## Obsługiwane platformy\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.backgroundColorByHexString\n\nUstawia kolor tła stanu przez ciąg szesnastkowy.\n\n    StatusBar.backgroundColorByHexString(\"#C0C0C0\");\n    \n\nObsługiwane są również właściwości CSS.\n\n    StatusBar.backgroundColorByHexString(\"#333\"); // => #333333\n    StatusBar.backgroundColorByHexString(\"#FAB\"); // => #FFAABB\n    \n\nNa iOS 7 gdy zostanie ustawiona wartość false, StatusBar.statusBarOverlaysWebView można ustawić kolor tła stanu przez ciąg szesnastkowy (#RRGGBB).\n\nNa WP7 i WP8 można również określić wartości jako #AARRGGBB, gdzie AA jest wartością alfa\n\n## Obsługiwane platformy\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.hide\n\nUkryj pasek stanu.\n\n    StatusBar.hide();\n    \n\n## Obsługiwane platformy\n\n*   iOS\n*   Android\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.show\n\nPokazuje pasek stanu.\n\n    StatusBar.show();\n    \n\n## Obsługiwane platformy\n\n*   iOS\n*   Android\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.isVisible\n\nCzytać tej właściwość, aby sprawdzić, czy stanu jest widoczne lub nie.\n\n    if (StatusBar.isVisible) {\n        // do something\n    }\n    \n\n## Obsługiwane platformy\n\n*   iOS\n*   Android\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n"
  },
  {
    "path": "plugins/cordova-plugin-statusbar/doc/ru/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-statusbar\n\n# StatusBar\n\n> Объект `StatusBar` предоставляет некоторые функции для настройки статусной панели на iOS и Android.\n\n## Настройки\n\n#### config.xml\n\n*   **StatusBarOverlaysWebView** (логическое значение, по умолчанию true). В iOS 7 определяет необходимо ли сделать наложение статусной панели на WebView при запуске или нет.\n    \n        <preference name=\"StatusBarOverlaysWebView\" value=\"true\" />\n        \n\n*   **StatusBarBackgroundColor** (шестнадцатеричная строка цвета, значения по умолчанию #000000). На iOS 7 установит цвет фона статусной панели при запуске, на основании шестнадцатеричной строки цвета (#RRGGBB).\n    \n        <preference name=\"StatusBarBackgroundColor\" value=\"#000000\" />\n        \n\n*   **StatusBarStyle** (статус бар стиль, по умолчанию lightcontent). На iOS 7 установите стиль строки состояния. Доступные параметры по умолчанию, lightcontent, blacktranslucent, blackopaque.\n    \n        <preference name=\"StatusBarStyle\" value=\"lightcontent\" />\n        \n\n## Скрытие при запуске\n\nВо время выполнения можно использовать функцию StatusBar.hide ниже, но если вы хотите StatusBar быть скрыты при запуске приложения, необходимо изменить файл Info.plist вашего приложения.\n\nДобавьте/измените эти два атрибута, если они не присутствуют или отличаются от нижеуказанных значений. Установите значение **«Status bar is initially hidden»** равное **«YES»** и установите значение **«View controller-based status bar appearance»** на **«NO»**. Если вы измените его вручную без Xcode, ключи и значения являются следующими:\n\n    <key>UIStatusBarHidden</key>\n    <true/>\n    <key>UIViewControllerBasedStatusBarAppearance</key>\n    <false/>\n    \n\n## Методы\n\n*   StatusBar.overlaysWebView\n*   StatusBar.styleDefault\n*   StatusBar.styleLightContent\n*   StatusBar.styleBlackTranslucent\n*   StatusBar.styleBlackOpaque\n*   StatusBar.backgroundColorByName\n*   StatusBar.backgroundColorByHexString\n*   StatusBar.hide\n*   StatusBar.show\n\n## Параметры\n\n*   StatusBar.isVisible\n\n## Разрешения\n\n#### config.xml\n\n            <feature name=\"StatusBar\">\n                <param name=\"ios-package\" value=\"CDVStatusBar\" onload=\"true\" />\n            </feature>\n    \n\n# StatusBar.overlaysWebView\n\nНа iOS 7 Сделайте statusbar overlay или не поверх WebView.\n\n    StatusBar.overlaysWebView(true);\n    \n\n## Описание\n\nНа iOS 7 Установите значение false чтобы сделать statusbar появляются как iOS 6. Задайте стиль и цвет фона в соответствии с использованием других функций.\n\n## Поддерживаемые платформы\n\n*   iOS\n\n## Краткий пример\n\n    StatusBar.overlaysWebView(true);\n    StatusBar.overlaysWebView(false);\n    \n\n# StatusBar.styleDefault\n\nИспользуйте по умолчанию statusbar (темный текст, для легких стола).\n\n    StatusBar.styleDefault();\n    \n\n## Поддерживаемые платформы\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n\n# StatusBar.styleLightContent\n\nИспользуйте lightContent statusbar (светлый текст, на темном фоне).\n\n    StatusBar.styleLightContent();\n    \n\n## Поддерживаемые платформы\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n\n# StatusBar.styleBlackTranslucent\n\nИспользуйте blackTranslucent statusbar (светлый текст, на темном фоне).\n\n    StatusBar.styleBlackTranslucent();\n    \n\n## Поддерживаемые платформы\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n\n# StatusBar.styleBlackOpaque\n\nИспользуйте blackOpaque statusbar (светлый текст, на темном фоне).\n\n    StatusBar.styleBlackOpaque();\n    \n\n## Поддерживаемые платформы\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n\n# StatusBar.backgroundColorByName\n\nНа iOS 7 когда StatusBar.statusBarOverlaysWebView присвоено значение false, можно задать цвет фона для объекта statusbar по имени цвета.\n\n    StatusBar.backgroundColorByName(\"red\");\n    \n\nИмена поддерживаемых цветов являются:\n\n    black, darkGray, lightGray, white, gray, red, green, blue, cyan, yellow, magenta, orange, purple, brown\n    \n\n## Поддерживаемые платформы\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n\n# StatusBar.backgroundColorByHexString\n\nЗадает цвет фона для объекта statusbar, шестнадцатеричная строка.\n\n    StatusBar.backgroundColorByHexString(\"#C0C0C0\");\n    \n\nТакже поддерживаются свойства CSS стенографию.\n\n    StatusBar.backgroundColorByHexString(\"#333\"); // => #333333\n    StatusBar.backgroundColorByHexString(\"#FAB\"); // => #FFAABB\n    \n\nНа iOS 7 когда StatusBar.statusBarOverlaysWebView присвоено значение false, можно задать цвет фона для объекта statusbar, шестнадцатеричная строка (#RRGGBB).\n\nНа WP7 и WP8 также можно указать значения как #AARRGGBB, где AA — это альфа-значение\n\n## Поддерживаемые платформы\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n\n# StatusBar.hide\n\nСкройте строку состояния statusbar.\n\n    StatusBar.hide();\n    \n\n## Поддерживаемые платформы\n\n*   iOS\n*   Android\n*   Windows Phone 7\n*   Windows Phone 8\n\n# StatusBar.show\n\nПоказывает строку состояния statusbar.\n\n    StatusBar.show();\n    \n\n## Поддерживаемые платформы\n\n*   iOS\n*   Android\n*   Windows Phone 7\n*   Windows Phone 8\n\n# StatusBar.isVisible\n\nЧтение это свойство, чтобы увидеть, если statusbar является видимым или нет.\n\n    if (StatusBar.isVisible) {\n        // do something\n    }\n    \n\n## Поддерживаемые платформы\n\n*   iOS\n*   Android\n*   Windows Phone 7\n*   Windows Phone 8\n"
  },
  {
    "path": "plugins/cordova-plugin-statusbar/doc/zh/README.md",
    "content": "<!---\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-statusbar\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-statusbar.svg)](https://travis-ci.org/apache/cordova-plugin-statusbar)\n\n# StatusBar\n\n> `StatusBar`物件提供了一些功能，自訂的 iOS 和 Android 狀態列。\n\n## 安裝\n\n    cordova plugin add cordova-plugin-statusbar\n    \n\n## 首選項\n\n#### config.xml\n\n  * **StatusBarOverlaysWebView**（布林值，預設值為 true）。在 iOS 7，使狀態列覆蓋或不覆蓋 web 視圖在啟動時。\n    \n        <preference name=\"StatusBarOverlaysWebView\" value=\"true\" />\n        \n\n  * **StatusBarBackgroundColor**(顏色十六進位字串，預設值為 #000000)。IOS 7 和 Android 5，由十六進位字串 (#RRGGBB) 在啟動時設置狀態列的背景色。\n    \n        <preference name=\"StatusBarBackgroundColor\" value=\"#000000\" />\n        \n\n  * **狀態列**（狀態列樣式，預設值為 lightcontent）。在 iOS 7，設置的狀態橫條圖樣式。可用的選項預設，lightcontent，blacktranslucent，blackopaque。\n    \n        <preference name=\"StatusBarStyle\" value=\"lightcontent\" />\n        \n\n### Android 的怪癖\n\nAndroid 的 5 + 準則指定使用不同的顏色比您主要的應用程式狀態欄顏色 (不像很多 iOS 7 + 應用程式的統一狀態列顏色)，所以你可能想要設置在運行時顯示狀態列顏色而不是通過`StatusBar.backgroundColorByHexString`或`StatusBar.backgroundColorByName`。 一個的方式做到這一點將是:\n\n```js\nif (cordova.platformId == 'android') {\n    StatusBar.backgroundColorByHexString(\"#333\");\n}\n```\n\n## 在啟動時隱藏\n\n在運行時期間，你可以使用 StatusBar.hide 函數下面，但如果你想要顯示狀態列隱藏在應用程式啟動時，你必須修改你的應用程式的 Info.plist 檔。\n\n添加編輯這兩個屬性，如果不存在。 將**\"狀態列最初隱藏\"**設置為**\"YES\"**和**\"視圖基於控制器的狀態列外觀\"**設置為**\"否\"**。 如果您手動編輯它沒有 Xcode，鍵和值是：\n\n    <key>UIStatusBarHidden</key>\n    <true/>\n    <key>UIViewControllerBasedStatusBarAppearance</key>\n    <false/>\n    \n\n## 方法\n\n這個外掛程式定義全域 `StatusBar` 物件。\n\n雖然在全球範圍內，它不可用直到 `deviceready` 事件之後。\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(StatusBar);\n    }\n    \n\n  * StatusBar.overlaysWebView\n  * StatusBar.styleDefault\n  * StatusBar.styleLightContent\n  * StatusBar.styleBlackTranslucent\n  * StatusBar.styleBlackOpaque\n  * StatusBar.backgroundColorByName\n  * StatusBar.backgroundColorByHexString\n  * StatusBar.hide\n  * StatusBar.show\n\n## 屬性\n\n  * StatusBar.isVisible\n\n## 許可權\n\n#### config.xml\n\n            <feature name=\"StatusBar\">\n                <param name=\"ios-package\" value=\"CDVStatusBar\" onload=\"true\" />\n            </feature>\n    \n\n# StatusBar.overlaysWebView\n\n在 iOS 7，使狀態列覆蓋或不覆蓋 web 視圖。\n\n    StatusBar.overlaysWebView(true);\n    \n\n## 說明\n\n在 iOS 7，設置為 false，使狀態列出現像 iOS 6。設置樣式和背景顏色，適合使用其他函數。\n\n## 支援的平臺\n\n  * iOS\n\n## 快速的示例\n\n    StatusBar.overlaysWebView(true);\n    StatusBar.overlaysWebView(false);\n    \n\n# StatusBar.styleDefault\n\n使用預設狀態列 （淺色背景深色文本）。\n\n    StatusBar.styleDefault();\n    \n\n## 支援的平臺\n\n  * iOS\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.styleLightContent\n\n使用 lightContent 狀態列 （深色背景光文本）。\n\n    StatusBar.styleLightContent();\n    \n\n## 支援的平臺\n\n  * iOS\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.styleBlackTranslucent\n\n使用 blackTranslucent 狀態列 （深色背景光文本）。\n\n    StatusBar.styleBlackTranslucent();\n    \n\n## 支援的平臺\n\n  * iOS\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.styleBlackOpaque\n\n使用 blackOpaque 狀態列 （深色背景光文本）。\n\n    StatusBar.styleBlackOpaque();\n    \n\n## 支援的平臺\n\n  * iOS\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.backgroundColorByName\n\n在 iOS 7，當您將 StatusBar.statusBarOverlaysWebView 設置為 false，你可以設置狀態列的背景色的顏色名稱。\n\n    StatusBar.backgroundColorByName(\"red\");\n    \n\n支援的顏色名稱是：\n\n    black, darkGray, lightGray, white, gray, red, green, blue, cyan, yellow, magenta, orange, purple, brown\n    \n\n## 支援的平臺\n\n  * iOS\n  * Android 5+\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.backgroundColorByHexString\n\n由十六進位字串設置狀態列的背景色。\n\n    StatusBar.backgroundColorByHexString(\"#C0C0C0\");\n    \n\n此外支援 CSS 速記屬性。\n\n    StatusBar.backgroundColorByHexString(\"#333\"); // => #333333\n    StatusBar.backgroundColorByHexString(\"#FAB\"); // => #FFAABB\n    \n\n在 iOS 7，當將 StatusBar.statusBarOverlaysWebView 設置為 false，您可以設置狀態列的背景色由十六進位字串 （#RRGGBB）。\n\nWP7 和 WP8 您還可以指定值為 #AARRGGBB，其中 AA 是 Alpha 值\n\n## 支援的平臺\n\n  * iOS\n  * Android 5+\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.hide\n\n隱藏狀態列。\n\n    StatusBar.hide();\n    \n\n## 支援的平臺\n\n  * iOS\n  * Android 系統\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.show\n\n顯示狀態列。\n\n    StatusBar.show();\n    \n\n## 支援的平臺\n\n  * iOS\n  * Android 系統\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1\n\n# StatusBar.isVisible\n\n讀取此屬性，以查看狀態列是否可見。\n\n    if (StatusBar.isVisible) {\n        // do something\n    }\n    \n\n## 支援的平臺\n\n  * iOS\n  * Android 系統\n  * Windows Phone 7\n  * Windows Phone 8\n  * Windows Phone 8.1"
  },
  {
    "path": "plugins/cordova-plugin-statusbar/doc/zh/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-statusbar\n\n# StatusBar\n\n> `StatusBar`物件提供了一些功能，自訂的 iOS 和 Android 狀態列。\n\n## 安裝\n\n    cordova plugin add cordova-plugin-statusbar\n    \n\n## 首選項\n\n#### config.xml\n\n*   **StatusBarOverlaysWebView**（布林值，預設值為 true）。在 iOS 7，使狀態列覆蓋或不覆蓋 web 視圖在啟動時。\n    \n        <preference name=\"StatusBarOverlaysWebView\" value=\"true\" />\n        \n\n*   **StatusBarBackgroundColor**（顏色十六進位字串，預設值為 #000000）。在 iOS 7，通過一個十六進位字串 （#RRGGBB） 在啟動時設置狀態列的背景色。\n    \n        <preference name=\"StatusBarBackgroundColor\" value=\"#000000\" />\n        \n\n*   **狀態列**（狀態列樣式，預設值為 lightcontent）。在 iOS 7，設置的狀態橫條圖樣式。可用的選項預設，lightcontent，blacktranslucent，blackopaque。\n    \n        <preference name=\"StatusBarStyle\" value=\"lightcontent\" />\n        \n\n## 在啟動時隱藏\n\n在運行時期間，你可以使用 StatusBar.hide 函數下面，但如果你想要顯示狀態列隱藏在應用程式啟動時，你必須修改你的應用程式的 Info.plist 檔。\n\n添加編輯這兩個屬性，如果不存在。 將**\"狀態列最初隱藏\"**設置為**\"YES\"**和**\"視圖基於控制器的狀態列外觀\"**設置為**\"否\"**。 如果您手動編輯它沒有 Xcode，鍵和值是：\n\n    <key>UIStatusBarHidden</key>\n    <true/>\n    <key>UIViewControllerBasedStatusBarAppearance</key>\n    <false/>\n    \n\n## 方法\n\n這個外掛程式定義全域 `StatusBar` 物件。\n\n雖然在全球範圍內，它不可用直到 `deviceready` 事件之後。\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(StatusBar);\n    }\n    \n\n*   StatusBar.overlaysWebView\n*   StatusBar.styleDefault\n*   StatusBar.styleLightContent\n*   StatusBar.styleBlackTranslucent\n*   StatusBar.styleBlackOpaque\n*   StatusBar.backgroundColorByName\n*   StatusBar.backgroundColorByHexString\n*   StatusBar.hide\n*   StatusBar.show\n\n## 屬性\n\n*   StatusBar.isVisible\n\n## 許可權\n\n#### config.xml\n\n            <feature name=\"StatusBar\">\n                <param name=\"ios-package\" value=\"CDVStatusBar\" onload=\"true\" />\n            </feature>\n    \n\n# StatusBar.overlaysWebView\n\n在 iOS 7，使狀態列覆蓋或不覆蓋 web 視圖。\n\n    StatusBar.overlaysWebView(true);\n    \n\n## 說明\n\n在 iOS 7，設置為 false，使狀態列出現像 iOS 6。設置樣式和背景顏色，適合使用其他函數。\n\n## 支援的平臺\n\n*   iOS\n\n## 快速的示例\n\n    StatusBar.overlaysWebView(true);\n    StatusBar.overlaysWebView(false);\n    \n\n# StatusBar.styleDefault\n\n使用預設狀態列 （淺色背景深色文本）。\n\n    StatusBar.styleDefault();\n    \n\n## 支援的平臺\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.styleLightContent\n\n使用 lightContent 狀態列 （深色背景光文本）。\n\n    StatusBar.styleLightContent();\n    \n\n## 支援的平臺\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.styleBlackTranslucent\n\n使用 blackTranslucent 狀態列 （深色背景光文本）。\n\n    StatusBar.styleBlackTranslucent();\n    \n\n## 支援的平臺\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.styleBlackOpaque\n\n使用 blackOpaque 狀態列 （深色背景光文本）。\n\n    StatusBar.styleBlackOpaque();\n    \n\n## 支援的平臺\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.backgroundColorByName\n\n在 iOS 7，當您將 StatusBar.statusBarOverlaysWebView 設置為 false，你可以設置狀態列的背景色的顏色名稱。\n\n    StatusBar.backgroundColorByName(\"red\");\n    \n\n支援的顏色名稱是：\n\n    black, darkGray, lightGray, white, gray, red, green, blue, cyan, yellow, magenta, orange, purple, brown\n    \n\n## 支援的平臺\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.backgroundColorByHexString\n\n由十六進位字串設置狀態列的背景色。\n\n    StatusBar.backgroundColorByHexString(\"#C0C0C0\");\n    \n\n此外支援 CSS 速記屬性。\n\n    StatusBar.backgroundColorByHexString(\"#333\"); // => #333333\n    StatusBar.backgroundColorByHexString(\"#FAB\"); // => #FFAABB\n    \n\n在 iOS 7，當將 StatusBar.statusBarOverlaysWebView 設置為 false，您可以設置狀態列的背景色由十六進位字串 （#RRGGBB）。\n\nWP7 和 WP8 您還可以指定值為 #AARRGGBB，其中 AA 是 Alpha 值\n\n## 支援的平臺\n\n*   iOS\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.hide\n\n隱藏狀態列。\n\n    StatusBar.hide();\n    \n\n## 支援的平臺\n\n*   iOS\n*   安卓系統\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.show\n\n顯示狀態列。\n\n    StatusBar.show();\n    \n\n## 支援的平臺\n\n*   iOS\n*   安卓系統\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n\n# StatusBar.isVisible\n\n讀取此屬性，以查看狀態列是否可見。\n\n    if (StatusBar.isVisible) {\n        // do something\n    }\n    \n\n## 支援的平臺\n\n*   iOS\n*   安卓系統\n*   Windows Phone 7\n*   Windows Phone 8\n*   Windows Phone 8.1\n"
  },
  {
    "path": "plugins/cordova-plugin-statusbar/package.json",
    "content": "{\n  \"name\": \"cordova-plugin-statusbar\",\n  \"version\": \"1.0.1\",\n  \"description\": \"Cordova StatusBar Plugin\",\n  \"cordova\": {\n    \"id\": \"cordova-plugin-statusbar\",\n    \"platforms\": [\n      \"android\",\n      \"ios\",\n      \"wp7\",\n      \"wp8\",\n      \"windows\"\n    ]\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/apache/cordova-plugin-statusbar\"\n  },\n  \"keywords\": [\n    \"cordova\",\n    \"statusbar\",\n    \"ecosystem:cordova\",\n    \"cordova-android\",\n    \"cordova-ios\",\n    \"cordova-wp7\",\n    \"cordova-wp8\",\n    \"cordova-windows\"\n  ],\n  \"engines\": [\n    {\n      \"name\": \"cordova\",\n      \"version\": \">=3.0.0\"\n    }\n  ],\n  \"author\": \"Apache Software Foundation\",\n  \"license\": \"Apache 2.0\"\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-statusbar/plugin.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  Licensed to the Apache Software Foundation (ASF) under one\n  or more contributor license agreements.  See the NOTICE file\n  distributed with this work for additional information\n  regarding copyright ownership.  The ASF licenses this file\n  to you under the Apache License, Version 2.0 (the\n  \"License\"); you may not use this file except in compliance\n  with the License.  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing,\n  software distributed under the License is distributed on an\n  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n  KIND, either express or implied.  See the License for the\n  specific language governing permissions and limitations\n  under the License.\n-->\n\n<plugin xmlns=\"http://apache.org/cordova/ns/plugins/1.0\"\n    xmlns:rim=\"http://www.blackberry.com/ns/widgets\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    id=\"cordova-plugin-statusbar\"\n    version=\"1.0.1\">\n    <name>StatusBar</name>\n    <description>Cordova StatusBar Plugin</description>\n    <license>Apache 2.0</license>\n    <keywords>cordova,statusbar</keywords>\n\n    <engines>\n            <engine name=\"cordova\" version=\">=3.0.0\" />\n    </engines>\n\n    <js-module src=\"www/statusbar.js\" name=\"statusbar\">\n        <clobbers target=\"window.StatusBar\" />\n    </js-module>\n\n    <platform name=\"android\">\n        <source-file src=\"src/android/StatusBar.java\" target-dir=\"src/org/apache/cordova/statusbar\" />\n\n        <config-file target=\"res/xml/config.xml\" parent=\"/*\">\n            <feature name=\"StatusBar\">\n                <param name=\"android-package\" value=\"org.apache.cordova.statusbar.StatusBar\" />\n                <param name=\"onload\" value=\"true\" />\n            </feature>\n        </config-file>\n    </platform>\n\n    <!-- ios -->\n    <platform name=\"ios\">\n\n        <config-file target=\"config.xml\" parent=\"/*\">\n            <feature name=\"StatusBar\">\n                <param name=\"ios-package\" value=\"CDVStatusBar\" />\n                <param name=\"onload\" value=\"true\" />\n            </feature>\n            <preference name=\"StatusBarOverlaysWebView\" value=\"true\" />\n            <preference name=\"StatusBarStyle\" value=\"lightcontent\" />\n        </config-file>\n\n        <header-file src=\"src/ios/CDVStatusBar.h\" />\n        <source-file src=\"src/ios/CDVStatusBar.m\" />\n\n    </platform>\n\n    <!-- wp7 -->\n    <platform name=\"wp7\">\n        <config-file target=\"config.xml\" parent=\"/*\">\n            <feature name=\"StatusBar\">\n                <param name=\"wp-package\" value=\"StatusBar\"/>\n            </feature>\n        </config-file>\n        <source-file src=\"src/wp/StatusBar.cs\" />\n    </platform>\n\n    <!-- wp8 -->\n    <platform name=\"wp8\">\n        <config-file target=\"config.xml\" parent=\"/*\">\n            <feature name=\"StatusBar\">\n                <param name=\"wp-package\" value=\"StatusBar\"/>\n            </feature>\n        </config-file>\n        <source-file src=\"src/wp/StatusBar.cs\" />\n    </platform>\n\n    <!-- windows -->\n    <platform name=\"windows\">\n        <js-module src=\"src/windows/StatusBarProxy.js\" name=\"StatusBarProxy\">\n            <runs />\n        </js-module>\n    </platform>\n</plugin>\n"
  },
  {
    "path": "plugins/cordova-plugin-statusbar/src/android/StatusBar.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\npackage org.apache.cordova.statusbar;\n\nimport android.app.Activity;\nimport android.graphics.Color;\nimport android.os.Build;\nimport android.util.Log;\nimport android.view.Window;\nimport android.view.WindowManager;\n\nimport org.apache.cordova.CallbackContext;\nimport org.apache.cordova.CordovaArgs;\nimport org.apache.cordova.CordovaInterface;\nimport org.apache.cordova.CordovaPlugin;\nimport org.apache.cordova.CordovaWebView;\nimport org.apache.cordova.PluginResult;\nimport org.json.JSONException;\n\npublic class StatusBar extends CordovaPlugin {\n    private static final String TAG = \"StatusBar\";\n\n    /**\n     * Sets the context of the Command. This can then be used to do things like\n     * get file paths associated with the Activity.\n     *\n     * @param cordova The context of the main Activity.\n     * @param webView The CordovaWebView Cordova is running in.\n     */\n    @Override\n    public void initialize(final CordovaInterface cordova, CordovaWebView webView) {\n        Log.v(TAG, \"StatusBar: initialization\");\n        super.initialize(cordova, webView);\n\n        this.cordova.getActivity().runOnUiThread(new Runnable() {\n            @Override\n            public void run() {\n                // Clear flag FLAG_FORCE_NOT_FULLSCREEN which is set initially\n                // by the Cordova.\n                Window window = cordova.getActivity().getWindow();\n                window.clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);\n\n                // Read 'StatusBarBackgroundColor' from config.xml, default is #000000.\n                setStatusBarBackgroundColor(preferences.getString(\"StatusBarBackgroundColor\", \"#000000\"));\n            }\n        });\n    }\n\n    /**\n     * Executes the request and returns PluginResult.\n     *\n     * @param action            The action to execute.\n     * @param args              JSONArry of arguments for the plugin.\n     * @param callbackContext   The callback id used when calling back into JavaScript.\n     * @return                  True if the action was valid, false otherwise.\n     */\n    @Override\n    public boolean execute(final String action, final CordovaArgs args, final CallbackContext callbackContext) throws JSONException {\n        Log.v(TAG, \"Executing action: \" + action);\n        final Activity activity = this.cordova.getActivity();\n        final Window window = activity.getWindow();\n        if (\"_ready\".equals(action)) {\n            boolean statusBarVisible = (window.getAttributes().flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) == 0;\n            callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, statusBarVisible));\n        }\n\n        if (\"show\".equals(action)) {\n            this.cordova.getActivity().runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);\n                }\n            });\n            return true;\n        }\n\n        if (\"hide\".equals(action)) {\n            this.cordova.getActivity().runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);\n                }\n            });\n            return true;\n        }\n\n        if (\"backgroundColorByHexString\".equals(action)) {\n            this.cordova.getActivity().runOnUiThread(new Runnable() {\n                @Override\n                public void run() {\n                    try {\n                        setStatusBarBackgroundColor(args.getString(0));\n                    } catch (JSONException ignore) {\n                        Log.e(TAG, \"Invalid hexString argument, use f.i. '#777777'\");\n                    }\n                }\n            });\n            return true;\n        }\n\n        return false;\n    }\n\n    private void setStatusBarBackgroundColor(final String colorPref) {\n        if (Build.VERSION.SDK_INT >= 21) {\n            if (colorPref != null && !colorPref.isEmpty()) {\n                final Window window = cordova.getActivity().getWindow();\n                // Method and constants not available on all SDKs but we want to be able to compile this code with any SDK\n                window.clearFlags(0x04000000); // SDK 19: WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);\n                window.addFlags(0x80000000); // SDK 21: WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);\n                try {\n                    // Using reflection makes sure any 5.0+ device will work without having to compile with SDK level 21\n                    window.getClass().getDeclaredMethod(\"setStatusBarColor\", int.class).invoke(window, Color.parseColor(colorPref));\n                } catch (IllegalArgumentException ignore) {\n                    Log.e(TAG, \"Invalid hexString argument, use f.i. '#999999'\");\n                } catch (Exception ignore) {\n                    // this should not happen, only in case Android removes this method in a version > 21\n                    Log.w(TAG, \"Method window.setStatusBarColor not found for SDK level \" + Build.VERSION.SDK_INT);\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-statusbar/src/ios/CDVStatusBar.h",
    "content": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements.  See the NOTICE file\n distributed with this work for additional information\n regarding copyright ownership.  The ASF licenses this file\n to you under the Apache License, Version 2.0 (the\n \"License\"); you may not use this file except in compliance\n with the License.  You may obtain a copy of the License at\n \n http://www.apache.org/licenses/LICENSE-2.0\n \n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an\n \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n KIND, either express or implied.  See the License for the\n specific language governing permissions and limitations\n under the License.\n */\n\n#import <Cordova/CDVPlugin.h>\n#import <Cordova/CDVInvokedUrlCommand.h>\n\n@interface CDVStatusBar : CDVPlugin {\n    @protected\n    BOOL _statusBarOverlaysWebView;\n    UIView* _statusBarBackgroundView;\n    BOOL _uiviewControllerBasedStatusBarAppearance;\n    UIColor* _statusBarBackgroundColor;\n    NSString* _eventsCallbackId;\n}\n\n@property (atomic, assign) BOOL statusBarOverlaysWebView;\n\n- (void) overlaysWebView:(CDVInvokedUrlCommand*)command;\n\n- (void) styleDefault:(CDVInvokedUrlCommand*)command;\n- (void) styleLightContent:(CDVInvokedUrlCommand*)command;\n- (void) styleBlackTranslucent:(CDVInvokedUrlCommand*)command;\n- (void) styleBlackOpaque:(CDVInvokedUrlCommand*)command;\n\n- (void) backgroundColorByName:(CDVInvokedUrlCommand*)command;\n- (void) backgroundColorByHexString:(CDVInvokedUrlCommand*)command;\n\n- (void) hide:(CDVInvokedUrlCommand*)command;\n- (void) show:(CDVInvokedUrlCommand*)command;\n    \n- (void) _ready:(CDVInvokedUrlCommand*)command;\n\n@end\n"
  },
  {
    "path": "plugins/cordova-plugin-statusbar/src/ios/CDVStatusBar.m",
    "content": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements.  See the NOTICE file\n distributed with this work for additional information\n regarding copyright ownership.  The ASF licenses this file\n to you under the Apache License, Version 2.0 (the\n \"License\"); you may not use this file except in compliance\n with the License.  You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an\n \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n KIND, either express or implied.  See the License for the\n specific language governing permissions and limitations\n under the License.\n */\n\n/*\n NOTE: plugman/cordova cli should have already installed this,\n but you need the value UIViewControllerBasedStatusBarAppearance\n in your Info.plist as well to set the styles in iOS 7\n */\n\n#import \"CDVStatusBar.h\"\n#import <objc/runtime.h>\n#import <Cordova/CDVViewController.h>\n\nstatic const void *kHideStatusBar = &kHideStatusBar;\nstatic const void *kStatusBarStyle = &kStatusBarStyle;\n\n@interface CDVViewController (StatusBar)\n\n@property (nonatomic, retain) id sb_hideStatusBar;\n@property (nonatomic, retain) id sb_statusBarStyle;\n\n@end\n\n@implementation CDVViewController (StatusBar)\n\n@dynamic sb_hideStatusBar;\n@dynamic sb_statusBarStyle;\n\n- (id)sb_hideStatusBar {\n    return objc_getAssociatedObject(self, kHideStatusBar);\n}\n\n- (void)setSb_hideStatusBar:(id)newHideStatusBar {\n    objc_setAssociatedObject(self, kHideStatusBar, newHideStatusBar, OBJC_ASSOCIATION_RETAIN_NONATOMIC);\n}\n\n- (id)sb_statusBarStyle {\n    return objc_getAssociatedObject(self, kStatusBarStyle);\n}\n\n- (void)setSb_statusBarStyle:(id)newStatusBarStyle {\n    objc_setAssociatedObject(self, kStatusBarStyle, newStatusBarStyle, OBJC_ASSOCIATION_RETAIN_NONATOMIC);\n}\n\n- (BOOL) prefersStatusBarHidden {\n    return [self.sb_hideStatusBar boolValue];\n}\n\n- (UIStatusBarStyle)preferredStatusBarStyle\n{\n    return (UIStatusBarStyle)[self.sb_statusBarStyle intValue];\n}\n\n@end\n\n\n@interface CDVStatusBar () <UIScrollViewDelegate>\n- (void)fireTappedEvent;\n- (void)updateIsVisible:(BOOL)visible;\n@end\n\n@implementation CDVStatusBar\n\n- (id)settingForKey:(NSString*)key\n{\n    return [self.commandDelegate.settings objectForKey:[key lowercaseString]];\n}\n\n- (void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary*)change context:(void*)context\n{\n    if ([keyPath isEqual:@\"statusBarHidden\"]) {\n        NSNumber* newValue = [change objectForKey:NSKeyValueChangeNewKey];\n        [self updateIsVisible:![newValue boolValue]];\n    }\n}\n\n- (void)pluginInitialize\n{\n    BOOL isiOS7 = (IsAtLeastiOSVersion(@\"7.0\"));\n\n    // init\n    NSNumber* uiviewControllerBasedStatusBarAppearance = [[NSBundle mainBundle] objectForInfoDictionaryKey:@\"UIViewControllerBasedStatusBarAppearance\"];\n    _uiviewControllerBasedStatusBarAppearance = (uiviewControllerBasedStatusBarAppearance == nil || [uiviewControllerBasedStatusBarAppearance boolValue]) && isiOS7;\n\n    // observe the statusBarHidden property\n    [[UIApplication sharedApplication] addObserver:self forKeyPath:@\"statusBarHidden\" options:NSKeyValueObservingOptionNew context:NULL];\n\n    _statusBarOverlaysWebView = YES; // default\n\n    [self initializeStatusBarBackgroundView];\n\n    self.viewController.view.autoresizesSubviews = YES;\n\n    NSString* setting;\n\n    setting  = @\"StatusBarOverlaysWebView\";\n    if ([self settingForKey:setting]) {\n        self.statusBarOverlaysWebView = [(NSNumber*)[self settingForKey:setting] boolValue];\n    }\n\n    setting  = @\"StatusBarBackgroundColor\";\n    if ([self settingForKey:setting]) {\n        [self _backgroundColorByHexString:[self settingForKey:setting]];\n    }\n\n    setting  = @\"StatusBarStyle\";\n    if ([self settingForKey:setting]) {\n        [self setStatusBarStyle:[self settingForKey:setting]];\n    }\n\n    // blank scroll view to intercept status bar taps\n    self.webView.scrollView.scrollsToTop = NO;\n    UIScrollView *fakeScrollView = [[UIScrollView alloc] initWithFrame:UIScreen.mainScreen.bounds];\n    fakeScrollView.delegate = self;\n    fakeScrollView.scrollsToTop = YES;\n    [self.viewController.view addSubview:fakeScrollView]; // Add scrollview to the view heirarchy so that it will begin accepting status bar taps\n    [self.viewController.view sendSubviewToBack:fakeScrollView]; // Send it to the very back of the view heirarchy\n    fakeScrollView.contentSize = CGSizeMake(UIScreen.mainScreen.bounds.size.width, UIScreen.mainScreen.bounds.size.height * 2.0f); // Make the scroll view longer than the screen itself\n    fakeScrollView.contentOffset = CGPointMake(0.0f, UIScreen.mainScreen.bounds.size.height); // Scroll down so a tap will take scroll view back to the top\n}\n\n- (void)onReset {\n    _eventsCallbackId = nil;\n}\n\n- (void)fireTappedEvent {\n    if (_eventsCallbackId == nil) {\n        return;\n    }\n    NSDictionary* payload = @{@\"type\": @\"tap\"};\n    CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:payload];\n    [result setKeepCallbackAsBool:YES];\n    [self.commandDelegate sendPluginResult:result callbackId:_eventsCallbackId];\n}\n\n- (void)updateIsVisible:(BOOL)visible {\n    if (_eventsCallbackId == nil) {\n        return;\n    }\n    CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:visible];\n    [result setKeepCallbackAsBool:YES];\n    [self.commandDelegate sendPluginResult:result callbackId:_eventsCallbackId];\n}\n\n\n- (void) _ready:(CDVInvokedUrlCommand*)command\n{\n    _eventsCallbackId = command.callbackId;\n    [self updateIsVisible:![UIApplication sharedApplication].statusBarHidden];\n}\n\n- (void) initializeStatusBarBackgroundView\n{\n    CGRect statusBarFrame = [UIApplication sharedApplication].statusBarFrame;\n    statusBarFrame = [self invertFrameIfNeeded:statusBarFrame orientation:self.viewController.interfaceOrientation];\n\n    _statusBarBackgroundView = [[UIView alloc] initWithFrame:statusBarFrame];\n    _statusBarBackgroundView.backgroundColor = _statusBarBackgroundColor;\n    _statusBarBackgroundView.autoresizingMask = (UIViewAutoresizingFlexibleWidth  | UIViewAutoresizingFlexibleBottomMargin);\n    _statusBarBackgroundView.autoresizesSubviews = YES;\n}\n\n- (CGRect) invertFrameIfNeeded:(CGRect)rect orientation:(UIInterfaceOrientation)orientation {\n    // landscape is where (width > height). On iOS < 8, we need to invert since frames are\n    // always in Portrait context\n    if (UIDeviceOrientationIsLandscape(orientation) && (rect.size.width < rect.size.height) ) {\n        CGFloat temp = rect.size.width;\n        rect.size.width = rect.size.height;\n        rect.size.height = temp;\n        rect.origin = CGPointZero;\n    }\n    \n    return rect;\n}\n\n- (void) setStatusBarOverlaysWebView:(BOOL)statusBarOverlaysWebView\n{\n    // we only care about the latest iOS version or a change in setting\n    if (!IsAtLeastiOSVersion(@\"7.0\") || statusBarOverlaysWebView == _statusBarOverlaysWebView) {\n        return;\n    }\n\n    CGRect bounds = [[UIScreen mainScreen] bounds];\n\n    if (statusBarOverlaysWebView) {\n\n        [_statusBarBackgroundView removeFromSuperview];\n        if (UIDeviceOrientationIsLandscape(self.viewController.interfaceOrientation)) {\n            self.webView.frame = CGRectMake(0, 0, bounds.size.height, bounds.size.width);\n        } else {\n            self.webView.frame = bounds;\n        }\n\n    } else {\n\n        CGRect statusBarFrame = [UIApplication sharedApplication].statusBarFrame;\n        statusBarFrame = [self invertFrameIfNeeded:statusBarFrame orientation:self.viewController.interfaceOrientation];\n\n        [self initializeStatusBarBackgroundView];\n\n        CGRect frame = self.webView.frame;\n        frame.origin.y = statusBarFrame.size.height;\n        frame.size.height -= statusBarFrame.size.height;\n\n        self.webView.frame = frame;\n        [self.webView.superview addSubview:_statusBarBackgroundView];\n    }\n\n    _statusBarOverlaysWebView = statusBarOverlaysWebView;\n}\n\n- (BOOL) statusBarOverlaysWebView\n{\n    return _statusBarOverlaysWebView;\n}\n\n- (void) overlaysWebView:(CDVInvokedUrlCommand*)command\n{\n    id value = [command argumentAtIndex:0];\n    if (!([value isKindOfClass:[NSNumber class]])) {\n        value = [NSNumber numberWithBool:YES];\n    }\n\n    self.statusBarOverlaysWebView = [value boolValue];\n}\n\n- (void) refreshStatusBarAppearance\n{\n    SEL sel = NSSelectorFromString(@\"setNeedsStatusBarAppearanceUpdate\");\n    if ([self.viewController respondsToSelector:sel]) {\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Warc-performSelector-leaks\"\n        [self.viewController performSelector:sel withObject:nil];\n#pragma clang diagnostic pop\n    }\n}\n\n- (void) setStyleForStatusBar:(UIStatusBarStyle)style\n{\n    if (_uiviewControllerBasedStatusBarAppearance) {\n        CDVViewController* vc = (CDVViewController*)self.viewController;\n        vc.sb_statusBarStyle = [NSNumber numberWithInt:style];\n        [self refreshStatusBarAppearance];\n\n    } else {\n        [[UIApplication sharedApplication] setStatusBarStyle:style];\n    }\n}\n\n- (void) setStatusBarStyle:(NSString*)statusBarStyle\n{\n    // default, lightContent, blackTranslucent, blackOpaque\n    NSString* lcStatusBarStyle = [statusBarStyle lowercaseString];\n\n    if ([lcStatusBarStyle isEqualToString:@\"default\"]) {\n        [self styleDefault:nil];\n    } else if ([lcStatusBarStyle isEqualToString:@\"lightcontent\"]) {\n        [self styleLightContent:nil];\n    } else if ([lcStatusBarStyle isEqualToString:@\"blacktranslucent\"]) {\n        [self styleBlackTranslucent:nil];\n    } else if ([lcStatusBarStyle isEqualToString:@\"blackopaque\"]) {\n        [self styleBlackOpaque:nil];\n    }\n}\n\n- (void) styleDefault:(CDVInvokedUrlCommand*)command\n{\n    [self setStyleForStatusBar:UIStatusBarStyleDefault];\n}\n\n- (void) styleLightContent:(CDVInvokedUrlCommand*)command\n{\n    [self setStyleForStatusBar:UIStatusBarStyleLightContent];\n}\n\n- (void) styleBlackTranslucent:(CDVInvokedUrlCommand*)command\n{\n    [self setStyleForStatusBar:UIStatusBarStyleBlackTranslucent];\n}\n\n- (void) styleBlackOpaque:(CDVInvokedUrlCommand*)command\n{\n    [self setStyleForStatusBar:UIStatusBarStyleBlackOpaque];\n}\n\n- (void) backgroundColorByName:(CDVInvokedUrlCommand*)command\n{\n    id value = [command argumentAtIndex:0];\n    if (!([value isKindOfClass:[NSString class]])) {\n        value = @\"black\";\n    }\n\n    SEL selector = NSSelectorFromString([value stringByAppendingString:@\"Color\"]);\n    if ([UIColor respondsToSelector:selector]) {\n        _statusBarBackgroundView.backgroundColor = [UIColor performSelector:selector];\n    }\n}\n\n- (void) _backgroundColorByHexString:(NSString*)hexString\n{\n    unsigned int rgbValue = 0;\n    NSScanner* scanner = [NSScanner scannerWithString:hexString];\n    [scanner setScanLocation:1];\n    [scanner scanHexInt:&rgbValue];\n\n    _statusBarBackgroundColor = [UIColor colorWithRed:((rgbValue & 0xFF0000) >> 16)/255.0 green:((rgbValue & 0xFF00) >> 8)/255.0 blue:(rgbValue & 0xFF)/255.0 alpha:1.0];\n    _statusBarBackgroundView.backgroundColor = _statusBarBackgroundColor;\n}\n\n- (void) backgroundColorByHexString:(CDVInvokedUrlCommand*)command\n{\n    NSString* value = [command argumentAtIndex:0];\n    if (!([value isKindOfClass:[NSString class]])) {\n        value = @\"#000000\";\n    }\n\n    if (![value hasPrefix:@\"#\"] || [value length] < 7) {\n        return;\n    }\n\n    [self _backgroundColorByHexString:value];\n}\n\n- (void) hideStatusBar\n{\n    if (_uiviewControllerBasedStatusBarAppearance) {\n        CDVViewController* vc = (CDVViewController*)self.viewController;\n        vc.sb_hideStatusBar = [NSNumber numberWithBool:YES];\n        [self refreshStatusBarAppearance];\n\n    } else {\n        UIApplication* app = [UIApplication sharedApplication];\n        [app setStatusBarHidden:YES];\n    }\n}\n\n- (void) hide:(CDVInvokedUrlCommand*)command\n{\n    UIApplication* app = [UIApplication sharedApplication];\n\n    if (!app.isStatusBarHidden)\n    {\n        self.viewController.wantsFullScreenLayout = YES;\n        CGRect statusBarFrame = [UIApplication sharedApplication].statusBarFrame;\n\n        [self hideStatusBar];\n\n        if (IsAtLeastiOSVersion(@\"7.0\")) {\n            [_statusBarBackgroundView removeFromSuperview];\n        }\n\n        if (!_statusBarOverlaysWebView) {\n\n            CGRect frame = self.webView.frame;\n            frame.origin.y = 0;\n            if (!self.statusBarOverlaysWebView) {\n                if (UIDeviceOrientationIsLandscape(self.viewController.interfaceOrientation)) {\n                    frame.size.height += statusBarFrame.size.width;\n                } else {\n                    frame.size.height += statusBarFrame.size.height;\n                }\n            }\n\n            self.webView.frame = frame;\n        }\n\n        _statusBarBackgroundView.hidden = YES;\n    }\n}\n\n- (void) showStatusBar\n{\n    if (_uiviewControllerBasedStatusBarAppearance) {\n        CDVViewController* vc = (CDVViewController*)self.viewController;\n        vc.sb_hideStatusBar = [NSNumber numberWithBool:NO];\n        [self refreshStatusBarAppearance];\n\n    } else {\n        UIApplication* app = [UIApplication sharedApplication];\n        [app setStatusBarHidden:NO];\n    }\n}\n\n- (void) show:(CDVInvokedUrlCommand*)command\n{\n    UIApplication* app = [UIApplication sharedApplication];\n\n    if (app.isStatusBarHidden)\n    {\n        BOOL isIOS7 = (IsAtLeastiOSVersion(@\"7.0\"));\n        self.viewController.wantsFullScreenLayout = isIOS7;\n\n        [self showStatusBar];\n\n        if (isIOS7) {\n            CGRect frame = self.webView.frame;\n            self.viewController.view.frame = [[UIScreen mainScreen] bounds];\n\n            CGRect statusBarFrame = [UIApplication sharedApplication].statusBarFrame;\n            statusBarFrame = [self invertFrameIfNeeded:statusBarFrame orientation:self.viewController.interfaceOrientation];\n\n            if (!self.statusBarOverlaysWebView) {\n\n                // there is a possibility that when the statusbar was hidden, it was in a different orientation\n                // from the current one. Therefore we need to expand the statusBarBackgroundView as well to the\n                // statusBar's current size\n                CGRect sbBgFrame = _statusBarBackgroundView.frame;\n                frame.origin.y = statusBarFrame.size.height;\n                frame.size.height -= statusBarFrame.size.height;\n                sbBgFrame.size = statusBarFrame.size;\n\n                _statusBarBackgroundView.frame = sbBgFrame;\n                [self.webView.superview addSubview:_statusBarBackgroundView];\n            }\n\n            self.webView.frame = frame;\n\n        } else {\n\n            CGRect bounds = [[UIScreen mainScreen] applicationFrame];\n            self.viewController.view.frame = bounds;\n        }\n\n        _statusBarBackgroundView.hidden = NO;\n    }\n}\n\n- (void) dealloc\n{\n    [[UIApplication sharedApplication] removeObserver:self forKeyPath:@\"statusBarHidden\"];\n}\n\n\n#pragma mark - UIScrollViewDelegate\n\n- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView\n{\n    [self fireTappedEvent];\n    return NO;\n}\n\n@end\n"
  },
  {
    "path": "plugins/cordova-plugin-statusbar/src/windows/StatusBarProxy.js",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n */\n\n var _supported = null; // set to null so we can check first time\n\n function isSupported() {\n\t// if not checked before, run check\n    if (_supported == null) {\n        var viewMan = Windows.UI.ViewManagement; \n        _supported = (viewMan.StatusBar && viewMan.StatusBar.getForCurrentView);\n    }\n    return _supported;\n }\n\nfunction getViewStatusBar() {\n    if (!isSupported()) {\n        throw new Error(\"Status bar is not supported\");\n    }\n    return Windows.UI.ViewManagement.StatusBar.getForCurrentView();\n}\n\nfunction hexToRgb(hex) {\n    // Expand shorthand form (e.g. \"03F\") to full form (e.g. \"0033FF\")\n    var shorthandRegex = /^#?([a-f\\d])([a-f\\d])([a-f\\d])$/i;\n    hex = hex.replace(shorthandRegex, function (m, r, g, b) {\n        return r + r + g + g + b + b;\n    });\n\n    var result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n    return result ? {\n        r: parseInt(result[1], 16),\n        g: parseInt(result[2], 16),\n        b: parseInt(result[3], 16)\n    } : null;\n}\n\nmodule.exports = {\n    _ready: function(win, fail) {\n        win(statusBar.occludedRect.height !== 0);\n    },\n\n    overlaysWebView: function () {\n        // not supported\n    },\n\n    styleDefault: function () {\n        // dark text ( to be used on a light background )\n        if (isSupported()) {\n            getViewStatusBar().foregroundColor = { a: 0, r: 0, g: 0, b: 0 };\n        }\n    },\n\n    styleLightContent: function () {\n        // light text ( to be used on a dark background )\n        if (isSupported()) {\n            getViewStatusBar().foregroundColor = { a: 0, r: 255, g: 255, b: 255 };\n        }\n    },\n\n    styleBlackTranslucent: function () {\n        // #88000000 ? Apple says to use lightContent instead\n        return module.exports.styleLightContent();\n    },\n\n    styleBlackOpaque: function () {\n        // #FF000000 ? Apple says to use lightContent instead\n        return module.exports.styleLightContent();\n    },\n\n    backgroundColorByHexString: function (win, fail, args) {\n        var rgb = hexToRgb(args[0]);\n        if(isSupported()) {\n            var statusBar = getViewStatusBar();\n            statusBar.backgroundColor = { a: 0, r: rgb.r, g: rgb.g, b: rgb.b };\n            statusBar.backgroundOpacity = 1;\n        }\n    },\n\n    show: function (win, fail) {\n\t\t// added support check so no error thrown, when calling this method\n        if (isSupported()) {\n            getViewStatusBar().showAsync().done(win, fail);\n        }\n    },\n\n    hide: function (win, fail) {\n\t\t// added support check so no error thrown, when calling this method\n        if (isSupported()) {\n            getViewStatusBar().hideAsync().done(win, fail);\n        }\n    }\n};\nrequire(\"cordova/exec/proxy\").add(\"StatusBar\", module.exports);"
  },
  {
    "path": "plugins/cordova-plugin-statusbar/src/wp/StatusBar.cs",
    "content": "/*  \n\tLicensed under the Apache License, Version 2.0 (the \"License\");\n\tyou may not use this file except in compliance with the License.\n\tYou may obtain a copy of the License at\n\t\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\t\n\tUnless required by applicable law or agreed to in writing, software\n\tdistributed under the License is distributed on an \"AS IS\" BASIS,\n\tWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n\tSee the License for the specific language governing permissions and\n\tlimitations under the License.\n*/\n\n\nusing Microsoft.Phone.Shell;\nusing System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Globalization;\nusing System.Threading;\nusing System.Windows;\nusing System.Windows.Media;\nusing System.Windows.Threading;\n\n\n/*\n *   http://www.idev101.com/code/User_Interface/StatusBar.html\n *   https://developer.apple.com/library/ios/documentation/userexperience/conceptual/transitionguide/Bars.html\n *   https://developer.apple.com/library/ios/documentation/uikit/reference/UIApplication_Class/Reference/Reference.html#//apple_ref/c/econst/UIStatusBarStyleDefault\n * */\n\n\nnamespace WPCordovaClassLib.Cordova.Commands\n{\n    public class StatusBar : BaseCommand\n    {\n\n        // returns an argb value, if the hex is only rgb, it will be full opacity\n        protected Color ColorFromHex(string hexString)\n        {\n            string cleanHex = hexString.Replace(\"#\", \"\").Replace(\"0x\", \"\");\n            // turn #FFF into #FFFFFF\n            if (cleanHex.Length == 3)\n            {\n                cleanHex = \"\" + cleanHex[0] + cleanHex[0] + cleanHex[1] + cleanHex[1] + cleanHex[2] + cleanHex[2];\n            }\n            // add an alpha 100% if it is missing\n            if (cleanHex.Length == 6)\n            {\n                cleanHex = \"FF\" + cleanHex;\n            }\n            int argb = Int32.Parse(cleanHex, NumberStyles.HexNumber);\n            Color clr = Color.FromArgb((byte)((argb & 0xff000000) >> 0x18),\n                              (byte)((argb & 0xff0000) >> 0x10),\n                              (byte)((argb & 0xff00) >> 8),\n                              (byte)(argb & 0xff));\n            return clr;\n        }\n\n        public void _ready(string options)\n        {\n            Deployment.Current.Dispatcher.BeginInvoke(() =>\n            {\n                bool isVis = SystemTray.IsVisible;\n                // TODO: pass this to JS\n                //Debug.WriteLine(\"Result::\" + res);\n                DispatchCommandResult(new PluginResult(PluginResult.Status.OK, isVis));\n            });\n        }\n\n        public void overlaysWebView(string options)\n        {    //exec(null, null, \"StatusBar\", \"overlaysWebView\", [doOverlay]);\n             // string arg = JSON.JsonHelper.Deserialize<string[]>(options)[0];\n        }\n\n        public void styleDefault(string options)\n        {    //exec(null, null, \"StatusBar\", \"styleDefault\", []);\n            Deployment.Current.Dispatcher.BeginInvoke(() =>\n            {\n                SystemTray.ForegroundColor = Colors.Black;\n            });\n        }\n\n        public void styleLightContent(string options)\n        {    //exec(null, null, \"StatusBar\", \"styleLightContent\", []);\n            \n            Deployment.Current.Dispatcher.BeginInvoke(() =>\n            {\n                SystemTray.ForegroundColor = Colors.White;\n            });\n        }\n\n        public void styleBlackTranslucent(string options)\n        {    //exec(null, null, \"StatusBar\", \"styleBlackTranslucent\", []);\n            styleLightContent(options);\n        }\n\n        public void styleBlackOpaque(string options)\n        {    //exec(null, null, \"StatusBar\", \"styleBlackOpaque\", []);\n            styleLightContent(options);\n        }\n\n        public void backgroundColorByName(string options)\n        {    //exec(null, null, \"StatusBar\", \"backgroundColorByName\", [colorname]);\n             // this should NOT be called, js should now be using/converting color names to hex \n        }\n\n        public void backgroundColorByHexString(string options)\n        {    //exec(null, null, \"StatusBar\", \"backgroundColorByHexString\", [hexString]);\n            string argb = JSON.JsonHelper.Deserialize<string[]>(options)[0];\n\n            Color clr = ColorFromHex(argb);\n              \n            Deployment.Current.Dispatcher.BeginInvoke(() =>\n            {\n                SystemTray.Opacity = clr.A / 255.0d;\n                SystemTray.BackgroundColor = clr;\n                \n            });\n        }\n\n        public void hide(string options)\n        {    //exec(null, null, \"StatusBar\", \"hide\", []);\n            Deployment.Current.Dispatcher.BeginInvoke(() =>\n            {\n                SystemTray.IsVisible = false;\n            });\n\n        }\n\n        public void show(string options)\n        {    //exec(null, null, \"StatusBar\", \"show\", []);\n            Deployment.Current.Dispatcher.BeginInvoke(() =>\n            {\n                SystemTray.IsVisible = true;\n            });\n        }\n\t}\n}"
  },
  {
    "path": "plugins/cordova-plugin-statusbar/tests/plugin.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  Licensed to the Apache Software Foundation (ASF) under one\n  or more contributor license agreements.  See the NOTICE file\n  distributed with this work for additional information\n  regarding copyright ownership.  The ASF licenses this file\n  to you under the Apache License, Version 2.0 (the\n  \"License\"); you may not use this file except in compliance\n  with the License.  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing,\n  software distributed under the License is distributed on an\n  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n  KIND, either express or implied.  See the License for the\n  specific language governing permissions and limitations\n  under the License.\n-->\n\n<plugin xmlns=\"http://apache.org/cordova/ns/plugins/1.0\"\n    xmlns:rim=\"http://www.blackberry.com/ns/widgets\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    id=\"cordova-plugin-statusbar-tests\"\n    version=\"1.0.1\">\n    <name>Cordova StatusBar Plugin Tests</name>\n    <license>Apache 2.0</license>\n\n    <js-module src=\"tests.js\" name=\"tests\">\n    </js-module>\n</plugin>\n"
  },
  {
    "path": "plugins/cordova-plugin-statusbar/tests/tests.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\nexports.defineAutoTests = function () {\n    describe(\"StatusBar\", function () {\n        it(\"statusbar.spec.1 should exist\", function() {\n            expect(window.StatusBar).toBeDefined();\n        });\n\n        it(\"statusbar.spec.2 should have show|hide methods\", function() {\n            expect(window.StatusBar.show).toBeDefined();\n            expect(typeof window.StatusBar.show).toBe(\"function\");\n\n            expect(window.StatusBar.hide).toBeDefined();\n            expect(typeof window.StatusBar.hide).toBe(\"function\");\n        });\n\n        it(\"statusbar.spec.3 should have set backgroundColor methods\", function() {\n            expect(window.StatusBar.backgroundColorByName).toBeDefined();\n            expect(typeof window.StatusBar.backgroundColorByName).toBe(\"function\");\n\n            expect(window.StatusBar.backgroundColorByHexString).toBeDefined();\n            expect(typeof window.StatusBar.backgroundColorByHexString).toBe(\"function\");\n        });\n\n        it(\"statusbar.spec.4 should have set style methods\", function() {\n            expect(window.StatusBar.styleBlackTranslucent).toBeDefined();\n            expect(typeof window.StatusBar.styleBlackTranslucent).toBe(\"function\");\n\n            expect(window.StatusBar.styleDefault).toBeDefined();\n            expect(typeof window.StatusBar.styleDefault).toBe(\"function\");\n\n            expect(window.StatusBar.styleLightContent).toBeDefined();\n            expect(typeof window.StatusBar.styleLightContent).toBe(\"function\");\n\n            expect(window.StatusBar.styleBlackOpaque).toBeDefined();\n            expect(typeof window.StatusBar.styleBlackOpaque).toBe(\"function\");\n\n            expect(window.StatusBar.overlaysWebView).toBeDefined();\n            expect(typeof window.StatusBar.overlaysWebView).toBe(\"function\");\n        });\n    });\n};\n\nexports.defineManualTests = function (contentEl, createActionButton) {\n    function log(msg) {\n        var el = document.getElementById(\"info\");\n        var logLine = document.createElement('div');\n        logLine.innerHTML = msg;\n        el.appendChild(logLine);\n    }\n\n    function doShow() {\n        StatusBar.show();\n        log('StatusBar.isVisible=' + StatusBar.isVisible);\n    }\n\n    function doHide() {\n        StatusBar.hide();\n        log('StatusBar.isVisible=' + StatusBar.isVisible);\n    }\n\n    function doColor1() {\n        log('set color=red');\n        StatusBar.backgroundColorByName('red');\n    }\n\n    function doColor2() {\n        log('set style=translucent black');\n        StatusBar.styleBlackTranslucent();\n    }\n\n    function doColor3() {\n        log('set style=default');\n        StatusBar.styleDefault();\n    }\n\n    var showOverlay = true;\n    function doOverlay() {\n        showOverlay = !showOverlay;\n        StatusBar.overlaysWebView(showOverlay);\n        log('Set overlay=' + showOverlay);\n    }\n\n    /******************************************************************************/\n\n    contentEl.innerHTML = '<div id=\"info\"></div>' +\n        'Also: tapping bar on iOS should emit a log.' +\n        '<div id=\"action-show\"></div>' +\n        'Expected result: Status bar will be visible' +\n        '</p> <div id=\"action-hide\"></div>' +\n        'Expected result: Status bar will be hidden' +\n        '</p> <div id=\"action-color2\"></div>' +\n        'Expected result: Status bar text will be a light (white) color' +\n        '</p> <div id=\"action-color3\"></div>' +\n        'Expected result: Status bar text will be a dark (black) color' +\n        '</p> <div id=\"action-overlays\"></div>' +\n        'Expected result:<br>Overlay true = status bar will lay on top of web view content<br>Overlay false = status bar will be separate from web view and will not cover content' +\n        '</p> <div id=\"action-color1\"></div>' +\n        'Expected result: If overlay false, background color for status bar will be red';\n\n    log('StatusBar.isVisible=' + StatusBar.isVisible);\n    window.addEventListener('statusTap', function () {\n        log('tap!');\n    }, false);\n\n    createActionButton(\"Show\", function () {\n        doShow();\n    }, 'action-show');\n\n    createActionButton(\"Hide\", function () {\n        doHide();\n    }, 'action-hide');\n\n    createActionButton(\"Style=red (background)\", function () {\n        doColor1();\n    }, 'action-color1');\n\n    createActionButton(\"Style=translucent black\", function () {\n        doColor2();\n    }, 'action-color2');\n\n    createActionButton(\"Style=default\", function () {\n        doColor3();\n    }, 'action-color3');\n\n    createActionButton(\"Toggle Overlays\", function () {\n        doOverlay();\n    }, 'action-overlays');\n};\n"
  },
  {
    "path": "plugins/cordova-plugin-statusbar/www/statusbar.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\nvar exec = require('cordova/exec');\n\nvar namedColors = {\n    \"black\": \"#000000\",\n    \"darkGray\": \"#A9A9A9\",\n    \"lightGray\": \"#D3D3D3\",\n    \"white\": \"#FFFFFF\",\n    \"gray\": \"#808080\",\n    \"red\": \"#FF0000\",\n    \"green\": \"#00FF00\",\n    \"blue\": \"#0000FF\",\n    \"cyan\": \"#00FFFF\",\n    \"yellow\": \"#FFFF00\",\n    \"magenta\": \"#FF00FF\",\n    \"orange\": \"#FFA500\",\n    \"purple\": \"#800080\",\n    \"brown\": \"#A52A2A\"\n};\n\nvar StatusBar = {\n\n    isVisible: true,\n\n    overlaysWebView: function (doOverlay) {\n        exec(null, null, \"StatusBar\", \"overlaysWebView\", [doOverlay]);\n    },\n\n    styleDefault: function () {\n        // dark text ( to be used on a light background )\n        exec(null, null, \"StatusBar\", \"styleDefault\", []);\n    },\n\n    styleLightContent: function () {\n        // light text ( to be used on a dark background )\n        exec(null, null, \"StatusBar\", \"styleLightContent\", []);\n    },\n\n    styleBlackTranslucent: function () {\n        // #88000000 ? Apple says to use lightContent instead\n        exec(null, null, \"StatusBar\", \"styleBlackTranslucent\", []);\n    },\n\n    styleBlackOpaque: function () {\n        // #FF000000 ? Apple says to use lightContent instead\n        exec(null, null, \"StatusBar\", \"styleBlackOpaque\", []);\n    },\n\n    backgroundColorByName: function (colorname) {\n        return StatusBar.backgroundColorByHexString(namedColors[colorname]);\n    },\n\n    backgroundColorByHexString: function (hexString) {\n        if (hexString.charAt(0) !== \"#\") {\n            hexString = \"#\" + hexString;\n        }\n\n        if (hexString.length === 4) {\n            var split = hexString.split(\"\");\n            hexString = \"#\" + split[1] + split[1] + split[2] + split[2] + split[3] + split[3];\n        }\n\n        exec(null, null, \"StatusBar\", \"backgroundColorByHexString\", [hexString]);\n    },\n\n    hide: function () {\n        exec(null, null, \"StatusBar\", \"hide\", []);\n        StatusBar.isVisible = false;\n    },\n\n    show: function () {\n        exec(null, null, \"StatusBar\", \"show\", []);\n        StatusBar.isVisible = true;\n    }\n\n};\n\n// prime it\nexec(function (res) {\n    if (typeof res == 'object') {\n        if (res.type == 'tap') {\n            cordova.fireWindowEvent('statusTap');\n        }\n    } else {\n        StatusBar.isVisible = res;\n    }\n}, null, \"StatusBar\", \"_ready\", []);\n\nmodule.exports = StatusBar;\n"
  },
  {
    "path": "plugins/cordova-plugin-vibration/CONTRIBUTING.md",
    "content": "<!--\n#\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#  KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n#\n-->\n\n# Contributing to Apache Cordova\n\nAnyone can contribute to Cordova. And we need your contributions.\n\nThere are multiple ways to contribute: report bugs, improve the docs, and\ncontribute code.\n\nFor instructions on this, start with the \n[contribution overview](http://cordova.apache.org/#contribute).\n\nThe details are explained there, but the important items are:\n - Sign and submit an Apache ICLA (Contributor License Agreement).\n - Have a Jira issue open that corresponds to your contribution.\n - Run the tests so your patch doesn't break existing functionality.\n\nWe look forward to your contributions!\n"
  },
  {
    "path": "plugins/cordova-plugin-vibration/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License."
  },
  {
    "path": "plugins/cordova-plugin-vibration/NOTICE",
    "content": "Apache Cordova\nCopyright 2012 The Apache Software Foundation\n\nThis product includes software developed at\nThe Apache Software Foundation (http://www.apache.org/).\n\nThis product includes software developed by Joerg Wiedenmann under the zlib license (http://www.gzip.org/zlib/zlib_license.html)\n"
  },
  {
    "path": "plugins/cordova-plugin-vibration/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-vibration\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-vibration.svg)](https://travis-ci.org/apache/cordova-plugin-vibration)\n\nThis plugin aligns with the W3C vibration specification http://www.w3.org/TR/vibration/\n\nThis plugin provides a way to vibrate the device.\n\nThis plugin defines global objects including `navigator.vibrate`.\n\nAlthough in the global scope, they are not available until after the `deviceready` event.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(navigator.vibrate);\n    }\n\n## Installation\n\n    cordova plugin add cordova-plugin-vibration\n\n## Supported Platforms\n\nnavigator.vibrate,<br />\nnavigator.notification.vibrate\n- Amazon Fire OS\n- Android\n- BlackBerry 10\n- Firefox OS\n- iOS\n- Windows Phone 7 and 8\n- Windows (Windows Phone 8.1 devices only)\n\nnavigator.notification.vibrateWithPattern<br />\nnavigator.notification.cancelVibration\n- Android\n- Windows Phone 8\n- Windows (Windows Phone 8.1 devices only)\n\n## vibrate (recommended)\n\nThis function has three different functionalities based on parameters passed to it.\n\n###Standard vibrate\n\nVibrates the device for a given amount of time.\n\n    navigator.vibrate(time)\n\nor\n\n    navigator.vibrate([time])\n\n\n-__time__: Milliseconds to vibrate the device. _(Number)_\n\n####Example\n\n    // Vibrate for 3 seconds\n    navigator.vibrate(3000);\n\n    // Vibrate for 3 seconds\n    navigator.vibrate([3000]);\n\n####iOS Quirks\n\n- __time__: Ignores the specified time and vibrates for a pre-set amount of time.\n\n    navigator.vibrate(3000); // 3000 is ignored\n\n####Windows and Blackberry Quirks\n\n- __time__: Max time is 5000ms (5s) and min time is 1ms\n\n    navigator.vibrate(8000); // will be truncated to 5000\n\n###Vibrate with a pattern (Android and Windows only)\nVibrates the device with a given pattern\n\n    navigator.vibrate(pattern);   \n\n- __pattern__: Sequence of durations (in milliseconds) for which to turn on or off the vibrator. _(Array of Numbers)_\n\n####Example\n\n    // Vibrate for 1 second\n    // Wait for 1 second\n    // Vibrate for 3 seconds\n    // Wait for 1 second\n    // Vibrate for 5 seconds\n    navigator.vibrate([1000, 1000, 3000, 1000, 5000]);\n\n####Windows Phone 8 Quirks\n\n- vibrate(pattern) falls back on vibrate with default duration\n\n####Windows Quirks\n\n- vibrate(pattern) falls back on vibrate with default duration\n\n###Cancel vibration (not supported in iOS)\n\nImmediately cancels any currently running vibration.\n\n    navigator.vibrate(0)\n\nor\n\n    navigator.vibrate([])\n\nor\n\n    navigator.vibrate([0])\n\nPassing in a parameter of 0, an empty array, or an array with one element of value 0 will cancel any vibrations.\n\n## *notification.vibrate (deprecated)\n\nVibrates the device for a given amount of time.\n\n    navigator.notification.vibrate(time)\n\n- __time__: Milliseconds to vibrate the device. _(Number)_\n\n### Example\n\n    // Vibrate for 2.5 seconds\n    navigator.notification.vibrate(2500);\n\n### iOS Quirks\n\n- __time__: Ignores the specified time and vibrates for a pre-set amount of time.\n\n        navigator.notification.vibrate();\n        navigator.notification.vibrate(2500);   // 2500 is ignored\n\n## *notification.vibrateWithPattern (deprecated)\n\nVibrates the device with a given pattern.\n\n    navigator.notification.vibrateWithPattern(pattern, repeat)\n\n- __pattern__: Sequence of durations (in milliseconds) for which to turn on or off the vibrator. _(Array of Numbers)_\n- __repeat__: Optional index into the pattern array at which to start repeating (will repeat until canceled), or -1 for no repetition (default). _(Number)_\n\n### Example\n\n    // Immediately start vibrating\n    // vibrate for 100ms,\n    // wait for 100ms,\n    // vibrate for 200ms,\n    // wait for 100ms,\n    // vibrate for 400ms,\n    // wait for 100ms,\n    // vibrate for 800ms,\n    // (do not repeat)\n    navigator.notification.vibrateWithPattern([0, 100, 100, 200, 100, 400, 100, 800]);\n\n## *notification.cancelVibration (deprecated)\n\nImmediately cancels any currently running vibration.\n\n    navigator.notification.cancelVibration()\n\n*Note - due to alignment with w3c spec, the starred methods will be phased out"
  },
  {
    "path": "plugins/cordova-plugin-vibration/RELEASENOTES.md",
    "content": "<!--\n#\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n# \n# http://www.apache.org/licenses/LICENSE-2.0\n# \n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#  KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n#\n-->\n# Release Notes\n\n### 0.3.0 (Sept 5, 2013)\n* Initial FirefoxOS support\n* [CB-4661] VIBRATE permission for Android\n\n### 0.3.2 (Sept 25, 2013)\n* CB-4889 bumping&resetting version\n* CB-4889 renaming org.apache.cordova.core.vibration to org.apache.cordova.vibration\n* Rename CHANGELOG.md -> RELEASENOTES.md\n* updated to work with ffos commandProxy\n* fixed plugin.xml for vibration\n* [CB-4593] [Blackberry10] Added vibration support for bb10\n* updated plugin to work with ffos\n* [CB-4752] Incremented plugin version on dev branch.\n\n### 0.3.3 (Oct 9, 2013)\n* add missing android namespace\n* [CB-4915] Incremented plugin version on dev branch.\n\n### 0.3.4 (Oct 28, 2013)\n* add repo + issue tag to plugin.xml for vibration plugin\n* corrected plugin.xml to write properly to config.xml for ffos\n* [CB-5010] Incremented plugin version on dev branch.\n\n### 0.3.5 (Dec 4, 2013)\n* add ubuntu platform\n* Added amazon-fireos platform. Change to include amazon-fireos as a platform if the user agent string contains 'cordova-amazon-fireos'\n* CB-4747 Fixed Blackberry background vibrate\n\n### 0.3.6 (Jan 02, 2014)\n* CB-5658 Add doc/index.md for Vibration plugin\n\n### 0.3.7 (Feb 05, 2014)\n* Add support for Tizen.\n* CB-3206 - Supported platforms updated\n\n### 0.3.8 (Apr 17, 2014)\n* CB-6465: Add license headers to Tizen code\n* CB-6460: Update license headers\n* Add NOTICE file\n\n### 0.3.9 (Jun 05, 2014)\n* updated notice file\n* Github close #11\n* Extended vibrateWithPattern to allow for pattern repetition, implemented a complementary cancelVibration function and adapted documentation.\n* Implemented vibrateWithPattern (for android) and adapted documentation.\n* CB-6811 Add license to CONTRIBUTING.md\n* CB-6491 add CONTRIBUTING.md\n\n### 0.3.10 (Aug 06, 2014)\n* ubuntu: Implemented vibrateWithPattern/cancelVibration\n* **FFOS** update VibrationProxy.js\n* CB-6127 Updated translations for docs\n\n### 0.3.11 (Sep 17, 2014)\n* CB-7249 cordova-plugin-vibration documentation translation\n* CB-6724 documented Windows support for vibrate with pattern and cancel vibrate in manual test doc and moved tests to tests dir\n* add longer pattern sequence for testing, change expected result for old vibrate with pattern test\n* added more test cases, changed vibrate with pattern durations, changed where vibrateOn is set to true\n* clear settimeout when user cancels vibration\n* add setTimeout function to update vibrateOn var if user doesn't cancel vibrate, add note about iOS\n* on/off button for cancel tests, add results box and msgs\n* added tests for old vibrateWithPattern and cancelVibration calls\n* added 'Android only' to buttons for specific tests, changed where console.log is executed for user to see earlier\n* added tests to ensure compliance with w3c spec\n* CB-6963 ported vibration automated & manual tests\n* CB-6966 renamed folder to tests + added nested plugin.xml\n* CB-6966 Ported Vibration automated & manual tests\n* removed duplicate messaging\n* CB-5459 slight change to the vibration documentation for pattern due to merge issue\n* changes to how 0 is getting added to array in order to align with w3c spec\n* changes to vibration.java to align with w3c, changes to vibration.js for backwards compatibility\n* changes made to align with w3c spec\n* Updated doc with Windows support for vibrate with pattern\n* Added note to doc about w3c alignment and min time for Windows\n* update doc with another way to cancel vibration\n* update doc to show vibrate([num]) is a standard vibrate\n* vibrate([num]) is treated as a vibrate not vibrate with pattern\n* added new example to documentation\n* updated doc for w3c alignment\n* changes to how 0 is getting added to array in order to align with w3c spec\n* changes to vibration.java to align with w3c, changes to vibration.js for backwards compatibility\n* changes made to align with w3c spec\n\n### 0.3.12 (Dec 02, 2014)\n* CB-8018 Add `vibrate(pattern)` fallback on vibrate for **Windows Phone 8**\n* CB-7977 Mention `deviceready` in plugin docs\n* CB-7700 cordova-plugin-vibration documentation translation: cordova-plugin-vibration\n* CB-7571 Bump version of nested plugin to match parent plugin\n\n### 0.3.13 (Feb 04, 2015)\n* CB-8243 cordova-plugin-vibration documentation translation: cordova-plugin-vibration\n\n### 1.0.0 (Apr 15, 2015)\n* CB-8746 gave plugin major version bump\n* CB-8683 changed plugin-id to pacakge-name\n* CB-8653 properly updated translated docs to use new id\n* CB-8653 updated translated docs to use new id\n* CB-7970 Reference proxy project instead of compiled winmd\n* CB-7970 Add cordova-plugin-vibration support for Windows Phone 8.1\n* Use TRAVIS_BUILD_DIR, install paramedic by npm\n* CB-8653 Updated Readme\n* CB-8576 Integrate TravisCI\n* CB-8438 cordova-plugin-vibration documentation translation: cordova-plugin-vibration\n* CB-8538 Added package.json file\n\n### 1.1.0 (May 06, 2015)\n* CB-8930: Vibration on **Windows** fails without a helpful error message when vibration functionality is missing from the platform.  This detects such a case and instead fails gracefully that the feature isn't available.  Also supports the **Windows 10** vibration mechanism.\n\n### 1.2.0 (Jun 17, 2015)\n* Adding .ratignore file.\n* CB-9128 cordova-plugin-vibration documentation translation: cordova-plugin-vibration\n* fix npm md issue\n* used min/max statics in vibrate with pattern. Use callbackId in callbacks, catch json format exceptions\n* static-ized MIN_DURATION and MAX_DURATION\n* CB-7216 changed cancelWasCalled boolean\n* CB-7218 truncate vibration to 5 secs for WP8\n* CB-6916 added vibrateWithPattern for wp8\n* CB-6914 added cancelVibration for wp8\n* android: respect silent audio setting\n"
  },
  {
    "path": "plugins/cordova-plugin-vibration/doc/de/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-vibration\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-vibration.svg)](https://travis-ci.org/apache/cordova-plugin-vibration)\n\nDieses Plugin richtet mit dem W3C Vibration Spezifikation http://www.w3.org/TR/vibration/\n\nDieses Plugin bietet eine Möglichkeit, das Gerät zu vibrieren.\n\nDieses Plugin definiert globale Objekte einschließlich `navigator.vibrate`.\n\nObwohl im globalen Gültigkeitsbereich, sind sie nicht bis nach dem `deviceready`-Ereignis.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(navigator.vibrate);\n    }\n    \n\n## Installation\n\n    cordova plugin add cordova-plugin-vibration\n    \n\n## Unterstützte Plattformen\n\nnavigator.vibrate,  \nnavigator.notification.vibrate - Amazon Fire OS - Android - BlackBerry 10 - Firefox OS - iOS - Windows Phone 7 and 8 - Windows (Windows Phone 8.1 devices only)\n\nnavigator.notification.vibrateWithPattern  \nnavigator.notification.cancelVibration - Android - Windows Phone 8 - Windows (Windows Phone 8.1 devices only)\n\n## vibrieren (empfohlen)\n\nDiese Funktion hat drei verschiedene Funktionalitäten, die auf der Grundlage von an sie übergebenen Parameter.\n\n### Standard vibrieren\n\nVibriert das Gerät für einen bestimmten Zeitraum.\n\n    navigator.vibrate(time)\n    \n\noder\n\n    navigator.vibrate([time])\n    \n\n-**time**: Millisekunden das Gerät vibriert. *(Anzahl)*\n\n#### Beispiel\n\n    // Vibrate for 3 seconds\n    navigator.vibrate(3000);\n    \n    // Vibrate for 3 seconds\n    navigator.vibrate([3000]);\n    \n\n#### iOS Macken\n\n  * **Zeit**: ignoriert die angegebene Zeit und für eine voreingestellte Zeit vibriert.\n    \n    navigator.vibrate(3000); // 3000 is ignored\n\n#### Windows und Blackberry-Kniffe\n\n  * **Zeit**: Max. Zeit 5000ms (5 s) und min Zeit ist 1ms\n    \n    navigator.vibrate(8000); // will be truncated to 5000\n\n### Vibrieren Sie mit einem Muster (Android und Windows nur)\n\nVibriert das Gerät mit einem vorgegebenen Muster\n\n    navigator.vibrate(pattern);   \n    \n\n  * **Muster**: Folge von Dauer (in Millisekunden) für den ein-oder Ausschalten der Vibrator. *(Array von Zahlen)*\n\n#### Beispiel\n\n    // Vibrate for 1 second\n    // Wait for 1 second\n    // Vibrate for 3 seconds\n    // Wait for 1 second\n    // Vibrate for 5 seconds\n    navigator.vibrate([1000, 1000, 3000, 1000, 5000]);\n    \n\n#### Windows Phone 8 Macken\n\n  * vibrate(Pattern) fällt zurück vibrieren auf mit Standarddauer\n\n#### Windows-Eigenheiten\n\n  * vibrate(Pattern) fällt zurück vibrieren auf mit Standarddauer\n\n### \"Abbrechen\" Vibration (nicht in iOS unterstützt)\n\nSofort bricht alle derzeit ausgeführten Schwingungen.\n\n    navigator.vibrate(0)\n    \n\noder\n\n    navigator.vibrate([])\n    \n\noder\n\n    navigator.vibrate([0])\n    \n\nÜbergabe eines Parameters 0, wird ein leeres Array, oder ein Array mit einem Element der Wert 0 auftretender Schwingungen abbrechen.\n\n## *Notification.Vibrate (veraltet)\n\nVibriert das Gerät für einen bestimmten Zeitraum.\n\n    navigator.notification.vibrate(time)\n    \n\n  * **time**: Millisekunden das Gerät vibriert. *(Anzahl)*\n\n### Beispiel\n\n    // Vibrate for 2.5 seconds\n    navigator.notification.vibrate(2500);\n    \n\n### iOS Macken\n\n  * **Zeit**: ignoriert die angegebene Zeit und für eine voreingestellte Zeit vibriert.\n    \n        navigator.notification.vibrate();\n        navigator.notification.vibrate(2500);   // 2500 is ignored\n        \n\n## *Notification.vibrateWithPattern (veraltet)\n\nVibriert das Gerät mit einem vorgegebenen Muster.\n\n    navigator.notification.vibrateWithPattern(pattern, repeat)\n    \n\n  * **Muster**: Folge von Dauer (in Millisekunden) für den ein-oder Ausschalten der Vibrator. *(Array von Zahlen)*\n  * **repeat**: optionale Index in das Array Muster an der wiederholte (wird wiederholt, bis abgebrochen) zu starten, oder-1 für Wiederholung (Standard). *(Anzahl)*\n\n### Beispiel\n\n    // Immediately start vibrating\n    // vibrate for 100ms,\n    // wait for 100ms,\n    // vibrate for 200ms,\n    // wait for 100ms,\n    // vibrate for 400ms,\n    // wait for 100ms,\n    // vibrate for 800ms,\n    // (do not repeat)\n    navigator.notification.vibrateWithPattern([0, 100, 100, 200, 100, 400, 100, 800]);\n    \n\n## *Notification.cancelVibration (veraltet)\n\nSofort bricht alle derzeit ausgeführten Schwingungen.\n\n    navigator.notification.cancelVibration()\n    \n\n* Note - durch Angleichung an die w3c-Spezifikation, die markierten Methoden abgeschafft werden wird"
  },
  {
    "path": "plugins/cordova-plugin-vibration/doc/de/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-vibration\n\nDieses Plugin richtet mit dem W3C Vibration Spezifikation http://www.w3.org/TR/vibration/\n\nDieses Plugin bietet eine Möglichkeit, das Gerät zu vibrieren.\n\nDieses Plugin definiert globale Objekte einschließlich `navigator.vibrate`.\n\nObwohl im globalen Gültigkeitsbereich, sind sie nicht bis nach dem `deviceready`-Ereignis.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(navigator.vibrate);\n    }\n    \n\n## Installation\n\n    cordova plugin add cordova-plugin-vibration\n    \n\n## Unterstützte Plattformen\n\nnavigator.vibrate,  \nnavigator.notification.vibrate - Amazon Fire OS - Android - BlackBerry 10 - Firefox OS - iOS - Windows Phone 7 and 8\n\nnavigator.notification.vibrateWithPattern,  \nnavigator.notification.cancelVibration - Android - Windows Phone 8\n\n## vibrieren (empfohlen)\n\nDiese Funktion hat drei verschiedene Funktionalitäten, die auf der Grundlage von an sie übergebenen Parameter.\n\n### Standard vibrieren\n\nVibriert das Gerät für einen bestimmten Zeitraum.\n\n    navigator.vibrate(time)\n    \n\noder\n\n    navigator.vibrate([time])\n    \n\n-**time**: Millisekunden das Gerät vibriert. *(Anzahl)*\n\n#### Beispiel\n\n    // Vibrate for 3 seconds\n    navigator.vibrate(3000);\n    \n    // Vibrate for 3 seconds\n    navigator.vibrate([3000]);\n    \n\n#### iOS Macken\n\n*   **Zeit**: ignoriert die angegebene Zeit und für eine voreingestellte Zeit vibriert.\n    \n    navigator.vibrate(3000); // 3000 is ignored\n\n#### Windows und Blackberry-Kniffe\n\n*   **Zeit**: Max. Zeit 5000ms (5 s) und min Zeit ist 1ms\n    \n    navigator.vibrate(8000); // will be truncated to 5000\n\n### Vibrieren Sie mit einem Muster (Android und Windows nur)\n\nVibriert das Gerät mit einem vorgegebenen Muster\n\n    navigator.vibrate(pattern);   \n    \n\n*   **Muster**: Folge von Dauer (in Millisekunden) für den ein-oder Ausschalten der Vibrator. *(Array von Zahlen)*\n\n#### Beispiel\n\n    // Vibrate for 1 second\n    // Wait for 1 second\n    // Vibrate for 3 seconds\n    // Wait for 1 second\n    // Vibrate for 5 seconds\n    navigator.vibrate([1000, 1000, 3000, 1000, 5000]);\n    \n\n#### Windows Phone 8 Macken\n\n*   vibrate(Pattern) fällt zurück vibrieren auf mit Standarddauer\n\n### \"Abbrechen\" Vibration (nicht in iOS unterstützt)\n\nSofort bricht alle derzeit ausgeführten Schwingungen.\n\n    navigator.vibrate(0)\n    \n\noder\n\n    navigator.vibrate([])\n    \n\noder\n\n    navigator.vibrate([0])\n    \n\nÜbergabe eines Parameters 0, wird ein leeres Array, oder ein Array mit einem Element der Wert 0 auftretender Schwingungen abbrechen.\n\n## *Notification.Vibrate (veraltet)\n\nVibriert das Gerät für einen bestimmten Zeitraum.\n\n    navigator.notification.vibrate(time)\n    \n\n*   **time**: Millisekunden das Gerät vibriert. *(Anzahl)*\n\n### Beispiel\n\n    // Vibrate for 2.5 seconds\n    navigator.notification.vibrate(2500);\n    \n\n### iOS Macken\n\n*   **Zeit**: ignoriert die angegebene Zeit und für eine voreingestellte Zeit vibriert.\n    \n        navigator.notification.vibrate();\n        navigator.notification.vibrate(2500);   // 2500 is ignored\n        \n\n## *Notification.vibrateWithPattern (veraltet)\n\nVibriert das Gerät mit einem vorgegebenen Muster.\n\n    navigator.notification.vibrateWithPattern(pattern, repeat)\n    \n\n*   **pattern**: Folge von Dauer (in Millisekunden) für den ein-oder Ausschalten der Vibrator. *(Array von Zahlen)*\n*   **repeat**: optionale Index in das Array Muster an der wiederholte (wird wiederholt, bis abgebrochen) zu starten, oder-1 für Wiederholung (Standard). *(Anzahl)*\n\n### Beispiel\n\n    // Immediately start vibrating\n    // vibrate for 100ms,\n    // wait for 100ms,\n    // vibrate for 200ms,\n    // wait for 100ms,\n    // vibrate for 400ms,\n    // wait for 100ms,\n    // vibrate for 800ms,\n    // (do not repeat)\n    navigator.notification.vibrateWithPattern([0, 100, 100, 200, 100, 400, 100, 800]);\n    \n\n## *Notification.cancelVibration (veraltet)\n\nSofort bricht alle derzeit ausgeführten Schwingungen.\n\n    navigator.notification.cancelVibration()\n    \n\n* Note - durch Angleichung an die w3c-Spezifikation, die markierten Methoden abgeschafft werden wird\n"
  },
  {
    "path": "plugins/cordova-plugin-vibration/doc/es/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-vibration\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-vibration.svg)](https://travis-ci.org/apache/cordova-plugin-vibration)\n\nEste plugin se alinea con la vibración W3C especificación http://www.w3.org/TR/vibration/\n\nEste plugin proporciona una manera de vibrar el dispositivo.\n\nEste plugin define objetos globales incluyendo`navigator.vibrate`.\n\nAunque en el ámbito global, no están disponibles hasta después de la `deviceready` evento.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(navigator.vibrate);\n    }\n    \n\n## Instalación\n\n    cordova plugin add cordova-plugin-vibration\n    \n\n## Plataformas soportadas\n\nnavigator.vibrate,  \nnavigator.notification.vibrate - Amazon Fire OS - Android - BlackBerry 10 - Firefox OS - iOS - Windows Phone 7 and 8 - Windows (Windows Phone 8.1 devices only)\n\nnavigator.notification.vibrateWithPattern  \nnavigator.notification.cancelVibration - Android - Windows Phone 8 - Windows (Windows Phone 8.1 devices only)\n\n## vibrar (recomendado)\n\nEsta función tiene tres diferentes funcionalidades basadas en los parámetros pasados a él.\n\n### Estándar de vibrar\n\nVibra el dispositivo para una cantidad dada de tiempo.\n\n    navigator.vibrate(time)\n    \n\no\n\n    navigator.vibrate([time])\n    \n\n-**tiempo**: milisegundos a vibrar el dispositivo. *(Número)*\n\n#### Ejemplo\n\n    // Vibrate for 3 seconds\n    navigator.vibrate(3000);\n    \n    // Vibrate for 3 seconds\n    navigator.vibrate([3000]);\n    \n\n#### iOS rarezas\n\n  * **time**: ignora el tiempo especificado y vibra por un tiempo preestablecido.\n    \n    navigator.vibrate(3000); // 3000 is ignored\n\n#### Windows y rarezas de Blackberry\n\n  * **tiempo**: tiempo máximo es 5000ms (5s) y min tiempo 1ms\n    \n    navigator.vibrate(8000); // will be truncated to 5000\n\n### Vibrar con un patrón (Android y Windows solamente)\n\nVibra el dispositivo con un patrón determinado\n\n    navigator.vibrate(pattern);   \n    \n\n  * **patrón**: secuencia de duraciones (en milisegundos) que desea activar o desactivar el vibrador. *(Matriz de números)*\n\n#### Ejemplo\n\n    // Vibrate for 1 second\n    // Wait for 1 second\n    // Vibrate for 3 seconds\n    // Wait for 1 second\n    // Vibrate for 5 seconds\n    navigator.vibrate([1000, 1000, 3000, 1000, 5000]);\n    \n\n#### Windows Phone 8 rarezas\n\n  * Vibrate(Pattern) caídas detrás en vibración con duración predeterminada\n\n#### Windows rarezas\n\n  * Vibrate(Pattern) caídas detrás en vibración con duración predeterminada\n\n### Cancelar vibración (no soportada en iOS)\n\nInmediatamente se cancela cualquier vibración actualmente en ejecución.\n\n    navigator.vibrate(0)\n    \n\no\n\n    navigator.vibrate([])\n    \n\no\n\n    navigator.vibrate([0])\n    \n\nPasando en un parámetro de 0, una matriz vacía o una matriz con un elemento de valor 0 se cancelará cualquier vibraciones.\n\n## *Notification.Vibrate (obsoleto)\n\nVibra el dispositivo para una cantidad dada de tiempo.\n\n    navigator.notification.vibrate(time)\n    \n\n  * **tiempo**: milisegundos a vibrar el dispositivo. *(Número)*\n\n### Ejemplo\n\n    Vibrar por 2.5 segundos navigator.notification.vibrate(2500);\n    \n\n### iOS rarezas\n\n  * **time**: ignora el tiempo especificado y vibra por un tiempo preestablecido.\n    \n        navigator.notification.vibrate();\n        navigator.notification.vibrate(2500);   // 2500 is ignored\n        \n\n## *Notification.vibrateWithPattern (obsoleto)\n\nVibra el dispositivo con un patrón determinado.\n\n    navigator.notification.vibrateWithPattern(pattern, repeat)\n    \n\n  * **patrón**: secuencia de duraciones (en milisegundos) que desea activar o desactivar el vibrador. *(Matriz de números)*\n  * **repito**: índice opcional en la matriz de patrón en el cual comenzar repitiendo (se repite hasta que se cancele), o -1 para la no repetición (por defecto). *(Número)*\n\n### Ejemplo\n\n    // Immediately start vibrating\n    // vibrate for 100ms,\n    // wait for 100ms,\n    // vibrate for 200ms,\n    // wait for 100ms,\n    // vibrate for 400ms,\n    // wait for 100ms,\n    // vibrate for 800ms,\n    // (do not repeat)\n    navigator.notification.vibrateWithPattern([0, 100, 100, 200, 100, 400, 100, 800]);\n    \n\n## *Notification.cancelVibration (obsoleto)\n\nInmediatamente se cancela cualquier vibración actualmente en ejecución.\n\n    navigator.notification.cancelVibration()\n    \n\n* Nota: debido a la alineación con la especificación del w3c, los métodos favoritos a ser eliminados"
  },
  {
    "path": "plugins/cordova-plugin-vibration/doc/es/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-vibration\n\nEste plugin se alinea con la vibración W3C especificación http://www.w3.org/TR/vibration/\n\nEste plugin proporciona una manera de vibrar el dispositivo.\n\nEste plugin define objetos globales incluyendo`navigator.vibrate`.\n\nAunque en el ámbito global, no están disponibles hasta después de la `deviceready` evento.\n\n    document.addEventListener (\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {console.log(navigator.vibrate)};\n    \n\n## Instalación\n\n    Cordova plugin agregar cordova-plugin-vibration\n    \n\n## Plataformas soportadas\n\nNavigator.Vibrate,  \nNavigator.Notification.Vibrate - Amazon fuego OS - sistema operativo Android - BlackBerry 10 - Firefox - iOS - Windows Phone 7 y 8\n\nnavigator.notification.vibrateWithPattern,  \nnavigator.notification.cancelVibration - Android - Windows Phone 8\n\n## vibrar (recomendado)\n\nEsta función tiene tres diferentes funcionalidades basadas en los parámetros pasados a él.\n\n### Estándar de vibrar\n\nVibra el dispositivo para una cantidad dada de tiempo.\n\n    Navigator.Vibrate(Time)\n    \n\no\n\n    Navigator.Vibrate([time])\n    \n\n-**tiempo**: milisegundos a vibrar el dispositivo. *(Número)*\n\n#### Ejemplo\n\n    Vibrar para navigator.vibrate(3000) 3 segundos;\n    \n    Vibrar para navigator.vibrate([3000]) 3 segundos;\n    \n\n#### iOS rarezas\n\n*   **time**: ignora el tiempo especificado y vibra por un tiempo preestablecido.\n    \n    navigator.vibrate(3000); // 3000 is ignored\n\n#### Windows y rarezas de Blackberry\n\n*   **tiempo**: tiempo máximo es 5000ms (5s) y min tiempo 1ms\n    \n    navigator.vibrate(8000); // will be truncated to 5000\n\n### Vibrar con un patrón (Android y Windows solamente)\n\nVibra el dispositivo con un patrón determinado\n\n    Navigator.Vibrate(Pattern);   \n    \n\n*   **patrón**: secuencia de duraciones (en milisegundos) que desea activar o desactivar el vibrador. *(Matriz de números)*\n\n#### Ejemplo\n\n    Vibrar durante 1 segundo / / esperar 1 segundo / / vibrar durante 3 segundos / / esperar 1 segundo / / vibrar por 5 segundos navigator.vibrate ([1000, 1000, 3000, 1000, 5000]);\n    \n\n#### Windows Phone 8 rarezas\n\n*   Vibrate(Pattern) caídas detrás en vibración con duración predeterminada\n\n### Cancelar vibración (no soportada en iOS)\n\nInmediatamente se cancela cualquier vibración actualmente en ejecución.\n\n    Navigator.Vibrate(0)\n    \n\no\n\n    Navigator.Vibrate([])\n    \n\no\n\n    Navigator.Vibrate([0])\n    \n\nPasando en un parámetro de 0, una matriz vacía o una matriz con un elemento de valor 0 se cancelará cualquier vibraciones.\n\n## *Notification.Vibrate (obsoleto)\n\nVibra el dispositivo para una cantidad dada de tiempo.\n\n    Navigator.Notification.Vibrate(Time)\n    \n\n*   **tiempo**: milisegundos a vibrar el dispositivo. *(Número)*\n\n### Ejemplo\n\n    Vibrar por 2.5 segundos navigator.notification.vibrate(2500);\n    \n\n### iOS rarezas\n\n*   **tiempo**: ignora el tiempo especificado y vibra durante un tiempo preestablecido.\n    \n        Navigator.Notification.Vibrate();\n        Navigator.Notification.Vibrate(2500);   2500 se omite\n        \n\n## *Notification.vibrateWithPattern (obsoleto)\n\nVibra el dispositivo con un patrón determinado.\n\n    navigator.notification.vibrateWithPattern (patrón de repetición)\n    \n\n*   **patrón**: secuencia de duraciones (en milisegundos) que desea activar o desactivar el vibrador. *(Matriz de números)*\n*   **repito**: índice opcional en la matriz de patrón en el cual comenzar repitiendo (se repite hasta que se cancele), o -1 para la no repetición (por defecto). *(Número)*\n\n### Ejemplo\n\n    Inmediatamente comenzar a vibrar / / vibrar de 100ms, / / espera a 100ms, / / vibrar de 200ms, / / esperar 100ms, / / vibrar para 400ms, / / esperar 100ms, / / vibrar para 800ms, / / (no repetir) navigator.notification.vibrateWithPattern ([0, 100, 100, 200, 100, 400, 100, 800]);\n    \n\n## *Notification.cancelVibration (obsoleto)\n\nInmediatamente se cancela cualquier vibración actualmente en ejecución.\n\n    navigator.notification.cancelVibration()\n    \n\n* Nota: debido a la alineación con la especificación del w3c, los métodos favoritos a ser eliminados\n"
  },
  {
    "path": "plugins/cordova-plugin-vibration/doc/fr/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-vibration\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-vibration.svg)](https://travis-ci.org/apache/cordova-plugin-vibration)\n\nCe plugin s'aligne avec le W3C vibration spécification http://www.w3.org/TR/vibration/\n\nCe plugin permet de vibrer l'appareil.\n\nCe plugin définit notamment des objets globaux`navigator.vibrate`.\n\nBien que dans la portée globale, ils ne sont pas disponibles jusqu'après la `deviceready` événement.\n\n    document.addEventListener (« deviceready », onDeviceReady, false) ;\n    function onDeviceReady() {console.log(navigator.vibrate);}\n    \n\n## Installation\n\n    cordova plugin add cordova-plugin-vibration\n    \n\n## Plates-formes supportées\n\nnavigator.vibrate,  \nnavigator.notification.vibrate - Amazon Fire OS - Android - BlackBerry 10 - Firefox OS - iOS - Windows Phone 7 and 8 - Windows (Windows Phone 8.1 devices only)\n\nnavigator.notification.vibrateWithPattern  \nnavigator.notification.cancelVibration - Android - Windows Phone 8 - Windows (Windows Phone 8.1 devices only)\n\n## vibrer (recommandée)\n\nCette fonction a trois différentes fonctionnalités basées sur les paramètres passés à elle.\n\n### Norme vibrer\n\nVibre l'appareil pendant un certain temps.\n\n    Navigator.VIBRATE(Time)\n    \n\nou\n\n    Navigator.VIBRATE([time])\n    \n\n-**temps**: millisecondes à vibrer l'appareil. *(Nombre)*\n\n#### Exemple\n\n    Vibrer pour 3 secondes navigator.vibrate(3000) ;\n    \n    Vibrer pour 3 secondes navigator.vibrate([3000]) ;\n    \n\n#### Notes au sujet d'iOS\n\n  * **temps**: ne tient pas compte de la durée spécifiée et vibre pendant un temps prédéterminé.\n    \n    navigator.vibrate(3000); // 3000 is ignored\n\n#### Windows et les bizarreries de Blackberry\n\n  * **temps**: temps Max est 5000ms (5 s) et heure min est de 1 ms\n    \n    navigator.vibrate(8000); // will be truncated to 5000\n\n### Vibrer avec un motif (Android et Windows uniquement)\n\nVibre l'appareil avec un motif donné\n\n    Navigator.VIBRATE(Pattern) ;   \n    \n\n  * **modèle**: séquence de la durée (en millisecondes) pour lequel activer ou désactiver le vibreur. *(Tableau de nombres)*\n\n#### Exemple\n\n    Vibreur pendant 1 seconde / / attendre 1 seconde / / vibrer pendant 3 secondes / / attendre 1 seconde / / vibrer pour 5 secondes navigator.vibrate ([1000, 1000, 3000, 1000, 5000]) ;\n    \n\n#### Notes au sujet de Windows Phone 8\n\n  * chutes de VIBRATE(Pattern) retour à vibrent avec durée par défaut\n\n#### Bizarreries de Windows\n\n  * chutes de VIBRATE(Pattern) retour à vibrent avec durée par défaut\n\n### Annuler les vibrations (ne pas de prise en charge d'iOS)\n\nImmédiatement annule des vibrations en cours d'exécution.\n\n    Navigator.VIBRATE(0)\n    \n\nou\n\n    Navigator.VIBRATE([])\n    \n\nou\n\n    Navigator.VIBRATE([0])\n    \n\nEn passant un paramètre de 0, un tableau vide, ou un tableau contenant un seul élément de valeur 0 annulera toute vibration.\n\n## *notification.VIBRATE (obsolète)\n\nVibre l'appareil pendant un certain temps.\n\n    Navigator.notification.VIBRATE(Time)\n    \n\n  * **temps**: millisecondes à vibrer l'appareil. *(Nombre)*\n\n### Exemple\n\n    Vibrer pour 2,5 secondes navigator.notification.vibrate(2500) ;\n    \n\n### Notes au sujet d'iOS\n\n  * **temps**: ne tient pas compte de la durée spécifiée et vibre pendant un temps prédéterminé.\n    \n        Navigator.notification.VIBRATE() ;\n        Navigator.notification.VIBRATE(2500) ;   2500 est ignoré\n        \n\n## *notification.vibrateWithPattern (obsolète)\n\nVibre l'appareil avec un modèle donné.\n\n    navigator.notification.vibrateWithPattern (motif)\n    \n\n  * **modèle**: séquence de la durée (en millisecondes) pour lequel activer ou désactiver le vibreur. *(Tableau de nombres)*\n  * **répéter**: optionnel index dans le tableau de configuration à laquelle commencer à répéter (répétera jusqu'à annulation), ou -1 pour aucune répétition (par défaut). *(Nombre)*\n\n### Exemple\n\n    Commencent immédiatement à vibrer / / vibrer de 100ms, / / attendre 100ms, / / vibrer pour 200ms, / / attendre 100ms, / / vibrer pour 400ms, / / attendre 100ms, / / vibrer pour 800ms, / / (ne pas répéter) navigator.notification.vibrateWithPattern ([0, 100, 100, 200, 100, 400, 100, 800]) ;\n    \n\n## *notification.cancelVibration (obsolète)\n\nImmédiatement annule des vibrations en cours d'exécution.\n\n    navigator.notification.cancelVibration()\n    \n\n* Remarque : en raison de l'alignement avec les spécifications w3c, les méthodes étoilées seront progressivement"
  },
  {
    "path": "plugins/cordova-plugin-vibration/doc/fr/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-vibration\n\nCe plugin s'aligne avec le W3C vibration spécification http://www.w3.org/TR/vibration/\n\nCe plugin permet de vibrer l'appareil.\n\nCe plugin définit notamment des objets globaux`navigator.vibrate`.\n\nBien que dans la portée globale, ils ne sont pas disponibles jusqu'après la `deviceready` événement.\n\n    document.addEventListener (« deviceready », onDeviceReady, false) ;\n    function onDeviceReady() {console.log(navigator.vibrate);}\n    \n\n## Installation\n\n    Cordova plugin ajouter cordova-plugin-vibration\n    \n\n## Plates-formes prises en charge\n\nNavigator.VIBRATE,  \nNavigator.notification.VIBRATE - Amazon Fire OS - Android - BlackBerry 10 - Firefox OS - iOS - Windows Phone 7 et 8\n\nnavigator.notification.vibrateWithPattern,  \nnavigator.notification.cancelVibration - Android - Windows Phone 8\n\n## vibrer (recommandée)\n\nCette fonction a trois différentes fonctionnalités basées sur les paramètres passés à elle.\n\n### Norme vibrer\n\nVibre l'appareil pendant un certain temps.\n\n    Navigator.VIBRATE(Time)\n    \n\nou\n\n    Navigator.VIBRATE([time])\n    \n\n-**temps**: millisecondes à vibrer l'appareil. *(Nombre)*\n\n#### Exemple\n\n    Vibrer pour 3 secondes navigator.vibrate(3000) ;\n    \n    Vibrer pour 3 secondes navigator.vibrate([3000]) ;\n    \n\n#### iOS Quirks\n\n*   **temps**: ne tient pas compte de la durée spécifiée et vibre pendant un temps prédéterminé.\n    \n    navigator.vibrate(3000); // 3000 is ignored\n\n#### Windows et les bizarreries de Blackberry\n\n*   **temps**: temps Max est 5000ms (5 s) et heure min est de 1 ms\n    \n    navigator.vibrate(8000); // will be truncated to 5000\n\n### Vibrer avec un motif (Android et Windows uniquement)\n\nVibre l'appareil avec un motif donné\n\n    Navigator.VIBRATE(Pattern) ;   \n    \n\n*   **modèle**: séquence de la durée (en millisecondes) pour lequel activer ou désactiver le vibreur. *(Tableau de nombres)*\n\n#### Exemple\n\n    Vibreur pendant 1 seconde / / attendre 1 seconde / / vibrer pendant 3 secondes / / attendre 1 seconde / / vibrer pour 5 secondes navigator.vibrate ([1000, 1000, 3000, 1000, 5000]) ;\n    \n\n#### Windows Phone 8 Quirks\n\n*   chutes de VIBRATE(Pattern) retour à vibrent avec durée par défaut\n\n### Annuler les vibrations (ne pas de prise en charge d'iOS)\n\nImmédiatement annule des vibrations en cours d'exécution.\n\n    Navigator.VIBRATE(0)\n    \n\nou\n\n    Navigator.VIBRATE([])\n    \n\nou\n\n    Navigator.VIBRATE([0])\n    \n\nEn passant un paramètre de 0, un tableau vide, ou un tableau contenant un seul élément de valeur 0 annulera toute vibration.\n\n## *notification.VIBRATE (obsolète)\n\nVibre l'appareil pendant un certain temps.\n\n    Navigator.notification.VIBRATE(Time)\n    \n\n*   **temps**: millisecondes à vibrer l'appareil. *(Nombre)*\n\n### Exemple\n\n    Vibrer pour 2,5 secondes navigator.notification.vibrate(2500) ;\n    \n\n### iOS Quirks\n\n*   **temps**: ne tient pas compte de la durée spécifiée et vibre pendant un temps prédéterminé.\n    \n        Navigator.notification.VIBRATE() ;\n        Navigator.notification.VIBRATE(2500) ;   2500 est ignoré\n        \n\n## *notification.vibrateWithPattern (obsolète)\n\nVibre l'appareil avec un modèle donné.\n\n    navigator.notification.vibrateWithPattern (motif)\n    \n\n*   **modèle**: séquence de la durée (en millisecondes) pour lequel activer ou désactiver le vibreur. *(Tableau de nombres)*\n*   **répéter**: optionnel index dans le tableau de configuration à laquelle commencer à répéter (répétera jusqu'à annulation), ou -1 pour aucune répétition (par défaut). *(Nombre)*\n\n### Exemple\n\n    Commencent immédiatement à vibrer / / vibrer de 100ms, / / attendre 100ms, / / vibrer pour 200ms, / / attendre 100ms, / / vibrer pour 400ms, / / attendre 100ms, / / vibrer pour 800ms, / / (ne pas répéter) navigator.notification.vibrateWithPattern ([0, 100, 100, 200, 100, 400, 100, 800]) ;\n    \n\n## *notification.cancelVibration (obsolète)\n\nImmédiatement annule des vibrations en cours d'exécution.\n\n    navigator.notification.cancelVibration()\n    \n\n* Remarque : en raison de l'alignement avec les spécifications w3c, les méthodes étoilées seront progressivement\n"
  },
  {
    "path": "plugins/cordova-plugin-vibration/doc/it/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-vibration\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-vibration.svg)](https://travis-ci.org/apache/cordova-plugin-vibration)\n\nQuesto plugin si allinea con il W3C vibrazione specifica http://www.w3.org/TR/vibration/\n\nQuesto plugin consente di vibrare il dispositivo.\n\nQuesto plugin definisce gli oggetti globali, tra cui `navigator.vibrate`.\n\nAnche se in ambito globale, non sono disponibili fino a dopo l'evento `deviceready`.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(navigator.vibrate);\n    }\n    \n\n## Installazione\n\n    cordova plugin add cordova-plugin-vibration\n    \n\n## Piattaforme supportate\n\nnavigator.vibrate,  \nnavigator.notification.vibrate - Amazon Fire OS - Android - BlackBerry 10 - Firefox OS - iOS - Windows Phone 7 and 8 - Windows (Windows Phone 8.1 devices only)\n\nnavigator.notification.vibrateWithPattern  \nnavigator.notification.cancelVibration - Android - Windows Phone 8 - Windows (Windows Phone 8.1 devices only)\n\n## vibrare (consigliato)\n\nQuesta funzione ha tre differenti funzionalità basate su parametri passati ad esso.\n\n### Standard vibrare\n\nVibra il dispositivo per un determinato periodo di tempo.\n\n    navigator.vibrate(time)\n    \n\no\n\n    navigator.vibrate([time])\n    \n\n-**time**: millisecondi a vibrare il dispositivo. *(Numero)*\n\n#### Esempio\n\n    // Vibrate for 3 seconds\n    navigator.vibrate(3000);\n    \n    // Vibrate for 3 seconds\n    navigator.vibrate([3000]);\n    \n\n#### iOS stranezze\n\n  * **time**: ignora il tempo specificato e vibra per un tempo pre-impostato.\n    \n    navigator.vibrate(3000); // 3000 is ignored\n\n#### Windows e stranezze di Blackberry\n\n  * **time**: tempo Max 5000ms (5s) edè min tempo di 1ms\n    \n    navigator.vibrate(8000); // will be truncated to 5000\n\n### Vibrare con un pattern (Android e solo per Windows)\n\nVibra il dispositivo con un determinato modello\n\n    navigator.vibrate(pattern);   \n    \n\n  * **modello**: sequenza di durate (in millisecondi) per il quale attivare o disattivare il vibratore. *(Matrice di numeri)*\n\n#### Esempio\n\n    // Vibrate for 1 second\n    // Wait for 1 second\n    // Vibrate for 3 seconds\n    // Wait for 1 second\n    // Vibrate for 5 seconds\n    navigator.vibrate([1000, 1000, 3000, 1000, 5000]);\n    \n\n#### Windows Phone 8 stranezze\n\n  * vibrate(pattern) cade indietro a vibrano con durata predefinita\n\n#### Stranezze di Windows\n\n  * vibrate(pattern) cade indietro a vibrano con durata predefinita\n\n### Annullare le vibrazioni (non supportata in iOS)\n\nAnnulla immediatamente qualsiasi vibrazione attualmente in esecuzione.\n\n    navigator.vibrate(0)\n    \n\no\n\n    navigator.vibrate([])\n    \n\no\n\n    navigator.vibrate([0])\n    \n\nPassa un parametro 0, matrice vuota o una matrice con un elemento di valore 0 annullerà eventuali vibrazioni.\n\n## *notification.vibrate (deprecated)\n\nVibra il dispositivo per un determinato periodo di tempo.\n\n    navigator.notification.vibrate(time)\n    \n\n  * **time**: millisecondi a vibrare il dispositivo. *(Numero)*\n\n### Esempio\n\n    // Vibrate for 2.5 seconds\n    navigator.notification.vibrate(2500);\n    \n\n### iOS stranezze\n\n  * **time**: ignora il tempo specificato e vibra per un tempo pre-impostato.\n    \n        navigator.notification.vibrate();\n        navigator.notification.vibrate(2500);   // 2500 is ignored\n        \n\n## *Notification.vibrateWithPattern (obsoleto)\n\nVibra il dispositivo con un determinato modello.\n\n    navigator.notification.vibrateWithPattern(pattern, repeat)\n    \n\n  * **modello**: sequenza di durate (in millisecondi) per il quale attivare o disattivare il vibratore. *(Matrice di numeri)*\n  * **repeat**: opzionale indice nell'array modello presso cui iniziare ripetendo (ripeterà finché non annullato), o -1 per nessuna ripetizione (impostazione predefinita). *(Numero)*\n\n### Esempio\n\n    // Immediately start vibrating\n    // vibrate for 100ms,\n    // wait for 100ms,\n    // vibrate for 200ms,\n    // wait for 100ms,\n    // vibrate for 400ms,\n    // wait for 100ms,\n    // vibrate for 800ms,\n    // (do not repeat)\n    navigator.notification.vibrateWithPattern([0, 100, 100, 200, 100, 400, 100, 800]);\n    \n\n## *Notification.cancelVibration (obsoleto)\n\nAnnulla immediatamente qualsiasi vibrazione attualmente in esecuzione.\n\n    navigator.notification.cancelVibration()\n    \n\n* Nota - a causa di allineamento con le specifiche w3c, saranno essere ritirati i metodi speciali"
  },
  {
    "path": "plugins/cordova-plugin-vibration/doc/it/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-vibration\n\nQuesto plugin si allinea con il W3C vibrazione specifica http://www.w3.org/TR/vibration/\n\nQuesto plugin consente di vibrare il dispositivo.\n\nQuesto plugin definisce gli oggetti globali, tra cui `navigator.vibrate`.\n\nAnche se in ambito globale, non sono disponibili fino a dopo l'evento `deviceready`.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(navigator.vibrate);\n    }\n    \n\n## Installazione\n\n    cordova plugin add cordova-plugin-vibration\n    \n\n## Piattaforme supportate\n\nnavigator.vibrate,  \nnavigator.notification.vibrate - Amazon Fire OS - Android - BlackBerry 10 - Firefox OS - iOS - Windows Phone 7 and 8\n\nnavigator.notification.vibrateWithPattern,  \nnavigator.notification.cancelVibration - Android - Windows Phone 8\n\n## vibrare (consigliato)\n\nQuesta funzione ha tre differenti funzionalità basate su parametri passati ad esso.\n\n### Standard vibrare\n\nVibra il dispositivo per un determinato periodo di tempo.\n\n    navigator.vibrate(time)\n    \n\no\n\n    navigator.vibrate([time])\n    \n\n-**time**: millisecondi a vibrare il dispositivo. *(Numero)*\n\n#### Esempio\n\n    // Vibrate for 3 seconds\n    navigator.vibrate(3000);\n    \n    // Vibrate for 3 seconds\n    navigator.vibrate([3000]);\n    \n\n#### iOS stranezze\n\n*   **time**: ignora il tempo specificato e vibra per un tempo pre-impostato.\n    \n    navigator.vibrate(3000); // 3000 is ignored\n\n#### Windows e stranezze di Blackberry\n\n*   **time**: tempo Max 5000ms (5s) edè min tempo di 1ms\n    \n    navigator.vibrate(8000); // will be truncated to 5000\n\n### Vibrare con un pattern (Android e solo per Windows)\n\nVibra il dispositivo con un determinato modello\n\n    navigator.vibrate(pattern);   \n    \n\n*   **modello**: sequenza di durate (in millisecondi) per il quale attivare o disattivare il vibratore. *(Matrice di numeri)*\n\n#### Esempio\n\n    // Vibrate for 1 second\n    // Wait for 1 second\n    // Vibrate for 3 seconds\n    // Wait for 1 second\n    // Vibrate for 5 seconds\n    navigator.vibrate([1000, 1000, 3000, 1000, 5000]);\n    \n\n#### Windows Phone 8 stranezze\n\n*   vibrate(pattern) cade indietro a vibrano con durata predefinita\n\n### Annullare le vibrazioni (non supportata in iOS)\n\nAnnulla immediatamente qualsiasi vibrazione attualmente in esecuzione.\n\n    navigator.vibrate(0)\n    \n\no\n\n    navigator.vibrate([])\n    \n\no\n\n    navigator.vibrate([0])\n    \n\nPassa un parametro 0, matrice vuota o una matrice con un elemento di valore 0 annullerà eventuali vibrazioni.\n\n## *notification.vibrate (deprecated)\n\nVibra il dispositivo per un determinato periodo di tempo.\n\n    navigator.notification.vibrate(time)\n    \n\n*   **time**: millisecondi a vibrare il dispositivo. *(Numero)*\n\n### Esempio\n\n    // Vibrate for 2.5 seconds\n    navigator.notification.vibrate(2500);\n    \n\n### iOS stranezze\n\n*   **time**: ignora il tempo specificato e vibra per un tempo pre-impostato.\n    \n        navigator.notification.vibrate();\n        navigator.notification.vibrate(2500);   // 2500 is ignored\n        \n\n## *Notification.vibrateWithPattern (obsoleto)\n\nVibra il dispositivo con un determinato modello.\n\n    navigator.notification.vibrateWithPattern(pattern, repeat)\n    \n\n*   **modello**: sequenza di durate (in millisecondi) per il quale attivare o disattivare il vibratore. *(Matrice di numeri)*\n*   **repeat**: opzionale indice nell'array modello presso cui iniziare ripetendo (ripeterà finché non annullato), o -1 per nessuna ripetizione (impostazione predefinita). *(Numero)*\n\n### Esempio\n\n    // Immediately start vibrating\n    // vibrate for 100ms,\n    // wait for 100ms,\n    // vibrate for 200ms,\n    // wait for 100ms,\n    // vibrate for 400ms,\n    // wait for 100ms,\n    // vibrate for 800ms,\n    // (do not repeat)\n    navigator.notification.vibrateWithPattern([0, 100, 100, 200, 100, 400, 100, 800]);\n    \n\n## *Notification.cancelVibration (obsoleto)\n\nAnnulla immediatamente qualsiasi vibrazione attualmente in esecuzione.\n\n    navigator.notification.cancelVibration()\n    \n\n* Nota - a causa di allineamento con le specifiche w3c, saranno essere ritirati i metodi speciali\n"
  },
  {
    "path": "plugins/cordova-plugin-vibration/doc/ja/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-vibration\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-vibration.svg)](https://travis-ci.org/apache/cordova-plugin-vibration)\n\nこのプラグインに準拠 W3C 振動仕様 http://www.w3.org/TR/vibration/\n\nこのプラグインは、デバイスを振動させる方法を提供します。\n\nこのプラグインは `navigator.vibrate` などのグローバル オブジェクトを定義します.\n\nグローバル スコープでは使用できませんまで `deviceready` イベントの後です。\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(navigator.vibrate);\n    }\n    \n\n## インストール\n\n    cordova plugin add cordova-plugin-vibration\n    \n\n## サポートされているプラットフォーム\n\nnavigator.vibrate,  \nnavigator.notification.vibrate - Amazon Fire OS - Android - BlackBerry 10 - Firefox OS - iOS - Windows Phone 7 and 8 - Windows (Windows Phone 8.1 devices only)\n\nnavigator.notification.vibrateWithPattern  \nnavigator.notification.cancelVibration - Android - Windows Phone 8 - Windows (Windows Phone 8.1 devices only)\n\n## 振動 (推奨)\n\nこの関数は、渡されたパラメーターに基づいて 3 つのさまざまな機能。\n\n### 標準を振動します。\n\n一定の時間のため、デバイスが振動します。\n\n    navigator.vibrate(time)\n    \n\nまたは\n\n    navigator.vibrate([time])\n    \n\n-**time**: ミリ秒、デバイスを振動させる。*(数)*\n\n#### 例\n\n    // Vibrate for 3 seconds\n    navigator.vibrate(3000);\n    \n    // Vibrate for 3 seconds\n    navigator.vibrate([3000]);\n    \n\n#### iOS の癖\n\n  * **時間**: 指定された時間を無視し、時間の事前に設定された量のために振動します。\n    \n    navigator.vibrate(3000); // 3000 is ignored\n\n#### Windows とブラックベリー癖\n\n  * **時間**: 5000 (5 秒) は、最大時間と最小時間は 1 ms\n    \n    navigator.vibrate(8000); // will be truncated to 5000\n\n### （人造人間と Windows のみ) パターンで振動します。\n\n特定のパターンを持つデバイスが振動します。\n\n    navigator.vibrate(pattern);   \n    \n\n  * **パターン**: シーケンスの継続時間 (ミリ秒単位) をオンまたはオフ、バイブします。*(数字の配列)*\n\n#### 例\n\n    // Vibrate for 1 second\n    // Wait for 1 second\n    // Vibrate for 3 seconds\n    // Wait for 1 second\n    // Vibrate for 5 seconds\n    navigator.vibrate([1000, 1000, 3000, 1000, 5000]);\n    \n\n#### Windows Phone 8 癖\n\n  * 既定の期間の振動で戻る vibrate(pattern) の滝\n\n#### Windows の癖\n\n  * 既定の期間の振動で戻る vibrate(pattern) の滝\n\n### [キャンセル] 振動 (iOS ではサポートされていません)\n\nすぐに、現在実行中の振動をキャンセルします。\n\n    navigator.vibrate(0)\n    \n\nまたは\n\n    navigator.vibrate([])\n    \n\nまたは\n\n    navigator.vibrate([0])\n    \n\n0 のパラメーターを渡して、空の配列、または 0 の値の 1 つの要素を持つ配列は任意振動がキャンセルされます。\n\n## *notification.vibrate (非推奨)\n\n一定の時間のため、デバイスが振動します。\n\n    navigator.notification.vibrate(time)\n    \n\n  * **time**: ミリ秒、デバイスを振動させる。*(数)*\n\n### 例\n\n    // Vibrate for 2.5 seconds\n    navigator.notification.vibrate(2500);\n    \n\n### iOS の癖\n\n  * **時間**: 指定された時間を無視し、時間の事前に設定された量のために振動します。\n    \n        navigator.notification.vibrate();\n        navigator.notification.vibrate(2500);   // 2500 is ignored\n        \n\n## *notification.vibrateWithPattern (非推奨)\n\n特定のパターンを持つデバイスが振動します。\n\n    navigator.notification.vibrateWithPattern(pattern, repeat)\n    \n\n  * **パターン**: シーケンスの継続時間 (ミリ秒単位) をオンまたはオフ、バイブします。*(数字の配列)*\n  * **repeat**: 省略可能な配列のインデックスのパターン （でしょう） を繰り返す取り消されるまで、繰り返しを開始するまたは反復なし (既定値) の場合は-1。*(数)*\n\n### 例\n\n    // Immediately start vibrating\n    // vibrate for 100ms,\n    // wait for 100ms,\n    // vibrate for 200ms,\n    // wait for 100ms,\n    // vibrate for 400ms,\n    // wait for 100ms,\n    // vibrate for 800ms,\n    // (do not repeat)\n    navigator.notification.vibrateWithPattern([0, 100, 100, 200, 100, 400, 100, 800]);\n    \n\n## *notification.cancelVibration (非推奨)\n\nすぐに、現在実行中の振動をキャンセルします。\n\n    navigator.notification.cancelVibration()\n    \n\n* 注 - w3c の仕様を配置、ため主演メソッドがフェーズ アウトされます。"
  },
  {
    "path": "plugins/cordova-plugin-vibration/doc/ja/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-vibration\n\nこのプラグインに準拠 W3C 振動仕様 http://www.w3.org/TR/vibration/\n\nこのプラグインは、デバイスを振動させる方法を提供します。\n\nこのプラグインは `navigator.vibrate` などのグローバル オブジェクトを定義します.\n\nグローバル スコープでは使用できませんまで `deviceready` イベントの後です。\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(navigator.vibrate);\n    }\n    \n\n## インストール\n\n    cordova plugin add cordova-plugin-vibration\n    \n\n## サポートされているプラットフォーム\n\nnavigator.vibrate,  \nnavigator.notification.vibrate - Amazon Fire OS - Android - BlackBerry 10 - Firefox OS - iOS - Windows Phone 7 and 8\n\nnavigator.notification.vibrateWithPattern,  \nnavigator.notification.cancelVibration - Android - Windows Phone 8\n\n## 振動 (推奨)\n\nこの関数は、渡されたパラメーターに基づいて 3 つのさまざまな機能。\n\n### 標準を振動します。\n\n一定の時間のため、デバイスが振動します。\n\n    navigator.vibrate(time)\n    \n\nまたは\n\n    navigator.vibrate([time])\n    \n\n-**time**: ミリ秒、デバイスを振動させる。*(数)*\n\n#### 例\n\n    // Vibrate for 3 seconds\n    navigator.vibrate(3000);\n    \n    // Vibrate for 3 seconds\n    navigator.vibrate([3000]);\n    \n\n#### iOS の癖\n\n*   **時間**: 指定された時間を無視し、時間の事前に設定された量のために振動します。\n    \n    navigator.vibrate(3000); // 3000 is ignored\n\n#### Windows とブラックベリー癖\n\n*   **時間**: 5000 (5 秒) は、最大時間と最小時間は 1 ms\n    \n    navigator.vibrate(8000); // will be truncated to 5000\n\n### （人造人間と Windows のみ) パターンで振動します。\n\n特定のパターンを持つデバイスが振動します。\n\n    navigator.vibrate(pattern);   \n    \n\n*   **パターン**: シーケンスの継続時間 (ミリ秒単位) をオンまたはオフ、バイブします。*(数字の配列)*\n\n#### 例\n\n    // Vibrate for 1 second\n    // Wait for 1 second\n    // Vibrate for 3 seconds\n    // Wait for 1 second\n    // Vibrate for 5 seconds\n    navigator.vibrate([1000, 1000, 3000, 1000, 5000]);\n    \n\n#### Windows Phone 8 癖\n\n*   既定の期間の振動で戻る vibrate(pattern) の滝\n\n### [キャンセル] 振動 (iOS ではサポートされていません)\n\nすぐに、現在実行中の振動をキャンセルします。\n\n    navigator.vibrate(0)\n    \n\nまたは\n\n    navigator.vibrate([])\n    \n\nまたは\n\n    navigator.vibrate([0])\n    \n\n0 のパラメーターを渡して、空の配列、または 0 の値の 1 つの要素を持つ配列は任意振動がキャンセルされます。\n\n## *notification.vibrate (非推奨)\n\n一定の時間のため、デバイスが振動します。\n\n    navigator.notification.vibrate(time)\n    \n\n*   **time**: ミリ秒、デバイスを振動させる。*(数)*\n\n### 例\n\n    // Vibrate for 2.5 seconds\n    navigator.notification.vibrate(2500);\n    \n\n### iOS の癖\n\n*   **時間**: 指定された時間を無視し、時間の事前に設定された量のために振動します。\n    \n        navigator.notification.vibrate();\n        navigator.notification.vibrate(2500);   // 2500 is ignored\n        \n\n## *notification.vibrateWithPattern (非推奨)\n\n特定のパターンを持つデバイスが振動します。\n\n    navigator.notification.vibrateWithPattern(pattern, repeat)\n    \n\n*   **pattern**: シーケンスの継続時間 (ミリ秒単位) をオンまたはオフ、バイブします。*(数字の配列)*\n*   **repeat**: 省略可能な配列のインデックスのパターン （でしょう） を繰り返す取り消されるまで、繰り返しを開始するまたは反復なし (既定値) の場合は-1。*(数)*\n\n### 例\n\n    // Immediately start vibrating\n    // vibrate for 100ms,\n    // wait for 100ms,\n    // vibrate for 200ms,\n    // wait for 100ms,\n    // vibrate for 400ms,\n    // wait for 100ms,\n    // vibrate for 800ms,\n    // (do not repeat)\n    navigator.notification.vibrateWithPattern([0, 100, 100, 200, 100, 400, 100, 800]);\n    \n\n## *notification.cancelVibration (非推奨)\n\nすぐに、現在実行中の振動をキャンセルします。\n\n    navigator.notification.cancelVibration()\n    \n\n* 注 - w3c の仕様を配置、ため主演メソッドがフェーズ アウトされます。\n"
  },
  {
    "path": "plugins/cordova-plugin-vibration/doc/ko/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-vibration\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-vibration.svg)](https://travis-ci.org/apache/cordova-plugin-vibration)\n\n이 플러그인에 W3C 진동 사양 http://www.w3.org/TR/vibration/ 정렬\n\n이 플러그인에는 장치를 진동 하는 방법을 제공 합니다.\n\n이 플러그인 `navigator.vibrate`를 포함 하는 전역 개체를 정의 합니다..\n\n전역 범위에서 그들은 제공 되지 않습니다 때까지 `deviceready` 이벤트 후.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(navigator.vibrate);\n    }\n    \n\n## 설치\n\n    cordova plugin add cordova-plugin-vibration\n    \n\n## 지원 되는 플랫폼\n\nnavigator.vibrate,  \nnavigator.notification.vibrate - Amazon Fire OS - Android - BlackBerry 10 - Firefox OS - iOS - Windows Phone 7 and 8 - Windows (Windows Phone 8.1 devices only)\n\nnavigator.notification.vibrateWithPattern  \nnavigator.notification.cancelVibration - Android - Windows Phone 8 - Windows (Windows Phone 8.1 devices only)\n\n## 진동 (권장)\n\n이 함수는 전달 된 매개 변수에 따라 세 가지 다른 기능.\n\n### 기준 진동\n\n주어진 시간 동안 장치를 진동.\n\n    navigator.vibrate(time)\n    \n\n또는\n\n    navigator.vibrate([time])\n    \n\n-**time**: 진동 장치 (밀리초)입니다. *(수)*\n\n#### 예를 들어\n\n    // Vibrate for 3 seconds\n    navigator.vibrate(3000);\n    \n    // Vibrate for 3 seconds\n    navigator.vibrate([3000]);\n    \n\n#### iOS 단점\n\n  * **시간**: 지정 된 시간을 무시 하 고 미리 설정 된 시간 동안 진동.\n    \n    navigator.vibrate(3000); // 3000 is ignored\n\n#### 윈도 즈와 블랙베리 단점\n\n  * **시간**: 최대 시간은 2000ms (5s) 이며 최소 시간 1ms\n    \n    navigator.vibrate(8000); // will be truncated to 5000\n\n### (안 드 로이드와 Windows에만 해당) 패턴으로 진동\n\n지정 된 패턴으로 장치를 진동\n\n    navigator.vibrate(pattern);   \n    \n\n  * **패턴**:의 기간 (밀리초)에서 진동을 켜거나 끌 수 있는 순서. *(숫자의 배열)*\n\n#### 예를 들어\n\n    // Vibrate for 1 second\n    // Wait for 1 second\n    // Vibrate for 3 seconds\n    // Wait for 1 second\n    // Vibrate for 5 seconds\n    navigator.vibrate([1000, 1000, 3000, 1000, 5000]);\n    \n\n#### Windows Phone 8 단점\n\n  * vibrate(pattern) 폭포 다시에 기본 기간 진동\n\n#### 윈도우 특수\n\n  * vibrate(pattern) 폭포 다시에 기본 기간 진동\n\n### 진동 (iOS에서 지원 되지 않음) 취소\n\n즉시 모든 현재 실행 중인 진동을 취소합니다.\n\n    navigator.vibrate(0)\n    \n\n또는\n\n    navigator.vibrate([])\n    \n\n또는\n\n    navigator.vibrate([0])\n    \n\n0의 매개 변수 전달, 빈 배열, 또는 0 값의 한 요소 배열은 어떤 진동을 취소할 것 이다.\n\n## *notification.vibrate (사용 되지 않음)\n\n주어진 시간 동안 장치를 진동.\n\n    navigator.notification.vibrate(time)\n    \n\n  * **time**: 진동 장치 (밀리초)입니다. *(수)*\n\n### 예를 들어\n\n    // Vibrate for 2.5 seconds\n    navigator.notification.vibrate(2500);\n    \n\n### iOS 단점\n\n  * **시간**: 지정 된 시간을 무시 하 고 미리 설정 된 시간 동안 진동.\n    \n        navigator.notification.vibrate();\n        navigator.notification.vibrate(2500);   // 2500 is ignored\n        \n\n## *notification.vibrateWithPattern (사용 되지 않음)\n\n지정 된 패턴으로 장치 진동.\n\n    navigator.notification.vibrateWithPattern(pattern, repeat)\n    \n\n  * **패턴**:의 기간 (밀리초)에서 진동을 켜거나 끌 수 있는 순서. *(숫자의 배열)*\n  * **repeat**: 반복 (취소 될 때까지 반복 됩니다), 시작 하는 또는-1 (기본값) 없는 반복에 대 한 패턴 배열에 선택적 인덱스. *(수)*\n\n### 예를 들어\n\n    // Immediately start vibrating\n    // vibrate for 100ms,\n    // wait for 100ms,\n    // vibrate for 200ms,\n    // wait for 100ms,\n    // vibrate for 400ms,\n    // wait for 100ms,\n    // vibrate for 800ms,\n    // (do not repeat)\n    navigator.notification.vibrateWithPattern([0, 100, 100, 200, 100, 400, 100, 800]);\n    \n\n## *notification.cancelVibration (사용 되지 않음)\n\n즉시 모든 현재 실행 중인 진동을 취소합니다.\n\n    navigator.notification.cancelVibration()\n    \n\n* 참고-때문에 w3c 사양 가진 줄 맞춤, 별표 메서드 밖으로 단계별로 됩니다."
  },
  {
    "path": "plugins/cordova-plugin-vibration/doc/ko/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-vibration\n\n이 플러그인에 W3C 진동 사양 http://www.w3.org/TR/vibration/ 정렬\n\n이 플러그인에는 장치를 진동 하는 방법을 제공 합니다.\n\n이 플러그인 `navigator.vibrate`를 포함 하는 전역 개체를 정의 합니다..\n\n전역 범위에서 그들은 제공 되지 않습니다 때까지 `deviceready` 이벤트 후.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(navigator.vibrate);\n    }\n    \n\n## 설치\n\n    cordova plugin add cordova-plugin-vibration\n    \n\n## 지원 되는 플랫폼\n\nnavigator.vibrate,  \nnavigator.notification.vibrate - Amazon Fire OS - Android - BlackBerry 10 - Firefox OS - iOS - Windows Phone 7 and 8\n\nnavigator.notification.vibrateWithPattern,  \nnavigator.notification.cancelVibration - Android - Windows Phone 8\n\n## vibrate (recommended)\n\n이 함수는 전달 된 매개 변수에 따라 세 가지 다른 기능.\n\n### 기준 진동\n\n주어진 시간 동안 장치를 진동.\n\n    navigator.vibrate(time)\n    \n\n또는\n\n    navigator.vibrate([time])\n    \n\n-**time**: 진동 장치 (밀리초)입니다. *(수)*\n\n#### 예를 들어\n\n    // Vibrate for 3 seconds\n    navigator.vibrate(3000);\n    \n    // Vibrate for 3 seconds\n    navigator.vibrate([3000]);\n    \n\n#### iOS 단점\n\n*   **시간**: 지정 된 시간을 무시 하 고 미리 설정 된 시간 동안 진동.\n    \n    navigator.vibrate(3000); // 3000 is ignored\n\n#### 윈도 즈와 블랙베리 단점\n\n*   **시간**: 최대 시간은 2000ms (5s) 이며 최소 시간 1ms\n    \n    navigator.vibrate(8000); // will be truncated to 5000\n\n### (안 드 로이드와 Windows에만 해당) 패턴으로 진동\n\n지정 된 패턴으로 장치를 진동\n\n    navigator.vibrate(pattern);   \n    \n\n*   **패턴**:의 기간 (밀리초)에서 진동을 켜거나 끌 수 있는 순서. *(숫자의 배열)*\n\n#### 예를 들어\n\n    // Vibrate for 1 second\n    // Wait for 1 second\n    // Vibrate for 3 seconds\n    // Wait for 1 second\n    // Vibrate for 5 seconds\n    navigator.vibrate([1000, 1000, 3000, 1000, 5000]);\n    \n\n#### Windows Phone 8 단점\n\n*   vibrate(pattern) 폭포 다시에 기본 기간 진동\n\n### 진동 (iOS에서 지원 되지 않음) 취소\n\n즉시 모든 현재 실행 중인 진동을 취소합니다.\n\n    navigator.vibrate(0)\n    \n\n또는\n\n    navigator.vibrate([])\n    \n\n또는\n\n    navigator.vibrate([0])\n    \n\n0의 매개 변수 전달, 빈 배열, 또는 0 값의 한 요소 배열은 어떤 진동을 취소할 것 이다.\n\n## *notification.vibrate (사용 되지 않음)\n\n주어진 시간 동안 장치를 진동.\n\n    navigator.notification.vibrate(time)\n    \n\n*   **time**: 진동 장치 (밀리초)입니다. *(수)*\n\n### 예를 들어\n\n    // Vibrate for 2.5 seconds\n    navigator.notification.vibrate(2500);\n    \n\n### iOS 단점\n\n*   **시간**: 지정 된 시간을 무시 하 고 미리 설정 된 시간 동안 진동.\n    \n        navigator.notification.vibrate();\n        navigator.notification.vibrate(2500);   // 2500 is ignored\n        \n\n## *notification.vibrateWithPattern (사용 되지 않음)\n\n지정 된 패턴으로 장치 진동.\n\n    navigator.notification.vibrateWithPattern(pattern, repeat)\n    \n\n*   **pattern**:의 기간 (밀리초)에서 진동을 켜거나 끌 수 있는 순서. *(숫자의 배열)*\n*   **repeat**: 반복 (취소 될 때까지 반복 됩니다), 시작 하는 또는-1 (기본값) 없는 반복에 대 한 패턴 배열에 선택적 인덱스. *(수)*\n\n### 예를 들어\n\n    // Immediately start vibrating\n    // vibrate for 100ms,\n    // wait for 100ms,\n    // vibrate for 200ms,\n    // wait for 100ms,\n    // vibrate for 400ms,\n    // wait for 100ms,\n    // vibrate for 800ms,\n    // (do not repeat)\n    navigator.notification.vibrateWithPattern([0, 100, 100, 200, 100, 400, 100, 800]);\n    \n\n## *notification.cancelVibration (사용 되지 않음)\n\n즉시 모든 현재 실행 중인 진동을 취소합니다.\n\n    navigator.notification.cancelVibration()\n    \n\n* 참고-때문에 w3c 사양 가진 줄 맞춤, 별표 메서드 밖으로 단계별로 됩니다.\n"
  },
  {
    "path": "plugins/cordova-plugin-vibration/doc/pl/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-vibration\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-vibration.svg)](https://travis-ci.org/apache/cordova-plugin-vibration)\n\nTen plugin wyrównuje z http://www.w3.org/TR/vibration/ specyfikacji W3C wibracji\n\nTen plugin umożliwia wibracje urządzenia.\n\nTen plugin definiuje obiekty globalne, w tym `navigator.vibrate`.\n\nChociaż w globalnym zasięgu, są nie dostępne dopiero po `deviceready` imprezie.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(navigator.vibrate);\n    }\n    \n\n## Instalacja\n\n    cordova plugin add cordova-plugin-vibration\n    \n\n## Obsługiwane platformy\n\nnavigator.vibrate,  \nnavigator.notification.vibrate - Amazon Fire OS - Android - BlackBerry 10 - Firefox OS - iOS - Windows Phone 7 and 8 - Windows (Windows Phone 8.1 devices only)\n\nnavigator.notification.vibrateWithPattern  \nnavigator.notification.cancelVibration - Android - Windows Phone 8 - Windows (Windows Phone 8.1 devices only)\n\n## wibracje (zalecane)\n\nFunkcja ta ma trzy różne funkcje na podstawie parametrów przekazywanych do niej.\n\n### Standardowe wibracje\n\nWibruje urządzenie na określoną ilość czasu.\n\n    navigator.vibrate(time)\n    \n\nlub\n\n    navigator.vibrate([time])\n    \n\n-**time**: milisekund wibracje urządzenia. *(Liczba)*\n\n#### Przykład\n\n    // Vibrate for 3 seconds\n    navigator.vibrate(3000);\n    \n    // Vibrate for 3 seconds\n    navigator.vibrate([3000]);\n    \n\n#### Dziwactwa iOS\n\n  * **czas**: ignoruje określony czas i wibruje na wstępnie określoną ilość czasu.\n    \n    navigator.vibrate(3000); // 3000 is ignored\n\n#### Windows i Blackberry dziwactwa\n\n  * **czas**: Max czas jest 5000ms (5s) i min czas 1ms\n    \n    navigator.vibrate(8000); // will be truncated to 5000\n\n### Wibracje z wzorem (Android i Windows tylko)\n\nWibruje urządzenie z danego wzoru\n\n    navigator.vibrate(pattern);   \n    \n\n  * **wzór**: sekwencja czas trwania (w milisekundach), dla której chcesz włączyć lub wyłączyć wibrator. *(Tablica liczb)*\n\n#### Przykład\n\n    // Vibrate for 1 second\n    // Wait for 1 second\n    // Vibrate for 3 seconds\n    // Wait for 1 second\n    // Vibrate for 5 seconds\n    navigator.vibrate([1000, 1000, 3000, 1000, 5000]);\n    \n\n#### Windows Phone 8 dziwactwa\n\n  * vibrate(Pattern) spada z powrotem na wibracje z domyślny czas trwania\n\n#### Windows dziwactwa\n\n  * vibrate(Pattern) spada z powrotem na wibracje z domyślny czas trwania\n\n### Anuluj wibracji (nieobsługiwane w iOS)\n\nNiezwłocznie anuluje aktualnie uruchomione wibracje.\n\n    navigator.vibrate(0)\n    \n\nlub\n\n    navigator.vibrate([])\n    \n\nlub\n\n    navigator.vibrate([0])\n    \n\nPrzekazując parametr 0, pustą tablicę lub tablicy z jednym z elementów wartości 0 spowoduje anulowanie wibracji.\n\n## *Notification.vibrate (przestarzałe)\n\nWibruje urządzenie na określoną ilość czasu.\n\n    navigator.notification.vibrate(time)\n    \n\n  * **time**: milisekund wibracje urządzenia. *(Liczba)*\n\n### Przykład\n\n    // Vibrate for 2.5 seconds\n    navigator.notification.vibrate(2500);\n    \n\n### Dziwactwa iOS\n\n  * **czas**: ignoruje określony czas i wibruje na wstępnie określoną ilość czasu.\n    \n        navigator.notification.vibrate();\n        navigator.notification.vibrate(2500);   // 2500 is ignored\n        \n\n## *Notification.vibrateWithPattern (przestarzałe)\n\nWibruje urządzenie z danego wzoru.\n\n    navigator.notification.vibrateWithPattern(pattern, repeat)\n    \n\n  * **wzór**: sekwencja czas trwania (w milisekundach), dla której chcesz włączyć lub wyłączyć wibrator. *(Tablica liczb)*\n  * **repeat**: opcjonalny indeks do tablicy wzór który zacząć powtarzać (będzie powtarzać do momentu anulowane), lub -1 nie powtarzania (domyślnie). *(Liczba)*\n\n### Przykład\n\n    // Immediately start vibrating\n    // vibrate for 100ms,\n    // wait for 100ms,\n    // vibrate for 200ms,\n    // wait for 100ms,\n    // vibrate for 400ms,\n    // wait for 100ms,\n    // vibrate for 800ms,\n    // (do not repeat)\n    navigator.notification.vibrateWithPattern([0, 100, 100, 200, 100, 400, 100, 800]);\n    \n\n## *Notification.cancelVibration (przestarzałe)\n\nNiezwłocznie anuluje aktualnie uruchomione wibracje.\n\n    navigator.notification.cancelVibration()\n    \n\n* Uwaga - ze względu na dostosowanie specyfikacji w3c, oznaczonych gwiazdką metody zostaną wycofane"
  },
  {
    "path": "plugins/cordova-plugin-vibration/doc/pl/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-vibration\n\nTen plugin wyrównuje z http://www.w3.org/TR/vibration/ specyfikacji W3C wibracji\n\nTen plugin umożliwia wibracje urządzenia.\n\nTen plugin definiuje obiekty globalne, w tym `navigator.vibrate`.\n\nChociaż w globalnym zasięgu, są nie dostępne dopiero po `deviceready` imprezie.\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(navigator.vibrate);\n    }\n    \n\n## Instalacja\n\n    cordova plugin add cordova-plugin-vibration\n    \n\n## Obsługiwane platformy\n\nnavigator.vibrate,  \nnavigator.notification.vibrate - Amazon Fire OS - Android - BlackBerry 10 - Firefox OS - iOS - Windows Phone 7 and 8\n\nnavigator.notification.vibrateWithPattern,  \nnavigator.notification.cancelVibration - Android - Windows Phone 8\n\n## wibracje (zalecane)\n\nFunkcja ta ma trzy różne funkcje na podstawie parametrów przekazywanych do niej.\n\n### Standardowe wibracje\n\nWibruje urządzenie na określoną ilość czasu.\n\n    navigator.vibrate(time)\n    \n\nlub\n\n    navigator.vibrate([time])\n    \n\n-**time**: milisekund wibracje urządzenia. *(Liczba)*\n\n#### Przykład\n\n    // Vibrate for 3 seconds\n    navigator.vibrate(3000);\n    \n    // Vibrate for 3 seconds\n    navigator.vibrate([3000]);\n    \n\n#### Dziwactwa iOS\n\n*   **czas**: ignoruje określony czas i wibruje na wstępnie określoną ilość czasu.\n    \n    navigator.vibrate(3000); // 3000 is ignored\n\n#### Windows i Blackberry dziwactwa\n\n*   **czas**: Max czas jest 5000ms (5s) i min czas 1ms\n    \n    navigator.vibrate(8000); // will be truncated to 5000\n\n### Wibracje z wzorem (Android i Windows tylko)\n\nWibruje urządzenie z danego wzoru\n\n    navigator.vibrate(pattern);   \n    \n\n*   **wzór**: sekwencja czas trwania (w milisekundach), dla której chcesz włączyć lub wyłączyć wibrator. *(Tablica liczb)*\n\n#### Przykład\n\n    // Vibrate for 1 second\n    // Wait for 1 second\n    // Vibrate for 3 seconds\n    // Wait for 1 second\n    // Vibrate for 5 seconds\n    navigator.vibrate([1000, 1000, 3000, 1000, 5000]);\n    \n\n#### Windows Phone 8 dziwactwa\n\n*   vibrate(Pattern) spada z powrotem na wibracje z domyślny czas trwania\n\n### Anuluj wibracji (nieobsługiwane w iOS)\n\nNiezwłocznie anuluje aktualnie uruchomione wibracje.\n\n    navigator.vibrate(0)\n    \n\nlub\n\n    navigator.vibrate([])\n    \n\nlub\n\n    navigator.vibrate([0])\n    \n\nPrzekazując parametr 0, pustą tablicę lub tablicy z jednym z elementów wartości 0 spowoduje anulowanie wibracji.\n\n## *Notification.vibrate (przestarzałe)\n\nWibruje urządzenie na określoną ilość czasu.\n\n    navigator.notification.vibrate(time)\n    \n\n*   **time**: milisekund wibracje urządzenia. *(Liczba)*\n\n### Przykład\n\n    // Vibrate for 2.5 seconds\n    navigator.notification.vibrate(2500);\n    \n\n### Dziwactwa iOS\n\n*   **czas**: ignoruje określony czas i wibruje na wstępnie określoną ilość czasu.\n    \n        navigator.notification.vibrate();\n        navigator.notification.vibrate(2500);   // 2500 is ignored\n        \n\n## *Notification.vibrateWithPattern (przestarzałe)\n\nWibruje urządzenie z danego wzoru.\n\n    navigator.notification.vibrateWithPattern(pattern, repeat)\n    \n\n*   **pattern**: sekwencja czas trwania (w milisekundach), dla której chcesz włączyć lub wyłączyć wibrator. *(Tablica liczb)*\n*   **repeat**: opcjonalny indeks do tablicy wzór który zacząć powtarzać (będzie powtarzać do momentu anulowane), lub -1 nie powtarzania (domyślnie). *(Liczba)*\n\n### Przykład\n\n    // Immediately start vibrating\n    // vibrate for 100ms,\n    // wait for 100ms,\n    // vibrate for 200ms,\n    // wait for 100ms,\n    // vibrate for 400ms,\n    // wait for 100ms,\n    // vibrate for 800ms,\n    // (do not repeat)\n    navigator.notification.vibrateWithPattern([0, 100, 100, 200, 100, 400, 100, 800]);\n    \n\n## *Notification.cancelVibration (przestarzałe)\n\nNiezwłocznie anuluje aktualnie uruchomione wibracje.\n\n    navigator.notification.cancelVibration()\n    \n\n* Uwaga - ze względu na dostosowanie specyfikacji w3c, oznaczonych gwiazdką metody zostaną wycofane\n"
  },
  {
    "path": "plugins/cordova-plugin-vibration/doc/ru/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-vibration\n\nЭтот плагин соотвествует спецификации W3C http://www.w3.org/TR/vibration/ о вибрации\n\nЭтот плагин позволяет управлять вибрацией устройства.\n\n## Установка\n\n    cordova plugin add cordova-plugin-vibration\n    \n\n## Поддерживаемые платформы\n\nNavigator.Vibrate  \nNavigator.Notification.Vibrate - Amazon Fire OS - Android - BlackBerry 10 - Firefox OS - iOS - Windows Phone 7 и 8\n\nnavigator.notification.vibrateWithPattern,  \nnavigator.notification.cancelVibration - Android\n\n## vibrate (рекомендуемый)\n\nЭта функция имеет три различных функцала, на основе параметров, передаваемых ей.\n\n### Стандартная вибрация\n\nУстройство вибрирует в течении определенного количества времени.\n\n    navigator.vibrate(time)\n    \n\nили\n\n    navigator.vibrate([time])\n    \n\n-**time**: Сколько миллисекунд будет вибрировать устройство. *(Число)*\n\n#### Пример\n\n    // Vibrate for 3 seconds\n    navigator.vibrate(3000);\n    \n    // Vibrate for 3 seconds\n    navigator.vibrate([3000]);\n    \n\n#### Особенности iOS\n\n*   **time**: игнорирует указанное время и вибрирует предопределенный отрезок времени.\n    \n    navigator.vibrate(3000); // 3000 is ignored\n\n#### Особенности Windows и Blackberry\n\n*   **time**: Максимальное время 5000мс (5с) и минимальное время 1 мс\n    \n    navigator.vibrate(8000); // will be truncated to 5000\n\n### Вибрировать по шаблону (только Android и Windows)\n\nВибрирует на устройства с заданным шаблоном\n\n    navigator.vibrate(pattern);   \n    \n\n*   **pattern**: последовательность длительностей (в миллисекундах), в течение которого требуется включить или выключить вибрацию. *(Массив из чисел)*\n\n#### Пример\n\n    // Vibrate for 1 second\n    // Wait for 1 second\n    // Vibrate for 3 seconds\n    // Wait for 1 second\n    // Vibrate for 5 seconds\n    navigator.vibrate([1000, 1000, 3000, 1000, 5000]);\n    \n\n### Отмена вибрации (не поддерживается в iOS)\n\nНемедленно отменяет любые выполняющиеся вибрации.\n\n    navigator.vibrate(0)\n    \n\nили\n\n    navigator.vibrate([])\n    \n\nили\n\n    navigator.vibrate([0])\n    \n\nПередавая в параметре 0, пустой массив, или массив с одним элементом значения 0, на устройстве будет отменена любая вибрация.\n\n## *notification.vibrate (устарело)\n\nУстройство вибрирует за определенное количество времени.\n\n    navigator.notification.vibrate(time)\n    \n\n*   **time**: Сколько миллисекунд будет вибрировать устройство. *(Число)*\n\n### Пример\n\n    // Vibrate for 2.5 seconds\n    navigator.notification.vibrate(2500);\n    \n\n### Особенности iOS\n\n*   **time**: игнорирует указанное время и вибрирует предопределенный отрезок времени.\n    \n        navigator.notification.vibrate();\n        navigator.notification.vibrate(2500);   // 2500 is ignored\n        \n\n## *notification.vibrateWithPattern (устарело)\n\nВибрирует на устройства с заданным шаблоном.\n\n    navigator.notification.vibrateWithPattern(pattern, repeat)\n    \n\n*   **pattern**: последовательность длительностей (в миллисекундах), в течение которого требуется включить или выключить вибрацию. *(Массив из чисел)*\n*   **repeat**: Необязательные индекс в массиве шаблона вибрации, начиная с которого начать повторять вибрацию (будет повторяться пока не будет отменен), или -1 для отсуствия повторения (по умолчанию). *(Число)*\n\n### Пример\n\n    // Immediately start vibrating\n    // vibrate for 100ms,\n    // wait for 100ms,\n    // vibrate for 200ms,\n    // wait for 100ms,\n    // vibrate for 400ms,\n    // wait for 100ms,\n    // vibrate for 800ms,\n    // (do not repeat)\n    navigator.notification.vibrateWithPattern([0, 100, 100, 200, 100, 400, 100, 800]);\n    \n\n## *notification.cancelVibration (устарело)\n\nНемедленно отменяет любые выполняющиеся вибрации.\n\n    navigator.notification.cancelVibration()\n    \n\n* Обратите внимание - из-за соответствие спецификации w3c, Отмеченные методы будут поэтапно выведены из эксплаутации\n"
  },
  {
    "path": "plugins/cordova-plugin-vibration/doc/zh/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-vibration\n\n[![Build Status](https://travis-ci.org/apache/cordova-plugin-vibration.svg)](https://travis-ci.org/apache/cordova-plugin-vibration)\n\n這個外掛程式將對齊與 W3C 振動規範 HTTP://www.w3.org/TR/vibration/\n\n這個外掛程式提供了方法振動設備。\n\n這個外掛程式定義全域物件包括 `navigator.vibrate`.\n\n雖然在全球範圍內，他們不可用直到 `deviceready` 事件之後。\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(navigator.vibrate);\n    }\n    \n\n## 安裝\n\n    cordova plugin add cordova-plugin-vibration\n    \n\n## 支援的平臺\n\nnavigator.vibrate,  \nnavigator.notification.vibrate - Amazon Fire OS - Android - BlackBerry 10 - Firefox OS - iOS - Windows Phone 7 and 8 - Windows (Windows Phone 8.1 devices only)\n\nnavigator.notification.vibrateWithPattern  \nnavigator.notification.cancelVibration - Android - Windows Phone 8 - Windows (Windows Phone 8.1 devices only)\n\n## 震動 (推薦)\n\n此函數具有三個不同的功能，基於傳遞給它的參數。\n\n### 標準振動\n\n為給定時間振動設備。\n\n    navigator.vibrate(time)\n    \n\n或\n\n    navigator.vibrate([time])\n    \n\n-**time**： 毫秒振動裝置。*（數）*\n\n#### 示例\n\n    // Vibrate for 3 seconds\n    navigator.vibrate(3000);\n    \n    // Vibrate for 3 seconds\n    navigator.vibrate([3000]);\n    \n\n#### iOS 的怪癖\n\n  * **time**： 忽略指定的時間和震動的一個預先設定的時間。\n    \n    navigator.vibrate(3000); // 3000 is ignored\n\n#### Windows 和黑莓的怪癖\n\n  * **time**： 最長時間是 5000ms (5s) 和最小時間為 1ms\n    \n    navigator.vibrate(8000); // will be truncated to 5000\n\n### 以一種模式 （安卓系統和僅限 Windows） 振動\n\n振動具有給定模式的設備\n\n    navigator.vibrate(pattern);   \n    \n\n  * **pattern**： 序列的持續時間 （以毫秒為單位） 為其打開或關閉振動器。*（數位陣列）*\n\n#### 示例\n\n    // Vibrate for 1 second\n    // Wait for 1 second\n    // Vibrate for 3 seconds\n    // Wait for 1 second\n    // Vibrate for 5 seconds\n    navigator.vibrate([1000, 1000, 3000, 1000, 5000]);\n    \n\n#### Windows Phone 8 怪癖\n\n  * vibrate(pattern) 瀑布回來上振動與預設持續時間\n\n#### Windows 的怪癖\n\n  * vibrate(pattern) 瀑布回來上振動與預設持續時間\n\n### 取消振動 （iOS 中不支援）\n\n立即取消任何當前正在運行的振動。\n\n    navigator.vibrate(0)\n    \n\n或\n\n    navigator.vibrate([])\n    \n\n或\n\n    navigator.vibrate([0])\n    \n\n在一個為 0 的參數中傳遞，空陣列或陣列的一個元素的值為 0 將取消任何振動。\n\n## *notification.vibrate (已棄用)\n\n為給定時間振動設備。\n\n    navigator.notification.vibrate(time)\n    \n\n  * **time**： 毫秒振動裝置。*（數）*\n\n### 示例\n\n    // Vibrate for 2.5 seconds\n    navigator.notification.vibrate(2500);\n    \n\n### iOS 的怪癖\n\n  * **time**： 忽略指定的時間和震動的一個預先設定的時間。\n    \n        navigator.notification.vibrate();\n        navigator.notification.vibrate(2500);   // 2500 is ignored\n        \n\n## *notification.vibrateWithPattern (已棄用)\n\n振動具有給定模式的設備。\n\n    navigator.notification.vibrateWithPattern(pattern, repeat)\n    \n\n  * **pattern**： 序列的持續時間 （以毫秒為單位） 為其打開或關閉振動器。*（數位陣列）*\n  * **repeat**： 在從中開始重複 （會重複，直到取消)，或-1 （預設值） 沒有重複模式陣列中的可選索引。*（數）*\n\n### 示例\n\n    // Immediately start vibrating\n    // vibrate for 100ms,\n    // wait for 100ms,\n    // vibrate for 200ms,\n    // wait for 100ms,\n    // vibrate for 400ms,\n    // wait for 100ms,\n    // vibrate for 800ms,\n    // (do not repeat)\n    navigator.notification.vibrateWithPattern([0, 100, 100, 200, 100, 400, 100, 800]);\n    \n\n## *notification.cancelVibration (已棄用)\n\n立即取消任何當前正在運行的振動。\n\n    navigator.notification.cancelVibration()\n    \n\n* 請注意--由於符合 w3c 規範，出演的方法將被淘汰"
  },
  {
    "path": "plugins/cordova-plugin-vibration/doc/zh/index.md",
    "content": "<!---\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n-->\n\n# cordova-plugin-vibration\n\n這個外掛程式將對齊與 W3C 振動規範 HTTP://www.w3.org/TR/vibration/\n\n這個外掛程式提供了方法振動設備。\n\n這個外掛程式定義全域物件包括 `navigator.vibrate`.\n\n雖然在全球範圍內，他們不可用直到 `deviceready` 事件之後。\n\n    document.addEventListener(\"deviceready\", onDeviceReady, false);\n    function onDeviceReady() {\n        console.log(navigator.vibrate);\n    }\n    \n\n## 安裝\n\n    cordova plugin add cordova-plugin-vibration\n    \n\n## 支援的平臺\n\nnavigator.vibrate,  \nnavigator.notification.vibrate - Amazon Fire OS - Android - BlackBerry 10 - Firefox OS - iOS - Windows Phone 7 and 8\n\nnavigator.notification.vibrateWithPattern,  \nnavigator.notification.cancelVibration - Android - Windows Phone 8\n\n## 震動 (推薦)\n\n此函數具有三個不同的功能，基於傳遞給它的參數。\n\n### 標準振動\n\n為給定時間振動設備。\n\n    navigator.vibrate(time)\n    \n\n或\n\n    navigator.vibrate([time])\n    \n\n-**time**： 毫秒振動裝置。*（數）*\n\n#### 示例\n\n    // Vibrate for 3 seconds\n    navigator.vibrate(3000);\n    \n    // Vibrate for 3 seconds\n    navigator.vibrate([3000]);\n    \n\n#### iOS 的怪癖\n\n*   **time**： 忽略指定的時間和震動的一個預先設定的時間。\n    \n    navigator.vibrate(3000); // 3000 is ignored\n\n#### Windows 和黑莓的怪癖\n\n*   **time**： 最長時間是 5000ms (5s) 和最小時間為 1ms\n    \n    navigator.vibrate(8000); // will be truncated to 5000\n\n### 以一種模式 （安卓系統和僅限 Windows） 振動\n\n振動具有給定模式的設備\n\n    navigator.vibrate(pattern);   \n    \n\n*   **pattern**： 序列的持續時間 （以毫秒為單位） 為其打開或關閉振動器。*（數位陣列）*\n\n#### 示例\n\n    // Vibrate for 1 second\n    // Wait for 1 second\n    // Vibrate for 3 seconds\n    // Wait for 1 second\n    // Vibrate for 5 seconds\n    navigator.vibrate([1000, 1000, 3000, 1000, 5000]);\n    \n\n#### Windows Phone 8 怪癖\n\n*   vibrate(pattern) 瀑布回來上振動與預設持續時間\n\n### 取消振動 （iOS 中不支援）\n\n立即取消任何當前正在運行的振動。\n\n    navigator.vibrate(0)\n    \n\n或\n\n    navigator.vibrate([])\n    \n\n或\n\n    navigator.vibrate([0])\n    \n\n在一個為 0 的參數中傳遞，空陣列或陣列的一個元素的值為 0 將取消任何振動。\n\n## *notification.vibrate (已棄用)\n\n為給定時間振動設備。\n\n    navigator.notification.vibrate(time)\n    \n\n*   **time**： 毫秒振動裝置。*（數）*\n\n### 示例\n\n    // Vibrate for 2.5 seconds\n    navigator.notification.vibrate(2500);\n    \n\n### iOS 的怪癖\n\n*   **time**： 忽略指定的時間和震動的一個預先設定的時間。\n    \n        navigator.notification.vibrate();\n        navigator.notification.vibrate(2500);   // 2500 is ignored\n        \n\n## *notification.vibrateWithPattern (已棄用)\n\n振動具有給定模式的設備。\n\n    navigator.notification.vibrateWithPattern(pattern, repeat)\n    \n\n*   **pattern**： 序列的持續時間 （以毫秒為單位） 為其打開或關閉振動器。*（數位陣列）*\n*   **repeat**： 在從中開始重複 （會重複，直到取消)，或-1 （預設值） 沒有重複模式陣列中的可選索引。*（數）*\n\n### 示例\n\n    // Immediately start vibrating\n    // vibrate for 100ms,\n    // wait for 100ms,\n    // vibrate for 200ms,\n    // wait for 100ms,\n    // vibrate for 400ms,\n    // wait for 100ms,\n    // vibrate for 800ms,\n    // (do not repeat)\n    navigator.notification.vibrateWithPattern([0, 100, 100, 200, 100, 400, 100, 800]);\n    \n\n## *notification.cancelVibration (已棄用)\n\n立即取消任何當前正在運行的振動。\n\n    navigator.notification.cancelVibration()\n    \n\n* 請注意--由於符合 w3c 規範，出演的方法將被淘汰\n"
  },
  {
    "path": "plugins/cordova-plugin-vibration/package.json",
    "content": "{\n  \"name\": \"cordova-plugin-vibration\",\n  \"version\": \"1.2.0\",\n  \"description\": \"Cordova Vibration Plugin\",\n  \"cordova\": {\n    \"id\": \"cordova-plugin-vibration\",\n    \"platforms\": [\n      \"firefoxos\",\n      \"wp7\",\n      \"wp8\",\n      \"android\",\n      \"amazon-fireos\",\n      \"ubuntu\",\n      \"ios\",\n      \"blackberry10\",\n      \"tizen\"\n    ]\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/apache/cordova-plugin-vibration\"\n  },\n  \"keywords\": [\n    \"cordova\",\n    \"vibration\",\n    \"ecosystem:cordova\",\n    \"cordova-firefoxos\",\n    \"cordova-wp7\",\n    \"cordova-wp8\",\n    \"cordova-android\",\n    \"cordova-amazon-fireos\",\n    \"cordova-ubuntu\",\n    \"cordova-ios\",\n    \"cordova-blackberry10\",\n    \"cordova-tizen\"\n  ],\n  \"author\": \"Apache Software Foundation\",\n  \"license\": \"Apache 2.0\"\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-vibration/plugin.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  Licensed to the Apache Software Foundation (ASF) under one\n  or more contributor license agreements.  See the NOTICE file\n  distributed with this work for additional information\n  regarding copyright ownership.  The ASF licenses this file\n  to you under the Apache License, Version 2.0 (the\n  \"License\"); you may not use this file except in compliance\n  with the License.  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing,\n  software distributed under the License is distributed on an\n  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n  KIND, either express or implied.  See the License for the\n  specific language governing permissions and limitations\n  under the License.\n-->\n\n<plugin xmlns=\"http://apache.org/cordova/ns/plugins/1.0\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    id=\"cordova-plugin-vibration\"\n    version=\"1.2.0\">\n\n    <name>Vibration</name>\n    <description>Cordova Vibration Plugin</description>\n    <license>Apache 2.0</license>\n    <keywords>cordova,vibration</keywords>\n    <repo>https://git-wip-us.apache.org/repos/asf/cordova-plugin-vibration.git</repo>\n    <issue>https://issues.apache.org/jira/browse/CB/component/12320639</issue>\n\n    <js-module src=\"www/vibration.js\" name=\"notification\">\n        <merges target=\"navigator.notification\" />\n        <merges target=\"navigator\" />\n    </js-module>\n\n    <!-- firefoxos -->\n    <platform name=\"firefoxos\">\n        <config-file target=\"www/config.xml\" parent=\"/*\">\n            <feature name=\"Vibration\">\n                <param name=\"firefoxos-package\" value=\"Vibration\" />\n            </feature>\n        </config-file>                                         \n        <js-module src=\"src/firefoxos/VibrationProxy.js\" name=\"VibrationProxy\">\n            <runs />\n        </js-module>\n    </platform>\n\n    <!-- wp7 -->\n    <platform name=\"wp7\">\n        <config-file target=\"config.xml\" parent=\"/*\">\n            <feature name=\"Vibration\">\n                <param name=\"wp-package\" value=\"Vibration\"/>\n            </feature>\n        </config-file>\n\n        <source-file src=\"src/wp/Vibration.cs\" />\n    </platform>\n\n    <!-- wp8 -->\n    <platform name=\"wp8\">\n        <config-file target=\"config.xml\" parent=\"/*\">\n            <feature name=\"Vibration\">\n                <param name=\"wp-package\" value=\"Vibration\"/>\n            </feature>\n        </config-file>\n\n        <source-file src=\"src/wp/Vibration.cs\" />\n    </platform>\n\n    <!-- windows -->\n    <platform name=\"windows\">\n        <js-module src=\"src/windows/VibrationProxy.js\" name=\"VibrationProxy\">\n            <runs />\n        </js-module>\n\n        <framework src=\"src/windows/Vibration/Vibration.csproj\" target=\"phone\"\n            type=\"projectReference\" custom=\"true\" versions=\"<10.0.0\" />\n    </platform>\n\n    <!-- android -->\n    <platform name=\"android\">\n        <config-file target=\"res/xml/config.xml\" parent=\"/*\">\n            <feature name=\"Vibration\">\n                <param name=\"android-package\" value=\"org.apache.cordova.vibration.Vibration\"/>\n            </feature>\n        </config-file>\n\n        <source-file src=\"src/android/Vibration.java\" target-dir=\"src/org/apache/cordova/vibration\" />\n\n        <config-file target=\"AndroidManifest.xml\" parent=\"/manifest\">\n            <uses-permission android:name=\"android.permission.VIBRATE\"/>\n        </config-file>\n    </platform>\n\n    <!-- amazon-fireos -->\n    <platform name=\"amazon-fireos\">\n        <config-file target=\"res/xml/config.xml\" parent=\"/*\">\n            <feature name=\"Vibration\">\n                <param name=\"android-package\" value=\"org.apache.cordova.vibration.Vibration\"/>\n            </feature>\n        </config-file>\n\n        <source-file src=\"src/android/Vibration.java\" target-dir=\"src/org/apache/cordova/vibration\" />\n\n        <config-file target=\"AndroidManifest.xml\" parent=\"/manifest\">\n            <uses-permission android:name=\"android.permission.VIBRATE\"/>\n        </config-file>\n    </platform>\n    \n    <!-- ubuntu -->\n    <platform name=\"ubuntu\">\n        <header-file src=\"src/ubuntu/vibration.h\" />\n        <source-file src=\"src/ubuntu/vibration.cpp\" />\n    </platform>\n\n    <!-- ios -->\n    <platform name=\"ios\">\n        <config-file target=\"config.xml\" parent=\"/*\">\n            <feature name=\"Vibration\">\n                <param name=\"ios-package\" value=\"CDVVibration\"/>\n            </feature>\n        </config-file>\n        <header-file src=\"src/ios/CDVVibration.h\" />\n\t    <source-file src=\"src/ios/CDVVibration.m\" />\n\n\t\t<framework src=\"AudioToolbox.framework\" weak=\"true\" />\n    </platform>\n\t\n    <!-- blackberry10 -->\n    <platform name=\"blackberry10\">\n        <source-file src=\"src/blackberry10/index.js\" target-dir=\"Vibration\"/>\n        <lib-file src=\"src/blackberry10/native/device/libVibration.so\" arch=\"device\" />\n        <lib-file src=\"src/blackberry10/native/simulator/libVibration.so\" arch=\"simulator\" />\n        <config-file target=\"www/config.xml\" parent=\"/widget\">\n            <feature name=\"Vibration\" value=\"Vibration\" />\n        </config-file>\n    </platform>\n\n    <!-- tizen -->\n    <platform name=\"tizen\">\n        <js-module src=\"src/tizen/VibrationProxy.js\" name=\"VibrationProxy\">\n            <runs />\n        </js-module>\n    </platform>\n</plugin>\n"
  },
  {
    "path": "plugins/cordova-plugin-vibration/src/android/Vibration.java",
    "content": "/*\n       Licensed to the Apache Software Foundation (ASF) under one\n       or more contributor license agreements.  See the NOTICE file\n       distributed with this work for additional information\n       regarding copyright ownership.  The ASF licenses this file\n       to you under the Apache License, Version 2.0 (the\n       \"License\"); you may not use this file except in compliance\n       with the License.  You may obtain a copy of the License at\n\n         http://www.apache.org/licenses/LICENSE-2.0\n\n       Unless required by applicable law or agreed to in writing,\n       software distributed under the License is distributed on an\n       \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n       KIND, either express or implied.  See the License for the\n       specific language governing permissions and limitations\n       under the License.\n*/\npackage org.apache.cordova.vibration;\n\nimport org.apache.cordova.CallbackContext;\nimport org.apache.cordova.CordovaPlugin;\nimport org.json.JSONArray;\nimport org.json.JSONException;\nimport android.content.Context;\nimport android.os.Vibrator;\nimport android.media.AudioManager;\n\n/**\n * This class provides access to vibration on the device.\n */\npublic class Vibration extends CordovaPlugin {\n\n    /**\n     * Constructor.\n     */\n    public Vibration() {\n    }\n\n    /**\n     * Executes the request and returns PluginResult.\n     *\n     * @param action            The action to execute.\n     * @param args              JSONArray of arguments for the plugin.\n     * @param callbackContext   The callback context used when calling back into JavaScript.\n     * @return                  True when the action was valid, false otherwise.\n     */\n    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {\n        if (action.equals(\"vibrate\")) {\n            this.vibrate(args.getLong(0));\n        }\n        else if (action.equals(\"vibrateWithPattern\")) {\n            JSONArray pattern = args.getJSONArray(0);\n            int repeat = args.getInt(1);\n            //add a 0 at the beginning of pattern to align with w3c\n            long[] patternArray = new long[pattern.length()+1];\n            patternArray[0] = 0;\n            for (int i = 0; i < pattern.length(); i++) {\n                patternArray[i+1] = pattern.getLong(i);\n            }\n            this.vibrateWithPattern(patternArray, repeat);\n        }\n        else if (action.equals(\"cancelVibration\")) {\n            this.cancelVibration();\n        }\n        else {\n            return false;\n        }\n\n        // Only alert and confirm are async.\n        callbackContext.success();\n\n        return true;\n    }\n\n    //--------------------------------------------------------------------------\n    // LOCAL METHODS\n    //--------------------------------------------------------------------------\n\n    /**\n     * Vibrates the device for a given amount of time.\n     *\n     * @param time      Time to vibrate in ms.\n     */\n    public void vibrate(long time) {\n        // Start the vibration, 0 defaults to half a second.\n        if (time == 0) {\n            time = 500;\n        }\n        AudioManager manager = (AudioManager) this.cordova.getActivity().getSystemService(Context.AUDIO_SERVICE);\n        if (manager.getRingerMode() != AudioManager.RINGER_MODE_SILENT) {\n            Vibrator vibrator = (Vibrator) this.cordova.getActivity().getSystemService(Context.VIBRATOR_SERVICE);\n            vibrator.vibrate(time);\n        }\n    }\n\n    /**\n     * Vibrates the device with a given pattern.\n     *\n     * @param pattern     Pattern with which to vibrate the device.\n     *                    Pass in an array of longs that\n     *                    are the durations for which to\n     *                    turn on or off the vibrator in\n     *                    milliseconds. The first value\n     *                    indicates the number of milliseconds\n     *                    to wait before turning the vibrator\n     *                    on. The next value indicates the\n     *                    number of milliseconds for which\n     *                    to keep the vibrator on before\n     *                    turning it off. Subsequent values\n     *                    alternate between durations in\n     *                    milliseconds to turn the vibrator\n     *                    off or to turn the vibrator on.\n     *\n     * @param repeat      Optional index into the pattern array at which\n     *                    to start repeating, or -1 for no repetition (default).\n     */\n    public void vibrateWithPattern(long[] pattern, int repeat) {\n        AudioManager manager = (AudioManager) this.cordova.getActivity().getSystemService(Context.AUDIO_SERVICE);\n        if (manager.getRingerMode() != AudioManager.RINGER_MODE_SILENT) {\n            Vibrator vibrator = (Vibrator) this.cordova.getActivity().getSystemService(Context.VIBRATOR_SERVICE);\n            vibrator.vibrate(pattern, repeat);\n        }\n    }\n\n    /**\n     * Immediately cancels any currently running vibration.\n     */\n    public void cancelVibration() {\n        Vibrator vibrator = (Vibrator) this.cordova.getActivity().getSystemService(Context.VIBRATOR_SERVICE);\n        vibrator.cancel();\n    }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-vibration/src/blackberry10/index.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\nvar vibration;\n\nmodule.exports = {\n    vibrate: function (success, fail, args, env) {\n        var result = new PluginResult(args, env),\n            duration = args[0],\n            response = vibration.getInstance().vibrate(duration);\n        result.ok(response, false);\n    }\n};\n\n///////////////////////////////////////////////////////////////////\n// JavaScript wrapper for JNEXT plugin\n///////////////////////////////////////////////////////////////////\n\nJNEXT.Vibration = function () {\n    var self = this,\n        hasInstance = false;\n\n    self.vibrate = function (duration) {\n        //This is how Javascript calls into native\n        return JNEXT.invoke(self.m_id, \"vibrate \" + duration);\n    };\n\n    self.init = function () {\n        //Checks that the jnext library is present and loads it\n        if (!JNEXT.require(\"libVibration\")) {\n            return false;\n        }\n\n        //Creates the native object that this interface will call\n        self.m_id = JNEXT.createObject(\"libVibration.Vibration\");\n\n        if (self.m_id === \"\") {\n            return false;\n        }\n\n        //Registers for the JNEXT event loop\n        JNEXT.registerEvents(self);\n    };\n\n    self.m_id = \"\";\n\n    //Used by JNEXT library to get the ID\n    self.getId = function () {\n        return self.m_id;\n    };\n\n    //Not truly required but useful for instance management\n    self.getInstance = function () {\n        if (!hasInstance) {\n            self.init();\n            hasInstance = true;\n        }\n        return self;\n    };\n};\n\nvibration = new JNEXT.Vibration();\n"
  },
  {
    "path": "plugins/cordova-plugin-vibration/src/blackberry10/native/.cproject",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<?fileVersion 4.0.0?>\n<!--\n  Licensed to the Apache Software Foundation (ASF) under one\n  or more contributor license agreements.  See the NOTICE file\n  distributed with this work for additional information\n  regarding copyright ownership.  The ASF licenses this file\n  to you under the Apache License, Version 2.0 (the\n  \"License\"); you may not use this file except in compliance\n  with the License.  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing,\n  software distributed under the License is distributed on an\n  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n  KIND, either express or implied.  See the License for the\n  specific language governing permissions and limitations\n  under the License.\n-->\n<cproject storage_type_id=\"org.eclipse.cdt.core.XmlProjectDescriptionStorage\">\n\t<storageModule moduleId=\"org.eclipse.cdt.core.settings\">\n\t\t<cconfiguration id=\"com.qnx.qcc.configuration.sharedLib.debug.377515531\">\n\t\t\t<storageModule buildSystemId=\"org.eclipse.cdt.managedbuilder.core.configurationDataProvider\" id=\"com.qnx.qcc.configuration.sharedLib.debug.377515531\" moduleId=\"org.eclipse.cdt.core.settings\" name=\"Device-Debug\">\n\t\t\t\t<externalSettings>\n\t\t\t\t\t<externalSetting>\n\t\t\t\t\t\t<entry flags=\"VALUE_WORKSPACE_PATH\" kind=\"includePath\" name=\"/Vibration/public\"/>\n\t\t\t\t\t\t<entry flags=\"VALUE_WORKSPACE_PATH\" kind=\"libraryPath\" name=\"/Vibration/Device-Debug\"/>\n\t\t\t\t\t\t<entry flags=\"\" kind=\"libraryFile\" name=\"Vibration\" srcPrefixMapping=\"\" srcRootPath=\"\"/>\n\t\t\t\t\t</externalSetting>\n\t\t\t\t</externalSettings>\n\t\t\t\t<extensions>\n\t\t\t\t\t<extension id=\"com.qnx.tools.ide.qde.core.QDEBynaryParser\" point=\"org.eclipse.cdt.core.BinaryParser\"/>\n\t\t\t\t\t<extension id=\"com.qnx.tools.ide.qde.core.QDELinkerErrorParser\" point=\"org.eclipse.cdt.core.ErrorParser\"/>\n\t\t\t\t\t<extension id=\"org.eclipse.cdt.core.GCCErrorParser\" point=\"org.eclipse.cdt.core.ErrorParser\"/>\n\t\t\t\t\t<extension id=\"org.eclipse.cdt.core.GLDErrorParser\" point=\"org.eclipse.cdt.core.ErrorParser\"/>\n\t\t\t\t</extensions>\n\t\t\t</storageModule>\n\t\t\t<storageModule moduleId=\"cdtBuildSystem\" version=\"4.0.0\">\n\t\t\t\t<configuration artifactExtension=\"so\" artifactName=\"${ProjName}\" buildArtefactType=\"org.eclipse.cdt.build.core.buildArtefactType.sharedLib\" buildProperties=\"org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.sharedLib\" description=\"\" id=\"com.qnx.qcc.configuration.sharedLib.debug.377515531\" name=\"Device-Debug\" parent=\"com.qnx.qcc.configuration.sharedLib.debug\">\n\t\t\t\t\t<folderInfo id=\"com.qnx.qcc.configuration.sharedLib.debug.377515531.\" name=\"/\" resourcePath=\"\">\n\t\t\t\t\t\t<toolChain id=\"com.qnx.qcc.toolChain.sharedLib.debug.971164565\" name=\"QNX QCC\" superClass=\"com.qnx.qcc.toolChain\">\n\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.cpu.2087890036\" superClass=\"com.qnx.qcc.option.cpu\" value=\"com.qnx.qcc.option.gen.cpu.armle-v7\" valueType=\"enumerated\"/>\n\t\t\t\t\t\t\t<targetPlatform archList=\"all\" binaryParser=\"com.qnx.tools.ide.qde.core.QDEBynaryParser\" id=\"com.qnx.qcc.targetPlatform.1402574041\" osList=\"all\" superClass=\"com.qnx.qcc.targetPlatform\"/>\n\t\t\t\t\t\t\t<builder buildPath=\"${workspace_loc:/Vibration}/Device-Debug\" id=\"com.qnx.nto.2045212918\" keepEnvironmentInBuildfile=\"false\" name=\"CDT Internal Builder.Debug\" parallelBuildOn=\"true\" parallelizationNumber=\"optimal\" superClass=\"com.qnx.nto\"/>\n\t\t\t\t\t\t\t<tool id=\"com.qnx.qcc.tool.compiler.132315977\" name=\"QCC Compiler\" superClass=\"com.qnx.qcc.tool.compiler\">\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compiler.shared.1393127199\" superClass=\"com.qnx.qcc.option.compiler.shared\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compiler.optlevel.1372523509\" superClass=\"com.qnx.qcc.option.compiler.optlevel\" value=\"com.qnx.qcc.option.compiler.optlevel.0\" valueType=\"enumerated\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compile.debug.197267590\" superClass=\"com.qnx.qcc.option.compile.debug\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compiler.includePath.1822603065\" superClass=\"com.qnx.qcc.option.compiler.includePath\" valueType=\"includePath\">\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"${workspace_loc:/${ProjName}/public}\"/>\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"${QNX_TARGET}/usr/include/freetype2\"/>\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"${QNX_TARGET}/../target-override/usr/include\"/>\n\t\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compiler.security.1943099120\" superClass=\"com.qnx.qcc.option.compiler.security\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compiler.defines.195649660\" superClass=\"com.qnx.qcc.option.compiler.defines\" valueType=\"definedSymbols\">\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"_FORTIFY_SOURCE=2\"/>\n\t\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t\t\t<inputType id=\"com.qnx.qcc.inputType.compiler.580792363\" superClass=\"com.qnx.qcc.inputType.compiler\"/>\n\t\t\t\t\t\t\t</tool>\n\t\t\t\t\t\t\t<tool id=\"com.qnx.qcc.tool.assembler.987029866\" name=\"QCC Assembler\" superClass=\"com.qnx.qcc.tool.assembler\">\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.assembler.debug.1650183957\" superClass=\"com.qnx.qcc.option.assembler.debug\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<inputType id=\"com.qnx.qcc.inputType.assembler.48195162\" superClass=\"com.qnx.qcc.inputType.assembler\"/>\n\t\t\t\t\t\t\t</tool>\n\t\t\t\t\t\t\t<tool id=\"com.qnx.qcc.tool.linker.1975544943\" name=\"QCC Linker\" superClass=\"com.qnx.qcc.tool.linker\">\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.linker.debug.1211149040\" superClass=\"com.qnx.qcc.option.linker.debug\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.linker.shared.1550477607\" superClass=\"com.qnx.qcc.option.linker.shared\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.linker.langcpp.1528479645\" superClass=\"com.qnx.qcc.option.linker.langcpp\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.linker.libraryPaths.656170241\" superClass=\"com.qnx.qcc.option.linker.libraryPaths\" valueType=\"libPaths\">\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"${QNX_TARGET}/../target-override/${CPUVARDIR}/lib\"/>\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"${QNX_TARGET}/../target-override/${CPUVARDIR}/usr/lib\"/>\n\t\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.linker.security.1172942377\" superClass=\"com.qnx.qcc.option.linker.security\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<inputType id=\"com.qnx.qcc.inputType.linker.749863253\" superClass=\"com.qnx.qcc.inputType.linker\">\n\t\t\t\t\t\t\t\t\t<additionalInput kind=\"additionalinputdependency\" paths=\"$(USER_OBJS)\"/>\n\t\t\t\t\t\t\t\t\t<additionalInput kind=\"additionalinput\" paths=\"$(LIBS)\"/>\n\t\t\t\t\t\t\t\t</inputType>\n\t\t\t\t\t\t\t</tool>\n\t\t\t\t\t\t\t<tool id=\"com.qnx.qcc.tool.archiver.305797868\" name=\"QCC Archiver\" superClass=\"com.qnx.qcc.tool.archiver\"/>\n\t\t\t\t\t\t</toolChain>\n\t\t\t\t\t</folderInfo>\n\t\t\t\t\t<sourceEntries>\n\t\t\t\t\t\t<entry flags=\"VALUE_WORKSPACE_PATH|RESOLVED\" kind=\"sourcePath\" name=\"src\"/>\n\t\t\t\t\t\t<entry flags=\"VALUE_WORKSPACE_PATH|RESOLVED\" kind=\"sourcePath\" name=\"public\"/>\n\t\t\t\t\t</sourceEntries>\n\t\t\t\t</configuration>\n\t\t\t</storageModule>\n\t\t\t<storageModule moduleId=\"org.eclipse.cdt.core.externalSettings\"/>\n\t\t</cconfiguration>\n\t\t<cconfiguration id=\"com.qnx.qcc.configuration.sharedLib.release.655086625\">\n\t\t\t<storageModule buildSystemId=\"org.eclipse.cdt.managedbuilder.core.configurationDataProvider\" id=\"com.qnx.qcc.configuration.sharedLib.release.655086625\" moduleId=\"org.eclipse.cdt.core.settings\" name=\"Device-Release\">\n\t\t\t\t<externalSettings>\n\t\t\t\t\t<externalSetting>\n\t\t\t\t\t\t<entry flags=\"VALUE_WORKSPACE_PATH\" kind=\"includePath\" name=\"/Vibration/public\"/>\n\t\t\t\t\t\t<entry flags=\"VALUE_WORKSPACE_PATH\" kind=\"libraryPath\" name=\"/Vibration/Device-Release\"/>\n\t\t\t\t\t\t<entry flags=\"\" kind=\"libraryFile\" name=\"Vibration\" srcPrefixMapping=\"\" srcRootPath=\"\"/>\n\t\t\t\t\t</externalSetting>\n\t\t\t\t</externalSettings>\n\t\t\t\t<extensions>\n\t\t\t\t\t<extension id=\"com.qnx.tools.ide.qde.core.QDEBynaryParser\" point=\"org.eclipse.cdt.core.BinaryParser\"/>\n\t\t\t\t\t<extension id=\"com.qnx.tools.ide.qde.core.QDELinkerErrorParser\" point=\"org.eclipse.cdt.core.ErrorParser\"/>\n\t\t\t\t\t<extension id=\"org.eclipse.cdt.core.GCCErrorParser\" point=\"org.eclipse.cdt.core.ErrorParser\"/>\n\t\t\t\t\t<extension id=\"org.eclipse.cdt.core.GLDErrorParser\" point=\"org.eclipse.cdt.core.ErrorParser\"/>\n\t\t\t\t</extensions>\n\t\t\t</storageModule>\n\t\t\t<storageModule moduleId=\"cdtBuildSystem\" version=\"4.0.0\">\n\t\t\t\t<configuration artifactExtension=\"so\" artifactName=\"${ProjName}\" buildArtefactType=\"org.eclipse.cdt.build.core.buildArtefactType.sharedLib\" buildProperties=\"org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.sharedLib\" description=\"\" id=\"com.qnx.qcc.configuration.sharedLib.release.655086625\" name=\"Device-Release\" parent=\"com.qnx.qcc.configuration.sharedLib.release\">\n\t\t\t\t\t<folderInfo id=\"com.qnx.qcc.configuration.sharedLib.release.655086625.\" name=\"/\" resourcePath=\"\">\n\t\t\t\t\t\t<toolChain id=\"com.qnx.qcc.toolChain.sharedLib.release.2049587681\" name=\"QNX QCC\" superClass=\"com.qnx.qcc.toolChain\">\n\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.cpu.395550082\" superClass=\"com.qnx.qcc.option.cpu\" value=\"com.qnx.qcc.option.gen.cpu.armle-v7\" valueType=\"enumerated\"/>\n\t\t\t\t\t\t\t<targetPlatform archList=\"all\" binaryParser=\"com.qnx.tools.ide.qde.core.QDEBynaryParser\" id=\"com.qnx.qcc.targetPlatform.785796836\" osList=\"all\" superClass=\"com.qnx.qcc.targetPlatform\"/>\n\t\t\t\t\t\t\t<builder buildPath=\"${workspace_loc:/Vibration}/Device-Release\" id=\"com.qnx.nto.1038591073\" keepEnvironmentInBuildfile=\"false\" name=\"CDT Internal Builder.Release\" parallelBuildOn=\"true\" parallelizationNumber=\"optimal\" superClass=\"com.qnx.nto\"/>\n\t\t\t\t\t\t\t<tool id=\"com.qnx.qcc.tool.compiler.602676193\" name=\"QCC Compiler\" superClass=\"com.qnx.qcc.tool.compiler\">\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compiler.shared.527286912\" superClass=\"com.qnx.qcc.option.compiler.shared\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compiler.optlevel.2036261479\" superClass=\"com.qnx.qcc.option.compiler.optlevel\" value=\"com.qnx.qcc.option.compiler.optlevel.2\" valueType=\"enumerated\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compiler.includePath.1214557951\" superClass=\"com.qnx.qcc.option.compiler.includePath\" valueType=\"includePath\">\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"${workspace_loc:/${ProjName}/public}\"/>\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"${QNX_TARGET}/usr/include/freetype2\"/>\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"${QNX_TARGET}/../target-override/usr/include\"/>\n\t\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compiler.security.1008196277\" superClass=\"com.qnx.qcc.option.compiler.security\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compiler.defines.1060017509\" superClass=\"com.qnx.qcc.option.compiler.defines\" valueType=\"definedSymbols\">\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"_FORTIFY_SOURCE=2\"/>\n\t\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compiler.qccoptions.1733718200\" superClass=\"com.qnx.qcc.option.compiler.qccoptions\" valueType=\"stringList\">\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"-frecord-gcc-switches\"/>\n\t\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t\t\t<inputType id=\"com.qnx.qcc.inputType.compiler.1684912453\" superClass=\"com.qnx.qcc.inputType.compiler\"/>\n\t\t\t\t\t\t\t</tool>\n\t\t\t\t\t\t\t<tool id=\"com.qnx.qcc.tool.assembler.1750419766\" name=\"QCC Assembler\" superClass=\"com.qnx.qcc.tool.assembler\">\n\t\t\t\t\t\t\t\t<inputType id=\"com.qnx.qcc.inputType.assembler.1709300785\" superClass=\"com.qnx.qcc.inputType.assembler\"/>\n\t\t\t\t\t\t\t</tool>\n\t\t\t\t\t\t\t<tool id=\"com.qnx.qcc.tool.linker.964898329\" name=\"QCC Linker\" superClass=\"com.qnx.qcc.tool.linker\">\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.linker.shared.2055906818\" superClass=\"com.qnx.qcc.option.linker.shared\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.linker.langcpp.433725757\" superClass=\"com.qnx.qcc.option.linker.langcpp\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.linker.libraryPaths.866157469\" superClass=\"com.qnx.qcc.option.linker.libraryPaths\" valueType=\"libPaths\">\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"${QNX_TARGET}/../target-override/${CPUVARDIR}/lib\"/>\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"${QNX_TARGET}/../target-override/${CPUVARDIR}/usr/lib\"/>\n\t\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.linker.security.916984508\" superClass=\"com.qnx.qcc.option.linker.security\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<inputType id=\"com.qnx.qcc.inputType.linker.602198304\" superClass=\"com.qnx.qcc.inputType.linker\">\n\t\t\t\t\t\t\t\t\t<additionalInput kind=\"additionalinputdependency\" paths=\"$(USER_OBJS)\"/>\n\t\t\t\t\t\t\t\t\t<additionalInput kind=\"additionalinput\" paths=\"$(LIBS)\"/>\n\t\t\t\t\t\t\t\t</inputType>\n\t\t\t\t\t\t\t</tool>\n\t\t\t\t\t\t\t<tool id=\"com.qnx.qcc.tool.archiver.816267623\" name=\"QCC Archiver\" superClass=\"com.qnx.qcc.tool.archiver\"/>\n\t\t\t\t\t\t</toolChain>\n\t\t\t\t\t</folderInfo>\n\t\t\t\t\t<sourceEntries>\n\t\t\t\t\t\t<entry flags=\"VALUE_WORKSPACE_PATH|RESOLVED\" kind=\"sourcePath\" name=\"src\"/>\n\t\t\t\t\t\t<entry flags=\"VALUE_WORKSPACE_PATH|RESOLVED\" kind=\"sourcePath\" name=\"public\"/>\n\t\t\t\t\t</sourceEntries>\n\t\t\t\t</configuration>\n\t\t\t</storageModule>\n\t\t\t<storageModule moduleId=\"org.eclipse.cdt.core.externalSettings\"/>\n\t\t</cconfiguration>\n\t\t<cconfiguration id=\"com.qnx.qcc.configuration.sharedLib.profile.1631657520\">\n\t\t\t<storageModule buildSystemId=\"org.eclipse.cdt.managedbuilder.core.configurationDataProvider\" id=\"com.qnx.qcc.configuration.sharedLib.profile.1631657520\" moduleId=\"org.eclipse.cdt.core.settings\" name=\"Device-Profile\">\n\t\t\t\t<externalSettings>\n\t\t\t\t\t<externalSetting>\n\t\t\t\t\t\t<entry flags=\"VALUE_WORKSPACE_PATH\" kind=\"includePath\" name=\"/Vibration/public\"/>\n\t\t\t\t\t\t<entry flags=\"VALUE_WORKSPACE_PATH\" kind=\"libraryPath\" name=\"/Vibration/Device-Profile\"/>\n\t\t\t\t\t\t<entry flags=\"\" kind=\"libraryFile\" name=\"Vibration\" srcPrefixMapping=\"\" srcRootPath=\"\"/>\n\t\t\t\t\t</externalSetting>\n\t\t\t\t</externalSettings>\n\t\t\t\t<extensions>\n\t\t\t\t\t<extension id=\"com.qnx.tools.ide.qde.core.QDEBynaryParser\" point=\"org.eclipse.cdt.core.BinaryParser\"/>\n\t\t\t\t\t<extension id=\"com.qnx.tools.ide.qde.core.QDELinkerErrorParser\" point=\"org.eclipse.cdt.core.ErrorParser\"/>\n\t\t\t\t\t<extension id=\"org.eclipse.cdt.core.GCCErrorParser\" point=\"org.eclipse.cdt.core.ErrorParser\"/>\n\t\t\t\t\t<extension id=\"org.eclipse.cdt.core.GLDErrorParser\" point=\"org.eclipse.cdt.core.ErrorParser\"/>\n\t\t\t\t</extensions>\n\t\t\t</storageModule>\n\t\t\t<storageModule moduleId=\"cdtBuildSystem\" version=\"4.0.0\">\n\t\t\t\t<configuration artifactExtension=\"so\" artifactName=\"${ProjName}\" buildArtefactType=\"org.eclipse.cdt.build.core.buildArtefactType.sharedLib\" buildProperties=\"org.eclipse.cdt.build.core.buildType=com.qnx.buildType.profile,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.sharedLib\" description=\"Build for Profiling\" id=\"com.qnx.qcc.configuration.sharedLib.profile.1631657520\" name=\"Device-Profile\" parent=\"com.qnx.qcc.configuration.sharedLib.profile\">\n\t\t\t\t\t<folderInfo id=\"com.qnx.qcc.configuration.sharedLib.profile.1631657520.\" name=\"/\" resourcePath=\"\">\n\t\t\t\t\t\t<toolChain id=\"com.qnx.qcc.toolChain.sharedLib.profile.282876309\" name=\"QNX QCC\" superClass=\"com.qnx.qcc.toolChain\">\n\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.cpu.1459979445\" superClass=\"com.qnx.qcc.option.cpu\" value=\"com.qnx.qcc.option.gen.cpu.armle-v7\" valueType=\"enumerated\"/>\n\t\t\t\t\t\t\t<targetPlatform archList=\"all\" binaryParser=\"com.qnx.tools.ide.qde.core.QDEBynaryParser\" id=\"com.qnx.qcc.targetPlatform.817609196\" osList=\"all\" superClass=\"com.qnx.qcc.targetPlatform\"/>\n\t\t\t\t\t\t\t<builder buildPath=\"${workspace_loc:/Vibration}/Device-Profile\" id=\"com.qnx.nto.676566681\" keepEnvironmentInBuildfile=\"false\" name=\"CDT Internal Builder.Profile\" parallelBuildOn=\"true\" parallelizationNumber=\"optimal\" superClass=\"com.qnx.nto\"/>\n\t\t\t\t\t\t\t<tool id=\"com.qnx.qcc.tool.compiler.1491017260\" name=\"QCC Compiler\" superClass=\"com.qnx.qcc.tool.compiler\">\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compiler.shared.1916336926\" superClass=\"com.qnx.qcc.option.compiler.shared\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compiler.optlevel.493026428\" superClass=\"com.qnx.qcc.option.compiler.optlevel\" value=\"com.qnx.qcc.option.compiler.optlevel.0\" valueType=\"enumerated\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compile.debug.290853890\" superClass=\"com.qnx.qcc.option.compile.debug\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compiler.profile2.1269244077\" superClass=\"com.qnx.qcc.option.compiler.profile2\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compiler.includePath.927622461\" superClass=\"com.qnx.qcc.option.compiler.includePath\" valueType=\"includePath\">\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"${workspace_loc:/${ProjName}/public}\"/>\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"${QNX_TARGET}/usr/include/freetype2\"/>\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"${QNX_TARGET}/../target-override/usr/include\"/>\n\t\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compiler.security.395040157\" superClass=\"com.qnx.qcc.option.compiler.security\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compiler.defines.954315933\" superClass=\"com.qnx.qcc.option.compiler.defines\" valueType=\"definedSymbols\">\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"_FORTIFY_SOURCE=2\"/>\n\t\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t\t\t<inputType id=\"com.qnx.qcc.inputType.compiler.1743648550\" superClass=\"com.qnx.qcc.inputType.compiler\"/>\n\t\t\t\t\t\t\t</tool>\n\t\t\t\t\t\t\t<tool id=\"com.qnx.qcc.tool.assembler.1080707705\" name=\"QCC Assembler\" superClass=\"com.qnx.qcc.tool.assembler\">\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.assembler.debug.1817254367\" superClass=\"com.qnx.qcc.option.assembler.debug\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<inputType id=\"com.qnx.qcc.inputType.assembler.1683140498\" superClass=\"com.qnx.qcc.inputType.assembler\"/>\n\t\t\t\t\t\t\t</tool>\n\t\t\t\t\t\t\t<tool id=\"com.qnx.qcc.tool.linker.1605435025\" name=\"QCC Linker\" superClass=\"com.qnx.qcc.tool.linker\">\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.linker.debug.493747512\" superClass=\"com.qnx.qcc.option.linker.debug\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.linker.profile2.376547802\" superClass=\"com.qnx.qcc.option.linker.profile2\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.linker.shared.576455358\" superClass=\"com.qnx.qcc.option.linker.shared\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.linker.langcpp.604847411\" superClass=\"com.qnx.qcc.option.linker.langcpp\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.linker.libraryPaths.1497646038\" superClass=\"com.qnx.qcc.option.linker.libraryPaths\" valueType=\"libPaths\">\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"${QNX_TARGET}/../target-override/${CPUVARDIR}/lib\"/>\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"${QNX_TARGET}/../target-override/${CPUVARDIR}/usr/lib\"/>\n\t\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.linker.security.76015439\" superClass=\"com.qnx.qcc.option.linker.security\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<inputType id=\"com.qnx.qcc.inputType.linker.1395762141\" superClass=\"com.qnx.qcc.inputType.linker\">\n\t\t\t\t\t\t\t\t\t<additionalInput kind=\"additionalinputdependency\" paths=\"$(USER_OBJS)\"/>\n\t\t\t\t\t\t\t\t\t<additionalInput kind=\"additionalinput\" paths=\"$(LIBS)\"/>\n\t\t\t\t\t\t\t\t</inputType>\n\t\t\t\t\t\t\t</tool>\n\t\t\t\t\t\t\t<tool id=\"com.qnx.qcc.tool.archiver.2086191534\" name=\"QCC Archiver\" superClass=\"com.qnx.qcc.tool.archiver\"/>\n\t\t\t\t\t\t</toolChain>\n\t\t\t\t\t</folderInfo>\n\t\t\t\t\t<sourceEntries>\n\t\t\t\t\t\t<entry flags=\"VALUE_WORKSPACE_PATH|RESOLVED\" kind=\"sourcePath\" name=\"src\"/>\n\t\t\t\t\t\t<entry flags=\"VALUE_WORKSPACE_PATH|RESOLVED\" kind=\"sourcePath\" name=\"public\"/>\n\t\t\t\t\t</sourceEntries>\n\t\t\t\t</configuration>\n\t\t\t</storageModule>\n\t\t\t<storageModule moduleId=\"org.eclipse.cdt.core.externalSettings\"/>\n\t\t</cconfiguration>\n\t\t<cconfiguration id=\"com.qnx.qcc.configuration.sharedLib.coverage.1669049686\">\n\t\t\t<storageModule buildSystemId=\"org.eclipse.cdt.managedbuilder.core.configurationDataProvider\" id=\"com.qnx.qcc.configuration.sharedLib.coverage.1669049686\" moduleId=\"org.eclipse.cdt.core.settings\" name=\"Device-Coverage\">\n\t\t\t\t<externalSettings>\n\t\t\t\t\t<externalSetting>\n\t\t\t\t\t\t<entry flags=\"VALUE_WORKSPACE_PATH\" kind=\"includePath\" name=\"/Vibration/public\"/>\n\t\t\t\t\t\t<entry flags=\"VALUE_WORKSPACE_PATH\" kind=\"libraryPath\" name=\"/Vibration/Device-Coverage\"/>\n\t\t\t\t\t\t<entry flags=\"\" kind=\"libraryFile\" name=\"Vibration\" srcPrefixMapping=\"\" srcRootPath=\"\"/>\n\t\t\t\t\t</externalSetting>\n\t\t\t\t</externalSettings>\n\t\t\t\t<extensions>\n\t\t\t\t\t<extension id=\"com.qnx.tools.ide.qde.core.QDEBynaryParser\" point=\"org.eclipse.cdt.core.BinaryParser\"/>\n\t\t\t\t\t<extension id=\"com.qnx.tools.ide.qde.core.QDELinkerErrorParser\" point=\"org.eclipse.cdt.core.ErrorParser\"/>\n\t\t\t\t\t<extension id=\"org.eclipse.cdt.core.GCCErrorParser\" point=\"org.eclipse.cdt.core.ErrorParser\"/>\n\t\t\t\t\t<extension id=\"org.eclipse.cdt.core.GLDErrorParser\" point=\"org.eclipse.cdt.core.ErrorParser\"/>\n\t\t\t\t</extensions>\n\t\t\t</storageModule>\n\t\t\t<storageModule moduleId=\"cdtBuildSystem\" version=\"4.0.0\">\n\t\t\t\t<configuration artifactExtension=\"so\" artifactName=\"${ProjName}\" buildArtefactType=\"org.eclipse.cdt.build.core.buildArtefactType.sharedLib\" buildProperties=\"org.eclipse.cdt.build.core.buildType=com.qnx.buildType.coverage,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.sharedLib\" description=\"Build with Code Coverage\" id=\"com.qnx.qcc.configuration.sharedLib.coverage.1669049686\" name=\"Device-Coverage\" parent=\"com.qnx.qcc.configuration.sharedLib.coverage\">\n\t\t\t\t\t<folderInfo id=\"com.qnx.qcc.configuration.sharedLib.coverage.1669049686.\" name=\"/\" resourcePath=\"\">\n\t\t\t\t\t\t<toolChain id=\"com.qnx.qcc.toolChain.sharedLib.coverage.1862891100\" name=\"QNX QCC\" superClass=\"com.qnx.qcc.toolChain\">\n\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.cpu.43877958\" superClass=\"com.qnx.qcc.option.cpu\" value=\"com.qnx.qcc.option.gen.cpu.armle-v7\" valueType=\"enumerated\"/>\n\t\t\t\t\t\t\t<targetPlatform archList=\"all\" binaryParser=\"com.qnx.tools.ide.qde.core.QDEBynaryParser\" id=\"com.qnx.qcc.targetPlatform.942608594\" osList=\"all\" superClass=\"com.qnx.qcc.targetPlatform\"/>\n\t\t\t\t\t\t\t<builder buildPath=\"${workspace_loc:/Vibration}/Device-Coverage\" id=\"com.qnx.nto.1447597608\" keepEnvironmentInBuildfile=\"false\" name=\"CDT Internal Builder.Coverage\" parallelBuildOn=\"true\" parallelizationNumber=\"optimal\" superClass=\"com.qnx.nto\"/>\n\t\t\t\t\t\t\t<tool id=\"com.qnx.qcc.tool.compiler.1522602570\" name=\"QCC Compiler\" superClass=\"com.qnx.qcc.tool.compiler\">\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compiler.shared.1730794003\" superClass=\"com.qnx.qcc.option.compiler.shared\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compiler.optlevel.473996000\" superClass=\"com.qnx.qcc.option.compiler.optlevel\" value=\"com.qnx.qcc.option.compiler.optlevel.0\" valueType=\"enumerated\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compile.debug.1198148025\" superClass=\"com.qnx.qcc.option.compile.debug\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compiler.coverage.279342737\" superClass=\"com.qnx.qcc.option.compiler.coverage\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compiler.includePath.423607238\" superClass=\"com.qnx.qcc.option.compiler.includePath\" valueType=\"includePath\">\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"${workspace_loc:/${ProjName}/public}\"/>\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"${QNX_TARGET}/usr/include/freetype2\"/>\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"${QNX_TARGET}/../target-override/usr/include\"/>\n\t\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compiler.security.1167771303\" superClass=\"com.qnx.qcc.option.compiler.security\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compiler.defines.799285689\" superClass=\"com.qnx.qcc.option.compiler.defines\" valueType=\"definedSymbols\">\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"_FORTIFY_SOURCE=2\"/>\n\t\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t\t\t<inputType id=\"com.qnx.qcc.inputType.compiler.324050984\" superClass=\"com.qnx.qcc.inputType.compiler\"/>\n\t\t\t\t\t\t\t</tool>\n\t\t\t\t\t\t\t<tool id=\"com.qnx.qcc.tool.assembler.562556707\" name=\"QCC Assembler\" superClass=\"com.qnx.qcc.tool.assembler\">\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.assembler.debug.14550501\" superClass=\"com.qnx.qcc.option.assembler.debug\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<inputType id=\"com.qnx.qcc.inputType.assembler.1035459541\" superClass=\"com.qnx.qcc.inputType.assembler\"/>\n\t\t\t\t\t\t\t</tool>\n\t\t\t\t\t\t\t<tool id=\"com.qnx.qcc.tool.linker.1249852141\" name=\"QCC Linker\" superClass=\"com.qnx.qcc.tool.linker\">\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.linker.debug.91523793\" superClass=\"com.qnx.qcc.option.linker.debug\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.linker.coverage.240724101\" superClass=\"com.qnx.qcc.option.linker.coverage\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.linker.shared.537604163\" superClass=\"com.qnx.qcc.option.linker.shared\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.linker.langcpp.624009065\" superClass=\"com.qnx.qcc.option.linker.langcpp\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.linker.libraryPaths.156619993\" superClass=\"com.qnx.qcc.option.linker.libraryPaths\" valueType=\"libPaths\">\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"${QNX_TARGET}/../target-override/${CPUVARDIR}/lib\"/>\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"${QNX_TARGET}/../target-override/${CPUVARDIR}/usr/lib\"/>\n\t\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.linker.security.1731541195\" superClass=\"com.qnx.qcc.option.linker.security\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<inputType id=\"com.qnx.qcc.inputType.linker.281780675\" superClass=\"com.qnx.qcc.inputType.linker\">\n\t\t\t\t\t\t\t\t\t<additionalInput kind=\"additionalinputdependency\" paths=\"$(USER_OBJS)\"/>\n\t\t\t\t\t\t\t\t\t<additionalInput kind=\"additionalinput\" paths=\"$(LIBS)\"/>\n\t\t\t\t\t\t\t\t</inputType>\n\t\t\t\t\t\t\t</tool>\n\t\t\t\t\t\t\t<tool id=\"com.qnx.qcc.tool.archiver.1056642758\" name=\"QCC Archiver\" superClass=\"com.qnx.qcc.tool.archiver\"/>\n\t\t\t\t\t\t</toolChain>\n\t\t\t\t\t</folderInfo>\n\t\t\t\t\t<sourceEntries>\n\t\t\t\t\t\t<entry flags=\"VALUE_WORKSPACE_PATH|RESOLVED\" kind=\"sourcePath\" name=\"src\"/>\n\t\t\t\t\t\t<entry flags=\"VALUE_WORKSPACE_PATH|RESOLVED\" kind=\"sourcePath\" name=\"public\"/>\n\t\t\t\t\t</sourceEntries>\n\t\t\t\t</configuration>\n\t\t\t</storageModule>\n\t\t\t<storageModule moduleId=\"org.eclipse.cdt.core.externalSettings\"/>\n\t\t</cconfiguration>\n\t\t<cconfiguration id=\"com.qnx.qcc.configuration.sharedLib.debug.318750407\">\n\t\t\t<storageModule buildSystemId=\"org.eclipse.cdt.managedbuilder.core.configurationDataProvider\" id=\"com.qnx.qcc.configuration.sharedLib.debug.318750407\" moduleId=\"org.eclipse.cdt.core.settings\" name=\"Simulator-Debug\">\n\t\t\t\t<externalSettings>\n\t\t\t\t\t<externalSetting>\n\t\t\t\t\t\t<entry flags=\"VALUE_WORKSPACE_PATH\" kind=\"includePath\" name=\"/Vibration/public\"/>\n\t\t\t\t\t\t<entry flags=\"VALUE_WORKSPACE_PATH\" kind=\"libraryPath\" name=\"/Vibration/Simulator-Debug\"/>\n\t\t\t\t\t\t<entry flags=\"\" kind=\"libraryFile\" name=\"Vibration\" srcPrefixMapping=\"\" srcRootPath=\"\"/>\n\t\t\t\t\t</externalSetting>\n\t\t\t\t</externalSettings>\n\t\t\t\t<extensions>\n\t\t\t\t\t<extension id=\"com.qnx.tools.ide.qde.core.QDEBynaryParser\" point=\"org.eclipse.cdt.core.BinaryParser\"/>\n\t\t\t\t\t<extension id=\"com.qnx.tools.ide.qde.core.QDELinkerErrorParser\" point=\"org.eclipse.cdt.core.ErrorParser\"/>\n\t\t\t\t\t<extension id=\"org.eclipse.cdt.core.GCCErrorParser\" point=\"org.eclipse.cdt.core.ErrorParser\"/>\n\t\t\t\t\t<extension id=\"org.eclipse.cdt.core.GLDErrorParser\" point=\"org.eclipse.cdt.core.ErrorParser\"/>\n\t\t\t\t</extensions>\n\t\t\t</storageModule>\n\t\t\t<storageModule moduleId=\"cdtBuildSystem\" version=\"4.0.0\">\n\t\t\t\t<configuration artifactExtension=\"so\" artifactName=\"${ProjName}\" buildArtefactType=\"org.eclipse.cdt.build.core.buildArtefactType.sharedLib\" buildProperties=\"org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.sharedLib\" description=\"\" id=\"com.qnx.qcc.configuration.sharedLib.debug.318750407\" name=\"Simulator-Debug\" parent=\"com.qnx.qcc.configuration.sharedLib.debug\">\n\t\t\t\t\t<folderInfo id=\"com.qnx.qcc.configuration.sharedLib.debug.318750407.\" name=\"/\" resourcePath=\"\">\n\t\t\t\t\t\t<toolChain id=\"com.qnx.qcc.toolChain.sharedLib.debug.469135654\" name=\"QNX QCC\" superClass=\"com.qnx.qcc.toolChain\">\n\t\t\t\t\t\t\t<targetPlatform archList=\"all\" binaryParser=\"com.qnx.tools.ide.qde.core.QDEBynaryParser\" id=\"com.qnx.qcc.targetPlatform.603547490\" osList=\"all\" superClass=\"com.qnx.qcc.targetPlatform\"/>\n\t\t\t\t\t\t\t<builder buildPath=\"${workspace_loc:/Vibration}/Simulator-Debug\" id=\"com.qnx.nto.617065941\" keepEnvironmentInBuildfile=\"false\" name=\"CDT Internal Builder.Debug\" parallelBuildOn=\"true\" parallelizationNumber=\"optimal\" superClass=\"com.qnx.nto\"/>\n\t\t\t\t\t\t\t<tool id=\"com.qnx.qcc.tool.compiler.275711021\" name=\"QCC Compiler\" superClass=\"com.qnx.qcc.tool.compiler\">\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compiler.shared.2083417607\" superClass=\"com.qnx.qcc.option.compiler.shared\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compiler.optlevel.1329689874\" superClass=\"com.qnx.qcc.option.compiler.optlevel\" value=\"com.qnx.qcc.option.compiler.optlevel.0\" valueType=\"enumerated\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compile.debug.300609140\" superClass=\"com.qnx.qcc.option.compile.debug\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compiler.includePath.1025907475\" superClass=\"com.qnx.qcc.option.compiler.includePath\" valueType=\"includePath\">\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"${workspace_loc:/${ProjName}/public}\"/>\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"${QNX_TARGET}/usr/include/freetype2\"/>\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"${QNX_TARGET}/../target-override/usr/include\"/>\n\t\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compiler.security.1239055828\" superClass=\"com.qnx.qcc.option.compiler.security\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compiler.defines.2050551984\" superClass=\"com.qnx.qcc.option.compiler.defines\" valueType=\"definedSymbols\">\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"_FORTIFY_SOURCE=2\"/>\n\t\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t\t\t<inputType id=\"com.qnx.qcc.inputType.compiler.1442442859\" superClass=\"com.qnx.qcc.inputType.compiler\"/>\n\t\t\t\t\t\t\t</tool>\n\t\t\t\t\t\t\t<tool id=\"com.qnx.qcc.tool.assembler.1971343031\" name=\"QCC Assembler\" superClass=\"com.qnx.qcc.tool.assembler\">\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.assembler.debug.1818701561\" superClass=\"com.qnx.qcc.option.assembler.debug\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<inputType id=\"com.qnx.qcc.inputType.assembler.262556017\" superClass=\"com.qnx.qcc.inputType.assembler\"/>\n\t\t\t\t\t\t\t</tool>\n\t\t\t\t\t\t\t<tool id=\"com.qnx.qcc.tool.linker.1511042630\" name=\"QCC Linker\" superClass=\"com.qnx.qcc.tool.linker\">\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.linker.debug.470782220\" superClass=\"com.qnx.qcc.option.linker.debug\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.linker.shared.1667356098\" superClass=\"com.qnx.qcc.option.linker.shared\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.linker.langcpp.1195851133\" superClass=\"com.qnx.qcc.option.linker.langcpp\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.linker.libraryPaths.29130917\" superClass=\"com.qnx.qcc.option.linker.libraryPaths\" valueType=\"libPaths\">\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"${QNX_TARGET}/../target-override/${CPUVARDIR}/lib\"/>\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"${QNX_TARGET}/../target-override/${CPUVARDIR}/usr/lib\"/>\n\t\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.linker.security.372829751\" superClass=\"com.qnx.qcc.option.linker.security\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<inputType id=\"com.qnx.qcc.inputType.linker.1264830362\" superClass=\"com.qnx.qcc.inputType.linker\">\n\t\t\t\t\t\t\t\t\t<additionalInput kind=\"additionalinputdependency\" paths=\"$(USER_OBJS)\"/>\n\t\t\t\t\t\t\t\t\t<additionalInput kind=\"additionalinput\" paths=\"$(LIBS)\"/>\n\t\t\t\t\t\t\t\t</inputType>\n\t\t\t\t\t\t\t</tool>\n\t\t\t\t\t\t\t<tool id=\"com.qnx.qcc.tool.archiver.1549000616\" name=\"QCC Archiver\" superClass=\"com.qnx.qcc.tool.archiver\"/>\n\t\t\t\t\t\t</toolChain>\n\t\t\t\t\t</folderInfo>\n\t\t\t\t\t<sourceEntries>\n\t\t\t\t\t\t<entry flags=\"VALUE_WORKSPACE_PATH|RESOLVED\" kind=\"sourcePath\" name=\"src\"/>\n\t\t\t\t\t\t<entry flags=\"VALUE_WORKSPACE_PATH|RESOLVED\" kind=\"sourcePath\" name=\"public\"/>\n\t\t\t\t\t</sourceEntries>\n\t\t\t\t</configuration>\n\t\t\t</storageModule>\n\t\t\t<storageModule moduleId=\"org.eclipse.cdt.core.externalSettings\"/>\n\t\t</cconfiguration>\n\t\t<cconfiguration id=\"com.qnx.qcc.configuration.sharedLib.profile.2026630093\">\n\t\t\t<storageModule buildSystemId=\"org.eclipse.cdt.managedbuilder.core.configurationDataProvider\" id=\"com.qnx.qcc.configuration.sharedLib.profile.2026630093\" moduleId=\"org.eclipse.cdt.core.settings\" name=\"Simulator-Profile\">\n\t\t\t\t<externalSettings>\n\t\t\t\t\t<externalSetting>\n\t\t\t\t\t\t<entry flags=\"VALUE_WORKSPACE_PATH\" kind=\"includePath\" name=\"/Vibration/public\"/>\n\t\t\t\t\t\t<entry flags=\"VALUE_WORKSPACE_PATH\" kind=\"libraryPath\" name=\"/Vibration/Simulator-Profile\"/>\n\t\t\t\t\t\t<entry flags=\"\" kind=\"libraryFile\" name=\"Vibration\" srcPrefixMapping=\"\" srcRootPath=\"\"/>\n\t\t\t\t\t</externalSetting>\n\t\t\t\t</externalSettings>\n\t\t\t\t<extensions>\n\t\t\t\t\t<extension id=\"com.qnx.tools.ide.qde.core.QDEBynaryParser\" point=\"org.eclipse.cdt.core.BinaryParser\"/>\n\t\t\t\t\t<extension id=\"com.qnx.tools.ide.qde.core.QDELinkerErrorParser\" point=\"org.eclipse.cdt.core.ErrorParser\"/>\n\t\t\t\t\t<extension id=\"org.eclipse.cdt.core.GCCErrorParser\" point=\"org.eclipse.cdt.core.ErrorParser\"/>\n\t\t\t\t\t<extension id=\"org.eclipse.cdt.core.GLDErrorParser\" point=\"org.eclipse.cdt.core.ErrorParser\"/>\n\t\t\t\t</extensions>\n\t\t\t</storageModule>\n\t\t\t<storageModule moduleId=\"cdtBuildSystem\" version=\"4.0.0\">\n\t\t\t\t<configuration artifactExtension=\"so\" artifactName=\"${ProjName}\" buildArtefactType=\"org.eclipse.cdt.build.core.buildArtefactType.sharedLib\" buildProperties=\"org.eclipse.cdt.build.core.buildType=com.qnx.buildType.profile,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.sharedLib\" description=\"Build for Profiling\" id=\"com.qnx.qcc.configuration.sharedLib.profile.2026630093\" name=\"Simulator-Profile\" parent=\"com.qnx.qcc.configuration.sharedLib.profile\">\n\t\t\t\t\t<folderInfo id=\"com.qnx.qcc.configuration.sharedLib.profile.2026630093.\" name=\"/\" resourcePath=\"\">\n\t\t\t\t\t\t<toolChain id=\"com.qnx.qcc.toolChain.sharedLib.profile.1556550840\" name=\"QNX QCC\" superClass=\"com.qnx.qcc.toolChain\">\n\t\t\t\t\t\t\t<targetPlatform archList=\"all\" binaryParser=\"com.qnx.tools.ide.qde.core.QDEBynaryParser\" id=\"com.qnx.qcc.targetPlatform.792046885\" osList=\"all\" superClass=\"com.qnx.qcc.targetPlatform\"/>\n\t\t\t\t\t\t\t<builder buildPath=\"${workspace_loc:/Vibration}/Simulator-Profile\" id=\"com.qnx.nto.1026624341\" keepEnvironmentInBuildfile=\"false\" name=\"CDT Internal Builder.Profile\" parallelBuildOn=\"true\" parallelizationNumber=\"optimal\" superClass=\"com.qnx.nto\"/>\n\t\t\t\t\t\t\t<tool id=\"com.qnx.qcc.tool.compiler.465539195\" name=\"QCC Compiler\" superClass=\"com.qnx.qcc.tool.compiler\">\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compiler.shared.268803332\" superClass=\"com.qnx.qcc.option.compiler.shared\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compiler.optlevel.435310067\" superClass=\"com.qnx.qcc.option.compiler.optlevel\" value=\"com.qnx.qcc.option.compiler.optlevel.0\" valueType=\"enumerated\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compile.debug.1617979862\" superClass=\"com.qnx.qcc.option.compile.debug\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compiler.profile2.1848276705\" superClass=\"com.qnx.qcc.option.compiler.profile2\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compiler.includePath.362396476\" superClass=\"com.qnx.qcc.option.compiler.includePath\" valueType=\"includePath\">\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"${workspace_loc:/${ProjName}/public}\"/>\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"${QNX_TARGET}/usr/include/freetype2\"/>\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"${QNX_TARGET}/../target-override/usr/include\"/>\n\t\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compiler.security.900632224\" superClass=\"com.qnx.qcc.option.compiler.security\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compiler.defines.1404187270\" superClass=\"com.qnx.qcc.option.compiler.defines\" valueType=\"definedSymbols\">\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"_FORTIFY_SOURCE=2\"/>\n\t\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t\t\t<inputType id=\"com.qnx.qcc.inputType.compiler.1980742037\" superClass=\"com.qnx.qcc.inputType.compiler\"/>\n\t\t\t\t\t\t\t</tool>\n\t\t\t\t\t\t\t<tool id=\"com.qnx.qcc.tool.assembler.2046179860\" name=\"QCC Assembler\" superClass=\"com.qnx.qcc.tool.assembler\">\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.assembler.debug.1728123212\" superClass=\"com.qnx.qcc.option.assembler.debug\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<inputType id=\"com.qnx.qcc.inputType.assembler.1163089150\" superClass=\"com.qnx.qcc.inputType.assembler\"/>\n\t\t\t\t\t\t\t</tool>\n\t\t\t\t\t\t\t<tool id=\"com.qnx.qcc.tool.linker.54496955\" name=\"QCC Linker\" superClass=\"com.qnx.qcc.tool.linker\">\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.linker.debug.1533171992\" superClass=\"com.qnx.qcc.option.linker.debug\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.linker.profile2.420100114\" superClass=\"com.qnx.qcc.option.linker.profile2\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.linker.shared.1394492179\" superClass=\"com.qnx.qcc.option.linker.shared\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.linker.langcpp.1888189753\" superClass=\"com.qnx.qcc.option.linker.langcpp\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.linker.libraryPaths.1535608973\" superClass=\"com.qnx.qcc.option.linker.libraryPaths\" valueType=\"libPaths\">\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"${QNX_TARGET}/../target-override/${CPUVARDIR}/lib\"/>\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"${QNX_TARGET}/../target-override/${CPUVARDIR}/usr/lib\"/>\n\t\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.linker.security.235501299\" superClass=\"com.qnx.qcc.option.linker.security\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<inputType id=\"com.qnx.qcc.inputType.linker.617653803\" superClass=\"com.qnx.qcc.inputType.linker\">\n\t\t\t\t\t\t\t\t\t<additionalInput kind=\"additionalinputdependency\" paths=\"$(USER_OBJS)\"/>\n\t\t\t\t\t\t\t\t\t<additionalInput kind=\"additionalinput\" paths=\"$(LIBS)\"/>\n\t\t\t\t\t\t\t\t</inputType>\n\t\t\t\t\t\t\t</tool>\n\t\t\t\t\t\t\t<tool id=\"com.qnx.qcc.tool.archiver.607513860\" name=\"QCC Archiver\" superClass=\"com.qnx.qcc.tool.archiver\"/>\n\t\t\t\t\t\t</toolChain>\n\t\t\t\t\t</folderInfo>\n\t\t\t\t\t<sourceEntries>\n\t\t\t\t\t\t<entry flags=\"VALUE_WORKSPACE_PATH|RESOLVED\" kind=\"sourcePath\" name=\"src\"/>\n\t\t\t\t\t\t<entry flags=\"VALUE_WORKSPACE_PATH|RESOLVED\" kind=\"sourcePath\" name=\"public\"/>\n\t\t\t\t\t</sourceEntries>\n\t\t\t\t</configuration>\n\t\t\t</storageModule>\n\t\t\t<storageModule moduleId=\"org.eclipse.cdt.core.externalSettings\"/>\n\t\t</cconfiguration>\n\t\t<cconfiguration id=\"com.qnx.qcc.configuration.sharedLib.coverage.1737845529\">\n\t\t\t<storageModule buildSystemId=\"org.eclipse.cdt.managedbuilder.core.configurationDataProvider\" id=\"com.qnx.qcc.configuration.sharedLib.coverage.1737845529\" moduleId=\"org.eclipse.cdt.core.settings\" name=\"Simulator-Coverage\">\n\t\t\t\t<externalSettings>\n\t\t\t\t\t<externalSetting>\n\t\t\t\t\t\t<entry flags=\"VALUE_WORKSPACE_PATH\" kind=\"includePath\" name=\"/Vibration/public\"/>\n\t\t\t\t\t\t<entry flags=\"VALUE_WORKSPACE_PATH\" kind=\"libraryPath\" name=\"/Vibration/Simulator-Coverage\"/>\n\t\t\t\t\t\t<entry flags=\"\" kind=\"libraryFile\" name=\"Vibration\" srcPrefixMapping=\"\" srcRootPath=\"\"/>\n\t\t\t\t\t</externalSetting>\n\t\t\t\t</externalSettings>\n\t\t\t\t<extensions>\n\t\t\t\t\t<extension id=\"com.qnx.tools.ide.qde.core.QDEBynaryParser\" point=\"org.eclipse.cdt.core.BinaryParser\"/>\n\t\t\t\t\t<extension id=\"com.qnx.tools.ide.qde.core.QDELinkerErrorParser\" point=\"org.eclipse.cdt.core.ErrorParser\"/>\n\t\t\t\t\t<extension id=\"org.eclipse.cdt.core.GCCErrorParser\" point=\"org.eclipse.cdt.core.ErrorParser\"/>\n\t\t\t\t\t<extension id=\"org.eclipse.cdt.core.GLDErrorParser\" point=\"org.eclipse.cdt.core.ErrorParser\"/>\n\t\t\t\t</extensions>\n\t\t\t</storageModule>\n\t\t\t<storageModule moduleId=\"cdtBuildSystem\" version=\"4.0.0\">\n\t\t\t\t<configuration artifactExtension=\"so\" artifactName=\"${ProjName}\" buildArtefactType=\"org.eclipse.cdt.build.core.buildArtefactType.sharedLib\" buildProperties=\"org.eclipse.cdt.build.core.buildType=com.qnx.buildType.coverage,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.sharedLib\" description=\"Build with Code Coverage\" id=\"com.qnx.qcc.configuration.sharedLib.coverage.1737845529\" name=\"Simulator-Coverage\" parent=\"com.qnx.qcc.configuration.sharedLib.coverage\">\n\t\t\t\t\t<folderInfo id=\"com.qnx.qcc.configuration.sharedLib.coverage.1737845529.\" name=\"/\" resourcePath=\"\">\n\t\t\t\t\t\t<toolChain id=\"com.qnx.qcc.toolChain.sharedLib.coverage.813560014\" name=\"QNX QCC\" superClass=\"com.qnx.qcc.toolChain\">\n\t\t\t\t\t\t\t<targetPlatform archList=\"all\" binaryParser=\"com.qnx.tools.ide.qde.core.QDEBynaryParser\" id=\"com.qnx.qcc.targetPlatform.2059487021\" osList=\"all\" superClass=\"com.qnx.qcc.targetPlatform\"/>\n\t\t\t\t\t\t\t<builder buildPath=\"${workspace_loc:/Vibration}/Simulator-Coverage\" id=\"com.qnx.nto.1697138981\" keepEnvironmentInBuildfile=\"false\" name=\"CDT Internal Builder.Coverage\" parallelBuildOn=\"true\" parallelizationNumber=\"optimal\" superClass=\"com.qnx.nto\"/>\n\t\t\t\t\t\t\t<tool id=\"com.qnx.qcc.tool.compiler.632222624\" name=\"QCC Compiler\" superClass=\"com.qnx.qcc.tool.compiler\">\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compiler.shared.1095559068\" superClass=\"com.qnx.qcc.option.compiler.shared\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compiler.optlevel.1930203142\" superClass=\"com.qnx.qcc.option.compiler.optlevel\" value=\"com.qnx.qcc.option.compiler.optlevel.0\" valueType=\"enumerated\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compile.debug.578985773\" superClass=\"com.qnx.qcc.option.compile.debug\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compiler.coverage.1160044272\" superClass=\"com.qnx.qcc.option.compiler.coverage\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compiler.includePath.1573089856\" superClass=\"com.qnx.qcc.option.compiler.includePath\" valueType=\"includePath\">\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"${workspace_loc:/${ProjName}/public}\"/>\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"${QNX_TARGET}/usr/include/freetype2\"/>\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"${QNX_TARGET}/../target-override/usr/include\"/>\n\t\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compiler.security.231036501\" superClass=\"com.qnx.qcc.option.compiler.security\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.compiler.defines.1066744967\" superClass=\"com.qnx.qcc.option.compiler.defines\" valueType=\"definedSymbols\">\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"_FORTIFY_SOURCE=2\"/>\n\t\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t\t\t<inputType id=\"com.qnx.qcc.inputType.compiler.1022269077\" superClass=\"com.qnx.qcc.inputType.compiler\"/>\n\t\t\t\t\t\t\t</tool>\n\t\t\t\t\t\t\t<tool id=\"com.qnx.qcc.tool.assembler.1479728358\" name=\"QCC Assembler\" superClass=\"com.qnx.qcc.tool.assembler\">\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.assembler.debug.626730276\" superClass=\"com.qnx.qcc.option.assembler.debug\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<inputType id=\"com.qnx.qcc.inputType.assembler.722608186\" superClass=\"com.qnx.qcc.inputType.assembler\"/>\n\t\t\t\t\t\t\t</tool>\n\t\t\t\t\t\t\t<tool id=\"com.qnx.qcc.tool.linker.56068196\" name=\"QCC Linker\" superClass=\"com.qnx.qcc.tool.linker\">\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.linker.debug.1597589951\" superClass=\"com.qnx.qcc.option.linker.debug\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.linker.coverage.1244601678\" superClass=\"com.qnx.qcc.option.linker.coverage\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.linker.shared.1289066697\" superClass=\"com.qnx.qcc.option.linker.shared\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.linker.langcpp.1640677180\" superClass=\"com.qnx.qcc.option.linker.langcpp\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.linker.libraryPaths.429486871\" superClass=\"com.qnx.qcc.option.linker.libraryPaths\" valueType=\"libPaths\">\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"${QNX_TARGET}/../target-override/${CPUVARDIR}/lib\"/>\n\t\t\t\t\t\t\t\t\t<listOptionValue builtIn=\"false\" value=\"${QNX_TARGET}/../target-override/${CPUVARDIR}/usr/lib\"/>\n\t\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t\t\t<option id=\"com.qnx.qcc.option.linker.security.227221019\" superClass=\"com.qnx.qcc.option.linker.security\" value=\"true\" valueType=\"boolean\"/>\n\t\t\t\t\t\t\t\t<inputType id=\"com.qnx.qcc.inputType.linker.1443697759\" superClass=\"com.qnx.qcc.inputType.linker\">\n\t\t\t\t\t\t\t\t\t<additionalInput kind=\"additionalinputdependency\" paths=\"$(USER_OBJS)\"/>\n\t\t\t\t\t\t\t\t\t<additionalInput kind=\"additionalinput\" paths=\"$(LIBS)\"/>\n\t\t\t\t\t\t\t\t</inputType>\n\t\t\t\t\t\t\t</tool>\n\t\t\t\t\t\t\t<tool id=\"com.qnx.qcc.tool.archiver.973736251\" name=\"QCC Archiver\" superClass=\"com.qnx.qcc.tool.archiver\"/>\n\t\t\t\t\t\t</toolChain>\n\t\t\t\t\t</folderInfo>\n\t\t\t\t\t<sourceEntries>\n\t\t\t\t\t\t<entry flags=\"VALUE_WORKSPACE_PATH|RESOLVED\" kind=\"sourcePath\" name=\"src\"/>\n\t\t\t\t\t\t<entry flags=\"VALUE_WORKSPACE_PATH|RESOLVED\" kind=\"sourcePath\" name=\"public\"/>\n\t\t\t\t\t</sourceEntries>\n\t\t\t\t</configuration>\n\t\t\t</storageModule>\n\t\t\t<storageModule moduleId=\"org.eclipse.cdt.core.externalSettings\"/>\n\t\t</cconfiguration>\n\t</storageModule>\n\t<storageModule moduleId=\"cdtBuildSystem\" version=\"4.0.0\">\n\t\t<project id=\"Vibration.null.2116773605\" name=\"Vibration\"/>\n\t</storageModule>\n\t<storageModule moduleId=\"scannerConfiguration\">\n\t\t<autodiscovery enabled=\"true\" problemReportingEnabled=\"true\" selectedProfileId=\"com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo\"/>\n\t\t<scannerConfigBuildInfo instanceId=\"com.qnx.qcc.configuration.sharedLib.coverage.1669049686\">\n\t\t\t<autodiscovery enabled=\"true\" problemReportingEnabled=\"true\" selectedProfileId=\"com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo\"/>\n\t\t</scannerConfigBuildInfo>\n\t\t<scannerConfigBuildInfo instanceId=\"com.qnx.qcc.configuration.sharedLib.coverage.1737845529\">\n\t\t\t<autodiscovery enabled=\"true\" problemReportingEnabled=\"true\" selectedProfileId=\"com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo\"/>\n\t\t</scannerConfigBuildInfo>\n\t\t<scannerConfigBuildInfo instanceId=\"com.qnx.qcc.configuration.sharedLib.profile.2026630093\">\n\t\t\t<autodiscovery enabled=\"true\" problemReportingEnabled=\"true\" selectedProfileId=\"com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo\"/>\n\t\t</scannerConfigBuildInfo>\n\t\t<scannerConfigBuildInfo instanceId=\"com.qnx.qcc.configuration.sharedLib.debug.377515531\">\n\t\t\t<autodiscovery enabled=\"true\" problemReportingEnabled=\"true\" selectedProfileId=\"com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo\"/>\n\t\t</scannerConfigBuildInfo>\n\t\t<scannerConfigBuildInfo instanceId=\"com.qnx.qcc.configuration.sharedLib.release.655086625\">\n\t\t\t<autodiscovery enabled=\"true\" problemReportingEnabled=\"true\" selectedProfileId=\"com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo\"/>\n\t\t</scannerConfigBuildInfo>\n\t\t<scannerConfigBuildInfo instanceId=\"com.qnx.qcc.configuration.sharedLib.debug.318750407\">\n\t\t\t<autodiscovery enabled=\"true\" problemReportingEnabled=\"true\" selectedProfileId=\"com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo\"/>\n\t\t</scannerConfigBuildInfo>\n\t\t<scannerConfigBuildInfo instanceId=\"com.qnx.qcc.configuration.sharedLib.profile.1631657520\">\n\t\t\t<autodiscovery enabled=\"true\" problemReportingEnabled=\"true\" selectedProfileId=\"com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo\"/>\n\t\t</scannerConfigBuildInfo>\n\t</storageModule>\n\t<storageModule moduleId=\"org.eclipse.cdt.core.LanguageSettingsProviders\"/>\n</cproject>\n"
  },
  {
    "path": "plugins/cordova-plugin-vibration/src/blackberry10/native/.project",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  Licensed to the Apache Software Foundation (ASF) under one\n  or more contributor license agreements.  See the NOTICE file\n  distributed with this work for additional information\n  regarding copyright ownership.  The ASF licenses this file\n  to you under the Apache License, Version 2.0 (the\n  \"License\"); you may not use this file except in compliance\n  with the License.  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing,\n  software distributed under the License is distributed on an\n  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n  KIND, either express or implied.  See the License for the\n  specific language governing permissions and limitations\n  under the License.\n-->\n<projectDescription>\n\t<name>Vibration</name>\n\t<comment></comment>\n\t<projects>\n\t</projects>\n\t<buildSpec>\n\t\t<buildCommand>\n\t\t\t<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>\n\t\t\t<triggers>clean,full,incremental,</triggers>\n\t\t\t<arguments>\n\t\t\t</arguments>\n\t\t</buildCommand>\n\t\t<buildCommand>\n\t\t\t<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>\n\t\t\t<triggers>full,incremental,</triggers>\n\t\t\t<arguments>\n\t\t\t</arguments>\n\t\t</buildCommand>\n\t\t<buildCommand>\n\t\t\t<name>com.qnx.tools.bbt.xml.core.bbtXMLValidationBuilder</name>\n\t\t\t<arguments>\n\t\t\t</arguments>\n\t\t</buildCommand>\n\t</buildSpec>\n\t<natures>\n\t\t<nature>org.eclipse.cdt.core.cnature</nature>\n\t\t<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>\n\t\t<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>\n\t\t<nature>com.qnx.tools.ide.bbt.core.bbtnature</nature>\n\t\t<nature>org.eclipse.cdt.core.ccnature</nature>\n\t</natures>\n</projectDescription>\n"
  },
  {
    "path": "plugins/cordova-plugin-vibration/src/blackberry10/native/public/plugin.cpp",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n#include \"plugin.h\"\n#include \"tokenizer.h\"\n\n#ifdef _WINDOWS\n#include <windows.h>\nBOOL APIENTRY DllMain( HANDLE hModule,\n                       DWORD ul_reason_for_call,\n                       LPVOID lpReserved )\n{\n    return TRUE;\n}\n#else\n#include <errno.h>\n#include <string.h>\n\nextern int errno;\n#endif\n\nSendPluginEv SendPluginEvent;\n\nstring g_GetSysErrMsg( void )\n{\n    string strError = \"Unknown\";\n    // Problem loading\n#ifdef _WINDOWS\n    int nErrorCode = GetLastError();\n    LPTSTR s;\n    if ( ::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,\n    NULL, nErrorCode, 0, ( LPTSTR ) &s, 0, NULL ) )\n    {\n        strError = s;\n    }\n    else\n    {\n        char szBuf[ 20 ];\n        _snprintf_s( szBuf, _countof(szBuf), 19, \"%d\", nErrorCode );\n        strError = szBuf;\n    }\n#else\n    char szError[80];\n    if ( strerror_r( errno, szError, sizeof(szError)  ) )\n    {\n        strError = \"no description found\";\n    }\n    else\n    {\n        strError = szError;\n    }\n#endif\n    return strError;\n}\n\nvoid g_sleep( unsigned int mseconds )\n{\n#ifdef _WINDOWS\n    Sleep( mseconds );\n#else\n    usleep( mseconds * 1000 );\n#endif\n}\n\nstring& g_trim( string& str )\n{\n    // Whitespace characters\n    char whspc[] = \" \\t\\r\\n\\v\\f\";\n\n    // Whack off first part\n    size_t pos = str.find_first_not_of( whspc );\n\n    if ( pos != string::npos )\n        str.replace( 0, pos, \"\" );\n\n    // Whack off trailing stuff\n    pos = str.find_last_not_of( whspc );\n\n    if ( pos != string::npos )\n        str.replace( pos + 1, str.length() - pos, \"\" );\n\n    return str;\n}\n\nvoid g_tokenize( const string& str, const string& delimiters, vector<string>& tokens )\n{\n    tokenize( str, tokens, delimiters );\n}\n\nchar* SetEventFunc( SendPluginEv funcPtr )\n{\n    static char * szObjList = onGetObjList();\n    SendPluginEvent = funcPtr;\n    return szObjList;\n}\n\n\nconst int nMAXSIZE = 512;\nchar* g_pszRetVal = NULL;\n\n//-----------------------------------------------------------\n// Map from an object Id to an object instance\n//-----------------------------------------------------------\ntypedef std::map<string, JSExt*> StringToJExt_T;\n\n//-----------------------------------------------------------\n// Map from a browser context to an id mapping\n//-----------------------------------------------------------\ntypedef std::map<void*, StringToJExt_T*> VoidToMap_T;\n\nVoidToMap_T g_context2Map;\n\nclass GlobalSharedModule\n{\n\npublic:\n    GlobalSharedModule( void )\n    {\n        g_pszRetVal = new char[ nMAXSIZE ];\n    }\n\n    ~GlobalSharedModule()\n    {\n        delete [] g_pszRetVal;\n\n        VoidToMap_T::iterator posMaps;\n\n        for ( posMaps = g_context2Map.begin(); posMaps != g_context2Map.end(); ++posMaps )\n        {\n            StringToJExt_T& id2Obj = *posMaps->second;\n            StringToJExt_T::iterator posMap;\n\n            for ( posMap = id2Obj.begin(); posMap != id2Obj.end(); ++posMap )\n            {\n                JSExt* pJSExt = posMap->second;\n\n                if ( pJSExt->CanDelete() )\n                {\n                    delete pJSExt;\n                }\n            }\n\n            id2Obj.erase( id2Obj.begin(), id2Obj.end() );\n        }\n\n        g_context2Map.erase( g_context2Map.begin(), g_context2Map.end() );\n    }\n};\n\nGlobalSharedModule g_sharedModule;\n\nchar* g_str2global( const string& strRetVal )\n{\n    int nLen = strRetVal.size();\n\n    if ( nLen >= nMAXSIZE )\n    {\n        delete [] g_pszRetVal;\n        g_pszRetVal = new char[ nLen + 1 ];\n    }\n\n    else\n    {\n        // To minimaize the number of memory reallocations, the assumption\n        // is that in most times this will be the case\n        delete [] g_pszRetVal;\n        g_pszRetVal = new char[ nMAXSIZE ];\n    }\n\n    strcpy( g_pszRetVal, strRetVal.c_str() );\n    return g_pszRetVal;\n}\n\nbool g_unregisterObject( const string& strObjId, void* pContext )\n{\n    // Called by the plugin extension implementation\n    // if the extension handles the deletion of its object\n\n    StringToJExt_T * pID2Obj = NULL;\n\n    VoidToMap_T::iterator iter = g_context2Map.find( pContext );\n\n    if ( iter != g_context2Map.end() )\n    {\n        pID2Obj = iter->second;\n    }\n    else\n    {\n        return false;\n    }\n\n    StringToJExt_T& mapID2Obj = *pID2Obj;\n\n    StringToJExt_T::iterator r = mapID2Obj.find( strObjId );\n\n    if ( r == mapID2Obj.end() )\n    {\n        return false;\n    }\n\n    mapID2Obj.erase( strObjId );\n    return true;\n}\n\nchar* InvokeFunction( const char* szCommand, void* pContext )\n{\n    StringToJExt_T * pID2Obj = NULL;\n\n    VoidToMap_T::iterator iter = g_context2Map.find( pContext );\n\n    if ( iter != g_context2Map.end() )\n    {\n        pID2Obj = iter->second;\n    }\n    else\n    {\n        pID2Obj = new StringToJExt_T;\n        g_context2Map[ pContext ] = pID2Obj;\n    }\n\n    StringToJExt_T& mapID2Obj = *pID2Obj;\n\n    string strFullCommand = szCommand;\n    vector<string> arParams;\n    g_tokenize( strFullCommand, \" \", arParams );\n    string strCommand = arParams[ 0 ];\n    string strRetVal = szERROR;\n\n    if ( strCommand == szCREATE )\n    {\n        string strClassName = arParams[ 1 ];\n        string strObjId = arParams[ 2 ];\n\n        StringToJExt_T::iterator r = mapID2Obj.find( strObjId );\n\n        if ( r != mapID2Obj.end() )\n        {\n            strRetVal += strObjId;\n            strRetVal += \" :Object already exists.\";\n            return g_str2global( strRetVal );\n        }\n\n        JSExt* pJSExt = onCreateObject( strClassName, strObjId );\n\n        if ( pJSExt == NULL )\n        {\n            strRetVal += strObjId;\n            strRetVal += \" :Unknown object type \";\n            strRetVal += strClassName;\n            return g_str2global( strRetVal );\n        }\n\n        pJSExt->m_pContext = pContext;\n        mapID2Obj[ strObjId ] = pJSExt;\n\n        strRetVal = szOK;\n        strRetVal += strObjId;\n        return g_str2global( strRetVal );\n    }\n    else\n    if ( strCommand == szINVOKE )\n    {\n        string strObjId = arParams[ 1 ];\n        string strMethod = arParams[ 2 ];\n\n        StringToJExt_T::iterator r = mapID2Obj.find( strObjId );\n\n        if ( r == mapID2Obj.end() )\n        {\n            strRetVal += strObjId;\n            strRetVal += \" :No object found for id.\";\n            return g_str2global( strRetVal );\n        }\n\n        JSExt* pJSExt = r->second;\n\n        size_t nLoc = strFullCommand.find( strObjId );\n\n        if ( nLoc == string::npos )\n        {\n            strRetVal += strObjId;\n            strRetVal += \" :Internal InvokeMethod error.\";\n            return g_str2global( strRetVal );\n        }\n\n        if ( strMethod == szDISPOSE )\n        {\n            StringToJExt_T::iterator r = mapID2Obj.find( strObjId );\n\n            if ( r == mapID2Obj.end() )\n            {\n                strRetVal = szERROR;\n                strRetVal += strObjId;\n                return g_str2global( strRetVal );\n            }\n\n            JSExt * pJSExt = mapID2Obj[ strObjId ];\n\n            if ( pJSExt->CanDelete() )\n            {\n                delete pJSExt;\n            }\n\n            mapID2Obj.erase( strObjId );\n            strRetVal = szOK;\n            strRetVal += strObjId;\n            return g_str2global( strRetVal );\n        }\n\n        size_t nSuffixLoc = nLoc + strObjId.size();\n        string strInvoke = strFullCommand.substr( nSuffixLoc );\n        strInvoke = g_trim( strInvoke );\n        strRetVal = pJSExt->InvokeMethod( strInvoke );\n        return g_str2global( strRetVal );\n    }\n\n    strRetVal += \" :Unknown command \";\n    strRetVal += strCommand;\n    return g_str2global( strRetVal );\n}\n\n//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n\n"
  },
  {
    "path": "plugins/cordova-plugin-vibration/src/blackberry10/native/public/plugin.h",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n#ifndef _PLUGIN_H\n#define _PLUGIN_H\n\n#include <map>\n#include <string>\n#include <vector>\n#include <unistd.h>\n//#include \"tokenizer.h\"\n\nusing namespace std;\n\n//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n//%% Functions exported by this DLL\n//%% Should always be only SetEventFunc and InvokeFunction\n//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n// g++ requires extern \"C\" otherwise the names of SetEventFunc and InvokeFunction\n// are mangled C++ style. MS Visual Studio doesn't seem to care though.\nextern \"C\"\n{\n    typedef void (*SendPluginEv)( const char* szEvent, void* pContext );\n    char* SetEventFunc(SendPluginEv funcPtr);\n    char* InvokeFunction( const char* szCommand, void* pContext );\n}\n\n// JNEXT Framework function of the form:\n// typedef void (*SendPluginEv)( const char* szEvent );\n// used to notify JavaScript of an asynchronous event\nextern SendPluginEv SendPluginEvent;\n\n/////////////////////////////////////////////////////////////////////////\n// Constants and methods common to all JNEXT extensions types\n/////////////////////////////////////////////////////////////////////////\n#define szERROR         \"Error \"\n#define szOK            \"Ok \"\n\n#define szDISPOSE       \"Dispose\"\n#define szINVOKE        \"InvokeMethod\"\n#define szCREATE        \"CreateObj\"\n\n/////////////////////////////////////////////////////////////////////////\n// Utility functions\n/////////////////////////////////////////////////////////////////////////\nstring& g_trim( string& str );\nvoid g_tokenize(const string& str,const string& delimiters, vector<string>& tokens);\nchar* g_str2static( const string& strRetVal );\nvoid g_sleep( unsigned int mseconds );\nbool g_unregisterObject( const string& strObjId, void* pContext );\n\n\n/////////////////////////////////////////////////////////////////////////\n// Abstract extension object\n/////////////////////////////////////////////////////////////////////////\nclass JSExt\n{\npublic:\n    virtual ~JSExt() {};\n    virtual string InvokeMethod( const string& strCommand ) = 0;\n    virtual bool CanDelete( void ) = 0;\n    virtual void TryDelete( void ) {}\npublic:\n    void* m_pContext;\n};\n\n/////////////////////////////////////////////////////////////////////////\n// Callback functions to be implemented by the plugin implementation\n/////////////////////////////////////////////////////////////////////////\nextern char* onGetObjList( void );\nextern JSExt* onCreateObject( const string& strClassName, const string& strObjId );\n\n#endif\n"
  },
  {
    "path": "plugins/cordova-plugin-vibration/src/blackberry10/native/public/tokenizer.cpp",
    "content": "/************************************************************************\nThe zlib/libpng License\n\nCopyright (c) 2006 Joerg Wiedenmann\n\nThis software is provided 'as-is', without any express or implied warranty.\nIn no event will the authors be held liable for any damages arising from\nthe use of this software.\n\nPermission is granted to anyone to use this software for any purpose,\nincluding commercial applications, and to alter it and redistribute it\nfreely, subject to the following restrictions:\n\n1. The origin of this software must not be misrepresented;\nyou must not claim that you wrote the original software.\nIf you use this software in a product, an acknowledgment\nin the product documentation would be appreciated but is\nnot required.\n\n2. Altered source versions must be plainly marked as such,\nand must not be misrepresented as being the original software.\n\n3. This notice may not be removed or altered from any source distribution.\n\n***********************************************************************/\n\n/********************************************************************\n\tcreated:\t2006-01-28\n\tfilename: \ttokenizer.cpp\n\tauthor:\t\tJrg Wiedenmann\n\t\n\tpurpose:\tA tokenizer function which provides a very\n\t\t\t\tcustomizable way of breaking up strings.\n\n\thistory:\t2006-01-28, Original version\n\t\t\t\t2006-03-04, Fixed a small parsing bug, thanks Elias.\n*********************************************************************/\n\n#include \"tokenizer.h\"\n\nusing namespace std;\n\nvoid tokenize ( const string& str, vector<string>& result,\n\t\t\t   const string& delimiters, const string& delimiters_preserve,\n\t\t\t   const string& quote, const string& esc )\n{\n\t// clear the vector\n\tif ( false == result.empty() )\n\t{\n\t\tresult.clear();\n\t}\n\n\tstring::size_type pos = 0; // the current position (char) in the string\n\tchar ch = 0; // buffer for the current character\n\tchar delimiter = 0;\t// the buffer for the delimiter char which\n\t\t\t\t\t\t\t// will be added to the tokens if the delimiter\n\t\t\t\t\t\t\t// is preserved\n\tchar current_quote = 0; // the char of the current open quote\n\tbool quoted = false; // indicator if there is an open quote\n\tstring token;  // string buffer for the token\n\tbool token_complete = false; // indicates if the current token is\n\t\t\t\t\t\t\t\t // read to be added to the result vector\n\tstring::size_type len = str.length();  // length of the input-string\n\n\t// for every char in the input-string\n\twhile ( len > pos )\n\t{\n\t\t// get the character of the string and reset the delimiter buffer\n\t\tch = str.at(pos);\n\t\tdelimiter = 0;\n\n\t\t// assume ch isn't a delimiter\n\t\tbool add_char = true;\n\n\t\t// check ...\n\n\t\t// ... if the delimiter is an escaped character\n\t\tbool escaped = false; // indicates if the next char is protected\n\t\tif ( false == esc.empty() ) // check if esc-chars are  provided\n\t\t{\n\t\t\tif ( string::npos != esc.find_first_of(ch) )\n\t\t\t{\n\t\t\t\t// get the escaped char\n\t\t\t\t++pos;\n\t\t\t\tif ( pos < len ) // if there are more chars left\n\t\t\t\t{\n\t\t\t\t\t// get the next one\n\t\t\t\t\tch = str.at(pos);\n\n\t\t\t\t\t// add the escaped character to the token\n\t\t\t\t\tadd_char = true;\n\t\t\t\t}\n\t\t\t\telse // cannot get any more characters\n\t\t\t\t{\n\t\t\t\t\t// don't add the esc-char\n\t\t\t\t\tadd_char = false;\n\t\t\t\t}\n\n\t\t\t\t// ignore the remaining delimiter checks\n\t\t\t\tescaped = true;\n\t\t\t}\n\t\t}\n\n\t\t// ... if the delimiter is a quote\n\t\tif ( false == quote.empty() && false == escaped )\n\t\t{\n\t\t\t// if quote chars are provided and the char isn't protected\n\t\t\tif ( string::npos != quote.find_first_of(ch) )\n\t\t\t{\n\t\t\t\t// if not quoted, set state to open quote and set\n\t\t\t\t// the quote character\n\t\t\t\tif ( false == quoted )\n\t\t\t\t{\n\t\t\t\t\tquoted = true;\n\t\t\t\t\tcurrent_quote = ch;\n\n\t\t\t\t\t// don't add the quote-char to the token\n\t\t\t\t\tadd_char = false;\n\t\t\t\t}\n\t\t\t\telse // if quote is open already\n\t\t\t\t{\n\t\t\t\t\t// check if it is the matching character to close it\n\t\t\t\t\tif ( current_quote == ch )\n\t\t\t\t\t{\n\t\t\t\t\t\t// close quote and reset the quote character\n\t\t\t\t\t\tquoted = false;\n\t\t\t\t\t\tcurrent_quote = 0;\n\n\t\t\t\t\t\t// don't add the quote-char to the token\n\t\t\t\t\t\tadd_char = false;\n\t\t\t\t\t}\n\t\t\t\t} // else\n\t\t\t}\n\t\t}\n\n\t\t// ... if the delimiter isn't preserved\n\t\tif ( false == delimiters.empty() && false == escaped &&\n\t\t\t false == quoted )\n\t\t{\n\t\t\t// if a delimiter is provided and the char isn't protected by\n\t\t\t// quote or escape char\n\t\t\tif ( string::npos != delimiters.find_first_of(ch) )\n\t\t\t{\n\t\t\t\t// if ch is a delimiter and the token string isn't empty\n\t\t\t\t// the token is complete\n\t\t\t\tif ( false == token.empty() ) // BUGFIX: 2006-03-04\n\t\t\t\t{\n\t\t\t\t\ttoken_complete = true;\n\t\t\t\t}\n\n\t\t\t\t// don't add the delimiter to the token\n\t\t\t\tadd_char = false;\n\t\t\t}\n\t\t}\n\n\t\t// ... if the delimiter is preserved - add it as a token\n\t\tbool add_delimiter = false;\n\t\tif ( false == delimiters_preserve.empty() && false == escaped &&\n\t\t\t false == quoted )\n\t\t{\n\t\t\t// if a delimiter which will be preserved is provided and the\n\t\t\t// char isn't protected by quote or escape char\n\t\t\tif ( string::npos != delimiters_preserve.find_first_of(ch) )\n\t\t\t{\n\t\t\t\t// if ch is a delimiter and the token string isn't empty\n\t\t\t\t// the token is complete\n\t\t\t\tif ( false == token.empty() ) // BUGFIX: 2006-03-04\n\t\t\t\t{\n\t\t\t\t\ttoken_complete = true;\n\t\t\t\t}\n\n\t\t\t\t// don't add the delimiter to the token\n\t\t\t\tadd_char = false;\n\n\t\t\t\t// add the delimiter\n\t\t\t\tdelimiter = ch;\n\t\t\t\tadd_delimiter = true;\n\t\t\t}\n\t\t}\n\n\n\t\t// add the character to the token\n\t\tif ( true == add_char )\n\t\t{\n\t\t\t// add the current char\n\t\t\ttoken.push_back( ch );\n\t\t}\n\n\t\t// add the token if it is complete\n\t\tif ( true == token_complete && false == token.empty() )\n\t\t{\n\t\t\t// add the token string\n\t\t\tresult.push_back( token );\n\n\t\t\t// clear the contents\n\t\t\ttoken.clear();\n\n\t\t\t// build the next token\n\t\t\ttoken_complete = false;\n\t\t}\n\n\t\t// add the delimiter\n\t\tif ( true == add_delimiter )\n\t\t{\n\t\t\t// the next token is the delimiter\n\t\t\tstring delim_token;\n\t\t\tdelim_token.push_back( delimiter );\n\t\t\tresult.push_back( delim_token );\n\n\t\t\t// REMOVED: 2006-03-04, Bugfix\n\t\t}\n\n\t\t// repeat for the next character\n\t\t++pos;\n\t} // while\n\n\t// add the final token\n\tif ( false == token.empty() )\n\t{\n\t\tresult.push_back( token );\n\t}\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-vibration/src/blackberry10/native/public/tokenizer.h",
    "content": "/************************************************************************\nThe zlib/libpng License\n\nCopyright (c) 2006 Joerg Wiedenmann\n\nThis software is provided 'as-is', without any express or implied warranty.\nIn no event will the authors be held liable for any damages arising from\nthe use of this software.\n\nPermission is granted to anyone to use this software for any purpose,\nincluding commercial applications, and to alter it and redistribute it\nfreely, subject to the following restrictions:\n\n1. The origin of this software must not be misrepresented;\n\tyou must not claim that you wrote the original software.\n\tIf you use this software in a product, an acknowledgment\n\tin the product documentation would be appreciated but is\n\tnot required.\n\n2. Altered source versions must be plainly marked as such,\n\tand must not be misrepresented as being the original software.\n\n3. This notice may not be removed or altered from any source distribution.\n\n***********************************************************************/\n\n/********************************************************************\n\tcreated:\t2006-01-28\n\tfilename: \ttokenizer.cpp\n\tauthor:\t\tJrg Wiedenmann\n\n\tpurpose:\tA tokenizer function which provides a very\n\t\t\t\tcustomizable way of breaking up strings.\n*********************************************************************/\n\n#include <vector>\n#include <string>\nusing namespace std;\n\n// Function to break up a string into tokens\n//\n// Parameters:\n//-----------\n// str = the input string that will be tokenized\n// result = the tokens for str\n// delimiters = the delimiter characters\n// delimiters preserve = same as above, but the delimiter characters\n//\t\twill be put into the result as a token\n// quote = characters to protect the enclosed characters\n// esc = characters to protect a single character\n//\n\nvoid tokenize ( const string& str, vector<string>& result,\n\t\t\tconst string& delimiters, const string& delimiters_preserve = \"\",\n\t\t\tconst string& quote = \"\\\"\", const string& esc = \"\\\\\" );\n"
  },
  {
    "path": "plugins/cordova-plugin-vibration/src/blackberry10/native/src/vibration_js.cpp",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n#include <string>\n#include <sstream>\n#include <sys/stat.h>\n#include <sys/types.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include \"vibration_js.hpp\"\n#include <bps/vibration.h>\n\nusing namespace std;\n\n/**\n * Default constructor.\n */\nVibration::Vibration(const std::string& id) : m_id(id){\n\tbps_initialize();\n}\n\n/**\n * Vibration destructor.\n */\nVibration::~Vibration() {\n\tbps_shutdown();\n}\n\n/**\n * This method returns the list of objects implemented by this native extension.\n */\nchar* onGetObjList() {\n    static char name[] = \"Vibration\";\n    return name;\n}\n\n/**\n * This method is used by JNext to instantiate the Vibration object when\n * an object is created on the JavaScript server side.\n */\nJSExt* onCreateObject(const string& className, const string& id) {\n    if (className == \"Vibration\") {\n        return new Vibration(id);\n    }\n    return NULL;\n}\n\n/**\n * Method used by JNext to determine if the object can be deleted.\n */\nbool Vibration::CanDelete() {\n    return true;\n}\n\n/**\n * It will be called from JNext JavaScript side with passed string.\n * This method implements the interface for the JavaScript to native binding\n * for invoking native code. This method is triggered when JNext.invoke is\n * called on the JavaScript side with this native objects id.\n */\nstring Vibration::InvokeMethod(const string& command) {\n\n    // parse command and args from string\n    int indexOfFirstSpace = command.find_first_of(\" \");\n    string strCommand = command.substr(0, indexOfFirstSpace);\n    string strValue = command.substr(indexOfFirstSpace + 1, command.length());\n    char info[1024];\n\n    //Process the vibrate command\n    if (strCommand == \"vibrate\") {\n    \t//Get the duration\n    \tint duration = atoi(strValue.substr(0, strValue.length()).c_str());\n\n    \tif (duration <= 0) {\n    \t\t//Default to 1 second\n    \t\tduration = 1000;\n    \t} else if (duration > 5000) {\n    \t\t//Max 5 seconds\n    \t\tduration = 5000;\n    \t}\n\n    \t//Vibrate\n\t\tint value = vibration_request(VIBRATION_INTENSITY_HIGH , duration);\n\n\t\t//Check return\n\t\tif (value == BPS_SUCCESS) {\n\t\t\tsprintf(info, \"Vibration successful.\");\n\t\t} else if(value == BPS_FAILURE) {\n\t\t\tsprintf(info, \"Vibration failed.\");\n\t\t} else {\n\t\t\tsprintf(info, \"Vibration unknown error: %d\", value);\n\t\t}\n\t\treturn info;\n    } else {\n    \tsprintf(info, \"Unsupported method: %s\", strCommand.c_str());\n    }\n    return info;\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-vibration/src/blackberry10/native/src/vibration_js.hpp",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n#ifndef VIBRATION_JS_HPP_\n#define VIBRATION_JS_HPP_\n\n#include <string>\n#include \"../public/plugin.h\"\n\nclass Vibration: public JSExt {\n\npublic:\n    explicit Vibration(const std::string& id);\n    virtual ~Vibration();\n\n    // Interfaces of JSExt\n    virtual bool CanDelete();\n    virtual std::string InvokeMethod(const std::string& command);\n\nprivate:\n    std::string m_id;\n};\n\n#endif /* VIBRATION_JS_HPP_ */\n"
  },
  {
    "path": "plugins/cordova-plugin-vibration/src/firefoxos/VibrationProxy.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\nvar cordova = require('cordova');\n\nmodule.exports = {\n\n    vibrate: function(success, fail, milliseconds) {\n        if (navigator.notification.vibrate) {\n            navigator.vibrate(milliseconds);\n        } else {\n            console.log (\"cordova/plugin/firefoxos/vibration, vibrate API does not exist\");\n        }\n    }\n};\n\nrequire(\"cordova/exec/proxy\").add(\"Vibration\", module.exports);"
  },
  {
    "path": "plugins/cordova-plugin-vibration/src/ios/CDVVibration.h",
    "content": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements.  See the NOTICE file\n distributed with this work for additional information\n regarding copyright ownership.  The ASF licenses this file\n to you under the Apache License, Version 2.0 (the\n \"License\"); you may not use this file except in compliance\n with the License.  You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an\n \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n KIND, either express or implied.  See the License for the\n specific language governing permissions and limitations\n under the License.\n */\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n#import <AudioToolbox/AudioServices.h>\n#import <Cordova/CDVPlugin.h>\n\n@interface CDVVibration : CDVPlugin {}\n\n- (void)vibrate:(CDVInvokedUrlCommand*)command;\n\n@end\n"
  },
  {
    "path": "plugins/cordova-plugin-vibration/src/ios/CDVVibration.m",
    "content": "/*\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements.  See the NOTICE file\n distributed with this work for additional information\n regarding copyright ownership.  The ASF licenses this file\n to you under the Apache License, Version 2.0 (the\n \"License\"); you may not use this file except in compliance\n with the License.  You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an\n \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n KIND, either express or implied.  See the License for the\n specific language governing permissions and limitations\n under the License.\n */\n\n#import \"CDVVibration.h\"\n\n@implementation CDVVibration\n\n- (void)vibrate:(CDVInvokedUrlCommand*)command\n{\n    AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);\n}\n\n@end\n"
  },
  {
    "path": "plugins/cordova-plugin-vibration/src/tizen/VibrationProxy.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\nmodule.exports = {\n    vibrate: function(milliseconds) {\n        if (navigator.vibrate) {\n            navigator.vibrate(milliseconds);\n        }\n    }\n};\n\nrequire(\"cordova/tizen/commandProxy\").add(\"Vibration\", module.exports);\n"
  },
  {
    "path": "plugins/cordova-plugin-vibration/src/ubuntu/vibration.cpp",
    "content": "/*\n *\n * Copyright 2013 Canonical Ltd.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n#include \"vibration.h\"\n\nvoid Vibration::vibrate(int, int, int mills) {\n    QSharedPointer<QFeedbackHapticsEffect> vibrate = QSharedPointer<QFeedbackHapticsEffect>::create();\n    vibrate->setIntensity(1.0);\n    vibrate->setDuration(mills);\n\n    vibrate->start();\n\n    _effects.append(vibrate);\n}\n\nvoid Vibration::cancelVibration(int, int) {\n    _timers.clear();\n    _effects.clear();\n}\n\nvoid Vibration::vibrateWithPattern(int, int, const QList<int> &pattern, int repeat) {\n    QSharedPointer<QTimer> timer = QSharedPointer<QTimer>::create();\n    QSharedPointer<int> k = QSharedPointer<int>::create();\n\n    QSharedPointer<QFeedbackHapticsEffect> vibrate = QSharedPointer<QFeedbackHapticsEffect>::create();\n    vibrate->setIntensity(1.0);\n\n    _effects.append(vibrate);\n    _timers.append(timer);\n\n    timer->connect(timer.data(), &QTimer::timeout, [=, timer = timer.data()] () {\n        if (*k >= pattern.size()) {\n            if (repeat < 0 || repeat >= pattern.size()) {\n                timer->stop();\n                return;\n            }\n            *k = repeat;\n        }\n        bool idle = (*k % 2 == 0);\n        if (!idle) {\n            vibrate->setDuration(pattern[*k]);\n            vibrate->start();\n        }\n        timer->start(pattern[*k]);\n        (*k)++;\n    });\n    timer->start(1);\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-vibration/src/ubuntu/vibration.h",
    "content": "/*\n *\n * Copyright 2013 Canonical Ltd.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\n#ifndef _VIBRATION_H_SFAFKNVX3456\n#define _VIBRATION_H_SFAFKNVX3456\n\n#include <QtCore>\n#include <QFeedbackHapticsEffect>\n#include <cplugin.h>\n\nclass Vibration: public CPlugin {\n    Q_OBJECT\npublic:\n    explicit Vibration(Cordova *cordova): CPlugin(cordova) {\n    }\n\n    virtual const QString fullName() override {\n        return Vibration::fullID();\n    }\n\n    virtual const QString shortName() override {\n        return \"Vibration\";\n    }\n\n    static const QString fullID() {\n        return \"Vibration\";\n    }\npublic slots:\n    void vibrate(int, int, int mills);\n    void cancelVibration(int, int);\n    void vibrateWithPattern(int, int, const QList<int> &pattern, int);\n\nprivate:\n    QList<QSharedPointer<QFeedbackEffect>> _effects;\n    QList<QSharedPointer<QTimer>> _timers;\n};\n\n#endif\n"
  },
  {
    "path": "plugins/cordova-plugin-vibration/src/windows/Vibration/.npmignore",
    "content": "/bin/\n/obj/\n*.suo"
  },
  {
    "path": "plugins/cordova-plugin-vibration/src/windows/Vibration/Properties/AssemblyInfo.cs",
    "content": "﻿/*  \n    Licensed under the Apache License, Version 2.0 (the \"License\");\n    you may not use this file except in compliance with the License.\n    You may obtain a copy of the License at\n    \n    http://www.apache.org/licenses/LICENSE-2.0\n    \n    Unless required by applicable law or agreed to in writing, software\n    distributed under the License is distributed on an \"AS IS\" BASIS,\n    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n    See the License for the specific language governing permissions and\n    limitations under the License.\n*/\n\nusing System.Resources;\nusing System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"Vibration\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"Vibration\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2014\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n[assembly: NeutralResourcesLanguage(\"en\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version \n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers \n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "plugins/cordova-plugin-vibration/src/windows/Vibration/Vibration.cs",
    "content": "﻿/*\n       Licensed to the Apache Software Foundation (ASF) under one\n       or more contributor license agreements.  See the NOTICE file\n       distributed with this work for additional information\n       regarding copyright ownership.  The ASF licenses this file\n       to you under the Apache License, Version 2.0 (the\n       \"License\"); you may not use this file except in compliance\n       with the License.  You may obtain a copy of the License at\n\n         http://www.apache.org/licenses/LICENSE-2.0\n\n       Unless required by applicable law or agreed to in writing,\n       software distributed under the License is distributed on an\n       \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n       KIND, either express or implied.  See the License for the\n       specific language governing permissions and limitations\n       under the License.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Runtime.InteropServices.WindowsRuntime;\nusing System.Text;\nusing Windows.Phone.Devices.Notification;\n\nnamespace Vibration\n{\n    public sealed class Vibration\n    {\n        private static VibrationDevice _vibrationDevice = VibrationDevice.GetDefault();\n\n        public static void vibrate([ReadOnlyArray()] object[] args)\n        {\n            // set default\n            int duration = 200;\n\n            try \n            {\n                duration = Convert.ToInt32(args[0]);\n            }\n            catch \n            { \n\n            }\n\n            _vibrationDevice.Vibrate(TimeSpan.FromMilliseconds(duration));\n        }\n\n        public static void cancelVibration()\n        {\n            _vibrationDevice.Cancel();\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-vibration/src/windows/Vibration/Vibration.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements.  See the NOTICE file\n distributed with this work for additional information\n regarding copyright ownership.  The ASF licenses this file\n to you under the Apache License, Version 2.0 (the\n \"License\"); you may not use this file except in compliance\n with the License.  You may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an\n \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n KIND, either express or implied.  See the License for the\n specific language governing permissions and limitations\n under the License. \n-->\n<Project ToolsVersion=\"12.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <PropertyGroup>\n    <MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProjectGuid>{D4F9F695-ECD5-49FC-B58A-B1E0E754E159}</ProjectGuid>\n    <ProjectName>Vibration</ProjectName>\n    <OutputType>winmdobj</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>Vibration</RootNamespace>\n    <AssemblyName>Vibration</AssemblyName>\n    <DefaultLanguage>en-US</DefaultLanguage>\n    <FileAlignment>512</FileAlignment>\n    <ProjectTypeGuids>{76F1466A-8B6D-4E39-A767-685A06062A39};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>\n    <TargetPlatformIdentifier>WindowsPhoneApp</TargetPlatformIdentifier>\n    <TargetPlatformVersion>8.1</TargetPlatformVersion>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_PHONE_APP</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE;NETFX_CORE;WINDOWS_PHONE_APP</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <ItemGroup>\n    <!-- A reference to the entire .NET Framework is automatically included -->\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"Vibration.cs\" />\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n  </ItemGroup>\n  <Import Project=\"$(MSBuildExtensionsPath)\\Microsoft\\WindowsXaml\\v$(VisualStudioVersion)\\Microsoft.Windows.UI.Xaml.CSharp.targets\" />\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\n</Project>"
  },
  {
    "path": "plugins/cordova-plugin-vibration/src/windows/VibrationProxy.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n */\n\nfunction checkReqs(actionName, fail) {\n    if (!(Windows.Phone && Windows.Phone.Devices && Windows.Phone.Devices.Notification && Windows.Phone.Devices.Notification.VibrationDevice) && WinJS.Utilities.isPhone !== true) {       \n        fail(actionName + ' is unsupported by this platform.');\n        return false;\n    }\n\n    return true;\n}\n\nfunction tryDoAction(actionName, success, fail, args, action) {\n    try {\n        if (checkReqs(actionName, fail) !== true) {\n            return;\n        }\n\n        action(args);\n        success();        \n    } catch (e) {\n        fail('Error occured while trying to ' + actionName + ': ' + e);\n    }\n}\n\nvar DEFAULT_DURATION = 200;\n\nvar VibrationDevice = (Windows.Phone && Windows.Phone.Devices && Windows.Phone.Devices.Notification && Windows.Phone.Devices.Notification.VibrationDevice && Windows.Phone.Devices.Notification.VibrationDevice);\nif (VibrationDevice) {\n    // Windows Phone 10 code paths\n    module.exports = {\n        vibrate: function(success, fail, args) {\n            try {\n                var duration = parseInt(args[0]);\n                if (isNaN(duration)) {\n                    duration = DEFAULT_DURATION;\n                }\n                VibrationDevice.getDefault().vibrate(duration);\n                success();\n            }\n            catch (e) {\n                fail(e);\n            }\n        }, \n        vibrateWithPattern: function(success, fail, args) {\n            // TODO: Implement with setTimeout.\n            fail('\"vibrateWithPattern\" is unsupported by this platform.');\n        },\n        cancelVibration: function(success, fail, args) {\n            try {\n                VibrationDevice.getDefault().cancel();\n                success();\n            }\n            catch (e) {\n                fail(e);\n            }\n        }\n    };\n} else if (typeof Vibration !== 'undefined' && Vibration.Vibration) { \n    // Windows Phone 8.1 code paths\n    module.exports = {\n        vibrate: function (success, fail, args) {\n            tryDoAction(\"vibrate\", success, fail, args, Vibration.Vibration.vibrate);\n        },\n\n        vibrateWithPattern: function (success, fail, args) {\n            tryDoAction(\"vibrate\", success, fail, [DEFAULT_DURATION], Vibration.Vibration.vibrate);\n        },\n\n        cancelVibration: function(success, fail, args) {\n            tryDoAction(\"cancelVibration\", success, fail, args, Vibration.Vibration.cancelVibration);\n        }\n    };\n} else {\n    // code paths where no vibration mechanism is present\n    module.exports = {\n        vibrate: function (a, fail) {\n            fail('\"vibrate\" is unsupported by this device.');\n        },\n        vibrateWithPattern: function (success, fail, args) {\n            fail('\"vibrateWithPattern\" is unsupported by this device.');\n        },\n\n        cancelVibration: function(success, fail, args) {\n            success();\n        }\n    }\n}\n\nrequire(\"cordova/exec/proxy\").add(\"Vibration\", module.exports);\n"
  },
  {
    "path": "plugins/cordova-plugin-vibration/src/wp/Vibration.cs",
    "content": "﻿/*  \n\tLicensed under the Apache License, Version 2.0 (the \"License\");\n\tyou may not use this file except in compliance with the License.\n\tYou may obtain a copy of the License at\n\t\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\t\n\tUnless required by applicable law or agreed to in writing, software\n\tdistributed under the License is distributed on an \"AS IS\" BASIS,\n\tWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n\tSee the License for the specific language governing permissions and\n\tlimitations under the License.\n*/\n\nusing System;\nusing System.Windows;\nusing System.Windows.Controls;\nusing Microsoft.Devices;\nusing System.Runtime.Serialization;\nusing System.Threading;\nusing System.Windows.Resources;\nusing Microsoft.Phone.Controls;\nusing System.Diagnostics;\nusing System.Threading.Tasks;\n\n\nnamespace WPCordovaClassLib.Cordova.Commands\n{\n    public class Vibration : BaseCommand\n    {\n\n        private static readonly int DEFAULT_DURATION = 200;\n        private static readonly int MAX_DURATION = 5000;\n        private static readonly int MIN_DURATION = 5;\n\n        // bool used to determine if cancel was called during vibrateWithPattern\n        private bool cancelWasCalled = false;\n\n        public void vibrate(string vibrateDuration)\n        {\n            int msecs = DEFAULT_DURATION; // set default\n            string callbackId = CurrentCommandCallbackId;\n\n            try\n            {\n                string[] args = JSON.JsonHelper.Deserialize<string[]>(vibrateDuration);\n                msecs = int.Parse(args[0]);\n                callbackId = args[1];\n\n                if (msecs < MIN_DURATION)\n                {\n                    msecs = MIN_DURATION;\n                }\n                else if (msecs > MAX_DURATION)\n                {\n                    msecs = MAX_DURATION;\n                }\n            }\n            catch (FormatException)\n            {\n                 DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);\n            }\n\n            vibrateMs(msecs);\n\n            // TODO: may need to add listener to trigger DispatchCommandResult when the vibration ends...\n            DispatchCommandResult(new PluginResult(PluginResult.Status.OK),callbackId);\n        }\n\n        private static void vibrateMs(int msecs)\n        {\n            VibrateController.Default.Start(TimeSpan.FromMilliseconds(msecs));\n        }\n\n        public async Task vibrateWithPattern(string options)\n        {\n            string callbackId = CurrentCommandCallbackId;\n            // clear the cancelWasCalled flag\n            cancelWasCalled = false;\n            // get options\n            try\n            {\n                string[] args = JSON.JsonHelper.Deserialize<string[]>(options);\n                int[] pattern = JSON.JsonHelper.Deserialize<int[]>(args[0]);\n                callbackId = args[1];\n\n                for (int i = 0; i < pattern.Length && !cancelWasCalled; i++)\n                {\n                    int msecs = pattern[i];\n                    if (msecs < MIN_DURATION)\n                    {\n                        msecs = MIN_DURATION;\n                    }\n                    if (i % 2 == 0)\n                    {\n                        msecs = (msecs > MAX_DURATION) ? MAX_DURATION : msecs;\n                        VibrateController.Default.Start(TimeSpan.FromMilliseconds(msecs));\n                    }\n                    await Task.Delay(TimeSpan.FromMilliseconds(msecs));\n                }\n                DispatchCommandResult(new PluginResult(PluginResult.Status.OK), callbackId);\n            }\n            catch (FormatException)\n            {\n                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);\n            }\n        }\n\n        public void cancelVibration(string options)\n        {\n            string callbackId = JSON.JsonHelper.Deserialize<string[]>(options)[0];\n            VibrateController.Default.Stop();\n            cancelWasCalled = true;\n            DispatchCommandResult(new PluginResult(PluginResult.Status.OK), callbackId);\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-vibration/tests/plugin.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  Licensed to the Apache Software Foundation (ASF) under one\n  or more contributor license agreements.  See the NOTICE file\n  distributed with this work for additional information\n  regarding copyright ownership.  The ASF licenses this file\n  to you under the Apache License, Version 2.0 (the\n  \"License\"); you may not use this file except in compliance\n  with the License.  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing,\n  software distributed under the License is distributed on an\n  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n  KIND, either express or implied.  See the License for the\n  specific language governing permissions and limitations\n  under the License.\n-->\n\n<plugin xmlns=\"http://apache.org/cordova/ns/plugins/1.0\"\n    xmlns:rim=\"http://www.blackberry.com/ns/widgets\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    id=\"cordova-plugin-vibration-tests\"\n    version=\"1.2.0\">\n    <name>Cordova Vibration Plugin Tests</name>\n    <license>Apache 2.0</license>\n\n    <js-module src=\"tests.js\" name=\"tests\">\n    </js-module>\n</plugin>\n"
  },
  {
    "path": "plugins/cordova-plugin-vibration/tests/tests.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n */\n\nexports.defineAutoTests = function () {\n\n    describe('Vibration (navigator.notification.vibrate)', function () {\n        it(\"navigator.notification should exist\", function () {\n            expect(navigator.notification).toBeDefined();\n        });\n\n        it(\"should contain a vibrate function\", function () {\n            expect(typeof navigator.notification.vibrate).toBeDefined();\n            expect(typeof navigator.notification.vibrate).toBe(\"function\");\n        });\n    });\n};\n\nexports.defineManualTests = function (contentEl, createActionButton) {\n    var logMessage = function (message, color) {\n        var log = document.getElementById('info');\n        var logLine = document.createElement('div');\n        if (color) {\n            logLine.style.color = color;\n        }\n        logLine.innerHTML = message;\n        log.appendChild(logLine);\n    }\n\n    var clearLog = function () {\n        var log = document.getElementById('info');\n        log.innerHTML = '';\n    }\n\n    //-------------------------------------------------------------------------\n    // Vibrations\n    //-------------------------------------------------------------------------\n\n    //old vibrate call\n    var vibrateOld = function(){\n        clearLog();\n        navigator.notification.vibrate(2500);\n        logMessage(\"navigator.notification.vibrate(2500)\", \"green\");\n    };\n\n    //old vibrate with pattern call\n    var vibrateWithPatternOld = function(){\n        clearLog();\n        navigator.notification.vibrateWithPattern([1000, 3000, 2000, 5000]);\n        logMessage(\"navigator.notification.vibrateWithPattern([1000, 3000, 2000, 5000])\", \"green\");\n    };\n\n    //old cancel vibrate call\n    var cancelOld = function(){\n        clearLog();\n        navigator.notification.cancelVibration();\n        logMessage(\"navigator.notification.cancelVibration()\", \"green\");\n    };\n\n    //new standard vibrate call that aligns to w3c spec with param long\n    var vibrateWithInt = function() {\n        clearLog();\n        navigator.vibrate(3000);\n        logMessage(\"navigator.vibrate(3000)\", \"green\");\n    };\n\n    //new standard vibrate call that aligns to w3c spec with param array\n    var vibrateWithArray = function() {\n        clearLog();\n        navigator.vibrate([3000]);\n        logMessage(\"navigator.vibrate([3000])\", \"green\");\n    };\n\n    //vibrate with a pattern using w3c spec\n    var vibrateWithPattern = function() {\n        clearLog();\n        navigator.vibrate([1000, 2000, 3000, 2000, 5000]);\n        logMessage(\"navigator.vibrate([1000, 2000, 3000, 2000, 5000])\", \"green\");\n    };\n\n    //cancel existing vibration using w3c spec navigator.vibrate(0)\n    var cancelWithZero = function() {\n        clearLog();\n        navigator.vibrate(0);\n        logMessage(\"navigator.vibrate(0)\", \"green\");\n    };\n\n    //cancel existing vibration using w3c spec navigator.vibrate([])\n    var cancelWithEmpty = function() {\n        clearLog();\n        navigator.vibrate([]);\n        logMessage(\"navigator.vibrate([])\", \"green\");\n    };\n\n    //reference to the timeout variable\n    var timeout;\n\n    //special long vibrate used to test cancel\n    var longVibrate = function() {\n        clearLog();\n        navigator.vibrate(60000);\n        vibrateOn = true;\n        logMessage(\"navigator.vibrate(60000)\", \"green\");\n        timeout = setTimeout(resetVibrateOn, 60000); //if user doesn't cancel vibrate, reset vibrateOn var after 60 seconds\n    };\n\n    //special long vibrate with pattern used to test cancel\n    var longVibrateWithPattern = function() {\n        clearLog();\n        navigator.vibrate([1000, 2000, 3000, 2000, 5000, 2000, 30000]);\n        vibrateOn = true;\n        logMessage(\"navigator.vibrate([1000, 2000, 3000, 2000, 5000, 2000, 30000])\", \"green\");\n        timeout = setTimeout(resetVibrateOn, 45000); //if user doesn't cancel vibrate, reset vibrateOn var after 45 seconds\n    };\n\n    //initiate two vibrations to test cancel\n    var multipleVibrations = function() {\n        clearLog();\n        navigator.vibrate(20000);\n        navigator.vibrate(45000);\n        vibrateOn = true;\n        logMessage(\"navigator.vibrate(15000)\\nnavigator.vibrate(45000)\", \"green\");\n        timeout = setTimeout(resetVibrateOn, 45000); //if user doesn't cancel vibrate, reset vibrateOn var after 45 seconds\n    }\n\n    function resetVibrateOn() {\n        vibrateOn = false;\n    }\n\n    //check whether there is an ongoing vibration\n    var vibrateOn = false;\n\n\n\n\n    var vibrate_tests = '<h1>Vibrate Tests</h1>' +\n        '<h3>Starred tests only work for Android and Windows. </h3>' +\n        '<h3>iOS ignores the time given for a vibrate </h3>' +\n        '<div id=\"vibrate_old\"></div>' +\n        'Expected result: Vibrate once for 2.5 seconds.' +\n        '<p/> <div id=\"vibrateWithPattern_old\"></div>' +\n        'Expected result: Pause for 1s, vibrate for 3s, pause for 2s, vibrate for 5s.' +\n        '<p/> <div id=\"cancelVibrate_old\"></div>' +\n        'Expected result: Press once to initiate vibrate for 60 seconds. Press again to cancel vibrate immediately.' +\n        '<p/> <div id=\"cancelVibrateWithPattern_old\"></div>' +\n        'Expected result: Press once to initiate vibrate with pattern for 45s. Press again to cancel vibrate immediately.' +\n        '<p/> <div id=\"vibrate_int\"></div>' +\n        'Expected result: Vibrate once for 3 seconds.' +\n        '<p/> <div id=\"vibrate_array\"></div>' +\n        'Expected result: Vibrate once for 3 seconds.' +\n        '<p/> <div id=\"vibrate_with_pattern\"></div>' +\n        'Expected result: Vibrate for 1s, pause for 2s, vibrate for 3s, pause for 2s, vibrate for 5s.' +\n        '<p/> <div id=\"cancel_zero\"></div>' +\n        'Expected result: Press once to initiate vibrate for 60 seconds. Press again to cancel vibrate immediately.' +\n        '<p/><div id=\"cancel_array\"></div>' +\n        'Expected result: Press once to initiate vibrate for 60 seconds. Press again to cancel vibrate immediately.' +\n        '<p/> <div id=\"cancelWithPattern_zero\"></div>' +\n        'Expected result: Press once to initiate vibrate with pattern for 45s. Press again to cancel vibrate immediately.' +\n        '<p/> <div id=\"cancelWithPattern_array\"></div>' +\n        'Expected result: Press once to initiate vibrate with pattern for 45s. Press again to cancel vibrate immediately.' +\n        '<p/> <div id=\"cancelMultipleVibrations\"></div>' +\n        'Expected result: Press once to initiate two vibrations simultaneously (one for 20s the other for 45s so total of 45s). Press again to cancel both vibrations immediately.';\n\n\n    contentEl.innerHTML = '<div id=\"info\"></div>' + vibrate_tests;\n\n    //standard vibrate with old call\n    createActionButton('Vibrate (Old)', function () {\n        vibrateOld();\n    }, 'vibrate_old');\n\n    //vibrate with pattern with old call\n    createActionButton('* Vibrate with a pattern (Old)', function () {\n        vibrateWithPatternOld();\n    }, 'vibrateWithPattern_old');\n\n    //cancel vibrate with old call\n    createActionButton('* Cancel vibration (Old)', function() {\n\n        if (!vibrateOn)\n        {\n            longVibrate();\n        }\n        else\n        {\n            cancelOld();\n            resetVibrateOn();\n            clearTimeout(timeout); //clear the timeout since user has canceled the vibrate\n        }\n    }, 'cancelVibrate_old');\n\n    //cancel vibrate with pattern with old call\n    createActionButton('* Cancel vibration with pattern (Old)', function() {\n\n        if (!vibrateOn)\n        {\n            longVibrateWithPattern();\n        }\n        else\n        {\n            cancelOld();\n            resetVibrateOn();\n            clearTimeout(timeout); //clear the timeout since user has canceled the vibrate\n        }\n    }, 'cancelVibrateWithPattern_old');\n\n    //standard vibrate with new call param int\n    createActionButton('Vibrate with int', function() {\n        vibrateWithInt();\n    }, 'vibrate_int');\n\n    //standard vibrate with new call param array\n    createActionButton('Vibrate with array', function() {\n        vibrateWithArray();\n    }, 'vibrate_array');\n\n    //vibrate with a pattern\n    createActionButton('* Vibrate with a pattern', function() {\n        vibrateWithPattern();\n    }, 'vibrate_with_pattern');\n\n    //cancel any existing vibrations with param 0\n    createActionButton('* Cancel vibration with 0', function() {\n\n        if (!vibrateOn)\n        {\n            longVibrate();\n        }\n        else\n        {\n            cancelWithZero();\n            resetVibrateOn();\n            clearTimeout(timeout); //clear the timeout since user has canceled the vibrate\n        }\n    }, 'cancel_zero');\n\n    //cancel any existing vibrations with param []\n    createActionButton('* Cancel vibration with []', function() {\n\n        if (!vibrateOn)\n        {\n            longVibrate();\n        }\n        else\n        {\n            cancelWithEmpty();\n            resetVibrateOn();\n            clearTimeout(timeout); //clear the timeout since user has canceled the vibrate\n        }\n    }, 'cancel_array');\n\n    //cancel vibration with pattern with param 0\n    createActionButton('* Cancel vibration with pattern with 0', function() {\n\n        if (!vibrateOn)\n        {\n            longVibrateWithPattern();\n        }\n        else\n        {\n            cancelWithZero();\n            resetVibrateOn();\n            clearTimeout(timeout); //clear the timeout since user has canceled the vibrate\n        }\n    }, 'cancelWithPattern_zero');\n\n    //cancel vibration with pattern with param []\n    createActionButton('* Cancel vibration with pattern with []', function() {\n\n        if (!vibrateOn)\n        {\n            longVibrateWithPattern();\n        }\n        else\n        {\n            cancelWithEmpty();\n            resetVibrateOn();\n            clearTimeout(timeout); //clear the timeout since user has canceled the vibrate\n        }\n    }, 'cancelWithPattern_array');\n\n    //cancel multiple vibrations\n    createActionButton('* Cancel multiple vibrations', function() {\n\n        if (!vibrateOn)\n        {\n            multipleVibrations();\n        }\n        else\n        {\n            cancelWithZero();\n            resetVibrateOn();\n            clearTimeout(timeout); //clear the timeout since user has canceled the vibrate\n        }\n    }, 'cancelMultipleVibrations');\n};\n"
  },
  {
    "path": "plugins/cordova-plugin-vibration/www/blackberry10/vibrate.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\nvar vibrate = function(duration) {\n    navigator.vibrate(duration);\n};\n\nmodule.exports = vibrate;\n"
  },
  {
    "path": "plugins/cordova-plugin-vibration/www/vibration.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\n\nvar exec = require('cordova/exec');\n\n/**\n * Provides access to the vibration mechanism on the device.\n */\n\nmodule.exports = {\n\n    /**\n     * Vibrates the device for a given amount of time or for a given pattern or immediately cancels any ongoing vibrations (depending on the parameter).\n     *\n     * @param {Integer} param       The number of milliseconds to vibrate (if 0, cancels vibration)\n     *\n     *\n     * @param {Array of Integer} param    Pattern with which to vibrate the device.\n     *                                      Pass in an array of integers that\n     *                                      are the durations for which to\n     *                                      turn on or off the vibrator in\n     *                                      milliseconds. The FIRST value\n     *                                      indicates the\n     *                                      number of milliseconds for which\n     *                                      to keep the vibrator ON before\n     *                                      turning it off. The NEXT value indicates the\n     *                                      number of milliseconds for which\n     *                                      to keep the vibrator OFF before\n     *                                      turning it on. Subsequent values\n     *                                      alternate between durations in\n     *                                      milliseconds to turn the vibrator\n     *                                      off or to turn the vibrator on.\n     *                                      (if empty, cancels vibration)\n     */\n    vibrate: function(param) {\n\n        /* Aligning with w3c spec */\n        \n        //vibrate\n        if ((typeof param == 'number') && param != 0)\n            exec(null, null, \"Vibration\", \"vibrate\", [param]);\n\n        //vibrate with array ( i.e. vibrate([3000]) )\n        else if ((typeof param == 'object') && param.length == 1)\n        {\n            //cancel if vibrate([0])\n            if (param[0] == 0)\n                exec(null, null, \"Vibration\", \"cancelVibration\", []);\n\n            //else vibrate\n            else\n                exec(null, null, \"Vibration\", \"vibrate\", [param[0]]);\n        }\n\n        //vibrate with a pattern\n        else if ((typeof param == 'object') && param.length > 1)\n        {\n            var repeat = -1; //no repeat\n            exec(null, null, \"Vibration\", \"vibrateWithPattern\", [param, repeat]);\n        }\n\n        //cancel vibration (param = 0 or [])\n        else\n            exec(null, null, \"Vibration\", \"cancelVibration\", []);\n    },\n\n    /**\n     * Vibrates the device with a given pattern.\n     *\n     * @param {Array of Integer} pattern    Pattern with which to vibrate the device.\n     *                                      Pass in an array of integers that\n     *                                      are the durations for which to\n     *                                      turn on or off the vibrator in\n     *                                      milliseconds. The first value\n     *                                      indicates the number of milliseconds\n     *                                      to wait before turning the vibrator\n     *                                      on. The next value indicates the\n     *                                      number of milliseconds for which\n     *                                      to keep the vibrator on before\n     *                                      turning it off. Subsequent values\n     *                                      alternate between durations in\n     *                                      milliseconds to turn the vibrator\n     *                                      off or to turn the vibrator on.\n     *\n     * @param {Integer} repeat              Optional index into the pattern array at which\n     *                                      to start repeating (will repeat until canceled),\n     *                                      or -1 for no repetition (default).\n     */\n    vibrateWithPattern: function(pattern, repeat) {\n        repeat = (typeof repeat !== \"undefined\") ? repeat : -1;\n        pattern.unshift(0); //add a 0 at beginning for backwards compatibility from w3c spec\n        exec(null, null, \"Vibration\", \"vibrateWithPattern\", [pattern, repeat]);\n    },\n\n    /**\n     * Immediately cancels any currently running vibration.\n     */\n    cancelVibration: function() {\n        exec(null, null, \"Vibration\", \"cancelVibration\", []);\n    }\n};\n"
  },
  {
    "path": "plugins/cordova-plugin-whitelist/CONTRIBUTING.md",
    "content": "<!--\n#\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#  KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n#\n-->\n\n# Contributing to Apache Cordova\n\nAnyone can contribute to Cordova. And we need your contributions.\n\nThere are multiple ways to contribute: report bugs, improve the docs, and\ncontribute code.\n\nFor instructions on this, start with the\n[contribution overview](http://cordova.apache.org/contribute/).\n\nThe details are explained there, but the important items are:\n - Sign and submit an Apache ICLA (Contributor License Agreement).\n - Have a Jira issue open that corresponds to your contribution.\n - Run the tests so your patch doesn't break existing functionality.\n\nWe look forward to your contributions!\n"
  },
  {
    "path": "plugins/cordova-plugin-whitelist/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License."
  },
  {
    "path": "plugins/cordova-plugin-whitelist/NOTICE",
    "content": "Apache Cordova\nCopyright 2012 The Apache Software Foundation\n\nThis product includes software developed at\nThe Apache Software Foundation (http://www.apache.org/).\n"
  },
  {
    "path": "plugins/cordova-plugin-whitelist/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-whitelist\n\nThis plugin implements a whitelist policy for navigating the application webview on Cordova 4.0\n\n:warning: Report issues on the [Apache Cordova issue tracker](https://issues.apache.org/jira/issues/?jql=project%20%3D%20CB%20AND%20status%20in%20%28Open%2C%20%22In%20Progress%22%2C%20Reopened%29%20AND%20resolution%20%3D%20Unresolved%20AND%20component%20%3D%20%22Plugin%20Whitelist%22%20ORDER%20BY%20priority%20DESC%2C%20summary%20ASC%2C%20updatedDate%20DESC)\n\n\n## Supported Cordova Platforms\n\n* Android 4.0.0 or above\n\n## Navigation Whitelist\nControls which URLs the WebView itself can be navigated to. Applies to\ntop-level navigations only.\n\nQuirks: on Android it also applies to iframes for non-http(s) schemes.\n\nBy default, navigations only to `file://` URLs, are allowed. To allow others URLs, you must add `<allow-navigation>` tags to your `config.xml`:\n\n    <!-- Allow links to example.com -->\n    <allow-navigation href=\"http://example.com/*\" />\n\n    <!-- Wildcards are allowed for the protocol, as a prefix\n         to the host, or as a suffix to the path -->\n    <allow-navigation href=\"*://*.example.com/*\" />\n\n    <!-- A wildcard can be used to whitelist the entire network,\n         over HTTP and HTTPS.\n         *NOT RECOMMENDED* -->\n    <allow-navigation href=\"*\" />\n\n    <!-- The above is equivalent to these three declarations -->\n    <allow-navigation href=\"http://*/*\" />\n    <allow-navigation href=\"https://*/*\" />\n    <allow-navigation href=\"data:*\" />\n\n## Intent Whitelist\nControls which URLs the app is allowed to ask the system to open.\nBy default, no external URLs are allowed.\n\nOn Android, this equates to sending an intent of type BROWSEABLE.\n\nThis whitelist does not apply to plugins, only hyperlinks and calls to `window.open()`.\n\nIn `config.xml`, add `<allow-intent>` tags, like this:\n\n    <!-- Allow links to web pages to open in a browser -->\n    <allow-intent href=\"http://*/*\" />\n    <allow-intent href=\"https://*/*\" />\n\n    <!-- Allow links to example.com to open in a browser -->\n    <allow-intent href=\"http://example.com/*\" />\n\n    <!-- Wildcards are allowed for the protocol, as a prefix\n         to the host, or as a suffix to the path -->\n    <allow-intent href=\"*://*.example.com/*\" />\n\n    <!-- Allow SMS links to open messaging app -->\n    <allow-intent href=\"sms:*\" />\n\n    <!-- Allow tel: links to open the dialer -->\n    <allow-intent href=\"tel:*\" />\n\n    <!-- Allow geo: links to open maps -->\n    <allow-intent href=\"geo:*\" />\n\n    <!-- Allow all unrecognized URLs to open installed apps\n         *NOT RECOMMENDED* -->\n    <allow-intent href=\"*\" />\n\n## Network Request Whitelist\nControls which network requests (images, XHRs, etc) are allowed to be made (via cordova native hooks).\n\nNote: We suggest you use a Content Security Policy (see below), which is more secure.  This whitelist is mostly historical for webviews which do not support CSP.\n\nIn `config.xml`, add `<access>` tags, like this:\n\n    <!-- Allow images, xhrs, etc. to google.com -->\n    <access origin=\"http://google.com\" />\n    <access origin=\"https://google.com\" />\n\n    <!-- Access to the subdomain maps.google.com -->\n    <access origin=\"http://maps.google.com\" />\n\n    <!-- Access to all the subdomains on google.com -->\n    <access origin=\"http://*.google.com\" />\n\n    <!-- Enable requests to content: URLs -->\n    <access origin=\"content:///*\" />\n\n    <!-- Don't block any requests -->\n    <access origin=\"*\" />\n\nWithout any `<access>` tags, only requests to `file://` URLs are allowed. However, the default Cordova application includes `<access origin=\"*\">` by default.\n\n\nNote: Whitelist cannot block network redirects from a whitelisted remote website (i.e. http or https) to a non-whitelisted website. Use CSP rules to mitigate redirects to non-whitelisted websites for webviews that support CSP.\n\nQuirk: Android also allows requests to https://ssl.gstatic.com/accessibility/javascript/android/ by default, since this is required for TalkBack to function properly.\n\n### Content Security Policy\nControls which network requests (images, XHRs, etc) are allowed to be made (via webview directly).\n\nOn Android and iOS, the network request whitelist (see above) is not able to filter all types of requests (e.g. `<video>` & WebSockets are not blocked). So, in addition to the whitelist, you should use a [Content Security Policy](http://content-security-policy.com/) `<meta>` tag on all of your pages.\n\nOn Android, support for CSP within the system webview starts with KitKat (but is available on all versions using Crosswalk WebView).\n\nHere are some example CSP declarations for your `.html` pages:\n\n    <!-- Good default declaration:\n        * gap: is required only on iOS (when using UIWebView) and is needed for JS->native communication\n        * https://ssl.gstatic.com is required only on Android and is needed for TalkBack to function properly\n        * Disables use of eval() and inline scripts in order to mitigate risk of XSS vulnerabilities. To change this:\n            * Enable inline JS: add 'unsafe-inline' to default-src\n            * Enable eval(): add 'unsafe-eval' to default-src\n    -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self' data: gap: https://ssl.gstatic.com; style-src 'self' 'unsafe-inline'; media-src *\">\n\n    <!-- Allow everything but only from the same origin and foo.com -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self' foo.com\">\n\n    <!-- This policy allows everything (eg CSS, AJAX, object, frame, media, etc) except that \n        * CSS only from the same origin and inline styles,\n        * scripts only from the same origin and inline styles, and eval()\n    -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'\">\n\n    <!-- Allows XHRs only over HTTPS on the same domain. -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self' https:\">\n\n    <!-- Allow iframe to https://cordova.apache.org/ -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self'; frame-src 'self' https://cordova.apache.org\">\n"
  },
  {
    "path": "plugins/cordova-plugin-whitelist/RELEASENOTES.md",
    "content": "<!--\n#\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#  KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n#\n-->\n# Release Notes\n\n### 1.2.2 (Apr 15, 2016)\n* add note about redirects\n* CB-10624 remove error message from `whitelist.js`, which leaves it empty\n\n### 1.2.1 (Jan 15, 2016)\n* CB-10194 info tag prints for ios when not applicable\n\n### 1.2.0 (Nov 18, 2015)\n* removed **iOS** engine check from `plugin.xml`\n* [CB-10035](https://issues.apache.org/jira/browse/CB-10035) Updated `RELEASENOTES` to be newest to oldest\n* [CB-9972](https://issues.apache.org/jira/browse/CB-9972) - Remove **iOS** whitelist\n* Updated the text, it should read 4.0.x and greater, since this plugin will be required for `cordova-android 5.0`\n* Fixing contribute link.\n* Updated `plugin.xml <info>` tag to remove warning about not needing this plugin if you are using the **iOS 9 SDK**\n* [CB-9738](https://issues.apache.org/jira/browse/CB-9738) - Disable whitelist use when runtime environment is **iOS 9**\n* [CB-9740](https://issues.apache.org/jira/browse/CB-9740) - Add `<info>` tag describing whitelist plugin not needed on `cordova-ios` and cordova-android 3.x`\n* [CB-9568](https://issues.apache.org/jira/browse/CB-9568) - Update whitelist plugin to allow all network access by default\n* [CB-9337](https://issues.apache.org/jira/browse/CB-9337) - enable use of `<access>` tags for native code network requests\n\n### 1.1.0 (Jun 17, 2015)\n* [CB-9128](https://issues.apache.org/jira/browse/CB-9128) cordova-plugin-whitelist documentation translation: cordova-plugin-whitelist\n* fix npm md issue\n* Usage of CDVURLRequestFilter protocol.\n* [CB-9089](https://issues.apache.org/jira/browse/CB-9089) - iOS whitelist plugin does not compile\n* [CB-9090](https://issues.apache.org/jira/browse/CB-9090) - Enable whitelist plugin for cordova-ios 4.0.0\n* Fixed error in Content-Security-Policy example\n\n### 1.0.0 (Mar 25, 2015)\n* [CB-8739](https://issues.apache.org/jira/browse/CB-8739) added missing license headers\n* Add @Override to CustomConfigXmlParser methods\n* Change ID to cordova-plugin-whitelist rather than reverse-DNS-style\n* Tweak CSP examples in README\n* [CB-8660](https://issues.apache.org/jira/browse/CB-8660) remove extra commas from package.json\n"
  },
  {
    "path": "plugins/cordova-plugin-whitelist/doc/de/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-whitelist\n\nDieses Plugin implementiert eine Whitelist-Politik für die Navigation in der Anwendung Webview Cordova 4.0\n\n## Cordova unterstützte Plattformen\n\n  * Android 4.0.0 oder höher\n  * iOS 4.0.0 oder höher\n\n## Navigation-Whitelist\n\nSteuert, welche URLs die WebView selbst zu navigiert werden kann. Bezieht sich auf der obersten Ebene Navigationen nur.\n\nMacken: auf Android es gilt auch für Iframes für nicht-http(s) Systeme.\n\nIn der Standardeinstellung Navigationen nur auf `file://` URLs, sind zulässig. Wenn andere andere URLs zulassen möchten, müssen Sie Ihre `\"config.xml\"` `<allow-navigation>` Markierungen hinzufügen:\n\n    <!-- Allow links to example.com -->\n    <allow-navigation href=\"http://example.com/*\" />\n    \n    <!-- Wildcards are allowed for the protocol, as a prefix\n         to the host, or as a suffix to the path -->\n    <allow-navigation href=\"*://*.example.com/*\" />\n    \n    <!-- A wildcard can be used to whitelist the entire network,\n         over HTTP and HTTPS.\n         *NOT RECOMMENDED* -->\n    <allow-navigation href=\"*\" />\n    \n    <!-- The above is equivalent to these three declarations -->\n    <allow-navigation href=\"http://*/*\" />\n    <allow-navigation href=\"https://*/*\" />\n    <allow-navigation href=\"data:*\" />\n    \n\n## Vorsatz-Whitelist\n\nSteuert, welche URLs die app zulässig ist, um das System zu öffnen Fragen. Standardmäßig dürfen keine externe URLs.\n\nDas entspricht auf Android eine Absicht des Typs BROWSEABLE senden.\n\nDiese Whitelist gilt nicht für Plugins, nur Hyperlinks und Aufrufe von `window.open()`.\n\nFügen Sie in `\"config.xml\"` `<allow-intent>` Tags hinzu, wie folgt:\n\n    <!-- Allow links to web pages to open in a browser -->\n    <allow-intent href=\"http://*/*\" />\n    <allow-intent href=\"https://*/*\" />\n    \n    <!-- Allow links to example.com to open in a browser -->\n    <allow-intent href=\"http://example.com/*\" />\n    \n    <!-- Wildcards are allowed for the protocol, as a prefix\n         to the host, or as a suffix to the path -->\n    <allow-intent href=\"*://*.example.com/*\" />\n    \n    <!-- Allow SMS links to open messaging app -->\n    <allow-intent href=\"sms:*\" />\n    \n    <!-- Allow tel: links to open the dialer -->\n    <allow-intent href=\"tel:*\" />\n    \n    <!-- Allow geo: links to open maps -->\n    <allow-intent href=\"geo:*\" />\n    \n    <!-- Allow all unrecognized URLs to open installed apps\n         *NOT RECOMMENDED* -->\n    <allow-intent href=\"*\" />\n    \n\n## Netzwerk-Anforderung-Whitelist\n\nSteuert, welche-Anforderungen Netzwerk (Bilder, XHRs, etc.) dürfen (über Cordova native Haken) erfolgen.\n\nHinweis: Wir empfehlen Ihnen eine Content Security Policy (siehe unten), das ist sicherer. Diese Whitelist ist vor allem historisch für Webansichten für die CSP nicht unterstützen.\n\nFügen Sie in `\"config.xml\"` `<access>` Tags hinzu, wie folgt:\n\n    <!-- Allow images, xhrs, etc. to google.com -->\n    <access origin=\"http://google.com\" />\n    <access origin=\"https://google.com\" />\n    \n    <!-- Access to the subdomain maps.google.com -->\n    <access origin=\"http://maps.google.com\" />\n    \n    <!-- Access to all the subdomains on google.com -->\n    <access origin=\"http://*.google.com\" />\n    \n    <!-- Enable requests to content: URLs -->\n    <access origin=\"content:///*\" />\n    \n    <!-- Don't block any requests -->\n    <access origin=\"*\" />\n    \n\nOhne `<access>` -Tags dürfen nur Anforderungen an `file://` URLs. Enthält jedoch die Standardanwendung Cordova `<access origin=\"*\">` standardmäßig.\n\nEigenart: Android kann auch Anforderungen an https://ssl.gstatic.com/accessibility/javascript/android/ standardmäßig, da dies für TalkBack ordnungsgemäß erforderlich ist.\n\n### Content-Security-Policy\n\nSteuert, welche-Anforderungen Netzwerk (Bilder, XHRs, etc.) dürfen (über Webview direkt) erfolgen.\n\nAuf Android und iOS ist die Netzwerk Anfrage Whitelist (s.o.) nicht in der Lage, alle Arten von Anfragen (z.B. `< video >` & WebSockets nicht blockiert) filtern. Also, sollten Sie neben der Whitelist, [Content Security Policy](http://content-security-policy.com/) `< Meta >` -Tags auf allen Ihren Seiten verwenden.\n\nAuf Android Unterstützung für CSP innerhalb der System-Webview beginnt mit KitKat (aber ist in allen Versionen mit Crosswalk WebView verfügbar).\n\nHier sind einige Beispiel-CSP-Deklarationen für Ihre `HTML` -Seiten:\n\n    <!-- Good default declaration:\n        * gap: is required only on iOS (when using UIWebView) and is needed for JS->native communication\n        * https://ssl.gstatic.com is required only on Android and is needed for TalkBack to function properly\n        * Disables use of eval() and inline scripts in order to mitigate risk of XSS vulnerabilities. To change this:\n            * Enable inline JS: add 'unsafe-inline' to default-src\n            * Enable eval(): add 'unsafe-eval' to default-src\n    -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self' data: gap: https://ssl.gstatic.com; style-src 'self' 'unsafe-inline'; media-src *\">\n    \n    <!-- Allow requests to foo.com -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self' foo.com\">\n    \n    <!-- Enable all requests, inline styles, and eval() -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'\">\n    \n    <!-- Allow XHRs via https only -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self' https:\">\n    \n    <!-- Allow iframe to https://cordova.apache.org/ -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self'; frame-src 'self' https://cordova.apache.org\">"
  },
  {
    "path": "plugins/cordova-plugin-whitelist/doc/es/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-whitelist\n\nEste plugin implementa una política de lista blanca para navegar la aplicación webview en Cordova 4.0\n\n## Plataformas soportadas Cordova\n\n  * Android 4.0 o superior\n  * iOS 4.0.0 o superior\n\n## Lista blanca de navegación\n\nControla que las URLs del WebView se puede navegar a. Se aplica a nivel superior navegaciones solo.\n\nPeculiaridades: en Android también se aplica a iframes para esquemas que son de http (s).\n\nPor defecto, navegaciones solo a direcciones URL `file://` , son permitidas. Para permitir que otros otras URL, debe agregar `< allow-navegación >` etiquetas en el `archivo config.xml`:\n\n    <!-- Allow links to example.com -->\n    <allow-navigation href=\"http://example.com/*\" />\n    \n    <!-- Wildcards are allowed for the protocol, as a prefix\n         to the host, or as a suffix to the path -->\n    <allow-navigation href=\"*://*.example.com/*\" />\n    \n    <!-- A wildcard can be used to whitelist the entire network,\n         over HTTP and HTTPS.\n         *NOT RECOMMENDED* -->\n    <allow-navigation href=\"*\" />\n    \n    <!-- The above is equivalent to these three declarations -->\n    <allow-navigation href=\"http://*/*\" />\n    <allow-navigation href=\"https://*/*\" />\n    <allow-navigation href=\"data:*\" />\n    \n\n## Intención de lista blanca\n\nControla qué URLs de la aplicación se permite hacer el sistema para abrir. De forma predeterminada, se permiten ninguÌ n external URLs.\n\nEn Android, esto equivale a enviar una intención de tipo BROWSEABLE.\n\nEsta lista blanca no se aplica a plugins, sólo los hipervínculos y las llamadas a `window.Open)`.\n\nEn `config.xml`, agregar etiquetas `< allow-intent >` , como este:\n\n    <!-- Allow links to web pages to open in a browser -->\n    <allow-intent href=\"http://*/*\" />\n    <allow-intent href=\"https://*/*\" />\n    \n    <!-- Allow links to example.com to open in a browser -->\n    <allow-intent href=\"http://example.com/*\" />\n    \n    <!-- Wildcards are allowed for the protocol, as a prefix\n         to the host, or as a suffix to the path -->\n    <allow-intent href=\"*://*.example.com/*\" />\n    \n    <!-- Allow SMS links to open messaging app -->\n    <allow-intent href=\"sms:*\" />\n    \n    <!-- Allow tel: links to open the dialer -->\n    <allow-intent href=\"tel:*\" />\n    \n    <!-- Allow geo: links to open maps -->\n    <allow-intent href=\"geo:*\" />\n    \n    <!-- Allow all unrecognized URLs to open installed apps\n         *NOT RECOMMENDED* -->\n    <allow-intent href=\"*\" />\n    \n\n## Solicitud de red blanca\n\nControles que las peticiones de la red (imágenes, XHRs, etc.) se les permite hacer (a través de ganchos nativa de Córdoba).\n\nNota: Le sugerimos que utilice una política de seguridad de contenido (véase abajo), que es más seguro. Esta lista blanca es sobre todo histórico para webviews que no admiten la CSP.\n\nEn `config.xml`, agregue etiquetas de `< access >` , como este:\n\n    <!-- Allow images, xhrs, etc. to google.com -->\n    <access origin=\"http://google.com\" />\n    <access origin=\"https://google.com\" />\n    \n    <!-- Access to the subdomain maps.google.com -->\n    <access origin=\"http://maps.google.com\" />\n    \n    <!-- Access to all the subdomains on google.com -->\n    <access origin=\"http://*.google.com\" />\n    \n    <!-- Enable requests to content: URLs -->\n    <access origin=\"content:///*\" />\n    \n    <!-- Don't block any requests -->\n    <access origin=\"*\" />\n    \n\nSin las etiquetas `< access >` , se admiten sólo las solicitudes a direcciones URL `file://` . Sin embargo, la aplicación por defecto de Cordova incluye `< access origin = \"*\" >` por defecto.\n\nQuirk: Android también permite las solicitudes de https://ssl.gstatic.com/accessibility/javascript/android/ por defecto, puesto que es necesario para TalkBack funcionar correctamente.\n\n### Política de seguridad de contenido\n\nControles que las peticiones de la red (imágenes, XHRs, etc.) se les permite hacer (vía webview directamente).\n\nEn iOS y Android, la red solicitud lista blanca (véase arriba) no es capaz de filtrar todos los tipos de solicitudes (por ejemplo, `< video >` y WebSockets no estén bloqueadas). Así, además de la lista blanca, usted debe utilizar una etiqueta `< meta >` de [Contenido la política de seguridad](http://content-security-policy.com/) en todas las páginas.\n\nEn Android, soporte para CSP en el sistema webview comienza con KitKat (pero está disponible en todas las versiones con WebView de paso de peatones).\n\nAquí están algunas declaraciones de CSP de ejemplo para las páginas `.html` :\n\n    <!-- Good default declaration:\n        * gap: is required only on iOS (when using UIWebView) and is needed for JS->native communication\n        * https://ssl.gstatic.com is required only on Android and is needed for TalkBack to function properly\n        * Disables use of eval() and inline scripts in order to mitigate risk of XSS vulnerabilities. To change this:\n            * Enable inline JS: add 'unsafe-inline' to default-src\n            * Enable eval(): add 'unsafe-eval' to default-src\n    -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self' data: gap: https://ssl.gstatic.com; style-src 'self' 'unsafe-inline'; media-src *\">\n    \n    <!-- Allow requests to foo.com -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self' foo.com\">\n    \n    <!-- Enable all requests, inline styles, and eval() -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'\">\n    \n    <!-- Allow XHRs via https only -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self' https:\">\n    \n    <!-- Allow iframe to https://cordova.apache.org/ -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self'; frame-src 'self' https://cordova.apache.org\">"
  },
  {
    "path": "plugins/cordova-plugin-whitelist/doc/fr/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-whitelist\n\nCe plugin met en œuvre une politique de liste blanche pour naviguer le webview application sur Cordova 4.0\n\n## Plates-formes prises en charge Cordova\n\n  * 4.0.0 Android ou supérieur\n  * iOS 4.0.0 ou supérieur\n\n## Navigation liste blanche\n\nContrôle quels URL le WebView lui-même peut être parcourus à. S'applique à des navigations niveau supérieur seulement.\n\nParticularités : sur Android il s'applique également aux iframes pour non-schémas http (s).\n\nPar défaut, navigations qu'aux URL `file://` , sont autorisés. Pour permettre aux autres d'autres URL, vous devez ajouter des balises `<allow-navigation>` à votre `fichier config.xml`:\n\n    <!-- Allow links to example.com -->\n    <allow-navigation href=\"http://example.com/*\" />\n    \n    <!-- Wildcards are allowed for the protocol, as a prefix\n         to the host, or as a suffix to the path -->\n    <allow-navigation href=\"*://*.example.com/*\" />\n    \n    <!-- A wildcard can be used to whitelist the entire network,\n         over HTTP and HTTPS.\n         *NOT RECOMMENDED* -->\n    <allow-navigation href=\"*\" />\n    \n    <!-- The above is equivalent to these three declarations -->\n    <allow-navigation href=\"http://*/*\" />\n    <allow-navigation href=\"https://*/*\" />\n    <allow-navigation href=\"data:*\" />\n    \n\n## Intent Whitelist\n\nContrôle quels URL l'app n'est autorisé à poser le système d'ouverture. Par défaut, aucun external URL est autorisés.\n\nSur Android, cela équivaut à envoyer une intention de type BROWSEABLE.\n\nCette autorisation ne s'applique pas aux plugins, uniquement les liens hypertexte et les appels à `window.open()`.\n\nDans le `fichier config.xml`, ajouter des balises `<allow-intent>` , comme ceci :\n\n    <!-- Allow links to web pages to open in a browser -->\n    <allow-intent href=\"http://*/*\" />\n    <allow-intent href=\"https://*/*\" />\n    \n    <!-- Allow links to example.com to open in a browser -->\n    <allow-intent href=\"http://example.com/*\" />\n    \n    <!-- Wildcards are allowed for the protocol, as a prefix\n         to the host, or as a suffix to the path -->\n    <allow-intent href=\"*://*.example.com/*\" />\n    \n    <!-- Allow SMS links to open messaging app -->\n    <allow-intent href=\"sms:*\" />\n    \n    <!-- Allow tel: links to open the dialer -->\n    <allow-intent href=\"tel:*\" />\n    \n    <!-- Allow geo: links to open maps -->\n    <allow-intent href=\"geo:*\" />\n    \n    <!-- Allow all unrecognized URLs to open installed apps\n         *NOT RECOMMENDED* -->\n    <allow-intent href=\"*\" />\n    \n\n## Réseau demande liste blanche\n\nLes contrôles dont les demandes de réseau (images, XHRs, etc.) sont autorisés à effectuer (via cordova natif crochets).\n\nRemarque : Nous vous suggérons de qu'utiliser un contenu politique de sécurité (voir ci-dessous), qui est plus sûr. Cette liste blanche est surtout historique pour webviews qui ne prennent pas en charge les CSP.\n\nDans le `fichier config.xml`, ajouter des balises `<access>` , comme ceci :\n\n    <!-- Allow images, xhrs, etc. to google.com -->\n    <access origin=\"http://google.com\" />\n    <access origin=\"https://google.com\" />\n    \n    <!-- Access to the subdomain maps.google.com -->\n    <access origin=\"http://maps.google.com\" />\n    \n    <!-- Access to all the subdomains on google.com -->\n    <access origin=\"http://*.google.com\" />\n    \n    <!-- Enable requests to content: URLs -->\n    <access origin=\"content:///*\" />\n    \n    <!-- Don't block any requests -->\n    <access origin=\"*\" />\n    \n\nSans les balises `<access>` , seules les demandes d'URL `file://` sont autorisés. Toutefois, l'application de Cordoue par défaut inclut `<access origin=\"*\" >` par défaut.\n\nBizarrerie : Android permet également aux requêtes à https://ssl.gstatic.com/accessibility/javascript/android/ par défaut, puisque c'est nécessaire pour TalkBack fonctionner correctement.\n\n### Politique de sécurité du contenu\n\nLes contrôles dont les demandes de réseau (images, XHRs, etc.) sont autorisés à effectuer (via webview directement).\n\nSur Android et iOS, la réseau demande liste blanche (voir ci-dessus) n'est pas en mesure de filtrer tous les types de demandes (p. ex. `< video >` & WebSockets ne sont pas bloquées). Ainsi, en plus de la liste blanche, vous devez utiliser une balise `< meta >` de [Contenu politique de sécurité](http://content-security-policy.com/) sur toutes vos pages.\n\nSur Android, support pour le CSP dans le système webview commence par KitKat (mais n'est disponible sur toutes les versions à l'aide du tableau de concordance WebView).\n\nVoici quelques exemples de déclarations de CSP pour vos pages `.html` :\n\n    <!-- Good default declaration:\n        * gap: is required only on iOS (when using UIWebView) and is needed for JS->native communication\n        * https://ssl.gstatic.com is required only on Android and is needed for TalkBack to function properly\n        * Disables use of eval() and inline scripts in order to mitigate risk of XSS vulnerabilities. To change this:\n            * Enable inline JS: add 'unsafe-inline' to default-src\n            * Enable eval(): add 'unsafe-eval' to default-src\n    -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self' data: gap: https://ssl.gstatic.com; style-src 'self' 'unsafe-inline'; media-src *\">\n    \n    <!-- Allow requests to foo.com -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self' foo.com\">\n    \n    <!-- Enable all requests, inline styles, and eval() -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'\">\n    \n    <!-- Allow XHRs via https only -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self' https:\">\n    \n    <!-- Allow iframe to https://cordova.apache.org/ -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self'; frame-src 'self' https://cordova.apache.org\">"
  },
  {
    "path": "plugins/cordova-plugin-whitelist/doc/it/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-whitelist\n\nQuesto plugin attua una politica di whitelist per spostarsi all'interno dell'applicazione webview in Cordova 4.0\n\n## Piattaforme supportate Cordova\n\n  * Android 4.0.0 o superiore\n  * iOS 4.0.0 o superiore\n\n## Navigazione Whitelist\n\nControlla quali URL WebView stessa può essere esplorato. Si applica al solo primo livello navigazioni.\n\nStranezze: su Android vale anche per gli iframe per non-schemi di http (s).\n\nPer impostazione predefinita, navigazioni solo agli URL `file://` , sono ammessi. Per consentire altri altri URL, è necessario aggiungere `<allow-navigation>` tag per il tuo `config. XML`:\n\n    <!-- Allow links to example.com -->\n    <allow-navigation href=\"http://example.com/*\" />\n    \n    <!-- Wildcards are allowed for the protocol, as a prefix\n         to the host, or as a suffix to the path -->\n    <allow-navigation href=\"*://*.example.com/*\" />\n    \n    <!-- A wildcard can be used to whitelist the entire network,\n         over HTTP and HTTPS.\n         *NOT RECOMMENDED* -->\n    <allow-navigation href=\"*\" />\n    \n    <!-- The above is equivalent to these three declarations -->\n    <allow-navigation href=\"http://*/*\" />\n    <allow-navigation href=\"https://*/*\" />\n    <allow-navigation href=\"data:*\" />\n    \n\n## Whitelist intento\n\nControlla quali URL app è consentito richiedere il sistema di apertura. Per impostazione predefinita, nessun esterno URL sono ammessi.\n\nSu Android, ciò equivale all'invio di un intento di tipo BROWSEABLE.\n\nQuesta whitelist non si applica ai plugin, solo i collegamenti ipertestuali e chiamate a `Window`.\n\nIn `config. XML`, aggiungere tag `<allow-intent>` , simile al seguente:\n\n    <!-- Allow links to web pages to open in a browser -->\n    <allow-intent href=\"http://*/*\" />\n    <allow-intent href=\"https://*/*\" />\n    \n    <!-- Allow links to example.com to open in a browser -->\n    <allow-intent href=\"http://example.com/*\" />\n    \n    <!-- Wildcards are allowed for the protocol, as a prefix\n         to the host, or as a suffix to the path -->\n    <allow-intent href=\"*://*.example.com/*\" />\n    \n    <!-- Allow SMS links to open messaging app -->\n    <allow-intent href=\"sms:*\" />\n    \n    <!-- Allow tel: links to open the dialer -->\n    <allow-intent href=\"tel:*\" />\n    \n    <!-- Allow geo: links to open maps -->\n    <allow-intent href=\"geo:*\" />\n    \n    <!-- Allow all unrecognized URLs to open installed apps\n         *NOT RECOMMENDED* -->\n    <allow-intent href=\"*\" />\n    \n\n## Rete richiesta Whitelist\n\nControlli che le richieste di rete (immagini, XHRs, ecc.) sono consentiti (tramite ganci nativo di cordova).\n\nNota: Si consiglia di che utilizzare un criterio di protezione contenuti (Vedi sotto), che è più sicuro. La whitelist è principalmente storico per visualizzazioni Web che non supportano la CSP.\n\nIn `config. XML`, aggiungere tag `< access >` , simile al seguente:\n\n    <!-- Allow images, xhrs, etc. to google.com -->\n    <access origin=\"http://google.com\" />\n    <access origin=\"https://google.com\" />\n    \n    <!-- Access to the subdomain maps.google.com -->\n    <access origin=\"http://maps.google.com\" />\n    \n    <!-- Access to all the subdomains on google.com -->\n    <access origin=\"http://*.google.com\" />\n    \n    <!-- Enable requests to content: URLs -->\n    <access origin=\"content:///*\" />\n    \n    <!-- Don't block any requests -->\n    <access origin=\"*\" />\n    \n\nSenza qualsiasi tag `< access >` , sono consentite solo le richieste di URL `file://` . Tuttavia, l'applicazione di Cordova predefinito include `< access origin = \"*\" >` per impostazione predefinita.\n\nStranezza: Android consente anche alle richieste di https://ssl.gstatic.com/accessibility/javascript/android/ per impostazione predefinita, poiché questa operazione è necessaria per TalkBack funzionare correttamente.\n\n### Politica di sicurezza del contenuto\n\nControlli che le richieste di rete (immagini, XHRs, ecc.) possono essere effettuate (via webview direttamente).\n\nSu Android e iOS, la rete richiesta whitelist (Vedi sopra) non è in grado di filtrare tutti i tipi di richieste (ad esempio non sono bloccate `< video >` & WebSockets). Così, oltre alla whitelist, è necessario utilizzare un tag `< meta >` [Content Security Policy](http://content-security-policy.com/) su tutte le pagine.\n\nSu Android, supporto per CSP all'interno webview sistema inizia con KitKat (ma è disponibile su tutte le versioni usando Crosswalk WebView).\n\nEcco alcuni esempi di dichiarazioni di CSP per le pagine `HTML` :\n\n    <!-- Good default declaration:\n        * gap: is required only on iOS (when using UIWebView) and is needed for JS->native communication\n        * https://ssl.gstatic.com is required only on Android and is needed for TalkBack to function properly\n        * Disables use of eval() and inline scripts in order to mitigate risk of XSS vulnerabilities. To change this:\n            * Enable inline JS: add 'unsafe-inline' to default-src\n            * Enable eval(): add 'unsafe-eval' to default-src\n    -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self' data: gap: https://ssl.gstatic.com; style-src 'self' 'unsafe-inline'; media-src *\">\n    \n    <!-- Allow requests to foo.com -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self' foo.com\">\n    \n    <!-- Enable all requests, inline styles, and eval() -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'\">\n    \n    <!-- Allow XHRs via https only -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self' https:\">\n    \n    <!-- Allow iframe to https://cordova.apache.org/ -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self'; frame-src 'self' https://cordova.apache.org\">"
  },
  {
    "path": "plugins/cordova-plugin-whitelist/doc/ja/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-whitelist\n\nこのプラグイン実装コルドバ 4.0 アプリケーション webview をナビゲートするためのホワイト リスト ポリシー\n\n## サポートされているコルドバのプラットフォーム\n\n  * アンドロイド 4.0.0 以上\n  * iOS 4.0.0 以上\n\n## ナビゲーションのホワイト リスト\n\nWebView 自体に移動に Url を制御します。最上位ナビゲーションのみに適用されます。\n\n癖: Android にもに適用されますの iframe 非-[http スキーム。\n\n既定では、ナビゲーション、 `file://`の Url にのみ許可されます。その他の他の Url を許可するように、 `config.xml`に`<allow-navigation>`タグを追加する必要があります。\n\n    <!-- Allow links to example.com -->\n    <allow-navigation href=\"http://example.com/*\" />\n    \n    <!-- Wildcards are allowed for the protocol, as a prefix\n         to the host, or as a suffix to the path -->\n    <allow-navigation href=\"*://*.example.com/*\" />\n    \n    <!-- A wildcard can be used to whitelist the entire network,\n         over HTTP and HTTPS.\n         *NOT RECOMMENDED* -->\n    <allow-navigation href=\"*\" />\n    \n    <!-- The above is equivalent to these three declarations -->\n    <allow-navigation href=\"http://*/*\" />\n    <allow-navigation href=\"https://*/*\" />\n    <allow-navigation href=\"data:*\" />\n    \n\n## インテントのホワイト リスト\n\nどの Url を開くようにシステムを聞いて、アプリに許可を制御します。 既定では、外部 Url 許可されません。\n\n人造人間、これは型 BROWSEABLE の意図を送信することに相当します。\n\nこのホワイト リストはプラグインのみハイパーリンクおよび`window.open()`への呼び出しには適用されません。.\n\n`Config.xml`内の`<allow-intent>`タグは、このようなを追加します。\n\n    <!-- Allow links to web pages to open in a browser -->\n    <allow-intent href=\"http://*/*\" />\n    <allow-intent href=\"https://*/*\" />\n    \n    <!-- Allow links to example.com to open in a browser -->\n    <allow-intent href=\"http://example.com/*\" />\n    \n    <!-- Wildcards are allowed for the protocol, as a prefix\n         to the host, or as a suffix to the path -->\n    <allow-intent href=\"*://*.example.com/*\" />\n    \n    <!-- Allow SMS links to open messaging app -->\n    <allow-intent href=\"sms:*\" />\n    \n    <!-- Allow tel: links to open the dialer -->\n    <allow-intent href=\"tel:*\" />\n    \n    <!-- Allow geo: links to open maps -->\n    <allow-intent href=\"geo:*\" />\n    \n    <!-- Allow all unrecognized URLs to open installed apps\n         *NOT RECOMMENDED* -->\n    <allow-intent href=\"*\" />\n    \n\n## ネットワーク要求のホワイト リスト\n\nネットワーク要求コントロール (画像、XHRs 等) (コルドバ ネイティブ フック) を介して行われることが。\n\n注: より安全なコンテンツ セキュリティ ポリシー (下記参照) を使用してお勧めします。 このホワイト リストほとんどの CSP をサポートしていない web 表示のために歴史的です。\n\n`Config.xml`内のこのような`<access>`タグを追加します。\n\n    <!-- Allow images, xhrs, etc. to google.com -->\n    <access origin=\"http://google.com\" />\n    <access origin=\"https://google.com\" />\n    \n    <!-- Access to the subdomain maps.google.com -->\n    <access origin=\"http://maps.google.com\" />\n    \n    <!-- Access to all the subdomains on google.com -->\n    <access origin=\"http://*.google.com\" />\n    \n    <!-- Enable requests to content: URLs -->\n    <access origin=\"content:///*\" />\n    \n    <!-- Don't block any requests -->\n    <access origin=\"*\" />\n    \n\n`<access>`タグ、なし`file://` Url に要求のみを許可します。 ただし、既定のコルドバ アプリケーションが含まれています`<access origin=\"*\">`デフォルトで。\n\n気まぐれ: アンドロイドも要求できます https://ssl.gstatic.com/accessibility/javascript/android/デフォルトでは、トークが正常に機能するために必要ですので。\n\n### コンテンツのセキュリティ ポリシー\n\nネットワーク要求コントロール (画像、XHRs 等) (直接 webview) を介して行われることが。\n\nAndroid と iOS は、ネットワーク要求ホワイト リスト (上記参照) はすべての種類の要求 (例: `< ビデオ >` & Websocket がふさがれていない) をフィルター処理できません。 だから、ホワイト リストに加えてすべてのページに[コンテンツ セキュリティ ポリシー](http://content-security-policy.com/) `< meta >`タグを使用する必要があります。\n\nAndroid 上システム webview 内 CSP サポート キットカットから始まります (しかし横断歩道 WebView を使用してすべてのバージョンで利用可能です)。\n\n`.Html`ページのいくつかの例 CSP の宣言は次のとおりです。\n\n    <!-- Good default declaration:\n        * gap: is required only on iOS (when using UIWebView) and is needed for JS->native communication\n        * https://ssl.gstatic.com is required only on Android and is needed for TalkBack to function properly\n        * Disables use of eval() and inline scripts in order to mitigate risk of XSS vulnerabilities. To change this:\n            * Enable inline JS: add 'unsafe-inline' to default-src\n            * Enable eval(): add 'unsafe-eval' to default-src\n    -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self' data: gap: https://ssl.gstatic.com; style-src 'self' 'unsafe-inline'; media-src *\">\n    \n    <!-- Allow requests to foo.com -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self' foo.com\">\n    \n    <!-- Enable all requests, inline styles, and eval() -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'\">\n    \n    <!-- Allow XHRs via https only -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self' https:\">\n    \n    <!-- Allow iframe to https://cordova.apache.org/ -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self'; frame-src 'self' https://cordova.apache.org\">"
  },
  {
    "path": "plugins/cordova-plugin-whitelist/doc/ko/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-whitelist\n\n이 플러그인 구현 코르도바 4.0 응용 프로그램 webview를 탐색에 대 한 허용 정책\n\n## 지원된 코르도바 플랫폼\n\n  * 안 드 로이드 4.0.0 이상\n  * iOS 4.0.0 이상\n\n## 탐색 허용\n\nWebView 자체가 탐색할 수 있는 Url을 제어 합니다. 최상위 탐색에만 적용 됩니다.\n\n단점: 안 드 로이드에도 적용 됩니다 iframe에 대 한 비-프로토콜인 계획.\n\n기본적으로 탐색 `file://` Url에만 사용할 수 있습니다. 다른 다른 Url을 허용 하려면 `config.xml`에 `< allow-navigation >` 태그를 추가 해야 합니다.\n\n    <!-- Allow links to example.com -->\n    <allow-navigation href=\"http://example.com/*\" />\n    \n    <!-- Wildcards are allowed for the protocol, as a prefix\n         to the host, or as a suffix to the path -->\n    <allow-navigation href=\"*://*.example.com/*\" />\n    \n    <!-- A wildcard can be used to whitelist the entire network,\n         over HTTP and HTTPS.\n         *NOT RECOMMENDED* -->\n    <allow-navigation href=\"*\" />\n    \n    <!-- The above is equivalent to these three declarations -->\n    <allow-navigation href=\"http://*/*\" />\n    <allow-navigation href=\"https://*/*\" />\n    <allow-navigation href=\"data:*\" />\n    \n\n## 의도 허용\n\nApp 시스템 열을 게 허용 되는 Url을 제어 합니다. 기본적으로 외부 Url은 사용할 수 있습니다.\n\n안 드 로이드에이 형식의 BROWSEABLE 의도 보내는 것 같습니다.\n\n이 허용 된 플러그인, 하이퍼링크 및 `window.open ()` 호출에 적용 되지 않습니다..\n\n`Config.xml`에이 같은 `< allow-intent >` 태그를 추가 합니다.\n\n    <!-- Allow links to web pages to open in a browser -->\n    <allow-intent href=\"http://*/*\" />\n    <allow-intent href=\"https://*/*\" />\n    \n    <!-- Allow links to example.com to open in a browser -->\n    <allow-intent href=\"http://example.com/*\" />\n    \n    <!-- Wildcards are allowed for the protocol, as a prefix\n         to the host, or as a suffix to the path -->\n    <allow-intent href=\"*://*.example.com/*\" />\n    \n    <!-- Allow SMS links to open messaging app -->\n    <allow-intent href=\"sms:*\" />\n    \n    <!-- Allow tel: links to open the dialer -->\n    <allow-intent href=\"tel:*\" />\n    \n    <!-- Allow geo: links to open maps -->\n    <allow-intent href=\"geo:*\" />\n    \n    <!-- Allow all unrecognized URLs to open installed apps\n         *NOT RECOMMENDED* -->\n    <allow-intent href=\"*\" />\n    \n\n## 네트워크 요청 허용\n\n요청을 네트워크 컨트롤 (이미지, XHRs, 등) (코르도바 네이티브 후크)를 통해 할 수 있습니다.\n\n참고: 당신이 사용 콘텐츠 보안 정책 (아래 참조), 더 안전한 것이 좋습니다. 이 허용은 CSP를 지원 하지 않는 webviews에 대 한 역사적.\n\n`Config.xml`에이 같은 `< access >` 태그를 추가 합니다.\n\n    <!-- Allow images, xhrs, etc. to google.com -->\n    <access origin=\"http://google.com\" />\n    <access origin=\"https://google.com\" />\n    \n    <!-- Access to the subdomain maps.google.com -->\n    <access origin=\"http://maps.google.com\" />\n    \n    <!-- Access to all the subdomains on google.com -->\n    <access origin=\"http://*.google.com\" />\n    \n    <!-- Enable requests to content: URLs -->\n    <access origin=\"content:///*\" />\n    \n    <!-- Don't block any requests -->\n    <access origin=\"*\" />\n    \n\n어떤 `< access >` 태그 없이 요청 `file://` Url 사용할 수 있습니다. 그러나 기본 코르도바 응용 프로그램을 포함 하는, `< access origin=\"*\" >` 기본적으로.\n\n특질: 안 드 로이드 또한 수 있습니다 요청을 https://ssl.gstatic.com/accessibility/javascript/android/ 기본적으로 필요 제대로 작동 하려면 의견 이므로.\n\n### 콘텐츠 보안 정책\n\n요청을 네트워크 컨트롤 (이미지, XHRs, 등) (webview 직접)를 통해 할 수 있습니다.\n\n안 드 로이드와 iOS에 네트워크 요청 허용 (위 참조)는 모든 종류의 요청 (예: `< 비디오 >` & WebSockets 차단 되지 않습니다)를 필터링 할 수 없습니다. 그래서, 허용, 뿐만 아니라 귀하의 모든 페이지에 [콘텐츠 보안 정책](http://content-security-policy.com/) `< meta >` 태그를 사용 해야 합니다.\n\n안 드 로이드, 시스템 webview 내에서 CSP에 대 한 지원을 KitKat 시작 (하지만 횡단 보도 WebView를 사용 하 여 모든 버전에서 사용할 수).\n\n다음은 `.html` 페이지에 대 한 몇 가지 예제 CSP 선언입니다.\n\n    <!-- Good default declaration:\n        * gap: is required only on iOS (when using UIWebView) and is needed for JS->native communication\n        * https://ssl.gstatic.com is required only on Android and is needed for TalkBack to function properly\n        * Disables use of eval() and inline scripts in order to mitigate risk of XSS vulnerabilities. To change this:\n            * Enable inline JS: add 'unsafe-inline' to default-src\n            * Enable eval(): add 'unsafe-eval' to default-src\n    -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self' data: gap: https://ssl.gstatic.com; style-src 'self' 'unsafe-inline'; media-src *\">\n    \n    <!-- Allow requests to foo.com -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self' foo.com\">\n    \n    <!-- Enable all requests, inline styles, and eval() -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'\">\n    \n    <!-- Allow XHRs via https only -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self' https:\">\n    \n    <!-- Allow iframe to https://cordova.apache.org/ -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self'; frame-src 'self' https://cordova.apache.org\">"
  },
  {
    "path": "plugins/cordova-plugin-whitelist/doc/pl/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-whitelist\n\nTen plugin wdraża polityki białej nawigacja widoku sieci Web aplikacji na Cordova 4.0\n\n## Cordova obsługiwanych platform\n\n  * Android 4.0.0 lub powyżej\n  * iOS 4.0.0 lub powyżej\n\n## Biała lista nawigacji\n\nKontroluje, których adresy URL widoku sieci Web, samej można nawigować do. Dotyczy tylko najwyższego poziomu nawigacje.\n\nDziwactwa: na Android to dotyczy także IFRAME do nie-http (s) systemów.\n\nDomyślnie, nawigacje tylko do URLi `file://` , są dozwolone. Aby zezwolić na inne adresy URL, należy dodać Tagi `< allow-navigation >` do pliku `config.xml`:\n\n    <!-- Allow links to example.com -->\n    <allow-navigation href=\"http://example.com/*\" />\n    \n    <!-- Wildcards are allowed for the protocol, as a prefix\n         to the host, or as a suffix to the path -->\n    <allow-navigation href=\"*://*.example.com/*\" />\n    \n    <!-- A wildcard can be used to whitelist the entire network,\n         over HTTP and HTTPS.\n         *NOT RECOMMENDED* -->\n    <allow-navigation href=\"*\" />\n    \n    <!-- The above is equivalent to these three declarations -->\n    <allow-navigation href=\"http://*/*\" />\n    <allow-navigation href=\"https://*/*\" />\n    <allow-navigation href=\"data:*\" />\n    \n\n## Zamiarem biała\n\nKontroluje, których adresy URL aplikacji jest możliwość zapytać systemem otwierania. Domyślnie nie ma zewnętrznych adresów URL są dozwolone.\n\nNa Android to przyrównuje do wysyłania zamiarem typu BROWSEABLE.\n\nTa biała nie ma zastosowania do pluginów, tylko hiperłącza i wywołania `window.open()`.\n\nW `pliku config.xml`dodawanie tagów `< allow-intent >` , jak to:\n\n    <!-- Allow links to web pages to open in a browser -->\n    <allow-intent href=\"http://*/*\" />\n    <allow-intent href=\"https://*/*\" />\n    \n    <!-- Allow links to example.com to open in a browser -->\n    <allow-intent href=\"http://example.com/*\" />\n    \n    <!-- Wildcards are allowed for the protocol, as a prefix\n         to the host, or as a suffix to the path -->\n    <allow-intent href=\"*://*.example.com/*\" />\n    \n    <!-- Allow SMS links to open messaging app -->\n    <allow-intent href=\"sms:*\" />\n    \n    <!-- Allow tel: links to open the dialer -->\n    <allow-intent href=\"tel:*\" />\n    \n    <!-- Allow geo: links to open maps -->\n    <allow-intent href=\"geo:*\" />\n    \n    <!-- Allow all unrecognized URLs to open installed apps\n         *NOT RECOMMENDED* -->\n    <allow-intent href=\"*\" />\n    \n\n## Sieci wniosek biała\n\nFormanty, które sieci żądań (obrazy, XHRs, itp.) mogą być wykonane (za pośrednictwem cordova rodzimych haki).\n\nUwaga: Zalecamy, że używasz treści polityki bezpieczeństwa (patrz poniżej), który jest bardziej bezpieczne. Ta Biała jest głównie historyczne dla webviews, które nie obsługują CSP.\n\nW `pliku config.xml`dodawanie tagów `< access >` , jak to:\n\n    <!-- Allow images, xhrs, etc. to google.com -->\n    <access origin=\"http://google.com\" />\n    <access origin=\"https://google.com\" />\n    \n    <!-- Access to the subdomain maps.google.com -->\n    <access origin=\"http://maps.google.com\" />\n    \n    <!-- Access to all the subdomains on google.com -->\n    <access origin=\"http://*.google.com\" />\n    \n    <!-- Enable requests to content: URLs -->\n    <access origin=\"content:///*\" />\n    \n    <!-- Don't block any requests -->\n    <access origin=\"*\" />\n    \n\nBez żadnych tagów `< access >` dozwolone są tylko żądania do URLi `file://` . Jednak domyślnie Cordova aplikacja zawiera `< access origin = \"*\" >` domyślnie.\n\nCokół: Android pozwala również żądania do https://ssl.gstatic.com/accessibility/javascript/android/ domyślnie, ponieważ jest to wymagane dla TalkBack wobec funkcja poprawnie.\n\n### Zasady zabezpieczeń zawartości\n\nFormanty, które sieci żądań (obrazy, XHRs, itp.) mogą być wykonane (za pomocą widoku sieci Web bezpośrednio).\n\nNa Androida i iOS biała żądanie sieci (patrz wyżej) nie jest w stanie filtrować wszystkie rodzaje wniosków (np. `< video >` & WebSockets nie są zablokowane). Tak oprócz białej listy, należy użyć tagu `< meta >` [Treści polityki bezpieczeństwa](http://content-security-policy.com/) na wszystkich stronach.\n\nNa Android wsparcie dla CSP w ramach systemu widoku sieci Web zaczyna KitKat (ale jest dostępne we wszystkich wersjach przy użyciu widoku sieci Web przejście dla pieszych).\n\nOto niektóre przykład CSP deklaracje dla strony `HTML` :\n\n    <!-- Good default declaration:\n        * gap: is required only on iOS (when using UIWebView) and is needed for JS->native communication\n        * https://ssl.gstatic.com is required only on Android and is needed for TalkBack to function properly\n        * Disables use of eval() and inline scripts in order to mitigate risk of XSS vulnerabilities. To change this:\n            * Enable inline JS: add 'unsafe-inline' to default-src\n            * Enable eval(): add 'unsafe-eval' to default-src\n    -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self' data: gap: https://ssl.gstatic.com; style-src 'self' 'unsafe-inline'; media-src *\">\n    \n    <!-- Allow requests to foo.com -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self' foo.com\">\n    \n    <!-- Enable all requests, inline styles, and eval() -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'\">\n    \n    <!-- Allow XHRs via https only -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self' https:\">\n    \n    <!-- Allow iframe to https://cordova.apache.org/ -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self'; frame-src 'self' https://cordova.apache.org\">"
  },
  {
    "path": "plugins/cordova-plugin-whitelist/doc/zh/README.md",
    "content": "<!--\n# license: Licensed to the Apache Software Foundation (ASF) under one\n#         or more contributor license agreements.  See the NOTICE file\n#         distributed with this work for additional information\n#         regarding copyright ownership.  The ASF licenses this file\n#         to you under the Apache License, Version 2.0 (the\n#         \"License\"); you may not use this file except in compliance\n#         with the License.  You may obtain a copy of the License at\n#\n#           http://www.apache.org/licenses/LICENSE-2.0\n#\n#         Unless required by applicable law or agreed to in writing,\n#         software distributed under the License is distributed on an\n#         \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#         KIND, either express or implied.  See the License for the\n#         specific language governing permissions and limitations\n#         under the License.\n-->\n\n# cordova-plugin-whitelist\n\n這個外掛程式實現一個用於導航在科爾多瓦 4.0 應用程式 web 視圖的白名單策略\n\n## 支援的科爾多瓦平臺\n\n  * Android 4.0.0 或以上\n  * iOS 4.0.0 或以上\n\n## 導航白名單\n\n控制 web 視圖本身可以導航到的 Url。適用于頂級導航只。\n\n怪癖: 在 Android 上它也適用于 iframe 的非-結計畫。\n\n預設情況下，只有到`file://` Url 導航允許。若要允許其他其他 Url，必須將`<allow-navigation>`標籤添加到您的`config.xml`:\n\n    <!-- Allow links to example.com -->\n    <allow-navigation href=\"http://example.com/*\" />\n    \n    <!-- Wildcards are allowed for the protocol, as a prefix\n         to the host, or as a suffix to the path -->\n    <allow-navigation href=\"*://*.example.com/*\" />\n    \n    <!-- A wildcard can be used to whitelist the entire network,\n         over HTTP and HTTPS.\n         *NOT RECOMMENDED* -->\n    <allow-navigation href=\"*\" />\n    \n    <!-- The above is equivalent to these three declarations -->\n    <allow-navigation href=\"http://*/*\" />\n    <allow-navigation href=\"https://*/*\" />\n    <allow-navigation href=\"data:*\" />\n    \n\n## 科爾多瓦-外掛程式-白名單\n\n控制應用程式允許讓系統打開的 Url。 預設情況下，沒有外部 Url 允許。\n\n在 android 系統，這相當於發送類型 BROWSEABLE 的意圖。\n\n此白名單並不適用于只超連結和對`window.open ()`調用的外掛程式.\n\n在`config.xml`中添加`<allow-intent>`標籤，像這樣:\n\n    <!-- Allow links to web pages to open in a browser -->\n    <allow-intent href=\"http://*/*\" />\n    <allow-intent href=\"https://*/*\" />\n    \n    <!-- Allow links to example.com to open in a browser -->\n    <allow-intent href=\"http://example.com/*\" />\n    \n    <!-- Wildcards are allowed for the protocol, as a prefix\n         to the host, or as a suffix to the path -->\n    <allow-intent href=\"*://*.example.com/*\" />\n    \n    <!-- Allow SMS links to open messaging app -->\n    <allow-intent href=\"sms:*\" />\n    \n    <!-- Allow tel: links to open the dialer -->\n    <allow-intent href=\"tel:*\" />\n    \n    <!-- Allow geo: links to open maps -->\n    <allow-intent href=\"geo:*\" />\n    \n    <!-- Allow all unrecognized URLs to open installed apps\n         *NOT RECOMMENDED* -->\n    <allow-intent href=\"*\" />\n    \n\n## 網路請求白名單\n\n網路請求的控制項 (圖像，XHRs 等) 允許 (通過科爾多瓦本機掛鉤)。\n\n注意: 我們建議你使用內容的安全性原則 (見下文)，這是更安全。 此白名單大多是為 webviews 不支援 CSP 的歷史。\n\n在`config.xml`中添加`<access>`標記，像這樣:\n\n    <!-- Allow images, xhrs, etc. to google.com -->\n    <access origin=\"http://google.com\" />\n    <access origin=\"https://google.com\" />\n    \n    <!-- Access to the subdomain maps.google.com -->\n    <access origin=\"http://maps.google.com\" />\n    \n    <!-- Access to all the subdomains on google.com -->\n    <access origin=\"http://*.google.com\" />\n    \n    <!-- Enable requests to content: URLs -->\n    <access origin=\"content:///*\" />\n    \n    <!-- Don't block any requests -->\n    <access origin=\"*\" />\n    \n\n沒有任何`<access>`標籤，只到`file://` Url 允許請求。 但是，預設的科爾多瓦應用程式包括`<access origin=\"*\">` ，預設情況。\n\n怪癖: Android 還允許對 HTTPs://ssl.gstatic.com/accessibility/javascript/android/ 請求預設情況下，因為這是對講正常所需。\n\n### 內容安全政策\n\n網路請求的控制項 (圖像，XHRs 等) 允許 (通過 web 視圖直接)。\n\n對 Android 和 iOS，網路請求白名單 (見上文) 是不能夠過濾所有類型的請求 (例如`<video>` & Websocket 未被阻止)。 那麼，除了白名單中，你應使用[內容安全性原則](http://content-security-policy.com/) `< 元 >`標記您的所有頁面。\n\n在 android 系統，對 CSP 系統 web 視圖的支援開始奇巧 (但是是上使用 web 視圖人行橫道上的所有版本可用)。\n\n下面是一些示例 CSP 聲明為`.html`頁面:\n\n    <!-- Good default declaration:\n        * gap: is required only on iOS (when using UIWebView) and is needed for JS->native communication\n        * https://ssl.gstatic.com is required only on Android and is needed for TalkBack to function properly\n        * Disables use of eval() and inline scripts in order to mitigate risk of XSS vulnerabilities. To change this:\n            * Enable inline JS: add 'unsafe-inline' to default-src\n            * Enable eval(): add 'unsafe-eval' to default-src\n    -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self' data: gap: https://ssl.gstatic.com; style-src 'self' 'unsafe-inline'; media-src *\">\n    \n    <!-- Allow requests to foo.com -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self' foo.com\">\n    \n    <!-- Enable all requests, inline styles, and eval() -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'\">\n    \n    <!-- Allow XHRs via https only -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self' https:\">\n    \n    <!-- Allow iframe to https://cordova.apache.org/ -->\n    <meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self'; frame-src 'self' https://cordova.apache.org\">"
  },
  {
    "path": "plugins/cordova-plugin-whitelist/package.json",
    "content": "{\n  \"name\": \"cordova-plugin-whitelist\",\n  \"version\": \"1.2.2\",\n  \"description\": \"Cordova Whitelist Plugin\",\n  \"cordova\": {\n    \"platforms\": [\n      \"android\"\n    ]\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/apache/cordova-plugin-whitelist\"\n  },\n  \"keywords\": [\n    \"cordova\",\n    \"whitelist\",\n    \"ecosystem:cordova\",\n    \"cordova-android\"\n  ],\n  \"engines\": [\n    {\n      \"name\": \"cordova-android\",\n      \"version\": \">=4.0.0\"\n    }\n  ],\n  \"author\": \"Apache Software Foundation\",\n  \"license\": \"Apache 2.0\"\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-whitelist/plugin.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  Licensed to the Apache Software Foundation (ASF) under one\n  or more contributor license agreements.  See the NOTICE file\n  distributed with this work for additional information\n  regarding copyright ownership.  The ASF licenses this file\n  to you under the Apache License, Version 2.0 (the\n  \"License\"); you may not use this file except in compliance\n  with the License.  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing,\n  software distributed under the License is distributed on an\n  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n  KIND, either express or implied.  See the License for the\n  specific language governing permissions and limitations\n  under the License.\n-->\n\n<plugin xmlns=\"http://apache.org/cordova/ns/plugins/1.0\"\n           id=\"cordova-plugin-whitelist\"\n      version=\"1.2.2\">\n    <name>Whitelist</name>\n    <description>Cordova Network Whitelist Plugin</description>\n    <license>Apache 2.0</license>\n    <keywords>cordova,whitelist,policy</keywords>\n\n    <engines>\n      <engine name=\"cordova-android\" version=\">=4.0.0\" />\n    </engines>\n\n    <platform name=\"android\">\n        <config-file target=\"res/xml/config.xml\" parent=\"/*\">\n            <feature name=\"Whitelist\" >\n                <param name=\"android-package\" value=\"org.apache.cordova.whitelist.WhitelistPlugin\"/>\n                <param name=\"onload\" value=\"true\" />\n            </feature>\n        </config-file>\n\n        <source-file src=\"src/android/WhitelistPlugin.java\" target-dir=\"src/org/apache/cordova/whitelist\" />\n\n        \t<info>\n               This plugin is only applicable for versions of cordova-android greater than 4.0. If you have a previous platform version, you do *not* need this plugin since the whitelist will be built in.\n          </info>\n    </platform>\n\t\n\n\n</plugin>\n"
  },
  {
    "path": "plugins/cordova-plugin-whitelist/src/android/WhitelistPlugin.java",
    "content": "/*\n       Licensed to the Apache Software Foundation (ASF) under one\n       or more contributor license agreements.  See the NOTICE file\n       distributed with this work for additional information\n       regarding copyright ownership.  The ASF licenses this file\n       to you under the Apache License, Version 2.0 (the\n       \"License\"); you may not use this file except in compliance\n       with the License.  You may obtain a copy of the License at\n\n         http://www.apache.org/licenses/LICENSE-2.0\n\n       Unless required by applicable law or agreed to in writing,\n       software distributed under the License is distributed on an\n       \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n       KIND, either express or implied.  See the License for the\n       specific language governing permissions and limitations\n       under the License.\n*/\n\npackage org.apache.cordova.whitelist;\n\nimport org.apache.cordova.CordovaPlugin;\nimport org.apache.cordova.ConfigXmlParser;\nimport org.apache.cordova.Whitelist;\nimport org.xmlpull.v1.XmlPullParser;\n\nimport android.content.Context;\nimport android.util.Log;\n\npublic class WhitelistPlugin extends CordovaPlugin {\n    private static final String LOG_TAG = \"WhitelistPlugin\";\n    private Whitelist allowedNavigations;\n    private Whitelist allowedIntents;\n    private Whitelist allowedRequests;\n\n    // Used when instantiated via reflection by PluginManager\n    public WhitelistPlugin() {\n    }\n    // These can be used by embedders to allow Java-configuration of whitelists.\n    public WhitelistPlugin(Context context) {\n        this(new Whitelist(), new Whitelist(), null);\n        new CustomConfigXmlParser().parse(context);\n    }\n    public WhitelistPlugin(XmlPullParser xmlParser) {\n        this(new Whitelist(), new Whitelist(), null);\n        new CustomConfigXmlParser().parse(xmlParser);\n    }\n    public WhitelistPlugin(Whitelist allowedNavigations, Whitelist allowedIntents, Whitelist allowedRequests) {\n        if (allowedRequests == null) {\n            allowedRequests = new Whitelist();\n            allowedRequests.addWhiteListEntry(\"file:///*\", false);\n            allowedRequests.addWhiteListEntry(\"data:*\", false);\n        }\n        this.allowedNavigations = allowedNavigations;\n        this.allowedIntents = allowedIntents;\n        this.allowedRequests = allowedRequests;\n    }\n    @Override\n    public void pluginInitialize() {\n        if (allowedNavigations == null) {\n            allowedNavigations = new Whitelist();\n            allowedIntents = new Whitelist();\n            allowedRequests = new Whitelist();\n            new CustomConfigXmlParser().parse(webView.getContext());\n        }\n    }\n\n    private class CustomConfigXmlParser extends ConfigXmlParser {\n        @Override\n        public void handleStartTag(XmlPullParser xml) {\n            String strNode = xml.getName();\n            if (strNode.equals(\"content\")) {\n                String startPage = xml.getAttributeValue(null, \"src\");\n                allowedNavigations.addWhiteListEntry(startPage, false);\n            } else if (strNode.equals(\"allow-navigation\")) {\n                String origin = xml.getAttributeValue(null, \"href\");\n                if (\"*\".equals(origin)) {\n                    allowedNavigations.addWhiteListEntry(\"http://*/*\", false);\n                    allowedNavigations.addWhiteListEntry(\"https://*/*\", false);\n                    allowedNavigations.addWhiteListEntry(\"data:*\", false);\n                } else {\n                    allowedNavigations.addWhiteListEntry(origin, false);\n                }\n            } else if (strNode.equals(\"allow-intent\")) {\n                String origin = xml.getAttributeValue(null, \"href\");\n                allowedIntents.addWhiteListEntry(origin, false);\n            } else if (strNode.equals(\"access\")) {\n                String origin = xml.getAttributeValue(null, \"origin\");\n                String subdomains = xml.getAttributeValue(null, \"subdomains\");\n                boolean external = (xml.getAttributeValue(null, \"launch-external\") != null);\n                if (origin != null) {\n                    if (external) {\n                        Log.w(LOG_TAG, \"Found <access launch-external> within config.xml. Please use <allow-intent> instead.\");\n                        allowedIntents.addWhiteListEntry(origin, (subdomains != null) && (subdomains.compareToIgnoreCase(\"true\") == 0));\n                    } else {\n                        if (\"*\".equals(origin)) {\n                            allowedRequests.addWhiteListEntry(\"http://*/*\", false);\n                            allowedRequests.addWhiteListEntry(\"https://*/*\", false);\n                        } else {\n                            allowedRequests.addWhiteListEntry(origin, (subdomains != null) && (subdomains.compareToIgnoreCase(\"true\") == 0));\n                        }\n                    }\n                }\n            }\n        }\n        @Override\n        public void handleEndTag(XmlPullParser xml) {\n        }\n    }\n\n    @Override\n    public Boolean shouldAllowNavigation(String url) {\n        if (allowedNavigations.isUrlWhiteListed(url)) {\n            return true;\n        }\n        return null; // Default policy\n    }\n\n    @Override\n    public Boolean shouldAllowRequest(String url) {\n        if (Boolean.TRUE == shouldAllowNavigation(url)) {\n            return true;\n        }\n        if (allowedRequests.isUrlWhiteListed(url)) {\n            return true;\n        }\n        return null; // Default policy\n    }\n\n    @Override\n    public Boolean shouldOpenExternalUrl(String url) {\n        if (allowedIntents.isUrlWhiteListed(url)) {\n            return true;\n        }\n        return null; // Default policy\n    }\n\n    public Whitelist getAllowedNavigations() {\n        return allowedNavigations;\n    }\n\n    public void setAllowedNavigations(Whitelist allowedNavigations) {\n        this.allowedNavigations = allowedNavigations;\n    }\n\n    public Whitelist getAllowedIntents() {\n        return allowedIntents;\n    }\n\n    public void setAllowedIntents(Whitelist allowedIntents) {\n        this.allowedIntents = allowedIntents;\n    }\n\n    public Whitelist getAllowedRequests() {\n        return allowedRequests;\n    }\n\n    public void setAllowedRequests(Whitelist allowedRequests) {\n        this.allowedRequests = allowedRequests;\n    }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-zip/CONTRIBUTING.md",
    "content": "# Contributing to this Repository\n\nThank you for your interest in contributing!\n\nUnfortunately there are some legal hurdles. Sorry about that.\n\nThis repository is a Google open source project, and so we require contributors to sign Google's open source Contributor License Agreement.\nIt's easy to do, just click here to sign as an [individual](https://developers.google.com/open-source/cla/individual) or [corporation](https://developers.google.com/open-source/cla/corporate).\nIndividuals can sign electronically in seconds (see the bottom of the page); corporations will need to email a PDF, or mail.\n\nWe cannot accept PRs or patches larger than fixing typos and the like without a signed CLA.\n\nIf your Github account doesn't show the name your used to sign, please mention your name in your PR.\n"
  },
  {
    "path": "plugins/cordova-plugin-zip/LICENSE",
    "content": "Copyright (c) 2014 The Chromium Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n   * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n================================================================================\nSSZipArchive (iOS)\n================================================================================\nCopyright (c) 2010-2015, Sam Soffes, http://soff.es\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n================================================================================\nMinizip (iOS)\n================================================================================\nCopyright (C) 1995-2013 Jean-loup Gailly and Mark Adler\n\nThis software is provided 'as-is', without any express or implied\nwarranty.  In no event will the authors be held liable for any damages\narising from the use of this software.\n\nPermission is granted to anyone to use this software for any purpose,\nincluding commercial applications, and to alter it and redistribute it\nfreely, subject to the following restrictions:\n\n1. The origin of this software must not be misrepresented; you must not\n   claim that you wrote the original software. If you use this software\n   in a product, an acknowledgment in the product documentation would be\n   appreciated but is not required.\n2. Altered source versions must be plainly marked as such, and must not be\n   misrepresented as being the original software.\n3. This notice may not be removed or altered from any source distribution.\n\nJean-loup Gailly        Mark Adler\njloup@gzip.org          madler@alumni.caltech.edu\n\n\n"
  },
  {
    "path": "plugins/cordova-plugin-zip/README.md",
    "content": "# cordova-plugin-zip\n\nA Cordova plugin to unzip files in Android and iOS.\n\n## Installation\n\n    cordova plugin add cordova-plugin-zip\n\n## Usage\n\n    zip.unzip(<source zip>, <destination dir>, <callback>, [<progressCallback>]);\n\nBoth source and destination arguments can be URLs obtained from the HTML File\ninterface or absolute paths to files on the device.\n\nThe callback argument will be executed when the unzip is complete, or when an\nerror occurs. It will be called with a single argument, which will be 0 on\nsuccess, or -1 on failure.\n\nThe progressCallback argument is optional and will be executed whenever a new ZipEntry\nhas been extracted. E.g.:\n\n    var progressCallback = function(progressEvent) {\n        $( \"#progressbar\" ).progressbar(\"value\", Math.round((progressEvent.loaded / progressEvent.total) * 100));\n    };\n\nThe values `loaded` and `total` are the number of compressed bytes processed and total. Total is the\nfile size of the zip file.\n\n## Release Notes\n\n### 3.1.0 (Feb 23, 2016)\n* Updated SSZipArchive (ios lib) to 1.1\n\n### 3.0.0 (May 1, 2015)\n* Updated SSZipArchive (ios lib) to 0.2.1\n* Update file plugin dependency to use npm version (cordova-plugin-file)\n\n### 2.1.0 (May 1, 2014)\n* Added progress events\n* Fix iOS path handling when given file: URLs as src/target\n"
  },
  {
    "path": "plugins/cordova-plugin-zip/package.json",
    "content": "{\n  \"name\": \"cordova-plugin-zip\",\n  \"version\": \"3.1.0\",\n  \"description\": \"Unzips zip files\",\n  \"cordova\": {\n    \"id\": \"cordova-plugin-unzip\",\n    \"platforms\": [\n      \"android\",\n      \"ios\"\n    ]\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/MobileChromeApps/cordova-plugin-zip.git\"\n  },\n  \"keywords\": [\n    \"ecosystem:cordova\",\n    \"cordova-android\",\n    \"cordova-ios\"\n  ],\n  \"engines\": [\n    {\n      \"name\": \"cordova\",\n      \"version\": \">=3.3.0\"\n    }\n  ],\n  \"author\": \"\",\n  \"license\": \"BSD\",\n  \"bugs\": {\n    \"url\": \"https://github.com/MobileChromeApps/zip/issues\"\n  },\n  \"homepage\": \"https://github.com/MobileChromeApps/zip\"\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-zip/plugin.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<plugin xmlns=\"http://phonegap.com/ns/plugins/1.0\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    id=\"cordova-plugin-zip\"\n    version=\"3.1.0\">\n  <engines>\n    <engine name=\"cordova\" version=\">=3.3.0\" />\n  </engines>\n  <dependency id=\"cordova-plugin-file\" version=\">=2.0.0\" />\n\n  <name>cordova-plugin-zip</name>\n  <description>Unzips zip files</description>\n\n  <js-module src=\"zip.js\" name=\"Zip\">\n    <clobbers target=\"zip\" />\n  </js-module>\n\n  <platform name=\"android\">\n    <source-file src=\"src/android/Zip.java\" target-dir=\"src/org/apache/cordova\" />\n\n    <config-file target=\"res/xml/config.xml\" parent=\"/widget\">\n      <feature name=\"Zip\">\n        <param name=\"android-package\" value=\"org.apache.cordova.Zip\"/>\n      </feature>\n    </config-file>\n  </platform>\n\n  <platform name=\"ios\">\n    <source-file src=\"src/ios/ZipPlugin.m\" />\n    <header-file src=\"src/ios/ZipPlugin.h\" />\n    <header-file src=\"src/ios/Common.h\" />\n    <header-file src=\"src/ios/aes/aes.h\" target-dir=\"Plugins/aes\" />\n    <header-file src=\"src/ios/aes/aes_via_ace.h\" target-dir=\"Plugins/aes\" />\n    <source-file src=\"src/ios/aes/aescrypt.c\" target-dir=\"Plugins/aes\" />\n    <source-file src=\"src/ios/aes/aeskey.c\" target-dir=\"Plugins/aes\" />\n    <header-file src=\"src/ios/aes/aesopt.h\" target-dir=\"Plugins/aes\" />\n    <source-file src=\"src/ios/aes/aestab.c\" target-dir=\"Plugins/aes\" />\n    <header-file src=\"src/ios/aes/aestab.h\" target-dir=\"Plugins/aes\" />\n    <header-file src=\"src/ios/aes/brg_endian.h\" target-dir=\"Plugins/aes\" />\n    <header-file src=\"src/ios/aes/brg_types.h\" target-dir=\"Plugins/aes\" />\n    <source-file src=\"src/ios/aes/entropy.c\" target-dir=\"Plugins/aes\" />\n    <header-file src=\"src/ios/aes/entropy.h\" target-dir=\"Plugins/aes\" />\n    <source-file src=\"src/ios/aes/fileenc.c\" target-dir=\"Plugins/aes\" />\n    <header-file src=\"src/ios/aes/fileenc.h\" target-dir=\"Plugins/aes\" />\n    <source-file src=\"src/ios/aes/hmac.c\" target-dir=\"Plugins/aes\" />\n    <header-file src=\"src/ios/aes/hmac.h\" target-dir=\"Plugins/aes\" />\n    <source-file src=\"src/ios/aes/prng.c\" target-dir=\"Plugins/aes\" />\n    <header-file src=\"src/ios/aes/prng.h\" target-dir=\"Plugins/aes\" />\n    <source-file src=\"src/ios/aes/pwd2key.c\" target-dir=\"Plugins/aes\" />\n    <header-file src=\"src/ios/aes/pwd2key.h\" target-dir=\"Plugins/aes\" />\n    <source-file src=\"src/ios/aes/sha1.c\" target-dir=\"Plugins/aes\" />\n    <header-file src=\"src/ios/aes/sha1.h\" target-dir=\"Plugins/aes\" />\n    <source-file src=\"src/ios/SSZipArchive.m\" target-dir=\"Plugins/minizip\" />\n    <header-file src=\"src/ios/SSZipArchive.h\" target-dir=\"Plugins/minizip\" />\n    <source-file src=\"src/ios/minizip/zip.c\" target-dir=\"Plugins/minizip\" />\n    <header-file src=\"src/ios/minizip/zip.h\" target-dir=\"Plugins/minizip\" />\n    <source-file src=\"src/ios/minizip/unzip.c\" target-dir=\"Plugins/minizip\" />\n    <header-file src=\"src/ios/minizip/unzip.h\" target-dir=\"Plugins/minizip\" />\n    <source-file src=\"src/ios/minizip/mztools.c\" target-dir=\"Plugins/minizip\" />\n    <header-file src=\"src/ios/minizip/mztools.h\" target-dir=\"Plugins/minizip\" />\n    <source-file src=\"src/ios/minizip/ioapi.c\" target-dir=\"Plugins/minizip\" />\n    <header-file src=\"src/ios/minizip/ioapi.h\" target-dir=\"Plugins/minizip\" />\n    <header-file src=\"src/ios/minizip/crypt.h\" target-dir=\"Plugins/minizip\" />\n\n    <config-file target=\"config.xml\" parent=\"/widget\">\n      <feature name=\"Zip\">\n        <param name=\"ios-package\" value=\"ZipPlugin\"/>\n      </feature>\n    </config-file>\n    <framework src=\"libz.dylib\" />\n  </platform>\n</plugin>\n"
  },
  {
    "path": "plugins/cordova-plugin-zip/src/android/Zip.java",
    "content": "package org.apache.cordova;\n\nimport java.io.BufferedInputStream;\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.FileNotFoundException;\nimport java.util.zip.ZipEntry;\nimport java.util.zip.ZipInputStream;\n\n\nimport android.net.Uri;\nimport org.apache.cordova.CallbackContext;\nimport org.apache.cordova.CordovaPlugin;\nimport org.apache.cordova.CordovaResourceApi.OpenForReadResult;\nimport org.apache.cordova.PluginResult;\nimport org.json.JSONException;\nimport org.json.JSONObject;\n\nimport android.util.Log;\n\npublic class Zip extends CordovaPlugin {\n\n    private static final String LOG_TAG = \"Zip\";\n\n    @Override\n    public boolean execute(String action, CordovaArgs args, final CallbackContext callbackContext) throws JSONException {\n        if (\"unzip\".equals(action)) {\n            unzip(args, callbackContext);\n            return true;\n        }\n        return false;\n    }\n\n    private void unzip(final CordovaArgs args, final CallbackContext callbackContext) {\n        this.cordova.getThreadPool().execute(new Runnable() {\n            public void run() {\n                unzipSync(args, callbackContext);\n            }\n        });\n    }\n\n    // Can't use DataInputStream because it has the wrong endian-ness.\n    private static int readInt(InputStream is) throws IOException {\n        int a = is.read();\n        int b = is.read();\n        int c = is.read();\n        int d = is.read();\n        return a | b << 8 | c << 16 | d << 24;\n    }\n\n    private void unzipSync(CordovaArgs args, CallbackContext callbackContext) {\n        InputStream inputStream = null;\n        try {\n            String zipFileName = args.getString(0);\n            String outputDirectory = args.getString(1);\n\n            // Since Cordova 3.3.0 and release of File plugins, files are accessed via cdvfile://\n            // Accept a path or a URI for the source zip.\n            Uri zipUri = getUriForArg(zipFileName);\n            Uri outputUri = getUriForArg(outputDirectory);\n\n            CordovaResourceApi resourceApi = webView.getResourceApi();\n\n            File tempFile = resourceApi.mapUriToFile(zipUri);\n            if (tempFile == null || !tempFile.exists()) {\n                String errorMessage = \"Zip file does not exist\";\n                callbackContext.error(errorMessage);\n                Log.e(LOG_TAG, errorMessage);\n                return;\n            }\n\n            File outputDir = resourceApi.mapUriToFile(outputUri);\n            outputDirectory = outputDir.getAbsolutePath();\n            outputDirectory += outputDirectory.endsWith(File.separator) ? \"\" : File.separator;\n            if (outputDir == null || (!outputDir.exists() && !outputDir.mkdirs())){\n                String errorMessage = \"Could not create output directory\";\n                callbackContext.error(errorMessage);\n                Log.e(LOG_TAG, errorMessage);\n                return;\n            }\n\n            OpenForReadResult zipFile = resourceApi.openForRead(zipUri);\n            ProgressEvent progress = new ProgressEvent();\n            progress.setTotal(zipFile.length);\n\n            inputStream = new BufferedInputStream(zipFile.inputStream);\n            inputStream.mark(10);\n            int magic = readInt(inputStream);\n\n            if (magic != 875721283) { // CRX identifier\n                inputStream.reset();\n            } else {\n                // CRX files contain a header. This header consists of:\n                //  * 4 bytes of magic number\n                //  * 4 bytes of CRX format version,\n                //  * 4 bytes of public key length\n                //  * 4 bytes of signature length\n                //  * the public key\n                //  * the signature\n                // and then the ordinary zip data follows. We skip over the header before creating the ZipInputStream.\n                readInt(inputStream); // version == 2.\n                int pubkeyLength = readInt(inputStream);\n                int signatureLength = readInt(inputStream);\n\n                inputStream.skip(pubkeyLength + signatureLength);\n                progress.setLoaded(16 + pubkeyLength + signatureLength);\n            }\n\n            // The inputstream is now pointing at the start of the actual zip file content.\n            ZipInputStream zis = new ZipInputStream(inputStream);\n            inputStream = zis;\n\n            ZipEntry ze;\n            byte[] buffer = new byte[32 * 1024];\n            boolean anyEntries = false;\n\n            while ((ze = zis.getNextEntry()) != null)\n            {\n                anyEntries = true;\n                String compressedName = ze.getName();\n\n                if (ze.isDirectory()) {\n                   File dir = new File(outputDirectory + compressedName);\n                   dir.mkdirs();\n                } else {\n                    File file = new File(outputDirectory + compressedName);\n                    file.getParentFile().mkdirs();\n                    if(file.exists() || file.createNewFile()){\n                        Log.w(\"Zip\", \"extracting: \" + file.getPath());\n                        FileOutputStream fout = new FileOutputStream(file);\n                        int count;\n                        while ((count = zis.read(buffer)) != -1)\n                        {\n                            fout.write(buffer, 0, count);\n                        }\n                        fout.close();\n                    }\n\n                }\n                progress.addLoaded(ze.getCompressedSize());\n                updateProgress(callbackContext, progress);\n                zis.closeEntry();\n            }\n\n            // final progress = 100%\n            progress.setLoaded(progress.getTotal());\n            updateProgress(callbackContext, progress);\n\n            if (anyEntries)\n                callbackContext.success();\n            else\n                callbackContext.error(\"Bad zip file\");\n        } catch (Exception e) {\n            String errorMessage = \"An error occurred while unzipping.\";\n            callbackContext.error(errorMessage);\n            Log.e(LOG_TAG, errorMessage, e);\n        } finally {\n            if (inputStream != null) {\n                try {\n                    inputStream.close();\n                } catch (IOException e) {\n                }\n            }\n        }\n    }\n\n    private void updateProgress(CallbackContext callbackContext, ProgressEvent progress) throws JSONException {\n        PluginResult pluginResult = new PluginResult(PluginResult.Status.OK, progress.toJSONObject());\n        pluginResult.setKeepCallback(true);\n        callbackContext.sendPluginResult(pluginResult);\n    }\n\n    private Uri getUriForArg(String arg) {\n        CordovaResourceApi resourceApi = webView.getResourceApi();\n        Uri tmpTarget = Uri.parse(arg);\n        return resourceApi.remapUri(\n                tmpTarget.getScheme() != null ? tmpTarget : Uri.fromFile(new File(arg)));\n    }\n\n    private static class ProgressEvent {\n        private long loaded;\n        private long total;\n        public long getLoaded() {\n            return loaded;\n        }\n        public void setLoaded(long loaded) {\n            this.loaded = loaded;\n        }\n        public void addLoaded(long add) {\n            this.loaded += add;\n        }\n        public long getTotal() {\n            return total;\n        }\n        public void setTotal(long total) {\n            this.total = total;\n        }\n        public JSONObject toJSONObject() throws JSONException {\n            return new JSONObject(\n                    \"{loaded:\" + loaded +\n                    \",total:\" + total + \"}\");\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-zip/src/ios/Common.h",
    "content": "#ifndef SSZipCommon\n#define SSZipCommon\n\n/* tm_unz contain date/time info */\ntypedef struct tm_unz_s\n{\n    unsigned int tm_sec;            /* seconds after the minute - [0,59] */\n    unsigned int tm_min;            /* minutes after the hour - [0,59] */\n    unsigned int tm_hour;           /* hours since midnight - [0,23] */\n    unsigned int tm_mday;           /* day of the month - [1,31] */\n    unsigned int tm_mon;            /* months since January - [0,11] */\n    unsigned int tm_year;           /* years - [1980..2044] */\n} tm_unz;\n\ntypedef struct unz_file_info_s\n{\n    unsigned long version;              /* version made by                 2 bytes */\n    unsigned long version_needed;       /* version needed to extract       2 bytes */\n    unsigned long flag;                 /* general purpose bit flag        2 bytes */\n    unsigned long compression_method;   /* compression method              2 bytes */\n    unsigned long dosDate;              /* last mod file date in Dos fmt   4 bytes */\n    unsigned long crc;                  /* crc-32                          4 bytes */\n    unsigned long compressed_size;      /* compressed size                 4 bytes */\n    unsigned long uncompressed_size;    /* uncompressed size               4 bytes */\n    unsigned long size_filename;        /* filename length                 2 bytes */\n    unsigned long size_file_extra;      /* extra field length              2 bytes */\n    unsigned long size_file_comment;    /* file comment length             2 bytes */\n\n    unsigned long disk_num_start;       /* disk number start               2 bytes */\n    unsigned long internal_fa;          /* internal file attributes        2 bytes */\n    unsigned long external_fa;          /* external file attributes        4 bytes */\n\n    tm_unz tmu_date;\n} unz_file_info;\n\n/* unz_file_info contain information about a file in the zipfile */\ntypedef struct unz_file_info64_s\n{\n    unsigned long version;              /* version made by                 2 bytes */\n    unsigned long version_needed;       /* version needed to extract       2 bytes */\n    unsigned long flag;                 /* general purpose bit flag        2 bytes */\n    unsigned long compression_method;   /* compression method              2 bytes */\n    unsigned long dosDate;              /* last mod file date in Dos fmt   4 bytes */\n    unsigned long crc;                  /* crc-32                          4 bytes */\n    unsigned long long compressed_size;   /* compressed size                 8 bytes */\n    unsigned long long uncompressed_size; /* uncompressed size               8 bytes */\n    unsigned long size_filename;        /* filename length                 2 bytes */\n    unsigned long size_file_extra;      /* extra field length              2 bytes */\n    unsigned long size_file_comment;    /* file comment length             2 bytes */\n    \n    unsigned long disk_num_start;       /* disk number start               2 bytes */\n    unsigned long internal_fa;          /* internal file attributes        2 bytes */\n    unsigned long external_fa;          /* external file attributes        4 bytes */\n    \n    tm_unz tmu_date;\n    unsigned long long disk_offset;\n    unsigned long size_file_extra_internal;\n} unz_file_info64;\n\ntypedef struct unz_global_info_s\n{\n    unsigned long number_entry;         /* total number of entries in\n                                         the central dir on this disk */\n    \n    unsigned long number_disk_with_CD;  /* number the the disk with central dir, used for spanning ZIP*/\n\n    \n    unsigned long size_comment;         /* size of the global comment of the zipfile */\n} unz_global_info;\n\ntypedef struct unz_global_info64\n{\n    unsigned long long number_entry;         /* total number of entries in\n                                 the central dir on this disk */\n    \n     unsigned long number_disk_with_CD;  /* number the the disk with central dir, used for spanning ZIP*/\n    \n    unsigned long size_comment;         /* size of the global comment of the zipfile */\n} unz_global_info64;\n\n#endif"
  },
  {
    "path": "plugins/cordova-plugin-zip/src/ios/SSZipArchive.h",
    "content": "//\n//  SSZipArchive.h\n//  SSZipArchive\n//\n//  Created by Sam Soffes on 7/21/10.\n//  Copyright (c) Sam Soffes 2010-2015. All rights reserved.\n//\n\n#ifndef _SSZIPARCHIVE_H\n#define _SSZIPARCHIVE_H\n\n#import <Foundation/Foundation.h>\n#include \"Common.h\"\n\n@protocol SSZipArchiveDelegate;\n\n@interface SSZipArchive : NSObject\n\n// Unzip\n+ (BOOL)unzipFileAtPath:(NSString *)path toDestination:(NSString *)destination;\n+ (BOOL)unzipFileAtPath:(NSString *)path toDestination:(NSString *)destination delegate:(id<SSZipArchiveDelegate>)delegate;\n\n+ (BOOL)unzipFileAtPath:(NSString *)path toDestination:(NSString *)destination overwrite:(BOOL)overwrite password:(NSString *)password error:(NSError * *)error;\n+ (BOOL)unzipFileAtPath:(NSString *)path toDestination:(NSString *)destination overwrite:(BOOL)overwrite password:(NSString *)password error:(NSError * *)error delegate:(id<SSZipArchiveDelegate>)delegate;\n\n+ (BOOL)unzipFileAtPath:(NSString *)path\n    toDestination:(NSString *)destination\n    progressHandler:(void (^)(NSString *entry, unz_file_info zipInfo, long entryNumber, long total))progressHandler\n    completionHandler:(void (^)(NSString *path, BOOL succeeded, NSError *error))completionHandler;\n\n+ (BOOL)unzipFileAtPath:(NSString *)path\n    toDestination:(NSString *)destination\n    overwrite:(BOOL)overwrite\n    password:(NSString *)password\n    progressHandler:(void (^)(NSString *entry, unz_file_info zipInfo, long entryNumber, long total))progressHandler\n    completionHandler:(void (^)(NSString *path, BOOL succeeded, NSError *error))completionHandler;\n\n// Zip\n\n// without password\n+ (BOOL)createZipFileAtPath:(NSString *)path withFilesAtPaths:(NSArray *)paths;\n+ (BOOL)createZipFileAtPath:(NSString *)path withContentsOfDirectory:(NSString *)directoryPath;\n+ (BOOL)createZipFileAtPath:(NSString *)path withContentsOfDirectory:(NSString *)directoryPath keepParentDirectory:(BOOL)keepParentDirector;\n\n// with password, password could be nil\n+ (BOOL)createZipFileAtPath:(NSString *)path withFilesAtPaths:(NSArray *)paths withPassword:(NSString *)password;\n+ (BOOL)createZipFileAtPath:(NSString *)path withContentsOfDirectory:(NSString *)directoryPath withPassword:(NSString *)password;\n+ (BOOL)createZipFileAtPath:(NSString *)path withContentsOfDirectory:(NSString *)directoryPath keepParentDirectory:(BOOL)keepParentDirectory withPassword:(NSString *)password;\n\n- (instancetype)initWithPath:(NSString *)path;\n@property (NS_NONATOMIC_IOSONLY, readonly, getter = isOpen) BOOL open;\n- (BOOL)writeFile:(NSString *)path withPassword:(NSString *)password;\n- (BOOL)writeFolderAtPath:(NSString *)path withFolderName:(NSString *)folderName withPassword:(NSString *)password;\n- (BOOL)writeFileAtPath:(NSString *)path withFileName:(NSString *)fileName withPassword:(NSString *)password;\n- (BOOL)writeData:(NSData *)data filename:(NSString *)filename withPassword:(NSString *)password;\n@property (NS_NONATOMIC_IOSONLY, readonly, getter = isClosed) BOOL close;\n\n@end\n\n@protocol SSZipArchiveDelegate <NSObject>\n\n@optional\n\n- (void)zipArchiveWillUnzipArchiveAtPath:(NSString *)path zipInfo:(unz_global_info)zipInfo;\n- (void)zipArchiveDidUnzipArchiveAtPath:(NSString *)path zipInfo:(unz_global_info)zipInfo unzippedPath:(NSString *)unzippedPath;\n\n- (BOOL)zipArchiveShouldUnzipFileAtIndex:(NSInteger)fileIndex totalFiles:(NSInteger)totalFiles archivePath:(NSString *)archivePath fileInfo:(unz_file_info)fileInfo;\n- (void)zipArchiveWillUnzipFileAtIndex:(NSInteger)fileIndex totalFiles:(NSInteger)totalFiles archivePath:(NSString *)archivePath fileInfo:(unz_file_info)fileInfo;\n- (void)zipArchiveDidUnzipFileAtIndex:(NSInteger)fileIndex totalFiles:(NSInteger)totalFiles archivePath:(NSString *)archivePath fileInfo:(unz_file_info)fileInfo;\n- (void)zipArchiveDidUnzipFileAtIndex:(NSInteger)fileIndex totalFiles:(NSInteger)totalFiles archivePath:(NSString *)archivePath unzippedFilePath:(NSString *)unzippedFilePath;\n\n- (void)zipArchiveProgressEvent:(unsigned long long)loaded total:(unsigned long long)total;\n- (void)zipArchiveDidUnzipArchiveFile:(NSString *)zipFile entryPath:(NSString *)entryPath destPath:(NSString *)destPath;\n\n@end\n\n#endif /* _SSZIPARCHIVE_H */\n"
  },
  {
    "path": "plugins/cordova-plugin-zip/src/ios/SSZipArchive.m",
    "content": "//\n//  SSZipArchive.m\n//  SSZipArchive\n//\n//  Created by Sam Soffes on 7/21/10.\n//  Copyright (c) Sam Soffes 2010-2015. All rights reserved.\n//\n#import \"SSZipArchive.h\"\n#include \"unzip.h\"\n#include \"zip.h\"\n#import \"zlib.h\"\n#import \"zconf.h\"\n\n#include <sys/stat.h>\n\n#define CHUNK 16384\n\n@interface SSZipArchive ()\n+ (NSDate *)_dateWithMSDOSFormat:(UInt32)msdosDateTime;\n@end\n\n@implementation SSZipArchive\n{\n    NSString *_path;\n    NSString *_filename;\n    zipFile _zip;\n}\n\n#pragma mark - Unzipping\n\n+ (BOOL)unzipFileAtPath:(NSString *)path toDestination:(NSString *)destination\n{\n    return [self unzipFileAtPath:path toDestination:destination delegate:nil];\n}\n\n+ (BOOL)unzipFileAtPath:(NSString *)path toDestination:(NSString *)destination overwrite:(BOOL)overwrite password:(NSString *)password error:(NSError **)error\n{\n    return [self unzipFileAtPath:path toDestination:destination overwrite:overwrite password:password error:error delegate:nil progressHandler:nil completionHandler:nil];\n}\n\n+ (BOOL)unzipFileAtPath:(NSString *)path toDestination:(NSString *)destination delegate:(id<SSZipArchiveDelegate>)delegate\n{\n    return [self unzipFileAtPath:path toDestination:destination overwrite:YES password:nil error:nil delegate:delegate progressHandler:nil completionHandler:nil];\n}\n\n+ (BOOL)unzipFileAtPath:(NSString *)path toDestination:(NSString *)destination overwrite:(BOOL)overwrite password:(NSString *)password error:(NSError **)error delegate:(id<SSZipArchiveDelegate>)delegate\n{\n    return [self unzipFileAtPath:path toDestination:destination overwrite:overwrite password:password error:error delegate:delegate progressHandler:nil completionHandler:nil];\n}\n\n+ (BOOL)unzipFileAtPath:(NSString *)path\n          toDestination:(NSString *)destination\n              overwrite:(BOOL)overwrite\n               password:(NSString *)password\n        progressHandler:(void (^)(NSString *entry, unz_file_info zipInfo, long entryNumber, long total))progressHandler\n      completionHandler:(void (^)(NSString *path, BOOL succeeded, NSError *error))completionHandler\n{\n    return [self unzipFileAtPath:path toDestination:destination overwrite:overwrite password:password error:nil delegate:nil progressHandler:progressHandler completionHandler:completionHandler];\n}\n\n+ (BOOL)unzipFileAtPath:(NSString *)path\n          toDestination:(NSString *)destination\n        progressHandler:(void (^)(NSString *entry, unz_file_info zipInfo, long entryNumber, long total))progressHandler\n      completionHandler:(void (^)(NSString *path, BOOL succeeded, NSError *error))completionHandler\n{\n    return [self unzipFileAtPath:path toDestination:destination overwrite:YES password:nil error:nil delegate:nil progressHandler:progressHandler completionHandler:completionHandler];\n}\n\n+ (BOOL)unzipFileAtPath:(NSString *)path\n          toDestination:(NSString *)destination\n              overwrite:(BOOL)overwrite\n               password:(NSString *)password\n                  error:(NSError **)error\n               delegate:(id<SSZipArchiveDelegate>)delegate\n        progressHandler:(void (^)(NSString *entry, unz_file_info zipInfo, long entryNumber, long total))progressHandler\n      completionHandler:(void (^)(NSString *path, BOOL succeeded, NSError *error))completionHandler\n{\n    // Begin opening\n    zipFile zip = unzOpen((const char*)[path UTF8String]);\n    if (zip == NULL)\n    {\n        NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @\"failed to open zip file\"};\n        NSError *err = [NSError errorWithDomain:@\"SSZipArchiveErrorDomain\" code:-1 userInfo:userInfo];\n        if (error)\n        {\n            *error = err;\n        }\n        if (completionHandler)\n        {\n            completionHandler(nil, NO, err);\n        }\n        return NO;\n    }\n    \n    NSDictionary * fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:nil];\n    unsigned long long fileSize = [fileAttributes[NSFileSize] unsignedLongLongValue];\n    unsigned long long currentPosition = 0;\n    \n    unz_global_info  globalInfo = {0ul, 0ul};\n    unzGetGlobalInfo(zip, &globalInfo);\n    \n    // Begin unzipping\n    if (unzGoToFirstFile(zip) != UNZ_OK)\n    {\n        NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @\"failed to open first file in zip file\"};\n        NSError *err = [NSError errorWithDomain:@\"SSZipArchiveErrorDomain\" code:-2 userInfo:userInfo];\n        if (error)\n        {\n            *error = err;\n        }\n        if (completionHandler)\n        {\n            completionHandler(nil, NO, err);\n        }\n        return NO;\n    }\n    \n    BOOL success = YES;\n    BOOL canceled = NO;\n    int ret = 0;\n    int crc_ret =0;\n    unsigned char buffer[4096] = {0};\n    NSFileManager *fileManager = [NSFileManager defaultManager];\n    NSMutableSet *directoriesModificationDates = [[NSMutableSet alloc] init];\n    \n    // Message delegate\n    if ([delegate respondsToSelector:@selector(zipArchiveWillUnzipArchiveAtPath:zipInfo:)]) {\n        [delegate zipArchiveWillUnzipArchiveAtPath:path zipInfo:globalInfo];\n    }\n    if ([delegate respondsToSelector:@selector(zipArchiveProgressEvent:total:)]) {\n        [delegate zipArchiveProgressEvent:currentPosition total:fileSize];\n    }\n    \n    NSInteger currentFileNumber = 0;\n    do {\n        @autoreleasepool {\n            if ([password length] == 0) {\n                ret = unzOpenCurrentFile(zip);\n            } else {\n                ret = unzOpenCurrentFilePassword(zip, [password cStringUsingEncoding:NSASCIIStringEncoding]);\n            }\n            \n            if (ret != UNZ_OK) {\n                success = NO;\n                break;\n            }\n            \n            // Reading data and write to file\n            unz_file_info fileInfo;\n            memset(&fileInfo, 0, sizeof(unz_file_info));\n            \n            ret = unzGetCurrentFileInfo(zip, &fileInfo, NULL, 0, NULL, 0, NULL, 0);\n            if (ret != UNZ_OK) {\n                success = NO;\n                unzCloseCurrentFile(zip);\n                break;\n            }\n            \n            currentPosition += fileInfo.compressed_size;\n            \n            // Message delegate\n            if ([delegate respondsToSelector:@selector(zipArchiveShouldUnzipFileAtIndex:totalFiles:archivePath:fileInfo:)]) {\n                if (![delegate zipArchiveShouldUnzipFileAtIndex:currentFileNumber\n                                                     totalFiles:(NSInteger)globalInfo.number_entry\n                                                    archivePath:path fileInfo:fileInfo]) {\n                    success = NO;\n                    canceled = YES;\n                    break;\n                }\n            }\n            if ([delegate respondsToSelector:@selector(zipArchiveWillUnzipFileAtIndex:totalFiles:archivePath:fileInfo:)]) {\n                [delegate zipArchiveWillUnzipFileAtIndex:currentFileNumber totalFiles:(NSInteger)globalInfo.number_entry\n                                             archivePath:path fileInfo:fileInfo];\n            }\n            if ([delegate respondsToSelector:@selector(zipArchiveProgressEvent:total:)]) {\n                [delegate zipArchiveProgressEvent:(NSInteger)currentPosition total:(NSInteger)fileSize];\n            }\n            \n            char *filename = (char *)malloc(fileInfo.size_filename + 1);\n            if (filename == NULL)\n            {\n                return NO;\n            }\n            \n            unzGetCurrentFileInfo(zip, &fileInfo, filename, fileInfo.size_filename + 1, NULL, 0, NULL, 0);\n            filename[fileInfo.size_filename] = '\\0';\n            \n            //\n            // Determine whether this is a symbolic link:\n            // - File is stored with 'version made by' value of UNIX (3),\n            //   as per http://www.pkware.com/documents/casestudies/APPNOTE.TXT\n            //   in the upper byte of the version field.\n            // - BSD4.4 st_mode constants are stored in the high 16 bits of the\n            //   external file attributes (defacto standard, verified against libarchive)\n            //\n            // The original constants can be found here:\n            //    http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.4BSD/usr/include/sys/stat.h\n            //\n            const uLong ZipUNIXVersion = 3;\n            const uLong BSD_SFMT = 0170000;\n            const uLong BSD_IFLNK = 0120000;\n            \n            BOOL fileIsSymbolicLink = NO;\n            if (((fileInfo.version >> 8) == ZipUNIXVersion) && BSD_IFLNK == (BSD_SFMT & (fileInfo.external_fa >> 16))) {\n                fileIsSymbolicLink = NO;\n            }\n            \n            // Check if it contains directory\n            NSString *strPath = @(filename);\n            BOOL isDirectory = NO;\n            if (filename[fileInfo.size_filename-1] == '/' || filename[fileInfo.size_filename-1] == '\\\\') {\n                isDirectory = YES;\n            }\n            free(filename);\n            \n            // Contains a path\n            if ([strPath rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@\"/\\\\\"]].location != NSNotFound) {\n                strPath = [strPath stringByReplacingOccurrencesOfString:@\"\\\\\" withString:@\"/\"];\n            }\n            \n            NSString *fullPath = [destination stringByAppendingPathComponent:strPath];\n            NSError *err = nil;\n            NSDate *modDate = [[self class] _dateWithMSDOSFormat:(UInt32)fileInfo.dosDate];\n            NSDictionary *directoryAttr = @{NSFileCreationDate: modDate, NSFileModificationDate: modDate};\n            \n            if (isDirectory) {\n                [fileManager createDirectoryAtPath:fullPath withIntermediateDirectories:YES attributes:directoryAttr  error:&err];\n            } else {\n                [fileManager createDirectoryAtPath:[fullPath stringByDeletingLastPathComponent] withIntermediateDirectories:YES attributes:directoryAttr error:&err];\n            }\n            if (nil != err) {\n                NSLog(@\"[SSZipArchive] Error: %@\", err.localizedDescription);\n            }\n            \n            if(!fileIsSymbolicLink)\n                [directoriesModificationDates addObject: @{@\"path\": fullPath, @\"modDate\": modDate}];\n            \n            if ([fileManager fileExistsAtPath:fullPath] && !isDirectory && !overwrite) {\n                //FIXME: couldBe CRC Check?\n                unzCloseCurrentFile(zip);\n                ret = unzGoToNextFile(zip);\n                continue;\n            }\n            \n            if (!fileIsSymbolicLink) {\n                FILE *fp = fopen((const char*)[fullPath UTF8String], \"wb\");\n                while (fp) {\n                    int readBytes = unzReadCurrentFile(zip, buffer, 4096);\n                    \n                    if (readBytes > 0) {\n                        fwrite(buffer, readBytes, 1, fp );\n                    } else {\n                        break;\n                    }\n                }\n                \n                if (fp) {\n                    if ([[[fullPath pathExtension] lowercaseString] isEqualToString:@\"zip\"]) {\n                        NSLog(@\"Unzipping nested .zip file:  %@\", [fullPath lastPathComponent]);\n                        if ([self unzipFileAtPath:fullPath toDestination:[fullPath stringByDeletingLastPathComponent] overwrite:overwrite password:password error:nil delegate:nil]) {\n                            [[NSFileManager defaultManager] removeItemAtPath:fullPath error:nil];\n                        }\n                    }\n                    \n                    fclose(fp);\n                    \n                    // Set the original datetime property\n                    if (fileInfo.dosDate != 0) {\n                        NSDate *orgDate = [[self class] _dateWithMSDOSFormat:(UInt32)fileInfo.dosDate];\n                        NSDictionary *attr = @{NSFileModificationDate: orgDate};\n                        \n                        if (attr) {\n                            if ([fileManager setAttributes:attr ofItemAtPath:fullPath error:nil] == NO) {\n                                // Can't set attributes\n                                NSLog(@\"[SSZipArchive] Failed to set attributes - whilst setting modification date\");\n                            }\n                        }\n                    }\n                    \n                    // Set the original permissions on the file\n                    uLong permissions = fileInfo.external_fa >> 16;\n                    if (permissions != 0) {\n                        // Store it into a NSNumber\n                        NSNumber *permissionsValue = @(permissions);\n                        \n                        // Retrieve any existing attributes\n                        NSMutableDictionary *attrs = [[NSMutableDictionary alloc] initWithDictionary:[fileManager attributesOfItemAtPath:fullPath error:nil]];\n                        \n                        // Set the value in the attributes dict\n                        attrs[NSFilePosixPermissions] = permissionsValue;\n                        \n                        // Update attributes\n                        if ([fileManager setAttributes:attrs ofItemAtPath:fullPath error:nil] == NO) {\n                            // Unable to set the permissions attribute\n                            NSLog(@\"[SSZipArchive] Failed to set attributes - whilst setting permissions\");\n                        }\n                        \n#if !__has_feature(objc_arc)\n                        [attrs release];\n#endif\n                    }\n                }\n            }\n            else\n            {\n                // Assemble the path for the symbolic link\n                NSMutableString* destinationPath = [NSMutableString string];\n                int bytesRead = 0;\n                while((bytesRead = unzReadCurrentFile(zip, buffer, 4096)) > 0)\n                {\n                    buffer[bytesRead] = (int)0;\n                    [destinationPath appendString:@((const char*)buffer)];\n                }\n                \n                // Create the symbolic link (making sure it stays relative if it was relative before)\n                int symlinkError = symlink([destinationPath cStringUsingEncoding:NSUTF8StringEncoding],\n                                           [fullPath cStringUsingEncoding:NSUTF8StringEncoding]);\n                \n                if(symlinkError != 0)\n                {\n                    NSLog(@\"Failed to create symbolic link at \\\"%@\\\" to \\\"%@\\\". symlink() error code: %d\", fullPath, destinationPath, errno);\n                }\n            }\n            \n            crc_ret = unzCloseCurrentFile( zip );\n            if (crc_ret == UNZ_CRCERROR) {\n                //CRC ERROR\n                success = NO;\n                break;\n            }\n            ret = unzGoToNextFile( zip );\n            \n            // Message delegate\n            if ([delegate respondsToSelector:@selector(zipArchiveDidUnzipFileAtIndex:totalFiles:archivePath:fileInfo:)]) {\n                [delegate zipArchiveDidUnzipFileAtIndex:currentFileNumber totalFiles:(NSInteger)globalInfo.number_entry\n                                            archivePath:path fileInfo:fileInfo];\n            } else if ([delegate respondsToSelector: @selector(zipArchiveDidUnzipFileAtIndex:totalFiles:archivePath:unzippedFilePath:)]) {\n                [delegate zipArchiveDidUnzipFileAtIndex: currentFileNumber totalFiles: (NSInteger)globalInfo.number_entry\n                                            archivePath:path unzippedFilePath: fullPath];\n            }\n            \n            currentFileNumber++;\n            if (progressHandler)\n            {\n                progressHandler(strPath, fileInfo, currentFileNumber, globalInfo.number_entry);\n            }\n        }\n    } while(ret == UNZ_OK && ret != UNZ_END_OF_LIST_OF_FILE);\n    \n    // Close\n    unzClose(zip);\n    \n    // The process of decompressing the .zip archive causes the modification times on the folders\n    // to be set to the present time. So, when we are done, they need to be explicitly set.\n    // set the modification date on all of the directories.\n    NSError * err = nil;\n    for (NSDictionary * d in directoriesModificationDates) {\n        if (![[NSFileManager defaultManager] setAttributes:@{NSFileModificationDate: d[@\"modDate\"]} ofItemAtPath:d[@\"path\"] error:&err]) {\n            NSLog(@\"[SSZipArchive] Set attributes failed for directory: %@.\", d[@\"path\"]);\n        }\n        if (err) {\n            NSLog(@\"[SSZipArchive] Error setting directory file modification date attribute: %@\",err.localizedDescription);\n        }\n    }\n    \n#if !__has_feature(objc_arc)\n    [directoriesModificationDates release];\n#endif\n    \n    // Message delegate\n    if (success && [delegate respondsToSelector:@selector(zipArchiveDidUnzipArchiveAtPath:zipInfo:unzippedPath:)]) {\n        [delegate zipArchiveDidUnzipArchiveAtPath:path zipInfo:globalInfo unzippedPath:destination];\n    }\n    // final progress event = 100%\n    if (!canceled && [delegate respondsToSelector:@selector(zipArchiveProgressEvent:total:)]) {\n        [delegate zipArchiveProgressEvent:fileSize total:fileSize];\n    }\n    \n    NSError *retErr = nil;\n    if (crc_ret == UNZ_CRCERROR)\n    {\n        NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @\"crc check failed for file\"};\n        retErr = [NSError errorWithDomain:@\"SSZipArchiveErrorDomain\" code:-3 userInfo:userInfo];\n    }\n    if (error)\n    {\n        *error = retErr;\n    }\n    if (completionHandler)\n    {\n        completionHandler(path, success, retErr);\n    }\n    return success;\n}\n\n#pragma mark - Zipping\n+ (BOOL)createZipFileAtPath:(NSString *)path withFilesAtPaths:(NSArray *)paths\n{\n    return [SSZipArchive createZipFileAtPath:path withFilesAtPaths:paths withPassword:nil];\n}\n+ (BOOL)createZipFileAtPath:(NSString *)path withContentsOfDirectory:(NSString *)directoryPath{\n    return [SSZipArchive createZipFileAtPath:path withContentsOfDirectory:directoryPath withPassword:nil];\n}\n\n+ (BOOL)createZipFileAtPath:(NSString *)path withContentsOfDirectory:(NSString *)directoryPath keepParentDirectory:(BOOL)keepParentDirector{\n    return [SSZipArchive createZipFileAtPath:path withContentsOfDirectory:directoryPath keepParentDirectory:keepParentDirector withPassword:nil];\n}\n\n+ (BOOL)createZipFileAtPath:(NSString *)path withFilesAtPaths:(NSArray *)paths withPassword:(NSString *)password\n{\n    BOOL success = NO;\n    SSZipArchive *zipArchive = [[SSZipArchive alloc] initWithPath:path];\n    if ([zipArchive open]) {\n        for (NSString *filePath in paths) {\n            [zipArchive writeFile:filePath withPassword:password];\n        }\n        success = [zipArchive close];\n    }\n    \n#if !__has_feature(objc_arc)\n    [zipArchive release];\n#endif\n    \n    return success;\n}\n\n+ (BOOL)createZipFileAtPath:(NSString *)path withContentsOfDirectory:(NSString *)directoryPath  withPassword:(NSString *)password{\n    return [self createZipFileAtPath:path withContentsOfDirectory:directoryPath keepParentDirectory:NO withPassword:password];\n}\n\n\n+ (BOOL)createZipFileAtPath:(NSString *)path withContentsOfDirectory:(NSString *)directoryPath keepParentDirectory:(BOOL)keepParentDirectory withPassword:(NSString *)password{\n    BOOL success = NO;\n    \n    NSFileManager *fileManager = nil;\n    SSZipArchive *zipArchive = [[SSZipArchive alloc] initWithPath:path];\n    \n    if ([zipArchive open]) {\n        // use a local filemanager (queue/thread compatibility)\n        fileManager = [[NSFileManager alloc] init];\n        NSDirectoryEnumerator *dirEnumerator = [fileManager enumeratorAtPath:directoryPath];\n        NSString *fileName;\n        while ((fileName = [dirEnumerator nextObject])) {\n            BOOL isDir;\n            NSString *fullFilePath = [directoryPath stringByAppendingPathComponent:fileName];\n            [fileManager fileExistsAtPath:fullFilePath isDirectory:&isDir];\n            if (!isDir) {\n                if (keepParentDirectory)\n                {\n                    fileName = [[directoryPath lastPathComponent] stringByAppendingPathComponent:fileName];\n                }\n                [zipArchive writeFileAtPath:fullFilePath withFileName:fileName withPassword:password];\n            }\n            else\n            {\n                if([[NSFileManager defaultManager] subpathsOfDirectoryAtPath:fullFilePath error:nil].count == 0)\n                {\n                    NSString *tempName = [fullFilePath stringByAppendingPathComponent:@\".DS_Store\"];\n                    [@\"\" writeToFile:tempName atomically:YES encoding:NSUTF8StringEncoding error:nil];\n                    [zipArchive writeFileAtPath:tempName withFileName:[fileName stringByAppendingPathComponent:@\".DS_Store\"] withPassword:password];\n                    [[NSFileManager defaultManager] removeItemAtPath:tempName error:nil];\n                }\n            }\n        }\n        success = [zipArchive close];\n    }\n    \n#if !__has_feature(objc_arc)\n    [fileManager release];\n    [zipArchive release];\n#endif\n    \n    return success;\n}\n\n\n- (instancetype)initWithPath:(NSString *)path\n{\n    if ((self = [super init])) {\n        _path = [path copy];\n    }\n    return self;\n}\n\n\n#if !__has_feature(objc_arc)\n- (void)dealloc\n{\n    [_path release];\n    [super dealloc];\n}\n#endif\n\n\n- (BOOL)open\n{\n    NSAssert((_zip == NULL), @\"Attempting open an archive which is already open\");\n    _zip = zipOpen([_path UTF8String], APPEND_STATUS_CREATE);\n    return (NULL != _zip);\n}\n\n\n- (void)zipInfo:(zip_fileinfo*)zipInfo setDate:(NSDate*)date\n{\n    NSCalendar *currentCalendar = [NSCalendar currentCalendar];\n#if defined(__IPHONE_8_0) || defined(__MAC_10_10)\n    uint flags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;\n#else\n    uint flags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;\n#endif\n    NSDateComponents *components = [currentCalendar components:flags fromDate:date];\n    zipInfo->tmz_date.tm_sec = (unsigned int)components.second;\n    zipInfo->tmz_date.tm_min = (unsigned int)components.minute;\n    zipInfo->tmz_date.tm_hour = (unsigned int)components.hour;\n    zipInfo->tmz_date.tm_mday = (unsigned int)components.day;\n    zipInfo->tmz_date.tm_mon = (unsigned int)components.month - 1;\n    zipInfo->tmz_date.tm_year = (unsigned int)components.year;\n}\n\n- (BOOL)writeFolderAtPath:(NSString *)path withFolderName:(NSString *)folderName withPassword:(NSString *)password\n{\n    NSAssert((_zip != NULL), @\"Attempting to write to an archive which was never opened\");\n    \n    zip_fileinfo zipInfo = {{0}};\n    \n    NSDictionary *attr = [[NSFileManager defaultManager] attributesOfItemAtPath:path error: nil];\n    if( attr )\n    {\n        NSDate *fileDate = (NSDate *)attr[NSFileModificationDate];\n        if( fileDate )\n        {\n            [self zipInfo:&zipInfo setDate: fileDate ];\n        }\n        \n        // Write permissions into the external attributes, for details on this see here: http://unix.stackexchange.com/a/14727\n        // Get the permissions value from the files attributes\n        NSNumber *permissionsValue = (NSNumber *)attr[NSFilePosixPermissions];\n        if (permissionsValue) {\n            // Get the short value for the permissions\n            short permissionsShort = permissionsValue.shortValue;\n            \n            // Convert this into an octal by adding 010000, 010000 being the flag for a regular file\n            NSInteger permissionsOctal = 0100000 + permissionsShort;\n            \n            // Convert this into a long value\n            uLong permissionsLong = @(permissionsOctal).unsignedLongValue;\n            \n            // Store this into the external file attributes once it has been shifted 16 places left to form part of the second from last byte\n            zipInfo.external_fa = permissionsLong << 16L;\n        }\n    }\n    \n    unsigned int len = 0;\n    zipOpenNewFileInZip3(_zip, [[folderName stringByAppendingString:@\"/\"] UTF8String], &zipInfo, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_NO_COMPRESSION, 0, -MAX_WBITS, DEF_MEM_LEVEL,\n                         Z_DEFAULT_STRATEGY, [password UTF8String], 0);\n    zipWriteInFileInZip(_zip, &len, 0);\n    zipCloseFileInZip(_zip);\n    return YES;\n}\n\n- (BOOL)writeFile:(NSString *)path withPassword:(NSString *)password;\n{\n    return [self writeFileAtPath:path withFileName:nil withPassword:password];\n}\n\n// supports writing files with logical folder/directory structure\n// *path* is the absolute path of the file that will be compressed\n// *fileName* is the relative name of the file how it is stored within the zip e.g. /folder/subfolder/text1.txt\n- (BOOL)writeFileAtPath:(NSString *)path withFileName:(NSString *)fileName withPassword:(NSString *)password\n{\n    NSAssert((_zip != NULL), @\"Attempting to write to an archive which was never opened\");\n    \n    FILE *input = fopen([path UTF8String], \"r\");\n    if (NULL == input) {\n        return NO;\n    }\n    \n    const char *afileName;\n    if (!fileName) {\n        afileName = [path.lastPathComponent UTF8String];\n    }\n    else {\n        afileName = [fileName UTF8String];\n    }\n    \n    zip_fileinfo zipInfo = {{0}};\n    \n    NSDictionary *attr = [[NSFileManager defaultManager] attributesOfItemAtPath:path error: nil];\n    if( attr )\n    {\n        NSDate *fileDate = (NSDate *)attr[NSFileModificationDate];\n        if( fileDate )\n        {\n            [self zipInfo:&zipInfo setDate: fileDate ];\n        }\n        \n        // Write permissions into the external attributes, for details on this see here: http://unix.stackexchange.com/a/14727\n        // Get the permissions value from the files attributes\n        NSNumber *permissionsValue = (NSNumber *)attr[NSFilePosixPermissions];\n        if (permissionsValue) {\n            // Get the short value for the permissions\n            short permissionsShort = permissionsValue.shortValue;\n            \n            // Convert this into an octal by adding 010000, 010000 being the flag for a regular file\n            NSInteger permissionsOctal = 0100000 + permissionsShort;\n            \n            // Convert this into a long value\n            uLong permissionsLong = @(permissionsOctal).unsignedLongValue;\n            \n            // Store this into the external file attributes once it has been shifted 16 places left to form part of the second from last byte\n            zipInfo.external_fa = permissionsLong << 16L;\n        }\n    }\n    \n    void *buffer = malloc(CHUNK);\n    if (buffer == NULL)\n    {\n        return NO;\n    }\n\n    zipOpenNewFileInZip3(_zip, afileName, &zipInfo, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION, 0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, [password UTF8String], 0);\n    unsigned int len = 0;\n    \n    while (!feof(input))\n    {\n        len = (unsigned int) fread(buffer, 1, CHUNK, input);\n        zipWriteInFileInZip(_zip, buffer, len);\n    }\n    \n    zipCloseFileInZip(_zip);\n    free(buffer);\n    fclose(input);\n    return YES;\n}\n\n- (BOOL)writeData:(NSData *)data filename:(NSString *)filename withPassword:(NSString *)password;\n{\n    if (!_zip) {\n        return NO;\n    }\n    if (!data) {\n        return NO;\n    }\n    zip_fileinfo zipInfo = {{0,0,0,0,0,0},0,0,0};\n    [self zipInfo:&zipInfo setDate:[NSDate date]];\n    \n    zipOpenNewFileInZip3(_zip, [filename UTF8String], &zipInfo, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION, 0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, [password UTF8String], 0);\n    \n    zipWriteInFileInZip(_zip, data.bytes, (unsigned int)data.length);\n    \n    zipCloseFileInZip(_zip);\n    return YES;\n}\n\n\n- (BOOL)close\n{\n    NSAssert((_zip != NULL), @\"[SSZipArchive] Attempting to close an archive which was never opened\");\n    zipClose(_zip, NULL);\n    return YES;\n}\n\n#pragma mark - Private\n\n// Format from http://newsgroups.derkeiler.com/Archive/Comp/comp.os.msdos.programmer/2009-04/msg00060.html\n// Two consecutive words, or a longword, YYYYYYYMMMMDDDDD hhhhhmmmmmmsssss\n// YYYYYYY is years from 1980 = 0\n// sssss is (seconds/2).\n//\n// 3658 = 0011 0110 0101 1000 = 0011011 0010 11000 = 27 2 24 = 2007-02-24\n// 7423 = 0111 0100 0010 0011 - 01110 100001 00011 = 14 33 3 = 14:33:06\n+ (NSDate *)_dateWithMSDOSFormat:(UInt32)msdosDateTime\n{\n    static const UInt32 kYearMask = 0xFE000000;\n    static const UInt32 kMonthMask = 0x1E00000;\n    static const UInt32 kDayMask = 0x1F0000;\n    static const UInt32 kHourMask = 0xF800;\n    static const UInt32 kMinuteMask = 0x7E0;\n    static const UInt32 kSecondMask = 0x1F;\n    \n    static NSCalendar *gregorian;\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n#if defined(__IPHONE_8_0) || defined(__MAC_10_10)\n        gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];\n#else\n        gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];\n#endif\n    });\n    \n    NSDateComponents *components = [[NSDateComponents alloc] init];\n    \n    NSAssert(0xFFFFFFFF == (kYearMask | kMonthMask | kDayMask | kHourMask | kMinuteMask | kSecondMask), @\"[SSZipArchive] MSDOS date masks don't add up\");\n    \n    [components setYear:1980 + ((msdosDateTime & kYearMask) >> 25)];\n    [components setMonth:(msdosDateTime & kMonthMask) >> 21];\n    [components setDay:(msdosDateTime & kDayMask) >> 16];\n    [components setHour:(msdosDateTime & kHourMask) >> 11];\n    [components setMinute:(msdosDateTime & kMinuteMask) >> 5];\n    [components setSecond:(msdosDateTime & kSecondMask) * 2];\n    \n    NSDate *date = [NSDate dateWithTimeInterval:0 sinceDate:[gregorian dateFromComponents:components]];\n    \n#if !__has_feature(objc_arc)\n    [components release];\n#endif\n    \n    return date;\n}\n\n@end"
  },
  {
    "path": "plugins/cordova-plugin-zip/src/ios/ZipPlugin.h",
    "content": "#import <Foundation/Foundation.h>\n#import <Cordova/CDVPlugin.h>\n#import \"SSZipArchive.h\"\n\n@interface ZipPlugin : CDVPlugin <SSZipArchiveDelegate> {\n    @private\n    CDVInvokedUrlCommand* _command;\n}\n\n\n- (void)unzip:(CDVInvokedUrlCommand*)command;\n- (void)zipArchiveWillUnzipFileAtIndex:(NSInteger)fileIndex totalFiles:(NSInteger)totalFiles archivePath:(NSString *)archivePath fileInfo:(unz_file_info)fileInfo;\n\n@end\n"
  },
  {
    "path": "plugins/cordova-plugin-zip/src/ios/ZipPlugin.m",
    "content": "#import \"ZipPlugin.h\"\n#import \"CDVFile.h\"\n\n@implementation ZipPlugin\n\n- (NSString *)pathForURL:(NSString *)urlString\n{\n    // Attempt to use the File plugin to resolve the destination argument to a\n    // file path.\n    NSString *path = nil;\n    id filePlugin = [self.commandDelegate getCommandInstance:@\"File\"];\n    if (filePlugin != nil) {\n        CDVFilesystemURL* url = [CDVFilesystemURL fileSystemURLWithString:urlString];\n        path = [filePlugin filesystemPathForURL:url];\n    }\n    // If that didn't work for any reason, assume file: URL.\n    if (path == nil) {\n        if ([urlString hasPrefix:@\"file:\"]) {\n            path = [[NSURL URLWithString:urlString] path];\n        }\n    }\n    return path;\n}\n\n- (void)unzip:(CDVInvokedUrlCommand*)command\n{\n    self->_command = command;\n    [self.commandDelegate runInBackground:^{\n        CDVPluginResult* pluginResult = nil;\n        \n        @try {\n            NSString *zipURL = [command.arguments objectAtIndex:0];\n            NSString *destinationURL = [command.arguments objectAtIndex:1];\n            NSError *error;\n\n            NSString *zipPath = [self pathForURL:zipURL];\n            NSString *destinationPath = [self pathForURL:destinationURL];\n\n            if([SSZipArchive unzipFileAtPath:zipPath toDestination:destinationPath overwrite:YES password:nil error:&error delegate:self]) {\n                pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];\n            } else {\n                NSLog(@\"%@ - %@\", @\"Error occurred during unzipping\", [error localizedDescription]);\n                pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@\"Error occurred during unzipping\"];\n            }\n        } @catch(NSException* exception) {\n            NSLog(@\"%@ - %@\", @\"Error occurred during unzipping\", [exception debugDescription]);\n            pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@\"Error occurred during unzipping\"];\n        }\n        \n        [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];\n    }];\n}\n\n- (void)zipArchiveWillUnzipFileAtIndex:(NSInteger)fileIndex totalFiles:(NSInteger)totalFiles archivePath:(NSString *)archivePath fileInfo:(unz_file_info)fileInfo\n{\n    NSMutableDictionary* message = [NSMutableDictionary dictionaryWithCapacity:2];\n    [message setObject:[NSNumber numberWithLongLong:fileIndex] forKey:@\"loaded\"];\n    [message setObject:[NSNumber numberWithLongLong:totalFiles] forKey:@\"total\"];\n    \n    CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:message];\n    [pluginResult setKeepCallbackAsBool:YES];\n    [self.commandDelegate sendPluginResult:pluginResult callbackId:self->_command.callbackId];\n}\n@end\n"
  },
  {
    "path": "plugins/cordova-plugin-zip/src/ios/aes/aes.h",
    "content": "/*\r\n---------------------------------------------------------------------------\r\nCopyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.\r\n\r\nThe redistribution and use of this software (with or without changes)\r\nis allowed without the payment of fees or royalties provided that:\r\n\r\n  source code distributions include the above copyright notice, this\r\n  list of conditions and the following disclaimer;\r\n\r\n  binary distributions include the above copyright notice, this list\r\n  of conditions and the following disclaimer in their documentation.\r\n\r\nThis software is provided 'as is' with no explicit or implied warranties\r\nin respect of its operation, including, but not limited to, correctness\r\nand fitness for purpose.\r\n---------------------------------------------------------------------------\r\nIssue Date: 20/12/2007\r\n\r\n This file contains the definitions required to use AES in C. See aesopt.h\r\n for optimisation details.\r\n*/\r\n\r\n#ifndef _AES_H\r\n#define _AES_H\r\n\r\n#include <stdlib.h>\r\n\r\n/*  This include is used to find 8 & 32 bit unsigned integer types  */\r\n#include \"brg_types.h\"\r\n\r\n#if defined(__cplusplus)\r\nextern \"C\"\r\n{\r\n#endif\r\n\r\n#define AES_128     /* if a fast 128 bit key scheduler is needed    */\r\n#define AES_192     /* if a fast 192 bit key scheduler is needed    */\r\n#define AES_256     /* if a fast 256 bit key scheduler is needed    */\r\n#define AES_VAR     /* if variable key size scheduler is needed     */\r\n#define AES_MODES   /* if support is needed for modes               */\r\n\r\n/* The following must also be set in assembler files if being used  */\r\n\r\n#define AES_ENCRYPT /* if support for encryption is needed          */\r\n#define AES_DECRYPT /* if support for decryption is needed          */\r\n#define AES_REV_DKS /* define to reverse decryption key schedule    */\r\n\r\n#define AES_BLOCK_SIZE  16  /* the AES block size in bytes          */\r\n#define N_COLS           4  /* the number of columns in the state   */\r\n\r\n/* The key schedule length is 11, 13 or 15 16-byte blocks for 128,  */\r\n/* 192 or 256-bit keys respectively. That is 176, 208 or 240 bytes  */\r\n/* or 44, 52 or 60 32-bit words.                                    */\r\n\r\n#if defined( AES_VAR ) || defined( AES_256 )\r\n#define KS_LENGTH       60\r\n#elif defined( AES_192 )\r\n#define KS_LENGTH       52\r\n#else\r\n#define KS_LENGTH       44\r\n#endif\r\n\r\n#define AES_RETURN INT_RETURN\r\n\r\n/* the character array 'inf' in the following structures is used    */\r\n/* to hold AES context information. This AES code uses cx->inf.b[0] */\r\n/* to hold the number of rounds multiplied by 16. The other three   */\r\n/* elements can be used by code that implements additional modes    */\r\n\r\ntypedef union\r\n{   uint_32t l;\r\n    uint_8t b[4];\r\n} aes_inf;\r\n\r\ntypedef struct\r\n{   uint_32t ks[KS_LENGTH];\r\n    aes_inf inf;\r\n} aes_encrypt_ctx;\r\n\r\ntypedef struct\r\n{   uint_32t ks[KS_LENGTH];\r\n    aes_inf inf;\r\n} aes_decrypt_ctx;\r\n\r\n/* This routine must be called before first use if non-static       */\r\n/* tables are being used                                            */\r\n\r\nAES_RETURN aes_init(void);\r\n\r\n/* Key lengths in the range 16 <= key_len <= 32 are given in bytes, */\r\n/* those in the range 128 <= key_len <= 256 are given in bits       */\r\n\r\n#if defined( AES_ENCRYPT )\r\n\r\n#if defined( AES_128 ) || defined( AES_VAR)\r\nAES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1]);\r\n#endif\r\n\r\n#if defined( AES_192 ) || defined( AES_VAR)\r\nAES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1]);\r\n#endif\r\n\r\n#if defined( AES_256 ) || defined( AES_VAR)\r\nAES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]);\r\n#endif\r\n\r\n#if defined( AES_VAR )\r\nAES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1]);\r\n#endif\r\n\r\nAES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1]);\r\n\r\n#endif\r\n\r\n#if defined( AES_DECRYPT )\r\n\r\n#if defined( AES_128 ) || defined( AES_VAR)\r\nAES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1]);\r\n#endif\r\n\r\n#if defined( AES_192 ) || defined( AES_VAR)\r\nAES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1]);\r\n#endif\r\n\r\n#if defined( AES_256 ) || defined( AES_VAR)\r\nAES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]);\r\n#endif\r\n\r\n#if defined( AES_VAR )\r\nAES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1]);\r\n#endif\r\n\r\nAES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1]);\r\n\r\n#endif\r\n\r\n#if defined( AES_MODES )\r\n\r\n/* Multiple calls to the following subroutines for multiple block   */\r\n/* ECB, CBC, CFB, OFB and CTR mode encryption can be used to handle */\r\n/* long messages incremantally provided that the context AND the iv */\r\n/* are preserved between all such calls.  For the ECB and CBC modes */\r\n/* each individual call within a series of incremental calls must   */\r\n/* process only full blocks (i.e. len must be a multiple of 16) but */\r\n/* the CFB, OFB and CTR mode calls can handle multiple incremental  */\r\n/* calls of any length. Each mode is reset when a new AES key is    */\r\n/* set but ECB and CBC operations can be reset without setting a    */\r\n/* new key by setting a new IV value.  To reset CFB, OFB and CTR    */\r\n/* without setting the key, aes_mode_reset() must be called and the */\r\n/* IV must be set.  NOTE: All these calls update the IV on exit so  */\r\n/* this has to be reset if a new operation with the same IV as the  */\r\n/* previous one is required (or decryption follows encryption with  */\r\n/* the same IV array).                                              */\r\n\r\nAES_RETURN aes_test_alignment_detection(unsigned int n);\r\n\r\nAES_RETURN aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf,\r\n                    int len, const aes_encrypt_ctx cx[1]);\r\n\r\nAES_RETURN aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf,\r\n                    int len, const aes_decrypt_ctx cx[1]);\r\n\r\nAES_RETURN aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf,\r\n                    int len, unsigned char *iv, const aes_encrypt_ctx cx[1]);\r\n\r\nAES_RETURN aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf,\r\n                    int len, unsigned char *iv, const aes_decrypt_ctx cx[1]);\r\n\r\nAES_RETURN aes_mode_reset(aes_encrypt_ctx cx[1]);\r\n\r\nAES_RETURN aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf,\r\n                    int len, unsigned char *iv, aes_encrypt_ctx cx[1]);\r\n\r\nAES_RETURN aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf,\r\n                    int len, unsigned char *iv, aes_encrypt_ctx cx[1]);\r\n\r\n#define aes_ofb_encrypt aes_ofb_crypt\r\n#define aes_ofb_decrypt aes_ofb_crypt\r\n\r\nAES_RETURN aes_ofb_crypt(const unsigned char *ibuf, unsigned char *obuf,\r\n                    int len, unsigned char *iv, aes_encrypt_ctx cx[1]);\r\n\r\ntypedef void cbuf_inc(unsigned char *cbuf);\r\n\r\n#define aes_ctr_encrypt aes_ctr_crypt\r\n#define aes_ctr_decrypt aes_ctr_crypt\r\n\r\nAES_RETURN aes_ctr_crypt(const unsigned char *ibuf, unsigned char *obuf,\r\n            int len, unsigned char *cbuf, cbuf_inc ctr_inc, aes_encrypt_ctx cx[1]);\r\n\r\n#endif\r\n\r\n#if defined(__cplusplus)\r\n}\r\n#endif\r\n\r\n#endif\r\n"
  },
  {
    "path": "plugins/cordova-plugin-zip/src/ios/aes/aes_via_ace.h",
    "content": "/*\r\nCopyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.\r\n\r\nThe redistribution and use of this software (with or without changes)\r\nis allowed without the payment of fees or royalties provided that:\r\n\r\n  source code distributions include the above copyright notice, this\r\n  list of conditions and the following disclaimer;\r\n\r\n  binary distributions include the above copyright notice, this list\r\n  of conditions and the following disclaimer in their documentation.\r\n\r\nThis software is provided 'as is' with no explicit or implied warranties\r\nin respect of its operation, including, but not limited to, correctness\r\nand fitness for purpose.\r\n---------------------------------------------------------------------------\r\nIssue Date: 20/12/2007\r\n*/\r\n\r\n#ifndef AES_VIA_ACE_H\r\n#define AES_VIA_ACE_H\r\n\r\n#if defined( _MSC_VER )\r\n#  define INLINE  __inline\r\n#elif defined( __GNUC__ )\r\n#  define INLINE  static inline\r\n#else\r\n#  error VIA ACE requires Microsoft or GNU C\r\n#endif\r\n\r\n#define NEH_GENERATE    1\r\n#define NEH_LOAD        2\r\n#define NEH_HYBRID      3\r\n\r\n#define MAX_READ_ATTEMPTS   1000\r\n\r\n/* VIA Nehemiah RNG and ACE Feature Mask Values */\r\n\r\n#define NEH_CPU_IS_VIA      0x00000001\r\n#define NEH_CPU_READ        0x00000010\r\n#define NEH_CPU_MASK        0x00000011\r\n\r\n#define NEH_RNG_PRESENT     0x00000004\r\n#define NEH_RNG_ENABLED     0x00000008\r\n#define NEH_ACE_PRESENT     0x00000040\r\n#define NEH_ACE_ENABLED     0x00000080\r\n#define NEH_RNG_FLAGS       (NEH_RNG_PRESENT | NEH_RNG_ENABLED)\r\n#define NEH_ACE_FLAGS       (NEH_ACE_PRESENT | NEH_ACE_ENABLED)\r\n#define NEH_FLAGS_MASK      (NEH_RNG_FLAGS | NEH_ACE_FLAGS)\r\n\r\n/* VIA Nehemiah Advanced Cryptography Engine (ACE) Control Word Values  */\r\n\r\n#define NEH_GEN_KEY     0x00000000      /* generate key schedule        */\r\n#define NEH_LOAD_KEY    0x00000080      /* load schedule from memory    */\r\n#define NEH_ENCRYPT     0x00000000      /* encryption                   */\r\n#define NEH_DECRYPT     0x00000200      /* decryption                   */\r\n#define NEH_KEY128      0x00000000+0x0a /* 128 bit key                  */\r\n#define NEH_KEY192      0x00000400+0x0c /* 192 bit key                  */\r\n#define NEH_KEY256      0x00000800+0x0e /* 256 bit key                  */\r\n\r\n#define NEH_ENC_GEN     (NEH_ENCRYPT | NEH_GEN_KEY)\r\n#define NEH_DEC_GEN     (NEH_DECRYPT | NEH_GEN_KEY)\r\n#define NEH_ENC_LOAD    (NEH_ENCRYPT | NEH_LOAD_KEY)\r\n#define NEH_DEC_LOAD    (NEH_DECRYPT | NEH_LOAD_KEY)\r\n\r\n#define NEH_ENC_GEN_DATA {\\\r\n    NEH_ENC_GEN | NEH_KEY128, 0, 0, 0,\\\r\n    NEH_ENC_GEN | NEH_KEY192, 0, 0, 0,\\\r\n    NEH_ENC_GEN | NEH_KEY256, 0, 0, 0 }\r\n\r\n#define NEH_ENC_LOAD_DATA {\\\r\n    NEH_ENC_LOAD | NEH_KEY128, 0, 0, 0,\\\r\n    NEH_ENC_LOAD | NEH_KEY192, 0, 0, 0,\\\r\n    NEH_ENC_LOAD | NEH_KEY256, 0, 0, 0 }\r\n\r\n#define NEH_ENC_HYBRID_DATA {\\\r\n    NEH_ENC_GEN  | NEH_KEY128, 0, 0, 0,\\\r\n    NEH_ENC_LOAD | NEH_KEY192, 0, 0, 0,\\\r\n    NEH_ENC_LOAD | NEH_KEY256, 0, 0, 0 }\r\n\r\n#define NEH_DEC_GEN_DATA {\\\r\n    NEH_DEC_GEN | NEH_KEY128, 0, 0, 0,\\\r\n    NEH_DEC_GEN | NEH_KEY192, 0, 0, 0,\\\r\n    NEH_DEC_GEN | NEH_KEY256, 0, 0, 0 }\r\n\r\n#define NEH_DEC_LOAD_DATA {\\\r\n    NEH_DEC_LOAD | NEH_KEY128, 0, 0, 0,\\\r\n    NEH_DEC_LOAD | NEH_KEY192, 0, 0, 0,\\\r\n    NEH_DEC_LOAD | NEH_KEY256, 0, 0, 0 }\r\n\r\n#define NEH_DEC_HYBRID_DATA {\\\r\n    NEH_DEC_GEN  | NEH_KEY128, 0, 0, 0,\\\r\n    NEH_DEC_LOAD | NEH_KEY192, 0, 0, 0,\\\r\n    NEH_DEC_LOAD | NEH_KEY256, 0, 0, 0 }\r\n\r\n#define neh_enc_gen_key(x)  ((x) == 128 ? (NEH_ENC_GEN | NEH_KEY128) :      \\\r\n     (x) == 192 ? (NEH_ENC_GEN | NEH_KEY192) : (NEH_ENC_GEN | NEH_KEY256))\r\n\r\n#define neh_enc_load_key(x) ((x) == 128 ? (NEH_ENC_LOAD | NEH_KEY128) :     \\\r\n     (x) == 192 ? (NEH_ENC_LOAD | NEH_KEY192) : (NEH_ENC_LOAD | NEH_KEY256))\r\n\r\n#define neh_enc_hybrid_key(x)   ((x) == 128 ? (NEH_ENC_GEN | NEH_KEY128) :  \\\r\n     (x) == 192 ? (NEH_ENC_LOAD | NEH_KEY192) : (NEH_ENC_LOAD | NEH_KEY256))\r\n\r\n#define neh_dec_gen_key(x)  ((x) == 128 ? (NEH_DEC_GEN | NEH_KEY128) :      \\\r\n     (x) == 192 ? (NEH_DEC_GEN | NEH_KEY192) : (NEH_DEC_GEN | NEH_KEY256))\r\n\r\n#define neh_dec_load_key(x) ((x) == 128 ? (NEH_DEC_LOAD | NEH_KEY128) :     \\\r\n     (x) == 192 ? (NEH_DEC_LOAD | NEH_KEY192) : (NEH_DEC_LOAD | NEH_KEY256))\r\n\r\n#define neh_dec_hybrid_key(x)   ((x) == 128 ? (NEH_DEC_GEN | NEH_KEY128) :  \\\r\n     (x) == 192 ? (NEH_DEC_LOAD | NEH_KEY192) : (NEH_DEC_LOAD | NEH_KEY256))\r\n\r\n#if defined( _MSC_VER ) && ( _MSC_VER > 1200 )\r\n#define aligned_auto(type, name, no, stride)  __declspec(align(stride)) type name[no]\r\n#else\r\n#define aligned_auto(type, name, no, stride)                \\\r\n    unsigned char _##name[no * sizeof(type) + stride];      \\\r\n    type *name = (type*)(16 * ((((unsigned long)(_##name)) + stride - 1) / stride))\r\n#endif\r\n\r\n#if defined( _MSC_VER ) && ( _MSC_VER > 1200 )\r\n#define aligned_array(type, name, no, stride) __declspec(align(stride)) type name[no]\r\n#elif defined( __GNUC__ )\r\n#define aligned_array(type, name, no, stride) type name[no] __attribute__ ((aligned(stride)))\r\n#else\r\n#define aligned_array(type, name, no, stride) type name[no]\r\n#endif\r\n\r\n/* VIA ACE codeword     */\r\n\r\nstatic unsigned char via_flags = 0;\r\n\r\n#if defined ( _MSC_VER ) && ( _MSC_VER > 800 )\r\n\r\n#define NEH_REKEY   __asm pushfd __asm popfd\r\n#define NEH_AES     __asm _emit 0xf3 __asm _emit 0x0f __asm _emit 0xa7\r\n#define NEH_ECB     NEH_AES __asm _emit 0xc8\r\n#define NEH_CBC     NEH_AES __asm _emit 0xd0\r\n#define NEH_CFB     NEH_AES __asm _emit 0xe0\r\n#define NEH_OFB     NEH_AES __asm _emit 0xe8\r\n#define NEH_RNG     __asm _emit 0x0f __asm _emit 0xa7 __asm _emit 0xc0\r\n\r\nINLINE int has_cpuid(void)\r\n{   char ret_value;\r\n    __asm\r\n    {   pushfd                  /* save EFLAGS register     */\r\n        mov     eax,[esp]       /* copy it to eax           */\r\n        mov     edx,0x00200000  /* CPUID bit position       */\r\n        xor     eax,edx         /* toggle the CPUID bit     */\r\n        push    eax             /* attempt to set EFLAGS to */\r\n        popfd                   /*     the new value        */\r\n        pushfd                  /* get the new EFLAGS value */\r\n        pop     eax             /*     into eax             */\r\n        xor     eax,[esp]       /* xor with original value  */\r\n        and     eax,edx         /* has CPUID bit changed?   */\r\n        setne   al              /* set to 1 if we have been */\r\n        mov     ret_value,al    /*     able to change it    */\r\n        popfd                   /* restore original EFLAGS  */\r\n    }\r\n    return (int)ret_value;\r\n}\r\n\r\nINLINE int is_via_cpu(void)\r\n{   char ret_value;\r\n    __asm\r\n    {   push    ebx\r\n        xor     eax,eax         /* use CPUID to get vendor  */\r\n        cpuid                   /* identity string          */\r\n        xor     eax,eax         /* is it \"CentaurHauls\" ?   */\r\n        sub     ebx,0x746e6543  /* 'Cent'                   */\r\n        or      eax,ebx\r\n        sub     edx,0x48727561  /* 'aurH'                   */\r\n        or      eax,edx\r\n        sub     ecx,0x736c7561  /* 'auls'                   */\r\n        or      eax,ecx\r\n        sete    al              /* set to 1 if it is VIA ID */\r\n        mov     dl,NEH_CPU_READ /* mark CPU type as read    */\r\n        or      dl,al           /* & store result in flags  */\r\n        mov     [via_flags],dl  /* set VIA detected flag    */\r\n        mov     ret_value,al    /*     able to change it    */\r\n        pop     ebx\r\n    }\r\n    return (int)ret_value;\r\n}\r\n\r\nINLINE int read_via_flags(void)\r\n{   char ret_value = 0;\r\n    __asm\r\n    {   mov     eax,0xC0000000  /* Centaur extended CPUID   */\r\n        cpuid\r\n        mov     edx,0xc0000001  /* >= 0xc0000001 if support */\r\n        cmp     eax,edx         /* for VIA extended feature */\r\n        jnae    no_rng          /*     flags is available   */\r\n        mov     eax,edx         /* read Centaur extended    */\r\n        cpuid                   /*     feature flags        */\r\n        mov     eax,NEH_FLAGS_MASK  /* mask out and save    */\r\n        and     eax,edx         /*  the RNG and ACE flags   */\r\n        or      [via_flags],al  /* present & enabled flags  */\r\n        mov     ret_value,al    /*     able to change it    */\r\nno_rng:\r\n    }\r\n    return (int)ret_value;\r\n}\r\n\r\nINLINE unsigned int via_rng_in(void *buf)\r\n{   char ret_value = 0x1f;\r\n    __asm\r\n    {   push    edi\r\n        mov     edi,buf         /* input buffer address     */\r\n        xor     edx,edx         /* try to fetch 8 bytes     */\r\n        NEH_RNG                 /* do RNG read operation    */\r\n        and     ret_value,al    /* count of bytes returned  */\r\n        pop     edi\r\n    }\r\n    return (int)ret_value;\r\n}\r\n\r\nINLINE void via_ecb_op5(\r\n            const void *k, const void *c, const void *s, void *d, int l)\r\n{   __asm\r\n    {   push    ebx\r\n        NEH_REKEY\r\n        mov     ebx, (k)\r\n        mov     edx, (c)\r\n        mov     esi, (s)\r\n        mov     edi, (d)\r\n        mov     ecx, (l)\r\n        NEH_ECB\r\n        pop     ebx\r\n    }\r\n}\r\n\r\nINLINE void via_cbc_op6(\r\n            const void *k, const void *c, const void *s, void *d, int l, void *v)\r\n{   __asm\r\n    {   push    ebx\r\n        NEH_REKEY\r\n        mov     ebx, (k)\r\n        mov     edx, (c)\r\n        mov     esi, (s)\r\n        mov     edi, (d)\r\n        mov     ecx, (l)\r\n        mov     eax, (v)\r\n        NEH_CBC\r\n        pop     ebx\r\n    }\r\n}\r\n\r\nINLINE void via_cbc_op7(\r\n        const void *k, const void *c, const void *s, void *d, int l, void *v, void *w)\r\n{   __asm\r\n    {   push    ebx\r\n        NEH_REKEY\r\n        mov     ebx, (k)\r\n        mov     edx, (c)\r\n        mov     esi, (s)\r\n        mov     edi, (d)\r\n        mov     ecx, (l)\r\n        mov     eax, (v)\r\n        NEH_CBC\r\n        mov     esi, eax\r\n        mov     edi, (w)\r\n        movsd\r\n        movsd\r\n        movsd\r\n        movsd\r\n        pop     ebx\r\n    }\r\n}\r\n\r\nINLINE void via_cfb_op6(\r\n            const void *k, const void *c, const void *s, void *d, int l, void *v)\r\n{   __asm\r\n    {   push    ebx\r\n        NEH_REKEY\r\n        mov     ebx, (k)\r\n        mov     edx, (c)\r\n        mov     esi, (s)\r\n        mov     edi, (d)\r\n        mov     ecx, (l)\r\n        mov     eax, (v)\r\n        NEH_CFB\r\n        pop     ebx\r\n    }\r\n}\r\n\r\nINLINE void via_cfb_op7(\r\n        const void *k, const void *c, const void *s, void *d, int l, void *v, void *w)\r\n{   __asm\r\n    {   push    ebx\r\n        NEH_REKEY\r\n        mov     ebx, (k)\r\n        mov     edx, (c)\r\n        mov     esi, (s)\r\n        mov     edi, (d)\r\n        mov     ecx, (l)\r\n        mov     eax, (v)\r\n        NEH_CFB\r\n        mov     esi, eax\r\n        mov     edi, (w)\r\n        movsd\r\n        movsd\r\n        movsd\r\n        movsd\r\n        pop     ebx\r\n    }\r\n}\r\n\r\nINLINE void via_ofb_op6(\r\n            const void *k, const void *c, const void *s, void *d, int l, void *v)\r\n{   __asm\r\n    {   push    ebx\r\n        NEH_REKEY\r\n        mov     ebx, (k)\r\n        mov     edx, (c)\r\n        mov     esi, (s)\r\n        mov     edi, (d)\r\n        mov     ecx, (l)\r\n        mov     eax, (v)\r\n        NEH_OFB\r\n        pop     ebx\r\n    }\r\n}\r\n\r\n#elif defined( __GNUC__ )\r\n\r\n#define NEH_REKEY   asm(\"pushfl\\n popfl\\n\\t\")\r\n#define NEH_ECB     asm(\".byte 0xf3, 0x0f, 0xa7, 0xc8\\n\\t\")\r\n#define NEH_CBC     asm(\".byte 0xf3, 0x0f, 0xa7, 0xd0\\n\\t\")\r\n#define NEH_CFB     asm(\".byte 0xf3, 0x0f, 0xa7, 0xe0\\n\\t\")\r\n#define NEH_OFB     asm(\".byte 0xf3, 0x0f, 0xa7, 0xe8\\n\\t\")\r\n#define NEH_RNG     asm(\".byte 0x0f, 0xa7, 0xc0\\n\\t\");\r\n\r\nINLINE int has_cpuid(void)\r\n{   int val;\r\n    asm(\"pushfl\\n\\t\");\r\n    asm(\"movl  0(%esp),%eax\\n\\t\");\r\n    asm(\"xor   $0x00200000,%eax\\n\\t\");\r\n    asm(\"pushl %eax\\n\\t\");\r\n    asm(\"popfl\\n\\t\");\r\n    asm(\"pushfl\\n\\t\");\r\n    asm(\"popl  %eax\\n\\t\");\r\n    asm(\"xorl  0(%esp),%edx\\n\\t\");\r\n    asm(\"andl  $0x00200000,%eax\\n\\t\");\r\n    asm(\"movl  %%eax,%0\\n\\t\" : \"=m\" (val));\r\n    asm(\"popfl\\n\\t\");\r\n    return val ? 1 : 0;\r\n}\r\n\r\nINLINE int is_via_cpu(void)\r\n{   int val;\r\n    asm(\"pushl %ebx\\n\\t\");\r\n    asm(\"xorl %eax,%eax\\n\\t\");\r\n    asm(\"cpuid\\n\\t\");\r\n    asm(\"xorl %eax,%eax\\n\\t\");\r\n    asm(\"subl $0x746e6543,%ebx\\n\\t\");\r\n    asm(\"orl  %ebx,%eax\\n\\t\");\r\n    asm(\"subl $0x48727561,%edx\\n\\t\");\r\n    asm(\"orl  %edx,%eax\\n\\t\");\r\n    asm(\"subl $0x736c7561,%ecx\\n\\t\");\r\n    asm(\"orl  %ecx,%eax\\n\\t\");\r\n    asm(\"movl %%eax,%0\\n\\t\" : \"=m\" (val));\r\n    asm(\"popl %ebx\\n\\t\");\r\n    val = (val ? 0 : 1);\r\n    via_flags = (val | NEH_CPU_READ);\r\n    return val;\r\n}\r\n\r\nINLINE int read_via_flags(void)\r\n{   unsigned char   val;\r\n    asm(\"movl $0xc0000000,%eax\\n\\t\");\r\n    asm(\"cpuid\\n\\t\");\r\n    asm(\"movl $0xc0000001,%edx\\n\\t\");\r\n    asm(\"cmpl %edx,%eax\\n\\t\");\r\n    asm(\"setae %al\\n\\t\");\r\n    asm(\"movb %%al,%0\\n\\t\" : \"=m\" (val));\r\n    if(!val) return 0;\r\n    asm(\"movl $0xc0000001,%eax\\n\\t\");\r\n    asm(\"cpuid\\n\\t\");\r\n    asm(\"movb %%dl,%0\\n\\t\" : \"=m\" (val));\r\n    val &= NEH_FLAGS_MASK;\r\n    via_flags |= val;\r\n    return (int) val;\r\n}\r\n\r\nINLINE int via_rng_in(void *buf)\r\n{   int val;\r\n    asm(\"pushl %edi\\n\\t\");\r\n    asm(\"movl %0,%%edi\\n\\t\" : : \"m\" (buf));\r\n    asm(\"xorl %edx,%edx\\n\\t\");\r\n    NEH_RNG\r\n    asm(\"andl $0x0000001f,%eax\\n\\t\");\r\n    asm(\"movl %%eax,%0\\n\\t\" : \"=m\" (val));\r\n    asm(\"popl %edi\\n\\t\");\r\n    return val;\r\n}\r\n\r\nINLINE volatile  void via_ecb_op5(\r\n            const void *k, const void *c, const void *s, void *d, int l)\r\n{\r\n    asm(\"pushl %ebx\\n\\t\");\r\n    NEH_REKEY;\r\n    asm(\"movl %0, %%ebx\\n\\t\" : : \"m\" (k));\r\n    asm(\"movl %0, %%edx\\n\\t\" : : \"m\" (c));\r\n    asm(\"movl %0, %%esi\\n\\t\" : : \"m\" (s));\r\n    asm(\"movl %0, %%edi\\n\\t\" : : \"m\" (d));\r\n    asm(\"movl %0, %%ecx\\n\\t\" : : \"m\" (l));\r\n    NEH_ECB;\r\n    asm(\"popl %ebx\\n\\t\");\r\n}\r\n\r\nINLINE volatile  void via_cbc_op6(\r\n            const void *k, const void *c, const void *s, void *d, int l, void *v)\r\n{\r\n    asm(\"pushl %ebx\\n\\t\");\r\n    NEH_REKEY;\r\n    asm(\"movl %0, %%ebx\\n\\t\" : : \"m\" (k));\r\n    asm(\"movl %0, %%edx\\n\\t\" : : \"m\" (c));\r\n    asm(\"movl %0, %%esi\\n\\t\" : : \"m\" (s));\r\n    asm(\"movl %0, %%edi\\n\\t\" : : \"m\" (d));\r\n    asm(\"movl %0, %%ecx\\n\\t\" : : \"m\" (l));\r\n    asm(\"movl %0, %%eax\\n\\t\" : : \"m\" (v));\r\n    NEH_CBC;\r\n    asm(\"popl %ebx\\n\\t\");\r\n}\r\n\r\nINLINE volatile  void via_cbc_op7(\r\n        const void *k, const void *c, const void *s, void *d, int l, void *v, void *w)\r\n{\r\n    asm(\"pushl %ebx\\n\\t\");\r\n    NEH_REKEY;\r\n    asm(\"movl %0, %%ebx\\n\\t\" : : \"m\" (k));\r\n    asm(\"movl %0, %%edx\\n\\t\" : : \"m\" (c));\r\n    asm(\"movl %0, %%esi\\n\\t\" : : \"m\" (s));\r\n    asm(\"movl %0, %%edi\\n\\t\" : : \"m\" (d));\r\n    asm(\"movl %0, %%ecx\\n\\t\" : : \"m\" (l));\r\n    asm(\"movl %0, %%eax\\n\\t\" : : \"m\" (v));\r\n    NEH_CBC;\r\n    asm(\"movl %eax,%esi\\n\\t\");\r\n    asm(\"movl %0, %%edi\\n\\t\" : : \"m\" (w));\r\n    asm(\"movsl; movsl; movsl; movsl\\n\\t\");\r\n    asm(\"popl %ebx\\n\\t\");\r\n}\r\n\r\nINLINE volatile  void via_cfb_op6(\r\n            const void *k, const void *c, const void *s, void *d, int l, void *v)\r\n{\r\n    asm(\"pushl %ebx\\n\\t\");\r\n    NEH_REKEY;\r\n    asm(\"movl %0, %%ebx\\n\\t\" : : \"m\" (k));\r\n    asm(\"movl %0, %%edx\\n\\t\" : : \"m\" (c));\r\n    asm(\"movl %0, %%esi\\n\\t\" : : \"m\" (s));\r\n    asm(\"movl %0, %%edi\\n\\t\" : : \"m\" (d));\r\n    asm(\"movl %0, %%ecx\\n\\t\" : : \"m\" (l));\r\n    asm(\"movl %0, %%eax\\n\\t\" : : \"m\" (v));\r\n    NEH_CFB;\r\n    asm(\"popl %ebx\\n\\t\");\r\n}\r\n\r\nINLINE volatile  void via_cfb_op7(\r\n        const void *k, const void *c, const void *s, void *d, int l, void *v, void *w)\r\n{\r\n    asm(\"pushl %ebx\\n\\t\");\r\n    NEH_REKEY;\r\n    asm(\"movl %0, %%ebx\\n\\t\" : : \"m\" (k));\r\n    asm(\"movl %0, %%edx\\n\\t\" : : \"m\" (c));\r\n    asm(\"movl %0, %%esi\\n\\t\" : : \"m\" (s));\r\n    asm(\"movl %0, %%edi\\n\\t\" : : \"m\" (d));\r\n    asm(\"movl %0, %%ecx\\n\\t\" : : \"m\" (l));\r\n    asm(\"movl %0, %%eax\\n\\t\" : : \"m\" (v));\r\n    NEH_CFB;\r\n    asm(\"movl %eax,%esi\\n\\t\");\r\n    asm(\"movl %0, %%edi\\n\\t\" : : \"m\" (w));\r\n    asm(\"movsl; movsl; movsl; movsl\\n\\t\");\r\n    asm(\"popl %ebx\\n\\t\");\r\n}\r\n\r\nINLINE volatile  void via_ofb_op6(\r\n            const void *k, const void *c, const void *s, void *d, int l, void *v)\r\n{\r\n    asm(\"pushl %ebx\\n\\t\");\r\n    NEH_REKEY;\r\n    asm(\"movl %0, %%ebx\\n\\t\" : : \"m\" (k));\r\n    asm(\"movl %0, %%edx\\n\\t\" : : \"m\" (c));\r\n    asm(\"movl %0, %%esi\\n\\t\" : : \"m\" (s));\r\n    asm(\"movl %0, %%edi\\n\\t\" : : \"m\" (d));\r\n    asm(\"movl %0, %%ecx\\n\\t\" : : \"m\" (l));\r\n    asm(\"movl %0, %%eax\\n\\t\" : : \"m\" (v));\r\n    NEH_OFB;\r\n    asm(\"popl %ebx\\n\\t\");\r\n}\r\n\r\n#else\r\n#error VIA ACE is not available with this compiler\r\n#endif\r\n\r\nINLINE int via_ace_test(void)\r\n{\r\n    return has_cpuid() && is_via_cpu() && ((read_via_flags() & NEH_ACE_FLAGS) == NEH_ACE_FLAGS);\r\n}\r\n\r\n#define VIA_ACE_AVAILABLE   (((via_flags & NEH_ACE_FLAGS) == NEH_ACE_FLAGS)         \\\r\n    || (via_flags & NEH_CPU_READ) && (via_flags & NEH_CPU_IS_VIA) || via_ace_test())\r\n\r\nINLINE int via_rng_test(void)\r\n{\r\n    return has_cpuid() && is_via_cpu() && ((read_via_flags() & NEH_RNG_FLAGS) == NEH_RNG_FLAGS);\r\n}\r\n\r\n#define VIA_RNG_AVAILABLE   (((via_flags & NEH_RNG_FLAGS) == NEH_RNG_FLAGS)         \\\r\n    || (via_flags & NEH_CPU_READ) && (via_flags & NEH_CPU_IS_VIA) || via_rng_test())\r\n\r\nINLINE int read_via_rng(void *buf, int count)\r\n{   int nbr, max_reads, lcnt = count;\r\n    unsigned char *p, *q;\r\n    aligned_auto(unsigned char, bp, 64, 16);\r\n\r\n    if(!VIA_RNG_AVAILABLE)\r\n        return 0;\r\n\r\n    do\r\n    {\r\n        max_reads = MAX_READ_ATTEMPTS;\r\n        do\r\n            nbr = via_rng_in(bp);\r\n        while\r\n            (nbr == 0 && --max_reads);\r\n\r\n        lcnt -= nbr;\r\n        p = (unsigned char*)buf; q = bp;\r\n        while(nbr--)\r\n            *p++ = *q++;\r\n    }\r\n    while\r\n        (lcnt && max_reads);\r\n\r\n    return count - lcnt;\r\n}\r\n\r\n#endif\r\n"
  },
  {
    "path": "plugins/cordova-plugin-zip/src/ios/aes/aescrypt.c",
    "content": "/*\r\n---------------------------------------------------------------------------\r\nCopyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.\r\n\r\nThe redistribution and use of this software (with or without changes)\r\nis allowed without the payment of fees or royalties provided that:\r\n\r\n  source code distributions include the above copyright notice, this\r\n  list of conditions and the following disclaimer;\r\n\r\n  binary distributions include the above copyright notice, this list\r\n  of conditions and the following disclaimer in their documentation.\r\n\r\nThis software is provided 'as is' with no explicit or implied warranties\r\nin respect of its operation, including, but not limited to, correctness\r\nand fitness for purpose.\r\n---------------------------------------------------------------------------\r\nIssue Date: 20/12/2007\r\n*/\r\n\r\n#include \"aesopt.h\"\r\n#include \"aestab.h\"\r\n\r\n#if defined(__cplusplus)\r\nextern \"C\"\r\n{\r\n#endif\r\n\r\n#define si(y,x,k,c) (s(y,c) = word_in(x, c) ^ (k)[c])\r\n#define so(y,x,c)   word_out(y, c, s(x,c))\r\n\r\n#if defined(ARRAYS)\r\n#define locals(y,x)     x[4],y[4]\r\n#else\r\n#define locals(y,x)     x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3\r\n#endif\r\n\r\n#define l_copy(y, x)    s(y,0) = s(x,0); s(y,1) = s(x,1); \\\r\n                        s(y,2) = s(x,2); s(y,3) = s(x,3);\r\n#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3)\r\n#define state_out(y,x)  so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)\r\n#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3)\r\n\r\n#if ( FUNCS_IN_C & ENCRYPTION_IN_C )\r\n\r\n/* Visual C++ .Net v7.1 provides the fastest encryption code when using\r\n   Pentium optimiation with small code but this is poor for decryption\r\n   so we need to control this with the following VC++ pragmas\r\n*/\r\n\r\n#if defined( _MSC_VER ) && !defined( _WIN64 )\r\n#pragma optimize( \"s\", on )\r\n#endif\r\n\r\n/* Given the column (c) of the output state variable, the following\r\n   macros give the input state variables which are needed in its\r\n   computation for each row (r) of the state. All the alternative\r\n   macros give the same end values but expand into different ways\r\n   of calculating these values.  In particular the complex macro\r\n   used for dynamically variable block sizes is designed to expand\r\n   to a compile time constant whenever possible but will expand to\r\n   conditional clauses on some branches (I am grateful to Frank\r\n   Yellin for this construction)\r\n*/\r\n\r\n#define fwd_var(x,r,c)\\\r\n ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\\\r\n : r == 1 ? ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))\\\r\n : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\\\r\n :          ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2)))\r\n\r\n#if defined(FT4_SET)\r\n#undef  dec_fmvars\r\n#define fwd_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,n),fwd_var,rf1,c))\r\n#elif defined(FT1_SET)\r\n#undef  dec_fmvars\r\n#define fwd_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(f,n),fwd_var,rf1,c))\r\n#else\r\n#define fwd_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ fwd_mcol(no_table(x,t_use(s,box),fwd_var,rf1,c)))\r\n#endif\r\n\r\n#if defined(FL4_SET)\r\n#define fwd_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,l),fwd_var,rf1,c))\r\n#elif defined(FL1_SET)\r\n#define fwd_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(f,l),fwd_var,rf1,c))\r\n#else\r\n#define fwd_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ no_table(x,t_use(s,box),fwd_var,rf1,c))\r\n#endif\r\n\r\nAES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1])\r\n{   uint_32t         locals(b0, b1);\r\n    const uint_32t   *kp;\r\n#if defined( dec_fmvars )\r\n    dec_fmvars; /* declare variables for fwd_mcol() if needed */\r\n#endif\r\n\r\n    if( cx->inf.b[0] != 10 * 16 && cx->inf.b[0] != 12 * 16 && cx->inf.b[0] != 14 * 16 )\r\n        return EXIT_FAILURE;\r\n\r\n    kp = cx->ks;\r\n    state_in(b0, in, kp);\r\n\r\n#if (ENC_UNROLL == FULL)\r\n\r\n    switch(cx->inf.b[0])\r\n    {\r\n    case 14 * 16:\r\n        round(fwd_rnd,  b1, b0, kp + 1 * N_COLS);\r\n        round(fwd_rnd,  b0, b1, kp + 2 * N_COLS);\r\n        kp += 2 * N_COLS;\r\n    case 12 * 16:\r\n        round(fwd_rnd,  b1, b0, kp + 1 * N_COLS);\r\n        round(fwd_rnd,  b0, b1, kp + 2 * N_COLS);\r\n        kp += 2 * N_COLS;\r\n    case 10 * 16:\r\n        round(fwd_rnd,  b1, b0, kp + 1 * N_COLS);\r\n        round(fwd_rnd,  b0, b1, kp + 2 * N_COLS);\r\n        round(fwd_rnd,  b1, b0, kp + 3 * N_COLS);\r\n        round(fwd_rnd,  b0, b1, kp + 4 * N_COLS);\r\n        round(fwd_rnd,  b1, b0, kp + 5 * N_COLS);\r\n        round(fwd_rnd,  b0, b1, kp + 6 * N_COLS);\r\n        round(fwd_rnd,  b1, b0, kp + 7 * N_COLS);\r\n        round(fwd_rnd,  b0, b1, kp + 8 * N_COLS);\r\n        round(fwd_rnd,  b1, b0, kp + 9 * N_COLS);\r\n        round(fwd_lrnd, b0, b1, kp +10 * N_COLS);\r\n    }\r\n\r\n#else\r\n\r\n#if (ENC_UNROLL == PARTIAL)\r\n    {   uint_32t    rnd;\r\n        for(rnd = 0; rnd < (cx->inf.b[0] >> 5) - 1; ++rnd)\r\n        {\r\n            kp += N_COLS;\r\n            round(fwd_rnd, b1, b0, kp);\r\n            kp += N_COLS;\r\n            round(fwd_rnd, b0, b1, kp);\r\n        }\r\n        kp += N_COLS;\r\n        round(fwd_rnd,  b1, b0, kp);\r\n#else\r\n    {   uint_32t    rnd;\r\n        for(rnd = 0; rnd < (cx->inf.b[0] >> 4) - 1; ++rnd)\r\n        {\r\n            kp += N_COLS;\r\n            round(fwd_rnd, b1, b0, kp);\r\n            l_copy(b0, b1);\r\n        }\r\n#endif\r\n        kp += N_COLS;\r\n        round(fwd_lrnd, b0, b1, kp);\r\n    }\r\n#endif\r\n\r\n    state_out(out, b0);\r\n    return EXIT_SUCCESS;\r\n}\r\n\r\n#endif\r\n\r\n#if ( FUNCS_IN_C & DECRYPTION_IN_C)\r\n\r\n/* Visual C++ .Net v7.1 provides the fastest encryption code when using\r\n   Pentium optimiation with small code but this is poor for decryption\r\n   so we need to control this with the following VC++ pragmas\r\n*/\r\n\r\n#if defined( _MSC_VER ) && !defined( _WIN64 )\r\n#pragma optimize( \"t\", on )\r\n#endif\r\n\r\n/* Given the column (c) of the output state variable, the following\r\n   macros give the input state variables which are needed in its\r\n   computation for each row (r) of the state. All the alternative\r\n   macros give the same end values but expand into different ways\r\n   of calculating these values.  In particular the complex macro\r\n   used for dynamically variable block sizes is designed to expand\r\n   to a compile time constant whenever possible but will expand to\r\n   conditional clauses on some branches (I am grateful to Frank\r\n   Yellin for this construction)\r\n*/\r\n\r\n#define inv_var(x,r,c)\\\r\n ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\\\r\n : r == 1 ? ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))\\\r\n : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\\\r\n :          ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0)))\r\n\r\n#if defined(IT4_SET)\r\n#undef  dec_imvars\r\n#define inv_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,n),inv_var,rf1,c))\r\n#elif defined(IT1_SET)\r\n#undef  dec_imvars\r\n#define inv_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(i,n),inv_var,rf1,c))\r\n#else\r\n#define inv_rnd(y,x,k,c)    (s(y,c) = inv_mcol((k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c)))\r\n#endif\r\n\r\n#if defined(IL4_SET)\r\n#define inv_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,l),inv_var,rf1,c))\r\n#elif defined(IL1_SET)\r\n#define inv_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(i,l),inv_var,rf1,c))\r\n#else\r\n#define inv_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c))\r\n#endif\r\n\r\n/* This code can work with the decryption key schedule in the   */\r\n/* order that is used for encrytpion (where the 1st decryption  */\r\n/* round key is at the high end ot the schedule) or with a key  */\r\n/* schedule that has been reversed to put the 1st decryption    */\r\n/* round key at the low end of the schedule in memory (when     */\r\n/* AES_REV_DKS is defined)                                      */\r\n\r\n#ifdef AES_REV_DKS\r\n#define key_ofs     0\r\n#define rnd_key(n)  (kp + n * N_COLS)\r\n#else\r\n#define key_ofs     1\r\n#define rnd_key(n)  (kp - n * N_COLS)\r\n#endif\r\n\r\nAES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1])\r\n{   uint_32t        locals(b0, b1);\r\n#if defined( dec_imvars )\r\n    dec_imvars; /* declare variables for inv_mcol() if needed */\r\n#endif\r\n    const uint_32t *kp;\r\n\r\n    if( cx->inf.b[0] != 10 * 16 && cx->inf.b[0] != 12 * 16 && cx->inf.b[0] != 14 * 16 )\r\n        return EXIT_FAILURE;\r\n\r\n    kp = cx->ks + (key_ofs ? (cx->inf.b[0] >> 2) : 0);\r\n    state_in(b0, in, kp);\r\n\r\n#if (DEC_UNROLL == FULL)\r\n\r\n    kp = cx->ks + (key_ofs ? 0 : (cx->inf.b[0] >> 2));\r\n    switch(cx->inf.b[0])\r\n    {\r\n    case 14 * 16:\r\n        round(inv_rnd,  b1, b0, rnd_key(-13));\r\n        round(inv_rnd,  b0, b1, rnd_key(-12));\r\n    case 12 * 16:\r\n        round(inv_rnd,  b1, b0, rnd_key(-11));\r\n        round(inv_rnd,  b0, b1, rnd_key(-10));\r\n    case 10 * 16:\r\n        round(inv_rnd,  b1, b0, rnd_key(-9));\r\n        round(inv_rnd,  b0, b1, rnd_key(-8));\r\n        round(inv_rnd,  b1, b0, rnd_key(-7));\r\n        round(inv_rnd,  b0, b1, rnd_key(-6));\r\n        round(inv_rnd,  b1, b0, rnd_key(-5));\r\n        round(inv_rnd,  b0, b1, rnd_key(-4));\r\n        round(inv_rnd,  b1, b0, rnd_key(-3));\r\n        round(inv_rnd,  b0, b1, rnd_key(-2));\r\n        round(inv_rnd,  b1, b0, rnd_key(-1));\r\n        round(inv_lrnd, b0, b1, rnd_key( 0));\r\n    }\r\n\r\n#else\r\n\r\n#if (DEC_UNROLL == PARTIAL)\r\n    {   uint_32t    rnd;\r\n        for(rnd = 0; rnd < (cx->inf.b[0] >> 5) - 1; ++rnd)\r\n        {\r\n            kp = rnd_key(1);\r\n            round(inv_rnd, b1, b0, kp);\r\n            kp = rnd_key(1);\r\n            round(inv_rnd, b0, b1, kp);\r\n        }\r\n        kp = rnd_key(1);\r\n        round(inv_rnd, b1, b0, kp);\r\n#else\r\n    {   uint_32t    rnd;\r\n        for(rnd = 0; rnd < (cx->inf.b[0] >> 4) - 1; ++rnd)\r\n        {\r\n            kp = rnd_key(1);\r\n            round(inv_rnd, b1, b0, kp);\r\n            l_copy(b0, b1);\r\n        }\r\n#endif\r\n        kp = rnd_key(1);\r\n        round(inv_lrnd, b0, b1, kp);\r\n        }\r\n#endif\r\n\r\n    state_out(out, b0);\r\n    return EXIT_SUCCESS;\r\n}\r\n\r\n#endif\r\n\r\n#if defined(__cplusplus)\r\n}\r\n#endif\r\n"
  },
  {
    "path": "plugins/cordova-plugin-zip/src/ios/aes/aeskey.c",
    "content": "/*\r\n---------------------------------------------------------------------------\r\nCopyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.\r\n\r\nThe redistribution and use of this software (with or without changes)\r\nis allowed without the payment of fees or royalties provided that:\r\n\r\n  source code distributions include the above copyright notice, this\r\n  list of conditions and the following disclaimer;\r\n\r\n  binary distributions include the above copyright notice, this list\r\n  of conditions and the following disclaimer in their documentation.\r\n\r\nThis software is provided 'as is' with no explicit or implied warranties\r\nin respect of its operation, including, but not limited to, correctness\r\nand fitness for purpose.\r\n---------------------------------------------------------------------------\r\nIssue Date: 20/12/2007\r\n*/\r\n\r\n#include \"aesopt.h\"\r\n#include \"aestab.h\"\r\n\r\n#ifdef USE_VIA_ACE_IF_PRESENT\r\n#  include \"aes_via_ace.h\"\r\n#endif\r\n\r\n#if defined(__cplusplus)\r\nextern \"C\"\r\n{\r\n#endif\r\n\r\n/* Initialise the key schedule from the user supplied key. The key\r\n   length can be specified in bytes, with legal values of 16, 24\r\n   and 32, or in bits, with legal values of 128, 192 and 256. These\r\n   values correspond with Nk values of 4, 6 and 8 respectively.\r\n\r\n   The following macros implement a single cycle in the key\r\n   schedule generation process. The number of cycles needed\r\n   for each cx->n_col and nk value is:\r\n\r\n    nk =             4  5  6  7  8\r\n    ------------------------------\r\n    cx->n_col = 4   10  9  8  7  7\r\n    cx->n_col = 5   14 11 10  9  9\r\n    cx->n_col = 6   19 15 12 11 11\r\n    cx->n_col = 7   21 19 16 13 14\r\n    cx->n_col = 8   29 23 19 17 14\r\n*/\r\n\r\n#if defined( REDUCE_CODE_SIZE )\r\n#  define ls_box ls_sub\r\n   uint_32t ls_sub(const uint_32t t, const uint_32t n);\r\n#  define inv_mcol im_sub\r\n   uint_32t im_sub(const uint_32t x);\r\n#  ifdef ENC_KS_UNROLL\r\n#    undef ENC_KS_UNROLL\r\n#  endif\r\n#  ifdef DEC_KS_UNROLL\r\n#    undef DEC_KS_UNROLL\r\n#  endif\r\n#endif\r\n\r\n#if (FUNCS_IN_C & ENC_KEYING_IN_C)\r\n\r\n#if defined(AES_128) || defined( AES_VAR )\r\n\r\n#define ke4(k,i) \\\r\n{   k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \\\r\n    k[4*(i)+5] = ss[1] ^= ss[0]; \\\r\n    k[4*(i)+6] = ss[2] ^= ss[1]; \\\r\n    k[4*(i)+7] = ss[3] ^= ss[2]; \\\r\n}\r\n\r\nAES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1])\r\n{   uint_32t    ss[4];\r\n\r\n    cx->ks[0] = ss[0] = word_in(key, 0);\r\n    cx->ks[1] = ss[1] = word_in(key, 1);\r\n    cx->ks[2] = ss[2] = word_in(key, 2);\r\n    cx->ks[3] = ss[3] = word_in(key, 3);\r\n\r\n#ifdef ENC_KS_UNROLL\r\n    ke4(cx->ks, 0);  ke4(cx->ks, 1);\r\n    ke4(cx->ks, 2);  ke4(cx->ks, 3);\r\n    ke4(cx->ks, 4);  ke4(cx->ks, 5);\r\n    ke4(cx->ks, 6);  ke4(cx->ks, 7);\r\n    ke4(cx->ks, 8);\r\n#else\r\n    {   uint_32t i;\r\n        for(i = 0; i < 9; ++i)\r\n            ke4(cx->ks, i);\r\n    }\r\n#endif\r\n    ke4(cx->ks, 9);\r\n    cx->inf.l = 0;\r\n    cx->inf.b[0] = 10 * 16;\r\n\r\n#ifdef USE_VIA_ACE_IF_PRESENT\r\n    if(VIA_ACE_AVAILABLE)\r\n        cx->inf.b[1] = 0xff;\r\n#endif\r\n    return EXIT_SUCCESS;\r\n}\r\n\r\n#endif\r\n\r\n#if defined(AES_192) || defined( AES_VAR )\r\n\r\n#define kef6(k,i) \\\r\n{   k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \\\r\n    k[6*(i)+ 7] = ss[1] ^= ss[0]; \\\r\n    k[6*(i)+ 8] = ss[2] ^= ss[1]; \\\r\n    k[6*(i)+ 9] = ss[3] ^= ss[2]; \\\r\n}\r\n\r\n#define ke6(k,i) \\\r\n{   kef6(k,i); \\\r\n    k[6*(i)+10] = ss[4] ^= ss[3]; \\\r\n    k[6*(i)+11] = ss[5] ^= ss[4]; \\\r\n}\r\n\r\nAES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1])\r\n{   uint_32t    ss[6];\r\n\r\n    cx->ks[0] = ss[0] = word_in(key, 0);\r\n    cx->ks[1] = ss[1] = word_in(key, 1);\r\n    cx->ks[2] = ss[2] = word_in(key, 2);\r\n    cx->ks[3] = ss[3] = word_in(key, 3);\r\n    cx->ks[4] = ss[4] = word_in(key, 4);\r\n    cx->ks[5] = ss[5] = word_in(key, 5);\r\n\r\n#ifdef ENC_KS_UNROLL\r\n    ke6(cx->ks, 0);  ke6(cx->ks, 1);\r\n    ke6(cx->ks, 2);  ke6(cx->ks, 3);\r\n    ke6(cx->ks, 4);  ke6(cx->ks, 5);\r\n    ke6(cx->ks, 6);\r\n#else\r\n    {   uint_32t i;\r\n        for(i = 0; i < 7; ++i)\r\n            ke6(cx->ks, i);\r\n    }\r\n#endif\r\n    kef6(cx->ks, 7);\r\n    cx->inf.l = 0;\r\n    cx->inf.b[0] = 12 * 16;\r\n\r\n#ifdef USE_VIA_ACE_IF_PRESENT\r\n    if(VIA_ACE_AVAILABLE)\r\n        cx->inf.b[1] = 0xff;\r\n#endif\r\n    return EXIT_SUCCESS;\r\n}\r\n\r\n#endif\r\n\r\n#if defined(AES_256) || defined( AES_VAR )\r\n\r\n#define kef8(k,i) \\\r\n{   k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \\\r\n    k[8*(i)+ 9] = ss[1] ^= ss[0]; \\\r\n    k[8*(i)+10] = ss[2] ^= ss[1]; \\\r\n    k[8*(i)+11] = ss[3] ^= ss[2]; \\\r\n}\r\n\r\n#define ke8(k,i) \\\r\n{   kef8(k,i); \\\r\n    k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); \\\r\n    k[8*(i)+13] = ss[5] ^= ss[4]; \\\r\n    k[8*(i)+14] = ss[6] ^= ss[5]; \\\r\n    k[8*(i)+15] = ss[7] ^= ss[6]; \\\r\n}\r\n\r\nAES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1])\r\n{   uint_32t    ss[8];\r\n\r\n    cx->ks[0] = ss[0] = word_in(key, 0);\r\n    cx->ks[1] = ss[1] = word_in(key, 1);\r\n    cx->ks[2] = ss[2] = word_in(key, 2);\r\n    cx->ks[3] = ss[3] = word_in(key, 3);\r\n    cx->ks[4] = ss[4] = word_in(key, 4);\r\n    cx->ks[5] = ss[5] = word_in(key, 5);\r\n    cx->ks[6] = ss[6] = word_in(key, 6);\r\n    cx->ks[7] = ss[7] = word_in(key, 7);\r\n\r\n#ifdef ENC_KS_UNROLL\r\n    ke8(cx->ks, 0); ke8(cx->ks, 1);\r\n    ke8(cx->ks, 2); ke8(cx->ks, 3);\r\n    ke8(cx->ks, 4); ke8(cx->ks, 5);\r\n#else\r\n    {   uint_32t i;\r\n        for(i = 0; i < 6; ++i)\r\n            ke8(cx->ks,  i);\r\n    }\r\n#endif\r\n    kef8(cx->ks, 6);\r\n    cx->inf.l = 0;\r\n    cx->inf.b[0] = 14 * 16;\r\n\r\n#ifdef USE_VIA_ACE_IF_PRESENT\r\n    if(VIA_ACE_AVAILABLE)\r\n        cx->inf.b[1] = 0xff;\r\n#endif\r\n    return EXIT_SUCCESS;\r\n}\r\n\r\n#endif\r\n\r\n#if defined( AES_VAR )\r\n\r\nAES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1])\r\n{   \r\n    switch(key_len)\r\n    {\r\n    case 16: case 128: return aes_encrypt_key128(key, cx);\r\n    case 24: case 192: return aes_encrypt_key192(key, cx);\r\n    case 32: case 256: return aes_encrypt_key256(key, cx);\r\n    default: return EXIT_FAILURE;\r\n    }\r\n}\r\n\r\n#endif\r\n\r\n#endif\r\n\r\n#if (FUNCS_IN_C & DEC_KEYING_IN_C)\r\n\r\n/* this is used to store the decryption round keys  */\r\n/* in forward or reverse order                      */\r\n\r\n#ifdef AES_REV_DKS\r\n#define v(n,i)  ((n) - (i) + 2 * ((i) & 3))\r\n#else\r\n#define v(n,i)  (i)\r\n#endif\r\n\r\n#if DEC_ROUND == NO_TABLES\r\n#define ff(x)   (x)\r\n#else\r\n#define ff(x)   inv_mcol(x)\r\n#if defined( dec_imvars )\r\n#define d_vars  dec_imvars\r\n#endif\r\n#endif\r\n\r\n#if defined(AES_128) || defined( AES_VAR )\r\n\r\n#define k4e(k,i) \\\r\n{   k[v(40,(4*(i))+4)] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \\\r\n    k[v(40,(4*(i))+5)] = ss[1] ^= ss[0]; \\\r\n    k[v(40,(4*(i))+6)] = ss[2] ^= ss[1]; \\\r\n    k[v(40,(4*(i))+7)] = ss[3] ^= ss[2]; \\\r\n}\r\n\r\n#if 1\r\n\r\n#define kdf4(k,i) \\\r\n{   ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; \\\r\n    ss[1] = ss[1] ^ ss[3]; \\\r\n    ss[2] = ss[2] ^ ss[3]; \\\r\n    ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \\\r\n    ss[i % 4] ^= ss[4]; \\\r\n    ss[4] ^= k[v(40,(4*(i)))];   k[v(40,(4*(i))+4)] = ff(ss[4]); \\\r\n    ss[4] ^= k[v(40,(4*(i))+1)]; k[v(40,(4*(i))+5)] = ff(ss[4]); \\\r\n    ss[4] ^= k[v(40,(4*(i))+2)]; k[v(40,(4*(i))+6)] = ff(ss[4]); \\\r\n    ss[4] ^= k[v(40,(4*(i))+3)]; k[v(40,(4*(i))+7)] = ff(ss[4]); \\\r\n}\r\n\r\n#define kd4(k,i) \\\r\n{   ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \\\r\n    ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \\\r\n    k[v(40,(4*(i))+4)] = ss[4] ^= k[v(40,(4*(i)))]; \\\r\n    k[v(40,(4*(i))+5)] = ss[4] ^= k[v(40,(4*(i))+1)]; \\\r\n    k[v(40,(4*(i))+6)] = ss[4] ^= k[v(40,(4*(i))+2)]; \\\r\n    k[v(40,(4*(i))+7)] = ss[4] ^= k[v(40,(4*(i))+3)]; \\\r\n}\r\n\r\n#define kdl4(k,i) \\\r\n{   ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; \\\r\n    k[v(40,(4*(i))+4)] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; \\\r\n    k[v(40,(4*(i))+5)] = ss[1] ^ ss[3]; \\\r\n    k[v(40,(4*(i))+6)] = ss[0]; \\\r\n    k[v(40,(4*(i))+7)] = ss[1]; \\\r\n}\r\n\r\n#else\r\n\r\n#define kdf4(k,i) \\\r\n{   ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[v(40,(4*(i))+ 4)] = ff(ss[0]); \\\r\n    ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ff(ss[1]); \\\r\n    ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ff(ss[2]); \\\r\n    ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ff(ss[3]); \\\r\n}\r\n\r\n#define kd4(k,i) \\\r\n{   ss[4] = ls_box(ss[3],3) ^ t_use(r,c)[i]; \\\r\n    ss[0] ^= ss[4]; ss[4] = ff(ss[4]); k[v(40,(4*(i))+ 4)] = ss[4] ^= k[v(40,(4*(i)))]; \\\r\n    ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ss[4] ^= k[v(40,(4*(i))+ 1)]; \\\r\n    ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ss[4] ^= k[v(40,(4*(i))+ 2)]; \\\r\n    ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ss[4] ^= k[v(40,(4*(i))+ 3)]; \\\r\n}\r\n\r\n#define kdl4(k,i) \\\r\n{   ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[v(40,(4*(i))+ 4)] = ss[0]; \\\r\n    ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ss[1]; \\\r\n    ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ss[2]; \\\r\n    ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ss[3]; \\\r\n}\r\n\r\n#endif\r\n\r\nAES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1])\r\n{   uint_32t    ss[5];\r\n#if defined( d_vars )\r\n        d_vars;\r\n#endif\r\n    cx->ks[v(40,(0))] = ss[0] = word_in(key, 0);\r\n    cx->ks[v(40,(1))] = ss[1] = word_in(key, 1);\r\n    cx->ks[v(40,(2))] = ss[2] = word_in(key, 2);\r\n    cx->ks[v(40,(3))] = ss[3] = word_in(key, 3);\r\n\r\n#ifdef DEC_KS_UNROLL\r\n     kdf4(cx->ks, 0); kd4(cx->ks, 1);\r\n     kd4(cx->ks, 2);  kd4(cx->ks, 3);\r\n     kd4(cx->ks, 4);  kd4(cx->ks, 5);\r\n     kd4(cx->ks, 6);  kd4(cx->ks, 7);\r\n     kd4(cx->ks, 8);  kdl4(cx->ks, 9);\r\n#else\r\n    {   uint_32t i;\r\n        for(i = 0; i < 10; ++i)\r\n            k4e(cx->ks, i);\r\n#if !(DEC_ROUND == NO_TABLES)\r\n        for(i = N_COLS; i < 10 * N_COLS; ++i)\r\n            cx->ks[i] = inv_mcol(cx->ks[i]);\r\n#endif\r\n    }\r\n#endif\r\n    cx->inf.l = 0;\r\n    cx->inf.b[0] = 10 * 16;\r\n\r\n#ifdef USE_VIA_ACE_IF_PRESENT\r\n    if(VIA_ACE_AVAILABLE)\r\n        cx->inf.b[1] = 0xff;\r\n#endif\r\n    return EXIT_SUCCESS;\r\n}\r\n\r\n#endif\r\n\r\n#if defined(AES_192) || defined( AES_VAR )\r\n\r\n#define k6ef(k,i) \\\r\n{   k[v(48,(6*(i))+ 6)] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \\\r\n    k[v(48,(6*(i))+ 7)] = ss[1] ^= ss[0]; \\\r\n    k[v(48,(6*(i))+ 8)] = ss[2] ^= ss[1]; \\\r\n    k[v(48,(6*(i))+ 9)] = ss[3] ^= ss[2]; \\\r\n}\r\n\r\n#define k6e(k,i) \\\r\n{   k6ef(k,i); \\\r\n    k[v(48,(6*(i))+10)] = ss[4] ^= ss[3]; \\\r\n    k[v(48,(6*(i))+11)] = ss[5] ^= ss[4]; \\\r\n}\r\n\r\n#define kdf6(k,i) \\\r\n{   ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ff(ss[0]); \\\r\n    ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ff(ss[1]); \\\r\n    ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ff(ss[2]); \\\r\n    ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ff(ss[3]); \\\r\n    ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ff(ss[4]); \\\r\n    ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ff(ss[5]); \\\r\n}\r\n\r\n#define kd6(k,i) \\\r\n{   ss[6] = ls_box(ss[5],3) ^ t_use(r,c)[i]; \\\r\n    ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[v(48,(6*(i))+ 6)] = ss[6] ^= k[v(48,(6*(i)))]; \\\r\n    ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[6] ^= k[v(48,(6*(i))+ 1)]; \\\r\n    ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[6] ^= k[v(48,(6*(i))+ 2)]; \\\r\n    ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[6] ^= k[v(48,(6*(i))+ 3)]; \\\r\n    ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ss[6] ^= k[v(48,(6*(i))+ 4)]; \\\r\n    ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ss[6] ^= k[v(48,(6*(i))+ 5)]; \\\r\n}\r\n\r\n#define kdl6(k,i) \\\r\n{   ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ss[0]; \\\r\n    ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[1]; \\\r\n    ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[2]; \\\r\n    ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[3]; \\\r\n}\r\n\r\nAES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1])\r\n{   uint_32t    ss[7];\r\n#if defined( d_vars )\r\n        d_vars;\r\n#endif\r\n    cx->ks[v(48,(0))] = ss[0] = word_in(key, 0);\r\n    cx->ks[v(48,(1))] = ss[1] = word_in(key, 1);\r\n    cx->ks[v(48,(2))] = ss[2] = word_in(key, 2);\r\n    cx->ks[v(48,(3))] = ss[3] = word_in(key, 3);\r\n\r\n#ifdef DEC_KS_UNROLL\r\n    cx->ks[v(48,(4))] = ff(ss[4] = word_in(key, 4));\r\n    cx->ks[v(48,(5))] = ff(ss[5] = word_in(key, 5));\r\n    kdf6(cx->ks, 0); kd6(cx->ks, 1);\r\n    kd6(cx->ks, 2);  kd6(cx->ks, 3);\r\n    kd6(cx->ks, 4);  kd6(cx->ks, 5);\r\n    kd6(cx->ks, 6);  kdl6(cx->ks, 7);\r\n#else\r\n    cx->ks[v(48,(4))] = ss[4] = word_in(key, 4);\r\n    cx->ks[v(48,(5))] = ss[5] = word_in(key, 5);\r\n    {   uint_32t i;\r\n\r\n        for(i = 0; i < 7; ++i)\r\n            k6e(cx->ks, i);\r\n        k6ef(cx->ks, 7);\r\n#if !(DEC_ROUND == NO_TABLES)\r\n        for(i = N_COLS; i < 12 * N_COLS; ++i)\r\n            cx->ks[i] = inv_mcol(cx->ks[i]);\r\n#endif\r\n    }\r\n#endif\r\n    cx->inf.l = 0;\r\n    cx->inf.b[0] = 12 * 16;\r\n\r\n#ifdef USE_VIA_ACE_IF_PRESENT\r\n    if(VIA_ACE_AVAILABLE)\r\n        cx->inf.b[1] = 0xff;\r\n#endif\r\n    return EXIT_SUCCESS;\r\n}\r\n\r\n#endif\r\n\r\n#if defined(AES_256) || defined( AES_VAR )\r\n\r\n#define k8ef(k,i) \\\r\n{   k[v(56,(8*(i))+ 8)] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \\\r\n    k[v(56,(8*(i))+ 9)] = ss[1] ^= ss[0]; \\\r\n    k[v(56,(8*(i))+10)] = ss[2] ^= ss[1]; \\\r\n    k[v(56,(8*(i))+11)] = ss[3] ^= ss[2]; \\\r\n}\r\n\r\n#define k8e(k,i) \\\r\n{   k8ef(k,i); \\\r\n    k[v(56,(8*(i))+12)] = ss[4] ^= ls_box(ss[3],0); \\\r\n    k[v(56,(8*(i))+13)] = ss[5] ^= ss[4]; \\\r\n    k[v(56,(8*(i))+14)] = ss[6] ^= ss[5]; \\\r\n    k[v(56,(8*(i))+15)] = ss[7] ^= ss[6]; \\\r\n}\r\n\r\n#define kdf8(k,i) \\\r\n{   ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ff(ss[0]); \\\r\n    ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ff(ss[1]); \\\r\n    ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ff(ss[2]); \\\r\n    ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ff(ss[3]); \\\r\n    ss[4] ^= ls_box(ss[3],0); k[v(56,(8*(i))+12)] = ff(ss[4]); \\\r\n    ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ff(ss[5]); \\\r\n    ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ff(ss[6]); \\\r\n    ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ff(ss[7]); \\\r\n}\r\n\r\n#define kd8(k,i) \\\r\n{   ss[8] = ls_box(ss[7],3) ^ t_use(r,c)[i]; \\\r\n    ss[0] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+ 8)] = ss[8] ^= k[v(56,(8*(i)))]; \\\r\n    ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[8] ^= k[v(56,(8*(i))+ 1)]; \\\r\n    ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[8] ^= k[v(56,(8*(i))+ 2)]; \\\r\n    ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[8] ^= k[v(56,(8*(i))+ 3)]; \\\r\n    ss[8] = ls_box(ss[3],0); \\\r\n    ss[4] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+12)] = ss[8] ^= k[v(56,(8*(i))+ 4)]; \\\r\n    ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ss[8] ^= k[v(56,(8*(i))+ 5)]; \\\r\n    ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ss[8] ^= k[v(56,(8*(i))+ 6)]; \\\r\n    ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ss[8] ^= k[v(56,(8*(i))+ 7)]; \\\r\n}\r\n\r\n#define kdl8(k,i) \\\r\n{   ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ss[0]; \\\r\n    ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[1]; \\\r\n    ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[2]; \\\r\n    ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[3]; \\\r\n}\r\n\r\nAES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1])\r\n{   uint_32t    ss[9];\r\n#if defined( d_vars )\r\n        d_vars;\r\n#endif\r\n    cx->ks[v(56,(0))] = ss[0] = word_in(key, 0);\r\n    cx->ks[v(56,(1))] = ss[1] = word_in(key, 1);\r\n    cx->ks[v(56,(2))] = ss[2] = word_in(key, 2);\r\n    cx->ks[v(56,(3))] = ss[3] = word_in(key, 3);\r\n\r\n#ifdef DEC_KS_UNROLL\r\n    cx->ks[v(56,(4))] = ff(ss[4] = word_in(key, 4));\r\n    cx->ks[v(56,(5))] = ff(ss[5] = word_in(key, 5));\r\n    cx->ks[v(56,(6))] = ff(ss[6] = word_in(key, 6));\r\n    cx->ks[v(56,(7))] = ff(ss[7] = word_in(key, 7));\r\n    kdf8(cx->ks, 0); kd8(cx->ks, 1);\r\n    kd8(cx->ks, 2);  kd8(cx->ks, 3);\r\n    kd8(cx->ks, 4);  kd8(cx->ks, 5);\r\n    kdl8(cx->ks, 6);\r\n#else\r\n    cx->ks[v(56,(4))] = ss[4] = word_in(key, 4);\r\n    cx->ks[v(56,(5))] = ss[5] = word_in(key, 5);\r\n    cx->ks[v(56,(6))] = ss[6] = word_in(key, 6);\r\n    cx->ks[v(56,(7))] = ss[7] = word_in(key, 7);\r\n    {   uint_32t i;\r\n\r\n        for(i = 0; i < 6; ++i)\r\n            k8e(cx->ks,  i);\r\n        k8ef(cx->ks,  6);\r\n#if !(DEC_ROUND == NO_TABLES)\r\n        for(i = N_COLS; i < 14 * N_COLS; ++i)\r\n            cx->ks[i] = inv_mcol(cx->ks[i]);\r\n#endif\r\n    }\r\n#endif\r\n    cx->inf.l = 0;\r\n    cx->inf.b[0] = 14 * 16;\r\n\r\n#ifdef USE_VIA_ACE_IF_PRESENT\r\n    if(VIA_ACE_AVAILABLE)\r\n        cx->inf.b[1] = 0xff;\r\n#endif\r\n    return EXIT_SUCCESS;\r\n}\r\n\r\n#endif\r\n\r\n#if defined( AES_VAR )\r\n\r\nAES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1])\r\n{\r\n    switch(key_len)\r\n    {\r\n    case 16: case 128: return aes_decrypt_key128(key, cx);\r\n    case 24: case 192: return aes_decrypt_key192(key, cx);\r\n    case 32: case 256: return aes_decrypt_key256(key, cx);\r\n    default: return EXIT_FAILURE;\r\n    }\r\n}\r\n\r\n#endif\r\n\r\n#endif\r\n\r\n#if defined(__cplusplus)\r\n}\r\n#endif\r\n"
  },
  {
    "path": "plugins/cordova-plugin-zip/src/ios/aes/aesopt.h",
    "content": "/*\r\n---------------------------------------------------------------------------\r\nCopyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.\r\n\r\nThe redistribution and use of this software (with or without changes)\r\nis allowed without the payment of fees or royalties provided that:\r\n\r\n  source code distributions include the above copyright notice, this\r\n  list of conditions and the following disclaimer;\r\n\r\n  binary distributions include the above copyright notice, this list\r\n  of conditions and the following disclaimer in their documentation.\r\n\r\nThis software is provided 'as is' with no explicit or implied warranties\r\nin respect of its operation, including, but not limited to, correctness\r\nand fitness for purpose.\r\n---------------------------------------------------------------------------\r\nIssue Date: 20/12/2007\r\n\r\n This file contains the compilation options for AES (Rijndael) and code\r\n that is common across encryption, key scheduling and table generation.\r\n\r\n OPERATION\r\n\r\n These source code files implement the AES algorithm Rijndael designed by\r\n Joan Daemen and Vincent Rijmen. This version is designed for the standard\r\n block size of 16 bytes and for key sizes of 128, 192 and 256 bits (16, 24\r\n and 32 bytes).\r\n\r\n This version is designed for flexibility and speed using operations on\r\n 32-bit words rather than operations on bytes.  It can be compiled with\r\n either big or little endian internal byte order but is faster when the\r\n native byte order for the processor is used.\r\n\r\n THE CIPHER INTERFACE\r\n\r\n The cipher interface is implemented as an array of bytes in which lower\r\n AES bit sequence indexes map to higher numeric significance within bytes.\r\n\r\n  uint_8t                 (an unsigned  8-bit type)\r\n  uint_32t                (an unsigned 32-bit type)\r\n  struct aes_encrypt_ctx  (structure for the cipher encryption context)\r\n  struct aes_decrypt_ctx  (structure for the cipher decryption context)\r\n  AES_RETURN                the function return type\r\n\r\n  C subroutine calls:\r\n\r\n  AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1]);\r\n  AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1]);\r\n  AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]);\r\n  AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out,\r\n                                                  const aes_encrypt_ctx cx[1]);\r\n\r\n  AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1]);\r\n  AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1]);\r\n  AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]);\r\n  AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out,\r\n                                                  const aes_decrypt_ctx cx[1]);\r\n\r\n IMPORTANT NOTE: If you are using this C interface with dynamic tables make sure that\r\n you call aes_init() before AES is used so that the tables are initialised.\r\n\r\n C++ aes class subroutines:\r\n\r\n     Class AESencrypt  for encryption\r\n\r\n      Construtors:\r\n          AESencrypt(void)\r\n          AESencrypt(const unsigned char *key) - 128 bit key\r\n      Members:\r\n          AES_RETURN key128(const unsigned char *key)\r\n          AES_RETURN key192(const unsigned char *key)\r\n          AES_RETURN key256(const unsigned char *key)\r\n          AES_RETURN encrypt(const unsigned char *in, unsigned char *out) const\r\n\r\n      Class AESdecrypt  for encryption\r\n      Construtors:\r\n          AESdecrypt(void)\r\n          AESdecrypt(const unsigned char *key) - 128 bit key\r\n      Members:\r\n          AES_RETURN key128(const unsigned char *key)\r\n          AES_RETURN key192(const unsigned char *key)\r\n          AES_RETURN key256(const unsigned char *key)\r\n          AES_RETURN decrypt(const unsigned char *in, unsigned char *out) const\r\n*/\r\n\r\n#if !defined( _AESOPT_H )\r\n#define _AESOPT_H\r\n\r\n#if defined( __cplusplus )\r\n#include \"aescpp.h\"\r\n#else\r\n#include \"aes.h\"\r\n#endif\r\n\r\n/*  PLATFORM SPECIFIC INCLUDES */\r\n\r\n#include \"brg_endian.h\"\r\n\r\n/*  CONFIGURATION - THE USE OF DEFINES\r\n\r\n    Later in this section there are a number of defines that control the\r\n    operation of the code.  In each section, the purpose of each define is\r\n    explained so that the relevant form can be included or excluded by\r\n    setting either 1's or 0's respectively on the branches of the related\r\n    #if clauses.  The following local defines should not be changed.\r\n*/\r\n\r\n#define ENCRYPTION_IN_C     1\r\n#define DECRYPTION_IN_C     2\r\n#define ENC_KEYING_IN_C     4\r\n#define DEC_KEYING_IN_C     8\r\n\r\n#define NO_TABLES           0\r\n#define ONE_TABLE           1\r\n#define FOUR_TABLES         4\r\n#define NONE                0\r\n#define PARTIAL             1\r\n#define FULL                2\r\n\r\n/*  --- START OF USER CONFIGURED OPTIONS --- */\r\n\r\n/*  1. BYTE ORDER WITHIN 32 BIT WORDS\r\n\r\n    The fundamental data processing units in Rijndael are 8-bit bytes. The\r\n    input, output and key input are all enumerated arrays of bytes in which\r\n    bytes are numbered starting at zero and increasing to one less than the\r\n    number of bytes in the array in question. This enumeration is only used\r\n    for naming bytes and does not imply any adjacency or order relationship\r\n    from one byte to another. When these inputs and outputs are considered\r\n    as bit sequences, bits 8*n to 8*n+7 of the bit sequence are mapped to\r\n    byte[n] with bit 8n+i in the sequence mapped to bit 7-i within the byte.\r\n    In this implementation bits are numbered from 0 to 7 starting at the\r\n    numerically least significant end of each byte (bit n represents 2^n).\r\n\r\n    However, Rijndael can be implemented more efficiently using 32-bit\r\n    words by packing bytes into words so that bytes 4*n to 4*n+3 are placed\r\n    into word[n]. While in principle these bytes can be assembled into words\r\n    in any positions, this implementation only supports the two formats in\r\n    which bytes in adjacent positions within words also have adjacent byte\r\n    numbers. This order is called big-endian if the lowest numbered bytes\r\n    in words have the highest numeric significance and little-endian if the\r\n    opposite applies.\r\n\r\n    This code can work in either order irrespective of the order used by the\r\n    machine on which it runs. Normally the internal byte order will be set\r\n    to the order of the processor on which the code is to be run but this\r\n    define can be used to reverse this in special situations\r\n\r\n    WARNING: Assembler code versions rely on PLATFORM_BYTE_ORDER being set.\r\n    This define will hence be redefined later (in section 4) if necessary\r\n*/\r\n\r\n#if 1\r\n#  define ALGORITHM_BYTE_ORDER PLATFORM_BYTE_ORDER\r\n#elif 0\r\n#  define ALGORITHM_BYTE_ORDER IS_LITTLE_ENDIAN\r\n#elif 0\r\n#  define ALGORITHM_BYTE_ORDER IS_BIG_ENDIAN\r\n#else\r\n#  error The algorithm byte order is not defined\r\n#endif\r\n\r\n/*  2. VIA ACE SUPPORT */\r\n\r\n#if !defined(__APPLE__) && defined( __GNUC__ ) && defined( __i386__ ) \\\r\n || defined( _WIN32   ) && defined( _M_IX86  ) \\\r\n && !(defined( _WIN64 ) || defined( _WIN32_WCE ) || defined( _MSC_VER ) && ( _MSC_VER <= 800 ))\r\n#  define VIA_ACE_POSSIBLE\r\n#endif\r\n\r\n/*  Define this option if support for the VIA ACE is required. This uses\r\n    inline assembler instructions and is only implemented for the Microsoft,\r\n    Intel and GCC compilers.  If VIA ACE is known to be present, then defining\r\n    ASSUME_VIA_ACE_PRESENT will remove the ordinary encryption/decryption\r\n    code.  If USE_VIA_ACE_IF_PRESENT is defined then VIA ACE will be used if\r\n    it is detected (both present and enabled) but the normal AES code will\r\n    also be present.\r\n\r\n    When VIA ACE is to be used, all AES encryption contexts MUST be 16 byte\r\n    aligned; other input/output buffers do not need to be 16 byte aligned\r\n    but there are very large performance gains if this can be arranged.\r\n    VIA ACE also requires the decryption key schedule to be in reverse\r\n    order (which later checks below ensure).\r\n*/\r\n\r\n#if 1 && defined( VIA_ACE_POSSIBLE ) && !defined( USE_VIA_ACE_IF_PRESENT )\r\n#  define USE_VIA_ACE_IF_PRESENT\r\n#endif\r\n\r\n#if 0 && defined( VIA_ACE_POSSIBLE ) && !defined( ASSUME_VIA_ACE_PRESENT )\r\n#  define ASSUME_VIA_ACE_PRESENT\r\n#  endif\r\n\r\n/*  3. ASSEMBLER SUPPORT\r\n\r\n    This define (which can be on the command line) enables the use of the\r\n    assembler code routines for encryption, decryption and key scheduling\r\n    as follows:\r\n\r\n    ASM_X86_V1C uses the assembler (aes_x86_v1.asm) with large tables for\r\n                encryption and decryption and but with key scheduling in C\r\n    ASM_X86_V2  uses assembler (aes_x86_v2.asm) with compressed tables for\r\n                encryption, decryption and key scheduling\r\n    ASM_X86_V2C uses assembler (aes_x86_v2.asm) with compressed tables for\r\n                encryption and decryption and but with key scheduling in C\r\n    ASM_AMD64_C uses assembler (aes_amd64.asm) with compressed tables for\r\n                encryption and decryption and but with key scheduling in C\r\n\r\n    Change one 'if 0' below to 'if 1' to select the version or define\r\n    as a compilation option.\r\n*/\r\n\r\n#if 0 && !defined( ASM_X86_V1C )\r\n#  define ASM_X86_V1C\r\n#elif 0 && !defined( ASM_X86_V2  )\r\n#  define ASM_X86_V2\r\n#elif 0 && !defined( ASM_X86_V2C )\r\n#  define ASM_X86_V2C\r\n#elif 0 && !defined( ASM_AMD64_C )\r\n#  define ASM_AMD64_C\r\n#endif\r\n\r\n#if (defined ( ASM_X86_V1C ) || defined( ASM_X86_V2 ) || defined( ASM_X86_V2C )) \\\r\n      && !defined( _M_IX86 ) || defined( ASM_AMD64_C ) && !defined( _M_X64 )\r\n#  error Assembler code is only available for x86 and AMD64 systems\r\n#endif\r\n\r\n/*  4. FAST INPUT/OUTPUT OPERATIONS.\r\n\r\n    On some machines it is possible to improve speed by transferring the\r\n    bytes in the input and output arrays to and from the internal 32-bit\r\n    variables by addressing these arrays as if they are arrays of 32-bit\r\n    words.  On some machines this will always be possible but there may\r\n    be a large performance penalty if the byte arrays are not aligned on\r\n    the normal word boundaries. On other machines this technique will\r\n    lead to memory access errors when such 32-bit word accesses are not\r\n    properly aligned. The option SAFE_IO avoids such problems but will\r\n    often be slower on those machines that support misaligned access\r\n    (especially so if care is taken to align the input  and output byte\r\n    arrays on 32-bit word boundaries). If SAFE_IO is not defined it is\r\n    assumed that access to byte arrays as if they are arrays of 32-bit\r\n    words will not cause problems when such accesses are misaligned.\r\n*/\r\n#if 1 && !defined( _MSC_VER )\r\n#  define SAFE_IO\r\n#endif\r\n\r\n/*  5. LOOP UNROLLING\r\n\r\n    The code for encryption and decrytpion cycles through a number of rounds\r\n    that can be implemented either in a loop or by expanding the code into a\r\n    long sequence of instructions, the latter producing a larger program but\r\n    one that will often be much faster. The latter is called loop unrolling.\r\n    There are also potential speed advantages in expanding two iterations in\r\n    a loop with half the number of iterations, which is called partial loop\r\n    unrolling.  The following options allow partial or full loop unrolling\r\n    to be set independently for encryption and decryption\r\n*/\r\n#if 1\r\n#  define ENC_UNROLL  FULL\r\n#elif 0\r\n#  define ENC_UNROLL  PARTIAL\r\n#else\r\n#  define ENC_UNROLL  NONE\r\n#endif\r\n\r\n#if 1\r\n#  define DEC_UNROLL  FULL\r\n#elif 0\r\n#  define DEC_UNROLL  PARTIAL\r\n#else\r\n#  define DEC_UNROLL  NONE\r\n#endif\r\n\r\n#if 1\r\n#  define ENC_KS_UNROLL\r\n#endif\r\n\r\n#if 1\r\n#  define DEC_KS_UNROLL\r\n#endif\r\n\r\n/*  6. FAST FINITE FIELD OPERATIONS\r\n\r\n    If this section is included, tables are used to provide faster finite\r\n    field arithmetic (this has no effect if FIXED_TABLES is defined).\r\n*/\r\n#if 1\r\n#  define FF_TABLES\r\n#endif\r\n\r\n/*  7. INTERNAL STATE VARIABLE FORMAT\r\n\r\n    The internal state of Rijndael is stored in a number of local 32-bit\r\n    word varaibles which can be defined either as an array or as individual\r\n    names variables. Include this section if you want to store these local\r\n    varaibles in arrays. Otherwise individual local variables will be used.\r\n*/\r\n#if 1\r\n#  define ARRAYS\r\n#endif\r\n\r\n/*  8. FIXED OR DYNAMIC TABLES\r\n\r\n    When this section is included the tables used by the code are compiled\r\n    statically into the binary file.  Otherwise the subroutine aes_init()\r\n    must be called to compute them before the code is first used.\r\n*/\r\n#if 1 && !(defined( _MSC_VER ) && ( _MSC_VER <= 800 ))\r\n#  define FIXED_TABLES\r\n#endif\r\n\r\n/*  9. MASKING OR CASTING FROM LONGER VALUES TO BYTES\r\n\r\n    In some systems it is better to mask longer values to extract bytes \r\n    rather than using a cast. This option allows this choice.\r\n*/\r\n#if 0\r\n#  define to_byte(x)  ((uint_8t)(x))\r\n#else\r\n#  define to_byte(x)  ((x) & 0xff)\r\n#endif\r\n\r\n/*  10. TABLE ALIGNMENT\r\n\r\n    On some sytsems speed will be improved by aligning the AES large lookup\r\n    tables on particular boundaries. This define should be set to a power of\r\n    two giving the desired alignment. It can be left undefined if alignment\r\n    is not needed.  This option is specific to the Microsft VC++ compiler -\r\n    it seems to sometimes cause trouble for the VC++ version 6 compiler.\r\n*/\r\n\r\n#if 1 && defined( _MSC_VER ) && ( _MSC_VER >= 1300 )\r\n#  define TABLE_ALIGN 32\r\n#endif\r\n\r\n/*  11.  REDUCE CODE AND TABLE SIZE\r\n\r\n    This replaces some expanded macros with function calls if AES_ASM_V2 or\r\n    AES_ASM_V2C are defined\r\n*/\r\n\r\n#if 1 && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C ))\r\n#  define REDUCE_CODE_SIZE\r\n#endif\r\n\r\n/*  12. TABLE OPTIONS\r\n\r\n    This cipher proceeds by repeating in a number of cycles known as 'rounds'\r\n    which are implemented by a round function which can optionally be speeded\r\n    up using tables.  The basic tables are each 256 32-bit words, with either\r\n    one or four tables being required for each round function depending on\r\n    how much speed is required. The encryption and decryption round functions\r\n    are different and the last encryption and decrytpion round functions are\r\n    different again making four different round functions in all.\r\n\r\n    This means that:\r\n      1. Normal encryption and decryption rounds can each use either 0, 1\r\n         or 4 tables and table spaces of 0, 1024 or 4096 bytes each.\r\n      2. The last encryption and decryption rounds can also use either 0, 1\r\n         or 4 tables and table spaces of 0, 1024 or 4096 bytes each.\r\n\r\n    Include or exclude the appropriate definitions below to set the number\r\n    of tables used by this implementation.\r\n*/\r\n\r\n#if 1   /* set tables for the normal encryption round */\r\n#  define ENC_ROUND   FOUR_TABLES\r\n#elif 0\r\n#  define ENC_ROUND   ONE_TABLE\r\n#else\r\n#  define ENC_ROUND   NO_TABLES\r\n#endif\r\n\r\n#if 1   /* set tables for the last encryption round */\r\n#  define LAST_ENC_ROUND  FOUR_TABLES\r\n#elif 0\r\n#  define LAST_ENC_ROUND  ONE_TABLE\r\n#else\r\n#  define LAST_ENC_ROUND  NO_TABLES\r\n#endif\r\n\r\n#if 1   /* set tables for the normal decryption round */\r\n#  define DEC_ROUND   FOUR_TABLES\r\n#elif 0\r\n#  define DEC_ROUND   ONE_TABLE\r\n#else\r\n#  define DEC_ROUND   NO_TABLES\r\n#endif\r\n\r\n#if 1   /* set tables for the last decryption round */\r\n#  define LAST_DEC_ROUND  FOUR_TABLES\r\n#elif 0\r\n#  define LAST_DEC_ROUND  ONE_TABLE\r\n#else\r\n#  define LAST_DEC_ROUND  NO_TABLES\r\n#endif\r\n\r\n/*  The decryption key schedule can be speeded up with tables in the same\r\n    way that the round functions can.  Include or exclude the following\r\n    defines to set this requirement.\r\n*/\r\n#if 1\r\n#  define KEY_SCHED   FOUR_TABLES\r\n#elif 0\r\n#  define KEY_SCHED   ONE_TABLE\r\n#else\r\n#  define KEY_SCHED   NO_TABLES\r\n#endif\r\n\r\n/*  ---- END OF USER CONFIGURED OPTIONS ---- */\r\n\r\n/* VIA ACE support is only available for VC++ and GCC */\r\n\r\n#if !defined( _MSC_VER ) && !defined( __GNUC__ )\r\n#  if defined( ASSUME_VIA_ACE_PRESENT )\r\n#    undef ASSUME_VIA_ACE_PRESENT\r\n#  endif\r\n#  if defined( USE_VIA_ACE_IF_PRESENT )\r\n#    undef USE_VIA_ACE_IF_PRESENT\r\n#  endif\r\n#endif\r\n\r\n#if defined( ASSUME_VIA_ACE_PRESENT ) && !defined( USE_VIA_ACE_IF_PRESENT )\r\n#  define USE_VIA_ACE_IF_PRESENT\r\n#endif\r\n\r\n#if defined( USE_VIA_ACE_IF_PRESENT ) && !defined ( AES_REV_DKS )\r\n#  define AES_REV_DKS\r\n#endif\r\n\r\n/* Assembler support requires the use of platform byte order */\r\n\r\n#if ( defined( ASM_X86_V1C ) || defined( ASM_X86_V2C ) || defined( ASM_AMD64_C ) ) \\\r\n    && (ALGORITHM_BYTE_ORDER != PLATFORM_BYTE_ORDER)\r\n#  undef  ALGORITHM_BYTE_ORDER\r\n#  define ALGORITHM_BYTE_ORDER PLATFORM_BYTE_ORDER\r\n#endif\r\n\r\n/* In this implementation the columns of the state array are each held in\r\n   32-bit words. The state array can be held in various ways: in an array\r\n   of words, in a number of individual word variables or in a number of\r\n   processor registers. The following define maps a variable name x and\r\n   a column number c to the way the state array variable is to be held.\r\n   The first define below maps the state into an array x[c] whereas the\r\n   second form maps the state into a number of individual variables x0,\r\n   x1, etc.  Another form could map individual state colums to machine\r\n   register names.\r\n*/\r\n\r\n#if defined( ARRAYS )\r\n#  define s(x,c) x[c]\r\n#else\r\n#  define s(x,c) x##c\r\n#endif\r\n\r\n/*  This implementation provides subroutines for encryption, decryption\r\n    and for setting the three key lengths (separately) for encryption\r\n    and decryption. Since not all functions are needed, masks are set\r\n    up here to determine which will be implemented in C\r\n*/\r\n\r\n#if !defined( AES_ENCRYPT )\r\n#  define EFUNCS_IN_C   0\r\n#elif defined( ASSUME_VIA_ACE_PRESENT ) || defined( ASM_X86_V1C ) \\\r\n    || defined( ASM_X86_V2C ) || defined( ASM_AMD64_C )\r\n#  define EFUNCS_IN_C   ENC_KEYING_IN_C\r\n#elif !defined( ASM_X86_V2 )\r\n#  define EFUNCS_IN_C   ( ENCRYPTION_IN_C | ENC_KEYING_IN_C )\r\n#else\r\n#  define EFUNCS_IN_C   0\r\n#endif\r\n\r\n#if !defined( AES_DECRYPT )\r\n#  define DFUNCS_IN_C   0\r\n#elif defined( ASSUME_VIA_ACE_PRESENT ) || defined( ASM_X86_V1C ) \\\r\n    || defined( ASM_X86_V2C ) || defined( ASM_AMD64_C )\r\n#  define DFUNCS_IN_C   DEC_KEYING_IN_C\r\n#elif !defined( ASM_X86_V2 )\r\n#  define DFUNCS_IN_C   ( DECRYPTION_IN_C | DEC_KEYING_IN_C )\r\n#else\r\n#  define DFUNCS_IN_C   0\r\n#endif\r\n\r\n#define FUNCS_IN_C  ( EFUNCS_IN_C | DFUNCS_IN_C )\r\n\r\n/* END OF CONFIGURATION OPTIONS */\r\n\r\n#define RC_LENGTH   (5 * (AES_BLOCK_SIZE / 4 - 2))\r\n\r\n/* Disable or report errors on some combinations of options */\r\n\r\n#if ENC_ROUND == NO_TABLES && LAST_ENC_ROUND != NO_TABLES\r\n#  undef  LAST_ENC_ROUND\r\n#  define LAST_ENC_ROUND  NO_TABLES\r\n#elif ENC_ROUND == ONE_TABLE && LAST_ENC_ROUND == FOUR_TABLES\r\n#  undef  LAST_ENC_ROUND\r\n#  define LAST_ENC_ROUND  ONE_TABLE\r\n#endif\r\n\r\n#if ENC_ROUND == NO_TABLES && ENC_UNROLL != NONE\r\n#  undef  ENC_UNROLL\r\n#  define ENC_UNROLL  NONE\r\n#endif\r\n\r\n#if DEC_ROUND == NO_TABLES && LAST_DEC_ROUND != NO_TABLES\r\n#  undef  LAST_DEC_ROUND\r\n#  define LAST_DEC_ROUND  NO_TABLES\r\n#elif DEC_ROUND == ONE_TABLE && LAST_DEC_ROUND == FOUR_TABLES\r\n#  undef  LAST_DEC_ROUND\r\n#  define LAST_DEC_ROUND  ONE_TABLE\r\n#endif\r\n\r\n#if DEC_ROUND == NO_TABLES && DEC_UNROLL != NONE\r\n#  undef  DEC_UNROLL\r\n#  define DEC_UNROLL  NONE\r\n#endif\r\n\r\n#if defined( bswap32 )\r\n#  define aes_sw32    bswap32\r\n#elif defined( bswap_32 )\r\n#  define aes_sw32    bswap_32\r\n#else\r\n#  define brot(x,n)   (((uint_32t)(x) <<  n) | ((uint_32t)(x) >> (32 - n)))\r\n#  define aes_sw32(x) ((brot((x),8) & 0x00ff00ff) | (brot((x),24) & 0xff00ff00))\r\n#endif\r\n\r\n/*  upr(x,n):  rotates bytes within words by n positions, moving bytes to\r\n               higher index positions with wrap around into low positions\r\n    ups(x,n):  moves bytes by n positions to higher index positions in\r\n               words but without wrap around\r\n    bval(x,n): extracts a byte from a word\r\n\r\n    WARNING:   The definitions given here are intended only for use with\r\n               unsigned variables and with shift counts that are compile\r\n               time constants\r\n*/\r\n\r\n#if ( ALGORITHM_BYTE_ORDER == IS_LITTLE_ENDIAN )\r\n#  define upr(x,n)      (((uint_32t)(x) << (8 * (n))) | ((uint_32t)(x) >> (32 - 8 * (n))))\r\n#  define ups(x,n)      ((uint_32t) (x) << (8 * (n)))\r\n#  define bval(x,n)     to_byte((x) >> (8 * (n)))\r\n#  define bytes2word(b0, b1, b2, b3)  \\\r\n        (((uint_32t)(b3) << 24) | ((uint_32t)(b2) << 16) | ((uint_32t)(b1) << 8) | (b0))\r\n#endif\r\n\r\n#if ( ALGORITHM_BYTE_ORDER == IS_BIG_ENDIAN )\r\n#  define upr(x,n)      (((uint_32t)(x) >> (8 * (n))) | ((uint_32t)(x) << (32 - 8 * (n))))\r\n#  define ups(x,n)      ((uint_32t) (x) >> (8 * (n)))\r\n#  define bval(x,n)     to_byte((x) >> (24 - 8 * (n)))\r\n#  define bytes2word(b0, b1, b2, b3)  \\\r\n        (((uint_32t)(b0) << 24) | ((uint_32t)(b1) << 16) | ((uint_32t)(b2) << 8) | (b3))\r\n#endif\r\n\r\n#if defined( SAFE_IO )\r\n#  define word_in(x,c)    bytes2word(((const uint_8t*)(x)+4*c)[0], ((const uint_8t*)(x)+4*c)[1], \\\r\n                                   ((const uint_8t*)(x)+4*c)[2], ((const uint_8t*)(x)+4*c)[3])\r\n#  define word_out(x,c,v) { ((uint_8t*)(x)+4*c)[0] = bval(v,0); ((uint_8t*)(x)+4*c)[1] = bval(v,1); \\\r\n                          ((uint_8t*)(x)+4*c)[2] = bval(v,2); ((uint_8t*)(x)+4*c)[3] = bval(v,3); }\r\n#elif ( ALGORITHM_BYTE_ORDER == PLATFORM_BYTE_ORDER )\r\n#  define word_in(x,c)    (*((uint_32t*)(x)+(c)))\r\n#  define word_out(x,c,v) (*((uint_32t*)(x)+(c)) = (v))\r\n#else\r\n#  define word_in(x,c)    aes_sw32(*((uint_32t*)(x)+(c)))\r\n#  define word_out(x,c,v) (*((uint_32t*)(x)+(c)) = aes_sw32(v))\r\n#endif\r\n\r\n/* the finite field modular polynomial and elements */\r\n\r\n#define WPOLY   0x011b\r\n#define BPOLY     0x1b\r\n\r\n/* multiply four bytes in GF(2^8) by 'x' {02} in parallel */\r\n\r\n#define gf_c1  0x80808080\r\n#define gf_c2  0x7f7f7f7f\r\n#define gf_mulx(x)  ((((x) & gf_c2) << 1) ^ ((((x) & gf_c1) >> 7) * BPOLY))\r\n\r\n/* The following defines provide alternative definitions of gf_mulx that might\r\n   give improved performance if a fast 32-bit multiply is not available. Note\r\n   that a temporary variable u needs to be defined where gf_mulx is used.\r\n\r\n#define gf_mulx(x) (u = (x) & gf_c1, u |= (u >> 1), ((x) & gf_c2) << 1) ^ ((u >> 3) | (u >> 6))\r\n#define gf_c4  (0x01010101 * BPOLY)\r\n#define gf_mulx(x) (u = (x) & gf_c1, ((x) & gf_c2) << 1) ^ ((u - (u >> 7)) & gf_c4)\r\n*/\r\n\r\n/* Work out which tables are needed for the different options   */\r\n\r\n#if defined( ASM_X86_V1C )\r\n#  if defined( ENC_ROUND )\r\n#    undef  ENC_ROUND\r\n#  endif\r\n#  define ENC_ROUND   FOUR_TABLES\r\n#  if defined( LAST_ENC_ROUND )\r\n#    undef  LAST_ENC_ROUND\r\n#  endif\r\n#  define LAST_ENC_ROUND  FOUR_TABLES\r\n#  if defined( DEC_ROUND )\r\n#    undef  DEC_ROUND\r\n#  endif\r\n#  define DEC_ROUND   FOUR_TABLES\r\n#  if defined( LAST_DEC_ROUND )\r\n#    undef  LAST_DEC_ROUND\r\n#  endif\r\n#  define LAST_DEC_ROUND  FOUR_TABLES\r\n#  if defined( KEY_SCHED )\r\n#    undef  KEY_SCHED\r\n#    define KEY_SCHED   FOUR_TABLES\r\n#  endif\r\n#endif\r\n\r\n#if ( FUNCS_IN_C & ENCRYPTION_IN_C ) || defined( ASM_X86_V1C )\r\n#  if ENC_ROUND == ONE_TABLE\r\n#    define FT1_SET\r\n#  elif ENC_ROUND == FOUR_TABLES\r\n#    define FT4_SET\r\n#  else\r\n#    define SBX_SET\r\n#  endif\r\n#  if LAST_ENC_ROUND == ONE_TABLE\r\n#    define FL1_SET\r\n#  elif LAST_ENC_ROUND == FOUR_TABLES\r\n#    define FL4_SET\r\n#  elif !defined( SBX_SET )\r\n#    define SBX_SET\r\n#  endif\r\n#endif\r\n\r\n#if ( FUNCS_IN_C & DECRYPTION_IN_C ) || defined( ASM_X86_V1C )\r\n#  if DEC_ROUND == ONE_TABLE\r\n#    define IT1_SET\r\n#  elif DEC_ROUND == FOUR_TABLES\r\n#    define IT4_SET\r\n#  else\r\n#    define ISB_SET\r\n#  endif\r\n#  if LAST_DEC_ROUND == ONE_TABLE\r\n#    define IL1_SET\r\n#  elif LAST_DEC_ROUND == FOUR_TABLES\r\n#    define IL4_SET\r\n#  elif !defined(ISB_SET)\r\n#    define ISB_SET\r\n#  endif\r\n#endif\r\n\r\n#if !(defined( REDUCE_CODE_SIZE ) && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C )))\r\n#  if ((FUNCS_IN_C & ENC_KEYING_IN_C) || (FUNCS_IN_C & DEC_KEYING_IN_C))\r\n#    if KEY_SCHED == ONE_TABLE\r\n#      if !defined( FL1_SET )  && !defined( FL4_SET ) \r\n#        define LS1_SET\r\n#      endif\r\n#    elif KEY_SCHED == FOUR_TABLES\r\n#      if !defined( FL4_SET )\r\n#        define LS4_SET\r\n#      endif\r\n#    elif !defined( SBX_SET )\r\n#      define SBX_SET\r\n#    endif\r\n#  endif\r\n#  if (FUNCS_IN_C & DEC_KEYING_IN_C)\r\n#    if KEY_SCHED == ONE_TABLE\r\n#      define IM1_SET\r\n#    elif KEY_SCHED == FOUR_TABLES\r\n#      define IM4_SET\r\n#    elif !defined( SBX_SET )\r\n#      define SBX_SET\r\n#    endif\r\n#  endif\r\n#endif\r\n\r\n/* generic definitions of Rijndael macros that use tables    */\r\n\r\n#define no_table(x,box,vf,rf,c) bytes2word( \\\r\n    box[bval(vf(x,0,c),rf(0,c))], \\\r\n    box[bval(vf(x,1,c),rf(1,c))], \\\r\n    box[bval(vf(x,2,c),rf(2,c))], \\\r\n    box[bval(vf(x,3,c),rf(3,c))])\r\n\r\n#define one_table(x,op,tab,vf,rf,c) \\\r\n (     tab[bval(vf(x,0,c),rf(0,c))] \\\r\n  ^ op(tab[bval(vf(x,1,c),rf(1,c))],1) \\\r\n  ^ op(tab[bval(vf(x,2,c),rf(2,c))],2) \\\r\n  ^ op(tab[bval(vf(x,3,c),rf(3,c))],3))\r\n\r\n#define four_tables(x,tab,vf,rf,c) \\\r\n (  tab[0][bval(vf(x,0,c),rf(0,c))] \\\r\n  ^ tab[1][bval(vf(x,1,c),rf(1,c))] \\\r\n  ^ tab[2][bval(vf(x,2,c),rf(2,c))] \\\r\n  ^ tab[3][bval(vf(x,3,c),rf(3,c))])\r\n\r\n#define vf1(x,r,c)  (x)\r\n#define rf1(r,c)    (r)\r\n#define rf2(r,c)    ((8+r-c)&3)\r\n\r\n/* perform forward and inverse column mix operation on four bytes in long word x in */\r\n/* parallel. NOTE: x must be a simple variable, NOT an expression in these macros.  */\r\n\r\n#if !(defined( REDUCE_CODE_SIZE ) && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C ))) \r\n\r\n#if defined( FM4_SET )      /* not currently used */\r\n#  define fwd_mcol(x)       four_tables(x,t_use(f,m),vf1,rf1,0)\r\n#elif defined( FM1_SET )    /* not currently used */\r\n#  define fwd_mcol(x)       one_table(x,upr,t_use(f,m),vf1,rf1,0)\r\n#else\r\n#  define dec_fmvars        uint_32t g2\r\n#  define fwd_mcol(x)       (g2 = gf_mulx(x), g2 ^ upr((x) ^ g2, 3) ^ upr((x), 2) ^ upr((x), 1))\r\n#endif\r\n\r\n#if defined( IM4_SET )\r\n#  define inv_mcol(x)       four_tables(x,t_use(i,m),vf1,rf1,0)\r\n#elif defined( IM1_SET )\r\n#  define inv_mcol(x)       one_table(x,upr,t_use(i,m),vf1,rf1,0)\r\n#else\r\n#  define dec_imvars        uint_32t g2, g4, g9\r\n#  define inv_mcol(x)       (g2 = gf_mulx(x), g4 = gf_mulx(g2), g9 = (x) ^ gf_mulx(g4), g4 ^= g9, \\\r\n                            (x) ^ g2 ^ g4 ^ upr(g2 ^ g9, 3) ^ upr(g4, 2) ^ upr(g9, 1))\r\n#endif\r\n\r\n#if defined( FL4_SET )\r\n#  define ls_box(x,c)       four_tables(x,t_use(f,l),vf1,rf2,c)\r\n#elif defined( LS4_SET )\r\n#  define ls_box(x,c)       four_tables(x,t_use(l,s),vf1,rf2,c)\r\n#elif defined( FL1_SET )\r\n#  define ls_box(x,c)       one_table(x,upr,t_use(f,l),vf1,rf2,c)\r\n#elif defined( LS1_SET )\r\n#  define ls_box(x,c)       one_table(x,upr,t_use(l,s),vf1,rf2,c)\r\n#else\r\n#  define ls_box(x,c)       no_table(x,t_use(s,box),vf1,rf2,c)\r\n#endif\r\n\r\n#endif\r\n\r\n#if defined( ASM_X86_V1C ) && defined( AES_DECRYPT ) && !defined( ISB_SET )\r\n#  define ISB_SET\r\n#endif\r\n\r\n#endif\r\n"
  },
  {
    "path": "plugins/cordova-plugin-zip/src/ios/aes/aestab.c",
    "content": "/*\r\n---------------------------------------------------------------------------\r\nCopyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.\r\n\r\nThe redistribution and use of this software (with or without changes)\r\nis allowed without the payment of fees or royalties provided that:\r\n\r\n  source code distributions include the above copyright notice, this\r\n  list of conditions and the following disclaimer;\r\n\r\n  binary distributions include the above copyright notice, this list\r\n  of conditions and the following disclaimer in their documentation.\r\n\r\nThis software is provided 'as is' with no explicit or implied warranties\r\nin respect of its operation, including, but not limited to, correctness\r\nand fitness for purpose.\r\n---------------------------------------------------------------------------\r\nIssue Date: 20/12/2007\r\n*/\r\n\r\n#define DO_TABLES\r\n\r\n#include \"aes.h\"\r\n#include \"aesopt.h\"\r\n\r\n#if defined(FIXED_TABLES)\r\n\r\n#define sb_data(w) {\\\r\n    w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5),\\\r\n    w(0x30), w(0x01), w(0x67), w(0x2b), w(0xfe), w(0xd7), w(0xab), w(0x76),\\\r\n    w(0xca), w(0x82), w(0xc9), w(0x7d), w(0xfa), w(0x59), w(0x47), w(0xf0),\\\r\n    w(0xad), w(0xd4), w(0xa2), w(0xaf), w(0x9c), w(0xa4), w(0x72), w(0xc0),\\\r\n    w(0xb7), w(0xfd), w(0x93), w(0x26), w(0x36), w(0x3f), w(0xf7), w(0xcc),\\\r\n    w(0x34), w(0xa5), w(0xe5), w(0xf1), w(0x71), w(0xd8), w(0x31), w(0x15),\\\r\n    w(0x04), w(0xc7), w(0x23), w(0xc3), w(0x18), w(0x96), w(0x05), w(0x9a),\\\r\n    w(0x07), w(0x12), w(0x80), w(0xe2), w(0xeb), w(0x27), w(0xb2), w(0x75),\\\r\n    w(0x09), w(0x83), w(0x2c), w(0x1a), w(0x1b), w(0x6e), w(0x5a), w(0xa0),\\\r\n    w(0x52), w(0x3b), w(0xd6), w(0xb3), w(0x29), w(0xe3), w(0x2f), w(0x84),\\\r\n    w(0x53), w(0xd1), w(0x00), w(0xed), w(0x20), w(0xfc), w(0xb1), w(0x5b),\\\r\n    w(0x6a), w(0xcb), w(0xbe), w(0x39), w(0x4a), w(0x4c), w(0x58), w(0xcf),\\\r\n    w(0xd0), w(0xef), w(0xaa), w(0xfb), w(0x43), w(0x4d), w(0x33), w(0x85),\\\r\n    w(0x45), w(0xf9), w(0x02), w(0x7f), w(0x50), w(0x3c), w(0x9f), w(0xa8),\\\r\n    w(0x51), w(0xa3), w(0x40), w(0x8f), w(0x92), w(0x9d), w(0x38), w(0xf5),\\\r\n    w(0xbc), w(0xb6), w(0xda), w(0x21), w(0x10), w(0xff), w(0xf3), w(0xd2),\\\r\n    w(0xcd), w(0x0c), w(0x13), w(0xec), w(0x5f), w(0x97), w(0x44), w(0x17),\\\r\n    w(0xc4), w(0xa7), w(0x7e), w(0x3d), w(0x64), w(0x5d), w(0x19), w(0x73),\\\r\n    w(0x60), w(0x81), w(0x4f), w(0xdc), w(0x22), w(0x2a), w(0x90), w(0x88),\\\r\n    w(0x46), w(0xee), w(0xb8), w(0x14), w(0xde), w(0x5e), w(0x0b), w(0xdb),\\\r\n    w(0xe0), w(0x32), w(0x3a), w(0x0a), w(0x49), w(0x06), w(0x24), w(0x5c),\\\r\n    w(0xc2), w(0xd3), w(0xac), w(0x62), w(0x91), w(0x95), w(0xe4), w(0x79),\\\r\n    w(0xe7), w(0xc8), w(0x37), w(0x6d), w(0x8d), w(0xd5), w(0x4e), w(0xa9),\\\r\n    w(0x6c), w(0x56), w(0xf4), w(0xea), w(0x65), w(0x7a), w(0xae), w(0x08),\\\r\n    w(0xba), w(0x78), w(0x25), w(0x2e), w(0x1c), w(0xa6), w(0xb4), w(0xc6),\\\r\n    w(0xe8), w(0xdd), w(0x74), w(0x1f), w(0x4b), w(0xbd), w(0x8b), w(0x8a),\\\r\n    w(0x70), w(0x3e), w(0xb5), w(0x66), w(0x48), w(0x03), w(0xf6), w(0x0e),\\\r\n    w(0x61), w(0x35), w(0x57), w(0xb9), w(0x86), w(0xc1), w(0x1d), w(0x9e),\\\r\n    w(0xe1), w(0xf8), w(0x98), w(0x11), w(0x69), w(0xd9), w(0x8e), w(0x94),\\\r\n    w(0x9b), w(0x1e), w(0x87), w(0xe9), w(0xce), w(0x55), w(0x28), w(0xdf),\\\r\n    w(0x8c), w(0xa1), w(0x89), w(0x0d), w(0xbf), w(0xe6), w(0x42), w(0x68),\\\r\n    w(0x41), w(0x99), w(0x2d), w(0x0f), w(0xb0), w(0x54), w(0xbb), w(0x16) }\r\n\r\n#define isb_data(w) {\\\r\n    w(0x52), w(0x09), w(0x6a), w(0xd5), w(0x30), w(0x36), w(0xa5), w(0x38),\\\r\n    w(0xbf), w(0x40), w(0xa3), w(0x9e), w(0x81), w(0xf3), w(0xd7), w(0xfb),\\\r\n    w(0x7c), w(0xe3), w(0x39), w(0x82), w(0x9b), w(0x2f), w(0xff), w(0x87),\\\r\n    w(0x34), w(0x8e), w(0x43), w(0x44), w(0xc4), w(0xde), w(0xe9), w(0xcb),\\\r\n    w(0x54), w(0x7b), w(0x94), w(0x32), w(0xa6), w(0xc2), w(0x23), w(0x3d),\\\r\n    w(0xee), w(0x4c), w(0x95), w(0x0b), w(0x42), w(0xfa), w(0xc3), w(0x4e),\\\r\n    w(0x08), w(0x2e), w(0xa1), w(0x66), w(0x28), w(0xd9), w(0x24), w(0xb2),\\\r\n    w(0x76), w(0x5b), w(0xa2), w(0x49), w(0x6d), w(0x8b), w(0xd1), w(0x25),\\\r\n    w(0x72), w(0xf8), w(0xf6), w(0x64), w(0x86), w(0x68), w(0x98), w(0x16),\\\r\n    w(0xd4), w(0xa4), w(0x5c), w(0xcc), w(0x5d), w(0x65), w(0xb6), w(0x92),\\\r\n    w(0x6c), w(0x70), w(0x48), w(0x50), w(0xfd), w(0xed), w(0xb9), w(0xda),\\\r\n    w(0x5e), w(0x15), w(0x46), w(0x57), w(0xa7), w(0x8d), w(0x9d), w(0x84),\\\r\n    w(0x90), w(0xd8), w(0xab), w(0x00), w(0x8c), w(0xbc), w(0xd3), w(0x0a),\\\r\n    w(0xf7), w(0xe4), w(0x58), w(0x05), w(0xb8), w(0xb3), w(0x45), w(0x06),\\\r\n    w(0xd0), w(0x2c), w(0x1e), w(0x8f), w(0xca), w(0x3f), w(0x0f), w(0x02),\\\r\n    w(0xc1), w(0xaf), w(0xbd), w(0x03), w(0x01), w(0x13), w(0x8a), w(0x6b),\\\r\n    w(0x3a), w(0x91), w(0x11), w(0x41), w(0x4f), w(0x67), w(0xdc), w(0xea),\\\r\n    w(0x97), w(0xf2), w(0xcf), w(0xce), w(0xf0), w(0xb4), w(0xe6), w(0x73),\\\r\n    w(0x96), w(0xac), w(0x74), w(0x22), w(0xe7), w(0xad), w(0x35), w(0x85),\\\r\n    w(0xe2), w(0xf9), w(0x37), w(0xe8), w(0x1c), w(0x75), w(0xdf), w(0x6e),\\\r\n    w(0x47), w(0xf1), w(0x1a), w(0x71), w(0x1d), w(0x29), w(0xc5), w(0x89),\\\r\n    w(0x6f), w(0xb7), w(0x62), w(0x0e), w(0xaa), w(0x18), w(0xbe), w(0x1b),\\\r\n    w(0xfc), w(0x56), w(0x3e), w(0x4b), w(0xc6), w(0xd2), w(0x79), w(0x20),\\\r\n    w(0x9a), w(0xdb), w(0xc0), w(0xfe), w(0x78), w(0xcd), w(0x5a), w(0xf4),\\\r\n    w(0x1f), w(0xdd), w(0xa8), w(0x33), w(0x88), w(0x07), w(0xc7), w(0x31),\\\r\n    w(0xb1), w(0x12), w(0x10), w(0x59), w(0x27), w(0x80), w(0xec), w(0x5f),\\\r\n    w(0x60), w(0x51), w(0x7f), w(0xa9), w(0x19), w(0xb5), w(0x4a), w(0x0d),\\\r\n    w(0x2d), w(0xe5), w(0x7a), w(0x9f), w(0x93), w(0xc9), w(0x9c), w(0xef),\\\r\n    w(0xa0), w(0xe0), w(0x3b), w(0x4d), w(0xae), w(0x2a), w(0xf5), w(0xb0),\\\r\n    w(0xc8), w(0xeb), w(0xbb), w(0x3c), w(0x83), w(0x53), w(0x99), w(0x61),\\\r\n    w(0x17), w(0x2b), w(0x04), w(0x7e), w(0xba), w(0x77), w(0xd6), w(0x26),\\\r\n    w(0xe1), w(0x69), w(0x14), w(0x63), w(0x55), w(0x21), w(0x0c), w(0x7d) }\r\n\r\n#define mm_data(w) {\\\r\n    w(0x00), w(0x01), w(0x02), w(0x03), w(0x04), w(0x05), w(0x06), w(0x07),\\\r\n    w(0x08), w(0x09), w(0x0a), w(0x0b), w(0x0c), w(0x0d), w(0x0e), w(0x0f),\\\r\n    w(0x10), w(0x11), w(0x12), w(0x13), w(0x14), w(0x15), w(0x16), w(0x17),\\\r\n    w(0x18), w(0x19), w(0x1a), w(0x1b), w(0x1c), w(0x1d), w(0x1e), w(0x1f),\\\r\n    w(0x20), w(0x21), w(0x22), w(0x23), w(0x24), w(0x25), w(0x26), w(0x27),\\\r\n    w(0x28), w(0x29), w(0x2a), w(0x2b), w(0x2c), w(0x2d), w(0x2e), w(0x2f),\\\r\n    w(0x30), w(0x31), w(0x32), w(0x33), w(0x34), w(0x35), w(0x36), w(0x37),\\\r\n    w(0x38), w(0x39), w(0x3a), w(0x3b), w(0x3c), w(0x3d), w(0x3e), w(0x3f),\\\r\n    w(0x40), w(0x41), w(0x42), w(0x43), w(0x44), w(0x45), w(0x46), w(0x47),\\\r\n    w(0x48), w(0x49), w(0x4a), w(0x4b), w(0x4c), w(0x4d), w(0x4e), w(0x4f),\\\r\n    w(0x50), w(0x51), w(0x52), w(0x53), w(0x54), w(0x55), w(0x56), w(0x57),\\\r\n    w(0x58), w(0x59), w(0x5a), w(0x5b), w(0x5c), w(0x5d), w(0x5e), w(0x5f),\\\r\n    w(0x60), w(0x61), w(0x62), w(0x63), w(0x64), w(0x65), w(0x66), w(0x67),\\\r\n    w(0x68), w(0x69), w(0x6a), w(0x6b), w(0x6c), w(0x6d), w(0x6e), w(0x6f),\\\r\n    w(0x70), w(0x71), w(0x72), w(0x73), w(0x74), w(0x75), w(0x76), w(0x77),\\\r\n    w(0x78), w(0x79), w(0x7a), w(0x7b), w(0x7c), w(0x7d), w(0x7e), w(0x7f),\\\r\n    w(0x80), w(0x81), w(0x82), w(0x83), w(0x84), w(0x85), w(0x86), w(0x87),\\\r\n    w(0x88), w(0x89), w(0x8a), w(0x8b), w(0x8c), w(0x8d), w(0x8e), w(0x8f),\\\r\n    w(0x90), w(0x91), w(0x92), w(0x93), w(0x94), w(0x95), w(0x96), w(0x97),\\\r\n    w(0x98), w(0x99), w(0x9a), w(0x9b), w(0x9c), w(0x9d), w(0x9e), w(0x9f),\\\r\n    w(0xa0), w(0xa1), w(0xa2), w(0xa3), w(0xa4), w(0xa5), w(0xa6), w(0xa7),\\\r\n    w(0xa8), w(0xa9), w(0xaa), w(0xab), w(0xac), w(0xad), w(0xae), w(0xaf),\\\r\n    w(0xb0), w(0xb1), w(0xb2), w(0xb3), w(0xb4), w(0xb5), w(0xb6), w(0xb7),\\\r\n    w(0xb8), w(0xb9), w(0xba), w(0xbb), w(0xbc), w(0xbd), w(0xbe), w(0xbf),\\\r\n    w(0xc0), w(0xc1), w(0xc2), w(0xc3), w(0xc4), w(0xc5), w(0xc6), w(0xc7),\\\r\n    w(0xc8), w(0xc9), w(0xca), w(0xcb), w(0xcc), w(0xcd), w(0xce), w(0xcf),\\\r\n    w(0xd0), w(0xd1), w(0xd2), w(0xd3), w(0xd4), w(0xd5), w(0xd6), w(0xd7),\\\r\n    w(0xd8), w(0xd9), w(0xda), w(0xdb), w(0xdc), w(0xdd), w(0xde), w(0xdf),\\\r\n    w(0xe0), w(0xe1), w(0xe2), w(0xe3), w(0xe4), w(0xe5), w(0xe6), w(0xe7),\\\r\n    w(0xe8), w(0xe9), w(0xea), w(0xeb), w(0xec), w(0xed), w(0xee), w(0xef),\\\r\n    w(0xf0), w(0xf1), w(0xf2), w(0xf3), w(0xf4), w(0xf5), w(0xf6), w(0xf7),\\\r\n    w(0xf8), w(0xf9), w(0xfa), w(0xfb), w(0xfc), w(0xfd), w(0xfe), w(0xff) }\r\n\r\n#define rc_data(w) {\\\r\n    w(0x01), w(0x02), w(0x04), w(0x08), w(0x10),w(0x20), w(0x40), w(0x80),\\\r\n    w(0x1b), w(0x36) }\r\n\r\n#define h0(x)   (x)\r\n\r\n#define w0(p)   bytes2word(p, 0, 0, 0)\r\n#define w1(p)   bytes2word(0, p, 0, 0)\r\n#define w2(p)   bytes2word(0, 0, p, 0)\r\n#define w3(p)   bytes2word(0, 0, 0, p)\r\n\r\n#define u0(p)   bytes2word(f2(p), p, p, f3(p))\r\n#define u1(p)   bytes2word(f3(p), f2(p), p, p)\r\n#define u2(p)   bytes2word(p, f3(p), f2(p), p)\r\n#define u3(p)   bytes2word(p, p, f3(p), f2(p))\r\n\r\n#define v0(p)   bytes2word(fe(p), f9(p), fd(p), fb(p))\r\n#define v1(p)   bytes2word(fb(p), fe(p), f9(p), fd(p))\r\n#define v2(p)   bytes2word(fd(p), fb(p), fe(p), f9(p))\r\n#define v3(p)   bytes2word(f9(p), fd(p), fb(p), fe(p))\r\n\r\n#endif\r\n\r\n#if defined(FIXED_TABLES) || !defined(FF_TABLES)\r\n\r\n#define f2(x)   ((x<<1) ^ (((x>>7) & 1) * WPOLY))\r\n#define f4(x)   ((x<<2) ^ (((x>>6) & 1) * WPOLY) ^ (((x>>6) & 2) * WPOLY))\r\n#define f8(x)   ((x<<3) ^ (((x>>5) & 1) * WPOLY) ^ (((x>>5) & 2) * WPOLY) \\\r\n                        ^ (((x>>5) & 4) * WPOLY))\r\n#define f3(x)   (f2(x) ^ x)\r\n#define f9(x)   (f8(x) ^ x)\r\n#define fb(x)   (f8(x) ^ f2(x) ^ x)\r\n#define fd(x)   (f8(x) ^ f4(x) ^ x)\r\n#define fe(x)   (f8(x) ^ f4(x) ^ f2(x))\r\n\r\n#else\r\n\r\n#define f2(x) ((x) ? pow[log[x] + 0x19] : 0)\r\n#define f3(x) ((x) ? pow[log[x] + 0x01] : 0)\r\n#define f9(x) ((x) ? pow[log[x] + 0xc7] : 0)\r\n#define fb(x) ((x) ? pow[log[x] + 0x68] : 0)\r\n#define fd(x) ((x) ? pow[log[x] + 0xee] : 0)\r\n#define fe(x) ((x) ? pow[log[x] + 0xdf] : 0)\r\n\r\n#endif\r\n\r\n#include \"aestab.h\"\r\n\r\n#if defined(__cplusplus)\r\nextern \"C\"\r\n{\r\n#endif\r\n\r\n#if defined(FIXED_TABLES)\r\n\r\n/* implemented in case of wrong call for fixed tables */\r\n\r\nAES_RETURN aes_init(void)\r\n{\r\n    return EXIT_SUCCESS;\r\n}\r\n\r\n#else   /*  Generate the tables for the dynamic table option */\r\n\r\n#if defined(FF_TABLES)\r\n\r\n#define gf_inv(x)   ((x) ? pow[ 255 - log[x]] : 0)\r\n\r\n#else \r\n\r\n/*  It will generally be sensible to use tables to compute finite\r\n    field multiplies and inverses but where memory is scarse this\r\n    code might sometimes be better. But it only has effect during\r\n    initialisation so its pretty unimportant in overall terms.\r\n*/\r\n\r\n/*  return 2 ^ (n - 1) where n is the bit number of the highest bit\r\n    set in x with x in the range 1 < x < 0x00000200.   This form is\r\n    used so that locals within fi can be bytes rather than words\r\n*/\r\n\r\nstatic uint_8t hibit(const uint_32t x)\r\n{   uint_8t r = (uint_8t)((x >> 1) | (x >> 2));\r\n\r\n    r |= (r >> 2);\r\n    r |= (r >> 4);\r\n    return (r + 1) >> 1;\r\n}\r\n\r\n/* return the inverse of the finite field element x */\r\n\r\nstatic uint_8t gf_inv(const uint_8t x)\r\n{   uint_8t p1 = x, p2 = BPOLY, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0;\r\n\r\n    if(x < 2) \r\n        return x;\r\n\r\n    for( ; ; )\r\n    {\r\n        if(n1)\r\n            while(n2 >= n1)             /* divide polynomial p2 by p1    */\r\n            {\r\n                n2 /= n1;               /* shift smaller polynomial left */ \r\n                p2 ^= (p1 * n2) & 0xff; /* and remove from larger one    */\r\n                v2 ^= v1 * n2;          /* shift accumulated value and   */ \r\n                n2 = hibit(p2);         /* add into result               */\r\n            }\r\n        else\r\n            return v1;\r\n\r\n        if(n2)                          /* repeat with values swapped    */ \r\n            while(n1 >= n2)\r\n            {\r\n                n1 /= n2; \r\n                p1 ^= p2 * n1; \r\n                v1 ^= v2 * n1; \r\n                n1 = hibit(p1);\r\n            }\r\n        else\r\n            return v2;\r\n    }\r\n}\r\n\r\n#endif\r\n\r\n/* The forward and inverse affine transformations used in the S-box */\r\nuint_8t fwd_affine(const uint_8t x)\r\n{   uint_32t w = x;\r\n    w ^= (w << 1) ^ (w << 2) ^ (w << 3) ^ (w << 4);\r\n    return 0x63 ^ ((w ^ (w >> 8)) & 0xff);\r\n}\r\n\r\nuint_8t inv_affine(const uint_8t x)\r\n{   uint_32t w = x;\r\n    w = (w << 1) ^ (w << 3) ^ (w << 6);\r\n    return 0x05 ^ ((w ^ (w >> 8)) & 0xff);\r\n}\r\n\r\nstatic int init = 0;\r\n\r\nAES_RETURN aes_init(void)\r\n{   uint_32t  i, w;\r\n\r\n#if defined(FF_TABLES)\r\n\r\n    uint_8t  pow[512], log[256];\r\n\r\n    if(init)\r\n        return EXIT_SUCCESS;\r\n    /*  log and power tables for GF(2^8) finite field with\r\n        WPOLY as modular polynomial - the simplest primitive\r\n        root is 0x03, used here to generate the tables\r\n    */\r\n\r\n    i = 0; w = 1;\r\n    do\r\n    {\r\n        pow[i] = (uint_8t)w;\r\n        pow[i + 255] = (uint_8t)w;\r\n        log[w] = (uint_8t)i++;\r\n        w ^=  (w << 1) ^ (w & 0x80 ? WPOLY : 0);\r\n    }\r\n    while (w != 1);\r\n\r\n#else\r\n    if(init)\r\n        return EXIT_SUCCESS;\r\n#endif\r\n\r\n    for(i = 0, w = 1; i < RC_LENGTH; ++i)\r\n    {\r\n        t_set(r,c)[i] = bytes2word(w, 0, 0, 0);\r\n        w = f2(w);\r\n    }\r\n\r\n    for(i = 0; i < 256; ++i)\r\n    {   uint_8t    b;\r\n\r\n        b = fwd_affine(gf_inv((uint_8t)i));\r\n        w = bytes2word(f2(b), b, b, f3(b));\r\n\r\n#if defined( SBX_SET )\r\n        t_set(s,box)[i] = b;\r\n#endif\r\n\r\n#if defined( FT1_SET )                 /* tables for a normal encryption round */\r\n        t_set(f,n)[i] = w;\r\n#endif\r\n#if defined( FT4_SET )\r\n        t_set(f,n)[0][i] = w;\r\n        t_set(f,n)[1][i] = upr(w,1);\r\n        t_set(f,n)[2][i] = upr(w,2);\r\n        t_set(f,n)[3][i] = upr(w,3);\r\n#endif\r\n        w = bytes2word(b, 0, 0, 0);\r\n\r\n#if defined( FL1_SET )            /* tables for last encryption round (may also   */\r\n        t_set(f,l)[i] = w;        /* be used in the key schedule)                 */\r\n#endif\r\n#if defined( FL4_SET )\r\n        t_set(f,l)[0][i] = w;\r\n        t_set(f,l)[1][i] = upr(w,1);\r\n        t_set(f,l)[2][i] = upr(w,2);\r\n        t_set(f,l)[3][i] = upr(w,3);\r\n#endif\r\n\r\n#if defined( LS1_SET )\t\t\t/* table for key schedule if t_set(f,l) above is*/\r\n        t_set(l,s)[i] = w;      /* not of the required form                     */\r\n#endif\r\n#if defined( LS4_SET )\r\n        t_set(l,s)[0][i] = w;\r\n        t_set(l,s)[1][i] = upr(w,1);\r\n        t_set(l,s)[2][i] = upr(w,2);\r\n        t_set(l,s)[3][i] = upr(w,3);\r\n#endif\r\n\r\n        b = gf_inv(inv_affine((uint_8t)i));\r\n        w = bytes2word(fe(b), f9(b), fd(b), fb(b));\r\n\r\n#if defined( IM1_SET )\t\t\t/* tables for the inverse mix column operation  */\r\n        t_set(i,m)[b] = w;\r\n#endif\r\n#if defined( IM4_SET )\r\n        t_set(i,m)[0][b] = w;\r\n        t_set(i,m)[1][b] = upr(w,1);\r\n        t_set(i,m)[2][b] = upr(w,2);\r\n        t_set(i,m)[3][b] = upr(w,3);\r\n#endif\r\n\r\n#if defined( ISB_SET )\r\n        t_set(i,box)[i] = b;\r\n#endif\r\n#if defined( IT1_SET )\t\t\t/* tables for a normal decryption round */\r\n        t_set(i,n)[i] = w;\r\n#endif\r\n#if defined( IT4_SET )\r\n        t_set(i,n)[0][i] = w;\r\n        t_set(i,n)[1][i] = upr(w,1);\r\n        t_set(i,n)[2][i] = upr(w,2);\r\n        t_set(i,n)[3][i] = upr(w,3);\r\n#endif\r\n        w = bytes2word(b, 0, 0, 0);\r\n#if defined( IL1_SET )\t\t\t/* tables for last decryption round */\r\n        t_set(i,l)[i] = w;\r\n#endif\r\n#if defined( IL4_SET )\r\n        t_set(i,l)[0][i] = w;\r\n        t_set(i,l)[1][i] = upr(w,1);\r\n        t_set(i,l)[2][i] = upr(w,2);\r\n        t_set(i,l)[3][i] = upr(w,3);\r\n#endif\r\n    }\r\n    init = 1;\r\n    return EXIT_SUCCESS;\r\n}\r\n\r\n#endif\r\n\r\n#if defined(__cplusplus)\r\n}\r\n#endif\r\n\r\n"
  },
  {
    "path": "plugins/cordova-plugin-zip/src/ios/aes/aestab.h",
    "content": "/*\r\n---------------------------------------------------------------------------\r\nCopyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.\r\n\r\nThe redistribution and use of this software (with or without changes)\r\nis allowed without the payment of fees or royalties provided that:\r\n\r\n  source code distributions include the above copyright notice, this\r\n  list of conditions and the following disclaimer;\r\n\r\n  binary distributions include the above copyright notice, this list\r\n  of conditions and the following disclaimer in their documentation.\r\n\r\nThis software is provided 'as is' with no explicit or implied warranties\r\nin respect of its operation, including, but not limited to, correctness\r\nand fitness for purpose.\r\n---------------------------------------------------------------------------\r\nIssue Date: 20/12/2007\r\n\r\n This file contains the code for declaring the tables needed to implement\r\n AES. The file aesopt.h is assumed to be included before this header file.\r\n If there are no global variables, the definitions here can be used to put\r\n the AES tables in a structure so that a pointer can then be added to the\r\n AES context to pass them to the AES routines that need them.   If this\r\n facility is used, the calling program has to ensure that this pointer is\r\n managed appropriately.  In particular, the value of the t_dec(in,it) item\r\n in the table structure must be set to zero in order to ensure that the\r\n tables are initialised. In practice the three code sequences in aeskey.c\r\n that control the calls to aes_init() and the aes_init() routine itself will\r\n have to be changed for a specific implementation. If global variables are\r\n available it will generally be preferable to use them with the precomputed\r\n FIXED_TABLES option that uses static global tables.\r\n\r\n The following defines can be used to control the way the tables\r\n are defined, initialised and used in embedded environments that\r\n require special features for these purposes\r\n\r\n    the 't_dec' construction is used to declare fixed table arrays\r\n    the 't_set' construction is used to set fixed table values\r\n    the 't_use' construction is used to access fixed table values\r\n\r\n    256 byte tables:\r\n\r\n        t_xxx(s,box)    => forward S box\r\n        t_xxx(i,box)    => inverse S box\r\n\r\n    256 32-bit word OR 4 x 256 32-bit word tables:\r\n\r\n        t_xxx(f,n)      => forward normal round\r\n        t_xxx(f,l)      => forward last round\r\n        t_xxx(i,n)      => inverse normal round\r\n        t_xxx(i,l)      => inverse last round\r\n        t_xxx(l,s)      => key schedule table\r\n        t_xxx(i,m)      => key schedule table\r\n\r\n    Other variables and tables:\r\n\r\n        t_xxx(r,c)      => the rcon table\r\n*/\r\n\r\n#if !defined( _AESTAB_H )\r\n#define _AESTAB_H\r\n\r\n#if defined(__cplusplus)\r\nextern \"C\" {\r\n#endif\r\n\r\n#define t_dec(m,n) t_##m##n\r\n#define t_set(m,n) t_##m##n\r\n#define t_use(m,n) t_##m##n\r\n\r\n#if defined(FIXED_TABLES)\r\n#  if !defined( __GNUC__ ) && (defined( __MSDOS__ ) || defined( __WIN16__ ))\r\n/*   make tables far data to avoid using too much DGROUP space (PG) */\r\n#    define CONST const far\r\n#  else\r\n#    define CONST const\r\n#  endif\r\n#else\r\n#  define CONST\r\n#endif\r\n\r\n#if defined(DO_TABLES)\r\n#  define EXTERN\r\n#else\r\n#  define EXTERN extern\r\n#endif\r\n\r\n#if defined(_MSC_VER) && defined(TABLE_ALIGN)\r\n#define ALIGN __declspec(align(TABLE_ALIGN))\r\n#else\r\n#define ALIGN\r\n#endif\r\n\r\n#if defined( __WATCOMC__ ) && ( __WATCOMC__ >= 1100 )\r\n#  define XP_DIR __cdecl\r\n#else\r\n#  define XP_DIR\r\n#endif\r\n\r\n#if defined(DO_TABLES) && defined(FIXED_TABLES)\r\n#define d_1(t,n,b,e)       EXTERN ALIGN CONST XP_DIR t n[256]    =   b(e)\r\n#define d_4(t,n,b,e,f,g,h) EXTERN ALIGN CONST XP_DIR t n[4][256] = { b(e), b(f), b(g), b(h) }\r\nEXTERN ALIGN CONST uint_32t t_dec(r,c)[RC_LENGTH] = rc_data(w0);\r\n#else\r\n#define d_1(t,n,b,e)       EXTERN ALIGN CONST XP_DIR t n[256]\r\n#define d_4(t,n,b,e,f,g,h) EXTERN ALIGN CONST XP_DIR t n[4][256]\r\nEXTERN ALIGN CONST uint_32t t_dec(r,c)[RC_LENGTH];\r\n#endif\r\n\r\n#if defined( SBX_SET )\r\n    d_1(uint_8t, t_dec(s,box), sb_data, h0);\r\n#endif\r\n#if defined( ISB_SET )\r\n    d_1(uint_8t, t_dec(i,box), isb_data, h0);\r\n#endif\r\n\r\n#if defined( FT1_SET )\r\n    d_1(uint_32t, t_dec(f,n), sb_data, u0);\r\n#endif\r\n#if defined( FT4_SET )\r\n    d_4(uint_32t, t_dec(f,n), sb_data, u0, u1, u2, u3);\r\n#endif\r\n\r\n#if defined( FL1_SET )\r\n    d_1(uint_32t, t_dec(f,l), sb_data, w0);\r\n#endif\r\n#if defined( FL4_SET )\r\n    d_4(uint_32t, t_dec(f,l), sb_data, w0, w1, w2, w3);\r\n#endif\r\n\r\n#if defined( IT1_SET )\r\n    d_1(uint_32t, t_dec(i,n), isb_data, v0);\r\n#endif\r\n#if defined( IT4_SET )\r\n    d_4(uint_32t, t_dec(i,n), isb_data, v0, v1, v2, v3);\r\n#endif\r\n\r\n#if defined( IL1_SET )\r\n    d_1(uint_32t, t_dec(i,l), isb_data, w0);\r\n#endif\r\n#if defined( IL4_SET )\r\n    d_4(uint_32t, t_dec(i,l), isb_data, w0, w1, w2, w3);\r\n#endif\r\n\r\n#if defined( LS1_SET )\r\n#if defined( FL1_SET )\r\n#undef  LS1_SET\r\n#else\r\n    d_1(uint_32t, t_dec(l,s), sb_data, w0);\r\n#endif\r\n#endif\r\n\r\n#if defined( LS4_SET )\r\n#if defined( FL4_SET )\r\n#undef  LS4_SET\r\n#else\r\n    d_4(uint_32t, t_dec(l,s), sb_data, w0, w1, w2, w3);\r\n#endif\r\n#endif\r\n\r\n#if defined( IM1_SET )\r\n    d_1(uint_32t, t_dec(i,m), mm_data, v0);\r\n#endif\r\n#if defined( IM4_SET )\r\n    d_4(uint_32t, t_dec(i,m), mm_data, v0, v1, v2, v3);\r\n#endif\r\n\r\n#if defined(__cplusplus)\r\n}\r\n#endif\r\n\r\n#endif\r\n"
  },
  {
    "path": "plugins/cordova-plugin-zip/src/ios/aes/brg_endian.h",
    "content": "/*\r\n---------------------------------------------------------------------------\r\nCopyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.\r\n\r\nThe redistribution and use of this software (with or without changes)\r\nis allowed without the payment of fees or royalties provided that:\r\n\r\n  source code distributions include the above copyright notice, this\r\n  list of conditions and the following disclaimer;\r\n\r\n  binary distributions include the above copyright notice, this list\r\n  of conditions and the following disclaimer in their documentation.\r\n\r\nThis software is provided 'as is' with no explicit or implied warranties\r\nin respect of its operation, including, but not limited to, correctness\r\nand fitness for purpose.\r\n---------------------------------------------------------------------------\r\nIssue Date: 20/12/2007\r\n*/\r\n\r\n#ifndef _BRG_ENDIAN_H\r\n#define _BRG_ENDIAN_H\r\n\r\n#define IS_BIG_ENDIAN      4321 /* byte 0 is most significant (mc68k) */\r\n#define IS_LITTLE_ENDIAN   1234 /* byte 0 is least significant (i386) */\r\n\r\n/* Include files where endian defines and byteswap functions may reside */\r\n#if defined( __sun )\r\n#  include <sys/isa_defs.h>\r\n#elif defined( __FreeBSD__ ) || defined( __OpenBSD__ ) || defined( __NetBSD__ )\r\n#  include <sys/endian.h>\r\n#elif defined( BSD ) && ( BSD >= 199103 ) || defined( __APPLE__ ) || \\\r\n      defined( __CYGWIN32__ ) || defined( __DJGPP__ ) || defined( __osf__ )\r\n#  include <machine/endian.h>\r\n#elif defined( __linux__ ) || defined( __GNUC__ ) || defined( __GNU_LIBRARY__ )\r\n#  if !defined( __MINGW32__ ) && !defined( _AIX )\r\n#    include <endian.h>\r\n#    if !defined( __BEOS__ )\r\n#      include <byteswap.h>\r\n#    endif\r\n#  endif\r\n#endif\r\n\r\n/* Now attempt to set the define for platform byte order using any  */\r\n/* of the four forms SYMBOL, _SYMBOL, __SYMBOL & __SYMBOL__, which  */\r\n/* seem to encompass most endian symbol definitions                 */\r\n\r\n#if defined( BIG_ENDIAN ) && defined( LITTLE_ENDIAN )\r\n#  if defined( BYTE_ORDER ) && BYTE_ORDER == BIG_ENDIAN\r\n#    define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN\r\n#  elif defined( BYTE_ORDER ) && BYTE_ORDER == LITTLE_ENDIAN\r\n#    define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN\r\n#  endif\r\n#elif defined( BIG_ENDIAN )\r\n#  define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN\r\n#elif defined( LITTLE_ENDIAN )\r\n#  define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN\r\n#endif\r\n\r\n#if defined( _BIG_ENDIAN ) && defined( _LITTLE_ENDIAN )\r\n#  if defined( _BYTE_ORDER ) && _BYTE_ORDER == _BIG_ENDIAN\r\n#    define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN\r\n#  elif defined( _BYTE_ORDER ) && _BYTE_ORDER == _LITTLE_ENDIAN\r\n#    define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN\r\n#  endif\r\n#elif defined( _BIG_ENDIAN )\r\n#  define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN\r\n#elif defined( _LITTLE_ENDIAN )\r\n#  define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN\r\n#endif\r\n\r\n#if defined( __BIG_ENDIAN ) && defined( __LITTLE_ENDIAN )\r\n#  if defined( __BYTE_ORDER ) && __BYTE_ORDER == __BIG_ENDIAN\r\n#    define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN\r\n#  elif defined( __BYTE_ORDER ) && __BYTE_ORDER == __LITTLE_ENDIAN\r\n#    define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN\r\n#  endif\r\n#elif defined( __BIG_ENDIAN )\r\n#  define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN\r\n#elif defined( __LITTLE_ENDIAN )\r\n#  define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN\r\n#endif\r\n\r\n#if defined( __BIG_ENDIAN__ ) && defined( __LITTLE_ENDIAN__ )\r\n#  if defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __BIG_ENDIAN__\r\n#    define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN\r\n#  elif defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __LITTLE_ENDIAN__\r\n#    define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN\r\n#  endif\r\n#elif defined( __BIG_ENDIAN__ )\r\n#  define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN\r\n#elif defined( __LITTLE_ENDIAN__ )\r\n#  define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN\r\n#endif\r\n\r\n/*  if the platform byte order could not be determined, then try to */\r\n/*  set this define using common machine defines                    */\r\n#if !defined(PLATFORM_BYTE_ORDER)\r\n\r\n#if   defined( __alpha__ ) || defined( __alpha ) || defined( i386 )       || \\\r\n      defined( __i386__ )  || defined( _M_I86 )  || defined( _M_IX86 )    || \\\r\n      defined( __OS2__ )   || defined( sun386 )  || defined( __TURBOC__ ) || \\\r\n      defined( vax )       || defined( vms )     || defined( VMS )        || \\\r\n      defined( __VMS )     || defined( _M_X64 )\r\n#  define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN\r\n\r\n#elif defined( AMIGA )   || defined( applec )    || defined( __AS400__ )  || \\\r\n      defined( _CRAY )   || defined( __hppa )    || defined( __hp9000 )   || \\\r\n      defined( ibm370 )  || defined( mc68000 )   || defined( m68k )       || \\\r\n      defined( __MRC__ ) || defined( __MVS__ )   || defined( __MWERKS__ ) || \\\r\n      defined( sparc )   || defined( __sparc)    || defined( SYMANTEC_C ) || \\\r\n      defined( __VOS__ ) || defined( __TIGCC__ ) || defined( __TANDEM )   || \\\r\n      defined( THINK_C ) || defined( __VMCMS__ ) || defined( _AIX )\r\n#  define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN\r\n\r\n#elif 0     /* **** EDIT HERE IF NECESSARY **** */\r\n#  define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN\r\n#elif 0     /* **** EDIT HERE IF NECESSARY **** */\r\n#  define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN\r\n#else\r\n#  error Please edit lines 126 or 128 in brg_endian.h to set the platform byte order\r\n#endif\r\n\r\n#endif\r\n\r\n#endif\r\n"
  },
  {
    "path": "plugins/cordova-plugin-zip/src/ios/aes/brg_types.h",
    "content": "/*\r\n---------------------------------------------------------------------------\r\nCopyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.\r\n\r\nThe redistribution and use of this software (with or without changes)\r\nis allowed without the payment of fees or royalties provided that:\r\n\r\n  source code distributions include the above copyright notice, this\r\n  list of conditions and the following disclaimer;\r\n\r\n  binary distributions include the above copyright notice, this list\r\n  of conditions and the following disclaimer in their documentation.\r\n\r\nThis software is provided 'as is' with no explicit or implied warranties\r\nin respect of its operation, including, but not limited to, correctness\r\nand fitness for purpose.\r\n---------------------------------------------------------------------------\r\nIssue Date: 20/12/2007\r\n\r\n The unsigned integer types defined here are of the form uint_<nn>t where\r\n <nn> is the length of the type; for example, the unsigned 32-bit type is\r\n 'uint_32t'.  These are NOT the same as the 'C99 integer types' that are\r\n defined in the inttypes.h and stdint.h headers since attempts to use these\r\n types have shown that support for them is still highly variable.  However,\r\n since the latter are of the form uint<nn>_t, a regular expression search\r\n and replace (in VC++ search on 'uint_{:z}t' and replace with 'uint\\1_t')\r\n can be used to convert the types used here to the C99 standard types.\r\n*/\r\n\r\n#ifndef _BRG_TYPES_H\r\n#define _BRG_TYPES_H\r\n\r\n#if defined(__cplusplus)\r\nextern \"C\" {\r\n#endif\r\n\r\n#include <limits.h>\r\n\r\n#if defined( _MSC_VER ) && ( _MSC_VER >= 1300 )\r\n#  include <stddef.h>\r\n#  define ptrint_t intptr_t\r\n#elif defined( __ECOS__ )\r\n#  define intptr_t unsigned int\r\n#  define ptrint_t intptr_t\r\n#elif defined( __GNUC__ ) && ( __GNUC__ >= 3 )\r\n#  include <stdint.h>\r\n#  define ptrint_t intptr_t\r\n#else\r\n#  define ptrint_t int\r\n#endif\r\n\r\n#ifndef BRG_UI8\r\n#  define BRG_UI8\r\n#  if UCHAR_MAX == 255u\r\n     typedef unsigned char uint_8t;\r\n#  else\r\n#    error Please define uint_8t as an 8-bit unsigned integer type in brg_types.h\r\n#  endif\r\n#endif\r\n\r\n#ifndef BRG_UI16\r\n#  define BRG_UI16\r\n#  if USHRT_MAX == 65535u\r\n     typedef unsigned short uint_16t;\r\n#  else\r\n#    error Please define uint_16t as a 16-bit unsigned short type in brg_types.h\r\n#  endif\r\n#endif\r\n\r\n#ifndef BRG_UI32\r\n#  define BRG_UI32\r\n#  if UINT_MAX == 4294967295u\r\n#    define li_32(h) 0x##h##u\r\n     typedef unsigned int uint_32t;\r\n#  elif ULONG_MAX == 4294967295u\r\n#    define li_32(h) 0x##h##ul\r\n     typedef unsigned long uint_32t;\r\n#  elif defined( _CRAY )\r\n#    error This code needs 32-bit data types, which Cray machines do not provide\r\n#  else\r\n#    error Please define uint_32t as a 32-bit unsigned integer type in brg_types.h\r\n#  endif\r\n#endif\r\n\r\n#ifndef BRG_UI64\r\n#  if defined( __BORLANDC__ ) && !defined( __MSDOS__ )\r\n#    define BRG_UI64\r\n#    define li_64(h) 0x##h##ui64\r\n     typedef unsigned __int64 uint_64t;\r\n#  elif defined( _MSC_VER ) && ( _MSC_VER < 1300 )    /* 1300 == VC++ 7.0 */\r\n#    define BRG_UI64\r\n#    define li_64(h) 0x##h##ui64\r\n     typedef unsigned __int64 uint_64t;\r\n#  elif defined( __sun ) && defined( ULONG_MAX ) && ULONG_MAX == 0xfffffffful\r\n#    define BRG_UI64\r\n#    define li_64(h) 0x##h##ull\r\n     typedef unsigned long long uint_64t;\r\n#  elif defined( __MVS__ )\r\n#    define BRG_UI64\r\n#    define li_64(h) 0x##h##ull\r\n     typedef unsigned int long long uint_64t;\r\n#  elif defined( UINT_MAX ) && UINT_MAX > 4294967295u\r\n#    if UINT_MAX == 18446744073709551615u\r\n#      define BRG_UI64\r\n#      define li_64(h) 0x##h##u\r\n       typedef unsigned int uint_64t;\r\n#    endif\r\n#  elif defined( ULONG_MAX ) && ULONG_MAX > 4294967295u\r\n#    if ULONG_MAX == 18446744073709551615ul\r\n#      define BRG_UI64\r\n#      define li_64(h) 0x##h##ul\r\n       typedef unsigned long uint_64t;\r\n#    endif\r\n#  elif defined( ULLONG_MAX ) && ULLONG_MAX > 4294967295u\r\n#    if ULLONG_MAX == 18446744073709551615ull\r\n#      define BRG_UI64\r\n#      define li_64(h) 0x##h##ull\r\n       typedef unsigned long long uint_64t;\r\n#    endif\r\n#  elif defined( ULONG_LONG_MAX ) && ULONG_LONG_MAX > 4294967295u\r\n#    if ULONG_LONG_MAX == 18446744073709551615ull\r\n#      define BRG_UI64\r\n#      define li_64(h) 0x##h##ull\r\n       typedef unsigned long long uint_64t;\r\n#    endif\r\n#  endif\r\n#endif\r\n\r\n#if !defined( BRG_UI64 )\r\n#  if defined( NEED_UINT_64T )\r\n#    error Please define uint_64t as an unsigned 64 bit type in brg_types.h\r\n#  endif\r\n#endif\r\n\r\n#ifndef RETURN_VALUES\r\n#  define RETURN_VALUES\r\n#  if defined( DLL_EXPORT )\r\n#    if defined( _MSC_VER ) || defined ( __INTEL_COMPILER )\r\n#      define VOID_RETURN    __declspec( dllexport ) void __stdcall\r\n#      define INT_RETURN     __declspec( dllexport ) int  __stdcall\r\n#    elif defined( __GNUC__ )\r\n#      define VOID_RETURN    __declspec( __dllexport__ ) void\r\n#      define INT_RETURN     __declspec( __dllexport__ ) int\r\n#    else\r\n#      error Use of the DLL is only available on the Microsoft, Intel and GCC compilers\r\n#    endif\r\n#  elif defined( DLL_IMPORT )\r\n#    if defined( _MSC_VER ) || defined ( __INTEL_COMPILER )\r\n#      define VOID_RETURN    __declspec( dllimport ) void __stdcall\r\n#      define INT_RETURN     __declspec( dllimport ) int  __stdcall\r\n#    elif defined( __GNUC__ )\r\n#      define VOID_RETURN    __declspec( __dllimport__ ) void\r\n#      define INT_RETURN     __declspec( __dllimport__ ) int\r\n#    else\r\n#      error Use of the DLL is only available on the Microsoft, Intel and GCC compilers\r\n#    endif\r\n#  elif defined( __WATCOMC__ )\r\n#    define VOID_RETURN  void __cdecl\r\n#    define INT_RETURN   int  __cdecl\r\n#  else\r\n#    define VOID_RETURN  void\r\n#    define INT_RETURN   int\r\n#  endif\r\n#endif\r\n\r\n/*\tThese defines are used to detect and set the memory alignment of pointers.\r\n    Note that offsets are in bytes.\r\n\r\n    ALIGN_OFFSET(x,n)\t\t\treturn the positive or zero offset of \r\n                                the memory addressed by the pointer 'x' \r\n                                from an address that is aligned on an \r\n                                'n' byte boundary ('n' is a power of 2)\r\n\r\n    ALIGN_FLOOR(x,n)\t\t\treturn a pointer that points to memory\r\n                                that is aligned on an 'n' byte boundary \r\n                                and is not higher than the memory address\r\n                                pointed to by 'x' ('n' is a power of 2)\r\n\r\n    ALIGN_CEIL(x,n)\t\t\t\treturn a pointer that points to memory\r\n                                that is aligned on an 'n' byte boundary \r\n                                and is not lower than the memory address\r\n                                pointed to by 'x' ('n' is a power of 2)\r\n*/\r\n\r\n#define ALIGN_OFFSET(x,n)\t(((ptrint_t)(x)) & ((n) - 1))\r\n#define ALIGN_FLOOR(x,n)\t((uint_8t*)(x) - ( ((ptrint_t)(x)) & ((n) - 1)))\r\n#define ALIGN_CEIL(x,n)\t\t((uint_8t*)(x) + (-((ptrint_t)(x)) & ((n) - 1)))\r\n\r\n/*  These defines are used to declare buffers in a way that allows\r\n    faster operations on longer variables to be used.  In all these\r\n    defines 'size' must be a power of 2 and >= 8. NOTE that the \r\n    buffer size is in bytes but the type length is in bits\r\n\r\n    UNIT_TYPEDEF(x,size)        declares a variable 'x' of length \r\n                                'size' bits\r\n\r\n    BUFR_TYPEDEF(x,size,bsize)  declares a buffer 'x' of length 'bsize' \r\n                                bytes defined as an array of variables\r\n                                each of 'size' bits (bsize must be a \r\n                                multiple of size / 8)\r\n\r\n    UNIT_CAST(x,size)           casts a variable to a type of \r\n                                length 'size' bits\r\n\r\n    UPTR_CAST(x,size)           casts a pointer to a pointer to a \r\n                                varaiable of length 'size' bits\r\n*/\r\n\r\n#define UI_TYPE(size)               uint_##size##t\r\n#define UNIT_TYPEDEF(x,size)        typedef UI_TYPE(size) x\r\n#define BUFR_TYPEDEF(x,size,bsize)  typedef UI_TYPE(size) x[bsize / (size >> 3)]\r\n#define UNIT_CAST(x,size)           ((UI_TYPE(size) )(x))  \r\n#define UPTR_CAST(x,size)           ((UI_TYPE(size)*)(x))\r\n\r\n#if defined(__cplusplus)\r\n}\r\n#endif\r\n\r\n#endif\r\n"
  },
  {
    "path": "plugins/cordova-plugin-zip/src/ios/aes/entropy.c",
    "content": "#ifdef _WIN32\n#include <windows.h>\n#else\n#include <sys/stat.h>\n#include <fcntl.h>\n#include <unistd.h>\n#endif\n\n#if defined(__cplusplus)\nextern \"C\"\n{\n#endif\n\n#ifdef _WIN32\nint entropy_fun(unsigned char buf[], unsigned int len)\n{\n    HCRYPTPROV provider;\n    unsigned __int64 pentium_tsc[1];\n    unsigned int i;\n    int result = 0;\n\n\n    if (CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT))\n    {\n        result = CryptGenRandom(provider, len, buf);\n        CryptReleaseContext(provider, 0);\n        if (result)\n            return len;\n    }\n\n    QueryPerformanceCounter((LARGE_INTEGER *)pentium_tsc);\n\n    for(i = 0; i < 8 && i < len; ++i)\n        buf[i] = ((unsigned char*)pentium_tsc)[i];\n\n    return i;\n}\n#else\nint entropy_fun(unsigned char buf[], unsigned int len)\n{\n    int frand = open(\"/dev/random\", O_RDONLY);\n    int rlen = 0;\n    if (frand != -1)\n    {\n        rlen = (int)read(frand, buf, len);\n        close(frand);\n    }\n    return rlen;\n}\n#endif\n\n#if defined(__cplusplus)\n}\n#endif\n"
  },
  {
    "path": "plugins/cordova-plugin-zip/src/ios/aes/entropy.h",
    "content": "\r\n#ifndef _ENTROPY_FUN_H\r\n#define _ENTROPY_FUN_H\r\n\r\n#if defined(__cplusplus)\r\nextern \"C\"\r\n{\r\n#endif\r\n\r\nint entropy_fun(unsigned char buf[], unsigned int len);\n\r\n#if defined(__cplusplus)\r\n}\r\n#endif\r\n\r\n#endif\r\n"
  },
  {
    "path": "plugins/cordova-plugin-zip/src/ios/aes/fileenc.c",
    "content": "/*\r\n   ---------------------------------------------------------------------------\r\n   Copyright (c) 2002, Dr Brian Gladman <                 >, Worcester, UK.\r\n   All rights reserved.\r\n\r\n   LICENSE TERMS\r\n\r\n   The free distribution and use of this software in both source and binary\r\n   form is allowed (with or without changes) provided that:\r\n\r\n   1. distributions of this source code include the above copyright\r\n      notice, this list of conditions and the following disclaimer;\r\n\r\n   2. distributions in binary form include the above copyright\r\n      notice, this list of conditions and the following disclaimer\r\n      in the documentation and/or other associated materials;\r\n\r\n   3. the copyright holder's name is not used to endorse products\r\n      built using this software without specific written permission.\r\n\r\n   ALTERNATIVELY, provided that this notice is retained in full, this product\r\n   may be distributed under the terms of the GNU General Public License (GPL),\r\n   in which case the provisions of the GPL apply INSTEAD OF those given above.\r\n\r\n   DISCLAIMER\r\n\r\n   This software is provided 'as is' with no explicit or implied warranties\r\n   in respect of its properties, including, but not limited to, correctness\r\n   and/or fitness for purpose.\r\n   -------------------------------------------------------------------------\r\n   Issue Date: 24/01/2003\r\n\r\n   This file implements password based file encryption and authentication\r\n   using AES in CTR mode, HMAC-SHA1 authentication and RFC2898 password\r\n   based key derivation.\r\n\r\n */\r\n\r\n#include <memory.h>\r\n\r\n#include \"fileenc.h\"\r\n\r\n#if defined(__cplusplus)\r\nextern \"C\"\r\n{\r\n#endif\r\n\r\n/* subroutine for data encryption/decryption    */\r\n/* this could be speeded up a lot by aligning   */\r\n/* buffers and using 32 bit operations          */\r\n\r\nstatic void encr_data(unsigned char data[], unsigned long d_len, fcrypt_ctx cx[1])\r\n{\r\n    unsigned long i = 0, pos = cx->encr_pos;\r\n\r\n    while (i < d_len) {\r\n        if (pos == AES_BLOCK_SIZE) {\r\n            unsigned int j = 0;\r\n            /* increment encryption nonce   */\r\n            while (j < 8 && !++cx->nonce[j])\r\n                ++j;\r\n            /* encrypt the nonce to form next xor buffer    */\r\n            aes_encrypt(cx->nonce, cx->encr_bfr, cx->encr_ctx);\r\n            pos = 0;\r\n        }\r\n\r\n        data[i++] ^= cx->encr_bfr[pos++];\r\n    }\r\n\r\n    cx->encr_pos = (unsigned int)pos;\r\n}\r\n\r\nint fcrypt_init(\r\n    int mode,                               /* the mode to be used (input)          */\r\n    const unsigned char pwd[],              /* the user specified password (input)  */\r\n    unsigned int pwd_len,                   /* the length of the password (input)   */\r\n    const unsigned char salt[],             /* the salt (input)                     */\r\n#ifdef PASSWORD_VERIFIER\r\n    unsigned char pwd_ver[PWD_VER_LENGTH],  /* 2 byte password verifier (output)    */\r\n#endif\r\n    fcrypt_ctx cx[1])                       /* the file encryption context (output) */\r\n{\r\n    unsigned char kbuf[2 * MAX_KEY_LENGTH + PWD_VER_LENGTH];\r\n\r\n    if (pwd_len > MAX_PWD_LENGTH)\r\n        return PASSWORD_TOO_LONG;\r\n\r\n    if (mode < 1 || mode > 3)\r\n        return BAD_MODE;\r\n\r\n    cx->mode = mode;\r\n    cx->pwd_len = pwd_len;\r\n\r\n    /* derive the encryption and authentication keys and the password verifier   */\r\n    derive_key(pwd, pwd_len, salt, SALT_LENGTH(mode), KEYING_ITERATIONS,\r\n               kbuf, 2 * KEY_LENGTH(mode) + PWD_VER_LENGTH);\r\n\r\n    /* initialise the encryption nonce and buffer pos   */\r\n    cx->encr_pos = AES_BLOCK_SIZE;\r\n    /* if we need a random component in the encryption  */\r\n    /* nonce, this is where it would have to be set     */\r\n    memset(cx->nonce, 0, AES_BLOCK_SIZE * sizeof(unsigned char));\r\n\r\n    /* initialise for encryption using key 1            */\r\n    aes_encrypt_key(kbuf, KEY_LENGTH(mode), cx->encr_ctx);\r\n\r\n    /* initialise for authentication using key 2        */\r\n    hmac_sha_begin(cx->auth_ctx);\r\n    hmac_sha_key(kbuf + KEY_LENGTH(mode), KEY_LENGTH(mode), cx->auth_ctx);\r\n\r\n#ifdef PASSWORD_VERIFIER\r\n    memcpy(pwd_ver, kbuf + 2 * KEY_LENGTH(mode), PWD_VER_LENGTH);\r\n#endif\r\n\r\n    return GOOD_RETURN;\r\n}\r\n\r\n/* perform 'in place' encryption and authentication */\r\n\r\nvoid fcrypt_encrypt(unsigned char data[], unsigned int data_len, fcrypt_ctx cx[1])\r\n{\r\n    encr_data(data, data_len, cx);\r\n    hmac_sha_data(data, data_len, cx->auth_ctx);\r\n}\r\n\r\n/* perform 'in place' authentication and decryption */\r\n\r\nvoid fcrypt_decrypt(unsigned char data[], unsigned int data_len, fcrypt_ctx cx[1])\r\n{\r\n    hmac_sha_data(data, data_len, cx->auth_ctx);\r\n    encr_data(data, data_len, cx);\r\n}\r\n\r\n/* close encryption/decryption and return the MAC value */\r\n\r\nint fcrypt_end(unsigned char mac[], fcrypt_ctx cx[1])\r\n{\r\n    hmac_sha_end(mac, MAC_LENGTH(cx->mode), cx->auth_ctx);\r\n    return MAC_LENGTH(cx->mode);    /* return MAC length in bytes   */\r\n}\r\n\r\n#if defined(__cplusplus)\r\n}\r\n#endif\r\n"
  },
  {
    "path": "plugins/cordova-plugin-zip/src/ios/aes/fileenc.h",
    "content": "/*\r\n ---------------------------------------------------------------------------\r\n Copyright (c) 2002, Dr Brian Gladman <                 >, Worcester, UK.\r\n All rights reserved.\r\n\r\n LICENSE TERMS\r\n\r\n The free distribution and use of this software in both source and binary\r\n form is allowed (with or without changes) provided that:\r\n\r\n   1. distributions of this source code include the above copyright\r\n      notice, this list of conditions and the following disclaimer;\r\n\r\n   2. distributions in binary form include the above copyright\r\n      notice, this list of conditions and the following disclaimer\r\n      in the documentation and/or other associated materials;\r\n\r\n   3. the copyright holder's name is not used to endorse products\r\n      built using this software without specific written permission.\r\n\r\n ALTERNATIVELY, provided that this notice is retained in full, this product\r\n may be distributed under the terms of the GNU General Public License (GPL),\r\n in which case the provisions of the GPL apply INSTEAD OF those given above.\r\n\r\n DISCLAIMER\r\n\r\n This software is provided 'as is' with no explicit or implied warranties\r\n in respect of its properties, including, but not limited to, correctness\r\n and/or fitness for purpose.\r\n ---------------------------------------------------------------------------\r\n Issue Date: 24/01/2003\r\n\r\n This file contains the header file for fileenc.c, which implements password\r\n based file encryption and authentication using AES in CTR mode, HMAC-SHA1 \r\n authentication and RFC2898 password based key derivation.\r\n*/\r\n\r\n#ifndef _FENC_H\r\n#define _FENC_H\r\n\r\n#include \"aes.h\"\r\n#include \"hmac.h\"\r\n#include \"pwd2key.h\"\r\n\r\n#define PASSWORD_VERIFIER\r\n\r\n#define MAX_KEY_LENGTH        32\r\n#define MAX_PWD_LENGTH       128\r\n#define MAX_SALT_LENGTH       16\r\n#define KEYING_ITERATIONS   1000\r\n\r\n#ifdef  PASSWORD_VERIFIER\r\n#define PWD_VER_LENGTH         2\r\n#else\r\n#define PWD_VER_LENGTH         0\r\n#endif\r\n\r\n#define GOOD_RETURN            0\r\n#define PASSWORD_TOO_LONG   -100\r\n#define BAD_MODE            -101\r\n\r\n/*\r\n    Field lengths (in bytes) versus File Encryption Mode (0 < mode < 4)\r\n\r\n    Mode Key Salt  MAC Overhead\r\n       1  16    8   10       18\r\n       2  24   12   10       22\r\n       3  32   16   10       26\r\n\r\n   The following macros assume that the mode value is correct.\r\n*/\r\n\r\n#define KEY_LENGTH(mode)        (8 * (mode & 3) + 8)\r\n#define SALT_LENGTH(mode)       (4 * (mode & 3) + 4)\r\n#define MAC_LENGTH(mode)        (10)\r\n\r\n/* the context for file encryption   */\r\n\r\n#if defined(__cplusplus)\r\nextern \"C\"\r\n{\r\n#endif\r\n\r\ntypedef struct\r\n{   unsigned char   nonce[AES_BLOCK_SIZE];      /* the CTR nonce          */\r\n    unsigned char   encr_bfr[AES_BLOCK_SIZE];   /* encrypt buffer         */\r\n    aes_encrypt_ctx encr_ctx[1];                /* encryption context     */\r\n    hmac_ctx        auth_ctx[1];                /* authentication context */\r\n    unsigned int    encr_pos;                   /* block position (enc)   */\r\n    unsigned int    pwd_len;                    /* password length        */\r\n    unsigned int    mode;                       /* File encryption mode   */\r\n} fcrypt_ctx;\r\n\r\n/* initialise file encryption or decryption */\r\n\r\nint fcrypt_init(\r\n    int mode,                               /* the mode to be used (input)          */\r\n    const unsigned char pwd[],              /* the user specified password (input)  */\r\n    unsigned int pwd_len,                   /* the length of the password (input)   */\r\n    const unsigned char salt[],             /* the salt (input)                     */\r\n#ifdef PASSWORD_VERIFIER\r\n    unsigned char pwd_ver[PWD_VER_LENGTH],  /* 2 byte password verifier (output)    */\r\n#endif\r\n    fcrypt_ctx      cx[1]);                 /* the file encryption context (output) */\r\n\r\n/* perform 'in place' encryption or decryption and authentication               */\r\n\r\nvoid fcrypt_encrypt(unsigned char data[], unsigned int data_len, fcrypt_ctx cx[1]);\r\nvoid fcrypt_decrypt(unsigned char data[], unsigned int data_len, fcrypt_ctx cx[1]);\r\n\r\n/* close encryption/decryption and return the MAC value */\r\n/* the return value is the length of the MAC            */\r\n\r\nint fcrypt_end(unsigned char mac[],     /* the MAC value (output)   */\r\n               fcrypt_ctx cx[1]);       /* the context (input)      */\r\n\r\n#if defined(__cplusplus)\r\n}\r\n#endif\r\n\r\n#endif\r\n"
  },
  {
    "path": "plugins/cordova-plugin-zip/src/ios/aes/hmac.c",
    "content": "/*\r\n ---------------------------------------------------------------------------\r\n Copyright (c) 2002, Dr Brian Gladman, Worcester, UK.   All rights reserved.\r\n\r\n LICENSE TERMS\r\n\r\n The free distribution and use of this software in both source and binary\r\n form is allowed (with or without changes) provided that:\r\n\r\n   1. distributions of this source code include the above copyright\r\n      notice, this list of conditions and the following disclaimer;\r\n\r\n   2. distributions in binary form include the above copyright\r\n      notice, this list of conditions and the following disclaimer\r\n      in the documentation and/or other associated materials;\r\n\r\n   3. the copyright holder's name is not used to endorse products\r\n      built using this software without specific written permission.\r\n\r\n ALTERNATIVELY, provided that this notice is retained in full, this product\r\n may be distributed under the terms of the GNU General Public License (GPL),\r\n in which case the provisions of the GPL apply INSTEAD OF those given above.\r\n\r\n DISCLAIMER\r\n\r\n This software is provided 'as is' with no explicit or implied warranties\r\n in respect of its properties, including, but not limited to, correctness\r\n and/or fitness for purpose.\r\n ---------------------------------------------------------------------------\r\n Issue Date: 26/08/2003\r\n\r\n This is an implementation of HMAC, the FIPS standard keyed hash function\r\n*/\r\n\r\n#include \"hmac.h\"\r\n#include \"brg_types.h\"\r\n\r\n#if defined(__cplusplus)\r\nextern \"C\"\r\n{\r\n#endif\r\n\r\n/* initialise the HMAC context to zero */\r\nvoid hmac_sha_begin(hmac_ctx cx[1])\r\n{\r\n    memset(cx, 0, sizeof(hmac_ctx));\r\n}\r\n\r\n/* input the HMAC key (can be called multiple times)    */\r\nint hmac_sha_key(const unsigned char key[], unsigned long key_len, hmac_ctx cx[1])\r\n{\r\n    if(cx->klen == HMAC_IN_DATA)                /* error if further key input   */\r\n        return HMAC_BAD_MODE;                   /* is attempted in data mode    */\r\n\r\n    if(cx->klen + key_len > HASH_INPUT_SIZE)    /* if the key has to be hashed  */\r\n    {\r\n        if(cx->klen <= HASH_INPUT_SIZE)         /* if the hash has not yet been */\r\n        {                                       /* started, initialise it and   */\r\n            sha_begin(cx->ctx);                 /* hash stored key characters   */\r\n            sha_hash(cx->key, cx->klen, cx->ctx);\r\n        }\r\n\r\n        sha_hash(key, key_len, cx->ctx);       /* hash long key data into hash */\r\n    }\r\n    else                                        /* otherwise store key data     */\r\n        memcpy(cx->key + cx->klen, key, key_len);\r\n\r\n    cx->klen += key_len;                        /* update the key length count  */\r\n    return HMAC_OK;\r\n}\r\n\r\n/* input the HMAC data (can be called multiple times) - */\r\n/* note that this call terminates the key input phase   */\r\nvoid hmac_sha_data(const unsigned char data[], unsigned long data_len, hmac_ctx cx[1])\r\n{   unsigned int i;\r\n\r\n    if(cx->klen != HMAC_IN_DATA)                /* if not yet in data phase */\r\n    {\r\n        if(cx->klen > HASH_INPUT_SIZE)          /* if key is being hashed   */\r\n        {                                       /* complete the hash and    */\r\n            sha_end(cx->key, cx->ctx);          /* store the result as the  */\r\n            cx->klen = HASH_OUTPUT_SIZE;        /* key and set new length   */\r\n        }\r\n\r\n        /* pad the key if necessary */\r\n        memset(cx->key + cx->klen, 0, HASH_INPUT_SIZE - cx->klen);\r\n\r\n        /* xor ipad into key value  */\r\n        for(i = 0; i < (HASH_INPUT_SIZE >> 2); ++i)\r\n            ((uint_32t*)cx->key)[i] ^= 0x36363636;\r\n\r\n        /* and start hash operation */\r\n        sha_begin(cx->ctx);\r\n        sha_hash(cx->key, HASH_INPUT_SIZE, cx->ctx);\r\n\r\n        /* mark as now in data mode */\r\n        cx->klen = HMAC_IN_DATA;\r\n    }\r\n\r\n    /* hash the data (if any)       */\r\n    if(data_len)\r\n        sha_hash(data, data_len, cx->ctx);\r\n}\r\n\r\n/* compute and output the MAC value */\r\nvoid hmac_sha_end(unsigned char mac[], unsigned long mac_len, hmac_ctx cx[1])\r\n{   unsigned char dig[HASH_OUTPUT_SIZE];\r\n    unsigned int i;\r\n\r\n    /* if no data has been entered perform a null data phase        */\r\n    if(cx->klen != HMAC_IN_DATA)\r\n        hmac_sha_data((const unsigned char*)0, 0, cx);\r\n\r\n    sha_end(dig, cx->ctx);         /* complete the inner hash       */\r\n\r\n    /* set outer key value using opad and removing ipad */\r\n    for(i = 0; i < (HASH_INPUT_SIZE >> 2); ++i)\r\n        ((uint_32t*)cx->key)[i] ^= 0x36363636 ^ 0x5c5c5c5c;\r\n\r\n    /* perform the outer hash operation */\r\n    sha_begin(cx->ctx);\r\n    sha_hash(cx->key, HASH_INPUT_SIZE, cx->ctx);\r\n    sha_hash(dig, HASH_OUTPUT_SIZE, cx->ctx);\r\n    sha_end(dig, cx->ctx);\r\n\r\n    /* output the hash value            */\r\n    for(i = 0; i < mac_len; ++i)\r\n        mac[i] = dig[i];\r\n}\r\n\r\n/* 'do it all in one go' subroutine     */\r\nvoid hmac_sha(const unsigned char key[], unsigned long key_len,\r\n          const unsigned char data[], unsigned long data_len,\r\n          unsigned char mac[], unsigned long mac_len)\r\n{   hmac_ctx    cx[1];\r\n\r\n    hmac_sha_begin(cx);\r\n    hmac_sha_key(key, key_len, cx);\r\n    hmac_sha_data(data, data_len, cx);\r\n    hmac_sha_end(mac, mac_len, cx);\r\n}\r\n\r\n#if defined(__cplusplus)\r\n}\r\n#endif\r\n"
  },
  {
    "path": "plugins/cordova-plugin-zip/src/ios/aes/hmac.h",
    "content": "/*\r\n ---------------------------------------------------------------------------\r\n Copyright (c) 2002, Dr Brian Gladman, Worcester, UK.   All rights reserved.\r\n\r\n LICENSE TERMS\r\n\r\n The free distribution and use of this software in both source and binary\r\n form is allowed (with or without changes) provided that:\r\n\r\n   1. distributions of this source code include the above copyright\r\n      notice, this list of conditions and the following disclaimer;\r\n\r\n   2. distributions in binary form include the above copyright\r\n      notice, this list of conditions and the following disclaimer\r\n      in the documentation and/or other associated materials;\r\n\r\n   3. the copyright holder's name is not used to endorse products\r\n      built using this software without specific written permission.\r\n\r\n ALTERNATIVELY, provided that this notice is retained in full, this product\r\n may be distributed under the terms of the GNU General Public License (GPL),\r\n in which case the provisions of the GPL apply INSTEAD OF those given above.\r\n\r\n DISCLAIMER\r\n\r\n This software is provided 'as is' with no explicit or implied warranties\r\n in respect of its properties, including, but not limited to, correctness\r\n and/or fitness for purpose.\r\n ---------------------------------------------------------------------------\r\n Issue Date: 26/08/2003\r\n\r\n This is an implementation of HMAC, the FIPS standard keyed hash function\r\n*/\r\n\r\n#ifndef _HMAC_H\r\n#define _HMAC_H\r\n\r\n#include <memory.h>\r\n\r\n#if defined(__cplusplus)\r\nextern \"C\"\r\n{\r\n#endif\r\n\r\n#define USE_SHA1\r\n\r\n#if !defined(USE_SHA1) && !defined(USE_SHA256)\r\n#error define USE_SHA1 or USE_SHA256 to set the HMAC hash algorithm\r\n#endif\r\n\r\n#ifdef USE_SHA1\r\n\r\n#include \"sha1.h\"\r\n\r\n#define HASH_INPUT_SIZE     SHA1_BLOCK_SIZE\r\n#define HASH_OUTPUT_SIZE    SHA1_DIGEST_SIZE\r\n#define sha_ctx             sha1_ctx\r\n#define sha_begin           sha1_begin\r\n#define sha_hash            sha1_hash\r\n#define sha_end             sha1_end\r\n\r\n#endif\r\n\r\n#ifdef USE_SHA256\r\n\r\n#include \"sha2.h\"\r\n\r\n#define HASH_INPUT_SIZE     SHA256_BLOCK_SIZE\r\n#define HASH_OUTPUT_SIZE    SHA256_DIGEST_SIZE\r\n#define sha_ctx             sha256_ctx\r\n#define sha_begin           sha256_begin\r\n#define sha_hash            sha256_hash\r\n#define sha_end             sha256_end\r\n\r\n#endif\r\n\r\n#define HMAC_OK                0\r\n#define HMAC_BAD_MODE         -1\r\n#define HMAC_IN_DATA  0xffffffff\r\n\r\ntypedef struct\r\n{   unsigned char   key[HASH_INPUT_SIZE];\r\n    sha_ctx         ctx[1];\r\n    unsigned long   klen;\r\n} hmac_ctx;\r\n\r\nvoid hmac_sha_begin(hmac_ctx cx[1]);\r\n\r\nint  hmac_sha_key(const unsigned char key[], unsigned long key_len, hmac_ctx cx[1]);\r\n\r\nvoid hmac_sha_data(const unsigned char data[], unsigned long data_len, hmac_ctx cx[1]);\r\n\r\nvoid hmac_sha_end(unsigned char mac[], unsigned long mac_len, hmac_ctx cx[1]);\r\n\r\nvoid hmac_sha(const unsigned char key[], unsigned long key_len,\r\n          const unsigned char data[], unsigned long data_len,\r\n          unsigned char mac[], unsigned long mac_len);\r\n\r\n#if defined(__cplusplus)\r\n}\r\n#endif\r\n\r\n#endif\r\n"
  },
  {
    "path": "plugins/cordova-plugin-zip/src/ios/aes/prng.c",
    "content": "/*\r\n ---------------------------------------------------------------------------\r\n Copyright (c) 2002, Dr Brian Gladman <                 >, Worcester, UK.\r\n All rights reserved.\r\n\r\n LICENSE TERMS\r\n\r\n The free distribution and use of this software in both source and binary\r\n form is allowed (with or without changes) provided that:\r\n\r\n   1. distributions of this source code include the above copyright\r\n      notice, this list of conditions and the following disclaimer;\r\n\r\n   2. distributions in binary form include the above copyright\r\n      notice, this list of conditions and the following disclaimer\r\n      in the documentation and/or other associated materials;\r\n\r\n   3. the copyright holder's name is not used to endorse products\r\n      built using this software without specific written permission.\r\n\r\n ALTERNATIVELY, provided that this notice is retained in full, this product\r\n may be distributed under the terms of the GNU General Public License (GPL),\r\n in which case the provisions of the GPL apply INSTEAD OF those given above.\r\n\r\n DISCLAIMER\r\n\r\n This software is provided 'as is' with no explicit or implied warranties\r\n in respect of its properties, including, but not limited to, correctness\r\n and/or fitness for purpose.\r\n ---------------------------------------------------------------------------\r\n Issue Date: 24/01/2003\r\n\r\n This file implements a random data pool based on the use of an external\r\n entropy function.  It is based on the ideas advocated by Peter Gutmann in\r\n his work on pseudo random sequence generators.  It is not a 'paranoid'\r\n random sequence generator and no attempt is made to protect the pool\r\n from prying eyes either by memory locking or by techniques to obscure\r\n its location in memory.\r\n*/\r\n\r\n#include <memory.h>\r\n#include \"prng.h\"\r\n\r\n#if defined(__cplusplus)\r\nextern \"C\"\r\n{\r\n#endif\r\n\r\n/* mix a random data pool using the SHA1 compression function (as   */\r\n/* suggested by Peter Gutmann in his paper on random pools)         */\r\n\r\nstatic void prng_mix(unsigned char buf[])\r\n{   unsigned int    i, len;\r\n    sha1_ctx        ctx[1];\r\n\r\n    /*lint -e{663}  unusual array to pointer conversion */\r\n    for(i = 0; i < PRNG_POOL_SIZE; i += SHA1_DIGEST_SIZE)\r\n    {\r\n        /* copy digest size pool block into SHA1 hash block */\r\n        memcpy(ctx->hash, buf + (i ? i : PRNG_POOL_SIZE)\r\n                            - SHA1_DIGEST_SIZE, SHA1_DIGEST_SIZE);\r\n\r\n        /* copy data from pool into the SHA1 data buffer    */\r\n        len = PRNG_POOL_SIZE - i;\r\n        memcpy(ctx->wbuf, buf + i, (len > SHA1_BLOCK_SIZE ? SHA1_BLOCK_SIZE : len));\r\n\r\n        if(len < SHA1_BLOCK_SIZE)\r\n            memcpy(((char*)ctx->wbuf) + len, buf, SHA1_BLOCK_SIZE - len);\r\n\r\n        /* compress using the SHA1 compression function     */\r\n        sha1_compile(ctx);\r\n\r\n        /* put digest size block back into the random pool  */\r\n        memcpy(buf + i, ctx->hash, SHA1_DIGEST_SIZE);\r\n    }\r\n}\r\n\r\n/* refresh the output buffer and update the random pool by adding   */\r\n/* entropy and remixing                                             */\r\n\r\nstatic void update_pool(prng_ctx ctx[1])\r\n{   unsigned int    i = 0;\r\n\r\n    /* transfer random pool data to the output buffer   */\r\n    memcpy(ctx->obuf, ctx->rbuf, PRNG_POOL_SIZE);\r\n\r\n    /* enter entropy data into the pool */\r\n    while(i < PRNG_POOL_SIZE)\r\n        i += ctx->entropy(ctx->rbuf + i, PRNG_POOL_SIZE - i);\r\n\r\n    /* invert and xor the original pool data into the pool  */\r\n    for(i = 0; i < PRNG_POOL_SIZE; ++i)\r\n        ctx->rbuf[i] ^= ~ctx->obuf[i];\r\n\r\n    /* mix the pool and the output buffer   */\r\n    prng_mix(ctx->rbuf);\r\n    prng_mix(ctx->obuf);\r\n}\r\n\r\nvoid prng_init(prng_entropy_fn fun, prng_ctx ctx[1])\r\n{   int i;\r\n\r\n    /* clear the buffers and the counter in the context     */\r\n    memset(ctx, 0, sizeof(prng_ctx));\r\n\r\n    /* set the pointer to the entropy collection function   */\r\n    ctx->entropy = fun;\r\n\r\n    /* initialise the random data pool                      */\r\n    update_pool(ctx);\r\n\r\n    /* mix the pool a minimum number of times               */\r\n    for(i = 0; i < PRNG_MIN_MIX; ++i)\r\n        prng_mix(ctx->rbuf);\r\n\r\n    /* update the pool to prime the pool output buffer      */\r\n    update_pool(ctx);\r\n}\r\n\r\n/* provide random bytes from the random data pool   */\r\n\r\nvoid prng_rand(unsigned char data[], unsigned int data_len, prng_ctx ctx[1])\r\n{   unsigned char   *rp = data;\r\n    unsigned int    len, pos = ctx->pos;\r\n\r\n    while(data_len)\r\n    {\r\n        /* transfer 'data_len' bytes (or the number of bytes remaining  */\r\n        /* the pool output buffer if less) into the output              */\r\n        len = (data_len < PRNG_POOL_SIZE - pos ? data_len : PRNG_POOL_SIZE - pos);\r\n        memcpy(rp, ctx->obuf + pos, len);\r\n        rp += len;          /* update ouput buffer position pointer     */\r\n        pos += len;         /* update pool output buffer pointer        */\r\n        data_len -= len;    /* update the remaining data count          */\r\n\r\n        /* refresh the random pool if necessary */\r\n        if(pos == PRNG_POOL_SIZE)\r\n        {\r\n            update_pool(ctx); pos = 0;\r\n        }\r\n    }\r\n\r\n    ctx->pos = pos;\r\n}\r\n\r\nvoid prng_end(prng_ctx ctx[1])\r\n{\r\n    /* ensure the data in the context is destroyed  */\r\n    memset(ctx, 0, sizeof(prng_ctx));\r\n}\r\n\r\n#if defined(__cplusplus)\r\n}\r\n#endif\r\n\r\n"
  },
  {
    "path": "plugins/cordova-plugin-zip/src/ios/aes/prng.h",
    "content": "/*\r\n ---------------------------------------------------------------------------\r\n Copyright (c) 2002, Dr Brian Gladman <                 >, Worcester, UK.\r\n All rights reserved.\r\n\r\n LICENSE TERMS\r\n\r\n The free distribution and use of this software in both source and binary\r\n form is allowed (with or without changes) provided that:\r\n\r\n   1. distributions of this source code include the above copyright\r\n      notice, this list of conditions and the following disclaimer;\r\n\r\n   2. distributions in binary form include the above copyright\r\n      notice, this list of conditions and the following disclaimer\r\n      in the documentation and/or other associated materials;\r\n\r\n   3. the copyright holder's name is not used to endorse products\r\n      built using this software without specific written permission.\r\n\r\n ALTERNATIVELY, provided that this notice is retained in full, this product\r\n may be distributed under the terms of the GNU General Public License (GPL),\r\n in which case the provisions of the GPL apply INSTEAD OF those given above.\r\n\r\n DISCLAIMER\r\n\r\n This software is provided 'as is' with no explicit or implied warranties\r\n in respect of its properties, including, but not limited to, correctness\r\n and/or fitness for purpose.\r\n ---------------------------------------------------------------------------\r\n Issue Date: 24/01/2003\r\n\r\n This is the header file for an implementation of a random data pool based on\r\n the use of an external entropy function (inspired by Peter Gutmann's work).\r\n*/\r\n\r\n#ifndef _PRNG_H\r\n#define _PRNG_H\r\n\r\n#include \"sha1.h\"\r\n\r\n#define PRNG_POOL_LEN    256    /* minimum random pool size             */\r\n#define PRNG_MIN_MIX      20    /* min initial pool mixing iterations   */\r\n\r\n/* ensure that pool length is a multiple of the SHA1 digest size        */\r\n\r\n#define PRNG_POOL_SIZE  (SHA1_DIGEST_SIZE * (1 + (PRNG_POOL_LEN - 1) / SHA1_DIGEST_SIZE))\r\n\r\n#if defined(__cplusplus)\r\nextern \"C\"\r\n{\r\n#endif\r\n\r\n/* A function for providing entropy is a parameter in the prng_init()   */\r\n/* call.  This function has the following form and returns a maximum    */\r\n/* of 'len' bytes of pseudo random data in the buffer 'buf'.  It can    */\r\n/* return less than 'len' bytes but will be repeatedly called for more  */\r\n/* data in this case.                                                   */\r\n\r\ntypedef int (*prng_entropy_fn)(unsigned char buf[], unsigned int len);\r\n\r\ntypedef struct\r\n{   unsigned char   rbuf[PRNG_POOL_SIZE];   /* the random pool          */\r\n    unsigned char   obuf[PRNG_POOL_SIZE];   /* pool output buffer       */\r\n    unsigned int    pos;                    /* output buffer position   */\r\n    prng_entropy_fn entropy;                /* entropy function pointer */\r\n} prng_ctx;\r\n\r\n/* initialise the random stream generator   */\r\nvoid prng_init(prng_entropy_fn fun, prng_ctx ctx[1]);\r\n\r\n/* obtain random bytes from the generator   */\r\nvoid prng_rand(unsigned char data[], unsigned int data_len, prng_ctx ctx[1]);\r\n\r\n/* close the random stream generator        */\r\nvoid prng_end(prng_ctx ctx[1]);\r\n\r\n#if defined(__cplusplus)\r\n}\r\n#endif\r\n\r\n#endif\r\n"
  },
  {
    "path": "plugins/cordova-plugin-zip/src/ios/aes/pwd2key.c",
    "content": "/*\r\n ---------------------------------------------------------------------------\r\n Copyright (c) 2002, Dr Brian Gladman, Worcester, UK.   All rights reserved.\r\n\r\n LICENSE TERMS\r\n\r\n The free distribution and use of this software in both source and binary\r\n form is allowed (with or without changes) provided that:\r\n\r\n   1. distributions of this source code include the above copyright\r\n      notice, this list of conditions and the following disclaimer;\r\n\r\n   2. distributions in binary form include the above copyright\r\n      notice, this list of conditions and the following disclaimer\r\n      in the documentation and/or other associated materials;\r\n\r\n   3. the copyright holder's name is not used to endorse products\r\n      built using this software without specific written permission.\r\n\r\n ALTERNATIVELY, provided that this notice is retained in full, this product\r\n may be distributed under the terms of the GNU General Public License (GPL),\r\n in which case the provisions of the GPL apply INSTEAD OF those given above.\r\n\r\n DISCLAIMER\r\n\r\n This software is provided 'as is' with no explicit or implied warranties\r\n in respect of its properties, including, but not limited to, correctness\r\n and/or fitness for purpose.\r\n ---------------------------------------------------------------------------\r\n Issue Date: 26/08/2003\r\n\r\n This is an implementation of RFC2898, which specifies key derivation from\r\n a password and a salt value.\r\n*/\r\n\r\n#include <memory.h>\r\n#include \"hmac.h\"\r\n\r\n#if defined(__cplusplus)\r\nextern \"C\"\r\n{\r\n#endif\r\n\r\nvoid derive_key(const unsigned char pwd[],  /* the PASSWORD     */\r\n               unsigned int pwd_len,        /* and its length   */\r\n               const unsigned char salt[],  /* the SALT and its */\r\n               unsigned int salt_len,       /* length           */\r\n               unsigned int iter,   /* the number of iterations */\r\n               unsigned char key[], /* space for the output key */\r\n               unsigned int key_len)/* and its required length  */\r\n{\r\n    unsigned int    i, j, k, n_blk;\r\n    unsigned char uu[HASH_OUTPUT_SIZE], ux[HASH_OUTPUT_SIZE];\r\n    hmac_ctx c1[1], c2[1], c3[1];\r\n\r\n    /* set HMAC context (c1) for password               */\r\n    hmac_sha_begin(c1);\r\n    hmac_sha_key(pwd, pwd_len, c1);\r\n\r\n    /* set HMAC context (c2) for password and salt      */\r\n    memcpy(c2, c1, sizeof(hmac_ctx));\r\n    hmac_sha_data(salt, salt_len, c2);\r\n\r\n    /* find the number of SHA blocks in the key         */\r\n    n_blk = 1 + (key_len - 1) / HASH_OUTPUT_SIZE;\r\n\r\n    for(i = 0; i < n_blk; ++i) /* for each block in key */\r\n    {\r\n        /* ux[] holds the running xor value             */\r\n        memset(ux, 0, HASH_OUTPUT_SIZE);\r\n\r\n        /* set HMAC context (c3) for password and salt  */\r\n        memcpy(c3, c2, sizeof(hmac_ctx));\r\n\r\n        /* enter additional data for 1st block into uu  */\r\n        uu[0] = (unsigned char)((i + 1) >> 24);\r\n        uu[1] = (unsigned char)((i + 1) >> 16);\r\n        uu[2] = (unsigned char)((i + 1) >> 8);\r\n        uu[3] = (unsigned char)(i + 1);\r\n\r\n        /* this is the key mixing iteration         */\r\n        for(j = 0, k = 4; j < iter; ++j)\r\n        {\r\n            /* add previous round data to HMAC      */\r\n            hmac_sha_data(uu, k, c3);\r\n\r\n            /* obtain HMAC for uu[]                 */\r\n            hmac_sha_end(uu, HASH_OUTPUT_SIZE, c3);\r\n\r\n            /* xor into the running xor block       */\r\n            for(k = 0; k < HASH_OUTPUT_SIZE; ++k)\r\n                ux[k] ^= uu[k];\r\n\r\n            /* set HMAC context (c3) for password   */\r\n            memcpy(c3, c1, sizeof(hmac_ctx));\r\n        }\r\n\r\n        /* compile key blocks into the key output   */\r\n        j = 0; k = i * HASH_OUTPUT_SIZE;\r\n        while(j < HASH_OUTPUT_SIZE && k < key_len)\r\n            key[k++] = ux[j++];\r\n    }\r\n}\r\n\r\n#ifdef TEST\r\n\r\n#include <stdio.h>\r\n\r\nstruct\r\n{   unsigned int    pwd_len;\r\n    unsigned int    salt_len;\r\n    unsigned int    it_count;\r\n    unsigned char   *pwd;\r\n    unsigned char   salt[32];\r\n    unsigned char   key[32];\r\n} tests[] =\r\n{\r\n    {   8, 4, 5, (unsigned char*)\"password\",\r\n        {   \r\n            0x12, 0x34, 0x56, 0x78 \r\n        },\r\n        {   \r\n            0x5c, 0x75, 0xce, 0xf0, 0x1a, 0x96, 0x0d, 0xf7,\r\n            0x4c, 0xb6, 0xb4, 0x9b, 0x9e, 0x38, 0xe6, 0xb5 \r\n        }\r\n    },\r\n    {   8, 8, 5, (unsigned char*)\"password\",\r\n        {   \r\n            0x12, 0x34, 0x56, 0x78, 0x78, 0x56, 0x34, 0x12 \r\n        },\r\n        {   \r\n            0xd1, 0xda, 0xa7, 0x86, 0x15, 0xf2, 0x87, 0xe6,\r\n            0xa1, 0xc8, 0xb1, 0x20, 0xd7, 0x06, 0x2a, 0x49 \r\n        }\r\n    },\r\n    {   8, 21, 1, (unsigned char*)\"password\",\r\n        {\r\n            \"ATHENA.MIT.EDUraeburn\"\r\n        },\r\n        {\r\n            0xcd, 0xed, 0xb5, 0x28, 0x1b, 0xb2, 0xf8, 0x01,\r\n            0x56, 0x5a, 0x11, 0x22, 0xb2, 0x56, 0x35, 0x15\r\n        }\r\n    },\r\n    {   8, 21, 2, (unsigned char*)\"password\",\r\n        {\r\n            \"ATHENA.MIT.EDUraeburn\"\r\n        },\r\n        {\r\n            0x01, 0xdb, 0xee, 0x7f, 0x4a, 0x9e, 0x24, 0x3e, \r\n            0x98, 0x8b, 0x62, 0xc7, 0x3c, 0xda, 0x93, 0x5d\r\n        }\r\n    },\r\n    {   8, 21, 1200, (unsigned char*)\"password\",\r\n        {\r\n            \"ATHENA.MIT.EDUraeburn\"\r\n        },\r\n        {\r\n            0x5c, 0x08, 0xeb, 0x61, 0xfd, 0xf7, 0x1e, 0x4e, \r\n            0x4e, 0xc3, 0xcf, 0x6b, 0xa1, 0xf5, 0x51, 0x2b\r\n        }\r\n    }\r\n};\r\n\r\nint main()\r\n{   unsigned int    i, j, key_len = 256;\r\n    unsigned char   key[256];\r\n\r\n    printf(\"\\nTest of RFC2898 Password Based Key Derivation\");\r\n    for(i = 0; i < 5; ++i)\r\n    {\r\n        derive_key(tests[i].pwd, tests[i].pwd_len, tests[i].salt,\r\n                    tests[i].salt_len, tests[i].it_count, key, key_len);\r\n\r\n        printf(\"\\ntest %i: \", i + 1);\r\n        printf(\"key %s\", memcmp(tests[i].key, key, 16) ? \"is bad\" : \"is good\");\r\n        for(j = 0; j < key_len && j < 64; j += 4)\r\n        {\r\n            if(j % 16 == 0)\r\n                printf(\"\\n\");\r\n            printf(\"0x%02x%02x%02x%02x \", key[j], key[j + 1], key[j + 2], key[j + 3]);\r\n        }\r\n        printf(j < key_len ? \" ... \\n\" : \"\\n\");\r\n    }\r\n    printf(\"\\n\");\r\n    return 0;\r\n}\r\n\r\n#if defined(__cplusplus)\r\n}\r\n#endif\r\n\r\n#endif\r\n"
  },
  {
    "path": "plugins/cordova-plugin-zip/src/ios/aes/pwd2key.h",
    "content": "/*\r\n ---------------------------------------------------------------------------\r\n Copyright (c) 2002, Dr Brian Gladman, Worcester, UK.   All rights reserved.\r\n\r\n LICENSE TERMS\r\n\r\n The free distribution and use of this software in both source and binary \r\n form is allowed (with or without changes) provided that:\r\n\r\n   1. distributions of this source code include the above copyright \r\n      notice, this list of conditions and the following disclaimer;\r\n\r\n   2. distributions in binary form include the above copyright\r\n      notice, this list of conditions and the following disclaimer\r\n      in the documentation and/or other associated materials;\r\n\r\n   3. the copyright holder's name is not used to endorse products \r\n      built using this software without specific written permission. \r\n\r\n ALTERNATIVELY, provided that this notice is retained in full, this product\r\n may be distributed under the terms of the GNU General Public License (GPL),\r\n in which case the provisions of the GPL apply INSTEAD OF those given above.\r\n \r\n DISCLAIMER\r\n\r\n This software is provided 'as is' with no explicit or implied warranties\r\n in respect of its properties, including, but not limited to, correctness \r\n and/or fitness for purpose.\r\n ---------------------------------------------------------------------------\r\n Issue Date: 26/08/2003\r\n\r\n This is an implementation of RFC2898, which specifies key derivation from\r\n a password and a salt value.\r\n*/\r\n\r\n#ifndef PWD2KEY_H\r\n#define PWD2KEY_H\r\n\r\n#if defined(__cplusplus)\r\nextern \"C\"\r\n{\r\n#endif\r\n\r\nvoid derive_key(\r\n        const unsigned char pwd[],   /* the PASSWORD, and   */\r\n        unsigned int pwd_len,        /*    its length       */ \r\n        const unsigned char salt[],  /* the SALT and its    */\r\n        unsigned int salt_len,       /*    length           */\r\n        unsigned int iter,      /* the number of iterations */\r\n        unsigned char key[],    /* space for the output key */\r\n        unsigned int key_len);  /* and its required length  */\r\n\r\n#if defined(__cplusplus)\r\n}\r\n#endif\r\n\r\n#endif\r\n"
  },
  {
    "path": "plugins/cordova-plugin-zip/src/ios/aes/sha1.c",
    "content": "/*\r\n ---------------------------------------------------------------------------\r\n Copyright (c) 2002, Dr Brian Gladman, Worcester, UK.   All rights reserved.\r\n\r\n LICENSE TERMS\r\n\r\n The free distribution and use of this software in both source and binary\r\n form is allowed (with or without changes) provided that:\r\n\r\n   1. distributions of this source code include the above copyright\r\n      notice, this list of conditions and the following disclaimer;\r\n\r\n   2. distributions in binary form include the above copyright\r\n      notice, this list of conditions and the following disclaimer\r\n      in the documentation and/or other associated materials;\r\n\r\n   3. the copyright holder's name is not used to endorse products\r\n      built using this software without specific written permission.\r\n\r\n ALTERNATIVELY, provided that this notice is retained in full, this product\r\n may be distributed under the terms of the GNU General Public License (GPL),\r\n in which case the provisions of the GPL apply INSTEAD OF those given above.\r\n\r\n DISCLAIMER\r\n\r\n This software is provided 'as is' with no explicit or implied warranties\r\n in respect of its properties, including, but not limited to, correctness\r\n and/or fitness for purpose.\r\n ---------------------------------------------------------------------------\r\n Issue Date: 01/08/2005\r\n\r\n This is a byte oriented version of SHA1 that operates on arrays of bytes\r\n stored in memory.\r\n*/\r\n\r\n#include <string.h>     /* for memcpy() etc.        */\r\n\r\n#include \"sha1.h\"\r\n#include \"brg_endian.h\"\r\n\r\n#if defined(__cplusplus)\r\nextern \"C\"\r\n{\r\n#endif\r\n\r\n#if defined( _MSC_VER ) && ( _MSC_VER > 800 )\r\n#pragma intrinsic(memcpy)\r\n#endif\r\n\r\n#if 0 && defined(_MSC_VER)\r\n#define rotl32  _lrotl\r\n#define rotr32  _lrotr\r\n#else\r\n#define rotl32(x,n)   (((x) << n) | ((x) >> (32 - n)))\r\n#define rotr32(x,n)   (((x) >> n) | ((x) << (32 - n)))\r\n#endif\r\n\r\n#if !defined(bswap_32)\r\n#define bswap_32(x) ((rotr32((x), 24) & 0x00ff00ff) | (rotr32((x), 8) & 0xff00ff00))\r\n#endif\r\n\r\n#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)\r\n#define SWAP_BYTES\r\n#else\r\n#undef  SWAP_BYTES\r\n#endif\r\n\r\n#if defined(SWAP_BYTES)\r\n#define bsw_32(p,n) \\\r\n    { int _i = (n); while(_i--) ((uint_32t*)p)[_i] = bswap_32(((uint_32t*)p)[_i]); }\r\n#else\r\n#define bsw_32(p,n)\r\n#endif\r\n\r\n#define SHA1_MASK   (SHA1_BLOCK_SIZE - 1)\r\n\r\n#if 0\r\n\r\n#define ch(x,y,z)       (((x) & (y)) ^ (~(x) & (z)))\r\n#define parity(x,y,z)   ((x) ^ (y) ^ (z))\r\n#define maj(x,y,z)      (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))\r\n\r\n#else   /* Discovered by Rich Schroeppel and Colin Plumb   */\r\n\r\n#define ch(x,y,z)       ((z) ^ ((x) & ((y) ^ (z))))\r\n#define parity(x,y,z)   ((x) ^ (y) ^ (z))\r\n#define maj(x,y,z)      (((x) & (y)) | ((z) & ((x) ^ (y))))\r\n\r\n#endif\r\n\r\n/* Compile 64 bytes of hash data into SHA1 context. Note    */\r\n/* that this routine assumes that the byte order in the     */\r\n/* ctx->wbuf[] at this point is in such an order that low   */\r\n/* address bytes in the ORIGINAL byte stream will go in     */\r\n/* this buffer to the high end of 32-bit words on BOTH big  */\r\n/* and little endian systems                                */\r\n\r\n#ifdef ARRAY\r\n#define q(v,n)  v[n]\r\n#else\r\n#define q(v,n)  v##n\r\n#endif\r\n\r\n#define one_cycle(v,a,b,c,d,e,f,k,h)            \\\r\n    q(v,e) += rotr32(q(v,a),27) +               \\\r\n              f(q(v,b),q(v,c),q(v,d)) + k + h;  \\\r\n    q(v,b)  = rotr32(q(v,b), 2)\r\n\r\n#define five_cycle(v,f,k,i)                 \\\r\n    one_cycle(v, 0,1,2,3,4, f,k,hf(i  ));   \\\r\n    one_cycle(v, 4,0,1,2,3, f,k,hf(i+1));   \\\r\n    one_cycle(v, 3,4,0,1,2, f,k,hf(i+2));   \\\r\n    one_cycle(v, 2,3,4,0,1, f,k,hf(i+3));   \\\r\n    one_cycle(v, 1,2,3,4,0, f,k,hf(i+4))\r\n\r\nVOID_RETURN sha1_compile(sha1_ctx ctx[1])\r\n{   uint_32t    *w = ctx->wbuf;\r\n\r\n#ifdef ARRAY\r\n    uint_32t    v[5];\r\n    memcpy(v, ctx->hash, 5 * sizeof(uint_32t));\r\n#else\r\n    uint_32t    v0, v1, v2, v3, v4;\r\n    v0 = ctx->hash[0]; v1 = ctx->hash[1];\r\n    v2 = ctx->hash[2]; v3 = ctx->hash[3];\r\n    v4 = ctx->hash[4];\r\n#endif\r\n\r\n#define hf(i)   w[i]\r\n\r\n    five_cycle(v, ch, 0x5a827999,  0);\r\n    five_cycle(v, ch, 0x5a827999,  5);\r\n    five_cycle(v, ch, 0x5a827999, 10);\r\n    one_cycle(v,0,1,2,3,4, ch, 0x5a827999, hf(15)); \\\r\n\r\n#undef  hf\r\n#define hf(i) (w[(i) & 15] = rotl32(                    \\\r\n                 w[((i) + 13) & 15] ^ w[((i) + 8) & 15] \\\r\n               ^ w[((i) +  2) & 15] ^ w[(i) & 15], 1))\r\n\r\n    one_cycle(v,4,0,1,2,3, ch, 0x5a827999, hf(16));\r\n    one_cycle(v,3,4,0,1,2, ch, 0x5a827999, hf(17));\r\n    one_cycle(v,2,3,4,0,1, ch, 0x5a827999, hf(18));\r\n    one_cycle(v,1,2,3,4,0, ch, 0x5a827999, hf(19));\r\n\r\n    five_cycle(v, parity, 0x6ed9eba1,  20);\r\n    five_cycle(v, parity, 0x6ed9eba1,  25);\r\n    five_cycle(v, parity, 0x6ed9eba1,  30);\r\n    five_cycle(v, parity, 0x6ed9eba1,  35);\r\n\r\n    five_cycle(v, maj, 0x8f1bbcdc,  40);\r\n    five_cycle(v, maj, 0x8f1bbcdc,  45);\r\n    five_cycle(v, maj, 0x8f1bbcdc,  50);\r\n    five_cycle(v, maj, 0x8f1bbcdc,  55);\r\n\r\n    five_cycle(v, parity, 0xca62c1d6,  60);\r\n    five_cycle(v, parity, 0xca62c1d6,  65);\r\n    five_cycle(v, parity, 0xca62c1d6,  70);\r\n    five_cycle(v, parity, 0xca62c1d6,  75);\r\n\r\n#ifdef ARRAY\r\n    ctx->hash[0] += v[0]; ctx->hash[1] += v[1];\r\n    ctx->hash[2] += v[2]; ctx->hash[3] += v[3];\r\n    ctx->hash[4] += v[4];\r\n#else\r\n    ctx->hash[0] += v0; ctx->hash[1] += v1;\r\n    ctx->hash[2] += v2; ctx->hash[3] += v3;\r\n    ctx->hash[4] += v4;\r\n#endif\r\n}\r\n\r\nVOID_RETURN sha1_begin(sha1_ctx ctx[1])\r\n{\r\n    ctx->count[0] = ctx->count[1] = 0;\r\n    ctx->hash[0] = 0x67452301;\r\n    ctx->hash[1] = 0xefcdab89;\r\n    ctx->hash[2] = 0x98badcfe;\r\n    ctx->hash[3] = 0x10325476;\r\n    ctx->hash[4] = 0xc3d2e1f0;\r\n}\r\n\r\n/* SHA1 hash data in an array of bytes into hash buffer and */\r\n/* call the hash_compile function as required.              */\r\n\r\nVOID_RETURN sha1_hash(const unsigned char data[], unsigned long len, sha1_ctx ctx[1])\r\n{   uint_32t pos = (uint_32t)(ctx->count[0] & SHA1_MASK),\r\n            space = SHA1_BLOCK_SIZE - pos;\r\n    const unsigned char *sp = data;\r\n\r\n    if((ctx->count[0] += len) < len)\r\n        ++(ctx->count[1]);\r\n\r\n    while(len >= space)     /* tranfer whole blocks if possible  */\r\n    {\r\n        memcpy(((unsigned char*)ctx->wbuf) + pos, sp, space);\r\n        sp += space; len -= space; space = SHA1_BLOCK_SIZE; pos = 0;\r\n        bsw_32(ctx->wbuf, SHA1_BLOCK_SIZE >> 2);\r\n        sha1_compile(ctx);\r\n    }\r\n\r\n    memcpy(((unsigned char*)ctx->wbuf) + pos, sp, len);\r\n}\r\n\r\n/* SHA1 final padding and digest calculation  */\r\n\r\nVOID_RETURN sha1_end(unsigned char hval[], sha1_ctx ctx[1])\r\n{   uint_32t    i = (uint_32t)(ctx->count[0] & SHA1_MASK);\r\n\r\n    /* put bytes in the buffer in an order in which references to   */\r\n    /* 32-bit words will put bytes with lower addresses into the    */\r\n    /* top of 32 bit words on BOTH big and little endian machines   */\r\n    bsw_32(ctx->wbuf, (i + 3) >> 2);\r\n\r\n    /* we now need to mask valid bytes and add the padding which is */\r\n    /* a single 1 bit and as many zero bits as necessary. Note that */\r\n    /* we can always add the first padding byte here because the    */\r\n    /* buffer always has at least one empty slot                    */\r\n    ctx->wbuf[i >> 2] &= 0xffffff80 << 8 * (~i & 3);\r\n    ctx->wbuf[i >> 2] |= 0x00000080 << 8 * (~i & 3);\r\n\r\n    /* we need 9 or more empty positions, one for the padding byte  */\r\n    /* (above) and eight for the length count. If there is not      */\r\n    /* enough space, pad and empty the buffer                       */\r\n    if(i > SHA1_BLOCK_SIZE - 9)\r\n    {\r\n        if(i < 60) ctx->wbuf[15] = 0;\r\n        sha1_compile(ctx);\r\n        i = 0;\r\n    }\r\n    else    /* compute a word index for the empty buffer positions  */\r\n        i = (i >> 2) + 1;\r\n\r\n    while(i < 14) /* and zero pad all but last two positions        */\r\n        ctx->wbuf[i++] = 0;\r\n\r\n    /* the following 32-bit length fields are assembled in the      */\r\n    /* wrong byte order on little endian machines but this is       */\r\n    /* corrected later since they are only ever used as 32-bit      */\r\n    /* word values.                                                 */\r\n    ctx->wbuf[14] = (ctx->count[1] << 3) | (ctx->count[0] >> 29);\r\n    ctx->wbuf[15] = ctx->count[0] << 3;\r\n    sha1_compile(ctx);\r\n\r\n    /* extract the hash value as bytes in case the hash buffer is   */\r\n    /* misaligned for 32-bit words                                  */\r\n    for(i = 0; i < SHA1_DIGEST_SIZE; ++i)\r\n        hval[i] = (unsigned char)(ctx->hash[i >> 2] >> (8 * (~i & 3)));\r\n}\r\n\r\nVOID_RETURN sha1(unsigned char hval[], const unsigned char data[], unsigned long len)\r\n{   sha1_ctx    cx[1];\r\n\r\n    sha1_begin(cx); sha1_hash(data, len, cx); sha1_end(hval, cx);\r\n}\r\n\r\n#if defined(__cplusplus)\r\n}\r\n#endif\r\n"
  },
  {
    "path": "plugins/cordova-plugin-zip/src/ios/aes/sha1.h",
    "content": "/*\r\n ---------------------------------------------------------------------------\r\n Copyright (c) 2002, Dr Brian Gladman, Worcester, UK.   All rights reserved.\r\n\r\n LICENSE TERMS\r\n\r\n The free distribution and use of this software in both source and binary\r\n form is allowed (with or without changes) provided that:\r\n\r\n   1. distributions of this source code include the above copyright\r\n      notice, this list of conditions and the following disclaimer;\r\n\r\n   2. distributions in binary form include the above copyright\r\n      notice, this list of conditions and the following disclaimer\r\n      in the documentation and/or other associated materials;\r\n\r\n   3. the copyright holder's name is not used to endorse products\r\n      built using this software without specific written permission.\r\n\r\n ALTERNATIVELY, provided that this notice is retained in full, this product\r\n may be distributed under the terms of the GNU General Public License (GPL),\r\n in which case the provisions of the GPL apply INSTEAD OF those given above.\r\n\r\n DISCLAIMER\r\n\r\n This software is provided 'as is' with no explicit or implied warranties\r\n in respect of its properties, including, but not limited to, correctness\r\n and/or fitness for purpose.\r\n ---------------------------------------------------------------------------\r\n Issue Date: 01/08/2005\r\n*/\r\n\r\n#ifndef _SHA1_H\r\n#define _SHA1_H\r\n\r\n#include <stdlib.h>\r\n#include \"brg_types.h\"\r\n\r\n#define SHA1_BLOCK_SIZE  64\r\n#define SHA1_DIGEST_SIZE 20\r\n\r\n#if defined(__cplusplus)\r\nextern \"C\"\r\n{\r\n#endif\r\n\r\n/* type to hold the SHA256 context  */\r\n\r\ntypedef struct\r\n{   uint_32t count[2];\r\n    uint_32t hash[5];\r\n    uint_32t wbuf[16];\r\n} sha1_ctx;\r\n\r\n/* Note that these prototypes are the same for both bit and */\r\n/* byte oriented implementations. However the length fields */\r\n/* are in bytes or bits as appropriate for the version used */\r\n/* and bit sequences are input as arrays of bytes in which  */\r\n/* bit sequences run from the most to the least significant */\r\n/* end of each byte                                         */\r\n\r\nVOID_RETURN sha1_compile(sha1_ctx ctx[1]);\r\n\r\nVOID_RETURN sha1_begin(sha1_ctx ctx[1]);\r\nVOID_RETURN sha1_hash(const unsigned char data[], unsigned long len, sha1_ctx ctx[1]);\r\nVOID_RETURN sha1_end(unsigned char hval[], sha1_ctx ctx[1]);\r\nVOID_RETURN sha1(unsigned char hval[], const unsigned char data[], unsigned long len);\r\n\r\n#if defined(__cplusplus)\r\n}\r\n#endif\r\n\r\n#endif\r\n"
  },
  {
    "path": "plugins/cordova-plugin-zip/src/ios/minizip/crypt.h",
    "content": "/* crypt.h -- base code for traditional PKWARE encryption\n   Version 1.01e, February 12th, 2005\n\n   Copyright (C) 1998-2005 Gilles Vollant\n   Modifications for Info-ZIP crypting\n     Copyright (C) 2003 Terry Thorsen\n\n   This code is a modified version of crypting code in Info-ZIP distribution\n\n   Copyright (C) 1990-2000 Info-ZIP.  All rights reserved.\n\n   See the Info-ZIP LICENSE file version 2000-Apr-09 or later for terms of use\n   which also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html\n\n   The encryption/decryption parts of this source code (as opposed to the\n   non-echoing password parts) were originally written in Europe. The\n   whole source package can be freely distributed, including from the USA.\n   (Prior to January 2000, re-export from the US was a violation of US law.)\n\n   This encryption code is a direct transcription of the algorithm from\n   Roger Schlafly, described by Phil Katz in the file appnote.txt. This\n   file (appnote.txt) is distributed with the PKZIP program (even in the\n   version without encryption capabilities).\n\n   If you don't need crypting in your application, just define symbols\n   NOCRYPT and NOUNCRYPT.\n*/\n\n#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))\n\n/***********************************************************************\n * Return the next byte in the pseudo-random sequence\n */\nstatic int decrypt_byte(unsigned long* pkeys, const unsigned long* pcrc_32_tab)\n{\n    unsigned temp;  /* POTENTIAL BUG:  temp*(temp^1) may overflow in an\n                     * unpredictable manner on 16-bit systems; not a problem\n                     * with any known compiler so far, though */\n\n    temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2;\n    return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);\n}\n\n/***********************************************************************\n * Update the encryption keys with the next byte of plain text\n */\nstatic int update_keys(unsigned long* pkeys,const unsigned long* pcrc_32_tab,int c)\n{\n    (*(pkeys+0)) = CRC32((*(pkeys+0)), c);\n    (*(pkeys+1)) += (*(pkeys+0)) & 0xff;\n    (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;\n    {\n      register int keyshift = (int)((*(pkeys+1)) >> 24);\n      (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift);\n    }\n    return c;\n}\n\n\n/***********************************************************************\n * Initialize the encryption keys and the random header according to\n * the given password.\n */\nstatic void init_keys(const char* passwd,unsigned long* pkeys,const unsigned long* pcrc_32_tab)\n{\n    *(pkeys+0) = 305419896L;\n    *(pkeys+1) = 591751049L;\n    *(pkeys+2) = 878082192L;\n    while (*passwd != 0) {\n        update_keys(pkeys,pcrc_32_tab,(int)*passwd);\n        passwd++;\n    }\n}\n\n#define zdecode(pkeys,pcrc_32_tab,c) \\\n    (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab)))\n\n#define zencode(pkeys,pcrc_32_tab,c,t) \\\n    (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c))\n\n#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED\n\n#define RAND_HEAD_LEN  12\n   /* \"last resort\" source for second part of crypt seed pattern */\n#  ifndef ZCR_SEED2\n#    define ZCR_SEED2 3141592654UL     /* use PI as default pattern */\n#  endif\n\nstatic int crypthead(const char* passwd,      /* password string */\n                     unsigned char* buf,      /* where to write header */\n                     int bufSize,\n                     unsigned long* pkeys,\n                     const unsigned long* pcrc_32_tab,\n                     unsigned long crcForCrypting)\n{\n    int n;                                  /* index in random header */\n    int t;                                  /* temporary */\n    int c;                                  /* random byte */\n    unsigned char header[RAND_HEAD_LEN-2];  /* random header */\n    static unsigned calls = 0;              /* ensure different random header each time */\n\n    if (bufSize<RAND_HEAD_LEN)\n      return 0;\n\n    /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the\n     * output of rand() to get less predictability, since rand() is\n     * often poorly implemented.\n     */\n    if (++calls == 1)\n    {\n        srand((unsigned)(time(NULL) ^ ZCR_SEED2));\n    }\n    init_keys(passwd, pkeys, pcrc_32_tab);\n    for (n = 0; n < RAND_HEAD_LEN-2; n++)\n    {\n        c = (rand() >> 7) & 0xff;\n        header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t);\n    }\n    /* Encrypt random header (last two bytes is high word of crc) */\n    init_keys(passwd, pkeys, pcrc_32_tab);\n    for (n = 0; n < RAND_HEAD_LEN-2; n++)\n    {\n        buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t);\n    }\n    buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t);\n    buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t);\n    return n;\n}\n\n#endif\n"
  },
  {
    "path": "plugins/cordova-plugin-zip/src/ios/minizip/ioapi.c",
    "content": "/* ioapi.h -- IO base function header for compress/uncompress .zip\n   part of the MiniZip project\n\n   Copyright (C) 1998-2010 Gilles Vollant\n     http://www.winimage.com/zLibDll/minizip.html\n   Modifications for Zip64 support\n     Copyright (C) 2009-2010 Mathias Svensson\n     http://result42.com\n\n   This program is distributed under the terms of the same license as zlib.\n   See the accompanying LICENSE file for the full text of the license.\n*/\n\n#include <stdlib.h>\n#include <string.h>\n\n#include \"ioapi.h\"\n\n#if defined(_WIN32)\n#  define snprintf _snprintf\n#endif\n\n#ifdef __APPLE__\n/* In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions */\n#  define FOPEN_FUNC(filename, mode) fopen(filename, mode)\n#  define FTELLO_FUNC(stream) ftello(stream)\n#  define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin)\n#else\n#  define FOPEN_FUNC(filename, mode) fopen64(filename, mode)\n#  define FTELLO_FUNC(stream) ftello64(stream)\n#  define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin)\n#endif\n\n/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */\n#ifndef SEEK_CUR\n#  define SEEK_CUR    1\n#endif\n#ifndef SEEK_END\n#  define SEEK_END    2\n#endif\n#ifndef SEEK_SET\n#  define SEEK_SET    0\n#endif\n\nvoidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode)\n{\n    if (pfilefunc->zfile_func64.zopen64_file != NULL)\n        return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,filename,mode);\n    return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque,(const char*)filename,mode);\n}\n\nvoidpf call_zopendisk64 OF((const zlib_filefunc64_32_def* pfilefunc, voidpf filestream, int number_disk, int mode))\n{\n    if (pfilefunc->zfile_func64.zopendisk64_file != NULL)\n        return (*(pfilefunc->zfile_func64.zopendisk64_file)) (pfilefunc->zfile_func64.opaque,filestream,number_disk,mode);\n    return (*(pfilefunc->zopendisk32_file))(pfilefunc->zfile_func64.opaque,filestream,number_disk,mode);\n}\n\nlong call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)\n{\n    uLong offsetTruncated;\n    if (pfilefunc->zfile_func64.zseek64_file != NULL)\n        return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin);\n    offsetTruncated = (uLong)offset;\n    if (offsetTruncated != offset)\n        return -1;\n    return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream,offsetTruncated,origin);\n}\n\nZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)\n{\n    uLong tell_uLong;\n    if (pfilefunc->zfile_func64.zseek64_file != NULL)\n        return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream);\n    tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream);\n    if ((tell_uLong) == 0xffffffff)\n        return (ZPOS64_T)-1;\n    return tell_uLong;\n}\n\nvoid fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32)\n{\n    p_filefunc64_32->zfile_func64.zopen64_file = NULL;\n    p_filefunc64_32->zfile_func64.zopendisk64_file = NULL;\n    p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file;\n    p_filefunc64_32->zopendisk32_file = p_filefunc32->zopendisk_file;\n    p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;\n    p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file;\n    p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file;\n    p_filefunc64_32->zfile_func64.ztell64_file = NULL;\n    p_filefunc64_32->zfile_func64.zseek64_file = NULL;\n    p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file;\n    p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;\n    p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque;\n    p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file;\n    p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file;\n}\n\nstatic voidpf  ZCALLBACK fopen_file_func OF((voidpf opaque, const char* filename, int mode));\nstatic uLong   ZCALLBACK fread_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size));\nstatic uLong   ZCALLBACK fwrite_file_func OF((voidpf opaque, voidpf stream, const void* buf,uLong size));\nstatic ZPOS64_T ZCALLBACK ftell64_file_func OF((voidpf opaque, voidpf stream));\nstatic long    ZCALLBACK fseek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));\nstatic int     ZCALLBACK fclose_file_func OF((voidpf opaque, voidpf stream));\nstatic int     ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream));\n\ntypedef struct \n{\n    FILE *file;\n    int filenameLength;\n    void *filename;\n} FILE_IOPOSIX;\n\nstatic voidpf file_build_ioposix(FILE *file, const char *filename)\n{\n    FILE_IOPOSIX *ioposix = NULL;\n    if (file == NULL)\n        return NULL;\n    ioposix = (FILE_IOPOSIX*)malloc(sizeof(FILE_IOPOSIX));\n    ioposix->file = file;\n    ioposix->filenameLength = (int)strlen(filename) + 1;\n    ioposix->filename = (char*)malloc(ioposix->filenameLength * sizeof(char));\n    strncpy(ioposix->filename, filename, ioposix->filenameLength);\n    return (voidpf)ioposix;\n}\n\nstatic voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, int mode)\n{\n    FILE* file = NULL;\n    const char* mode_fopen = NULL;\n    if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER) == ZLIB_FILEFUNC_MODE_READ)\n        mode_fopen = \"rb\";\n    else if (mode & ZLIB_FILEFUNC_MODE_EXISTING)\n        mode_fopen = \"r+b\";\n    else if (mode & ZLIB_FILEFUNC_MODE_CREATE)\n        mode_fopen = \"wb\";\n\n    if ((filename != NULL) && (mode_fopen != NULL))\n    {\n        file = fopen(filename, mode_fopen);\n        return file_build_ioposix(file, filename);\n    }\n    return file;\n}\n\nstatic voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, int mode)\n{\n    FILE* file = NULL;\n    const char* mode_fopen = NULL;\n    if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER) == ZLIB_FILEFUNC_MODE_READ)\n        mode_fopen = \"rb\";\n    else if (mode & ZLIB_FILEFUNC_MODE_EXISTING)\n        mode_fopen = \"r+b\";\n    else if (mode & ZLIB_FILEFUNC_MODE_CREATE)\n        mode_fopen = \"wb\";\n\n    if ((filename != NULL) && (mode_fopen != NULL))\n    {\n        file = FOPEN_FUNC((const char*)filename, mode_fopen);\n        return file_build_ioposix(file, (const char*)filename);\n    }\n    return file;\n}\n\nstatic voidpf ZCALLBACK fopendisk64_file_func (voidpf opaque, voidpf stream, int number_disk, int mode)\n{\n    FILE_IOPOSIX *ioposix = NULL;\n    char *diskFilename = NULL;\n    voidpf ret = NULL;\n    int i = 0;\n\n    if (stream == NULL)\n        return NULL;\n    ioposix = (FILE_IOPOSIX*)stream;\n    diskFilename = (char*)malloc(ioposix->filenameLength * sizeof(char));\n    strncpy(diskFilename, ioposix->filename, ioposix->filenameLength);\n    for (i = ioposix->filenameLength - 1; i >= 0; i -= 1)\n    {\n        if (diskFilename[i] != '.') \n            continue;\n        snprintf(&diskFilename[i], ioposix->filenameLength - i, \".z%02d\", number_disk + 1);\n        break;\n    }\n    if (i >= 0)\n        ret = fopen64_file_func(opaque, diskFilename, mode);\n    free(diskFilename);\n    return ret;\n}\n\nstatic voidpf ZCALLBACK fopendisk_file_func (voidpf opaque, voidpf stream, int number_disk, int mode)\n{\n    FILE_IOPOSIX *ioposix = NULL;\n    char *diskFilename = NULL;\n    voidpf ret = NULL;\n    int i = 0;\n\n    if (stream == NULL)\n        return NULL;\n    ioposix = (FILE_IOPOSIX*)stream;\n    diskFilename = (char*)malloc(ioposix->filenameLength * sizeof(char));\n    strncpy(diskFilename, ioposix->filename, ioposix->filenameLength);\n    for (i = ioposix->filenameLength - 1; i >= 0; i -= 1)\n    {\n        if (diskFilename[i] != '.') \n            continue;\n        snprintf(&diskFilename[i], ioposix->filenameLength - i, \".z%02d\", number_disk + 1);\n        break;\n    }\n    if (i >= 0)\n        ret = fopen_file_func(opaque, diskFilename, mode);\n    free(diskFilename);\n    return ret;\n}\n\nstatic uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, uLong size)\n{\n    FILE_IOPOSIX *ioposix = NULL;\n    uLong ret;\n    if (stream == NULL)\n        return -1;\n    ioposix = (FILE_IOPOSIX*)stream;\n    ret = (uLong)fread(buf, 1, (size_t)size, ioposix->file);\n    return ret;\n}\n\nstatic uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const void* buf, uLong size)\n{\n    FILE_IOPOSIX *ioposix = NULL;\n    uLong ret;\n    if (stream == NULL)\n        return -1;\n    ioposix = (FILE_IOPOSIX*)stream;\n    ret = (uLong)fwrite(buf, 1, (size_t)size, ioposix->file);\n    return ret;\n}\n\nstatic long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream)\n{\n    FILE_IOPOSIX *ioposix = NULL;\n    long ret = -1;\n    if (stream == NULL)\n        return ret;\n    ioposix = (FILE_IOPOSIX*)stream;\n    ret = ftell(ioposix->file);\n    return ret;\n}\n\nstatic ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream)\n{\n    FILE_IOPOSIX *ioposix = NULL;\n    ZPOS64_T ret = -1;\n    if (stream == NULL)\n        return ret;\n    ioposix = (FILE_IOPOSIX*)stream;\n    ret = FTELLO_FUNC(ioposix->file);\n    return ret;\n}\n\nstatic long ZCALLBACK fseek_file_func (voidpf opaque, voidpf stream, uLong offset, int origin)\n{\n    FILE_IOPOSIX *ioposix = NULL;\n    int fseek_origin = 0;\n    long ret = 0;\n\n    if (stream == NULL)\n        return -1;\n    ioposix = (FILE_IOPOSIX*)stream;\n\n    switch (origin)\n    {\n        case ZLIB_FILEFUNC_SEEK_CUR:\n            fseek_origin = SEEK_CUR;\n            break;\n        case ZLIB_FILEFUNC_SEEK_END:\n            fseek_origin = SEEK_END;\n            break;\n        case ZLIB_FILEFUNC_SEEK_SET:\n            fseek_origin = SEEK_SET;\n            break;\n        default:\n            return -1;\n    }\n    if (fseek(ioposix->file, offset, fseek_origin) != 0)\n        ret = -1;\n    return ret;\n}\n\nstatic long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)\n{\n    FILE_IOPOSIX *ioposix = NULL;\n    int fseek_origin = 0;\n    long ret = 0;\n\n    if (stream == NULL)\n        return -1;\n    ioposix = (FILE_IOPOSIX*)stream;\n\n    switch (origin)\n    {\n        case ZLIB_FILEFUNC_SEEK_CUR:\n            fseek_origin = SEEK_CUR;\n            break;\n        case ZLIB_FILEFUNC_SEEK_END:\n            fseek_origin = SEEK_END;\n            break;\n        case ZLIB_FILEFUNC_SEEK_SET:\n            fseek_origin = SEEK_SET;\n            break;\n        default:\n            return -1;\n    }\n\n    if(FSEEKO_FUNC(ioposix->file, offset, fseek_origin) != 0)\n        ret = -1;\n\n    return ret;\n}\n\n\nstatic int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream)\n{\n    FILE_IOPOSIX *ioposix = NULL;\n    int ret = -1;\n    if (stream == NULL)\n        return ret;\n    ioposix = (FILE_IOPOSIX*)stream;\n    if (ioposix->filename != NULL)\n        free(ioposix->filename);\n    ret = fclose(ioposix->file);\n    free(ioposix);\n    return ret;\n}\n\nstatic int ZCALLBACK ferror_file_func (voidpf opaque, voidpf stream)\n{\n    FILE_IOPOSIX *ioposix = NULL;\n    int ret = -1;\n    if (stream == NULL)\n        return ret;\n    ioposix = (FILE_IOPOSIX*)stream;\n    ret = ferror(ioposix->file);\n    return ret;\n}\n\nvoid fill_fopen_filefunc (zlib_filefunc_def* pzlib_filefunc_def)\n{\n    pzlib_filefunc_def->zopen_file = fopen_file_func;\n    pzlib_filefunc_def->zopendisk_file = fopendisk_file_func;\n    pzlib_filefunc_def->zread_file = fread_file_func;\n    pzlib_filefunc_def->zwrite_file = fwrite_file_func;\n    pzlib_filefunc_def->ztell_file = ftell_file_func;\n    pzlib_filefunc_def->zseek_file = fseek_file_func;\n    pzlib_filefunc_def->zclose_file = fclose_file_func;\n    pzlib_filefunc_def->zerror_file = ferror_file_func;\n    pzlib_filefunc_def->opaque = NULL;\n}\n\nvoid fill_fopen64_filefunc (zlib_filefunc64_def* pzlib_filefunc_def)\n{\n    pzlib_filefunc_def->zopen64_file = fopen64_file_func;\n    pzlib_filefunc_def->zopendisk64_file = fopendisk64_file_func;\n    pzlib_filefunc_def->zread_file = fread_file_func;\n    pzlib_filefunc_def->zwrite_file = fwrite_file_func;\n    pzlib_filefunc_def->ztell64_file = ftell64_file_func;\n    pzlib_filefunc_def->zseek64_file = fseek64_file_func;\n    pzlib_filefunc_def->zclose_file = fclose_file_func;\n    pzlib_filefunc_def->zerror_file = ferror_file_func;\n    pzlib_filefunc_def->opaque = NULL;\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-zip/src/ios/minizip/ioapi.h",
    "content": "/* ioapi.h -- IO base function header for compress/uncompress .zip\n   part of the MiniZip project\n\n   Copyright (C) 1998-2010 Gilles Vollant\n     http://www.winimage.com/zLibDll/minizip.html\n   Modifications for Zip64 support\n     Copyright (C) 2009-2010 Mathias Svensson\n     http://result42.com\n\n   This program is distributed under the terms of the same license as zlib.\n   See the accompanying LICENSE file for the full text of the license.\n*/\n\n#ifndef _ZLIBIOAPI64_H\n#define _ZLIBIOAPI64_H\n\n#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__))\n#  ifndef __USE_FILE_OFFSET64\n#    define __USE_FILE_OFFSET64\n#  endif\n#  ifndef __USE_LARGEFILE64\n#    define __USE_LARGEFILE64\n#  endif\n#  ifndef _LARGEFILE64_SOURCE\n#    define _LARGEFILE64_SOURCE\n#  endif\n#  ifndef _FILE_OFFSET_BIT\n#    define _FILE_OFFSET_BIT 64\n#  endif\n#endif\n\n#include <stdio.h>\n#include <stdlib.h>\n#include \"zlib.h\"\n\n#if defined(USE_FILE32API)\n#  define fopen64 fopen\n#  define ftello64 ftell\n#  define fseeko64 fseek\n#else\n#  if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__OpenBSD__)\n#    define fopen64 fopen\n#    define ftello64 ftello\n#    define fseeko64 fseeko\n#  endif\n#  ifdef _MSC_VER\n#    define fopen64 fopen\n#    if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC)))\n#      define ftello64 _ftelli64\n#      define fseeko64 _fseeki64\n#    else /* old MSC */\n#      define ftello64 ftell\n#      define fseeko64 fseek\n#    endif\n#  endif\n#endif\n\n/* a type choosen by DEFINE */\n#ifdef HAVE_64BIT_INT_CUSTOM\ntypedef 64BIT_INT_CUSTOM_TYPE ZPOS64_T;\n#else\n#  ifdef HAS_STDINT_H\n#    include \"stdint.h\"\n     typedef uint64_t ZPOS64_T;\n#  else\n#    if defined(_MSC_VER) || defined(__BORLANDC__)\n       typedef unsigned __int64 ZPOS64_T;\n#    else\n       typedef unsigned long long int ZPOS64_T;\n#    endif\n#  endif\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define ZLIB_FILEFUNC_SEEK_CUR (1)\n#define ZLIB_FILEFUNC_SEEK_END (2)\n#define ZLIB_FILEFUNC_SEEK_SET (0)\n\n#define ZLIB_FILEFUNC_MODE_READ             (1)\n#define ZLIB_FILEFUNC_MODE_WRITE            (2)\n#define ZLIB_FILEFUNC_MODE_READWRITEFILTER  (3)\n#define ZLIB_FILEFUNC_MODE_EXISTING         (4)\n#define ZLIB_FILEFUNC_MODE_CREATE           (8)\n\n#ifndef ZCALLBACK\n#  if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || \\\n       defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK)\n#    define ZCALLBACK CALLBACK\n#  else\n#    define ZCALLBACK\n#  endif\n#endif\n\ntypedef voidpf   (ZCALLBACK *open_file_func)      OF((voidpf opaque, const char* filename, int mode));\ntypedef voidpf   (ZCALLBACK *opendisk_file_func)  OF((voidpf opaque, voidpf stream, int number_disk, int mode));\ntypedef uLong    (ZCALLBACK *read_file_func)      OF((voidpf opaque, voidpf stream, void* buf, uLong size));\ntypedef uLong    (ZCALLBACK *write_file_func)     OF((voidpf opaque, voidpf stream, const void* buf, uLong size));\ntypedef int      (ZCALLBACK *close_file_func)     OF((voidpf opaque, voidpf stream));\ntypedef int      (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream));\n\ntypedef long     (ZCALLBACK *tell_file_func)      OF((voidpf opaque, voidpf stream));\ntypedef long     (ZCALLBACK *seek_file_func)      OF((voidpf opaque, voidpf stream, uLong offset, int origin));\n\n/* here is the \"old\" 32 bits structure structure */\ntypedef struct zlib_filefunc_def_s\n{\n    open_file_func      zopen_file;\n    opendisk_file_func  zopendisk_file;\n    read_file_func      zread_file;\n    write_file_func     zwrite_file;\n    tell_file_func      ztell_file;\n    seek_file_func      zseek_file;\n    close_file_func     zclose_file;\n    testerror_file_func zerror_file;\n    voidpf              opaque;\n} zlib_filefunc_def;\n\ntypedef ZPOS64_T (ZCALLBACK *tell64_file_func)    OF((voidpf opaque, voidpf stream));\ntypedef long     (ZCALLBACK *seek64_file_func)    OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));\ntypedef voidpf   (ZCALLBACK *open64_file_func)    OF((voidpf opaque, const void* filename, int mode));\ntypedef voidpf   (ZCALLBACK *opendisk64_file_func)OF((voidpf opaque, voidpf stream, int number_disk, int mode));\n\ntypedef struct zlib_filefunc64_def_s\n{\n    open64_file_func     zopen64_file;\n    opendisk64_file_func zopendisk64_file;\n    read_file_func       zread_file;\n    write_file_func      zwrite_file;\n    tell64_file_func     ztell64_file;\n    seek64_file_func     zseek64_file;\n    close_file_func      zclose_file;\n    testerror_file_func  zerror_file;\n    voidpf               opaque;\n} zlib_filefunc64_def;\n\nvoid fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));\nvoid fill_fopen64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def));\n\n/* now internal definition, only for zip.c and unzip.h */\ntypedef struct zlib_filefunc64_32_def_s\n{\n    zlib_filefunc64_def zfile_func64;\n    open_file_func      zopen32_file;\n    opendisk_file_func  zopendisk32_file;\n    tell_file_func      ztell32_file;\n    seek_file_func      zseek32_file;\n} zlib_filefunc64_32_def;\n\n#define ZREAD64(filefunc,filestream,buf,size)       ((*((filefunc).zfile_func64.zread_file))        ((filefunc).zfile_func64.opaque,filestream,buf,size))\n#define ZWRITE64(filefunc,filestream,buf,size)      ((*((filefunc).zfile_func64.zwrite_file))       ((filefunc).zfile_func64.opaque,filestream,buf,size))\n/*#define ZTELL64(filefunc,filestream)                ((*((filefunc).ztell64_file))                   ((filefunc).opaque,filestream))*/\n/*#define ZSEEK64(filefunc,filestream,pos,mode)       ((*((filefunc).zseek64_file))                   ((filefunc).opaque,filestream,pos,mode))*/\n#define ZCLOSE64(filefunc,filestream)               ((*((filefunc).zfile_func64.zclose_file))       ((filefunc).zfile_func64.opaque,filestream))\n#define ZERROR64(filefunc,filestream)               ((*((filefunc).zfile_func64.zerror_file))       ((filefunc).zfile_func64.opaque,filestream))\n\nvoidpf   call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode));\nvoidpf   call_zopendisk64 OF((const zlib_filefunc64_32_def* pfilefunc, voidpf filestream, int number_disk, int mode));\nlong     call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin));\nZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream));\n\nvoid fill_zlib_filefunc64_32_def_from_filefunc32 OF((zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32));\n\n#define ZOPEN64(filefunc,filename,mode)             (call_zopen64((&(filefunc)),(filename),(mode)))\n#define ZOPENDISK64(filefunc,filestream,diskn,mode) (call_zopendisk64((&(filefunc)),(filestream),(diskn),(mode)))\n#define ZTELL64(filefunc,filestream)                (call_ztell64((&(filefunc)),(filestream)))\n#define ZSEEK64(filefunc,filestream,pos,mode)       (call_zseek64((&(filefunc)),(filestream),(pos),(mode)))\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "plugins/cordova-plugin-zip/src/ios/minizip/mztools.c",
    "content": "/*\n  Additional tools for Minizip\n  Code: Xavier Roche '2004\n  License: Same as ZLIB (www.gzip.org)\n*/\n\n/* Code */\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include \"zlib.h\"\n#include \"unzip.h\"\n#include \"mztools.h\"\n\n#define READ_8(adr)  ((unsigned char)*(adr))\n#define READ_16(adr) ( READ_8(adr) | (READ_8(adr+1) << 8) )\n#define READ_32(adr) ( READ_16(adr) | (READ_16((adr)+2) << 16) )\n\n#define WRITE_8(buff, n) do { \\\n  *((unsigned char*)(buff)) = (unsigned char) ((n) & 0xff); \\\n} while(0)\n#define WRITE_16(buff, n) do { \\\n  WRITE_8((unsigned char*)(buff), n); \\\n  WRITE_8(((unsigned char*)(buff)) + 1, (n) >> 8); \\\n} while(0)\n#define WRITE_32(buff, n) do { \\\n  WRITE_16((unsigned char*)(buff), (n) & 0xffff); \\\n  WRITE_16((unsigned char*)(buff) + 2, (n) >> 16); \\\n} while(0)\n\nextern int ZEXPORT unzRepair(file, fileOut, fileOutTmp, nRecovered, bytesRecovered)\nconst char* file;\nconst char* fileOut;\nconst char* fileOutTmp;\nuLong* nRecovered;\nuLong* bytesRecovered;\n{\n  int err = Z_OK;\n  FILE* fpZip = fopen(file, \"rb\");\n  FILE* fpOut = fopen(fileOut, \"wb\");\n  FILE* fpOutCD = fopen(fileOutTmp, \"wb\");\n  if (fpZip != NULL &&  fpOut != NULL) {\n    int entries = 0;\n    uLong totalBytes = 0;\n    char header[30];\n    char filename[256];\n    char extra[1024];\n    int offset = 0;\n    int offsetCD = 0;\n    while ( fread(header, 1, 30, fpZip) == 30 ) {\n      int currentOffset = offset;\n\n      /* File entry */\n      if (READ_32(header) == 0x04034b50) {\n        unsigned int version = READ_16(header + 4);\n        unsigned int gpflag = READ_16(header + 6);\n        unsigned int method = READ_16(header + 8);\n        unsigned int filetime = READ_16(header + 10);\n        unsigned int filedate = READ_16(header + 12);\n        unsigned int crc = READ_32(header + 14); /* crc */\n        unsigned int cpsize = READ_32(header + 18); /* compressed size */\n        unsigned int uncpsize = READ_32(header + 22); /* uncompressed sz */\n        unsigned int fnsize = READ_16(header + 26); /* file name length */\n        unsigned int extsize = READ_16(header + 28); /* extra field length */\n        filename[0] = extra[0] = '\\0';\n        \n        /* Header */\n        if (fwrite(header, 1, 30, fpOut) == 30) {\n          offset += 30;\n        } else {\n          err = Z_ERRNO;\n          break;\n        }\n        \n        /* Filename */\n        if (fnsize > 0) {\n          if (fread(filename, 1, fnsize, fpZip) == fnsize) {\n            if (fwrite(filename, 1, fnsize, fpOut) == fnsize) {\n              offset += fnsize;\n            } else {\n              err = Z_ERRNO;\n              break;\n            }\n          } else {\n            err = Z_ERRNO;\n            break;\n          }\n        } else {\n          err = Z_STREAM_ERROR;\n          break;\n        }\n\n        /* Extra field */\n        if (extsize > 0) {\n          if (fread(extra, 1, extsize, fpZip) == extsize) {\n            if (fwrite(extra, 1, extsize, fpOut) == extsize) {\n              offset += extsize;\n            } else {\n              err = Z_ERRNO;\n              break;\n            }\n          } else {\n            err = Z_ERRNO;\n            break;\n          }\n        }\n        \n        /* Data */\n        {\n          int dataSize = cpsize;\n          if (dataSize == 0) {\n            dataSize = uncpsize;\n          }\n          if (dataSize > 0) {\n            char* data = malloc(dataSize);\n            if (data != NULL) {\n              if ((int)fread(data, 1, dataSize, fpZip) == dataSize) {\n                if ((int)fwrite(data, 1, dataSize, fpOut) == dataSize) {\n                  offset += dataSize;\n                  totalBytes += dataSize;\n                } else {\n                  err = Z_ERRNO;\n                }\n              } else {\n                err = Z_ERRNO;\n              }\n              free(data);\n              if (err != Z_OK) {\n                break;\n              }\n            } else {\n              err = Z_MEM_ERROR;\n              break;\n            }\n          }\n        }\n        \n        /* Central directory entry */\n        {\n          char centralDirectoryEntryHeader[46];\n          //char* comment = \"\";\n          //int comsize = (int) strlen(comment);\n          WRITE_32(centralDirectoryEntryHeader, 0x02014b50);\n          WRITE_16(centralDirectoryEntryHeader + 4, version);\n          WRITE_16(centralDirectoryEntryHeader + 6, version);\n          WRITE_16(centralDirectoryEntryHeader + 8, gpflag);\n          WRITE_16(centralDirectoryEntryHeader + 10, method);\n          WRITE_16(centralDirectoryEntryHeader + 12, filetime);\n          WRITE_16(centralDirectoryEntryHeader + 14, filedate);\n          WRITE_32(centralDirectoryEntryHeader + 16, crc);\n          WRITE_32(centralDirectoryEntryHeader + 20, cpsize);\n          WRITE_32(centralDirectoryEntryHeader + 24, uncpsize);\n          WRITE_16(centralDirectoryEntryHeader + 28, fnsize);\n          WRITE_16(centralDirectoryEntryHeader + 30, extsize);\n          WRITE_16(centralDirectoryEntryHeader + 32, 0 /*comsize*/);\n          WRITE_16(centralDirectoryEntryHeader + 34, 0);     /* disk # */\n          WRITE_16(centralDirectoryEntryHeader + 36, 0);     /* int attrb */\n          WRITE_32(centralDirectoryEntryHeader + 38, 0);     /* ext attrb */\n          WRITE_32(centralDirectoryEntryHeader + 42, currentOffset);\n          /* Header */\n          if (fwrite(centralDirectoryEntryHeader, 1, 46, fpOutCD) == 46) {\n            offsetCD += 46;\n            \n            /* Filename */\n            if (fnsize > 0) {\n              if (fwrite(filename, 1, fnsize, fpOutCD) == fnsize) {\n                offsetCD += fnsize;\n              } else {\n                err = Z_ERRNO;\n                break;\n              }\n            } else {\n              err = Z_STREAM_ERROR;\n              break;\n            }\n            \n            /* Extra field */\n            if (extsize > 0) {\n              if (fwrite(extra, 1, extsize, fpOutCD) == extsize) {\n                offsetCD += extsize;\n              } else {\n                err = Z_ERRNO;\n                break;\n              }\n            }\n            \n            /* Comment field */\n            /*\n            if (comsize > 0) {\n              if ((int)fwrite(comment, 1, comsize, fpOutCD) == comsize) {\n                offsetCD += comsize;\n              } else {\n                err = Z_ERRNO;\n                break;\n              }\n            }\n            */\n            \n          } else {\n            err = Z_ERRNO;\n            break;\n          }\n        }\n\n        /* Success */\n        entries++;\n\n      } else {\n        break;\n      }\n    }\n\n    /* Final central directory  */\n    {\n      int entriesZip = entries;\n      char finalCentralDirectoryHeader[22];\n      //char* comment = \"\"; // \"ZIP File recovered by zlib/minizip/mztools\";\n      //int comsize = (int) strlen(comment);\n      if (entriesZip > 0xffff) {\n        entriesZip = 0xffff;\n      }\n      WRITE_32(finalCentralDirectoryHeader, 0x06054b50);\n      WRITE_16(finalCentralDirectoryHeader + 4, 0);    /* disk # */\n      WRITE_16(finalCentralDirectoryHeader + 6, 0);    /* disk # */\n      WRITE_16(finalCentralDirectoryHeader + 8, entriesZip);   /* hack */\n      WRITE_16(finalCentralDirectoryHeader + 10, entriesZip);  /* hack */\n      WRITE_32(finalCentralDirectoryHeader + 12, offsetCD);    /* size of CD */\n      WRITE_32(finalCentralDirectoryHeader + 16, offset);      /* offset to CD */\n      WRITE_16(finalCentralDirectoryHeader + 20, 0 /*comsize*/);     /* comment */\n      \n      /* Header */\n      if (fwrite(finalCentralDirectoryHeader, 1, 22, fpOutCD) == 22) {\n        \n        /* Comment field */\n        /*\n        if (comsize > 0) {\n          if ((int)fwrite(comment, 1, comsize, fpOutCD) != comsize) {\n            err = Z_ERRNO;\n          }\n        }\n        */\n      } else {\n        err = Z_ERRNO;\n      }\n    }\n\n    /* Final merge (file + central directory) */\n    fclose(fpOutCD);\n    if (err == Z_OK) {\n      fpOutCD = fopen(fileOutTmp, \"rb\");\n      if (fpOutCD != NULL) {\n        int nRead;\n        char buffer[8192];\n        while ( (nRead = (int)fread(buffer, 1, sizeof(buffer), fpOutCD)) > 0) {\n          if ((int)fwrite(buffer, 1, nRead, fpOut) != nRead) {\n            err = Z_ERRNO;\n            break;\n          }\n        }\n        fclose(fpOutCD);\n      }\n    }\n    \n    /* Close */\n    fclose(fpZip);\n    fclose(fpOut);\n    \n    /* Wipe temporary file */\n    (void)remove(fileOutTmp);\n    \n    /* Number of recovered entries */\n    if (err == Z_OK) {\n      if (nRecovered != NULL) {\n        *nRecovered = entries;\n      }\n      if (bytesRecovered != NULL) {\n        *bytesRecovered = totalBytes;\n      }\n    }\n  } else {\n    err = Z_STREAM_ERROR;\n  }\n  return err;\n}\n"
  },
  {
    "path": "plugins/cordova-plugin-zip/src/ios/minizip/mztools.h",
    "content": "/*\n  Additional tools for Minizip\n  Code: Xavier Roche '2004\n  License: Same as ZLIB (www.gzip.org)\n*/\n\n#ifndef _zip_tools_H\n#define _zip_tools_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#ifndef _ZLIB_H\n#include \"zlib.h\"\n#endif\n\n#include \"unzip.h\"\n\n/* Repair a ZIP file (missing central directory)\n   file: file to recover\n   fileOut: output file after recovery\n   fileOutTmp: temporary file name used for recovery\n*/\nextern int ZEXPORT unzRepair(const char* file,\n                             const char* fileOut,\n                             const char* fileOutTmp,\n                             uLong* nRecovered,\n                             uLong* bytesRecovered);\n\n#endif\n"
  },
  {
    "path": "plugins/cordova-plugin-zip/src/ios/minizip/unzip.c",
    "content": "/* unzip.c -- IO for uncompress .zip files using zlib\n   Version 1.1, February 14h, 2010\n   part of the MiniZip project\n\n   Copyright (C) 1998-2010 Gilles Vollant\n     http://www.winimage.com/zLibDll/minizip.html\n   Modifications of Unzip for Zip64\n     Copyright (C) 2007-2008 Even Rouault\n   Modifications for Zip64 support on both zip and unzip\n     Copyright (C) 2009-2010 Mathias Svensson\n     http://result42.com\n   Modifications for AES, PKWARE disk spanning\n     Copyright (C) 2010-2014 Nathan Moinvaziri\n\n   This program is distributed under the terms of the same license as zlib.\n   See the accompanying LICENSE file for the full text of the license.\n */\n\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n/*#ifndef NOUNCRYPT\n #  define NOUNCRYPT\n #endif*/\n\n#include \"zlib.h\"\n#include \"unzip.h\"\n\n#include \"Common.h\"\n\n#ifdef STDC\n#  include <stddef.h>\n#  include <string.h>\n#  include <stdlib.h>\n#endif\n#ifdef NO_ERRNO_H\nextern int errno;\n#else\n#  include <errno.h>\n#endif\n\n#ifdef HAVE_AES\n#  define AES_METHOD          (99)\n#  define AES_PWVERIFYSIZE    (2)\n#  define AES_MAXSALTLENGTH   (16)\n#  define AES_AUTHCODESIZE    (10)\n#  define AES_HEADERSIZE      (11)\n#  define AES_KEYSIZE(mode)   (64 + (mode * 64))\n\n#  include \"aes.h\"\n#  include \"fileenc.h\"\n#endif\n#ifndef NOUNCRYPT\n#  include \"crypt.h\"\n#endif\n\n#ifndef local\n#  define local static\n#endif\n/* compile with -Dlocal if your debugger can't find static symbols */\n\n#define DISKHEADERMAGIC          (0x08074b50)\n#define LOCALHEADERMAGIC         (0x04034b50)\n#define CENTRALHEADERMAGIC       (0x02014b50)\n#define ENDHEADERMAGIC           (0x06054b50)\n#define ZIP64ENDHEADERMAGIC      (0x06064b50)\n#define ZIP64ENDLOCHEADERMAGIC   (0x07064b50)\n\n#define SIZECENTRALDIRITEM       (0x2e)\n#define SIZECENTRALHEADERLOCATOR (0x14) /* 20 */\n#define SIZEZIPLOCALHEADER       (0x1e)\n\n#ifndef BUFREADCOMMENT\n#  define BUFREADCOMMENT (0x400)\n#endif\n\n#ifndef UNZ_BUFSIZE\n#  define UNZ_BUFSIZE (64 * 1024)\n#endif\n#ifndef UNZ_MAXFILENAMEINZIP\n#  define UNZ_MAXFILENAMEINZIP (256)\n#endif\n\n#ifndef ALLOC\n#  define ALLOC(size) (malloc(size))\n#endif\n#ifndef TRYFREE\n#  define TRYFREE(p) {if (p) free(p); }\n#endif\n\nconst char unz_copyright[] =\n    \" unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll\";\n\n/* unz_file_info_interntal contain internal info about a file in zipfile*/\ntypedef struct unz_file_info64_internal_s {\n    ZPOS64_T offset_curfile;            /* relative offset of local header 8 bytes */\n    ZPOS64_T byte_before_the_zipfile;   /* byte before the zipfile, (>0 for sfx) */\n#ifdef HAVE_AES\n    uLong aes_encryption_mode;\n    uLong aes_compression_method;\n    uLong aes_version;\n#endif\n} unz_file_info64_internal;\n\n/* file_in_zip_read_info_s contain internal information about a file in zipfile */\ntypedef struct {\n    Bytef *read_buffer;                 /* internal buffer for compressed data */\n    z_stream stream;                    /* zLib stream structure for inflate */\n\n#ifdef HAVE_BZIP2\n    bz_stream bstream;                  /* bzLib stream structure for bziped */\n#endif\n#ifdef HAVE_AES\n    fcrypt_ctx aes_ctx;\n#endif\n\n    ZPOS64_T pos_in_zipfile;            /* position in byte on the zipfile, for fseek */\n    uLong stream_initialised;           /* flag set if stream structure is initialised */\n\n    ZPOS64_T offset_local_extrafield;   /* offset of the local extra field */\n    uInt size_local_extrafield;         /* size of the local extra field */\n    ZPOS64_T pos_local_extrafield;      /* position in the local extra field in read */\n    ZPOS64_T total_out_64;\n\n    uLong crc32;                        /* crc32 of all data uncompressed */\n    uLong crc32_wait;                   /* crc32 we must obtain after decompress all */\n    ZPOS64_T rest_read_compressed;      /* number of byte to be decompressed */\n    ZPOS64_T rest_read_uncompressed;    /* number of byte to be obtained after decomp */\n\n    zlib_filefunc64_32_def z_filefunc;\n\n    voidpf filestream;                  /* io structore of the zipfile */\n    uLong compression_method;           /* compression method (0==store) */\n    ZPOS64_T byte_before_the_zipfile;   /* byte before the zipfile, (>0 for sfx) */\n    int raw;\n} file_in_zip64_read_info_s;\n\n/* unz64_s contain internal information about the zipfile */\ntypedef struct {\n    zlib_filefunc64_32_def z_filefunc;\n    voidpf filestream;                  /* io structure of the current zipfile */\n    voidpf filestream_with_CD;          /* io structure of the disk with the central directory */\n    unz_global_info64 gi;               /* public global information */\n    ZPOS64_T byte_before_the_zipfile;   /* byte before the zipfile, (>0 for sfx)*/\n    ZPOS64_T num_file;                  /* number of the current file in the zipfile*/\n    ZPOS64_T pos_in_central_dir;        /* pos of the current file in the central dir*/\n    ZPOS64_T current_file_ok;           /* flag about the usability of the current file*/\n    ZPOS64_T central_pos;               /* position of the beginning of the central dir*/\n    uLong number_disk;                  /* number of the current disk, used for spanning ZIP*/\n    ZPOS64_T size_central_dir;          /* size of the central directory  */\n    ZPOS64_T offset_central_dir;        /* offset of start of central directory with\n                                           respect to the starting disk number */\n\n    unz_file_info64 cur_file_info;      /* public info about the current file in zip*/\n    unz_file_info64_internal cur_file_info_internal;\n    /* private info about it*/\n    file_in_zip64_read_info_s *pfile_in_zip_read;\n    /* structure about the current file if we are decompressing it */\n    int isZip64;                        /* is the current file zip64 */\n#ifndef NOUNCRYPT\n    unsigned long keys[3];              /* keys defining the pseudo-random sequence */\n    const unsigned long *pcrc_32_tab;\n#endif\n} unz64_s;\n\n/* Translate date/time from Dos format to tm_unz (readable more easily) */\nlocal void unz64local_DosDateToTmuDate(ZPOS64_T ulDosDate, tm_unz *ptm)\n{\n    ZPOS64_T uDate = (ZPOS64_T)(ulDosDate >> 16);\n\n    ptm->tm_mday = (uInt)(uDate & 0x1f);\n    ptm->tm_mon = (uInt)((((uDate) & 0x1E0) / 0x20) - 1);\n    ptm->tm_year = (uInt)(((uDate & 0x0FE00) / 0x0200) + 1980);\n    ptm->tm_hour = (uInt)((ulDosDate & 0xF800) / 0x800);\n    ptm->tm_min = (uInt)((ulDosDate & 0x7E0) / 0x20);\n    ptm->tm_sec = (uInt)(2 * (ulDosDate & 0x1f));\n\n#define unz64local_in_range(min, max, value) ((min) <= (value) && (value) <= (max))\n    if (!unz64local_in_range(0, 11, ptm->tm_mon) ||\n        !unz64local_in_range(1, 31, ptm->tm_mday) ||\n        !unz64local_in_range(0, 23, ptm->tm_hour) ||\n        !unz64local_in_range(0, 59, ptm->tm_min) ||\n        !unz64local_in_range(0, 59, ptm->tm_sec))\n        /* Invalid date stored, so don't return it. */\n        memset(ptm, 0, sizeof(tm_unz));\n#undef unz64local_in_range\n}\n\n/* Read a byte from a gz_stream; Return EOF for end of file. */\nlocal int unz64local_getByte(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream, int *pi)\n{\n    unsigned char c;\n    int err = (int)ZREAD64(*pzlib_filefunc_def, filestream, &c, 1);\n    if (err == 1) {\n        *pi = (int)c;\n        return UNZ_OK;\n    }\n    if (ZERROR64(*pzlib_filefunc_def, filestream))\n        return UNZ_ERRNO;\n    return UNZ_EOF;\n}\n\nlocal int unz64local_getShort OF((const zlib_filefunc64_32_def * pzlib_filefunc_def, voidpf filestream, uLong * pX));\nlocal int unz64local_getShort(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream, uLong *pX)\n{\n    uLong x;\n    int i = 0;\n    int err;\n\n    err = unz64local_getByte(pzlib_filefunc_def, filestream, &i);\n    x = (uLong)i;\n    if (err == UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def, filestream, &i);\n    x |= ((uLong)i) << 8;\n\n    if (err == UNZ_OK)\n        *pX = x;\n    else\n        *pX = 0;\n    return err;\n}\n\nlocal int unz64local_getLong OF((const zlib_filefunc64_32_def * pzlib_filefunc_def, voidpf filestream, uLong * pX));\nlocal int unz64local_getLong(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream, uLong *pX)\n{\n    uLong x;\n    int i = 0;\n    int err;\n\n    err = unz64local_getByte(pzlib_filefunc_def, filestream, &i);\n    x = (uLong)i;\n    if (err == UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def, filestream, &i);\n    x |= ((uLong)i) << 8;\n    if (err == UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def, filestream, &i);\n    x |= ((uLong)i) << 16;\n    if (err == UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def, filestream, &i);\n    x += ((uLong)i) << 24;\n\n    if (err == UNZ_OK)\n        *pX = x;\n    else\n        *pX = 0;\n    return err;\n}\n\nlocal int unz64local_getLong64 OF((const zlib_filefunc64_32_def * pzlib_filefunc_def, voidpf filestream, ZPOS64_T * pX));\nlocal int unz64local_getLong64(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)\n{\n    ZPOS64_T x;\n    int i = 0;\n    int err;\n\n    err = unz64local_getByte(pzlib_filefunc_def, filestream, &i);\n    x = (ZPOS64_T)i;\n    if (err == UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def, filestream, &i);\n    x |= ((ZPOS64_T)i) << 8;\n    if (err == UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def, filestream, &i);\n    x |= ((ZPOS64_T)i) << 16;\n    if (err == UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def, filestream, &i);\n    x |= ((ZPOS64_T)i) << 24;\n    if (err == UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def, filestream, &i);\n    x |= ((ZPOS64_T)i) << 32;\n    if (err == UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def, filestream, &i);\n    x |= ((ZPOS64_T)i) << 40;\n    if (err == UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def, filestream, &i);\n    x |= ((ZPOS64_T)i) << 48;\n    if (err == UNZ_OK)\n        err = unz64local_getByte(pzlib_filefunc_def, filestream, &i);\n    x |= ((ZPOS64_T)i) << 56;\n\n    if (err == UNZ_OK)\n        *pX = x;\n    else\n        *pX = 0;\n    return err;\n}\n\n/* Locate the Central directory of a zip file (at the end, just before the global comment) */\nlocal ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def * pzlib_filefunc_def, voidpf filestream));\nlocal ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream)\n{\n    unsigned char *buf;\n    ZPOS64_T file_size;\n    ZPOS64_T back_read = 4;\n    ZPOS64_T max_back = 0xffff; /* maximum size of global comment */\n    ZPOS64_T pos_found = 0;\n    uLong read_size;\n    ZPOS64_T read_pos;\n    int i;\n\n    buf = (unsigned char *)ALLOC(BUFREADCOMMENT + 4);\n    if (buf == NULL)\n        return 0;\n\n    if (ZSEEK64(*pzlib_filefunc_def, filestream, 0, ZLIB_FILEFUNC_SEEK_END) != 0) {\n        TRYFREE(buf);\n        return 0;\n    }\n\n    file_size = ZTELL64(*pzlib_filefunc_def, filestream);\n\n    if (max_back > file_size)\n        max_back = file_size;\n\n    while (back_read < max_back) {\n        if (back_read + BUFREADCOMMENT > max_back)\n            back_read = max_back;\n        else\n            back_read += BUFREADCOMMENT;\n\n        read_pos = file_size - back_read;\n        read_size = ((BUFREADCOMMENT + 4) < (file_size - read_pos)) ?\n                    (BUFREADCOMMENT + 4) : (uLong)(file_size - read_pos);\n\n        if (ZSEEK64(*pzlib_filefunc_def, filestream, read_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)\n            break;\n        if (ZREAD64(*pzlib_filefunc_def, filestream, buf, read_size) != read_size)\n            break;\n\n        for (i = (int)read_size - 3; (i--) > 0; )\n            if (((*(buf + i)) == (ENDHEADERMAGIC & 0xff)) &&\n                ((*(buf + i + 1)) == (ENDHEADERMAGIC >> 8 & 0xff)) &&\n                ((*(buf + i + 2)) == (ENDHEADERMAGIC >> 16 & 0xff)) &&\n                ((*(buf + i + 3)) == (ENDHEADERMAGIC >> 24 & 0xff))) {\n                pos_found = read_pos + i;\n                break;\n            }\n\n        if (pos_found != 0)\n            break;\n    }\n    TRYFREE(buf);\n    return pos_found;\n}\n\n/* Locate the Central directory 64 of a zipfile (at the end, just before the global comment) */\nlocal ZPOS64_T unz64local_SearchCentralDir64 OF((const zlib_filefunc64_32_def * pzlib_filefunc_def, voidpf filestream,\n                                                 const ZPOS64_T endcentraloffset));\nlocal ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream,\n                                             const ZPOS64_T endcentraloffset)\n{\n    ZPOS64_T offset;\n    uLong uL;\n\n    /* Zip64 end of central directory locator */\n    if (ZSEEK64(*pzlib_filefunc_def, filestream, endcentraloffset - SIZECENTRALHEADERLOCATOR, ZLIB_FILEFUNC_SEEK_SET) != 0)\n        return 0;\n\n    /* read locator signature */\n    if (unz64local_getLong(pzlib_filefunc_def, filestream, &uL) != UNZ_OK)\n        return 0;\n    if (uL != ZIP64ENDLOCHEADERMAGIC)\n        return 0;\n    /* number of the disk with the start of the zip64 end of  central directory */\n    if (unz64local_getLong(pzlib_filefunc_def, filestream, &uL) != UNZ_OK)\n        return 0;\n    /* relative offset of the zip64 end of central directory record */\n    if (unz64local_getLong64(pzlib_filefunc_def, filestream, &offset) != UNZ_OK)\n        return 0;\n    /* total number of disks */\n    if (unz64local_getLong(pzlib_filefunc_def, filestream, &uL) != UNZ_OK)\n        return 0;\n    /* Goto end of central directory record */\n    if (ZSEEK64(*pzlib_filefunc_def, filestream, offset, ZLIB_FILEFUNC_SEEK_SET) != 0)\n        return 0;\n    /* the signature */\n    if (unz64local_getLong(pzlib_filefunc_def, filestream, &uL) != UNZ_OK)\n        return 0;\n    if (uL != ZIP64ENDHEADERMAGIC)\n        return 0;\n\n    return offset;\n}\n\nlocal unzFile unzOpenInternal(const void *path, zlib_filefunc64_32_def *pzlib_filefunc64_32_def)\n{\n    unz64_s us;\n    unz64_s *s;\n    ZPOS64_T central_pos;\n    uLong uL;\n    voidpf filestream = NULL;\n    ZPOS64_T number_entry_CD;\n    int err = UNZ_OK;\n\n    if (unz_copyright[0] != ' ')\n        return NULL;\n\n    us.filestream = NULL;\n    us.filestream_with_CD = NULL;\n    us.z_filefunc.zseek32_file = NULL;\n    us.z_filefunc.ztell32_file = NULL;\n    if (pzlib_filefunc64_32_def == NULL)\n        fill_fopen64_filefunc(&us.z_filefunc.zfile_func64);\n    else\n        us.z_filefunc = *pzlib_filefunc64_32_def;\n\n    us.filestream = ZOPEN64(us.z_filefunc, path, ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_EXISTING);\n\n    if (us.filestream == NULL)\n        return NULL;\n\n    us.filestream_with_CD = us.filestream;\n    us.isZip64 = 0;\n\n    /* Use unz64local_SearchCentralDir first. Only based on the result\n       is it necessary to locate the unz64local_SearchCentralDir64 */\n    central_pos = unz64local_SearchCentralDir(&us.z_filefunc, us.filestream);\n    if (central_pos) {\n        if (ZSEEK64(us.z_filefunc, us.filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)\n            err = UNZ_ERRNO;\n\n        /* the signature, already checked */\n        if (unz64local_getLong(&us.z_filefunc, us.filestream, &uL) != UNZ_OK)\n            err = UNZ_ERRNO;\n        /* number of this disk */\n        if (unz64local_getShort(&us.z_filefunc, us.filestream, &uL) != UNZ_OK)\n            err = UNZ_ERRNO;\n        us.number_disk = uL;\n        /* number of the disk with the start of the central directory */\n        if (unz64local_getShort(&us.z_filefunc, us.filestream, &uL) != UNZ_OK)\n            err = UNZ_ERRNO;\n        us.gi.number_disk_with_CD = uL;\n        /* total number of entries in the central directory on this disk */\n        if (unz64local_getShort(&us.z_filefunc, us.filestream, &uL) != UNZ_OK)\n            err = UNZ_ERRNO;\n        us.gi.number_entry = uL;\n        /* total number of entries in the central directory */\n        if (unz64local_getShort(&us.z_filefunc, us.filestream, &uL) != UNZ_OK)\n            err = UNZ_ERRNO;\n        number_entry_CD = uL;\n        if (number_entry_CD != us.gi.number_entry)\n            err = UNZ_BADZIPFILE;\n        /* size of the central directory */\n        if (unz64local_getLong(&us.z_filefunc, us.filestream, &uL) != UNZ_OK)\n            err = UNZ_ERRNO;\n        us.size_central_dir = uL;\n        /* offset of start of central directory with respect to the starting disk number */\n        if (unz64local_getLong(&us.z_filefunc, us.filestream, &uL) != UNZ_OK)\n            err = UNZ_ERRNO;\n        us.offset_central_dir = uL;\n        /* zipfile comment length */\n        if (unz64local_getShort(&us.z_filefunc, us.filestream, &us.gi.size_comment) != UNZ_OK)\n            err = UNZ_ERRNO;\n\n        if ((err == UNZ_OK) &&\n            ((us.gi.number_entry == 0xffff) || (us.size_central_dir == 0xffff) || (us.offset_central_dir == 0xffffffff))) {\n            /* Format should be Zip64, as the central directory or file size is too large */\n            central_pos = unz64local_SearchCentralDir64(&us.z_filefunc, us.filestream, central_pos);\n            if (central_pos) {\n                ZPOS64_T uL64;\n\n                us.isZip64 = 1;\n\n                if (ZSEEK64(us.z_filefunc, us.filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)\n                    err = UNZ_ERRNO;\n\n                /* the signature, already checked */\n                if (unz64local_getLong(&us.z_filefunc, us.filestream, &uL) != UNZ_OK)\n                    err = UNZ_ERRNO;\n                /* size of zip64 end of central directory record */\n                if (unz64local_getLong64(&us.z_filefunc, us.filestream, &uL64) != UNZ_OK)\n                    err = UNZ_ERRNO;\n                /* version made by */\n                if (unz64local_getShort(&us.z_filefunc, us.filestream, &uL) != UNZ_OK)\n                    err = UNZ_ERRNO;\n                /* version needed to extract */\n                if (unz64local_getShort(&us.z_filefunc, us.filestream, &uL) != UNZ_OK)\n                    err = UNZ_ERRNO;\n                /* number of this disk */\n                if (unz64local_getLong(&us.z_filefunc, us.filestream, &us.number_disk) != UNZ_OK)\n                    err = UNZ_ERRNO;\n                /* number of the disk with the start of the central directory */\n                if (unz64local_getLong(&us.z_filefunc, us.filestream, &us.gi.number_disk_with_CD) != UNZ_OK)\n                    err = UNZ_ERRNO;\n                /* total number of entries in the central directory on this disk */\n                if (unz64local_getLong64(&us.z_filefunc, us.filestream, &us.gi.number_entry) != UNZ_OK)\n                    err = UNZ_ERRNO;\n                /* total number of entries in the central directory */\n                if (unz64local_getLong64(&us.z_filefunc, us.filestream, &number_entry_CD) != UNZ_OK)\n                    err = UNZ_ERRNO;\n                if (number_entry_CD != us.gi.number_entry)\n                    err = UNZ_BADZIPFILE;\n                /* size of the central directory */\n                if (unz64local_getLong64(&us.z_filefunc, us.filestream, &us.size_central_dir) != UNZ_OK)\n                    err = UNZ_ERRNO;\n                /* offset of start of central directory with respect to the starting disk number */\n                if (unz64local_getLong64(&us.z_filefunc, us.filestream, &us.offset_central_dir) != UNZ_OK)\n                    err = UNZ_ERRNO;\n            } else\n                err = UNZ_BADZIPFILE;\n        }\n    } else\n        err = UNZ_ERRNO;\n\n    if ((err == UNZ_OK) && (central_pos < us.offset_central_dir + us.size_central_dir))\n        err = UNZ_BADZIPFILE;\n\n    if (err != UNZ_OK) {\n        ZCLOSE64(us.z_filefunc, us.filestream);\n        return NULL;\n    }\n\n    if (us.gi.number_disk_with_CD == 0) {\n        /* If there is only one disk open another stream so we don't have to seek between the CD\n           and the file headers constantly */\n        filestream = ZOPEN64(us.z_filefunc, path, ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_EXISTING);\n        if (filestream != NULL)\n            us.filestream = filestream;\n    }\n\n    /* Hack for zip files that have no respect for zip64\n       if ((central_pos > 0xffffffff) && (us.offset_central_dir < 0xffffffff))\n        us.offset_central_dir = central_pos - us.size_central_dir;*/\n\n    us.byte_before_the_zipfile = central_pos - (us.offset_central_dir + us.size_central_dir);\n    us.central_pos = central_pos;\n    us.pfile_in_zip_read = NULL;\n\n    s = (unz64_s *)ALLOC(sizeof(unz64_s));\n    if (s != NULL) {\n        *s = us;\n        unzGoToFirstFile((unzFile)s);\n    }\n    return (unzFile)s;\n}\n\nextern unzFile ZEXPORT unzOpen2(const char *path, zlib_filefunc_def *pzlib_filefunc32_def)\n{\n    if (pzlib_filefunc32_def != NULL) {\n        zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;\n        fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill, pzlib_filefunc32_def);\n        return unzOpenInternal(path, &zlib_filefunc64_32_def_fill);\n    }\n    return unzOpenInternal(path, NULL);\n}\n\nextern unzFile ZEXPORT unzOpen2_64(const void *path, zlib_filefunc64_def *pzlib_filefunc_def)\n{\n    if (pzlib_filefunc_def != NULL) {\n        zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;\n        zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;\n        zlib_filefunc64_32_def_fill.ztell32_file = NULL;\n        zlib_filefunc64_32_def_fill.zseek32_file = NULL;\n        return unzOpenInternal(path, &zlib_filefunc64_32_def_fill);\n    }\n    return unzOpenInternal(path, NULL);\n}\n\nextern unzFile ZEXPORT unzOpen(const char *path)\n{\n    return unzOpenInternal(path, NULL);\n}\n\nextern unzFile ZEXPORT unzOpen64(const void *path)\n{\n    return unzOpenInternal(path, NULL);\n}\n\nextern int ZEXPORT unzClose(unzFile file)\n{\n    unz64_s *s;\n    if (file == NULL)\n        return UNZ_PARAMERROR;\n    s = (unz64_s *)file;\n\n    if (s->pfile_in_zip_read != NULL)\n        unzCloseCurrentFile(file);\n\n    if ((s->filestream != NULL) && (s->filestream != s->filestream_with_CD))\n        ZCLOSE64(s->z_filefunc, s->filestream);\n    if (s->filestream_with_CD != NULL)\n        ZCLOSE64(s->z_filefunc, s->filestream_with_CD);\n\n    s->filestream = NULL;\n    s->filestream_with_CD = NULL;\n    TRYFREE(s);\n    return UNZ_OK;\n}\n\n/* Goto to the next available disk for spanned archives */\nlocal int unzGoToNextDisk OF((unzFile file));\nlocal int unzGoToNextDisk(unzFile file)\n{\n    unz64_s *s;\n    file_in_zip64_read_info_s *pfile_in_zip_read_info;\n    uLong number_disk_next = 0;\n\n    s = (unz64_s *)file;\n    if (s == NULL)\n        return UNZ_PARAMERROR;\n    pfile_in_zip_read_info = s->pfile_in_zip_read;\n    number_disk_next = s->number_disk;\n\n    if ((pfile_in_zip_read_info != NULL) && (pfile_in_zip_read_info->rest_read_uncompressed > 0))\n        /* We are currently reading a file and we need the next sequential disk */\n        number_disk_next += 1;\n    else\n        /* Goto the disk for the current file */\n        number_disk_next = s->cur_file_info.disk_num_start;\n\n    if (number_disk_next != s->number_disk) {\n        /* Switch disks */\n        if ((s->filestream != NULL) && (s->filestream != s->filestream_with_CD))\n            ZCLOSE64(s->z_filefunc, s->filestream);\n\n        if (number_disk_next == s->gi.number_disk_with_CD) {\n            s->filestream = s->filestream_with_CD;\n        } else {\n            s->filestream = ZOPENDISK64(s->z_filefunc, s->filestream_with_CD, (unsigned int)number_disk_next,\n                                        ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_EXISTING);\n        }\n\n        if (s->filestream == NULL)\n            return UNZ_ERRNO;\n\n        s->number_disk = number_disk_next;\n    }\n\n    return UNZ_OK;\n}\n\nextern int ZEXPORT unzGetGlobalInfo(unzFile file, unz_global_info *pglobal_info32)\n{\n    unz64_s *s;\n    if (file == NULL)\n        return UNZ_PARAMERROR;\n    s = (unz64_s *)file;\n    /* to do : check if number_entry is not truncated */\n    pglobal_info32->number_entry = (uLong)s->gi.number_entry;\n    pglobal_info32->size_comment = s->gi.size_comment;\n    pglobal_info32->number_disk_with_CD = s->gi.number_disk_with_CD;\n    return UNZ_OK;\n}\n\nextern int ZEXPORT unzGetGlobalInfo64(unzFile file, unz_global_info64 *pglobal_info)\n{\n    unz64_s *s;\n    if (file == NULL)\n        return UNZ_PARAMERROR;\n    s = (unz64_s *)file;\n    *pglobal_info = s->gi;\n    return UNZ_OK;\n}\n\nextern int ZEXPORT unzGetGlobalComment(unzFile file, char *comment, uLong comment_size)\n{\n    unz64_s *s;\n    uLong bytes_to_read = comment_size;\n    if (file == NULL)\n        return (int)UNZ_PARAMERROR;\n    s = (unz64_s *)file;\n\n    if (bytes_to_read > s->gi.size_comment)\n        bytes_to_read = s->gi.size_comment;\n\n    if (ZSEEK64(s->z_filefunc, s->filestream_with_CD, s->central_pos + 22, ZLIB_FILEFUNC_SEEK_SET) != 0)\n        return UNZ_ERRNO;\n\n    if (bytes_to_read > 0) {\n        *comment = 0;\n        if (ZREAD64(s->z_filefunc, s->filestream_with_CD, comment, bytes_to_read) != bytes_to_read)\n            return UNZ_ERRNO;\n    }\n\n    if ((comment != NULL) && (comment_size > s->gi.size_comment))\n        *(comment + s->gi.size_comment) = 0;\n    return (int)bytes_to_read;\n}\n\n/* Get Info about the current file in the zipfile, with internal only info */\nlocal int unz64local_GetCurrentFileInfoInternal(unzFile file, unz_file_info64 *pfile_info,\n                                                unz_file_info64_internal *pfile_info_internal, char *filename, uLong filename_size, void *extrafield,\n                                                uLong extrafield_size, char *comment, uLong comment_size)\n{\n    unz64_s *s;\n    unz_file_info64 file_info;\n    unz_file_info64_internal file_info_internal;\n    ZPOS64_T bytes_to_read;\n    int err = UNZ_OK;\n    uLong uMagic;\n    long lSeek = 0;\n    ZPOS64_T current_pos = 0;\n    uLong acc = 0;\n    uLong uL;\n    ZPOS64_T uL64;\n\n    if (file == NULL)\n        return UNZ_PARAMERROR;\n    s = (unz64_s *)file;\n\n    if (ZSEEK64(s->z_filefunc, s->filestream_with_CD,\n                s->pos_in_central_dir + s->byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0)\n        err = UNZ_ERRNO;\n\n    /* Check the magic */\n    if (err == UNZ_OK) {\n        if (unz64local_getLong(&s->z_filefunc, s->filestream_with_CD, &uMagic) != UNZ_OK)\n            err = UNZ_ERRNO;\n        else if (uMagic != CENTRALHEADERMAGIC)\n            err = UNZ_BADZIPFILE;\n    }\n\n    /* Read central directory header */\n    if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD, &file_info.version) != UNZ_OK)\n        err = UNZ_ERRNO;\n    if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD, &file_info.version_needed) != UNZ_OK)\n        err = UNZ_ERRNO;\n    if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD, &file_info.flag) != UNZ_OK)\n        err = UNZ_ERRNO;\n    if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD, &file_info.compression_method) != UNZ_OK)\n        err = UNZ_ERRNO;\n    if (unz64local_getLong(&s->z_filefunc, s->filestream_with_CD, &file_info.dosDate) != UNZ_OK)\n        err = UNZ_ERRNO;\n    unz64local_DosDateToTmuDate(file_info.dosDate, &file_info.tmu_date);\n    if (unz64local_getLong(&s->z_filefunc, s->filestream_with_CD, &file_info.crc) != UNZ_OK)\n        err = UNZ_ERRNO;\n    if (unz64local_getLong(&s->z_filefunc, s->filestream_with_CD, &uL) != UNZ_OK)\n        err = UNZ_ERRNO;\n    file_info.compressed_size = uL;\n    if (unz64local_getLong(&s->z_filefunc, s->filestream_with_CD, &uL) != UNZ_OK)\n        err = UNZ_ERRNO;\n    file_info.uncompressed_size = uL;\n    if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD, &file_info.size_filename) != UNZ_OK)\n        err = UNZ_ERRNO;\n    if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD, &file_info.size_file_extra) != UNZ_OK)\n        err = UNZ_ERRNO;\n    if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD, &file_info.size_file_comment) != UNZ_OK)\n        err = UNZ_ERRNO;\n    if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD, &file_info.disk_num_start) != UNZ_OK)\n        err = UNZ_ERRNO;\n    if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD, &file_info.internal_fa) != UNZ_OK)\n        err = UNZ_ERRNO;\n    if (unz64local_getLong(&s->z_filefunc, s->filestream_with_CD, &file_info.external_fa) != UNZ_OK)\n        err = UNZ_ERRNO;\n    /* Relative offset of local header */\n    if (unz64local_getLong(&s->z_filefunc, s->filestream_with_CD, &uL) != UNZ_OK)\n        err = UNZ_ERRNO;\n\n    file_info.size_file_extra_internal = 0;\n    file_info.disk_offset = uL;\n    file_info_internal.offset_curfile = uL;\n#ifdef HAVE_AES\n    file_info_internal.aes_compression_method = 0;\n    file_info_internal.aes_encryption_mode = 0;\n    file_info_internal.aes_version = 0;\n#endif\n\n    lSeek += file_info.size_filename;\n\n    if ((err == UNZ_OK) && (filename != NULL)) {\n        if (file_info.size_filename < filename_size) {\n            *(filename + file_info.size_filename) = 0;\n            bytes_to_read = file_info.size_filename;\n        } else\n            bytes_to_read = filename_size;\n\n        if ((file_info.size_filename > 0) && (filename_size > 0))\n            if (ZREAD64(s->z_filefunc, s->filestream_with_CD, filename, (uLong)bytes_to_read) != bytes_to_read)\n                err = UNZ_ERRNO;\n        lSeek -= (uLong)bytes_to_read;\n    }\n\n    /* Read extrafield */\n    if ((err == UNZ_OK) && (extrafield != NULL)) {\n        if (file_info.size_file_extra < extrafield_size)\n            bytes_to_read = file_info.size_file_extra;\n        else\n            bytes_to_read = extrafield_size;\n\n        if (lSeek != 0) {\n            if (ZSEEK64(s->z_filefunc, s->filestream_with_CD, lSeek, ZLIB_FILEFUNC_SEEK_CUR) == 0)\n                lSeek = 0;\n            else\n                err = UNZ_ERRNO;\n        }\n\n        if ((file_info.size_file_extra > 0) && (extrafield_size > 0))\n            if (ZREAD64(s->z_filefunc, s->filestream_with_CD, extrafield, (uLong)bytes_to_read) != bytes_to_read)\n                err = UNZ_ERRNO;\n        lSeek += file_info.size_file_extra - (uLong)bytes_to_read;\n    } else\n        lSeek += file_info.size_file_extra;\n\n    if ((err == UNZ_OK) && (file_info.size_file_extra != 0)) {\n        if (lSeek != 0) {\n            if (ZSEEK64(s->z_filefunc, s->filestream_with_CD, lSeek, ZLIB_FILEFUNC_SEEK_CUR) == 0)\n                lSeek = 0;\n            else\n                err = UNZ_ERRNO;\n        }\n\n        /* We are going to parse the extra field so we need to move back */\n        current_pos = ZTELL64(s->z_filefunc, s->filestream_with_CD);\n        if (current_pos < file_info.size_file_extra)\n            err = UNZ_ERRNO;\n        current_pos -= file_info.size_file_extra;\n        if (ZSEEK64(s->z_filefunc, s->filestream_with_CD, current_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)\n            err = UNZ_ERRNO;\n\n        while ((err != UNZ_ERRNO) && (acc < file_info.size_file_extra)) {\n            uLong headerid;\n            uLong datasize;\n\n            if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD, &headerid) != UNZ_OK)\n                err = UNZ_ERRNO;\n            if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD, &datasize) != UNZ_OK)\n                err = UNZ_ERRNO;\n\n            /* ZIP64 extra fields */\n            if (headerid == 0x0001) {\n                /* Subtract size of ZIP64 field, since ZIP64 is handled internally */\n                file_info.size_file_extra_internal += 2 + 2 + datasize;\n\n                if (file_info.uncompressed_size == 0xffffffff) {\n                    if (unz64local_getLong64(&s->z_filefunc, s->filestream_with_CD, &file_info.uncompressed_size) != UNZ_OK)\n                        err = UNZ_ERRNO;\n                }\n                if (file_info.compressed_size == 0xffffffff) {\n                    if (unz64local_getLong64(&s->z_filefunc, s->filestream_with_CD, &file_info.compressed_size) != UNZ_OK)\n                        err = UNZ_ERRNO;\n                }\n                if (file_info_internal.offset_curfile == 0xffffffff) {\n                    /* Relative Header offset */\n                    if (unz64local_getLong64(&s->z_filefunc, s->filestream_with_CD, &uL64) != UNZ_OK)\n                        err = UNZ_ERRNO;\n                    file_info_internal.offset_curfile = uL64;\n                    file_info.disk_offset = uL64;\n                }\n                if (file_info.disk_num_start == 0xffffffff) {\n                    /* Disk Start Number */\n                    if (unz64local_getLong(&s->z_filefunc, s->filestream_with_CD, &file_info.disk_num_start) != UNZ_OK)\n                        err = UNZ_ERRNO;\n                }\n            }\n#ifdef HAVE_AES\n            /* AES header */\n            else if (headerid == 0x9901) {\n                /* Subtract size of AES field, since AES is handled internally */\n                file_info.size_file_extra_internal += 2 + 2 + datasize;\n\n                /* Verify version info */\n                if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD, &uL) != UNZ_OK)\n                    err = UNZ_ERRNO;\n                /* Support AE-1 and AE-2 */\n                if (uL != 1 && uL != 2)\n                    err = UNZ_ERRNO;\n                file_info_internal.aes_version = uL;\n                if (unz64local_getByte(&s->z_filefunc, s->filestream_with_CD, (int *)&uL) != UNZ_OK)\n                    err = UNZ_ERRNO;\n                if ((char)uL != 'A')\n                    err = UNZ_ERRNO;\n                if (unz64local_getByte(&s->z_filefunc, s->filestream_with_CD, (int *)&uL) != UNZ_OK)\n                    err = UNZ_ERRNO;\n                if ((char)uL != 'E')\n                    err = UNZ_ERRNO;\n                /* Get AES encryption strength and actual compression method */\n                if (unz64local_getByte(&s->z_filefunc, s->filestream_with_CD, (int *)&uL) != UNZ_OK)\n                    err = UNZ_ERRNO;\n                file_info_internal.aes_encryption_mode = uL;\n                if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD, &uL) != UNZ_OK)\n                    err = UNZ_ERRNO;\n                file_info_internal.aes_compression_method = uL;\n            }\n#endif\n            else {\n                if (ZSEEK64(s->z_filefunc, s->filestream_with_CD, datasize, ZLIB_FILEFUNC_SEEK_CUR) != 0)\n                    err = UNZ_ERRNO;\n            }\n\n            acc += 2 + 2 + datasize;\n        }\n    }\n\n    if (file_info.disk_num_start == s->gi.number_disk_with_CD)\n        file_info_internal.byte_before_the_zipfile = s->byte_before_the_zipfile;\n    else\n        file_info_internal.byte_before_the_zipfile = 0;\n\n    if ((err == UNZ_OK) && (comment != NULL)) {\n        if (file_info.size_file_comment < comment_size) {\n            *(comment + file_info.size_file_comment) = 0;\n            bytes_to_read = file_info.size_file_comment;\n        } else\n            bytes_to_read = comment_size;\n\n        if (lSeek != 0) {\n            if (ZSEEK64(s->z_filefunc, s->filestream_with_CD, lSeek, ZLIB_FILEFUNC_SEEK_CUR) != 0)\n                err = UNZ_ERRNO;\n        }\n\n        if ((file_info.size_file_comment > 0) && (comment_size > 0))\n            if (ZREAD64(s->z_filefunc, s->filestream_with_CD, comment, (uLong)bytes_to_read) != bytes_to_read)\n                err = UNZ_ERRNO;\n        lSeek += file_info.size_file_comment - (uLong)bytes_to_read;\n    } else\n        lSeek += file_info.size_file_comment;\n\n    if ((err == UNZ_OK) && (pfile_info != NULL))\n        *pfile_info = file_info;\n\n    if ((err == UNZ_OK) && (pfile_info_internal != NULL))\n        *pfile_info_internal = file_info_internal;\n\n    return err;\n}\n\nextern int ZEXPORT unzGetCurrentFileInfo(unzFile file, unz_file_info *pfile_info, char *filename,\n                                         uLong filename_size, void *extrafield, uLong extrafield_size, char *comment, uLong comment_size)\n{\n    unz_file_info64 file_info64;\n    int err;\n\n    err = unz64local_GetCurrentFileInfoInternal(file, &file_info64, NULL, filename, filename_size,\n                                                extrafield, extrafield_size, comment, comment_size);\n\n    if ((err == UNZ_OK) && (pfile_info != NULL)) {\n        pfile_info->version = file_info64.version;\n        pfile_info->version_needed = file_info64.version_needed;\n        pfile_info->flag = file_info64.flag;\n        pfile_info->compression_method = file_info64.compression_method;\n        pfile_info->dosDate = file_info64.dosDate;\n        pfile_info->crc = file_info64.crc;\n\n        pfile_info->size_filename = file_info64.size_filename;\n        pfile_info->size_file_extra = file_info64.size_file_extra - file_info64.size_file_extra_internal;\n        pfile_info->size_file_comment = file_info64.size_file_comment;\n\n        pfile_info->disk_num_start = file_info64.disk_num_start;\n        pfile_info->internal_fa = file_info64.internal_fa;\n        pfile_info->external_fa = file_info64.external_fa;\n\n        pfile_info->tmu_date = file_info64.tmu_date,\n\n        pfile_info->compressed_size = (uLong)file_info64.compressed_size;\n        pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size;\n\n    }\n    return err;\n}\n\nextern int ZEXPORT unzGetCurrentFileInfo64(unzFile file, unz_file_info64 *pfile_info, char *filename,\n                                           uLong filename_size, void *extrafield, uLong extrafield_size, char *comment, uLong comment_size)\n{\n    return unz64local_GetCurrentFileInfoInternal(file, pfile_info, NULL, filename, filename_size,\n                                                 extrafield, extrafield_size, comment, comment_size);\n}\n\n/* Read the local header of the current zipfile. Check the coherency of the local header and info in the\n   end of central directory about this file store in *piSizeVar the size of extra info in local header\n   (filename and size of extra field data) */\nlocal int unz64local_CheckCurrentFileCoherencyHeader(unz64_s *s, uInt *piSizeVar, ZPOS64_T *poffset_local_extrafield,\n                                                     uInt *psize_local_extrafield)\n{\n    uLong uMagic, uL, uFlags;\n    uLong size_filename;\n    uLong size_extra_field;\n    int err = UNZ_OK;\n    int compression_method = 0;\n\n    *piSizeVar = 0;\n    *poffset_local_extrafield = 0;\n    *psize_local_extrafield = 0;\n\n    err = unzGoToNextDisk((unzFile)s);\n    if (err != UNZ_OK)\n        return err;\n\n    if (ZSEEK64(s->z_filefunc, s->filestream, s->cur_file_info_internal.offset_curfile +\n                s->cur_file_info_internal.byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0)\n        return UNZ_ERRNO;\n\n    if (err == UNZ_OK) {\n        if (unz64local_getLong(&s->z_filefunc, s->filestream, &uMagic) != UNZ_OK)\n            err = UNZ_ERRNO;\n        else if (uMagic != LOCALHEADERMAGIC)\n            err = UNZ_BADZIPFILE;\n    }\n\n    if (unz64local_getShort(&s->z_filefunc, s->filestream, &uL) != UNZ_OK)\n        err = UNZ_ERRNO;\n    if (unz64local_getShort(&s->z_filefunc, s->filestream, &uFlags) != UNZ_OK)\n        err = UNZ_ERRNO;\n    if (unz64local_getShort(&s->z_filefunc, s->filestream, &uL) != UNZ_OK)\n        err = UNZ_ERRNO;\n    else if ((err == UNZ_OK) && (uL != s->cur_file_info.compression_method))\n        err = UNZ_BADZIPFILE;\n\n    compression_method = (int)s->cur_file_info.compression_method;\n#ifdef HAVE_AES\n    if (compression_method == AES_METHOD)\n        compression_method = (int)s->cur_file_info_internal.aes_compression_method;\n#endif\n\n    if ((err == UNZ_OK) && (compression_method != 0) &&\n#ifdef HAVE_BZIP2\n        (compression_method != Z_BZIP2ED) &&\n#endif\n        (compression_method != Z_DEFLATED))\n        err = UNZ_BADZIPFILE;\n\n    if (unz64local_getLong(&s->z_filefunc, s->filestream, &uL) != UNZ_OK) /* date/time */\n        err = UNZ_ERRNO;\n    if (unz64local_getLong(&s->z_filefunc, s->filestream, &uL) != UNZ_OK) /* crc */\n        err = UNZ_ERRNO;\n    else if ((err == UNZ_OK) && (uL != s->cur_file_info.crc) && ((uFlags & 8) == 0))\n        err = UNZ_BADZIPFILE;\n    if (unz64local_getLong(&s->z_filefunc, s->filestream, &uL) != UNZ_OK) /* size compr */\n        err = UNZ_ERRNO;\n    else if ((uL != 0xffffffff) && (err == UNZ_OK) && (uL != s->cur_file_info.compressed_size) && ((uFlags & 8) == 0))\n        err = UNZ_BADZIPFILE;\n    if (unz64local_getLong(&s->z_filefunc, s->filestream, &uL) != UNZ_OK) /* size uncompr */\n        err = UNZ_ERRNO;\n    else if ((uL != 0xffffffff) && (err == UNZ_OK) && (uL != s->cur_file_info.uncompressed_size) && ((uFlags & 8) == 0))\n        err = UNZ_BADZIPFILE;\n    if (unz64local_getShort(&s->z_filefunc, s->filestream, &size_filename) != UNZ_OK)\n        err = UNZ_ERRNO;\n    else if ((err == UNZ_OK) && (size_filename != s->cur_file_info.size_filename))\n        err = UNZ_BADZIPFILE;\n\n    *piSizeVar += (uInt)size_filename;\n\n    if (unz64local_getShort(&s->z_filefunc, s->filestream, &size_extra_field) != UNZ_OK)\n        err = UNZ_ERRNO;\n    *poffset_local_extrafield = s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + size_filename;\n    *psize_local_extrafield = (uInt)size_extra_field;\n\n    *piSizeVar += (uInt)size_extra_field;\n\n    return err;\n}\n\n/*\n   Open for reading data the current file in the zipfile.\n   If there is no error and the file is opened, the return value is UNZ_OK.\n */\nextern int ZEXPORT unzOpenCurrentFile3(unzFile file, int *method, int *level, int raw, const char *password)\n{\n    int err = UNZ_OK;\n    int compression_method;\n    uInt iSizeVar;\n    unz64_s *s;\n    file_in_zip64_read_info_s *pfile_in_zip_read_info;\n    ZPOS64_T offset_local_extrafield;\n    uInt size_local_extrafield;\n#ifndef NOUNCRYPT\n    char source[12];\n#else\n    if (password != NULL)\n        return UNZ_PARAMERROR;\n#endif\n    if (file == NULL)\n        return UNZ_PARAMERROR;\n    s = (unz64_s *)file;\n    if (!s->current_file_ok)\n        return UNZ_PARAMERROR;\n\n    if (s->pfile_in_zip_read != NULL)\n        unzCloseCurrentFile(file);\n\n    if (unz64local_CheckCurrentFileCoherencyHeader(s, &iSizeVar, &offset_local_extrafield, &size_local_extrafield) != UNZ_OK)\n        return UNZ_BADZIPFILE;\n\n    pfile_in_zip_read_info = (file_in_zip64_read_info_s *)ALLOC(sizeof(file_in_zip64_read_info_s));\n    if (pfile_in_zip_read_info == NULL)\n        return UNZ_INTERNALERROR;\n\n    pfile_in_zip_read_info->read_buffer = (Bytef *)ALLOC(UNZ_BUFSIZE);\n    pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;\n    pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;\n    pfile_in_zip_read_info->pos_local_extrafield = 0;\n    pfile_in_zip_read_info->raw = raw;\n\n    if (pfile_in_zip_read_info->read_buffer == NULL) {\n        TRYFREE(pfile_in_zip_read_info);\n        return UNZ_INTERNALERROR;\n    }\n\n    pfile_in_zip_read_info->stream_initialised = 0;\n\n    compression_method = (int)s->cur_file_info.compression_method;\n#ifdef HAVE_AES\n    if (compression_method == AES_METHOD)\n        compression_method = (int)s->cur_file_info_internal.aes_compression_method;\n#endif\n\n    if (method != NULL)\n        *method = compression_method;\n\n    if (level != NULL) {\n        *level = 6;\n        switch (s->cur_file_info.flag & 0x06) {\n        case 6: *level = 1; break;\n        case 4: *level = 2; break;\n        case 2: *level = 9; break;\n        }\n    }\n\n    if ((compression_method != 0) &&\n#ifdef HAVE_BZIP2\n        (compression_method != Z_BZIP2ED) &&\n#endif\n        (compression_method != Z_DEFLATED))\n        err = UNZ_BADZIPFILE;\n\n    pfile_in_zip_read_info->crc32_wait = s->cur_file_info.crc;\n    pfile_in_zip_read_info->crc32 = 0;\n    pfile_in_zip_read_info->total_out_64 = 0;\n    pfile_in_zip_read_info->compression_method = compression_method;\n    pfile_in_zip_read_info->filestream = s->filestream;\n    pfile_in_zip_read_info->z_filefunc = s->z_filefunc;\n    if (s->number_disk == s->gi.number_disk_with_CD)\n        pfile_in_zip_read_info->byte_before_the_zipfile = s->byte_before_the_zipfile;\n    else\n        pfile_in_zip_read_info->byte_before_the_zipfile = 0;\n    pfile_in_zip_read_info->stream.total_out = 0;\n    pfile_in_zip_read_info->stream.total_in = 0;\n    pfile_in_zip_read_info->stream.next_in = NULL;\n\n    if (!raw) {\n        if (compression_method == Z_BZIP2ED) {\n#ifdef HAVE_BZIP2\n            pfile_in_zip_read_info->bstream.bzalloc = (void *(*)(void *, int, int)) 0;\n            pfile_in_zip_read_info->bstream.bzfree = (free_func)0;\n            pfile_in_zip_read_info->bstream.opaque = (voidpf)0;\n            pfile_in_zip_read_info->bstream.state = (voidpf)0;\n\n            pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;\n            pfile_in_zip_read_info->stream.zfree = (free_func)0;\n            pfile_in_zip_read_info->stream.opaque = (voidpf)0;\n            pfile_in_zip_read_info->stream.next_in = (voidpf)0;\n            pfile_in_zip_read_info->stream.avail_in = 0;\n\n            err = BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0);\n            if (err == Z_OK)\n                pfile_in_zip_read_info->stream_initialised = Z_BZIP2ED;\n            else {\n                TRYFREE(pfile_in_zip_read_info);\n                return err;\n            }\n#else\n            pfile_in_zip_read_info->raw = 1;\n#endif\n        } else if (compression_method == Z_DEFLATED) {\n            pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;\n            pfile_in_zip_read_info->stream.zfree = (free_func)0;\n            pfile_in_zip_read_info->stream.opaque = (voidpf)s;\n            pfile_in_zip_read_info->stream.next_in = 0;\n            pfile_in_zip_read_info->stream.avail_in = 0;\n\n            err = inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);\n            if (err == Z_OK)\n                pfile_in_zip_read_info->stream_initialised = Z_DEFLATED;\n            else {\n                TRYFREE(pfile_in_zip_read_info);\n                return err;\n            }\n            /* windowBits is passed < 0 to tell that there is no zlib header.\n             * Note that in this case inflate *requires* an extra \"dummy\" byte\n             * after the compressed stream in order to complete decompression and\n             * return Z_STREAM_END.\n             * In unzip, i don't wait absolutely Z_STREAM_END because I known the\n             * size of both compressed and uncompressed data\n             */\n        }\n    }\n\n    pfile_in_zip_read_info->rest_read_compressed = s->cur_file_info.compressed_size;\n    pfile_in_zip_read_info->rest_read_uncompressed = s->cur_file_info.uncompressed_size;\n    pfile_in_zip_read_info->pos_in_zipfile = s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + iSizeVar;\n    pfile_in_zip_read_info->stream.avail_in = (uInt)0;\n\n    s->pfile_in_zip_read = pfile_in_zip_read_info;\n\n#ifndef NOUNCRYPT\n    if ((password != NULL) && ((s->cur_file_info.flag & 1) != 0)) {\n        if (ZSEEK64(s->z_filefunc, s->filestream,\n                    s->pfile_in_zip_read->pos_in_zipfile + s->pfile_in_zip_read->byte_before_the_zipfile,\n                    ZLIB_FILEFUNC_SEEK_SET) != 0)\n            return UNZ_INTERNALERROR;\n#ifdef HAVE_AES\n        if (s->cur_file_info.compression_method == AES_METHOD) {\n            unsigned char passverify[AES_PWVERIFYSIZE];\n            unsigned char saltvalue[AES_MAXSALTLENGTH];\n            uInt saltlength;\n\n            if ((s->cur_file_info_internal.aes_encryption_mode < 1) ||\n                (s->cur_file_info_internal.aes_encryption_mode > 3))\n                return UNZ_INTERNALERROR;\n\n            saltlength = SALT_LENGTH(s->cur_file_info_internal.aes_encryption_mode);\n\n            if (ZREAD64(s->z_filefunc, s->filestream, saltvalue, saltlength) != saltlength)\n                return UNZ_INTERNALERROR;\n            if (ZREAD64(s->z_filefunc, s->filestream, passverify, AES_PWVERIFYSIZE) != AES_PWVERIFYSIZE)\n                return UNZ_INTERNALERROR;\n\n            fcrypt_init((int)s->cur_file_info_internal.aes_encryption_mode, (unsigned char *)password, (unsigned int)strlen(password), saltvalue,\n                        passverify, &s->pfile_in_zip_read->aes_ctx);\n\n            pfile_in_zip_read_info->rest_read_compressed -= saltlength + AES_PWVERIFYSIZE;\n            pfile_in_zip_read_info->rest_read_compressed -= AES_AUTHCODESIZE;\n\n            s->pfile_in_zip_read->pos_in_zipfile += saltlength + AES_PWVERIFYSIZE;\n        } else\n#endif\n        {\n            int i;\n            s->pcrc_32_tab = (const unsigned long *)get_crc_table();\n            init_keys(password, s->keys, s->pcrc_32_tab);\n\n            if (ZREAD64(s->z_filefunc, s->filestream, source, 12) < 12)\n                return UNZ_INTERNALERROR;\n\n            for (i = 0; i < 12; i++)\n                zdecode(s->keys, s->pcrc_32_tab, source[i]);\n\n            pfile_in_zip_read_info->rest_read_compressed -= 12;\n\n            s->pfile_in_zip_read->pos_in_zipfile += 12;\n        }\n    }\n#endif\n\n    return UNZ_OK;\n}\n\nextern int ZEXPORT unzOpenCurrentFile(unzFile file)\n{\n    return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);\n}\n\nextern int ZEXPORT unzOpenCurrentFilePassword(unzFile file, const char *password)\n{\n    return unzOpenCurrentFile3(file, NULL, NULL, 0, password);\n}\n\nextern int ZEXPORT unzOpenCurrentFile2(unzFile file, int *method, int *level, int raw)\n{\n    return unzOpenCurrentFile3(file, method, level, raw, NULL);\n}\n\n/* Read bytes from the current file.\n   buf contain buffer where data must be copied\n   len the size of buf.\n\n   return the number of byte copied if some bytes are copied\n   return 0 if the end of file was reached\n   return <0 with error code if there is an error (UNZ_ERRNO for IO error, or zLib error for uncompress error) */\nextern int ZEXPORT unzReadCurrentFile(unzFile file, voidp buf, unsigned len)\n{\n    int err = UNZ_OK;\n    uInt read = 0;\n    unz64_s *s;\n    file_in_zip64_read_info_s *pfile_in_zip_read_info;\n    if (file == NULL)\n        return UNZ_PARAMERROR;\n    s = (unz64_s *)file;\n    pfile_in_zip_read_info = s->pfile_in_zip_read;\n\n    if (pfile_in_zip_read_info == NULL)\n        return UNZ_PARAMERROR;\n    if (pfile_in_zip_read_info->read_buffer == NULL)\n        return UNZ_END_OF_LIST_OF_FILE;\n    if (len == 0)\n        return 0;\n\n    pfile_in_zip_read_info->stream.next_out = (Bytef *)buf;\n    pfile_in_zip_read_info->stream.avail_out = (uInt)len;\n\n    if (pfile_in_zip_read_info->raw) {\n        if (len > pfile_in_zip_read_info->rest_read_compressed + pfile_in_zip_read_info->stream.avail_in)\n            pfile_in_zip_read_info->stream.avail_out = (uInt)pfile_in_zip_read_info->rest_read_compressed +\n                                                       pfile_in_zip_read_info->stream.avail_in;\n    } else {\n        \n        // NOTE:\n        // This bit of code seems to try to set the amount of space in the output buffer based on the\n        // value stored in the headers stored in the .zip file. However, if those values are incorrect\n        // it may result in a loss of data when uncompresssing that file. The compressed data is still\n        // legit and will deflate without knowing the uncompressed code so this tidbit is unnecessary and\n        // may cause issues for some .zip files.\n        //\n        // It's removed in here to fix those issues.\n        //\n        // See: https://github.com/ZipArchive/ziparchive/issues/16\n        //\n        \n        /*\n        \n         \n         FIXME: Upgrading to minizip 1.1 caused issues here, Uncommented the code that was commented before. 11/24/2015\n         */\n        \n        if (len > pfile_in_zip_read_info->rest_read_uncompressed)\n            pfile_in_zip_read_info->stream.avail_out = (uInt)pfile_in_zip_read_info->rest_read_uncompressed;\n        \n         \n    \n    }\n\n    while (pfile_in_zip_read_info->stream.avail_out > 0) {\n        if (pfile_in_zip_read_info->stream.avail_in == 0) {\n            uInt bytes_to_read = UNZ_BUFSIZE;\n            uInt bytes_not_read = 0;\n            uInt bytes_read = 0;\n            uInt total_bytes_read = 0;\n\n            if (pfile_in_zip_read_info->stream.next_in != NULL)\n                bytes_not_read = (uInt)(pfile_in_zip_read_info->read_buffer + UNZ_BUFSIZE -\n                                        pfile_in_zip_read_info->stream.next_in);\n            bytes_to_read -= bytes_not_read;\n            if (bytes_not_read > 0)\n                memcpy(pfile_in_zip_read_info->read_buffer, pfile_in_zip_read_info->stream.next_in, bytes_not_read);\n            if (pfile_in_zip_read_info->rest_read_compressed < bytes_to_read)\n                bytes_to_read = (uInt)pfile_in_zip_read_info->rest_read_compressed;\n\n            while (total_bytes_read != bytes_to_read) {\n                if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, pfile_in_zip_read_info->filestream,\n                            pfile_in_zip_read_info->pos_in_zipfile + pfile_in_zip_read_info->byte_before_the_zipfile,\n                            ZLIB_FILEFUNC_SEEK_SET) != 0)\n                    return UNZ_ERRNO;\n\n                bytes_read = (int)ZREAD64(pfile_in_zip_read_info->z_filefunc, pfile_in_zip_read_info->filestream,\n                                          pfile_in_zip_read_info->read_buffer + bytes_not_read + total_bytes_read,\n                                          bytes_to_read - total_bytes_read);\n\n                total_bytes_read += bytes_read;\n                pfile_in_zip_read_info->pos_in_zipfile += bytes_read;\n\n                if (bytes_read == 0) {\n                    if (ZERROR64(pfile_in_zip_read_info->z_filefunc, pfile_in_zip_read_info->filestream))\n                        return UNZ_ERRNO;\n\n                    err = unzGoToNextDisk(file);\n                    if (err != UNZ_OK)\n                        return err;\n\n                    pfile_in_zip_read_info->pos_in_zipfile = 0;\n                    pfile_in_zip_read_info->filestream = s->filestream;\n                }\n            }\n\n#ifndef NOUNCRYPT\n            if ((s->cur_file_info.flag & 1) != 0) {\n#ifdef HAVE_AES\n                if (s->cur_file_info.compression_method == AES_METHOD) {\n                    fcrypt_decrypt(pfile_in_zip_read_info->read_buffer, bytes_to_read, &s->pfile_in_zip_read->aes_ctx);\n                } else\n#endif\n                {\n                    uInt i;\n                    for (i = 0; i < total_bytes_read; i++)\n                        pfile_in_zip_read_info->read_buffer[i] =\n                            zdecode(s->keys, s->pcrc_32_tab, pfile_in_zip_read_info->read_buffer[i]);\n                }\n            }\n#endif\n\n            pfile_in_zip_read_info->rest_read_compressed -= total_bytes_read;\n            pfile_in_zip_read_info->stream.next_in = (Bytef *)pfile_in_zip_read_info->read_buffer;\n            pfile_in_zip_read_info->stream.avail_in = (uInt)bytes_not_read + total_bytes_read;\n        }\n\n        if ((pfile_in_zip_read_info->compression_method == 0) || (pfile_in_zip_read_info->raw)) {\n            uInt copy, i;\n\n            if ((pfile_in_zip_read_info->stream.avail_in == 0) &&\n                (pfile_in_zip_read_info->rest_read_compressed == 0))\n                return (read == 0) ? UNZ_EOF : read;\n\n            if (pfile_in_zip_read_info->stream.avail_out < pfile_in_zip_read_info->stream.avail_in)\n                copy = pfile_in_zip_read_info->stream.avail_out;\n            else\n                copy = pfile_in_zip_read_info->stream.avail_in;\n\n            for (i = 0; i < copy; i++)\n                *(pfile_in_zip_read_info->stream.next_out + i) =\n                    *(pfile_in_zip_read_info->stream.next_in + i);\n\n            pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + copy;\n            pfile_in_zip_read_info->rest_read_uncompressed -= copy;\n            pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,\n                                                  pfile_in_zip_read_info->stream.next_out, copy);\n\n            pfile_in_zip_read_info->stream.avail_in -= copy;\n            pfile_in_zip_read_info->stream.avail_out -= copy;\n            pfile_in_zip_read_info->stream.next_out += copy;\n            pfile_in_zip_read_info->stream.next_in += copy;\n            pfile_in_zip_read_info->stream.total_out += copy;\n            read += copy;\n        } else if (pfile_in_zip_read_info->compression_method == Z_BZIP2ED) {\n#ifdef HAVE_BZIP2\n            uLong total_out_before, total_out_after;\n            const Bytef *buf_before;\n            uLong out_bytes;\n\n            pfile_in_zip_read_info->bstream.next_in = (char *)pfile_in_zip_read_info->stream.next_in;\n            pfile_in_zip_read_info->bstream.avail_in = pfile_in_zip_read_info->stream.avail_in;\n            pfile_in_zip_read_info->bstream.total_in_lo32 = pfile_in_zip_read_info->stream.total_in;\n            pfile_in_zip_read_info->bstream.total_in_hi32 = 0;\n            pfile_in_zip_read_info->bstream.next_out = (char *)pfile_in_zip_read_info->stream.next_out;\n            pfile_in_zip_read_info->bstream.avail_out = pfile_in_zip_read_info->stream.avail_out;\n            pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out;\n            pfile_in_zip_read_info->bstream.total_out_hi32 = 0;\n\n            total_out_before = pfile_in_zip_read_info->bstream.total_out_lo32;\n            buf_before = (const Bytef *)pfile_in_zip_read_info->bstream.next_out;\n\n            err = BZ2_bzDecompress(&pfile_in_zip_read_info->bstream);\n\n            total_out_after = pfile_in_zip_read_info->bstream.total_out_lo32;\n            out_bytes = total_out_after - total_out_before;\n\n            pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + out_bytes;\n            pfile_in_zip_read_info->rest_read_uncompressed -= out_bytes;\n            pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, buf_before, (uInt)(out_bytes));\n\n            read += (uInt)(total_out_after - total_out_before);\n\n            pfile_in_zip_read_info->stream.next_in = (Bytef *)pfile_in_zip_read_info->bstream.next_in;\n            pfile_in_zip_read_info->stream.avail_in = pfile_in_zip_read_info->bstream.avail_in;\n            pfile_in_zip_read_info->stream.total_in = pfile_in_zip_read_info->bstream.total_in_lo32;\n            pfile_in_zip_read_info->stream.next_out = (Bytef *)pfile_in_zip_read_info->bstream.next_out;\n            pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out;\n            pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32;\n\n            if (err == BZ_STREAM_END)\n                return (read == 0) ? UNZ_EOF : read;\n            if (err != BZ_OK)\n                break;\n#endif\n        } else {\n            ZPOS64_T total_out_before, total_out_after;\n            const Bytef *buf_before;\n            ZPOS64_T out_bytes;\n            int flush = Z_SYNC_FLUSH;\n\n            total_out_before = pfile_in_zip_read_info->stream.total_out;\n            buf_before = pfile_in_zip_read_info->stream.next_out;\n\n            /*\n               if ((pfile_in_zip_read_info->rest_read_uncompressed ==\n                     pfile_in_zip_read_info->stream.avail_out) &&\n                (pfile_in_zip_read_info->rest_read_compressed == 0))\n                flush = Z_FINISH;\n             */\n            err = inflate(&pfile_in_zip_read_info->stream, flush);\n\n            if ((err >= 0) && (pfile_in_zip_read_info->stream.msg != NULL))\n                err = Z_DATA_ERROR;\n\n            total_out_after = pfile_in_zip_read_info->stream.total_out;\n            out_bytes = total_out_after - total_out_before;\n\n            pfile_in_zip_read_info->total_out_64 += out_bytes;\n            pfile_in_zip_read_info->rest_read_uncompressed -= out_bytes;\n            pfile_in_zip_read_info->crc32 =\n                crc32(pfile_in_zip_read_info->crc32, buf_before, (uInt)(out_bytes));\n\n            read += (uInt)(total_out_after - total_out_before);\n\n            if (err == Z_STREAM_END)\n                return (read == 0) ? UNZ_EOF : read;\n            if (err != Z_OK)\n                break;\n        }\n    }\n\n    if (err == Z_OK)\n        return read;\n    return err;\n}\n\nextern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64(unzFile file)\n{\n    unz64_s *s;\n    file_in_zip64_read_info_s *pfile_in_zip_read_info;\n    s = (unz64_s *)file;\n    if (file == NULL)\n        return 0; /* UNZ_PARAMERROR */\n    pfile_in_zip_read_info = s->pfile_in_zip_read;\n    if (pfile_in_zip_read_info == NULL)\n        return 0; /* UNZ_PARAMERROR */\n    return pfile_in_zip_read_info->pos_in_zipfile + pfile_in_zip_read_info->byte_before_the_zipfile;\n}\n\nextern int ZEXPORT unzGetLocalExtrafield(unzFile file, voidp buf, unsigned len)\n{\n    unz64_s *s;\n    file_in_zip64_read_info_s *pfile_in_zip_read_info;\n    uInt read_now;\n    ZPOS64_T size_to_read;\n\n    if (file == NULL)\n        return UNZ_PARAMERROR;\n    s = (unz64_s *)file;\n    pfile_in_zip_read_info = s->pfile_in_zip_read;\n\n    if (pfile_in_zip_read_info == NULL)\n        return UNZ_PARAMERROR;\n\n    size_to_read = pfile_in_zip_read_info->size_local_extrafield - pfile_in_zip_read_info->pos_local_extrafield;\n\n    if (buf == NULL)\n        return (int)size_to_read;\n\n    if (len > size_to_read)\n        read_now = (uInt)size_to_read;\n    else\n        read_now = (uInt)len;\n\n    if (read_now == 0)\n        return 0;\n\n    if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, pfile_in_zip_read_info->filestream,\n                pfile_in_zip_read_info->offset_local_extrafield + pfile_in_zip_read_info->pos_local_extrafield,\n                ZLIB_FILEFUNC_SEEK_SET) != 0)\n        return UNZ_ERRNO;\n\n    if (ZREAD64(pfile_in_zip_read_info->z_filefunc, pfile_in_zip_read_info->filestream, buf, read_now) != read_now)\n        return UNZ_ERRNO;\n\n    return (int)read_now;\n}\n\nextern int ZEXPORT unzCloseCurrentFile(unzFile file)\n{\n    int err = UNZ_OK;\n\n    unz64_s *s;\n    file_in_zip64_read_info_s *pfile_in_zip_read_info;\n    if (file == NULL)\n        return UNZ_PARAMERROR;\n    s = (unz64_s *)file;\n    pfile_in_zip_read_info = s->pfile_in_zip_read;\n\n    if (pfile_in_zip_read_info == NULL)\n        return UNZ_PARAMERROR;\n\n#ifdef HAVE_AES\n    if (s->cur_file_info.compression_method == AES_METHOD) {\n        unsigned char authcode[AES_AUTHCODESIZE];\n        unsigned char rauthcode[AES_AUTHCODESIZE];\n\n        if (ZREAD64(s->z_filefunc, s->filestream, authcode, AES_AUTHCODESIZE) != AES_AUTHCODESIZE)\n            return UNZ_ERRNO;\n\n        if (fcrypt_end(rauthcode, &s->pfile_in_zip_read->aes_ctx) != AES_AUTHCODESIZE)\n            err = UNZ_CRCERROR;\n        if (memcmp(authcode, rauthcode, AES_AUTHCODESIZE) != 0)\n            err = UNZ_CRCERROR;\n    }\n    /* AES zip version AE-1 will expect a valid crc as well */\n    if ((s->cur_file_info.compression_method != AES_METHOD) ||\n        (s->cur_file_info_internal.aes_version == 0x0001))\n#endif\n    {\n        if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&\n            (!pfile_in_zip_read_info->raw)) {\n            if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)\n                err = UNZ_CRCERROR;\n        }\n    }\n\n    TRYFREE(pfile_in_zip_read_info->read_buffer);\n    pfile_in_zip_read_info->read_buffer = NULL;\n    if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED)\n        inflateEnd(&pfile_in_zip_read_info->stream);\n#ifdef HAVE_BZIP2\n    else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED)\n        BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream);\n#endif\n\n    pfile_in_zip_read_info->stream_initialised = 0;\n    TRYFREE(pfile_in_zip_read_info);\n\n    s->pfile_in_zip_read = NULL;\n\n    return err;\n}\n\nextern int ZEXPORT unzGoToFirstFile2(unzFile file, unz_file_info64 *pfile_info, char *filename,\n                                     uLong filename_size, void *extrafield, uLong extrafield_size, char *comment, uLong comment_size)\n{\n    int err = UNZ_OK;\n    unz64_s *s;\n    if (file == NULL)\n        return UNZ_PARAMERROR;\n    s = (unz64_s *)file;\n    s->pos_in_central_dir = s->offset_central_dir;\n    s->num_file = 0;\n    err = unz64local_GetCurrentFileInfoInternal(file, &s->cur_file_info, &s->cur_file_info_internal,\n                                                filename, filename_size, extrafield, extrafield_size, comment, comment_size);\n    s->current_file_ok = (err == UNZ_OK);\n    if ((err == UNZ_OK) && (pfile_info != NULL))\n        memcpy(pfile_info, &s->cur_file_info, sizeof(unz_file_info64));\n    return err;\n}\n\nextern int ZEXPORT unzGoToFirstFile(unzFile file)\n{\n    return unzGoToFirstFile2(file, NULL, NULL, 0, NULL, 0, NULL, 0);\n}\n\nextern int ZEXPORT unzGoToNextFile2(unzFile file, unz_file_info64 *pfile_info, char *filename,\n                                    uLong filename_size, void *extrafield, uLong extrafield_size, char *comment, uLong comment_size)\n{\n    unz64_s *s;\n    int err;\n\n    if (file == NULL)\n        return UNZ_PARAMERROR;\n    s = (unz64_s *)file;\n    if (!s->current_file_ok)\n        return UNZ_END_OF_LIST_OF_FILE;\n    if (s->gi.number_entry != 0xffff)    /* 2^16 files overflow hack */\n        if (s->num_file + 1 == s->gi.number_entry)\n            return UNZ_END_OF_LIST_OF_FILE;\n    s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +\n                             s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment;\n    s->num_file++;\n    err = unz64local_GetCurrentFileInfoInternal(file, &s->cur_file_info, &s->cur_file_info_internal,\n                                                filename, filename_size, extrafield, extrafield_size, comment, comment_size);\n    s->current_file_ok = (err == UNZ_OK);\n    if ((err == UNZ_OK) && (pfile_info != NULL))\n        memcpy(pfile_info, &s->cur_file_info, sizeof(unz_file_info64));\n    return err;\n}\n\nextern int ZEXPORT unzGoToNextFile(unzFile file)\n{\n    return unzGoToNextFile2(file, NULL, NULL, 0, NULL, 0, NULL, 0);\n}\n\nextern int ZEXPORT unzLocateFile(unzFile file, const char *filename, unzFileNameComparer filename_compare_func)\n{\n    unz64_s *s;\n    int err;\n    unz_file_info64 cur_file_info_saved;\n    unz_file_info64_internal cur_file_info_internal_saved;\n    ZPOS64_T num_file_saved;\n    ZPOS64_T pos_in_central_dir_saved;\n    char current_filename[UNZ_MAXFILENAMEINZIP + 1];\n\n    if (file == NULL)\n        return UNZ_PARAMERROR;\n    if (strlen(filename) >= UNZ_MAXFILENAMEINZIP)\n        return UNZ_PARAMERROR;\n    s = (unz64_s *)file;\n    if (!s->current_file_ok)\n        return UNZ_END_OF_LIST_OF_FILE;\n\n    /* Save the current state */\n    num_file_saved = s->num_file;\n    pos_in_central_dir_saved = s->pos_in_central_dir;\n    cur_file_info_saved = s->cur_file_info;\n    cur_file_info_internal_saved = s->cur_file_info_internal;\n\n    err = unzGoToFirstFile2(file, NULL, current_filename, sizeof(current_filename) - 1, NULL, 0, NULL, 0);\n\n    while (err == UNZ_OK) {\n        if (filename_compare_func != NULL)\n            err = filename_compare_func(file, current_filename, filename);\n        else\n            err = strcmp(current_filename, filename);\n        if (err == 0)\n            return UNZ_OK;\n        err = unzGoToNextFile2(file, NULL, current_filename, sizeof(current_filename) - 1, NULL, 0, NULL, 0);\n    }\n\n    /* We failed, so restore the state of the 'current file' to where we were. */\n    s->num_file = num_file_saved;\n    s->pos_in_central_dir = pos_in_central_dir_saved;\n    s->cur_file_info = cur_file_info_saved;\n    s->cur_file_info_internal = cur_file_info_internal_saved;\n    return err;\n}\n\nextern int ZEXPORT unzGetFilePos(unzFile file, unz_file_pos *file_pos)\n{\n    unz64_file_pos file_pos64;\n    int err = unzGetFilePos64(file, &file_pos64);\n    if (err == UNZ_OK) {\n        file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory;\n        file_pos->num_of_file = (uLong)file_pos64.num_of_file;\n    }\n    return err;\n}\n\nextern int ZEXPORT unzGoToFilePos(unzFile file, unz_file_pos *file_pos)\n{\n    unz64_file_pos file_pos64;\n\n    if (file_pos == NULL)\n        return UNZ_PARAMERROR;\n    file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory;\n    file_pos64.num_of_file = file_pos->num_of_file;\n    return unzGoToFilePos64(file, &file_pos64);\n}\n\nextern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos *file_pos)\n{\n    unz64_s *s;\n\n    if (file == NULL || file_pos == NULL)\n        return UNZ_PARAMERROR;\n    s = (unz64_s *)file;\n    if (!s->current_file_ok)\n        return UNZ_END_OF_LIST_OF_FILE;\n\n    file_pos->pos_in_zip_directory = s->pos_in_central_dir;\n    file_pos->num_of_file = s->num_file;\n\n    return UNZ_OK;\n}\n\nextern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos *file_pos)\n{\n    unz64_s *s;\n    int err;\n\n    if (file == NULL || file_pos == NULL)\n        return UNZ_PARAMERROR;\n    s = (unz64_s *)file;\n\n    /* jump to the right spot */\n    s->pos_in_central_dir = file_pos->pos_in_zip_directory;\n    s->num_file = file_pos->num_of_file;\n\n    /* set the current file */\n    err = unz64local_GetCurrentFileInfoInternal(file, &s->cur_file_info, &s->cur_file_info_internal, NULL, 0, NULL, 0, NULL, 0);\n    /* return results */\n    s->current_file_ok = (err == UNZ_OK);\n    return err;\n}\n\nextern uLong ZEXPORT unzGetOffset(unzFile file)\n{\n    ZPOS64_T offset64;\n\n    if (file == NULL)\n        return 0; /* UNZ_PARAMERROR; */\n    offset64 = unzGetOffset64(file);\n    return (uLong)offset64;\n}\n\nextern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file)\n{\n    unz64_s *s;\n\n    if (file == NULL)\n        return 0; /* UNZ_PARAMERROR; */\n    s = (unz64_s *)file;\n    if (!s->current_file_ok)\n        return 0;\n    if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)\n        if (s->num_file == s->gi.number_entry)\n            return 0;\n    return s->pos_in_central_dir;\n}\n\nextern int ZEXPORT unzSetOffset(unzFile file, uLong pos)\n{\n    return unzSetOffset64(file, pos);\n}\n\nextern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos)\n{\n    unz64_s *s;\n    int err;\n\n    if (file == NULL)\n        return UNZ_PARAMERROR;\n    s = (unz64_s *)file;\n\n    s->pos_in_central_dir = pos;\n    s->num_file = s->gi.number_entry;      /* hack */\n    err = unz64local_GetCurrentFileInfoInternal(file, &s->cur_file_info, &s->cur_file_info_internal, NULL, 0, NULL, 0, NULL, 0);\n    s->current_file_ok = (err == UNZ_OK);\n    return err;\n}\n\nextern z_off_t ZEXPORT unztell(unzFile file)\n{\n    unz64_s *s;\n    file_in_zip64_read_info_s *pfile_in_zip_read_info;\n    if (file == NULL)\n        return UNZ_PARAMERROR;\n    s = (unz64_s *)file;\n    pfile_in_zip_read_info = s->pfile_in_zip_read;\n    if (pfile_in_zip_read_info == NULL)\n        return UNZ_PARAMERROR;\n    return (z_off_t)pfile_in_zip_read_info->stream.total_out;\n}\n\nextern ZPOS64_T ZEXPORT unztell64(unzFile file)\n{\n\n    unz64_s *s;\n    file_in_zip64_read_info_s *pfile_in_zip_read_info;\n    if (file == NULL)\n        return (ZPOS64_T)-1;\n    s = (unz64_s *)file;\n    pfile_in_zip_read_info = s->pfile_in_zip_read;\n\n    if (pfile_in_zip_read_info == NULL)\n        return (ZPOS64_T)-1;\n\n    return pfile_in_zip_read_info->total_out_64;\n}\n\nextern int ZEXPORT unzeof(unzFile file)\n{\n    unz64_s *s;\n    file_in_zip64_read_info_s *pfile_in_zip_read_info;\n    if (file == NULL)\n        return UNZ_PARAMERROR;\n    s = (unz64_s *)file;\n    pfile_in_zip_read_info = s->pfile_in_zip_read;\n\n    if (pfile_in_zip_read_info == NULL)\n        return UNZ_PARAMERROR;\n\n    if (pfile_in_zip_read_info->rest_read_uncompressed == 0)\n        return 1;\n    return 0;\n}\n\n"
  },
  {
    "path": "plugins/cordova-plugin-zip/src/ios/minizip/unzip.h",
    "content": "/* unzip.h -- IO for uncompress .zip files using zlib\n   Version 1.1, February 14h, 2010\n   part of the MiniZip project\n\n   Copyright (C) 1998-2010 Gilles Vollant\n     http://www.winimage.com/zLibDll/minizip.html\n   Modifications of Unzip for Zip64\n     Copyright (C) 2007-2008 Even Rouault\n   Modifications for Zip64 support on both zip and unzip\n     Copyright (C) 2009-2010 Mathias Svensson\n     http://result42.com\n\n   This program is distributed under the terms of the same license as zlib.\n   See the accompanying LICENSE file for the full text of the license.\n*/\n\n#include \"Common.h\"\n\n#ifndef _UNZ_H\n#define _UNZ_H\n\n#define HAVE_AES\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#ifndef _ZLIB_H\n#include \"zlib.h\"\n#endif\n\n#ifndef  _ZLIBIOAPI_H\n#include \"ioapi.h\"\n#endif\n\n#ifdef HAVE_BZIP2\n#include \"bzlib.h\"\n#endif\n\n#define Z_BZIP2ED 12\n\n#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)\n/* like the STRICT of WIN32, we define a pointer that cannot be converted\n    from (void*) without cast */\ntypedef struct TagunzFile__ { int unused; } unzFile__;\ntypedef unzFile__ *unzFile;\n#else\ntypedef voidp unzFile;\n#endif\n\n\n#define UNZ_OK                          (0)\n#define UNZ_END_OF_LIST_OF_FILE         (-100)\n#define UNZ_ERRNO                       (Z_ERRNO)\n#define UNZ_EOF                         (0)\n#define UNZ_PARAMERROR                  (-102)\n#define UNZ_BADZIPFILE                  (-103)\n#define UNZ_INTERNALERROR               (-104)\n#define UNZ_CRCERROR                    (-105)\n\n\n/***************************************************************************/\n/* Opening and close a zip file */\n\nextern unzFile ZEXPORT unzOpen OF((const char *path));\nextern unzFile ZEXPORT unzOpen64 OF((const void *path));\n/* Open a Zip file.\n\n   path should contain the full pathname (by example, on a Windows XP computer \n      \"c:\\\\zlib\\\\zlib113.zip\" or on an Unix computer \"zlib/zlib113.zip\". \n   return NULL if zipfile cannot be opened or doesn't exist\n   return unzFile handle if no error\n\n   NOTE: The \"64\" function take a const void* pointer, because  the path is just the value passed to the\n   open64_file_func callback. Under Windows, if UNICODE is defined, using fill_fopen64_filefunc, the path \n   is a pointer to a wide unicode string  (LPCTSTR is LPCWSTR), so const char* does not describe the reality */\n\nextern unzFile ZEXPORT unzOpen2 OF((const char *path, zlib_filefunc_def* pzlib_filefunc_def));\n/* Open a Zip file, like unzOpen, but provide a set of file low level API for read/write operations */\nextern unzFile ZEXPORT unzOpen2_64 OF((const void *path, zlib_filefunc64_def* pzlib_filefunc_def));\n/* Open a Zip file, like unz64Open, but provide a set of file low level API for read/write 64-bit operations */\n\nextern int ZEXPORT unzClose OF((unzFile file));\n/* Close a ZipFile opened with unzipOpen. If there is files inside the .Zip opened with unzOpenCurrentFile,\n   these files MUST be closed with unzipCloseCurrentFile before call unzipClose.\n\n   return UNZ_OK if there is no error */\n\nextern int ZEXPORT unzGetGlobalInfo OF((unzFile file, unz_global_info *pglobal_info));\nextern int ZEXPORT unzGetGlobalInfo64 OF((unzFile file, unz_global_info64 *pglobal_info));\n/* Write info about the ZipFile in the *pglobal_info structure.\n\n   return UNZ_OK if no error */\n\nextern int ZEXPORT unzGetGlobalComment OF((unzFile file, char *comment, uLong comment_size));\n/* Get the global comment string of the ZipFile, in the comment buffer.\n\n   uSizeBuf is the size of the szComment buffer.\n   return the number of byte copied or an error code <0 */\n\n/***************************************************************************/\n/* Reading the content of the current zipfile, you can open it, read data from it, and close it\n   (you can close it before reading all the file) */\n\nextern int ZEXPORT unzOpenCurrentFile OF((unzFile file));\n/* Open for reading data the current file in the zipfile.\n\n   return UNZ_OK if no error */\n\nextern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file, const char* password));\n/* Open for reading data the current file in the zipfile.\n   password is a crypting password\n\n   return UNZ_OK if no error */\n\nextern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file, int* method, int* level, int raw));\n/* Same as unzOpenCurrentFile, but open for read raw the file (not uncompress)\n   if raw==1 *method will receive method of compression, *level will receive level of compression\n\n   NOTE: you can set level parameter as NULL (if you did not want known level,\n         but you CANNOT set method parameter as NULL */\n\nextern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file, int* method, int* level, int raw, const char* password));\n/* Same as unzOpenCurrentFile, but takes extra parameter password for encrypted files */\n\nextern int ZEXPORT unzReadCurrentFile OF((unzFile file, voidp buf, unsigned len));\n/* Read bytes from the current file (opened by unzOpenCurrentFile)\n   buf contain buffer where data must be copied\n   len the size of buf.\n\n   return the number of byte copied if somes bytes are copied\n   return 0 if the end of file was reached\n   return <0 with error code if there is an error (UNZ_ERRNO for IO error, or zLib error for uncompress error) */\n\nextern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, unz_file_info *pfile_info, char *filename, \n    uLong filename_size, void *extrafield, uLong extrafield_size, char *comment, uLong comment_size));\nextern int ZEXPORT unzGetCurrentFileInfo64 OF((unzFile file, unz_file_info64 *pfile_info, char *filename,\n    uLong filename_size, void *extrafield, uLong extrafield_size, char *comment, uLong comment_size));\n/* Get Info about the current file\n\n   pfile_info if != NULL, the *pfile_info structure will contain somes info about the current file\n   filename if != NULL, the file name string will be copied in filename \n   filename_size is the size of the filename buffer\n   extrafield if != NULL, the extra field information from the central header will be copied in to\n   extrafield_size is the size of the extraField buffer \n   comment if != NULL, the comment string of the file will be copied in to\n   comment_size is the size of the comment buffer */\n\nextern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64 OF((unzFile file));\n\nextern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, voidp buf, unsigned len));\n/* Read extra field from the current file (opened by unzOpenCurrentFile)\n   This is the local-header version of the extra field (sometimes, there is\n   more info in the local-header version than in the central-header)\n\n   if buf == NULL, it return the size of the local extra field\n   if buf != NULL, len is the size of the buffer, the extra header is copied in buf.\n\n   return number of bytes copied in buf, or (if <0) the error code */\n\nextern int ZEXPORT unzCloseCurrentFile OF((unzFile file));\n/* Close the file in zip opened with unzOpenCurrentFile\n\n   return UNZ_CRCERROR if all the file was read but the CRC is not good */\n\n/***************************************************************************/\n/* Browse the directory of the zipfile */\n\ntypedef int (*unzFileNameComparer)(unzFile file, const char *filename1, const char *filename2);\ntypedef int (*unzIteratorFunction)(unzFile file);\ntypedef int (*unzIteratorFunction2)(unzFile file, unz_file_info64 *pfile_info, char *filename,\n    uLong filename_size, void *extrafield, uLong extrafield_size, char *comment, uLong comment_size);\n\nextern int ZEXPORT unzGoToFirstFile OF((unzFile file));\n/* Set the current file of the zipfile to the first file.\n\n   return UNZ_OK if no error */\n\nextern int ZEXPORT unzGoToFirstFile2 OF((unzFile file, unz_file_info64 *pfile_info, char *filename,\n    uLong filename_size, void *extrafield, uLong extrafield_size, char *comment, uLong comment_size));\n/* Set the current file of the zipfile to the first file and retrieves the current info on success. \n   Not as seek intensive as unzGoToFirstFile + unzGetCurrentFileInfo.\n\n   return UNZ_OK if no error */\n\nextern int ZEXPORT unzGoToNextFile OF((unzFile file));\n/* Set the current file of the zipfile to the next file.\n\n   return UNZ_OK if no error\n   return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest */\n\nextern int ZEXPORT unzGoToNextFile2 OF((unzFile file, unz_file_info64 *pfile_info, char *filename,\n    uLong filename_size, void *extrafield, uLong extrafield_size, char *comment, uLong comment_size));\n/* Set the current file of the zipfile to the next file and retrieves the current \n   info on success. Does less seeking around than unzGotoNextFile + unzGetCurrentFileInfo.\n\n   return UNZ_OK if no error\n   return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest */\n\nextern int ZEXPORT unzLocateFile OF((unzFile file, const char *filename, unzFileNameComparer filename_compare_func));\n/* Try locate the file szFileName in the zipfile. For custom filename comparison pass in comparison function.\n\n   return UNZ_OK if the file is found (it becomes the current file)\n   return UNZ_END_OF_LIST_OF_FILE if the file is not found */\n\n/***************************************************************************/\n/* Raw access to zip file */\n\ntypedef struct unz_file_pos_s\n{\n    uLong pos_in_zip_directory;     /* offset in zip file directory */\n    uLong num_of_file;              /* # of file */\n} unz_file_pos;\n\nextern int ZEXPORT unzGetFilePos OF((unzFile file, unz_file_pos* file_pos));\nextern int ZEXPORT unzGoToFilePos OF((unzFile file, unz_file_pos* file_pos));\n\ntypedef struct unz64_file_pos_s\n{\n    ZPOS64_T pos_in_zip_directory;   /* offset in zip file directory */\n    ZPOS64_T num_of_file;            /* # of file */\n} unz64_file_pos;\n\nextern int ZEXPORT unzGetFilePos64 OF((unzFile file, unz64_file_pos* file_pos));\nextern int ZEXPORT unzGoToFilePos64 OF((unzFile file, const unz64_file_pos* file_pos));\n\nextern uLong ZEXPORT unzGetOffset OF((unzFile file));\nextern ZPOS64_T ZEXPORT unzGetOffset64 OF((unzFile file));\n/* Get the current file offset */\n\nextern int ZEXPORT unzSetOffset OF((unzFile file, uLong pos));\nextern int ZEXPORT unzSetOffset64 OF((unzFile file, ZPOS64_T pos));\n/* Set the current file offset */\n\nextern z_off_t ZEXPORT unztell OF((unzFile file));\nextern ZPOS64_T ZEXPORT unztell64 OF((unzFile file));\n/* return current position in uncompressed data */\n\nextern int ZEXPORT unzeof OF((unzFile file));\n/* return 1 if the end of file was reached, 0 elsewhere */\n\n/***************************************************************************/\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* _UNZ_H */\n"
  },
  {
    "path": "plugins/cordova-plugin-zip/src/ios/minizip/zip.c",
    "content": "/* zip.c -- IO on .zip files using zlib\n   Version 1.1, February 14h, 2010\n   part of the MiniZip project\n\n   Copyright (C) 1998-2010 Gilles Vollant\n     http://www.winimage.com/zLibDll/minizip.html\n   Modifications for Zip64 support\n     Copyright (C) 2009-2010 Mathias Svensson\n     http://result42.com\n   Modifications for AES, PKWARE disk spanning\n     Copyright (C) 2010-2014 Nathan Moinvaziri\n\n   This program is distributed under the terms of the same license as zlib.\n   See the accompanying LICENSE file for the full text of the license.\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <time.h>\n#include \"zlib.h\"\n#include \"zip.h\"\n\n#ifdef STDC\n#  include <stddef.h>\n#  include <string.h>\n#  include <stdlib.h>\n#endif\n#ifdef NO_ERRNO_H\nextern int errno;\n#else\n#   include <errno.h>\n#endif\n\n#ifdef HAVE_AES\n#  define AES_METHOD          (99)\n#  define AES_PWVERIFYSIZE    (2)\n#  define AES_AUTHCODESIZE    (10)\n#  define AES_MAXSALTLENGTH   (16)\n#  define AES_VERSION         (0x0001)\n#  define AES_ENCRYPTIONMODE  (0x03)\n\n#  include \"aes.h\"\n#  include \"fileenc.h\"\n#  include \"prng.h\"\n#  include \"entropy.h\"\n#endif\n\n#ifndef NOCRYPT\n#  define INCLUDECRYPTINGCODE_IFCRYPTALLOWED\n#  include \"crypt.h\"\n#endif\n\n#ifndef local\n#  define local static\n#endif\n/* compile with -Dlocal if your debugger can't find static symbols */\n\n#define SIZEDATA_INDATABLOCK        (4096 - (4 * 4))\n\n#define DISKHEADERMAGIC             (0x08074b50)\n#define LOCALHEADERMAGIC            (0x04034b50)\n#define CENTRALHEADERMAGIC          (0x02014b50)\n#define ENDHEADERMAGIC              (0x06054b50)\n#define ZIP64ENDHEADERMAGIC         (0x06064b50)\n#define ZIP64ENDLOCHEADERMAGIC      (0x07064b50)\n\n#define FLAG_LOCALHEADER_OFFSET     (0x06)\n#define CRC_LOCALHEADER_OFFSET      (0x0e)\n\n#define SIZECENTRALHEADER           (0x2e) /* 46 */\n#define SIZECENTRALHEADERLOCATOR    (0x14) /* 20 */\n#define SIZECENTRALDIRITEM          (0x2e)\n#define SIZEZIPLOCALHEADER          (0x1e)\n\n#ifndef BUFREADCOMMENT\n#  define BUFREADCOMMENT            (0x400)\n#endif\n#ifndef VERSIONMADEBY\n#  define VERSIONMADEBY             (0x0) /* platform dependent */\n#endif\n\n#ifndef Z_BUFSIZE\n#  define Z_BUFSIZE (64 * 1024)\n#endif\n#ifndef Z_MAXFILENAMEINZIP\n#  define Z_MAXFILENAMEINZIP (256)\n#endif\n\n#ifndef ALLOC\n#  define ALLOC(size) (malloc(size))\n#endif\n#ifndef TRYFREE\n#  define TRYFREE(p) {if (p) free(p); }\n#endif\n\n/* NOT sure that this work on ALL platform */\n#define MAKEULONG64(a, b) ((ZPOS64_T)(((unsigned long)(a)) | ((ZPOS64_T)((unsigned long)(b))) << 32))\n\n#ifndef DEF_MEM_LEVEL\n#  if MAX_MEM_LEVEL >= 8\n#    define DEF_MEM_LEVEL 8\n#  else\n#    define DEF_MEM_LEVEL  MAX_MEM_LEVEL\n#  endif\n#endif\n\nconst char zip_copyright[] = \" zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll\";\n\ntypedef struct linkedlist_datablock_internal_s {\n    struct linkedlist_datablock_internal_s *next_datablock;\n    uLong avail_in_this_block;\n    uLong filled_in_this_block;\n    uLong unused;  /* for future use and alignment */\n    unsigned char data[SIZEDATA_INDATABLOCK];\n} linkedlist_datablock_internal;\n\ntypedef struct linkedlist_data_s {\n    linkedlist_datablock_internal *first_block;\n    linkedlist_datablock_internal *last_block;\n} linkedlist_data;\n\ntypedef struct {\n    z_stream stream;                /* zLib stream structure for inflate */\n#ifdef HAVE_BZIP2\n    bz_stream bstream;              /* bzLib stream structure for bziped */\n#endif\n#ifdef HAVE_AES\n    fcrypt_ctx aes_ctx;\n    prng_ctx aes_rng[1];\n#endif\n    int stream_initialised;         /* 1 is stream is initialized */\n    uInt pos_in_buffered_data;      /* last written byte in buffered_data */\n\n    ZPOS64_T pos_local_header;      /* offset of the local header of the file currently writing */\n    char *central_header;           /* central header data for the current file */\n    uLong size_centralextra;\n    uLong size_centralheader;       /* size of the central header for cur file */\n    uLong size_centralextrafree;    /* Extra bytes allocated to the central header but that are not used */\n    uLong size_comment;\n    uLong flag;                     /* flag of the file currently writing */\n\n    int method;                     /* compression method written to file.*/\n    int compression_method;         /* compression method to use */\n    int raw;                        /* 1 for directly writing raw data */\n    Byte buffered_data[Z_BUFSIZE];  /* buffer contain compressed data to be writ*/\n    uLong dosDate;\n    uLong crc32;\n    int zip64;                      /* Add ZIP64 extended information in the extra field */\n    uLong number_disk;              /* number of current disk used for spanning ZIP */\n    ZPOS64_T pos_zip64extrainfo;\n    ZPOS64_T total_compressed;\n    ZPOS64_T total_uncompressed;\n#ifndef NOCRYPT\n    unsigned long keys[3];          /* keys defining the pseudo-random sequence */\n    const unsigned long *pcrc_32_tab;\n    int crypt_header_size;\n#endif\n} curfile64_info;\n\ntypedef struct {\n    zlib_filefunc64_32_def z_filefunc;\n    voidpf filestream;              /* io structure of the zipfile */\n    voidpf filestream_with_CD;      /* io structure of the zipfile with the central dir */\n    linkedlist_data central_dir;    /* datablock with central dir in construction*/\n    int in_opened_file_inzip;       /* 1 if a file in the zip is currently writ.*/\n    int append;                     /* append mode */\n    curfile64_info ci;              /* info on the file currently writing */\n\n    ZPOS64_T begin_pos;             /* position of the beginning of the zipfile */\n    ZPOS64_T add_position_when_writting_offset;\n    ZPOS64_T number_entry;\n    ZPOS64_T disk_size;             /* size of each disk */\n    uLong number_disk;              /* number of the current disk, used for spanning ZIP */\n    uLong number_disk_with_CD;      /* number the the disk with central dir, used for spanning ZIP */\n#ifndef NO_ADDFILEINEXISTINGZIP\n    char *globalcomment;\n#endif\n} zip64_internal;\n\n/* Allocate a new data block */\nlocal linkedlist_datablock_internal *allocate_new_datablock OF(());\nlocal linkedlist_datablock_internal *allocate_new_datablock()\n{\n    linkedlist_datablock_internal *ldi;\n\n    ldi = (linkedlist_datablock_internal *)ALLOC(sizeof(linkedlist_datablock_internal));\n\n    if (ldi != NULL) {\n        ldi->next_datablock = NULL;\n        ldi->filled_in_this_block = 0;\n        ldi->avail_in_this_block = SIZEDATA_INDATABLOCK;\n    }\n    return ldi;\n}\n\n/* Free data block in linked list */\nlocal void free_datablock OF((linkedlist_datablock_internal * ldi));\nlocal void free_datablock(linkedlist_datablock_internal *ldi)\n{\n    while (ldi != NULL) {\n        linkedlist_datablock_internal *ldinext = ldi->next_datablock;\n        TRYFREE(ldi);\n        ldi = ldinext;\n    }\n}\n\n/* Initialize linked list */\nlocal void init_linkedlist OF((linkedlist_data * ll));\nlocal void init_linkedlist(linkedlist_data *ll)\n{\n    ll->first_block = ll->last_block = NULL;\n}\n\n/* Free entire linked list and all data blocks */\nlocal void free_linkedlist OF((linkedlist_data * ll));\nlocal void free_linkedlist(linkedlist_data *ll)\n{\n    free_datablock(ll->first_block);\n    ll->first_block = ll->last_block = NULL;\n}\n\n/* Add data to linked list data block */\nlocal int add_data_in_datablock OF((linkedlist_data * ll, const void *buf, uLong len));\nlocal int add_data_in_datablock(linkedlist_data *ll, const void *buf, uLong len)\n{\n    linkedlist_datablock_internal *ldi;\n    const unsigned char *from_copy;\n\n    if (ll == NULL)\n        return ZIP_INTERNALERROR;\n\n    if (ll->last_block == NULL) {\n        ll->first_block = ll->last_block = allocate_new_datablock();\n        if (ll->first_block == NULL)\n            return ZIP_INTERNALERROR;\n    }\n\n    ldi = ll->last_block;\n    from_copy = (unsigned char *)buf;\n\n    while (len > 0) {\n        uInt copy_this;\n        uInt i;\n        unsigned char *to_copy;\n\n        if (ldi->avail_in_this_block == 0) {\n            ldi->next_datablock = allocate_new_datablock();\n            if (ldi->next_datablock == NULL)\n                return ZIP_INTERNALERROR;\n            ldi = ldi->next_datablock;\n            ll->last_block = ldi;\n        }\n\n        if (ldi->avail_in_this_block < len)\n            copy_this = (uInt)ldi->avail_in_this_block;\n        else\n            copy_this = (uInt)len;\n\n        to_copy = &(ldi->data[ldi->filled_in_this_block]);\n\n        for (i = 0; i < copy_this; i++)\n            *(to_copy + i) = *(from_copy + i);\n\n        ldi->filled_in_this_block += copy_this;\n        ldi->avail_in_this_block -= copy_this;\n        from_copy += copy_this;\n        len -= copy_this;\n    }\n    return ZIP_OK;\n}\n\nlocal uLong zip64local_TmzDateToDosDate OF((const tm_zip * ptm));\nlocal uLong zip64local_TmzDateToDosDate(const tm_zip *ptm)\n{\n    uLong year;\n#define zip64local_in_range(min, max, value) ((min) <= (value) && (value) <= (max))\n    /* Years supported:\n     * [00, 79] (assumed to be between 2000 and 2079)\n     * [80, 207] (assumed to be between 1980 and 2107, typical output of old\n         software that does 'year-1900' to get a double digit year)\n     * [1980, 2107]\n       Due to the date format limitations, only years between 1980 and 2107 can be stored.\n     */\n    if (!(zip64local_in_range(1980, 2107, ptm->tm_year) || zip64local_in_range(0, 207, ptm->tm_year)) ||\n        !zip64local_in_range(0, 11, ptm->tm_mon) ||\n        !zip64local_in_range(1, 31, ptm->tm_mday) ||\n        !zip64local_in_range(0, 23, ptm->tm_hour) ||\n        !zip64local_in_range(0, 59, ptm->tm_min) ||\n        !zip64local_in_range(0, 59, ptm->tm_sec))\n        return 0;\n#undef zip64local_in_range\n\n    year = (uLong)ptm->tm_year;\n    if (year >= 1980) /* range [1980, 2107] */\n        year -= 1980;\n    else if (year >= 80) /* range [80, 99] */\n        year -= 80;\n    else /* range [00, 79] */\n        year += 20;\n\n    return\n        (uLong)(((ptm->tm_mday) + (32 * (ptm->tm_mon + 1)) + (512 * year)) << 16) |\n        ((ptm->tm_sec / 2) + (32 * ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));\n}\n\n/* Inputs a long in LSB order to the given file: nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T) */\nlocal int zip64local_putValue OF((const zlib_filefunc64_32_def * pzlib_filefunc_def, voidpf filestream,\n                                  ZPOS64_T x, int nbByte));\nlocal int zip64local_putValue(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream,\n                              ZPOS64_T x, int nbByte)\n{\n    unsigned char buf[8];\n    int n;\n    for (n = 0; n < nbByte; n++) {\n        buf[n] = (unsigned char)(x & 0xff);\n        x >>= 8;\n    }\n    if (x != 0) {\n        /* data overflow - hack for ZIP64 (X Roche) */\n        for (n = 0; n < nbByte; n++) {\n            buf[n] = 0xff;\n        }\n    }\n\n    if (ZWRITE64(*pzlib_filefunc_def, filestream, buf, nbByte) != (uLong)nbByte)\n        return ZIP_ERRNO;\n\n    return ZIP_OK;\n}\n\nlocal void zip64local_putValue_inmemory OF((void *dest, ZPOS64_T x, int nbByte));\nlocal void zip64local_putValue_inmemory(void *dest, ZPOS64_T x, int nbByte)\n{\n    unsigned char *buf = (unsigned char *)dest;\n    int n;\n    for (n = 0; n < nbByte; n++) {\n        buf[n] = (unsigned char)(x & 0xff);\n        x >>= 8;\n    }\n\n    if (x != 0) {\n        /* data overflow - hack for ZIP64 */\n        for (n = 0; n < nbByte; n++) {\n            buf[n] = 0xff;\n        }\n    }\n}\n\nlocal int zip64local_getByte OF((const zlib_filefunc64_32_def * pzlib_filefunc_def, voidpf filestream, int *pi));\nlocal int zip64local_getByte(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream, int *pi)\n{\n    unsigned char c;\n    int err = (int)ZREAD64(*pzlib_filefunc_def, filestream, &c, 1);\n    if (err == 1) {\n        *pi = (int)c;\n        return ZIP_OK;\n    }\n    if (ZERROR64(*pzlib_filefunc_def, filestream))\n        return ZIP_ERRNO;\n    return ZIP_EOF;\n}\n\nlocal int zip64local_getShort OF((const zlib_filefunc64_32_def * pzlib_filefunc_def, voidpf filestream, uLong * pX));\nlocal int zip64local_getShort(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream, uLong *pX)\n{\n    uLong x;\n    int i = 0;\n    int err;\n\n    err = zip64local_getByte(pzlib_filefunc_def, filestream, &i);\n    x = (uLong)i;\n    if (err == ZIP_OK)\n        err = zip64local_getByte(pzlib_filefunc_def, filestream, &i);\n    x += ((uLong)i) << 8;\n\n    if (err == ZIP_OK)\n        *pX = x;\n    else\n        *pX = 0;\n    return err;\n}\n\nlocal int zip64local_getLong OF((const zlib_filefunc64_32_def * pzlib_filefunc_def, voidpf filestream, uLong * pX));\nlocal int zip64local_getLong(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream, uLong *pX)\n{\n    uLong x;\n    int i = 0;\n    int err;\n\n    err = zip64local_getByte(pzlib_filefunc_def, filestream, &i);\n    x = (uLong)i;\n    if (err == ZIP_OK)\n        err = zip64local_getByte(pzlib_filefunc_def, filestream, &i);\n    x += ((uLong)i) << 8;\n    if (err == ZIP_OK)\n        err = zip64local_getByte(pzlib_filefunc_def, filestream, &i);\n    x += ((uLong)i) << 16;\n    if (err == ZIP_OK)\n        err = zip64local_getByte(pzlib_filefunc_def, filestream, &i);\n    x += ((uLong)i) << 24;\n\n    if (err == ZIP_OK)\n        *pX = x;\n    else\n        *pX = 0;\n    return err;\n}\n\nlocal int zip64local_getLong64 OF((const zlib_filefunc64_32_def * pzlib_filefunc_def, voidpf filestream, ZPOS64_T * pX));\nlocal int zip64local_getLong64(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)\n{\n    ZPOS64_T x;\n    int i = 0;\n    int err;\n\n    err = zip64local_getByte(pzlib_filefunc_def, filestream, &i);\n    x = (ZPOS64_T)i;\n    if (err == ZIP_OK)\n        err = zip64local_getByte(pzlib_filefunc_def, filestream, &i);\n    x += ((ZPOS64_T)i) << 8;\n    if (err == ZIP_OK)\n        err = zip64local_getByte(pzlib_filefunc_def, filestream, &i);\n    x += ((ZPOS64_T)i) << 16;\n    if (err == ZIP_OK)\n        err = zip64local_getByte(pzlib_filefunc_def, filestream, &i);\n    x += ((ZPOS64_T)i) << 24;\n    if (err == ZIP_OK)\n        err = zip64local_getByte(pzlib_filefunc_def, filestream, &i);\n    x += ((ZPOS64_T)i) << 32;\n    if (err == ZIP_OK)\n        err = zip64local_getByte(pzlib_filefunc_def, filestream, &i);\n    x += ((ZPOS64_T)i) << 40;\n    if (err == ZIP_OK)\n        err = zip64local_getByte(pzlib_filefunc_def, filestream, &i);\n    x += ((ZPOS64_T)i) << 48;\n    if (err == ZIP_OK)\n        err = zip64local_getByte(pzlib_filefunc_def, filestream, &i);\n    x += ((ZPOS64_T)i) << 56;\n\n    if (err == ZIP_OK)\n        *pX = x;\n    else\n        *pX = 0;\n\n    return err;\n}\n\n/* Gets the amount of bytes left to write to the current disk for spanning archives */\nlocal int zipGetDiskSizeAvailable OF((zipFile file, ZPOS64_T * size_available));\nlocal int zipGetDiskSizeAvailable(zipFile file, ZPOS64_T *size_available)\n{\n    zip64_internal *zi;\n    ZPOS64_T current_disk_size;\n\n    zi = (zip64_internal *)file;\n    ZSEEK64(zi->z_filefunc, zi->filestream, 0, ZLIB_FILEFUNC_SEEK_END);\n    current_disk_size = ZTELL64(zi->z_filefunc, zi->filestream);\n    *size_available = zi->disk_size - current_disk_size;\n    return ZIP_OK;\n}\n\n/* Goes to a specific disk number for spanning archives */\nlocal int zipGoToSpecificDisk OF((zipFile file, int number_disk, int open_existing));\nlocal int zipGoToSpecificDisk(zipFile file, int number_disk, int open_existing)\n{\n    zip64_internal *zi;\n    int err = ZIP_OK;\n\n    zi = (zip64_internal *)file;\n    if (zi->disk_size == 0)\n        return err;\n\n    if ((zi->filestream != NULL) && (zi->filestream != zi->filestream_with_CD))\n        ZCLOSE64(zi->z_filefunc, zi->filestream);\n\n    zi->filestream = ZOPENDISK64(zi->z_filefunc, zi->filestream_with_CD, number_disk, (open_existing == 1) ?\n                                 (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING) :\n                                 (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE));\n\n    if (zi->filestream == NULL)\n        err = ZIP_ERRNO;\n\n    return err;\n}\n\n/* Goes to the first disk in a spanned archive */\nlocal int zipGoToFirstDisk OF((zipFile file));\nlocal int zipGoToFirstDisk(zipFile file)\n{\n    zip64_internal *zi;\n    int number_disk_next;\n    int err = ZIP_OK;\n\n    zi = (zip64_internal *)file;\n\n    if (zi->disk_size == 0)\n        return err;\n    number_disk_next = 0;\n    if (zi->number_disk_with_CD > 0)\n        number_disk_next = (int)zi->number_disk_with_CD - 1;\n    err = zipGoToSpecificDisk(file, number_disk_next, (zi->append == APPEND_STATUS_ADDINZIP));\n    if ((err == ZIP_ERRNO) && (zi->append == APPEND_STATUS_ADDINZIP))\n        err = zipGoToSpecificDisk(file, number_disk_next, 0);\n    if (err == ZIP_OK)\n        zi->number_disk = number_disk_next;\n    ZSEEK64(zi->z_filefunc, zi->filestream, 0, ZLIB_FILEFUNC_SEEK_END);\n    return err;\n}\n\n/* Goes to the next disk in a spanned archive */\nlocal int zipGoToNextDisk OF((zipFile file));\nlocal int zipGoToNextDisk(zipFile file)\n{\n    zip64_internal *zi;\n    ZPOS64_T size_available_in_disk;\n    int err = ZIP_OK;\n    int number_disk_next;\n\n    zi = (zip64_internal *)file;\n\n    if (zi->disk_size == 0)\n        return err;\n\n    number_disk_next = (int)zi->number_disk + 1;\n\n    do {\n        err = zipGoToSpecificDisk(file, number_disk_next, (zi->append == APPEND_STATUS_ADDINZIP));\n        if ((err == ZIP_ERRNO) && (zi->append == APPEND_STATUS_ADDINZIP))\n            err = zipGoToSpecificDisk(file, number_disk_next, 0);\n        if (err != ZIP_OK)\n            break;\n        err = zipGetDiskSizeAvailable(file, &size_available_in_disk);\n        if (err != ZIP_OK)\n            break;\n        zi->number_disk = number_disk_next;\n        zi->number_disk_with_CD = zi->number_disk + 1;\n\n        number_disk_next += 1;\n    } while (size_available_in_disk <= 0);\n\n    return err;\n}\n\n/* Locate the Central directory of a zipfile (at the end, just before the global comment) */\nlocal ZPOS64_T zip64local_SearchCentralDir OF((const zlib_filefunc64_32_def * pzlib_filefunc_def, voidpf filestream));\nlocal ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream)\n{\n    unsigned char *buf;\n    ZPOS64_T file_size;\n    ZPOS64_T back_read = 4;\n    ZPOS64_T max_back = 0xffff; /* maximum size of global comment */\n    ZPOS64_T pos_found = 0;\n    uLong read_size;\n    ZPOS64_T read_pos;\n    int i;\n\n    buf = (unsigned char *)ALLOC(BUFREADCOMMENT + 4);\n    if (buf == NULL)\n        return 0;\n\n    if (ZSEEK64(*pzlib_filefunc_def, filestream, 0, ZLIB_FILEFUNC_SEEK_END) != 0) {\n        TRYFREE(buf);\n        return 0;\n    }\n\n    file_size = ZTELL64(*pzlib_filefunc_def, filestream);\n\n    if (max_back > file_size)\n        max_back = file_size;\n\n    while (back_read < max_back) {\n        if (back_read + BUFREADCOMMENT > max_back)\n            back_read = max_back;\n        else\n            back_read += BUFREADCOMMENT;\n\n        read_pos = file_size - back_read;\n        read_size = ((BUFREADCOMMENT + 4) < (file_size - read_pos)) ?\n                    (BUFREADCOMMENT + 4) : (uLong)(file_size - read_pos);\n\n        if (ZSEEK64(*pzlib_filefunc_def, filestream, read_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)\n            break;\n        if (ZREAD64(*pzlib_filefunc_def, filestream, buf, read_size) != read_size)\n            break;\n\n        for (i = (int)read_size - 3; (i--) > 0; )\n            if ((*(buf + i)) == (ENDHEADERMAGIC & 0xff) &&\n                (*(buf + i + 1)) == (ENDHEADERMAGIC >> 8 & 0xff) &&\n                (*(buf + i + 2)) == (ENDHEADERMAGIC >> 16 & 0xff) &&\n                (*(buf + i + 3)) == (ENDHEADERMAGIC >> 24 & 0xff)) {\n                pos_found = read_pos + i;\n                break;\n            }\n\n        if (pos_found != 0)\n            break;\n    }\n    TRYFREE(buf);\n    return pos_found;\n}\n\n/* Locate the Central directory 64 of a zipfile (at the end, just before the global comment) */\nlocal ZPOS64_T zip64local_SearchCentralDir64 OF((const zlib_filefunc64_32_def * pzlib_filefunc_def, voidpf filestream,\n                                                 const ZPOS64_T endcentraloffset));\nlocal ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def *pzlib_filefunc_def, voidpf filestream,\n                                             const ZPOS64_T endcentraloffset)\n{\n    ZPOS64_T offset;\n    uLong uL;\n\n    /* Zip64 end of central directory locator */\n    if (ZSEEK64(*pzlib_filefunc_def, filestream, endcentraloffset - SIZECENTRALHEADERLOCATOR, ZLIB_FILEFUNC_SEEK_SET) != 0)\n        return 0;\n\n    /* read locator signature */\n    if (zip64local_getLong(pzlib_filefunc_def, filestream, &uL) != ZIP_OK)\n        return 0;\n    if (uL != ZIP64ENDLOCHEADERMAGIC)\n        return 0;\n    /* number of the disk with the start of the zip64 end of  central directory */\n    if (zip64local_getLong(pzlib_filefunc_def, filestream, &uL) != ZIP_OK)\n        return 0;\n    /* relative offset of the zip64 end of central directory record */\n    if (zip64local_getLong64(pzlib_filefunc_def, filestream, &offset) != ZIP_OK)\n        return 0;\n    /* total number of disks */\n    if (zip64local_getLong(pzlib_filefunc_def, filestream, &uL) != ZIP_OK)\n        return 0;\n    /* Goto end of central directory record */\n    if (ZSEEK64(*pzlib_filefunc_def, filestream, offset, ZLIB_FILEFUNC_SEEK_SET) != 0)\n        return 0;\n    /* the signature */\n    if (zip64local_getLong(pzlib_filefunc_def, filestream, &uL) != ZIP_OK)\n        return 0;\n    if (uL != ZIP64ENDHEADERMAGIC)\n        return 0;\n\n    return offset;\n}\n\nextern zipFile ZEXPORT zipOpen4(const void *pathname, int append, ZPOS64_T disk_size, zipcharpc *globalcomment,\n                                zlib_filefunc64_32_def *pzlib_filefunc64_32_def)\n{\n    zip64_internal ziinit;\n    zip64_internal *zi;\n#ifndef NO_ADDFILEINEXISTINGZIP\n    ZPOS64_T byte_before_the_zipfile;   /* byte before the zipfile, (>0 for sfx)*/\n    ZPOS64_T size_central_dir = 0;          /* size of the central directory  */\n    ZPOS64_T offset_central_dir = 0;        /* offset of start of central directory */\n    ZPOS64_T number_entry_CD = 0;           /* total number of entries in the central dir */\n    ZPOS64_T number_entry;\n    ZPOS64_T central_pos;\n    ZPOS64_T size_central_dir_to_read;\n    uLong uL;\n    uLong size_comment = 0;\n    size_t buf_size = SIZEDATA_INDATABLOCK;\n    void *buf_read;\n#endif\n    int err = ZIP_OK;\n    int mode;\n\n    ziinit.z_filefunc.zseek32_file = NULL;\n    ziinit.z_filefunc.ztell32_file = NULL;\n    if (pzlib_filefunc64_32_def == NULL)\n        fill_fopen64_filefunc(&ziinit.z_filefunc.zfile_func64);\n    else\n        ziinit.z_filefunc = *pzlib_filefunc64_32_def;\n\n    if (append == APPEND_STATUS_CREATE)\n        mode = (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE);\n    else\n        mode = (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING);\n\n    ziinit.filestream = ZOPEN64(ziinit.z_filefunc, pathname, mode);\n    if (ziinit.filestream == NULL)\n        return NULL;\n\n    if (append == APPEND_STATUS_CREATEAFTER) {\n        /* Don't support spanning ZIP with APPEND_STATUS_CREATEAFTER */\n        if (disk_size > 0)\n            return NULL;\n\n        ZSEEK64(ziinit.z_filefunc, ziinit.filestream, 0, SEEK_END);\n    }\n\n    ziinit.filestream_with_CD = ziinit.filestream;\n    ziinit.append = append;\n    ziinit.number_disk = 0;\n    ziinit.number_disk_with_CD = 0;\n    ziinit.disk_size = disk_size;\n    ziinit.begin_pos = ZTELL64(ziinit.z_filefunc, ziinit.filestream);\n    ziinit.in_opened_file_inzip = 0;\n    ziinit.ci.stream_initialised = 0;\n    ziinit.number_entry = 0;\n    ziinit.add_position_when_writting_offset = 0;\n    init_linkedlist(&(ziinit.central_dir));\n\n    zi = (zip64_internal *)ALLOC(sizeof(zip64_internal));\n    if (zi == NULL) {\n        ZCLOSE64(ziinit.z_filefunc, ziinit.filestream);\n        return NULL;\n    }\n\n#ifndef NO_ADDFILEINEXISTINGZIP\n    /* Add file in a zipfile */\n    ziinit.globalcomment = NULL;\n    if (append == APPEND_STATUS_ADDINZIP) {\n        /* Read and Cache Central Directory Records */\n        central_pos = zip64local_SearchCentralDir(&ziinit.z_filefunc, ziinit.filestream);\n        /* disable to allow appending to empty ZIP archive (must be standard zip, not zip64)\n            if (central_pos == 0)\n                err = ZIP_ERRNO;\n         */\n\n        if (err == ZIP_OK) {\n            /* read end of central directory info */\n            if (ZSEEK64(ziinit.z_filefunc, ziinit.filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)\n                err = ZIP_ERRNO;\n\n            /* the signature, already checked */\n            if (zip64local_getLong(&ziinit.z_filefunc, ziinit.filestream, &uL) != ZIP_OK)\n                err = ZIP_ERRNO;\n            /* number of this disk */\n            if (zip64local_getShort(&ziinit.z_filefunc, ziinit.filestream, &ziinit.number_disk) != ZIP_OK)\n                err = ZIP_ERRNO;\n            /* number of the disk with the start of the central directory */\n            if (zip64local_getShort(&ziinit.z_filefunc, ziinit.filestream, &ziinit.number_disk_with_CD) != ZIP_OK)\n                err = ZIP_ERRNO;\n            /* total number of entries in the central dir on this disk */\n            number_entry = 0;\n            if (zip64local_getShort(&ziinit.z_filefunc, ziinit.filestream, &uL) != ZIP_OK)\n                err = ZIP_ERRNO;\n            else\n                number_entry = uL;\n            /* total number of entries in the central dir */\n            number_entry_CD = 0;\n            if (zip64local_getShort(&ziinit.z_filefunc, ziinit.filestream, &uL) != ZIP_OK)\n                err = ZIP_ERRNO;\n            else\n                number_entry_CD = uL;\n            if (number_entry_CD != number_entry)\n                err = ZIP_BADZIPFILE;\n            /* size of the central directory */\n            size_central_dir = 0;\n            if (zip64local_getLong(&ziinit.z_filefunc, ziinit.filestream, &uL) != ZIP_OK)\n                err = ZIP_ERRNO;\n            else\n                size_central_dir = uL;\n            /* offset of start of central directory with respect to the starting disk number */\n            offset_central_dir = 0;\n            if (zip64local_getLong(&ziinit.z_filefunc, ziinit.filestream, &uL) != ZIP_OK)\n                err = ZIP_ERRNO;\n            else\n                offset_central_dir = uL;\n            /* zipfile global comment length */\n            if (zip64local_getShort(&ziinit.z_filefunc, ziinit.filestream, &size_comment) != ZIP_OK)\n                err = ZIP_ERRNO;\n\n            if ((err == ZIP_OK) && ((number_entry_CD == 0xffff) || (offset_central_dir == 0xffffffff))) {\n                /* Format should be Zip64, as the central directory or file size is too large */\n                central_pos = zip64local_SearchCentralDir64(&ziinit.z_filefunc, ziinit.filestream, central_pos);\n\n                if (central_pos) {\n                    ZPOS64_T sizeEndOfCentralDirectory;\n\n                    if (ZSEEK64(ziinit.z_filefunc, ziinit.filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)\n                        err = ZIP_ERRNO;\n\n                    /* the signature, already checked */\n                    if (zip64local_getLong(&ziinit.z_filefunc, ziinit.filestream, &uL) != ZIP_OK)\n                        err = ZIP_ERRNO;\n                    /* size of zip64 end of central directory record */\n                    if (zip64local_getLong64(&ziinit.z_filefunc, ziinit.filestream, &sizeEndOfCentralDirectory) != ZIP_OK)\n                        err = ZIP_ERRNO;\n                    /* version made by */\n                    if (zip64local_getShort(&ziinit.z_filefunc, ziinit.filestream, &uL) != ZIP_OK)\n                        err = ZIP_ERRNO;\n                    /* version needed to extract */\n                    if (zip64local_getShort(&ziinit.z_filefunc, ziinit.filestream, &uL) != ZIP_OK)\n                        err = ZIP_ERRNO;\n                    /* number of this disk */\n                    if (zip64local_getLong(&ziinit.z_filefunc, ziinit.filestream, &ziinit.number_disk) != ZIP_OK)\n                        err = ZIP_ERRNO;\n                    /* number of the disk with the start of the central directory */\n                    if (zip64local_getLong(&ziinit.z_filefunc, ziinit.filestream, &ziinit.number_disk_with_CD) != ZIP_OK)\n                        err = ZIP_ERRNO;\n                    /* total number of entries in the central directory on this disk */\n                    if (zip64local_getLong64(&ziinit.z_filefunc, ziinit.filestream, &number_entry) != ZIP_OK)\n                        err = ZIP_ERRNO;\n                    /* total number of entries in the central directory */\n                    if (zip64local_getLong64(&ziinit.z_filefunc, ziinit.filestream, &number_entry_CD) != ZIP_OK)\n                        err = ZIP_ERRNO;\n                    if (number_entry_CD != number_entry)\n                        err = ZIP_BADZIPFILE;\n                    /* size of the central directory */\n                    if (zip64local_getLong64(&ziinit.z_filefunc, ziinit.filestream, &size_central_dir) != ZIP_OK)\n                        err = ZIP_ERRNO;\n                    /* offset of start of central directory with respect to the starting disk number */\n                    if (zip64local_getLong64(&ziinit.z_filefunc, ziinit.filestream, &offset_central_dir) != ZIP_OK)\n                        err = ZIP_ERRNO;\n                } else\n                    err = ZIP_BADZIPFILE;\n            }\n        }\n\n        if ((err == ZIP_OK) && (central_pos < offset_central_dir + size_central_dir))\n            err = ZIP_BADZIPFILE;\n\n        if (err != ZIP_OK) {\n            ZCLOSE64(ziinit.z_filefunc, ziinit.filestream);\n            TRYFREE(zi);\n            return NULL;\n        }\n\n        if (size_comment > 0) {\n            ziinit.globalcomment = (char *)ALLOC(size_comment + 1);\n            if (ziinit.globalcomment) {\n                size_comment = ZREAD64(ziinit.z_filefunc, ziinit.filestream, ziinit.globalcomment, size_comment);\n                ziinit.globalcomment[size_comment] = 0;\n            }\n        }\n\n        byte_before_the_zipfile = central_pos - (offset_central_dir + size_central_dir);\n        ziinit.add_position_when_writting_offset = byte_before_the_zipfile;\n\n        /* Store central directory in memory */\n        size_central_dir_to_read = size_central_dir;\n        buf_size = SIZEDATA_INDATABLOCK;\n        buf_read = (void *)ALLOC(buf_size);\n        if (buf_read == NULL)\n            err = ZIP_INTERNALERROR;\n\n        if (ZSEEK64(ziinit.z_filefunc, ziinit.filestream,\n                    offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0)\n            err = ZIP_ERRNO;\n\n        while ((size_central_dir_to_read > 0) && (err == ZIP_OK)) {\n            ZPOS64_T read_this = SIZEDATA_INDATABLOCK;\n            if (read_this > size_central_dir_to_read)\n                read_this = size_central_dir_to_read;\n\n            if (ZREAD64(ziinit.z_filefunc, ziinit.filestream, buf_read, (uLong)read_this) != read_this)\n                err = ZIP_ERRNO;\n\n            if (err == ZIP_OK)\n                err = add_data_in_datablock(&ziinit.central_dir, buf_read, (uLong)read_this);\n\n            size_central_dir_to_read -= read_this;\n        }\n        TRYFREE(buf_read);\n\n        ziinit.begin_pos = byte_before_the_zipfile;\n        ziinit.number_entry = number_entry_CD;\n\n        if (ZSEEK64(ziinit.z_filefunc, ziinit.filestream,\n                    offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0)\n            err = ZIP_ERRNO;\n    }\n\n    if (globalcomment)\n        *globalcomment = ziinit.globalcomment;\n#endif\n\n    if (err != ZIP_OK) {\n#ifndef NO_ADDFILEINEXISTINGZIP\n        TRYFREE(ziinit.globalcomment);\n#endif\n        TRYFREE(zi);\n        return NULL;\n    }\n\n    *zi = ziinit;\n    zipGoToFirstDisk((zipFile)zi);\n    return (zipFile)zi;\n}\n\nextern zipFile ZEXPORT zipOpen2(const char *pathname, int append, zipcharpc *globalcomment,\n                                zlib_filefunc_def *pzlib_filefunc32_def)\n{\n    if (pzlib_filefunc32_def != NULL) {\n        zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;\n        fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill, pzlib_filefunc32_def);\n        return zipOpen4(pathname, append, 0, globalcomment, &zlib_filefunc64_32_def_fill);\n    }\n    return zipOpen4(pathname, append, 0, globalcomment, NULL);\n}\n\nextern zipFile ZEXPORT zipOpen2_64(const void *pathname, int append, zipcharpc *globalcomment,\n                                   zlib_filefunc64_def *pzlib_filefunc_def)\n{\n    if (pzlib_filefunc_def != NULL) {\n        zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;\n        zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;\n        zlib_filefunc64_32_def_fill.ztell32_file = NULL;\n        zlib_filefunc64_32_def_fill.zseek32_file = NULL;\n        return zipOpen4(pathname, append, 0, globalcomment, &zlib_filefunc64_32_def_fill);\n    }\n    return zipOpen4(pathname, append, 0, globalcomment, NULL);\n}\n\nextern zipFile ZEXPORT zipOpen3(const char *pathname, int append, ZPOS64_T disk_size, zipcharpc *globalcomment,\n                                zlib_filefunc_def *pzlib_filefunc32_def)\n{\n    if (pzlib_filefunc32_def != NULL) {\n        zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;\n        fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill, pzlib_filefunc32_def);\n        return zipOpen4(pathname, append, disk_size, globalcomment, &zlib_filefunc64_32_def_fill);\n    }\n    return zipOpen4(pathname, append, disk_size, globalcomment, NULL);\n}\n\nextern zipFile ZEXPORT zipOpen3_64(const void *pathname, int append, ZPOS64_T disk_size, zipcharpc *globalcomment,\n                                   zlib_filefunc64_def *pzlib_filefunc_def)\n{\n    if (pzlib_filefunc_def != NULL) {\n        zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;\n        zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;\n        zlib_filefunc64_32_def_fill.ztell32_file = NULL;\n        zlib_filefunc64_32_def_fill.zseek32_file = NULL;\n        return zipOpen4(pathname, append, disk_size, globalcomment, &zlib_filefunc64_32_def_fill);\n    }\n    return zipOpen4(pathname, append, disk_size, globalcomment, NULL);\n}\n\nextern zipFile ZEXPORT zipOpen(const char *pathname, int append)\n{\n    return zipOpen3((const void *)pathname, append, 0, NULL, NULL);\n}\n\nextern zipFile ZEXPORT zipOpen64(const void *pathname, int append)\n{\n    return zipOpen3(pathname, append, 0, NULL, NULL);\n}\n\nextern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char *filename, const zip_fileinfo *zipfi,\n                                           const void *extrafield_local, uInt size_extrafield_local, const void *extrafield_global,\n                                           uInt size_extrafield_global, const char *comment, int method, int level, int raw, int windowBits, int memLevel,\n                                           int strategy, const char *password, uLong crcForCrypting, uLong versionMadeBy, uLong flagBase, int zip64)\n{\n    zip64_internal *zi;\n    uInt size_filename;\n    uInt size_comment = 0;\n    uInt i;\n    int err = ZIP_OK;\n    ZPOS64_T size_available;\n    ZPOS64_T size_needed;\n\n#ifdef NOCRYPT\n    (crcForCrypting);\n    if (password != NULL)\n        return ZIP_PARAMERROR;\n#endif\n\n    if (file == NULL)\n        return ZIP_PARAMERROR;\n\n    if ((method != 0) &&\n#ifdef HAVE_BZIP2\n        (method != Z_BZIP2ED) &&\n#endif\n        (method != Z_DEFLATED))\n        return ZIP_PARAMERROR;\n\n    zi = (zip64_internal *)file;\n\n    if (zi->in_opened_file_inzip == 1) {\n        err = zipCloseFileInZip(file);\n        if (err != ZIP_OK)\n            return err;\n    }\n\n    if (filename == NULL)\n        filename = \"-\";\n    if (comment != NULL)\n        size_comment = (uInt)strlen(comment);\n\n    size_filename = (uInt)strlen(filename);\n\n    if (zipfi == NULL)\n        zi->ci.dosDate = 0;\n    else {\n        if (zipfi->dosDate != 0)\n            zi->ci.dosDate = zipfi->dosDate;\n        else\n            zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date);\n    }\n\n    zi->ci.method = method;\n    zi->ci.compression_method = method;\n    zi->ci.crc32 = 0;\n    zi->ci.stream_initialised = 0;\n    zi->ci.pos_in_buffered_data = 0;\n    zi->ci.raw = raw;\n    zi->ci.flag = flagBase;\n    if ((level == 8) || (level == 9))\n        zi->ci.flag |= 2;\n    if (level == 2)\n        zi->ci.flag |= 4;\n    if (level == 1)\n        zi->ci.flag |= 6;\n    if (password != NULL) {\n        zi->ci.flag |= 1;\n#ifdef HAVE_AES\n        zi->ci.method = AES_METHOD;\n#endif\n    }\n\n    if (zi->disk_size > 0) {\n        if ((zi->number_disk == 0) && (zi->number_entry == 0))\n            err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)DISKHEADERMAGIC, 4);\n\n        /* Make sure enough space available on current disk for local header */\n        zipGetDiskSizeAvailable((zipFile)zi, &size_available);\n        size_needed = 30 + size_filename + size_extrafield_local;\n        if (zi->ci.zip64)\n            size_needed += 20;\n#ifdef HAVE_AES\n        if (zi->ci.method == AES_METHOD)\n            size_needed += 11;\n#endif\n        if (size_available < size_needed)\n            zipGoToNextDisk((zipFile)zi);\n    }\n\n    zi->ci.pos_local_header = ZTELL64(zi->z_filefunc, zi->filestream);\n    zi->ci.size_comment = size_comment;\n    zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global;\n    zi->ci.size_centralextra = size_extrafield_global;\n    zi->ci.size_centralextrafree = 32; /* Extra space reserved for ZIP64 extra info */\n#ifdef HAVE_AES\n    if (zi->ci.method == AES_METHOD)\n        zi->ci.size_centralextrafree += 11; /* Extra space reserved for AES extra info */\n#endif\n    zi->ci.central_header = (char *)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralextrafree + size_comment);\n    if (zi->ci.central_header == NULL)\n        return ZIP_INTERNALERROR;\n    \n    zi->ci.number_disk = zi->number_disk;\n\n    /* Write central directory header */\n    zip64local_putValue_inmemory(zi->ci.central_header, (uLong)CENTRALHEADERMAGIC, 4);\n    zip64local_putValue_inmemory(zi->ci.central_header + 4, (uLong)versionMadeBy, 2);\n    zip64local_putValue_inmemory(zi->ci.central_header + 6, (uLong)20, 2);\n    zip64local_putValue_inmemory(zi->ci.central_header + 8, (uLong)zi->ci.flag, 2);\n    zip64local_putValue_inmemory(zi->ci.central_header + 10, (uLong)zi->ci.method, 2);\n    zip64local_putValue_inmemory(zi->ci.central_header + 12, (uLong)zi->ci.dosDate, 4);\n    zip64local_putValue_inmemory(zi->ci.central_header + 16, (uLong)0, 4); /*crc*/\n    zip64local_putValue_inmemory(zi->ci.central_header + 20, (uLong)0, 4); /*compr size*/\n    zip64local_putValue_inmemory(zi->ci.central_header + 24, (uLong)0, 4); /*uncompr size*/\n    zip64local_putValue_inmemory(zi->ci.central_header + 28, (uLong)size_filename, 2);\n    zip64local_putValue_inmemory(zi->ci.central_header + 30, (uLong)size_extrafield_global, 2);\n    zip64local_putValue_inmemory(zi->ci.central_header + 32, (uLong)size_comment, 2);\n    zip64local_putValue_inmemory(zi->ci.central_header + 34, (uLong)zi->ci.number_disk, 2); /*disk nm start*/\n\n    if (zipfi == NULL)\n        zip64local_putValue_inmemory(zi->ci.central_header + 36, (uLong)0, 2);\n    else\n        zip64local_putValue_inmemory(zi->ci.central_header + 36, (uLong)zipfi->internal_fa, 2);\n    if (zipfi == NULL)\n        zip64local_putValue_inmemory(zi->ci.central_header + 38, (uLong)0, 4);\n    else\n        zip64local_putValue_inmemory(zi->ci.central_header + 38, (uLong)zipfi->external_fa, 4);\n    if (zi->ci.pos_local_header >= 0xffffffff)\n        zip64local_putValue_inmemory(zi->ci.central_header + 42, (uLong)0xffffffff, 4);\n    else\n        zip64local_putValue_inmemory(zi->ci.central_header + 42,\n                                     (uLong)zi->ci.pos_local_header - zi->add_position_when_writting_offset, 4);\n\n    for (i = 0; i < size_filename; i++)\n        zi->ci.central_header[SIZECENTRALHEADER + i] = filename[i];\n    for (i = 0; i < size_extrafield_global; i++)\n        zi->ci.central_header[SIZECENTRALHEADER + size_filename + i] =\n            ((const char *)extrafield_global)[i];\n    /* Store comment at the end for later repositioning */\n    for (i = 0; i < size_comment; i++)\n        zi->ci.central_header[zi->ci.size_centralheader +\n                              zi->ci.size_centralextrafree + i] = comment[i];\n\n    if (zi->ci.central_header == NULL)\n        return ZIP_INTERNALERROR;\n\n    zi->ci.zip64 = zip64;\n    zi->ci.total_compressed = 0;\n    zi->ci.total_uncompressed = 0;\n    zi->ci.pos_zip64extrainfo = 0;\n\n    /* Write the local header */\n    err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)LOCALHEADERMAGIC, 4);\n\n    if (err == ZIP_OK) {\n        if (zi->ci.zip64)\n            err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)45, 2); /* version needed to extract */\n        else\n            err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)20, 2); /* version needed to extract */\n    }\n    if (err == ZIP_OK)\n        err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)zi->ci.flag, 2);\n    if (err == ZIP_OK)\n        err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)zi->ci.method, 2);\n    if (err == ZIP_OK)\n        err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)zi->ci.dosDate, 4);\n\n    /* CRC & compressed size & uncompressed size will be filled in later and rewritten later */\n\n    if (err == ZIP_OK)\n        err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)0, 4); /* crc 32, unknown */\n    if (err == ZIP_OK) {\n        if (zi->ci.zip64)\n            err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)0xFFFFFFFF, 4); /* compressed size, unknown */\n        else\n            err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)0, 4); /* compressed size, unknown */\n    }\n    if (err == ZIP_OK) {\n        if (zi->ci.zip64) /* uncompressed size, unknown */\n            err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)0xFFFFFFFF, 4);\n        else /* uncompressed size, unknown */\n            err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)0, 4);\n    }\n    if (err == ZIP_OK)\n        err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)size_filename, 2);\n    if (err == ZIP_OK) {\n        ZPOS64_T size_extrafield = size_extrafield_local;\n        if (zi->ci.zip64)\n            size_extrafield += 20;\n#ifdef HAVE_AES\n        if (zi->ci.method == AES_METHOD)\n            size_extrafield += 11;\n#endif\n        err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)size_extrafield, 2);\n    }\n    if ((err == ZIP_OK) && (size_filename > 0)) {\n        if (ZWRITE64(zi->z_filefunc, zi->filestream, filename, size_filename) != size_filename)\n            err = ZIP_ERRNO;\n    }\n    if ((err == ZIP_OK) && (size_extrafield_local > 0)) {\n        if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local)\n            err = ZIP_ERRNO;\n    }\n\n    /* Write the Zip64 extended info */\n    if ((err == ZIP_OK) && (zi->ci.zip64)) {\n        short headerid = 1;\n        short datasize = 16;\n        ZPOS64_T compressed_size = 0;\n        ZPOS64_T uncompressed_size = 0;\n\n        /* Remember position of Zip64 extended info for the local file header.\n           (needed when we update size after done with file) */\n        zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc, zi->filestream);\n\n        err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)headerid, 2);\n        err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)datasize, 2);\n\n        err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)uncompressed_size, 8);\n        err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)compressed_size, 8);\n    }\n#ifdef HAVE_AES\n    /* Write the AES extended info */\n    if ((err == ZIP_OK) && (zi->ci.method == AES_METHOD)) {\n        int headerid = 0x9901;\n        short datasize = 7;\n\n        err = zip64local_putValue(&zi->z_filefunc, zi->filestream, headerid, 2);\n        err = zip64local_putValue(&zi->z_filefunc, zi->filestream, datasize, 2);\n\n        err = zip64local_putValue(&zi->z_filefunc, zi->filestream, AES_VERSION, 2);\n        err = zip64local_putValue(&zi->z_filefunc, zi->filestream, 'A', 1);\n        err = zip64local_putValue(&zi->z_filefunc, zi->filestream, 'E', 1);\n        err = zip64local_putValue(&zi->z_filefunc, zi->filestream, AES_ENCRYPTIONMODE, 1);\n        err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->ci.compression_method, 2);\n    }\n#endif\n\n#ifdef HAVE_BZIP2\n    zi->ci.bstream.avail_in = (uInt)0;\n    zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;\n    zi->ci.bstream.next_out = (char *)zi->ci.buffered_data;\n    zi->ci.bstream.total_in_hi32 = 0;\n    zi->ci.bstream.total_in_lo32 = 0;\n    zi->ci.bstream.total_out_hi32 = 0;\n    zi->ci.bstream.total_out_lo32 = 0;\n#endif\n\n    zi->ci.stream.avail_in = (uInt)0;\n    zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;\n    zi->ci.stream.next_out = zi->ci.buffered_data;\n    zi->ci.stream.total_in = 0;\n    zi->ci.stream.total_out = 0;\n    zi->ci.stream.data_type = Z_BINARY;\n\n    if ((err == ZIP_OK) && (!zi->ci.raw)) {\n        if (method == Z_DEFLATED) {\n            zi->ci.stream.zalloc = (alloc_func)0;\n            zi->ci.stream.zfree = (free_func)0;\n            zi->ci.stream.opaque = (voidpf)zi;\n\n            if (windowBits > 0)\n                windowBits = -windowBits;\n\n            err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy);\n\n            if (err == Z_OK)\n                zi->ci.stream_initialised = Z_DEFLATED;\n        } else if (method == Z_BZIP2ED) {\n#ifdef HAVE_BZIP2\n            zi->ci.bstream.bzalloc = 0;\n            zi->ci.bstream.bzfree = 0;\n            zi->ci.bstream.opaque = (voidpf)0;\n\n            err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0, 35);\n            if (err == BZ_OK)\n                zi->ci.stream_initialised = Z_BZIP2ED;\n#endif\n        }\n    }\n\n#ifndef NOCRYPT\n    zi->ci.crypt_header_size = 0;\n    if ((err == Z_OK) && ((zi->ci.flag & 1) != 0)) {\n#ifdef HAVE_AES\n        if (zi->ci.method == AES_METHOD) {\n            unsigned char passverify[AES_PWVERIFYSIZE];\n            unsigned char saltvalue[AES_MAXSALTLENGTH];\n            uInt saltlength;\n\n            if ((AES_ENCRYPTIONMODE < 1) || (AES_ENCRYPTIONMODE > 3))\n                return Z_ERRNO;\n\n            saltlength = SALT_LENGTH(AES_ENCRYPTIONMODE);\n\n            prng_init(entropy_fun, zi->ci.aes_rng);\n            prng_rand(saltvalue, saltlength, zi->ci.aes_rng);\n            prng_end(zi->ci.aes_rng);\n\n            fcrypt_init(AES_ENCRYPTIONMODE, (unsigned char *)password, (unsigned int)strlen(password), saltvalue, passverify, &zi->ci.aes_ctx);\n\n            if (ZWRITE64(zi->z_filefunc, zi->filestream, saltvalue, saltlength) != saltlength)\n                err = ZIP_ERRNO;\n            if (ZWRITE64(zi->z_filefunc, zi->filestream, passverify, AES_PWVERIFYSIZE) != AES_PWVERIFYSIZE)\n                err = ZIP_ERRNO;\n\n            zi->ci.crypt_header_size = saltlength + AES_PWVERIFYSIZE + AES_AUTHCODESIZE;\n        } else\n#endif\n        {\n            unsigned char bufHead[RAND_HEAD_LEN];\n            unsigned int sizeHead;\n\n            zi->ci.pcrc_32_tab = (const unsigned long *)get_crc_table();\n            /*init_keys(password, zi->ci.keys, zi->ci.pcrc_32_tab);*/\n\n            sizeHead = crypthead(password, bufHead, RAND_HEAD_LEN, zi->ci.keys, zi->ci.pcrc_32_tab, crcForCrypting);\n            zi->ci.crypt_header_size = sizeHead;\n\n            if (ZWRITE64(zi->z_filefunc, zi->filestream, bufHead, sizeHead) != sizeHead)\n                err = ZIP_ERRNO;\n        }\n    }\n#endif\n\n    if (err == Z_OK)\n        zi->in_opened_file_inzip = 1;\n    return err;\n}\n\nextern int ZEXPORT zipOpenNewFileInZip4(zipFile file, const char *filename, const zip_fileinfo *zipfi,\n                                        const void *extrafield_local, uInt size_extrafield_local, const void *extrafield_global,\n                                        uInt size_extrafield_global, const char *comment, int method, int level, int raw, int windowBits,\n                                        int memLevel, int strategy, const char *password, uLong crcForCrypting, uLong versionMadeBy, uLong flagBase)\n{\n    return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local,\n                                   extrafield_global, size_extrafield_global, comment, method, level, raw, windowBits, memLevel,\n                                   strategy, password, crcForCrypting, versionMadeBy, flagBase, 0);\n}\n\nextern int ZEXPORT zipOpenNewFileInZip3(zipFile file, const char *filename, const zip_fileinfo *zipfi,\n                                        const void *extrafield_local, uInt size_extrafield_local, const void *extrafield_global,\n                                        uInt size_extrafield_global, const char *comment, int method, int level, int raw, int windowBits,\n                                        int memLevel, int strategy, const char *password, uLong crcForCrypting)\n{\n    return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local,\n                                   extrafield_global, size_extrafield_global, comment, method, level, raw, windowBits, memLevel,\n                                   strategy, password, crcForCrypting, VERSIONMADEBY, 0, 0);\n}\n\nextern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char *filename, const zip_fileinfo *zipfi,\n                                           const void *extrafield_local, uInt size_extrafield_local, const void *extrafield_global,\n                                           uInt size_extrafield_global, const char *comment, int method, int level, int raw, int windowBits,\n                                           int memLevel, int strategy, const char *password, uLong crcForCrypting, int zip64)\n{\n    return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local,\n                                   extrafield_global, size_extrafield_global, comment, method, level, raw, windowBits, memLevel, strategy,\n                                   password, crcForCrypting, VERSIONMADEBY, 0, zip64);\n}\n\nextern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char *filename, const zip_fileinfo *zipfi,\n                                        const void *extrafield_local, uInt size_extrafield_local, const void *extrafield_global,\n                                        uInt size_extrafield_global, const char *comment, int method, int level, int raw)\n{\n    return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local,\n                                   extrafield_global, size_extrafield_global, comment, method, level, raw, -MAX_WBITS, DEF_MEM_LEVEL,\n                                   Z_DEFAULT_STRATEGY, NULL, 0, VERSIONMADEBY, 0, 0);\n}\n\nextern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char *filename, const zip_fileinfo *zipfi,\n                                           const void *extrafield_local, uInt size_extrafield_local, const void *extrafield_global,\n                                           uInt size_extrafield_global, const char *comment, int method, int level, int raw, int zip64)\n{\n    return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local,\n                                   extrafield_global, size_extrafield_global, comment, method, level, raw, -MAX_WBITS, DEF_MEM_LEVEL,\n                                   Z_DEFAULT_STRATEGY, NULL, 0, VERSIONMADEBY, 0, zip64);\n}\n\nextern int ZEXPORT zipOpenNewFileInZip64(zipFile file, const char *filename, const zip_fileinfo *zipfi,\n                                         const void *extrafield_local, uInt size_extrafield_local, const void *extrafield_global,\n                                         uInt size_extrafield_global, const char *comment, int method, int level, int zip64)\n{\n    return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local,\n                                   extrafield_global, size_extrafield_global, comment, method, level, 0, -MAX_WBITS, DEF_MEM_LEVEL,\n                                   Z_DEFAULT_STRATEGY, NULL, 0, VERSIONMADEBY, 0, zip64);\n}\n\nextern int ZEXPORT zipOpenNewFileInZip(zipFile file, const char *filename, const zip_fileinfo *zipfi,\n                                       const void *extrafield_local, uInt size_extrafield_local, const void *extrafield_global,\n                                       uInt size_extrafield_global, const char *comment, int method, int level)\n{\n    return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local,\n                                   extrafield_global, size_extrafield_global, comment, method, level, 0, -MAX_WBITS, DEF_MEM_LEVEL,\n                                   Z_DEFAULT_STRATEGY, NULL, 0, VERSIONMADEBY, 0, 0);\n}\n\n/* Flushes the write buffer to disk */\nlocal int zip64FlushWriteBuffer OF((zip64_internal * zi));\nlocal int zip64FlushWriteBuffer(zip64_internal *zi)\n{\n    int err = ZIP_OK;\n    uInt written = 0;\n    uInt total_written = 0;\n    uInt write = 0;\n    uInt max_write = 0;\n    ZPOS64_T size_available = 0;\n\n    if ((zi->ci.flag & 1) != 0) {\n#ifndef NOCRYPT\n#ifdef HAVE_AES\n        if (zi->ci.method == AES_METHOD) {\n            fcrypt_encrypt(zi->ci.buffered_data, zi->ci.pos_in_buffered_data, &zi->ci.aes_ctx);\n        } else\n#endif\n        {\n            uInt i;\n            int t;\n            for (i = 0; i < zi->ci.pos_in_buffered_data; i++)\n                zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i], t);\n        }\n#endif\n    }\n\n    write = zi->ci.pos_in_buffered_data;\n\n    do {\n        max_write = write;\n\n        if (zi->disk_size > 0) {\n            err = zipGetDiskSizeAvailable((zipFile)zi, &size_available);\n            if (err != ZIP_OK)\n                return err;\n\n            if (size_available == 0) {\n                err = zipGoToNextDisk((zipFile)zi);\n                if (err != ZIP_OK)\n                    return err;\n            }\n\n            if (size_available < (ZPOS64_T)max_write)\n                max_write = (uInt)size_available;\n        }\n\n        written = (unsigned int)ZWRITE64(zi->z_filefunc, zi->filestream, zi->ci.buffered_data + total_written, max_write);\n\n        if (ZERROR64(zi->z_filefunc, zi->filestream)) {\n            err = ZIP_ERRNO;\n            break;\n        }\n\n        total_written += written;\n        write -= written;\n    } while (write > 0);\n\n    zi->ci.total_compressed += zi->ci.pos_in_buffered_data;\n\n#ifdef HAVE_BZIP2\n    if (zi->ci.compression_method == Z_BZIP2ED) {\n        zi->ci.total_uncompressed += zi->ci.bstream.total_in_lo32;\n        zi->ci.bstream.total_in_lo32 = 0;\n        zi->ci.bstream.total_in_hi32 = 0;\n    } else\n#endif\n    {\n        zi->ci.total_uncompressed += zi->ci.stream.total_in;\n        zi->ci.stream.total_in = 0;\n    }\n\n    zi->ci.pos_in_buffered_data = 0;\n\n    return err;\n}\n\nextern int ZEXPORT zipWriteInFileInZip(zipFile file, const void *buf, unsigned int len)\n{\n    zip64_internal *zi;\n    int err = ZIP_OK;\n\n    if (file == NULL)\n        return ZIP_PARAMERROR;\n    zi = (zip64_internal *)file;\n\n    if (zi->in_opened_file_inzip == 0)\n        return ZIP_PARAMERROR;\n\n    zi->ci.crc32 = crc32(zi->ci.crc32, buf, (uInt)len);\n\n#ifdef HAVE_BZIP2\n    if ((zi->ci.compression_method == Z_BZIP2ED) && (!zi->ci.raw)) {\n        zi->ci.bstream.next_in = (void *)buf;\n        zi->ci.bstream.avail_in = len;\n        err = BZ_RUN_OK;\n\n        while ((err == BZ_RUN_OK) && (zi->ci.bstream.avail_in > 0)) {\n            if (zi->ci.bstream.avail_out == 0) {\n                if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)\n                    err = ZIP_ERRNO;\n                zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;\n                zi->ci.bstream.next_out = (char *)zi->ci.buffered_data;\n            } else {\n                uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32;\n                uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32;\n\n                err = BZ2_bzCompress(&zi->ci.bstream, BZ_RUN);\n\n                zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo);\n            }\n        }\n\n        if (err == BZ_RUN_OK)\n            err = ZIP_OK;\n    } else\n#endif\n    {\n        zi->ci.stream.next_in = (Bytef *)buf;\n        zi->ci.stream.avail_in = len;\n\n        while ((err == ZIP_OK) && (zi->ci.stream.avail_in > 0)) {\n            if (zi->ci.stream.avail_out == 0) {\n                if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)\n                    err = ZIP_ERRNO;\n                zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;\n                zi->ci.stream.next_out = zi->ci.buffered_data;\n            }\n\n            if (err != ZIP_OK)\n                break;\n\n            if ((zi->ci.compression_method == Z_DEFLATED) && (!zi->ci.raw)) {\n                uLong total_out_before = zi->ci.stream.total_out;\n                err = deflate(&zi->ci.stream, Z_NO_FLUSH);\n                zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - total_out_before);\n            } else {\n                uInt copy_this, i;\n                if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)\n                    copy_this = zi->ci.stream.avail_in;\n                else\n                    copy_this = zi->ci.stream.avail_out;\n\n                for (i = 0; i < copy_this; i++)\n                    *(((char *)zi->ci.stream.next_out) + i) =\n                        *(((const char *)zi->ci.stream.next_in) + i);\n\n                zi->ci.stream.avail_in -= copy_this;\n                zi->ci.stream.avail_out -= copy_this;\n                zi->ci.stream.next_in += copy_this;\n                zi->ci.stream.next_out += copy_this;\n                zi->ci.stream.total_in += copy_this;\n                zi->ci.stream.total_out += copy_this;\n                zi->ci.pos_in_buffered_data += copy_this;\n            }\n        }\n    }\n\n    return err;\n}\n\nextern int ZEXPORT zipCloseFileInZipRaw(zipFile file, uLong uncompressed_size, uLong crc32)\n{\n    return zipCloseFileInZipRaw64(file, uncompressed_size, crc32);\n}\n\nextern int ZEXPORT zipCloseFileInZipRaw64(zipFile file, ZPOS64_T uncompressed_size, uLong crc32)\n{\n    zip64_internal *zi;\n    ZPOS64_T compressed_size;\n    uLong invalidValue = 0xffffffff;\n    uLong i = 0;\n    short datasize = 0;\n    int err = ZIP_OK;\n\n    if (file == NULL)\n        return ZIP_PARAMERROR;\n    zi = (zip64_internal *)file;\n\n    if (zi->in_opened_file_inzip == 0)\n        return ZIP_PARAMERROR;\n    zi->ci.stream.avail_in = 0;\n\n    if (!zi->ci.raw) {\n        if (zi->ci.compression_method == Z_DEFLATED) {\n            while (err == ZIP_OK) {\n                uLong total_out_before;\n                if (zi->ci.stream.avail_out == 0) {\n                    if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)\n                        err = ZIP_ERRNO;\n                    zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;\n                    zi->ci.stream.next_out = zi->ci.buffered_data;\n                }\n                total_out_before = zi->ci.stream.total_out;\n                err = deflate(&zi->ci.stream, Z_FINISH);\n                zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - total_out_before);\n            }\n        } else if (zi->ci.compression_method == Z_BZIP2ED) {\n#ifdef HAVE_BZIP2\n            err = BZ_FINISH_OK;\n            while (err == BZ_FINISH_OK) {\n                uLong total_out_before;\n                if (zi->ci.bstream.avail_out == 0) {\n                    if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)\n                        err = ZIP_ERRNO;\n                    zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;\n                    zi->ci.bstream.next_out = (char *)zi->ci.buffered_data;\n                }\n                total_out_before = zi->ci.bstream.total_out_lo32;\n                err = BZ2_bzCompress(&zi->ci.bstream, BZ_FINISH);\n                if (err == BZ_STREAM_END)\n                    err = Z_STREAM_END;\n                zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - total_out_before);\n            }\n\n            if (err == BZ_FINISH_OK)\n                err = ZIP_OK;\n#endif\n        }\n    }\n\n    if (err == Z_STREAM_END)\n        err = ZIP_OK; /* this is normal */\n\n    if ((zi->ci.pos_in_buffered_data > 0) && (err == ZIP_OK)) {\n        if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)\n            err = ZIP_ERRNO;\n    }\n\n#ifdef HAVE_AES\n    if (zi->ci.method == AES_METHOD) {\n        unsigned char authcode[AES_AUTHCODESIZE];\n\n        fcrypt_end(authcode, &zi->ci.aes_ctx);\n\n        if (ZWRITE64(zi->z_filefunc, zi->filestream, authcode, AES_AUTHCODESIZE) != AES_AUTHCODESIZE)\n            err = ZIP_ERRNO;\n    }\n#endif\n\n    if (!zi->ci.raw) {\n        if (zi->ci.compression_method == Z_DEFLATED) {\n            int tmp_err = deflateEnd(&zi->ci.stream);\n            if (err == ZIP_OK)\n                err = tmp_err;\n            zi->ci.stream_initialised = 0;\n        }\n#ifdef HAVE_BZIP2\n        else if (zi->ci.compression_method == Z_BZIP2ED) {\n            int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream);\n            if (err == ZIP_OK)\n                err = tmperr;\n            zi->ci.stream_initialised = 0;\n        }\n#endif\n\n        crc32 = (uLong)zi->ci.crc32;\n        uncompressed_size = zi->ci.total_uncompressed;\n    }\n\n    compressed_size = zi->ci.total_compressed;\n#ifndef NOCRYPT\n    compressed_size += zi->ci.crypt_header_size;\n#endif\n\n    /* Update current item crc and sizes */\n    if (compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff) {\n        zip64local_putValue_inmemory(zi->ci.central_header + 4, (uLong)45, 2); /* version made by */\n        zip64local_putValue_inmemory(zi->ci.central_header + 6, (uLong)45, 2); /* version needed */\n    }\n    zip64local_putValue_inmemory(zi->ci.central_header + 16, crc32, 4); /* crc */\n    if (compressed_size >= 0xffffffff)\n        zip64local_putValue_inmemory(zi->ci.central_header + 20, invalidValue, 4); /* compr size */\n    else\n        zip64local_putValue_inmemory(zi->ci.central_header + 20, compressed_size, 4); /* compr size */\n    if (zi->ci.stream.data_type == Z_ASCII)\n        zip64local_putValue_inmemory(zi->ci.central_header + 36, (uLong)Z_ASCII, 2); /* internal file attrib */\n    if (uncompressed_size >= 0xffffffff)\n        zip64local_putValue_inmemory(zi->ci.central_header + 24, invalidValue, 4); /* uncompr size */\n    else\n        zip64local_putValue_inmemory(zi->ci.central_header + 24, uncompressed_size, 4); /* uncompr size */\n\n    /* Add ZIP64 extra info field for uncompressed size */\n    if (uncompressed_size >= 0xffffffff)\n        datasize += 8;\n    /* Add ZIP64 extra info field for compressed size */\n    if (compressed_size >= 0xffffffff)\n        datasize += 8;\n    /* Add ZIP64 extra info field for relative offset to local file header of current file */\n    if (zi->ci.pos_local_header >= 0xffffffff)\n        datasize += 8;\n\n    /* Add Extra Information Header for 'ZIP64 information' */\n    if (datasize > 0) {\n        char *p = zi->ci.central_header + zi->ci.size_centralheader;\n\n        if ((uLong)(datasize + 4) > zi->ci.size_centralextrafree)\n            return ZIP_BADZIPFILE;\n\n        zip64local_putValue_inmemory(p, 0x0001, 2);\n        p += 2;\n        zip64local_putValue_inmemory(p, datasize, 2);\n        p += 2;\n\n        if (uncompressed_size >= 0xffffffff) {\n            zip64local_putValue_inmemory(p, uncompressed_size, 8);\n            p += 8;\n        }\n        if (compressed_size >= 0xffffffff) {\n            zip64local_putValue_inmemory(p, compressed_size, 8);\n            p += 8;\n        }\n        if (zi->ci.pos_local_header >= 0xffffffff) {\n            zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8);\n            p += 8;\n        }\n\n        zi->ci.size_centralextrafree -= datasize + 4;\n        zi->ci.size_centralheader += datasize + 4;\n        zi->ci.size_centralextra += datasize + 4;\n\n        zip64local_putValue_inmemory(zi->ci.central_header + 30, (uLong)zi->ci.size_centralextra, 2);\n    }\n\n#ifdef HAVE_AES\n    /* Write the AES extended info */\n    if (zi->ci.method == AES_METHOD) {\n        char *p = zi->ci.central_header + zi->ci.size_centralheader;\n\n        datasize = 7;\n\n        if ((uLong)(datasize + 4) > zi->ci.size_centralextrafree)\n            return ZIP_BADZIPFILE;\n\n        zip64local_putValue_inmemory(p, 0x9901, 2);\n        p += 2;\n        zip64local_putValue_inmemory(p, datasize, 2);\n        p += 2;\n        zip64local_putValue_inmemory(p, AES_VERSION, 2);\n        p += 2;\n        zip64local_putValue_inmemory(p, 'A', 1);\n        p += 1;\n        zip64local_putValue_inmemory(p, 'E', 1);\n        p += 1;\n        zip64local_putValue_inmemory(p, AES_ENCRYPTIONMODE, 1);\n        p += 1;\n        zip64local_putValue_inmemory(p, zi->ci.compression_method, 2);\n        p += 2;\n\n        zi->ci.size_centralextrafree -= datasize + 4;\n        zi->ci.size_centralheader += datasize + 4;\n        zi->ci.size_centralextra += datasize + 4;\n\n        zip64local_putValue_inmemory(zi->ci.central_header + 30, (uLong)zi->ci.size_centralextra, 2);\n    }\n#endif\n    /* Restore comment to correct position */\n    for (i = 0; i < zi->ci.size_comment; i++)\n        zi->ci.central_header[zi->ci.size_centralheader + i] =\n            zi->ci.central_header[zi->ci.size_centralheader + zi->ci.size_centralextrafree + i];\n    zi->ci.size_centralheader += zi->ci.size_comment;\n\n    if (err == ZIP_OK)\n        err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader);\n\n    free(zi->ci.central_header);\n\n    if (err == ZIP_OK) {\n        /* Update the LocalFileHeader with the new values. */\n        ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc, zi->filestream);\n        uLong cur_number_disk = zi->number_disk;\n\n        /* Local file header is stored on previous disk, switch to make edits */\n        if (zi->ci.number_disk != cur_number_disk)\n            err = zipGoToSpecificDisk(file, (int)zi->ci.number_disk, 1);\n\n        if (ZSEEK64(zi->z_filefunc, zi->filestream, zi->ci.pos_local_header + 14, ZLIB_FILEFUNC_SEEK_SET) != 0)\n            err = ZIP_ERRNO;\n        if (err == ZIP_OK)\n            err = zip64local_putValue(&zi->z_filefunc, zi->filestream, crc32, 4); /* crc 32, unknown */\n\n        if (uncompressed_size >= 0xffffffff || compressed_size >= 0xffffffff) {\n            if (zi->ci.pos_zip64extrainfo > 0) {\n                /* Update the size in the ZIP64 extended field. */\n                if (ZSEEK64(zi->z_filefunc, zi->filestream, zi->ci.pos_zip64extrainfo + 4, ZLIB_FILEFUNC_SEEK_SET) != 0)\n                    err = ZIP_ERRNO;\n\n                if (err == ZIP_OK) /* compressed size, unknown */\n                    err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8);\n                if (err == ZIP_OK) /* uncompressed size, unknown */\n                    err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8);\n            } else\n                err = ZIP_BADZIPFILE; /* Caller passed zip64 = 0, so no room for zip64 info -> fatal */\n        } else {\n            if (err == ZIP_OK) /* compressed size, unknown */\n                err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 4);\n            if (err == ZIP_OK) /* uncompressed size, unknown */\n                err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 4);\n        }\n\n        /* Now switch back again to the disk we were on before */\n        if (zi->ci.number_disk != cur_number_disk)\n            err = zipGoToSpecificDisk(file, (int)cur_number_disk, 1);\n\n        if (ZSEEK64(zi->z_filefunc, zi->filestream, cur_pos_inzip, ZLIB_FILEFUNC_SEEK_SET) != 0)\n            err = ZIP_ERRNO;\n    }\n\n    zi->number_entry++;\n    zi->in_opened_file_inzip = 0;\n\n    return err;\n}\n\nextern int ZEXPORT zipCloseFileInZip(zipFile file)\n{\n    return zipCloseFileInZipRaw(file, 0, 0);\n}\n\nextern int ZEXPORT zipClose(zipFile file, const char *global_comment)\n{\n    zip64_internal *zi;\n    int err = 0;\n    uLong size_centraldir = 0;\n    uInt size_global_comment = 0;\n    ZPOS64_T centraldir_pos_inzip;\n    ZPOS64_T pos = 0;\n    uLong write = 0;\n\n    if (file == NULL)\n        return ZIP_PARAMERROR;\n\n    zi = (zip64_internal *)file;\n\n    if (zi->in_opened_file_inzip == 1)\n        err = zipCloseFileInZip(file);\n\n#ifndef NO_ADDFILEINEXISTINGZIP\n    if (global_comment == NULL)\n        global_comment = zi->globalcomment;\n#endif\n\n    if (zi->filestream != zi->filestream_with_CD) {\n        if (ZCLOSE64(zi->z_filefunc, zi->filestream) != 0)\n            if (err == ZIP_OK)\n                err = ZIP_ERRNO;\n        if (zi->disk_size > 0)\n            zi->number_disk_with_CD = zi->number_disk + 1;\n        zi->filestream = zi->filestream_with_CD;\n    }\n\n    centraldir_pos_inzip = ZTELL64(zi->z_filefunc, zi->filestream);\n\n    if (err == ZIP_OK) {\n        linkedlist_datablock_internal *ldi = zi->central_dir.first_block;\n        while (ldi != NULL) {\n            if ((err == ZIP_OK) && (ldi->filled_in_this_block > 0)) {\n                write = ZWRITE64(zi->z_filefunc, zi->filestream, ldi->data, ldi->filled_in_this_block);\n                if (write != ldi->filled_in_this_block)\n                    err = ZIP_ERRNO;\n            }\n\n            size_centraldir += ldi->filled_in_this_block;\n            ldi = ldi->next_datablock;\n        }\n    }\n\n    free_linkedlist(&(zi->central_dir));\n\n    pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;\n\n    /* Write the ZIP64 central directory header */\n    if (pos >= 0xffffffff || zi->number_entry > 0xffff) {\n        ZPOS64_T zip64eocd_pos_inzip = ZTELL64(zi->z_filefunc, zi->filestream);\n        uLong zip64datasize = 44;\n\n        err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)ZIP64ENDHEADERMAGIC, 4);\n\n        /* size of this 'zip64 end of central directory' */\n        if (err == ZIP_OK)\n            err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)zip64datasize, 8);\n        /* version made by */\n        if (err == ZIP_OK)\n            err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)45, 2);\n        /* version needed */\n        if (err == ZIP_OK)\n            err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)45, 2);\n        /* number of this disk */\n        if (err == ZIP_OK)\n            err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)zi->number_disk_with_CD, 4);\n        /* number of the disk with the start of the central directory */\n        if (err == ZIP_OK)\n            err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)zi->number_disk_with_CD, 4);\n        /* total number of entries in the central dir on this disk */\n        if (err == ZIP_OK)\n            err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);\n        /* total number of entries in the central dir */\n        if (err == ZIP_OK)\n            err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);\n        /* size of the central directory */\n        if (err == ZIP_OK)\n            err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)size_centraldir, 8);\n\n        if (err == ZIP_OK) {\n            /* offset of start of central directory with respect to the starting disk number */\n            ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;\n            err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)pos, 8);\n        }\n        if (err == ZIP_OK)\n            err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)ZIP64ENDLOCHEADERMAGIC, 4);\n\n        /* number of the disk with the start of the central directory */\n        if (err == ZIP_OK)\n            err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)zi->number_disk_with_CD, 4);\n        /*relative offset to the Zip64EndOfCentralDirectory */\n        if (err == ZIP_OK) {\n            ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writting_offset;\n            err = zip64local_putValue(&zi->z_filefunc, zi->filestream, pos, 8);\n        }\n        /* number of the disk with the start of the central directory */\n        if (err == ZIP_OK)\n            err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)zi->number_disk_with_CD + 1, 4);\n    }\n\n    /* Write the central directory header */\n\n    /* signature */\n    if (err == ZIP_OK)\n        err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)ENDHEADERMAGIC, 4);\n    /* number of this disk */\n    if (err == ZIP_OK)\n        err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)zi->number_disk_with_CD, 2);\n    /* number of the disk with the start of the central directory */\n    if (err == ZIP_OK)\n        err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)zi->number_disk_with_CD, 2);\n    /* total number of entries in the central dir on this disk */\n    if (err == ZIP_OK) {\n        if (zi->number_entry >= 0xffff)\n            err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)0xffff, 2); /* use value in ZIP64 record */\n        else\n            err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)zi->number_entry, 2);\n    }\n    /* total number of entries in the central dir */\n    if (err == ZIP_OK) {\n        if (zi->number_entry >= 0xffff)\n            err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)0xffff, 2); /* use value in ZIP64 record */\n        else\n            err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)zi->number_entry, 2);\n    }\n    /* size of the central directory */\n    if (err == ZIP_OK)\n        err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)size_centraldir, 4);\n    /* offset of start of central directory with respect to the starting disk number */\n    if (err == ZIP_OK) {\n        ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;\n        if (pos >= 0xffffffff)\n            err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)0xffffffff, 4);\n        else\n            err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)pos, 4);\n    }\n\n    /* Write global comment */\n\n    if (global_comment != NULL)\n        size_global_comment = (uInt)strlen(global_comment);\n    if (err == ZIP_OK)\n        err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)size_global_comment, 2);\n    if (err == ZIP_OK && size_global_comment > 0) {\n        if (ZWRITE64(zi->z_filefunc, zi->filestream, global_comment, size_global_comment) != size_global_comment)\n            err = ZIP_ERRNO;\n    }\n\n    if ((ZCLOSE64(zi->z_filefunc, zi->filestream) != 0) && (err == ZIP_OK))\n        err = ZIP_ERRNO;\n\n#ifndef NO_ADDFILEINEXISTINGZIP\n    TRYFREE(zi->globalcomment);\n#endif\n    TRYFREE(zi);\n\n    return err;\n}\n\n"
  },
  {
    "path": "plugins/cordova-plugin-zip/src/ios/minizip/zip.h",
    "content": "/* zip.h -- IO on .zip files using zlib\n   Version 1.1, February 14h, 2010\n   part of the MiniZip project\n\n   Copyright (C) 1998-2010 Gilles Vollant\n     http://www.winimage.com/zLibDll/minizip.html\n   Modifications for Zip64 support\n     Copyright (C) 2009-2010 Mathias Svensson\n     http://result42.com\n\n   This program is distributed under the terms of the same license as zlib.\n   See the accompanying LICENSE file for the full text of the license.\n*/\n\n#ifndef _ZIP_H\n#define _ZIP_H\n\n#define HAVE_AES\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#ifndef _ZLIB_H\n#  include \"zlib.h\"\n#endif\n\n#ifndef _ZLIBIOAPI_H\n#  include \"ioapi.h\"\n#endif\n\n#ifdef HAVE_BZIP2\n#  include \"bzlib.h\"\n#endif\n\n#define Z_BZIP2ED 12\n\n#if defined(STRICTZIP) || defined(STRICTZIPUNZIP)\n/* like the STRICT of WIN32, we define a pointer that cannot be converted\n    from (void*) without cast */\ntypedef struct TagzipFile__ { int unused; } zipFile__;\ntypedef zipFile__ *zipFile;\n#else\ntypedef voidp zipFile;\n#endif\n\n#define ZIP_OK                          (0)\n#define ZIP_EOF                         (0)\n#define ZIP_ERRNO                       (Z_ERRNO)\n#define ZIP_PARAMERROR                  (-102)\n#define ZIP_BADZIPFILE                  (-103)\n#define ZIP_INTERNALERROR               (-104)\n\n#ifndef DEF_MEM_LEVEL\n#  if MAX_MEM_LEVEL >= 8\n#    define DEF_MEM_LEVEL 8\n#  else\n#    define DEF_MEM_LEVEL  MAX_MEM_LEVEL\n#  endif\n#endif\n/* default memLevel */\n\n/* tm_zip contain date/time info */\ntypedef struct tm_zip_s\n{\n    uInt tm_sec;                /* seconds after the minute - [0,59] */\n    uInt tm_min;                /* minutes after the hour - [0,59] */\n    uInt tm_hour;               /* hours since midnight - [0,23] */\n    uInt tm_mday;               /* day of the month - [1,31] */\n    uInt tm_mon;                /* months since January - [0,11] */\n    uInt tm_year;               /* years - [1980..2044] */\n} tm_zip;\n\ntypedef struct\n{\n    tm_zip      tmz_date;       /* date in understandable format           */\n    uLong       dosDate;        /* if dos_date == 0, tmu_date is used      */\n    uLong       internal_fa;    /* internal file attributes        2 bytes */\n    uLong       external_fa;    /* external file attributes        4 bytes */\n} zip_fileinfo;\n\ntypedef const char* zipcharpc;\n\n#define APPEND_STATUS_CREATE        (0)\n#define APPEND_STATUS_CREATEAFTER   (1)\n#define APPEND_STATUS_ADDINZIP      (2)\n\n/***************************************************************************/\n/* Writing a zip file */\n\nextern zipFile ZEXPORT zipOpen OF((const char *pathname, int append));\nextern zipFile ZEXPORT zipOpen64 OF((const void *pathname, int append));\n/* Create a zipfile.\n\n   pathname should contain the full pathname (by example, on a Windows XP computer \n      \"c:\\\\zlib\\\\zlib113.zip\" or on an Unix computer \"zlib/zlib113.zip\". \n\n   return NULL if zipfile cannot be opened\n   return zipFile handle if no error\n\n   If the file pathname exist and append == APPEND_STATUS_CREATEAFTER, the zip\n   will be created at the end of the file. (useful if the file contain a self extractor code)\n   If the file pathname exist and append == APPEND_STATUS_ADDINZIP, we will add files in existing \n   zip (be sure you don't add file that doesn't exist)\n\n   NOTE: There is no delete function into a zipfile. If you want delete file into a zipfile, \n   you must open a zipfile, and create another. Of course, you can use RAW reading and writing to copy\n   the file you did not want delete. */\n\nextern zipFile ZEXPORT zipOpen2 OF((const char *pathname, int append, zipcharpc* globalcomment, \n    zlib_filefunc_def* pzlib_filefunc_def));\n\nextern zipFile ZEXPORT zipOpen2_64 OF((const void *pathname, int append, zipcharpc* globalcomment, \n    zlib_filefunc64_def* pzlib_filefunc_def));\n\nextern zipFile ZEXPORT zipOpen3 OF((const char *pathname, int append, ZPOS64_T disk_size, \n    zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc_def));\n/* Same as zipOpen2 but allows specification of spanned zip size */\n\nextern zipFile ZEXPORT zipOpen3_64 OF((const void *pathname, int append, ZPOS64_T disk_size, \n    zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def));\n\nextern int ZEXPORT zipOpenNewFileInZip OF((zipFile file, const char* filename, const zip_fileinfo* zipfi,\n    const void* extrafield_local, uInt size_extrafield_local, const void* extrafield_global, \n    uInt size_extrafield_global, const char* comment, int method, int level));\n/* Open a file in the ZIP for writing.\n\n   filename : the filename in zip (if NULL, '-' without quote will be used\n   *zipfi contain supplemental information\n   extrafield_local buffer to store the local header extra field data, can be NULL\n   size_extrafield_local size of extrafield_local buffer\n   extrafield_global buffer to store the global header extra field data, can be NULL\n   size_extrafield_global size of extrafield_local buffer\n   comment buffer for comment string\n   method contain the compression method (0 for store, Z_DEFLATED for deflate)\n   level contain the level of compression (can be Z_DEFAULT_COMPRESSION)\n   zip64 is set to 1 if a zip64 extended information block should be added to the local file header.\n   this MUST be '1' if the uncompressed size is >= 0xffffffff. */\n\nextern int ZEXPORT zipOpenNewFileInZip64 OF((zipFile file, const char* filename, const zip_fileinfo* zipfi,\n    const void* extrafield_local, uInt size_extrafield_local, const void* extrafield_global, \n    uInt size_extrafield_global, const char* comment, int method, int level, int zip64));\n/* Same as zipOpenNewFileInZip with zip64 support */\n\nextern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file, const char* filename, const zip_fileinfo* zipfi,\n    const void* extrafield_local, uInt size_extrafield_local, const void* extrafield_global, \n    uInt size_extrafield_global, const char* comment, int method, int level, int raw));\n/* Same as zipOpenNewFileInZip, except if raw=1, we write raw file */\n\nextern int ZEXPORT zipOpenNewFileInZip2_64 OF((zipFile file, const char* filename, const zip_fileinfo* zipfi,\n    const void* extrafield_local, uInt size_extrafield_local, const void* extrafield_global, \n    uInt size_extrafield_global, const char* comment, int method, int level, int raw, int zip64));\n/* Same as zipOpenNewFileInZip3 with zip64 support */\n\nextern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file, const char* filename, const zip_fileinfo* zipfi,\n    const void* extrafield_local, uInt size_extrafield_local, const void* extrafield_global, \n    uInt size_extrafield_global, const char* comment, int method, int level, int raw, int windowBits, int memLevel, \n    int strategy, const char* password, uLong crcForCrypting));\n/* Same as zipOpenNewFileInZip2, except\n    windowBits, memLevel, strategy : see parameter strategy in deflateInit2\n    password : crypting password (NULL for no crypting)\n    crcForCrypting : crc of file to compress (needed for crypting) */\n\nextern int ZEXPORT zipOpenNewFileInZip3_64 OF((zipFile file, const char* filename, const zip_fileinfo* zipfi,\n    const void* extrafield_local, uInt size_extrafield_local, const void* extrafield_global, \n    uInt size_extrafield_global, const char* comment, int method, int level, int raw, int windowBits, int memLevel, \n    int strategy, const char* password, uLong crcForCrypting, int zip64));\n/* Same as zipOpenNewFileInZip3 with zip64 support */\n\nextern int ZEXPORT zipOpenNewFileInZip4 OF((zipFile file, const char* filename, const zip_fileinfo* zipfi,\n    const void* extrafield_local, uInt size_extrafield_local, const void* extrafield_global, \n    uInt size_extrafield_global, const char* comment, int method, int level, int raw, int windowBits, int memLevel, \n    int strategy, const char* password, uLong crcForCrypting, uLong versionMadeBy, uLong flagBase));\n/* Same as zipOpenNewFileInZip3 except versionMadeBy & flag fields */\n\nextern int ZEXPORT zipOpenNewFileInZip4_64 OF((zipFile file, const char* filename, const zip_fileinfo* zipfi,\n    const void* extrafield_local, uInt size_extrafield_local, const void* extrafield_global, \n    uInt size_extrafield_global, const char* comment, int method, int level, int raw, int windowBits, int memLevel, \n    int strategy, const char* password, uLong crcForCrypting, uLong versionMadeBy, uLong flagBase, int zip64));\n/* Same as zipOpenNewFileInZip4 with zip64 support */\n\nextern int ZEXPORT zipWriteInFileInZip OF((zipFile file, const void* buf, unsigned len));\n/* Write data in the zipfile */\n\nextern int ZEXPORT zipCloseFileInZip OF((zipFile file));\n/* Close the current file in the zipfile */\n\nextern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file, uLong uncompressed_size, uLong crc32));\nextern int ZEXPORT zipCloseFileInZipRaw64 OF((zipFile file, ZPOS64_T uncompressed_size, uLong crc32));\n/* Close the current file in the zipfile, for file opened with parameter raw=1 in zipOpenNewFileInZip2\n   uncompressed_size and crc32 are value for the uncompressed size */\n\nextern int ZEXPORT zipClose OF((zipFile file, const char* global_comment));\n/* Close the zipfile */\n\n/***************************************************************************/\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* _ZIP_H */\n"
  },
  {
    "path": "plugins/cordova-plugin-zip/tests/plugin.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  Licensed to the Apache Software Foundation (ASF) under one\n  or more contributor license agreements.  See the NOTICE file\n  distributed with this work for additional information\n  regarding copyright ownership.  The ASF licenses this file\n  to you under the Apache License, Version 2.0 (the\n  \"License\"); you may not use this file except in compliance\n  with the License.  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing,\n  software distributed under the License is distributed on an\n  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n  KIND, either express or implied.  See the License for the\n  specific language governing permissions and limitations\n  under the License.\n-->\n\n<plugin xmlns=\"http://apache.org/cordova/ns/plugins/1.0\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    id=\"org.chromium.zip.tests\">\n    <license>Apache 2.0</license>\n\n    <js-module src=\"tests.js\" name=\"tests\">\n    </js-module>\n</plugin>\n"
  },
  {
    "path": "plugins/cordova-plugin-zip/tests/tests.js",
    "content": "exports.defineAutoTests = function() {\n  jasmine.DEFAULT_TIMEOUT_INTERVAL = 75000;\n  var zip = require('org.chromium.zip.Zip');\n\n  describe('Zip', function () {\n    var fail = function(done, why) {\n      if (typeof why !== 'undefined') {\n        console.error(why);\n      }\n      expect(true).toBe(false);\n      done();\n    };\n\n    describe(\"unzip\", function() {\n      it(\"should be defined\", function() {\n        expect(typeof zip.unzip).toBeDefined();\n      });\n\n      var fileUrl = null;\n      var dirUrl = null;\n\n      it(\"downloading zip file\", function(done) {\n        window.requestFileSystem  = window.requestFileSystem || window.webkitRequestFileSystem;\n        var onError = fail.bind(null, done);\n\n        var xhr = new XMLHttpRequest();\n        xhr.open('GET', 'http://archive.apache.org/dist/cordova/cordova-2.9.1-src.zip', true);\n        xhr.responseType = 'blob';\n        xhr.onerror = onError;\n        xhr.onload = function(e) {\n\n          window.requestFileSystem(PERSISTENT, 1024 * 1024, function(fs) {\n            fs.root.getFile('cordova-2.9.1-src.zip', {create: true}, function(fileEntry) {\n              fileEntry.createWriter(function(writer) {\n\n                writer.onwrite = done;\n                writer.onerror = onError;\n\n                var blob = new Blob([xhr.response]);\n                writer.write(blob);\n                fileUrl = fileEntry.toURL();\n              }, onError);\n            }, onError);\n\n            fs.root.getDirectory('zipOutput', {create: true}, function(fileEntry) {\n              dirUrl = fileEntry.toURL();\n            }, onError);\n          }, onError);\n        };\n\n        xhr.send();\n      });\n\n      it(\"should unzip\", function(done) {\n        zip.unzip(fileUrl, dirUrl, function(result) {\n          expect(result).toBe(0);\n          done();\n        });\n      });\n\n      it(\"should have progress events\", function(done) {\n        var progress = 0;\n        zip.unzip(fileUrl, dirUrl, function(result) {\n          expect(result).toBe(0);\n          expect(progress).toBe(1.0);\n          done();\n        }, function(progressEvent) {\n          progress = progressEvent.loaded / progressEvent.total;\n          console.log(progress);\n        });\n      });\n    });\n  });\n};\n\n"
  },
  {
    "path": "plugins/cordova-plugin-zip/zip.js",
    "content": "var exec = cordova.require('cordova/exec');\n\nfunction newProgressEvent(result) {\n    var event = {\n            loaded: result.loaded,\n            total: result.total\n    };\n    return event;\n}\n\nexports.unzip = function(fileName, outputDirectory, callback, progressCallback) {\n    var win = function(result) {\n        if (result && typeof result.loaded != \"undefined\") {\n            if (progressCallback) {\n                return progressCallback(newProgressEvent(result));\n            }\n        } else if (callback) {\n            callback(0);\n        }\n    };\n    var fail = function(result) {\n        if (callback) {\n            callback(-1);\n        }\n    };\n    exec(win, fail, 'Zip', 'unzip', [fileName, outputDirectory]);\n};"
  },
  {
    "path": "plugins/fetch.json",
    "content": "{\n    \"cordova-plugin-code-push\": {\n        \"source\": {\n            \"type\": \"registry\",\n            \"id\": \"cordova-plugin-code-push@latest\"\n        },\n        \"is_top_level\": true,\n        \"variables\": {}\n    },\n    \"code-push\": {\n        \"source\": {\n            \"type\": \"registry\",\n            \"id\": \"code-push\"\n        },\n        \"is_top_level\": false,\n        \"variables\": {}\n    },\n    \"cordova-plugin-file\": {\n        \"source\": {\n            \"type\": \"registry\",\n            \"id\": \"cordova-plugin-file\"\n        },\n        \"is_top_level\": false,\n        \"variables\": {}\n    },\n    \"cordova-plugin-compat\": {\n        \"source\": {\n            \"type\": \"registry\",\n            \"id\": \"cordova-plugin-compat\"\n        },\n        \"is_top_level\": false,\n        \"variables\": {}\n    },\n    \"cordova-plugin-file-transfer\": {\n        \"source\": {\n            \"type\": \"registry\",\n            \"id\": \"cordova-plugin-file-transfer\"\n        },\n        \"is_top_level\": false,\n        \"variables\": {}\n    },\n    \"cordova-plugin-zip\": {\n        \"source\": {\n            \"type\": \"registry\",\n            \"id\": \"cordova-plugin-zip\"\n        },\n        \"is_top_level\": false,\n        \"variables\": {}\n    },\n    \"cordova-plugin-dialogs\": {\n        \"source\": {\n            \"type\": \"registry\",\n            \"id\": \"cordova-plugin-dialogs\"\n        },\n        \"is_top_level\": false,\n        \"variables\": {}\n    },\n    \"cordova-plugin-device\": {\n        \"source\": {\n            \"type\": \"registry\",\n            \"id\": \"cordova-plugin-device\"\n        },\n        \"is_top_level\": false,\n        \"variables\": {}\n    },\n    \"cordova-plugin-appavailability\": {\n        \"source\": {\n            \"type\": \"registry\",\n            \"id\": \"cordova-plugin-appavailability@^0.4.1\"\n        },\n        \"is_top_level\": true,\n        \"variables\": {}\n    },\n    \"cordova-plugin-inappbrowser\": {\n        \"source\": {\n            \"type\": \"registry\",\n            \"id\": \"cordova-plugin-inappbrowser@^1.0.0\"\n        },\n        \"is_top_level\": true,\n        \"variables\": {}\n    },\n    \"cordova-plugin-splashscreen\": {\n        \"source\": {\n            \"type\": \"registry\",\n            \"id\": \"cordova-plugin-splashscreen@^2.0.0\"\n        },\n        \"is_top_level\": true,\n        \"variables\": {}\n    },\n    \"cordova-plugin-statusbar\": {\n        \"source\": {\n            \"type\": \"registry\",\n            \"id\": \"cordova-plugin-statusbar@^1.0.0\"\n        },\n        \"is_top_level\": true,\n        \"variables\": {}\n    },\n    \"cordova-plugin-vibration\": {\n        \"source\": {\n            \"type\": \"registry\",\n            \"id\": \"cordova-plugin-vibration@^1.1.0\"\n        },\n        \"is_top_level\": true,\n        \"variables\": {}\n    },\n    \"cordova-plugin-whitelist\": {\n        \"source\": {\n            \"type\": \"registry\",\n            \"id\": \"cordova-plugin-whitelist@^1.1.0\"\n        },\n        \"is_top_level\": true,\n        \"variables\": {}\n    },\n    \"phonegap-plugin-barcodescanner\": {\n        \"source\": {\n            \"type\": \"registry\",\n            \"id\": \"phonegap-plugin-barcodescanner@^3.1.0\"\n        },\n        \"is_top_level\": true,\n        \"variables\": {}\n    }\n}"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/README.md",
    "content": "# PhoneGap Plugin BarcodeScanner\n================================\n\n[![Build Status](https://travis-ci.org/phonegap/phonegap-plugin-barcodescanner.svg)](https://travis-ci.org/phonegap/phonegap-plugin-barcodescanner)\n\nCross-platform BarcodeScanner for Cordova / PhoneGap.\n\nFollows the [Cordova Plugin spec](http://cordova.apache.org/docs/en/5.0.0/plugin_ref_spec.md), so that it works with [Plugman](https://github.com/apache/cordova-plugman).\n\n## Installation\n\n    \nThis requires phonegap 5.0+ ( current stable v3.0.0 )\n\n    phonegap plugin add phonegap-plugin-barcodescanner\n\nOlder versions of phonegap can still install via the __deprecated__ id ( stale v2.0.1 )\n\n    phonegap plugin add com.phonegap.plugins.barcodescanner\n\nIt is also possible to install via repo url directly ( unstable )\n\n    phonegap plugin add https://github.com/phonegap/phonegap-plugin-barcodescanner.git\n\n### Supported Platforms\n\n- Android\n- iOS\n- Windows 8\n- Windows Phone 8\n- Browser\n\nNote: the Android source for this project includes an Android Library Project.\nplugman currently doesn't support Library Project refs, so its been\nprebuilt as a jar library. Any updates to the Library Project should be\ncommitted with an updated jar.\n\n## Using the plugin ##\nThe plugin creates the object `cordova/plugin/BarcodeScanner` with the method `scan(success, fail)`. \n\nThe following barcode types are currently supported:\n### Android\n\n* QR_CODE\n* DATA_MATRIX\n* UPC_E\n* UPC_A\n* EAN_8\n* EAN_13\n* CODE_128\n* CODE_39\n* CODE_93\n* CODABAR\n* ITF\n* RSS14\n* PDF417\n* RSS_EXPANDED\n\n### iOS\n\n* QR_CODE\n* DATA_MATRIX\n* UPC_E\n* UPC_A\n* EAN_8\n* EAN_13\n* CODE_128\n* CODE_39\n* ITF\n\n### Windows8\n\n* UPC_A\n* UPC_E\n* EAN_8\n* EAN_13\n* CODE_39\n* CODE_93\n* CODE_128\n* ITF\n* CODABAR\n* MSI\n* RSS14\n* QR_CODE\n* DATA_MATRIX\n* AZTEC\n* PDF417\n\n### Windows Phone 8\n\n* UPC_A\n* UPC_E\n* EAN_8\n* EAN_13\n* CODE_39\n* CODE_93\n* CODE_128\n* ITF\n* CODABAR\n* MSI\n* RSS14\n* QR_CODE\n* DATA_MATRIX\n* AZTEC\n* PDF417\n\n`success` and `fail` are callback functions. Success is passed an object with data, type and cancelled properties. Data is the text representation of the barcode data, type is the type of barcode detected and cancelled is whether or not the user cancelled the scan.\n\nA full example could be:\n```\n   cordova.plugins.barcodeScanner.scan(\n      function (result) {\n          alert(\"We got a barcode\\n\" +\n                \"Result: \" + result.text + \"\\n\" +\n                \"Format: \" + result.format + \"\\n\" +\n                \"Cancelled: \" + result.cancelled);\n      }, \n      function (error) {\n          alert(\"Scanning failed: \" + error);\n      }\n   );\n```\n\n## Encoding a Barcode ##\n\nThe plugin creates the object `cordova.plugins.barcodeScanner` with the method `encode(type, data, success, fail)`. \n\nSupported encoding types:\n\n* TEXT_TYPE\n* EMAIL_TYPE\n* PHONE_TYPE\n* SMS_TYPE\n\n```\nA full example could be:\n\n   cordova.plugins.barcodeScanner.encode(cordova.plugins.barcodeScanner.Encode.TEXT_TYPE, \"http://www.nytimes.com\", function(success) {\n            alert(\"encode success: \" + success);\n          }, function(fail) {\n            alert(\"encoding failed: \" + fail);\n          }\n        );\n```\n\n## Windows8 quirks ##\nWindows 8 implenemtation currently doesn't support encode functionality.\n\n## Windows Phone 8 quirks ##\nWindows Phone 8 implenemtation currently doesn't support encode functionality.\n\n## Thanks on Github ##\n\nSo many -- check out the original [iOS](https://github.com/phonegap/phonegap-plugins/tree/DEPRECATED/iOS/BarcodeScanner) and [Android](https://github.com/phonegap/phonegap-plugins/tree/DEPRECATED/Android/BarcodeScanner) repos.\n\n\n## Licence ##\n\nThe MIT License\n\nCopyright (c) 2010 Matt Kane\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/package.json",
    "content": "{\n  \"name\": \"phonegap-plugin-barcodescanner\",\n  \"version\": \"3.1.2\",\n  \"description\": \"You can use the BarcodeScanner plugin to scan different types of barcodes (using the device's camera) and get the metadata encoded in them for processing within your application.\",\n  \"cordova\": {\n    \"id\": \"phonegap-plugin-barcodescanner\",\n    \"platforms\": [\n      \"ios\",\n      \"android\",\n      \"windows8\",\n      \"windows\",\n      \"wp8\",\n      \"browser\"\n    ]\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/phonegap/phonegap-plugin-barcodescanner.git\"\n  },\n  \"keywords\": [\n    \"ecosystem:cordova\",\n    \"ecosystem:phonegap\",\n    \"cordova-ios\",\n    \"cordova-android\",\n    \"cordova-windows8\",\n    \"cordova-windows\",\n    \"cordova-wp8\",\n    \"cordova-browser\"\n  ],\n  \"engines\": [\n    {\n      \"name\": \"cordova\",\n      \"version\": \">=3.0.0\"\n    }\n  ],\n  \"author\": \"Adobe PhoneGap Team\",\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/phonegap/phonegap-plugin-barcodescanner/issues\"\n  },\n  \"homepage\": \"https://github.com/phonegap/phonegap-plugin-barcodescanner#readme\"\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/plugin.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?><plugin xmlns=\"http://www.phonegap.com/ns/plugins/1.0\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    id=\"phonegap-plugin-barcodescanner\"\n    version=\"3.1.2\">\n\n    <name>BarcodeScanner</name>\n    <description>You can use the BarcodeScanner plugin to scan different types of barcodes (using the device's camera) and get the metadata encoded in them for processing within your application.</description>\n    <license>MIT</license>\n\n    <repo>https://github.com/wildabeast/BarcodeScanner</repo>\n    <issue>https://github.com/wildabeast/BarcodeScanner/issues</issue>\n\n    <engines>\n        <engine name=\"cordova\" version=\">=3.0.0\" />\n    </engines>\n\n    <js-module src=\"www/barcodescanner.js\" name=\"BarcodeScanner\">\n        <clobbers target=\"cordova.plugins.barcodeScanner\" />\n    </js-module>\n\n    <!-- ios -->\n    <platform name=\"ios\">\n        <!-- Cordova >= 2.8 -->\n        <config-file target=\"config.xml\" parent=\"/*\">\n            <feature name=\"BarcodeScanner\">\n                <param name=\"ios-package\" value=\"CDVBarcodeScanner\" />\n            </feature>\n        </config-file>\n\n        <resource-file src=\"src/ios/scannerOverlay.xib\" />\n        <resource-file src=\"src/ios/CDVBarcodeScanner.bundle\" />\n\n        <header-file src=\"src/ios/zxing-all-in-one.h\" />\n\n        <source-file src=\"src/ios/CDVBarcodeScanner.mm\" compiler-flags=\"-fno-objc-arc\" />\n        <source-file src=\"src/ios/zxing-all-in-one.cpp\" />\n\n        <framework src=\"libiconv.dylib\" />\n        <framework src=\"AVFoundation.framework\" />\n        <framework src=\"AssetsLibrary.framework\" />\n        <framework src=\"CoreVideo.framework\" />\n        <framework src=\"QuartzCore.framework\" />\n        <framework src=\"CoreGraphics.framework\" />\n        <framework src=\"CoreImage.framework\" />\n        <framework src=\"AudioToolbox.framework\" />\n    </platform>\n\n    <!-- android -->\n    <platform name=\"android\">\n\n        <source-file src=\"src/android/com/phonegap/plugins/barcodescanner/BarcodeScanner.java\" target-dir=\"src/com/phonegap/plugins/barcodescanner\" />\n        <!--\n        <source-file src=\"R.java\" target-dir=\"src/com/google/zxing/client/android\" />\n        -->\n\n        <!--\n        <config-file target=\"res/xml/plugins.xml\" parent=\"/plugins\">\n            <plugin name=\"BarcodeScanner\" value=\"com.phonegap.plugins.barcodescanner.BarcodeScanner\"/>\n        </config-file>\n        -->\n\n        <config-file target=\"res/xml/config.xml\" parent=\"/*\">\n            <feature name=\"BarcodeScanner\">\n                <param name=\"android-package\" value=\"com.phonegap.plugins.barcodescanner.BarcodeScanner\" />\n            </feature>\n        </config-file>\n\n        <config-file target=\"AndroidManifest.xml\" parent=\"/manifest/application\">\n            <activity\n                android:name=\"com.google.zxing.client.android.CaptureActivity\"\n                android:clearTaskOnLaunch=\"true\"\n                android:configChanges=\"orientation|keyboardHidden\"\n                android:theme=\"@android:style/Theme.NoTitleBar.Fullscreen\"\n                android:windowSoftInputMode=\"stateAlwaysHidden\"\n                android:exported=\"false\">\n                <intent-filter>\n                    <action android:name=\"com.google.zxing.client.android.SCAN\"/>\n                    <category android:name=\"android.intent.category.DEFAULT\"/>\n                </intent-filter>\n            </activity>\n            <activity android:name=\"com.google.zxing.client.android.encode.EncodeActivity\" android:label=\"@string/share_name\">\n                <intent-filter>\n                    <action android:name=\"com.phonegap.plugins.barcodescanner.ENCODE\"/>\n                    <category android:name=\"android.intent.category.DEFAULT\"/>\n                </intent-filter>\n            </activity>\n            <activity android:name=\"com.google.zxing.client.android.HelpActivity\" android:label=\"@string/share_name\">\n                <intent-filter>\n                    <action android:name=\"android.intent.action.VIEW\"/>\n                    <category android:name=\"android.intent.category.DEFAULT\"/>\n                </intent-filter>\n            </activity>\n        </config-file>\n\n        <config-file target=\"AndroidManifest.xml\" parent=\"/manifest\">\n            <uses-permission android:name=\"android.permission.CAMERA\" />\n            <uses-permission android:name=\"android.permission.FLASHLIGHT\" />\n            <!-- Not required to allow users to work around this -->\n            <uses-feature android:name=\"android.hardware.camera\" android:required=\"false\" />\n        </config-file>\n\n        <source-file src=\"src/android/com.google.zxing.client.android.captureactivity.jar\" target-dir=\"libs\"/>\n\n        <!--\n            LibraryProject/res/*.*\n            search: (src/android/LibraryProject/(.+?)/[^/]+)$\n            replace: <source-file src=\"$1\" target-dir=\"$2\"/>\n        -->\n\n        <source-file src=\"src/android/LibraryProject/res/drawable/launcher_icon.png\" target-dir=\"res/drawable\"/>\n        <source-file src=\"src/android/LibraryProject/res/drawable/share_via_barcode.png\" target-dir=\"res/drawable\"/>\n        <source-file src=\"src/android/LibraryProject/res/drawable/shopper_icon.png\" target-dir=\"res/drawable\"/>\n        <source-file src=\"src/android/LibraryProject/res/drawable-hdpi/launcher_icon.png\" target-dir=\"res/drawable-hdpi\"/>\n        <source-file src=\"src/android/LibraryProject/res/drawable-hdpi/shopper_icon.png\" target-dir=\"res/drawable-hdpi\"/>\n        <source-file src=\"src/android/LibraryProject/res/drawable-xhdpi/launcher_icon.png\" target-dir=\"res/drawable-xhdpi\"/>\n        <source-file src=\"src/android/LibraryProject/res/drawable-xxhdpi/launcher_icon.png\" target-dir=\"res/drawable-xxhdpi\"/>\n        <source-file src=\"src/android/LibraryProject/res/layout/bookmark_picker_list_item.xml\" target-dir=\"res/layout\"/>\n        <source-file src=\"src/android/LibraryProject/res/layout/capture.xml\" target-dir=\"res/layout\"/>\n        <source-file src=\"src/android/LibraryProject/res/layout/encode.xml\" target-dir=\"res/layout\"/>\n        <source-file src=\"src/android/LibraryProject/res/layout/help.xml\" target-dir=\"res/layout\"/>\n        <source-file src=\"src/android/LibraryProject/res/layout/history_list_item.xml\" target-dir=\"res/layout\"/>\n        <source-file src=\"src/android/LibraryProject/res/layout/search_book_contents.xml\" target-dir=\"res/layout\"/>\n        <source-file src=\"src/android/LibraryProject/res/layout/search_book_contents_header.xml\" target-dir=\"res/layout\"/>\n        <source-file src=\"src/android/LibraryProject/res/layout/search_book_contents_list_item.xml\" target-dir=\"res/layout\"/>\n        <source-file src=\"src/android/LibraryProject/res/layout/share.xml\" target-dir=\"res/layout\"/>\n        <source-file src=\"src/android/LibraryProject/res/layout-land/encode.xml\" target-dir=\"res/layout-land\"/>\n        <source-file src=\"src/android/LibraryProject/res/layout-land/share.xml\" target-dir=\"res/layout-land\"/>\n        <source-file src=\"src/android/LibraryProject/res/layout-ldpi/capture.xml\" target-dir=\"res/layout-ldpi\"/>\n        <source-file src=\"src/android/LibraryProject/res/menu/capture.xml\" target-dir=\"res/menu\"/>\n        <source-file src=\"src/android/LibraryProject/res/menu/encode.xml\" target-dir=\"res/menu\"/>\n        <source-file src=\"src/android/LibraryProject/res/menu/history.xml\" target-dir=\"res/menu\"/>\n        <source-file src=\"src/android/LibraryProject/res/raw/beep.ogg\" target-dir=\"res/raw\"/>\n        <source-file src=\"src/android/LibraryProject/res/values/arrays.xml\" target-dir=\"res/values\"/>\n        <source-file src=\"src/android/LibraryProject/res/values/colors.xml\" target-dir=\"res/values\"/>\n        <source-file src=\"src/android/LibraryProject/res/values/dimens.xml\" target-dir=\"res/values\"/>\n        <source-file src=\"src/android/LibraryProject/res/values/ids.xml\" target-dir=\"res/values\"/>\n        <source-file src=\"src/android/LibraryProject/res/values-ar/strings.xml\" target-dir=\"res/values-ar\"/>\n        <source-file src=\"src/android/LibraryProject/res/values-bg/strings.xml\" target-dir=\"res/values-bg\"/>\n        <source-file src=\"src/android/LibraryProject/res/values-ca/strings.xml\" target-dir=\"res/values-ca\"/>\n        <source-file src=\"src/android/LibraryProject/res/values-cs/strings.xml\" target-dir=\"res/values-cs\"/>\n        <source-file src=\"src/android/LibraryProject/res/values-da/strings.xml\" target-dir=\"res/values-da\"/>\n        <source-file src=\"src/android/LibraryProject/res/values-de/strings.xml\" target-dir=\"res/values-de\"/>\n        <source-file src=\"src/android/LibraryProject/res/values-el/strings.xml\" target-dir=\"res/values-el\"/>\n        <source-file src=\"src/android/LibraryProject/res/values-es/strings.xml\" target-dir=\"res/values-es\"/>\n        <source-file src=\"src/android/LibraryProject/res/values-eu/strings.xml\" target-dir=\"res/values-eu\"/>\n        <source-file src=\"src/android/LibraryProject/res/values-fi/strings.xml\" target-dir=\"res/values-fi\"/>\n        <source-file src=\"src/android/LibraryProject/res/values-fr/strings.xml\" target-dir=\"res/values-fr\"/>\n        <source-file src=\"src/android/LibraryProject/res/values-he/strings.xml\" target-dir=\"res/values-he\"/>\n        <source-file src=\"src/android/LibraryProject/res/values-hi/strings.xml\" target-dir=\"res/values-hi\"/>\n        <source-file src=\"src/android/LibraryProject/res/values-hu/strings.xml\" target-dir=\"res/values-hu\"/>\n        <source-file src=\"src/android/LibraryProject/res/values-id/strings.xml\" target-dir=\"res/values-id\"/>\n        <source-file src=\"src/android/LibraryProject/res/values-it/strings.xml\" target-dir=\"res/values-it\"/>\n        <source-file src=\"src/android/LibraryProject/res/values-iw/strings.xml\" target-dir=\"res/values-iw\"/>\n        <source-file src=\"src/android/LibraryProject/res/values-ja/strings.xml\" target-dir=\"res/values-ja\"/>\n        <source-file src=\"src/android/LibraryProject/res/values-ko/strings.xml\" target-dir=\"res/values-ko\"/>\n        <source-file src=\"src/android/LibraryProject/res/values-nl/strings.xml\" target-dir=\"res/values-nl\"/>\n        <source-file src=\"src/android/LibraryProject/res/values-pl/strings.xml\" target-dir=\"res/values-pl\"/>\n        <source-file src=\"src/android/LibraryProject/res/values-pt/strings.xml\" target-dir=\"res/values-pt\"/>\n        <source-file src=\"src/android/LibraryProject/res/values-ru/strings.xml\" target-dir=\"res/values-ru\"/>\n        <source-file src=\"src/android/LibraryProject/res/values-sk/strings.xml\" target-dir=\"res/values-sk\"/>\n        <source-file src=\"src/android/LibraryProject/res/values-sl/strings.xml\" target-dir=\"res/values-sl\"/>\n        <source-file src=\"src/android/LibraryProject/res/values-sv/strings.xml\" target-dir=\"res/values-sv\"/>\n        <source-file src=\"src/android/LibraryProject/res/values-tr/strings.xml\" target-dir=\"res/values-tr\"/>\n        <source-file src=\"src/android/LibraryProject/res/values-zh-rCN/strings.xml\" target-dir=\"res/values-zh-rCN\"/>\n        <source-file src=\"src/android/LibraryProject/res/values-zh-rTW/strings.xml\" target-dir=\"res/values-zh-rTW\"/>\n        <source-file src=\"src/android/LibraryProject/res/xml/preferences.xml\" target-dir=\"res/xml\"/>\n\n        <!-- plugman cannot merge - prepare manual merge -->\n        <config-file target=\"res/values/strings.xml\" parent=\"/resources\">\n            <string name=\"app_picker_name\">Applications</string>\n            <string name=\"bookmark_picker_name\">Bookmarks</string>\n            <string name=\"button_add_calendar\">Add to calendar</string>\n            <string name=\"button_add_contact\">Add contact</string>\n            <string name=\"button_back\">Back</string>\n            <string name=\"button_book_search\">Book Search</string>\n            <string name=\"button_cancel\">Cancel</string>\n            <string name=\"button_custom_product_search\">Custom search</string>\n            <string name=\"button_dial\">Dial number</string>\n            <string name=\"button_done\">Done</string>\n            <string name=\"button_email\">Send email</string>\n            <string name=\"button_get_directions\">Get directions</string>\n            <string name=\"button_google_shopper\">Shopper</string>\n            <string name=\"button_mms\">Send MMS</string>\n            <string name=\"button_ok\">OK</string>\n            <string name=\"button_open_browser\">Open browser</string>\n            <string name=\"button_product_search\">Product Search</string>\n            <string name=\"button_search_book_contents\">Search contents</string>\n            <string name=\"button_share_app\">Application</string>\n            <string name=\"button_share_bookmark\">Bookmark</string>\n            <string name=\"button_share_by_email\">Share via email</string>\n            <string name=\"button_share_by_sms\">Share via SMS</string>\n            <string name=\"button_share_clipboard\">Clipboard</string>\n            <string name=\"button_share_contact\">Contact</string>\n            <string name=\"button_show_map\">Show map</string>\n            <string name=\"button_sms\">Send SMS</string>\n            <string name=\"button_web_search\">Web search</string>\n            <string name=\"button_wifi\">Connect to Network</string>\n            <string name=\"contents_contact\">Contact info</string>\n            <string name=\"contents_email\">Email address</string>\n            <string name=\"contents_location\">Geographic coordinates</string>\n            <string name=\"contents_phone\">Phone number</string>\n            <string name=\"contents_sms\">SMS address</string>\n            <string name=\"contents_text\">Plain text</string>\n            <string name=\"history_clear_text\">Clear history</string>\n            <string name=\"history_clear_one_history_text\">Clear</string>\n            <string name=\"history_email_title\">Barcode Scanner history</string>\n            <string name=\"history_empty\">Empty</string>\n            <string name=\"history_empty_detail\">No barcode scans have been recorded</string>\n            <string name=\"history_send\">Send history</string>\n            <string name=\"history_title\">History</string>\n            <string name=\"menu_encode_mecard\">Use MECARD</string>\n            <string name=\"menu_encode_vcard\">Use vCard</string>\n            <string name=\"menu_help\">Help</string>\n            <string name=\"menu_history\">History</string>\n            <string name=\"menu_share\">Share</string>\n            <string name=\"msg_bulk_mode_scanned\">Bulk mode: barcode scanned and saved</string>\n            <string name=\"msg_camera_framework_bug\">Sorry, the Android camera encountered a problem. You may need to restart the device.</string>\n            <string name=\"msg_default_format\">Format</string>\n            <string name=\"msg_default_meta\">Metadata</string>\n            <string name=\"msg_default_mms_subject\">Hi</string>\n            <string name=\"msg_default_status\">Place a barcode inside the viewfinder rectangle to scan it.</string>\n            <string name=\"msg_default_time\">Time</string>\n            <string name=\"msg_default_type\">Type</string>\n            <string name=\"msg_encode_contents_failed\">Could not encode a barcode from the data provided.</string>\n            <string name=\"msg_google_books\">Google Books</string>\n            <string name=\"msg_google_product\">Google Product Search</string>\n            <string name=\"msg_google_shopper_missing\">Google Shopper is not installed</string>\n            <string name=\"msg_install_google_shopper\">Google Shopper combines barcode scanning with online and local prices, reviews and more without opening the browser. Would you like to try it?</string>\n            <string name=\"msg_intent_failed\">Sorry, the requested application could not be launched. The barcode contents may be invalid.</string>\n            <string name=\"msg_redirect\">Redirect</string>\n            <string name=\"msg_sbc_book_not_searchable\">Sorry, this book is not searchable.</string>\n            <string name=\"msg_sbc_failed\">Sorry, the search encountered a problem.</string>\n            <string name=\"msg_sbc_no_page_returned\">No page returned</string>\n            <string name=\"msg_sbc_page\">Page</string>\n            <string name=\"msg_sbc_results\">Results</string>\n            <string name=\"msg_sbc_searching_book\">Searching book\\u2026</string>\n            <string name=\"msg_sbc_snippet_unavailable\">Snippet not available</string>\n            <string name=\"msg_sbc_unknown_page\">Unknown page</string>\n            <string name=\"msg_share_explanation\">You can share data by displaying a barcode on your screen and scanning it with another phone.</string>\n            <string name=\"msg_share_subject_line\">Here are the contents of a barcode I scanned</string>\n            <string name=\"msg_share_text\">Or type some text and press Enter</string>\n            <string name=\"msg_sure\">Are you sure?</string>\n            <string name=\"msg_unmount_usb\">Sorry, the SD card is not accessible.</string>\n            <string name=\"preferences_actions_title\">When a barcode is found\\u2026</string>\n            <string name=\"preferences_auto_focus_title\">Use auto focus</string>\n            <string name=\"preferences_bulk_mode_summary\">Scan and save many barcodes continuously</string>\n            <string name=\"preferences_bulk_mode_title\">Bulk scan mode</string>\n            <string name=\"preferences_copy_to_clipboard_title\">Copy to clipboard</string>\n            <string name=\"preferences_custom_product_search_summary\" formatted=\"false\">Substitutions: %s = contents, %f = format, %t = type</string>\n            <string name=\"preferences_custom_product_search_title\">Custom search URL</string>\n            <string name=\"preferences_decode_1D_title\">1D barcodes</string>\n            <string name=\"preferences_decode_Data_Matrix_title\">Data Matrix</string>\n            <string name=\"preferences_decode_QR_title\">QR Codes</string>\n            <string name=\"preferences_device_bug_workarounds_title\">Device Bug Workarounds</string>\n            <string name=\"preferences_disable_continuous_focus_summary\">Use only standard focus mode</string>\n            <string name=\"preferences_disable_continuous_focus_title\">No continuous focus</string>\n            <string name=\"preferences_disable_exposure_title\">No exposure</string>\n            <string name=\"preferences_front_light_summary\">Improves scanning in low light on some phones, but may cause glare. Does not work on all phones.</string>\n            <string name=\"preferences_front_light_title\">Use front light</string>\n            <string name=\"preferences_general_title\">General settings</string>\n            <string name=\"preferences_name\">Settings</string>\n            <string name=\"preferences_play_beep_title\">Beep</string>\n            <string name=\"preferences_remember_duplicates_summary\">Store multiple scans of the same barcode in History</string>\n            <string name=\"preferences_remember_duplicates_title\">Remember duplicates</string>\n            <string name=\"preferences_result_title\">Result settings</string>\n            <string name=\"preferences_scanning_title\">When scanning for barcodes, decode\\u2026</string>\n            <string name=\"preferences_search_country\">Search country</string>\n            <string name=\"preferences_try_bsplus\">Try Barcode Scanner+</string>\n            <string name=\"preferences_try_bsplus_summary\">Enhanced with new features and interface</string>\n            <string name=\"preferences_supplemental_summary\">Try to retrieve more information about the barcode contents</string>\n            <string name=\"preferences_supplemental_title\">Retrieve more info</string>\n            <string name=\"preferences_vibrate_title\">Vibrate</string>\n            <string name=\"result_address_book\">Found contact info</string>\n            <string name=\"result_calendar\">Found calendar event</string>\n            <string name=\"result_email_address\">Found email address</string>\n            <string name=\"result_geo\">Found geographic coordinates</string>\n            <string name=\"result_isbn\">Found book</string>\n            <string name=\"result_product\">Found product</string>\n            <string name=\"result_sms\">Found SMS address</string>\n            <string name=\"result_tel\">Found phone number</string>\n            <string name=\"result_text\">Found plain text</string>\n            <string name=\"result_uri\">Found URL</string>\n            <string name=\"result_wifi\">Found WLAN Configuration</string>\n            <string name=\"sbc_name\">Google Book Search</string>\n            <string name=\"share_name\">Share via barcode</string>\n            <string name=\"wifi_changing_network\">Requesting connection to network\\u2026</string>\n            <string name=\"wifi_ssid_label\">Network Name</string>\n            <string name=\"wifi_type_label\">Type</string>\n        </config-file>\n    </platform>\n\n    <platform name=\"windows8\">\n        <js-module src=\"src/windows/BarcodeScannerProxy.js\" name=\"BarcodeScannerProxy\">\n            <merges target=\"\" />\n        </js-module>\n\n        <config-file target=\"package.appxmanifest\" parent=\"/Package/Capabilities\">\n            <DeviceCapability Name=\"webcam\" />\n        </config-file>\n\n        <framework src=\"src/windows/lib/WinRTBarcodeReader.csproj\" custom=\"true\" type=\"projectReference\"/>\n    </platform>\n\n    <platform name=\"windows\">\n        <js-module src=\"src/windows/BarcodeScannerProxy.js\" name=\"BarcodeScannerProxy\">\n            <merges target=\"\" />\n        </js-module>\n\n        <config-file target=\"package.appxmanifest\" parent=\"/Package/Capabilities\">\n            <DeviceCapability Name=\"webcam\" />\n        </config-file>\n\n        <framework src=\"src/windows/lib/WinRTBarcodeReader.csproj\" custom=\"true\" type=\"projectReference\"/>\n    </platform>\n\n    <!-- Windows Phone 8 -->\n    <platform name=\"wp8\">\n        <config-file target=\"config.xml\" parent=\"/*\">\n            <feature name=\"BarcodeScanner\">\n                <param name=\"wp-package\" value=\"BarcodeScanner\"/>\n            </feature>\n        </config-file>\n\n        <config-file target=\"Properties/WMAppManifest.xml\" parent=\"/Deployment/App/Capabilities\">\n            <Capability Name=\"ID_CAP_ISV_CAMERA\" />\n        </config-file>\n\n        <framework src=\"src/wp8/lib/zxing.wp8.0.dll\" custom=\"true\" />\n\n        <asset src=\"src/wp8/assets/cancel.png\" target=\"Images/appbar.cancel.png\" />\n\n        <source-file src=\"src/wp8/BarcodeScanner.cs\" />\n        <source-file src=\"src/wp8/BarcodeScannerTask.cs\" />\n        <source-file src=\"src/wp8/BarcodeScannerUI.xaml\" />\n        <source-file src=\"src/wp8/BarcodeScannerUI.xaml.cs\" />\n    </platform>\n\n    <!-- browser -->\n    <platform name=\"browser\">\n        <config-file target=\"config.xml\" parent=\"/*\">\n            <feature name=\"BarcodeScanner\">\n                <param name=\"browser-package\" value=\"BarcodeScanner\" />\n            </feature>\n        </config-file>\n\n        <js-module src=\"src/browser/BarcodeScannerProxy.js\" name=\"BarcodeScannerProxy\">\n            <runs />\n        </js-module>\n    </platform>\n\n</plugin>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/.npmignore",
    "content": "/libs\r\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2008 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n          package=\"com.google.zxing.client.android\"\n          android:versionName=\"4.3.1\"\n          android:versionCode=\"87\"\n          android:installLocation=\"auto\">\n\n  <uses-permission android:name=\"android.permission.CAMERA\"/>\n  <uses-permission android:name=\"android.permission.INTERNET\"/>\n  <uses-permission android:name=\"android.permission.VIBRATE\"/>\n  <uses-permission android:name=\"android.permission.FLASHLIGHT\"/>\n  <uses-permission android:name=\"android.permission.READ_CONTACTS\"/>\n  <uses-permission android:name=\"com.android.browser.permission.READ_HISTORY_BOOKMARKS\"/>\n  <uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>\n  <uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>\n  <uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>\n\n  <uses-sdk android:minSdkVersion=\"7\" android:targetSdkVersion=\"10\"/>\n\n  <!-- Don't require camera, as this requires a rear camera. This allows it to work on the Nexus 7 -->\n  <uses-feature android:name=\"android.hardware.camera\" android:required=\"false\"/>\n  <uses-feature android:name=\"android.hardware.camera.front\" android:required=\"false\"/>\n  <uses-feature android:name=\"android.hardware.camera.autofocus\" android:required=\"false\"/>\n  <uses-feature android:name=\"android.hardware.camera.flash\" android:required=\"false\"/>\n  <uses-feature android:name=\"android.hardware.screen.landscape\"/>\n  <uses-feature android:name=\"android.hardware.wifi\" android:required=\"false\"/>\n  <uses-feature android:name=\"android.hardware.touchscreen\" android:required=\"false\"/>\n\n  <!-- Donut-specific flags which allow us to run on any dpi screens. -->\n  <supports-screens android:xlargeScreens=\"true\"\n                    android:largeScreens=\"true\"\n                    android:normalScreens=\"true\"\n                    android:smallScreens=\"true\"\n                    android:anyDensity=\"true\"/>\n\n  <application android:icon=\"@drawable/launcher_icon\"\n               android:label=\"@string/app_name\">\n\n    <activity android:name=\".CaptureActivity\"\n              android:clearTaskOnLaunch=\"true\"\n              android:stateNotNeeded=\"true\"\n              android:configChanges=\"orientation|keyboardHidden\"\n              android:theme=\"@android:style/Theme.NoTitleBar.Fullscreen\"\n              android:windowSoftInputMode=\"stateAlwaysHidden\">\n      <intent-filter>\n        <action android:name=\"android.intent.action.MAIN\"/>\n        <category android:name=\"android.intent.category.LAUNCHER\"/>\n      </intent-filter>\n      <intent-filter>\n        <action android:name=\"com.google.zxing.client.android.SCAN\"/>\n        <category android:name=\"android.intent.category.DEFAULT\"/>\n      </intent-filter>\n      <!-- Allow web apps to launch Barcode Scanner by linking to http://zxing.appspot.com/scan. -->\n      <intent-filter>\n        <action android:name=\"android.intent.action.VIEW\"/>\n        <category android:name=\"android.intent.category.DEFAULT\"/>\n        <category android:name=\"android.intent.category.BROWSABLE\"/>\n        <data android:scheme=\"http\" android:host=\"zxing.appspot.com\" android:path=\"/scan\"/>\n      </intent-filter>\n      <!-- We also support a Google Product Search URL. -->\n      <intent-filter>\n        <action android:name=\"android.intent.action.VIEW\"/>\n        <category android:name=\"android.intent.category.DEFAULT\"/>\n        <category android:name=\"android.intent.category.BROWSABLE\"/>\n        <data android:scheme=\"http\" android:host=\"www.google.com\" android:path=\"/m/products/scan\"/>\n      </intent-filter>\n      <!-- And the UK version. -->\n      <intent-filter>\n        <action android:name=\"android.intent.action.VIEW\"/>\n        <category android:name=\"android.intent.category.DEFAULT\"/>\n        <category android:name=\"android.intent.category.BROWSABLE\"/>\n        <data android:scheme=\"http\" android:host=\"www.google.co.uk\" android:path=\"/m/products/scan\"/>\n      </intent-filter>\n      <!-- Support zxing://scan/?... like iPhone app -->\n      <intent-filter>\n        <action android:name=\"android.intent.action.VIEW\"/>\n        <category android:name=\"android.intent.category.DEFAULT\"/>\n        <category android:name=\"android.intent.category.BROWSABLE\"/>\n        <data android:scheme=\"zxing\" android:host=\"scan\" android:path=\"/\"/>\n      </intent-filter>\n    </activity>\n    <activity android:name=\".PreferencesActivity\"\n              android:label=\"@string/preferences_name\"\n              android:stateNotNeeded=\"true\">\n    </activity>\n    <activity android:name=\".encode.EncodeActivity\"\n              android:label=\"@string/share_name\"\n              android:stateNotNeeded=\"true\">\n      <intent-filter>\n        <action android:name=\"com.google.zxing.client.android.ENCODE\"/>\n        <category android:name=\"android.intent.category.DEFAULT\"/>\n      </intent-filter>\n      <!-- This allows us to handle the Share button in Contacts. -->\n      <intent-filter>\n        <action android:name=\"android.intent.action.SEND\"/>\n        <category android:name=\"android.intent.category.DEFAULT\"/>\n        <data android:mimeType=\"text/x-vcard\"/>\n      </intent-filter>\n      <!-- This allows us to handle sharing any plain text . -->\n      <intent-filter>\n        <action android:name=\"android.intent.action.SEND\"/>\n        <category android:name=\"android.intent.category.DEFAULT\"/>\n        <data android:mimeType=\"text/plain\"/>\n      </intent-filter>\n    </activity>\n    <activity android:name=\".book.SearchBookContentsActivity\"\n              android:label=\"@string/sbc_name\"\n              android:stateNotNeeded=\"true\"\n              android:screenOrientation=\"landscape\"\n              android:configChanges=\"orientation|keyboardHidden\">\n      <intent-filter>\n        <action android:name=\"com.google.zxing.client.android.SEARCH_BOOK_CONTENTS\"/>\n        <category android:name=\"android.intent.category.DEFAULT\"/>\n      </intent-filter>\n    </activity>\n    <activity android:name=\".share.ShareActivity\"\n              android:label=\"@string/share_name\"\n              android:stateNotNeeded=\"true\"\n              android:screenOrientation=\"user\"\n              android:theme=\"@android:style/Theme.Light\">\n      <intent-filter>\n        <action android:name=\"com.google.zxing.client.android.SHARE\"/>\n        <category android:name=\"android.intent.category.DEFAULT\"/>\n      </intent-filter>\n    </activity>\n    <activity android:name=\".history.HistoryActivity\"\n              android:label=\"@string/history_title\"\n              android:stateNotNeeded=\"true\">\n      <intent-filter>\n        <action android:name=\"android.intent.action.VIEW\"/>\n        <category android:name=\"android.intent.category.DEFAULT\"/>\n      </intent-filter>\n    </activity>\n    <activity android:name=\".share.BookmarkPickerActivity\"\n              android:label=\"@string/bookmark_picker_name\"\n              android:stateNotNeeded=\"true\">\n      <intent-filter>\n        <action android:name=\"android.intent.action.PICK\"/>\n        <category android:name=\"android.intent.category.DEFAULT\"/>\n      </intent-filter>\n    </activity>\n    <activity android:name=\".share.AppPickerActivity\"\n              android:label=\"@string/app_picker_name\"\n              android:stateNotNeeded=\"true\"\n              android:configChanges=\"orientation\">\n      <intent-filter>\n        <action android:name=\"android.intent.action.PICK\"/>\n        <category android:name=\"android.intent.category.DEFAULT\"/>\n      </intent-filter>\n    </activity>\n    <activity android:name=\".HelpActivity\"\n              android:screenOrientation=\"user\">\n      <intent-filter>\n        <action android:name=\"android.intent.action.VIEW\"/>\n        <category android:name=\"android.intent.category.DEFAULT\"/>\n      </intent-filter>\n    </activity>\n  </application>\n\n</manifest>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/ant.properties",
    "content": "# This file is used to override default values used by the Ant build system.\n#\n# This file must be checked in Version Control Systems, as it is\n# integral to the build system of your project.\n\n# This file is only used by the Ant script.\n\n# You can use this to override default values such as\n#  'source.dir' for the location of your java source folder and\n#  'out.dir' for the location of your output folder.\n\n# You can also use it define how the release builds are signed by declaring\n# the following properties:\n#  'key.store' for the location of your keystore and\n#  'key.alias' for the name of the key to use.\n# The password will be asked during the build when you use the 'release' target.\n\napplication-package=com.google.zxing.client.android\nexternal-libs-folder=libs\nkey.store=../../release.keystore\nkey.alias=release"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-de/about1d.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title>Über 1D-Barcodes (Strichcodes)</title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p>Die altbekannten Strichcodes, wie solche auf Produktverpackungen, werden auch eindimensionale Barcodes genannt. Es gibt einige verbreitete Arten, wie den UPC (Universal Product Code) und den EAN (European Article Number). Die meisten schauen so aus:</p>\n<p class=\"imgcenter\"><img src=\"../images/big-1d.png\"/></p>\n<p>Diese Strichcodes enthalten eine einmalige Nummer, welche ein Produkt, wie ein Buch oder eine CD, beschreiben. Man kann nach dieser Nummer im Internet suchen, um Preise oder Beurteilungen zu finden.</p>\n<p>Wenn man den Code eines Buches einscannt, kann man den Inhalt des Buches nach Wörtern oder Sätzen durchsuchen und alle Seiten finden, in denen dieses Wort vorkam:</p>\n<p class=\"imgcenter\"><img src=\"../images/search-book-contents.jpg\"/></p>\n</body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-de/about2d.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title>Über 2D-Barcodes</title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p>Der <strong>Barcode Scanner</strong> kann auch zweidimensionale Barcodes, wie den QR-Code und den DataMatrix-Code einlesen. Die Barcodes in diesem Beispiel enthalten einen Hyperlink auf die Projekt-Homepage von ZXing:</p>\n<p class=\"imgcenter\">\n  <img src=\"../images/big-qr.png\"/>\n  <img src=\"../images/big-datamatrix.png\"/>\n</p>\n<p>Ein QR-Code kann auch eine Visitenkarte mit Kontaktinformationen wie Telefonnummern und E-Mail-Adressen enthalten. Wird ein solcher Code eingescannt, dann wird eine Auswahl an Aktionen angezeigt:</p>\n<p class=\"imgcenter\"><img src=\"../images/contact-results-screen.jpg\"/></p>\n<p>Neben URLs und Kontaktdaten können QR-Codes auch folgendes enthalten:</p>\n<ul>\n  <li>Kalendereinträge, die man dem Kalender hinzufügen kann</li>\n  <li>Telefonnummern, die man anrufen oder abspeichern kann</li>\n  <li>SMS-Nachrichten, die man verschicken kann</li>\n  <li>E-Mail-Adressen, denen man eine Nachricht schreiben kann</li>\n  <li>Geographische Koordinaten, die zu der man die Karte öffnen kann</li>\n  <li>Einfachen Text, den man lesen oder in die Zwischenablage kopieren kann</li>\n</ul>\n</body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-de/index.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title>Barcode Scanner-Hilfe</title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p><strong>Barcode Scanner 4.3.1</strong></p>\n<p>Dies ist die offizielle Android App des Open-Source-Projekts ZXing:<br/>\n<a href=\"http://code.google.com/p/zxing\">http://code.google.com/p/zxing</a></p>\n<p>Der <strong>Barcode Scanner</strong> verwendet die Kamera ihres Handys, um Barcodes zu lesen und Produktinformationen wie Preise und Bewertungen zu suchen.</p>\n<p class=\"imgcenter\"><img src=\"../images/scan-example.png\"/></p>\n<p>Er liest auch 2D-Barcodes wie den QR-Code und DataMatrix. Diese Barcodes können z.B. Links zu Webseiten enthalten oder Kontaktinformationen wie Telefonnummern und E-Mail-Adressen und vieles mehr.</p>\n<ul class=\"touchable\">\n  <li><a href=\"whatsnew.html\">Neues in dieser Version</a></li>\n  <li><a href=\"scanning.html\">Tips fürs scannen</a></li>\n  <li><a href=\"about1d.html\">Mehr über 1D-Barcodes</a></li>\n  <li><a href=\"about2d.html\">Mehr über 2D-Barcodes</a></li>\n  <li><a href=\"sharing.html\">So erstellen Sie QR-Codes</a></li>\n</ul>\n</body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-de/scanning.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title>Tips fürs scannen</title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p>Der Scanner durchsucht kontinuierlich den rechteckigen Bereich auf dem Bildschirm. Dabei muss der Barcode vollständig im rechteckigen Sucher erscheinen:</p>\n<p class=\"imgcenter\"><img src=\"../images/demo-yes.png\" style=\"padding:5px\"/><img src=\"../images/demo-no.png\" style=\"padding:5px\"/></p>\n<p>Für 1D-Barcodes, auch Strichcodes genannt, welche sich auf allen Handelsprodukten befinden, benötigt man ein Handy mit Autofokus. Ohne diesen können nur QR-Codes und DataMatrix-Codes eingescannt werden.</p>\n<p>Wenn ein Barcode eingelesen wurde, piepst das Handy und es wird das Ergebnis des Scans angezeigt, sowie eine Beschreibung des Barcode-Inhalts, und verschiedene Möglichkeiten wie weiter verfahren werden soll.</p>\n<p>Falls das Einscannen nicht richtig funktioniert, versuchen Sie das Handy ruhiger zu halten. Wenn das Bild unscharf ist, vergrößern oder verkleinern Sie den Abstand zum Barcode.</p>\n<ul class=\"touchable\">\n  <li><a href=\"about1d.html\"> Über 1D-Barcodes </a></li>\n  <li><a href=\"about2d.html\"> Über 2D-Barcodes </a></li>\n</ul>\n</body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-de/sharing.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title>So erstellen Sie einen QR-Code</title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p>Der <strong>Barcode Scanner</strong> kann nicht nur QR-Codes einlesen, sondern auch selbst erzeugen und auf dem Bildschirm anzeigen. Diesen QR-Code können Sie dann einem Freund zeigen, der den Code mit seinen Handy einscannen kann.</p>\n<p class=\"imgcenter\"><img src=\"../images/scan-from-phone.png\"/></p>\n<p>Um diese Funktion zu nutzen, einfach auf dem Hauptbildschirm auf die Menü-Taste drücken, und auf <em>Senden</em> tippen. Dann wählen, ob Sie einen Kontakt, ein Lesezeichen, eine Anwendung oder den Inhalt der Zwischenablage senden wollen und der QR-Code wird automatisch generiert. Wenn Sie fertig sind, drücken Sie die Zurücktaste.</p>\n<p>Um QR-Codes auf Ihrem Computer zu erzeugen, testen Sie den ZXing QR Code Generator, er basiert auf dem selben Quelltext wie dieses Programm: <a href=\"http://zxing.appspot.com/generator/\">http://zxing.appspot.com/generator/</a></p>\n</body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-de/whatsnew.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title>Neues in dieser Version von Barcode Scanner</title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p>Neu in der Version 4.3.1:</p>\n<ul>\n  <li>Belichtungssteuerung deaktivierbar, wenn diese auf Ihrem Gerät Probleme verursacht</li>\n  <li>Einige weitere kleine Fehler behoben</li>\n</ul>\n</body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-en/about1d.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title>About 1D barcodes</title>\n<link rel=\"stylesheet\" href=\"../style.css\" type=\"text/css\"/>\n</head>\n<body>\n<p>Traditional barcodes, such as those printed on product packaging, are also known as one dimensional barcodes. There are several types commonly used, including UPC and EAN. Most look similar to this:</p>\n<p class=\"imgcenter\"><img src=\"../images/big-1d.png\"/></p>\n<p>These 1D barcodes contain a unique code which typically describes a product, like a CD or a book. You can look this code up on the internet to find prices, reviews, and more.</p>\n<p>If you scan a book, you can also search the contents of the book for a word or phrase, and find all the pages where it appears:</p>\n<p class=\"imgcenter\"><img src=\"../images/search-book-contents.jpg\"/></p>\n</body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-en/about2d.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title>About 2D barcodes</title>\n<link rel=\"stylesheet\" href=\"../style.css\" type=\"text/css\"/>\n</head>\n<body>\n<p><strong>Barcode Scanner</strong> also understands how to read two dimensional barcodes, like QR Codes and Data Matrix codes. For example, the codes below contain a hyperlink to the ZXing Project home page:</p>\n<p class=\"imgcenter\">\n  <img src=\"../images/big-qr.png\"/>\n  <img src=\"../images/big-datamatrix.png\"/>\n</p>\n<p>You can also represent contact information in a QR Code, and put it on a business card or web site. When you scan it, the results screen provides a choice of actions:</p>\n<p class=\"imgcenter\"><img src=\"../images/contact-results-screen.jpg\"/></p>\n<p>Besides URLs and contact info, QR Codes can also contain:</p>\n<ul>\n  <li>Calendar events, which you can add to your Calendar</li>\n  <li>Phone numbers, which you can dial</li>\n  <li>SMS numbers, which you can text message</li>\n  <li>Email addresses, which you can email</li>\n  <li>Geographic coordinates, which you can open in Maps</li>\n  <li>Plain text, which you can read, then share with a friend</li>\n</ul>\n</body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-en/index.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title>Barcode Scanner Help</title>\n<link rel=\"stylesheet\" href=\"../style.css\" type=\"text/css\"/>\n</head>\n<body>\n<p><strong>Barcode Scanner 4.3.1</strong></p>\n<p>The official Android app of the open source ZXing project:<br/>\n<a href=\"http://code.google.com/p/zxing\">http://code.google.com/p/zxing</a></p>\n<p>Barcode Scanner uses the camera on your phone to read barcodes and look up product information such as prices and reviews.</p>\n<p class=\"imgcenter\"><img src=\"../images/scan-example.png\"/></p>\n<p>It also reads 2D barcodes such as QR Codes and Data Matrix. These can contain links to web sites, contact information such as phone numbers and email addresses, and more.</p>\n<ul class=\"touchable\">\n  <li><a href=\"whatsnew.html\">What's new in this version</a></li>\n  <li><a href=\"scanning.html\">How to scan</a></li>\n  <li><a href=\"about1d.html\">About 1D barcodes</a></li>\n  <li><a href=\"about2d.html\">About 2D barcodes</a></li>\n  <li><a href=\"sharing.html\">How to create QR Codes</a></li>\n</ul>\n</body>\n</html>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-en/scanning.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title>How to scan</title>\n<link rel=\"stylesheet\" href=\"../style.css\" type=\"text/css\"/>\n</head>\n<body>\n<p>Barcode Scanner continuously scans a square region shown on your screen -- just line up the phone so the barcode is completely inside the viewfinder rectangle:</p>\n<p class=\"imgcenter\"><img src=\"../images/demo-yes.png\" style=\"padding:5px\"/><img src=\"../images/demo-no.png\" style=\"padding:5px\"/></p>\n<p>1D barcodes like those found on products require a phone with autofocus. Without it, only QR Codes and Data Matrix codes will be scannable.</p>\n<p>When a barcode is read, a beep sound will play and you'll see the results of the scan, a description of what the barcode contains, and options to take action on the contents.</p>\n<p>If you're having trouble scanning, make sure to hold the phone steady. If the camera is unable to focus, try moving the phone further or closer from the barcode.</p>\n<ul class=\"touchable\">\n  <li><a href=\"about1d.html\">About 1D barcodes</a></li>\n  <li><a href=\"about2d.html\">About 2D barcodes</a></li>\n</ul>\n</body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-en/sharing.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title>How to create QR Codes</title>\n<link rel=\"stylesheet\" href=\"../style.css\" type=\"text/css\"/>\n</head>\n<body>\n<p>In addition to scanning 2D barcodes, Barcode Scanner can also generate a QR Code and display it on your screen. Then you can show it to a friend, and let them scan the barcode with their phone:</p>\n<p class=\"imgcenter\"><img src=\"../images/scan-from-phone.png\"/></p>\n<p>To use this feature, press the Menu button from the main scanning screen, and tap Share. Then choose whether you want to share a contact, a bookmark, an application, or the contents of the clipboard. A QR Code will be generated automatically. When you're done, press Back or Home.</p>\n<p>To generate QR Codes from your computer, try the ZXing QR Code Generator: <a href=\"http://zxing.appspot.com/generator/\">http://zxing.appspot.com/generator/</a></p>\n</body>\n</html>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-en/whatsnew.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title>What's new in Barcode Scanner</title>\n<link rel=\"stylesheet\" href=\"../style.css\" type=\"text/css\"/>\n</head>\n<body>\n<p>New in version 4.3.1:</p>\n<ul>\n  <li>Disabled exposure control as it caused problems on several buggy devices</li>\n  <li>Other small bug fixes</li>\n</ul>\n</body>\n</html>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-es/about1d.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> Acerca de los códigos de barras 1D </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p> Códigos de barras tradicionales, tales como las impresas en el embalaje del producto, se conocen también como uno códigos de barras bidimensionales. Existen varios tipos de uso común, incluyendo UPC y EAN. La mayoría de aspecto similar a este: </p>\n<p class=\"imgcenter\"><img src=\"../images/big-1d.png\"/></p>\n<p> Estos códigos de barras 1D contiene un código único que generalmente describe un producto, como un CD o un libro. Usted puede ver este código en el Internet para encontrar precios, comentarios y más. </p>\n<p> Si digitaliza un libro, también puede buscar en el contenido del libro para una palabra o frase, y encontrar todas las páginas en las que aparece: </p>\n<p class=\"imgcenter\"><img src=\"../images/search-book-contents.jpg\"/></p>\n<p>Traducido por Google Translate.</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-es/about2d.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> Acerca de los códigos de barras 2D </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p><strong> Barcode Scanner </strong> También entiende cómo leer dos códigos de barras bidimensionales, como los códigos QR y códigos Data Matrix. Por ejemplo, los códigos que siguen contienen un hipervínculo a la página principal de Project ZXing: </p>\n<p class=\"imgcenter\">\n  <img src=\"../images/big-qr.png\"/>\n  <img src=\"../images/big-datamatrix.png\"/>\n</p>\n<p> También puede representar la información de contacto en un código QR, y lo puso en una tarjeta de visita o en el sitio web. Cuando se escanea, la pantalla de resultados se ofrecen una serie de acciones: </p>\n<p class=\"imgcenter\"><img src=\"../images/contact-results-screen.jpg\"/></p>\n<p> Además de las direcciones URL y la información de contacto, los códigos QR también puede contener: </p>\n<ul>\n  <li> Los eventos del calendario, que se pueden añadir a su calendario </li>\n  <li> Los números de teléfono, que puede marcar </li>\n  <li> SMS números, que puede mensaje de texto </li>\n  <li> Direcciones de correo electrónico, que se puede enviar por correo electrónico </li>\n  <li> Coordenadas Geográficas, que se puede abrir en Mapas </li>\n  <li> Texto sin formato, que se puede leer, compartir con un amigo </li>\n</ul>\n<p>Traducido por Google Translate.</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-es/index.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> Barcode Scanner Ayuda </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p><strong>Barcode Scanner 4.3.1</strong></p>\n<p> La aplicación oficial de Android del proyecto de código abierto ZXing:<br/>\n<a href=\"http://code.google.com/p/zxing\"> http://code.google.com/p/zxing </a></p>\n<p> Barcode Scanner utiliza la cámara de su móvil para leer códigos de barras y buscar información sobre los productos como los precios y las revisiones. </p>\n<p class=\"imgcenter\"><img src=\"../images/scan-example.png\"/></p>\n<p> También lee los códigos de barras 2D, como los Códigos QR y Data Matrix. Estos pueden contener enlaces a otros sitios web, información de contacto, como números de teléfono y direcciones de correo electrónico y mucho más. </p>\n<ul class=\"touchable\">\n  <li><a href=\"whatsnew.html\"> ¿Qué hay de nuevo en esta versión? </a></li>\n  <li><a href=\"scanning.html\"> Cómo analizar </a></li>\n  <li><a href=\"about1d.html\"> Acerca de los códigos de barras 1D </a></li>\n  <li><a href=\"about2d.html\"> Acerca de los códigos de barras 2D </a></li>\n  <li><a href=\"sharing.html\"> Cómo crear códigos QR </a></li>\n</ul>\n<p>Traducido por Google Translate.</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-es/scanning.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> Cómo analizar </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p> Barcode Scanner escanea continuamente una región cuadrada que aparece en su pantalla - Sólo basta definir el teléfono de modo que el código de barras es completamente dentro del rectángulo del visor: </p>\n<p class=\"imgcenter\"><img src=\"../images/demo-yes.png\" style=\"padding:5px\"/><img src=\"../images/demo-no.png\" style=\"padding:5px\"/></p>\n<p> Códigos de barras 1D, como las que se encuentran en los productos requieren un teléfono con enfoque automático. Sin él, sólo los códigos QR y códigos Data Matrix será susceptible de ser analizada. </p>\n<p> Cuando un código de barras es leído, un sonido se reproducirá y podrás ver los resultados del análisis, una descripción de lo que contiene el código de barras, y las opciones para tomar acción sobre los contenidos. </p>\n<p> Si usted está teniendo problemas de escaneo, asegúrese de sujetar el teléfono fijo. Si la cámara no puede enfocar, mueva el teléfono más lejos o más cerca del código de barras. </p>\n<ul class=\"touchable\">\n  <li><a href=\"about1d.html\"> Acerca de los códigos de barras 1D </a></li>\n  <li><a href=\"about2d.html\"> Acerca de los códigos de barras 2D </a></li>\n</ul>\n<p>Traducido por Google Translate.</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-es/sharing.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> Cómo crear códigos QR </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p> Además de escanear códigos de barras 2D, escáner de código de barras también puede generar un código QR y lo mostrará en la pantalla. A continuación, puede mostrar a un amigo, y dejar que escanear el código de barras con su teléfono: </p>\n<p class=\"imgcenter\"><img src=\"../images/scan-from-phone.png\"/></p>\n<p> Para utilizar esta función, presione el botón Menú en la pantalla de exploración principal y toque Compartir. A continuación, seleccione si desea compartir un contacto, un marcador, una aplicación o el contenido del portapapeles. Un código QR se generará automáticamente. Cuando haya terminado, pulse Atrás o Inicio. </p>\n<p> Para generar códigos QR desde su computadora, pruebe el generador ZXing Código QR: <a href=\"http://zxing.appspot.com/generator/\"> http://zxing.appspot.com/generator/ </a></p>\n<p>Traducido por Google Translate.</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-es/whatsnew.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> ¿Qué hay de nuevo en Barcode Scanner </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p> Nuevo en la versión 4.3.1: </p>\n<ul>\n  <li> Desactivado el control de exposición ya que causó problemas en los dispositivos con errores varios </li>\n  <li> Otras pequeñas correcciones de errores </li>\n</ul>\n<p>Traducido por Google Translate.</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-fr/about1d.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> À propos de codes à barres 1D </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p> Codes à barres traditionnels, tels que ceux imprimés sur l'emballage du produit, sont également connus comme une dimension codes à barres. Il existe plusieurs types couramment utilisés, y compris l'UPC et EAN. La plupart ressembler à ceci: </p>\n<p class=\"imgcenter\"><img src=\"../images/big-1d.png\"/></p>\n<p> Ces codes à barres 1D contient un code unique qui décrit typiquement un produit, comme un CD ou un livre. Vous pouvez regarder ce code sur internet pour trouver les prix, critiques et autres. </p>\n<p> Si vous numérisez un livre, vous pouvez également rechercher le contenu du livre pour un mot ou une phrase, et de trouver toutes les pages où il apparaît: </p>\n<p class=\"imgcenter\"><img src=\"../images/search-book-contents.jpg\"/></p>\n<p>Traduit par Google Translate.</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-fr/about2d.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> À propos de codes-barres 2D </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p><strong> Barcode Scanner </strong> comprend également comment lire deux dimensions, comme les codes-barres QR Codes et les codes Data Matrix. Par exemple, les codes ci-dessous contiennent un lien hypertexte vers la page d'accueil du projet ZXing: </p>\n<p class=\"imgcenter\">\n  <img src=\"../images/big-qr.png\"/>\n  <img src=\"../images/big-datamatrix.png\"/>\n</p>\n<p> Vous pouvez également représenter des informations de contact dans un QR Code, et le mettre sur une carte de visite ou un site Web. Lorsque vous scannez, l'écran de résultats fournit un choix d'actions: </p>\n<p class=\"imgcenter\"><img src=\"../images/contact-results-screen.jpg\"/></p>\n<p> Outre les URL et les informations de contact, les codes QR peuvent aussi contenir: </p>\n<ul>\n  <li> Calendrier des événements que vous pouvez ajouter à votre agenda </li>\n  <li> Les numéros de téléphone que vous pouvez composer </li>\n  <li> Numéros SMS, que vous pouvez Texte du message </li>\n  <li> Adresses e-mail, que vous pouvez envoyer un courriel </li>\n  <li> Coordonnées géographiques, que vous pouvez ouvrir dans Google Maps </li>\n  <li> Texte, que vous pouvez lire, puis partager avec un ami </li>\n</ul>\n<p>Traduit par Google Translate.</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-fr/index.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> Aide Barcode Scanner </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p><strong>Barcode Scanner 4.3.1</strong></p>\n<p> L'application officielle Android du projet ZXing open source:<br/>\n<a href=\"http://code.google.com/p/zxing\"> http://code.google.com/p/zxing </a></p>\n<p> Barcode Scanner utilise la caméra de votre téléphone pour lire des codes barres et de rechercher des informations sur des produits tels que les prix et les critiques. </p>\n<p class=\"imgcenter\"><img src=\"../images/scan-example.png\"/></p>\n<p> Il lit également les codes à barres 2D tels que les codes QR et Data Matrix. Ceux-ci peuvent contenir des liens vers des sites Web, communiquer avec des informations telles que les numéros de téléphone et adresses e-mail, et plus encore. </p>\n<ul class=\"touchable\">\n  <li><a href=\"whatsnew.html\"> Quoi de neuf dans cette version </a></li>\n  <li><a href=\"scanning.html\"> Comment numériser </a></li>\n  <li><a href=\"about1d.html\"> À propos de codes à barres 1D </a></li>\n  <li><a href=\"about2d.html\"> À propos de codes-barres 2D </a></li>\n  <li><a href=\"sharing.html\"> Comment créer des codes QR </a></li>\n</ul>\n<p>Traduit par Google Translate.</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-fr/scanning.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> Comment numériser </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p> Barcode Scanner scanne en permanence une zone carrée affichée sur votre écran - ligne juste le téléphone de sorte que le code à barres est complètement à l'intérieur du rectangle du viseur: </p>\n<p class=\"imgcenter\"><img src=\"../images/demo-yes.png\" style=\"padding:5px\"/><img src=\"../images/demo-no.png\" style=\"padding:5px\"/></p>\n<p> Codes à barres 1D comme ceux qu'on trouve sur les produits nécessitent un téléphone avec autofocus. Sans elle, seuls les codes QR et les codes Data Matrix sera analysable. </p>\n<p> Quand un code-barres est lu, un bip sonore se jouer et vous verrez les résultats de l'analyse, une description de ce que le code à barres contient, et les options à prendre des mesures sur le contenu. </p>\n<p> Si vous rencontrez des problèmes de numérisation, assurez-vous de tenir le téléphone fixe. Si l'appareil photo est incapable de se concentrer, essayez de déplacer le téléphone supplémentaire ou plus près du code à barres. </p>\n<ul class=\"touchable\">\n  <li><a href=\"about1d.html\"> À propos de codes à barres 1D </a></li>\n  <li><a href=\"about2d.html\"> À propos de codes-barres 2D </a></li>\n</ul>\n<p>Traduit par Google Translate.</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-fr/sharing.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> Comment créer des codes QR </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p> En plus de la numérisation des codes à barres 2D, Barcode Scanner peut aussi générer un QR Code et l'afficher sur votre écran. Ensuite, vous pouvez le montrer à un ami, et laissez-les scanner le code-barres avec leur téléphone: </p>\n<p class=\"imgcenter\"><img src=\"../images/scan-from-phone.png\"/></p>\n<p> Pour utiliser cette fonction, appuyez sur la touche Menu depuis l'écran du balayage principal, puis appuyez sur Partager. Ensuite, choisissez si vous voulez partager un contact, un signet, une application ou le contenu du presse-papiers. Un Code QR est généré automatiquement. Lorsque vous avez terminé, appuyez sur Retour ou d'accueil. </p>\n<p> Pour générer les codes QR à partir de votre ordinateur, essayez le générateur de code QR ZXing: <a href=\"http://zxing.appspot.com/generator/\"> http://zxing.appspot.com/generator/ </a></p>\n<p>Traduit par Google Translate.</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-fr/whatsnew.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> Quoi de neuf dans Barcode Scanner </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p> Nouveau dans la version 4.3.1: </p>\n<ul>\n  <li> Désactivé contrôle de l'exposition que cela causait des problèmes sur les appareils de buggy plusieurs </li>\n  <li> D'autres petites corrections de bugs </li>\n</ul>\n<p>Traduit par Google Translate.</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-it/about1d.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> A proposito di codici a barre 1D </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p> Codici a barre tradizionali, come quelle stampate sulla confezione del prodotto, sono noti anche come uno codici a barre bidimensionali. Ci sono diversi tipi di uso comune, tra cui UPC ed EAN. La maggior parte simile al seguente: </p>\n<p class=\"imgcenter\"><img src=\"../images/big-1d.png\"/></p>\n<p> Queste barre 1D contengono un codice unico che descrive tipicamente un prodotto, come un CD o un libro. È possibile cercare questo codice su internet per trovare i prezzi, recensioni e altro. </p>\n<p> Se si esegue la scansione di un libro, è anche possibile cercare i contenuti del libro per una parola o una frase, e trovare tutte le pagine in cui appare: </p>\n<p class=\"imgcenter\"><img src=\"../images/search-book-contents.jpg\"/></p>\n<p>Tradotto da Google Translate.</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-it/about2d.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> A proposito di codici a barre 2D </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p><strong> Barcode Scanner </strong> comprende anche come leggere due codici a barre bidimensionali, come i codici QR e codici Data Matrix. Per esempio, i seguenti codici contengono un collegamento ipertestuale alla pagina ZXing principale del progetto: </p>\n<p class=\"imgcenter\">\n  <img src=\"../images/big-qr.png\"/>\n  <img src=\"../images/big-datamatrix.png\"/>\n</p>\n<p> È anche possibile rappresentare le informazioni di contatto in un QR Code, e metterlo su un biglietto da visita o un sito web. Quando si esegue la scansione, la schermata dei risultati fornisce una serie di azioni: </p>\n<p class=\"imgcenter\"><img src=\"../images/contact-results-screen.jpg\"/></p>\n<p> Oltre URL e informazioni di contatto, i codici QR possono contenere anche: </p>\n<ul>\n  <li> Eventi del Calendario, che è possibile aggiungere al vostro calendario </li>\n  <li> I numeri di telefono, che possono essere digitati </li>\n  <li> Numeri di SMS, che è possibile il testo del messaggio </li>\n  <li> Indirizzi e-mail, che possono essere inviati per email </li>\n  <li> Coordinate geografiche, che è possibile aprire in Mappe </li>\n  <li> Testo semplice, che si può leggere, quindi condividere con un amico </li>\n</ul>\n<p>Tradotto da Google Translate.</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-it/index.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> Barcode Scanner Aiuto </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p><strong>Barcode Scanner 4.3.1</strong></p>\n<p> L'applicazione ufficiale di Android del progetto aperto ZXing fonte:<br/>\n<a href=\"http://code.google.com/p/zxing\"> http://code.google.com/p/zxing </a></p>\n<p> Scanner di codici a barre utilizza la fotocamera del telefono per leggere codici a barre e ricercare informazioni sui prodotti, i prezzi e le recensioni. </p>\n<p class=\"imgcenter\"><img src=\"../images/scan-example.png\"/></p>\n<p> Legge anche codici a barre 2D, come i codici QR e Data Matrix. Questi possono contenere link a siti web, informazioni di contatto, quali numeri di telefono e indirizzi e-mail e altro ancora. </p>\n<ul class=\"touchable\">\n  <li><a href=\"whatsnew.html\"> Cosa c'è di nuovo in questa versione </a></li>\n  <li><a href=\"scanning.html\"> Come eseguire la scansione </a></li>\n  <li><a href=\"about1d.html\"> A proposito di codici a barre 1D </a></li>\n  <li><a href=\"about2d.html\"> A proposito di codici a barre 2D </a></li>\n  <li><a href=\"sharing.html\"> Come creare codici QR </a></li>\n</ul>\n<p>Tradotto da Google Translate.</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-it/scanning.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> Come eseguire la scansione </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p> Barcode Scanner analizza continuamente una regione quadrata mostrata sullo schermo - solo linea il telefono in modo che il codice a barre è completamente all'interno del rettangolo del mirino: </p>\n<p class=\"imgcenter\"><img src=\"../images/demo-yes.png\" style=\"padding:5px\"/><img src=\"../images/demo-no.png\" style=\"padding:5px\"/></p>\n<p> Codici a barre 1D, come quelle che si trovano sui prodotti richiede un telefono con autofocus. Senza di essa, solo i codici QR e codici Data Matrix sarà leggibile. </p>\n<p> Quando un codice a barre viene letto, un bip si giocare e vedrete i risultati della scansione, una descrizione di ciò che il codice a barre contiene, e le opzioni per intervenire sui contenuti. </p>\n<p> Se hai dei problemi di scansione, assicurarsi di tenere il telefono fermo. Se la fotocamera non riesce a mettere a fuoco, provare a spostare il telefono lontano o più vicino dal codice a barre. </p>\n<ul class=\"touchable\">\n  <li><a href=\"about1d.html\"> A proposito di codici a barre 1D </a></li>\n  <li><a href=\"about2d.html\"> A proposito di codici a barre 2D </a></li>\n</ul>\n<p>Tradotto da Google Translate.</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-it/sharing.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> Come creare codici QR </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p> Oltre alla scansione di codici a barre 2D, Barcode Scanner può anche generare un codice QR e visualizzarla sullo schermo. Poi si può mostrare ad un amico, e far loro eseguire la scansione del codice a barre con il proprio telefono: </p>\n<p class=\"imgcenter\"><img src=\"../images/scan-from-phone.png\"/></p>\n<p> Per utilizzare questa funzione, premere il tasto Menu dalla schermata di scansione principale, e toccare Condividi. Quindi scegliere se si desidera condividere un contatto, un segnalibro, un'applicazione, o il contenuto degli appunti. Un codice a barre verrà generato automaticamente. Al termine, premere Indietro o Home. </p>\n<p> Per generare i codici QR dal tuo computer, provare il generatore di ZXing QR Code: <a href=\"http://zxing.appspot.com/generator/\"> http://zxing.appspot.com/generator/ </a></p>\n<p>Tradotto da Google Translate.</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-it/whatsnew.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> Cosa c'è di nuovo nella Barcode Scanner </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p> Nuovo nella versione 4.3.1: </p>\n<ul>\n  <li> Disabilitato il controllo dell'esposizione, ha causato problemi su dispositivi diversi buggy </li>\n  <li> Altre correzioni di bug piccoli </li>\n</ul>\n<p>Tradotto da Google Translate.</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-ja/about1d.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> 1Dバーコードについて </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p> そのような製品パッケージに印刷されるような伝統的なバーコードもまた、1次元バーコードとして知られています。 UPCとEANなど、一般的に使用されるいくつかの種類があります。ほとんどはこれに似ているように見えます： </p>\n<p class=\"imgcenter\"><img src=\"../images/big-1d.png\"/></p>\n<p> これらの1Dバーコードは、通常、CDや本のように、製品を説明する固有のコードが含まれています。あなたは、価格やレビューなどを見つけるために、インターネット上でこのコードを調べることができます。 </p>\n<p> あなたが本をスキャンする場合は、単語やフレーズの本の内容を検索して、それが表示されるすべてのページを見つけることができます： </p>\n<p class=\"imgcenter\"><img src=\"../images/search-book-contents.jpg\"/></p>\n<p>Google翻訳で翻訳。</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-ja/about2d.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> 約二次元バーコード </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p><strong> バーコードスキャナ </strong> また、QRコードとデータマトリックスコードのような2次元バーコードを読み取る方法を理解しています。たとえば、以下のコードは、ZXingプロジェクトのホーム·ページへのハイパーリンクが含まれています。 </p>\n<p class=\"imgcenter\">\n  <img src=\"../images/big-qr.png\"/>\n  <img src=\"../images/big-datamatrix.png\"/>\n</p>\n<p> また、QRコードで連絡先情報を表しており、名刺やWebサイト上でそれを置くことができます。あなたがそれをスキャンすると、結果画面には、アクションの選択肢を提供します： </p>\n<p class=\"imgcenter\"><img src=\"../images/contact-results-screen.jpg\"/></p>\n<p> URLや連絡先情報のほかに、QRコードも含めることができます。 </p>\n<ul>\n  <li> あなたのカレンダーに追加できるカレンダーイベント、 </li>\n  <li> あなたがダイヤルできる電話番号は、 </li>\n  <li> あなたがテキストメッセージできるSMS番号、 </li>\n  <li> あなたが電子メールで送ることができ、電子メールアドレス、 </li>\n  <li> あなたがマップで開くことができ、地理座標、 </li>\n  <li> あなたが読むことができるプレーンテキストは、その後、友人と共有 </li>\n</ul>\n<p>Google翻訳で翻訳。</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-ja/index.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> バーコードスキャナのヘルプ </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p><strong>Barcode Scanner 4.3.1</strong></p>\n<p> オープンソースZXingプロジェクトの公式Androidアプリ：<br/>\n<a href=\"http://code.google.com/p/zxing\"> http://code.google.com/p/zxing </a></p>\n<p> バーコードスキャナは、バーコードを読み取ると、価格やレビューなどの製品情報をルックアップするためにお使いの携帯電話のカメラを使用しています。 </p>\n<p class=\"imgcenter\"><img src=\"../images/scan-example.png\"/></p>\n<p> また、そのようなQRコードとデータマトリクスとして2次元バーコードを読み取ります。これらは、ウェブサイト、電話番号や電子メールアドレス、その他などの連絡先情報へのリンクを含めることができます。 </p>\n<ul class=\"touchable\">\n  <li><a href=\"whatsnew.html\"> このバージョンの新機能 </a></li>\n  <li><a href=\"scanning.html\"> スキャンする方法 </a></li>\n  <li><a href=\"about1d.html\"> 1Dバーコードについて </a></li>\n  <li><a href=\"about2d.html\"> 約二次元バーコード </a></li>\n  <li><a href=\"sharing.html\"> どのようにQRコードを作成する </a></li>\n</ul>\n<p>Google翻訳で翻訳。</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-ja/scanning.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> スキャンする方法 </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p> ：バーコードが完全にファインダーの四角形の内部にあるので、電話最大ちょうどライン - バーコードスキャナは、連続して、画面に表示される正方形の領域をスキャン </p>\n<p class=\"imgcenter\"><img src=\"../images/demo-yes.png\" style=\"padding:5px\"/><img src=\"../images/demo-no.png\" style=\"padding:5px\"/></p>\n<p> 商品で見られるような1Dバーコードは、オートフォーカス機能付きの携帯電話を必要とします。それがなければ、唯一のQRコードとデータマトリクスコードがスキャン可能になります。 </p>\n<p> バーコードが読み取られると、ビープ音が鳴り、あなたは、スキャン、バーコードが含まれている内容の説明、およびコンテンツに対してアクションを実行するためのオプションの結果が表示されます。 </p>\n<p> あなたは、スキャンのトラブルを抱えている場合は、電話機をしっかりと抑えていることを確認してください。ピントが合っていませんであれば、バーコードからさらなるまたは近い電話を動かしてみてください。 </p>\n<ul class=\"touchable\">\n  <li><a href=\"about1d.html\"> 1Dバーコードについて </a></li>\n  <li><a href=\"about2d.html\"> 約二次元バーコード </a></li>\n</ul>\n<p>Google翻訳で翻訳。</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-ja/sharing.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> どのようにQRコードを作成する </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p> 2Dバーコードをスキャンするだけでなく、バーコードスキャナもQRコードを生成することができ、あなたの画面上に表示。その後、友人にそれを見せ、それらを自分の携帯電話でバーコードをスキャンさせることができます： </p>\n<p class=\"imgcenter\"><img src=\"../images/scan-from-phone.png\"/></p>\n<p> この機能を使用するには、主走査画面からメニューボタンを押して、共有をタップします。次に、あなたが連絡先、ブックマーク、アプリケーション、またはクリップボードの内容を共有したいと思うかどうかを選択します。 QRコードが自動的に生成されます。設定が完了したら、[戻る]または[ホームキーを押します。 </p>\n<p> お使いのコンピュータからQRコードを生成するには、ZXingのQRコードジェネレータを試してください： <a href=\"http://zxing.appspot.com/generator/\"> http://zxing.appspot.com/generator/ </a></p>\n<p>Google翻訳で翻訳。</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-ja/whatsnew.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> バーコードスキャナの新機能 </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p> バージョン4.3.1の新機能： </p>\n<ul>\n  <li> それはいくつかのバグのデバイスで問題が発生した露光制御を無効にして </li>\n  <li> その他の小さなバグ修正 </li>\n</ul>\n<p>Google翻訳で翻訳。</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-ko/about1d.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> 1D 바코드 정보 </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p> 이러한 제품 포장에 인쇄 된 것과 같은 전통적인 바코드는도 1 차원 바코드로 알려져 있습니다. UPC 및 EAN 등 일반적으로 사용되는 여러 종류가 있습니다. 대부분은 다음과 유사 : </p>\n<p class=\"imgcenter\"><img src=\"../images/big-1d.png\"/></p>\n<p> 이 1D 바코드는 일반적으로 CD 나 책 같은 제품을 설명하는 고유 한 코드가 포함되어 있습니다. 당신은 가격, 리뷰 등을 찾아 인터넷에서이 코드를 찾아 볼 수 있습니다. </p>\n<p> 당신은 책을 스캔 할 경우, 당신은 또한 단어 나 문구에 대한 책의 내용을 검색하고 표시 모든 페이지를 찾을 수 있습니다 : </p>\n<p class=\"imgcenter\"><img src=\"../images/search-book-contents.jpg\"/></p>\n<p>Google 번역을 통해 번역.</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-ko/about2d.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> 에 대한 2 차원 바코드 </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p><strong> 바코드 스캐너 </strong> 또한, QR 코드 및 데이터 매트릭스 코드와 같은 2 차원 바코드를 읽는 방법을 이해하고 있습니다. 예를 들어, 아래의 코드는 ZXing 프로젝트 홈 페이지에 하이퍼 링크를 포함 : </p>\n<p class=\"imgcenter\">\n  <img src=\"../images/big-qr.png\"/>\n  <img src=\"../images/big-datamatrix.png\"/>\n</p>\n<p> 당신은 또한 QR 코드에 연락처 정보를 나타냅니다, 그리고 명함 또는 웹 사이트에 넣을 수 있습니다. 당신이 그것을 스캔하면 결과 화면이 작업의 선택을 제공합니다 : </p>\n<p class=\"imgcenter\"><img src=\"../images/contact-results-screen.jpg\"/></p>\n<p> URL 및 연락처 정보 외에, QR 코드도 포함 할 수 있습니다 : </p>\n<ul>\n  <li> 귀하의 캘린더에 추가 할 수있는 캘린더 이벤트, </li>\n  <li> 당신이 전화를 걸 수 전화 번호, </li>\n  <li> 당신은 문자 메시지를 보낼 수있는 SMS 번호, </li>\n  <li> 당신은 이메일을 보낼 수 이메일 주소 </li>\n  <li> 당신이지도에서 열 수있는 지리 좌표, </li>\n  <li> 당신이 읽을 수있는 일반 텍스트는 다음 친구와 공유 </li>\n</ul>\n<p>Google 번역을 통해 번역.</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-ko/index.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> 바코드 스캐너 도움말 </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p><strong>Barcode Scanner 4.3.1</strong></p>\n<p> 오픈 소스 ZXing 프로젝트의 공식 안드로이드 응용 프로그램 :<br/>\n<a href=\"http://code.google.com/p/zxing\"> http://code.google.com/p/zxing </a></p>\n<p> 바코드 스캐너는 바코드를 읽어와 같은 가격과 리뷰 등의 제품 정보를 조회 할 휴대 전화의 카메라를 사용합니다. </p>\n<p class=\"imgcenter\"><img src=\"../images/scan-example.png\"/></p>\n<p> 그것은 또한 QR 코드와 데이터 매트릭스와 같은 2 차원 바코드를 읽습니다. 이러한 웹 사이트에 대한 링크를 포함 할 수 있습니다, 같은 전화 번호와 이메일 주소 등의 정보를 문의하십시오. </p>\n<ul class=\"touchable\">\n  <li><a href=\"whatsnew.html\"> 이 버전의 새로운 기능 </a></li>\n  <li><a href=\"scanning.html\"> 스캔하는 방법 </a></li>\n  <li><a href=\"about1d.html\"> 1D 바코드 정보 </a></li>\n  <li><a href=\"about2d.html\"> 에 대한 2 차원 바코드 </a></li>\n  <li><a href=\"sharing.html\"> 어떻게 QR 코드를 만드는 방법 </a></li>\n</ul>\n<p>Google 번역을 통해 번역.</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-ko/scanning.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> 스캔하는 방법 </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p> : 바코드가 완전히 뷰 파인더의 사각형 안에하도록 전화, 조금만 라인 - 바코드 스캐너는 지속적으로 화면에 표시 사각형 영역을 검사 </p>\n<p class=\"imgcenter\"><img src=\"../images/demo-yes.png\" style=\"padding:5px\"/><img src=\"../images/demo-no.png\" style=\"padding:5px\"/></p>\n<p> 제품에서 발견 된 것과 같은 1D 바코드는 자동 초점과 전화를해야합니다. 가 없으면 만 QR 코드와 데이터 매트릭스 코드는 확인 가능한 것입니다. </p>\n<p> 바코드를 읽을 때, 삐 소리가 재생됩니다 그리고 당신은 스캔, 바코드의 내용이 뭔지 설명 및 내용에 조치를 취할 수있는 옵션의 결과를 볼 수 있습니다. </p>\n<p> 당신은 문제가 검색하는 데 문제가있는 경우 휴대 전화가 정상 상태에 있는지 확인하십시오. 카메라가 초점을 맞출 수없는 경우, 바코드에서 더 또는 더 가까이 휴대 전화를 이동하십시오. </p>\n<ul class=\"touchable\">\n  <li><a href=\"about1d.html\"> 1D 바코드 정보 </a></li>\n  <li><a href=\"about2d.html\"> 에 대한 2 차원 바코드 </a></li>\n</ul>\n<p>Google 번역을 통해 번역.</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-ko/sharing.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> 어떻게 QR 코드를 만드는 방법 </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p> 2D 바코드를 스캔뿐만 아니라, 바코드 스캐너는 QR 코드를 생성 할 수 있으며 화면에 표시됩니다. 그럼 당신은 친구에게 보여, 그 자신의 휴대 전화로 바코드를 스캔하도록 할 수 있습니다 : </p>\n<p class=\"imgcenter\"><img src=\"../images/scan-from-phone.png\"/></p>\n<p> 이 기능을 사용하려면 기본 검색 화면에서 메뉴 버튼을 누르면,하고 공유를 누릅니다. 그런 다음 연락처, 즐겨 찾기, 응용 프로그램 또는 클립 보드의 내용을 공유할지 여부를 선택합니다. QR 코드가 자동으로 생성됩니다. 이 완료되면, 뒤로 또는 홈을 누릅니다. </p>\n<p> 컴퓨터에서 QR 코드를 생성하려면 ZXing QR 코드 생성기를 사용해 : <a href=\"http://zxing.appspot.com/generator/\"> http://zxing.appspot.com/generator/ </a></p>\n<p>Google 번역을 통해 번역.</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-ko/whatsnew.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> 바코드 스캐너의 새로운 기능 </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p> 버전 4.3.1의 새로운 기능 : </p>\n<ul>\n  <li> 그것은 여러 버그가 장치에 문제를 야기로 노출 제어를 비활성화 </li>\n  <li> 기타 작은 버그 수정 </li>\n</ul>\n<p>Google 번역을 통해 번역.</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-nl/about1d.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> Over 1D barcodes </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p> Traditionele barcodes, zoals gedrukt op de verpakking, ook bekend als eendimensionale barcodes. Er zijn verschillende types gebruikt, zoals UPC en EAN. De meeste lijken op deze: </p>\n<p class=\"imgcenter\"><img src=\"../images/big-1d.png\"/></p>\n<p> Deze 1D barcodes bevatten een unieke code die typisch beschrijft een product, zoals een cd of een boek. U kunt kijken deze code op het internet om de prijzen, reviews en nog veel meer te vinden. </p>\n<p> Als u scant een boek, kunt u ook zoeken in de inhoud van het boek voor een woord of zin, en vind alle pagina's waar het verschijnt: </p>\n<p class=\"imgcenter\"><img src=\"../images/search-book-contents.jpg\"/></p>\n<p>Vertaald door Google Translate.</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-nl/about2d.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> Over 2D barcodes </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p><strong> Barcode Scanner </strong> begrijpt ook hoe om te lezen tweedimensionale barcodes, zoals QR Codes en Data Matrix codes. Bijvoorbeeld, de volgende codes bevatten een hyperlink naar de ZXing Project home page: </p>\n<p class=\"imgcenter\">\n  <img src=\"../images/big-qr.png\"/>\n  <img src=\"../images/big-datamatrix.png\"/>\n</p>\n<p> U kunt contactgegevens ook te vertegenwoordigen in een QR-code, en zet het op een visitekaartje of website. Als u het scannen, de resultaten scherm biedt een keuze van acties: </p>\n<p class=\"imgcenter\"><img src=\"../images/contact-results-screen.jpg\"/></p>\n<p> Naast URL's en contactgegevens, kunnen QR Codes bevatten: </p>\n<ul>\n  <li> Agenda-items, die u kunt toevoegen aan uw agenda </li>\n  <li> Telefoonnummers, die u kunt bellen </li>\n  <li> SMS-nummers, die u kunt SMS-bericht </li>\n  <li> E-mailadressen, die u kunt e-mailen </li>\n  <li> Geografische coördinaten, die u kunt openen in Google Maps </li>\n  <li> Platte tekst, die u kunt lezen, dan delen met een vriend </li>\n</ul>\n<p>Vertaald door Google Translate.</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-nl/index.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> Barcode Scanner Help </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p><strong>Barcode Scanner 4.3.1</strong></p>\n<p> De officiële Android app van de open source ZXing project:<br/>\n<a href=\"http://code.google.com/p/zxing\"> http://code.google.com/p/zxing </a></p>\n<p> Barcode Scanner maakt gebruik van de camera op je telefoon om barcodes te lezen en op te zoeken productinformatie, zoals prijzen en reviews. </p>\n<p class=\"imgcenter\"><img src=\"../images/scan-example.png\"/></p>\n<p> Het leest ook 2D barcodes zoals QR Codes en Data Matrix. Deze kunnen links naar websites bevatten, contactgegevens zoals telefoonnummers en e-mailadressen, en nog veel meer. </p>\n<ul class=\"touchable\">\n  <li><a href=\"whatsnew.html\"> Wat is nieuw in deze versie </a></li>\n  <li><a href=\"scanning.html\"> Hoe om te scannen </a></li>\n  <li><a href=\"about1d.html\"> Over 1D barcodes </a></li>\n  <li><a href=\"about2d.html\"> Over 2D barcodes </a></li>\n  <li><a href=\"sharing.html\"> Hoe kan ik QR Codes te creëren </a></li>\n</ul>\n<p>Vertaald door Google Translate.</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-nl/scanning.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> Hoe om te scannen </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p> Barcode Scanner scant continu een vierkant gebied op uw scherm - net line-up van de telefoon, zodat de barcode is helemaal in de zoeker rechthoek: </p>\n<p class=\"imgcenter\"><img src=\"../images/demo-yes.png\" style=\"padding:5px\"/><img src=\"../images/demo-no.png\" style=\"padding:5px\"/></p>\n<p> 1D barcodes zoals die gevonden op producten vereisen een telefoon met autofocus. Zonder dat zal alleen maar QR Codes en Data Matrix codes zijn leesbaar. </p>\n<p> Wanneer een barcode wordt gelezen, zal een pieptoon te spelen en zie je de resultaten van de scan, een beschrijving van wat de barcode bevat, en opties om actie te ondernemen op de inhoud. </p>\n<p> Als u problemen ondervindt bij het scannen, moet u Houd de telefoon stil. Als de camera niet kan scherpstellen, probeer dan het verplaatsen van de telefoon verder of dichter van de barcode. </p>\n<ul class=\"touchable\">\n  <li><a href=\"about1d.html\"> Over 1D barcodes </a></li>\n  <li><a href=\"about2d.html\"> Over 2D barcodes </a></li>\n</ul>\n<p>Vertaald door Google Translate.</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-nl/sharing.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> Hoe kan ik QR Codes te creëren </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p> In aanvulling op het scannen van 2D-barcodes, kan Barcode Scanner ook het genereren van een QR-code en geeft deze weer op het scherm. Dan kunt u laten zien aan een vriend, en laat ze de streepjescode scannen met hun telefoon: </p>\n<p class=\"imgcenter\"><img src=\"../images/scan-from-phone.png\"/></p>\n<p> Om deze functie te gebruiken, drukt u op de knop Menu van de belangrijkste scannen scherm en tik op Delen. Vervolgens kiest u of u een contact, een bladwijzer, een toepassing, of de inhoud van het klembord te delen. Een QR-code wordt automatisch gegenereerd. Als u klaar bent, drukt u op Terug of Home. </p>\n<p> Om QR Codes van uw computer te genereren, probeer dan de ZXing QR Code Generator: <a href=\"http://zxing.appspot.com/generator/\"> http://zxing.appspot.com/generator/ </a></p>\n<p>Vertaald door Google Translate.</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-nl/whatsnew.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> Wat is nieuw in Barcode Scanner </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p> Nieuw in versie 4.3.1: </p>\n<ul>\n  <li> Uitgeschakeld blootstelling beheersing als het veroorzaakt problemen op meerdere buggy apparaten </li>\n  <li> Andere kleine bugfixes </li>\n</ul>\n<p>Vertaald door Google Translate.</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-pt/about1d.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> Sobre códigos de barras 1D </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p> Códigos de barras tradicionais, tais como aqueles impressos nas embalagens dos produtos, são também conhecidos como um código de barras de dimensão. Existem vários tipos comumente usados, incluindo UPC e EAN. Mais semelhante a este: </p>\n<p class=\"imgcenter\"><img src=\"../images/big-1d.png\"/></p>\n<p> Estes códigos de barras 1D conter um código único, o qual geralmente descreve um produto, como um CD ou um livro. Você pode olhar este código na internet para pesquisar preços, opiniões, e muito mais. </p>\n<p> Se você digitalizar um livro, você também pode pesquisar o conteúdo do livro para uma palavra ou frase, e encontrar todas as páginas em que ele aparece: </p>\n<p class=\"imgcenter\"><img src=\"../images/search-book-contents.jpg\"/></p>\n<p>Traduzido pelo Google Translate.</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-pt/about2d.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> Sobre códigos de barras 2D </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p><strong> Barcode Scanner </strong> também entende como ler dois códigos de barras bidimensionais, como QR Codes e códigos Data Matrix. Por exemplo, os códigos abaixo contêm um link para a página do Projeto ZXing casa: </p>\n<p class=\"imgcenter\">\n  <img src=\"../images/big-qr.png\"/>\n  <img src=\"../images/big-datamatrix.png\"/>\n</p>\n<p> Você também pode representar informações de contato em um QR Code, e colocá-lo em um cartão de visita ou site. Quando você escaneá-lo, a tela de resultados fornece uma escolha de ações: </p>\n<p class=\"imgcenter\"><img src=\"../images/contact-results-screen.jpg\"/></p>\n<p> Além de URLs e informações de contato, QR Codes também pode conter: </p>\n<ul>\n  <li> Calendário de eventos, que você pode adicionar ao seu calendário </li>\n  <li> Os números de telefone, que você pode discar </li>\n  <li> Números de SMS, que você pode mensagem de texto </li>\n  <li> Endereços de e-mail, que você pode enviar e-mail </li>\n  <li> Coordenadas geográficas, que você pode abrir em Mapas </li>\n  <li> Texto simples, que você pode ler, em seguida, compartilhar com um amigo </li>\n</ul>\n<p>Traduzido pelo Google Translate.</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-pt/index.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> Ajuda Barcode Scanner </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p><strong>Barcode Scanner 4.3.1</strong></p>\n<p> O app Android oficial do projeto de código aberto ZXing:<br/>\n<a href=\"http://code.google.com/p/zxing\"> http://code.google.com/p/zxing </a></p>\n<p> Barcode Scanner utiliza a câmera do seu celular para ler códigos de barras e procurar informações sobre o produto, tais como preços e opiniões. </p>\n<p class=\"imgcenter\"><img src=\"../images/scan-example.png\"/></p>\n<p> Ele também lê código de barras 2D, tais como QR Codes e matriz de dados. Estes podem conter links para web sites, informações de contato, como números de telefone e endereços de e-mail, e muito mais. </p>\n<ul class=\"touchable\">\n  <li><a href=\"whatsnew.html\"> O que há de novo nesta versão </a></li>\n  <li><a href=\"scanning.html\"> Como digitalizar </a></li>\n  <li><a href=\"about1d.html\"> Sobre códigos de barras 1D </a></li>\n  <li><a href=\"about2d.html\"> Sobre códigos de barras 2D </a></li>\n  <li><a href=\"sharing.html\"> Como criar QR Codes </a></li>\n</ul>\n<p>Traduzido pelo Google Translate.</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-pt/scanning.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> Como digitalizar </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p> Barcode Scanner examina continuamente uma região quadrada mostrado na tela - apenas a linha até o telefone para o código de barras é completamente dentro do retângulo do visor: </p>\n<p class=\"imgcenter\"><img src=\"../images/demo-yes.png\" style=\"padding:5px\"/><img src=\"../images/demo-no.png\" style=\"padding:5px\"/></p>\n<p> Códigos de barras 1D como os encontrados em produtos necessitam de um telefone com foco automático. Sem ele, apenas QR Codes e códigos Data Matrix será legível. </p>\n<p> Quando um código de barras é lido, um sinal sonoro vai jogar e você vai ver os resultados da verificação, uma descrição do que contém o código de barras, e as opções a tomar medidas sobre o conteúdo. </p>\n<p> Se você está tendo problemas de digitalização, certifique-se de segurar o telefone fixo. Se a câmera não consegue focar, tente mover o telefone mais próximo ou a partir do código de barras. </p>\n<ul class=\"touchable\">\n  <li><a href=\"about1d.html\"> Sobre códigos de barras 1D </a></li>\n  <li><a href=\"about2d.html\"> Sobre códigos de barras 2D </a></li>\n</ul>\n<p>Traduzido pelo Google Translate.</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-pt/sharing.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> Como criar QR Codes </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p> Além de digitalizar códigos de barras 2D, Barcode Scanner também pode gerar um QR Code e exibi-lo na tela. Então você pode mostrá-lo a um amigo, e deixe-escanear o código de barras com o seu telefone: </p>\n<p class=\"imgcenter\"><img src=\"../images/scan-from-phone.png\"/></p>\n<p> Para usar esse recurso, pressione o botão Menu a partir do ecrã de digitalização principal e toque em Compartilhar. Em seguida, escolha se você deseja compartilhar um contato, um marcador, um aplicativo, ou o conteúdo da área de transferência. Um QR Code será gerado automaticamente. Quando estiver pronto, pressione Voltar ou Casa. </p>\n<p> Para gerar QR Codes do seu computador, experimente a Gerador de código QR ZXing: <a href=\"http://zxing.appspot.com/generator/\"> http://zxing.appspot.com/generator/ </a></p>\n<p>Traduzido pelo Google Translate.</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-pt/whatsnew.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> O que há de novo no Barcode Scanner </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p> Novo na versão 4.3.1: </p>\n<ul>\n  <li> Desativado controle de exposição, uma vez que causou problemas em dispositivos de buggy vários </li>\n  <li> Outras pequenas correções de bugs </li>\n</ul>\n<p>Traduzido pelo Google Translate.</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-ru/about1d.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> О 1D штрих-кодов </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p> Традиционные штрих-коды, такие как напечатанный на упаковке продукта, также известный как одномерные штрих-коды. Есть несколько типов широко используются, в том числе UPC и EAN. Большинство выглядеть примерно так: </p>\n<p class=\"imgcenter\"><img src=\"../images/big-1d.png\"/></p>\n<p> Эти 1D штрих-коды содержат уникальный код, который обычно описывает продукт, как компакт-диск или книгу. Вы можете посмотреть этот код на Интернет, чтобы найти цены, обзоры и многое другое. </p>\n<p> Если вы сканируете книгу, вы также можете найти в содержании книги слово или фразу, и найти все страницы, где он появляется: </p>\n<p class=\"imgcenter\"><img src=\"../images/search-book-contents.jpg\"/></p>\n<p>Перевод Google Translate.</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-ru/about2d.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> О 2D штрих-кодов </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p><strong> Barcode Scanner </strong> также понимает, как читать двумерные штрих-коды, такие как QR-коды и коды Data Matrix. Например, код ниже, содержат гиперссылки на ZXing домашней странице проекта: </p>\n<p class=\"imgcenter\">\n  <img src=\"../images/big-qr.png\"/>\n  <img src=\"../images/big-datamatrix.png\"/>\n</p>\n<p> Вы также можете представлять контактную информацию в QR Code, и положил его на визитную карточку или веб-сайт. При сканировании она, результатов экрана обеспечивает выбор действий: </p>\n<p class=\"imgcenter\"><img src=\"../images/contact-results-screen.jpg\"/></p>\n<p> Кроме того адреса и контактные данные, QR-коды могут также содержать: </p>\n<ul>\n  <li> Календарь событий, которые вы можете добавить в свой календарь </li>\n  <li> Телефонные номера, которые можно набрать </li>\n  <li> SMS-номера, который вы можете тексте сообщения </li>\n  <li> Адреса электронной почты, который вы можете по электронной почте </li>\n  <li> Географические координаты, которые можно открыть в карты </li>\n  <li> Обычный текст, который можно прочитать, а затем поделиться с другом </li>\n</ul>\n<p>Перевод Google Translate.</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-ru/index.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> Помощь Barcode Scanner </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p><strong>Barcode Scanner 4.3.1</strong></p>\n<p> Официальное приложение для Android проекта с открытым ZXing источник:<br/>\n<a href=\"http://code.google.com/p/zxing\"> http://code.google.com/p/zxing </a></p>\n<p> Barcode Scanner использует камеру на телефоне, чтобы читать штрих-код и посмотреть информацию о продуктах, таких как цены и отзывы. </p>\n<p class=\"imgcenter\"><img src=\"../images/scan-example.png\"/></p>\n<p> Он также читает 2D штрих-коды, такие как QR-коды и Data Matrix. Они могут содержать ссылки на веб-сайты, контактную информацию, такую как номера телефонов и адреса электронной почты и многое другое. </p>\n<ul class=\"touchable\">\n  <li><a href=\"whatsnew.html\"> Что нового в этой версии </a></li>\n  <li><a href=\"scanning.html\"> Как проверить </a></li>\n  <li><a href=\"about1d.html\"> О 1D штрих-кодов </a></li>\n  <li><a href=\"about2d.html\"> О 2D штрих-кодов </a></li>\n  <li><a href=\"sharing.html\"> Как создать QR-коды </a></li>\n</ul>\n<p>Перевод Google Translate.</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-ru/scanning.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> Как проверить </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p> Штрих коды непрерывно сканирует площадь области, показанной на экране - просто линия телефона, чтобы штрих-код полностью внутри видоискателя прямоугольника: </p>\n<p class=\"imgcenter\"><img src=\"../images/demo-yes.png\" style=\"padding:5px\"/><img src=\"../images/demo-no.png\" style=\"padding:5px\"/></p>\n<p> 1D штрих-кодов как найденные на продукты требуют телефону с автофокусом. Без него, только QR-коды и коды Data Matrix будет развертываемых. </p>\n<p> Если штрих-код считывается, звуковой сигнал будет играть, и вы увидите результаты проверки, описание того, что штрих-код содержит и варианты принятия решений по содержанию. </p>\n<p> Если у вас возникли проблемы сканирования, убедитесь, что держать телефон постоянно. Если фотокамера не может сфокусироваться, попробуйте переместить телефон дальше или ближе от штрих-кода. </p>\n<ul class=\"touchable\">\n  <li><a href=\"about1d.html\"> О 1D штрих-кодов </a></li>\n  <li><a href=\"about2d.html\"> О 2D штрих-кодов </a></li>\n</ul>\n<p>Перевод Google Translate.</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-ru/sharing.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> Как создать QR-коды </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p> В дополнение к сканированию 2D штрих-кодов, штрих-код сканером также может генерировать QR-код и отображает его на экране. Затем вы можете показать его другу, и пусть они сканировать штрих-код с телефона: </p>\n<p class=\"imgcenter\"><img src=\"../images/scan-from-phone.png\"/></p>\n<p> Чтобы использовать эту функцию, нажмите кнопку меню на главном экране сканирования и нажмите Отправить. Затем выберите, хотите ли вы поделиться контакт, закладки, приложения или содержимое буфера обмена. QR-код будет сгенерирован автоматически. Когда вы закончите, нажмите кнопку Назад или дома. </p>\n<p> Для создания QR-коды с компьютера, попробуйте ZXing QR Генератор кода: <a href=\"http://zxing.appspot.com/generator/\"> http://zxing.appspot.com/generator/ </a></p>\n<p>Перевод Google Translate.</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-ru/whatsnew.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> Что нового в Barcode Scanner </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p> Новое в версии 4.3.1: </p>\n<ul>\n  <li> Отключен контроль экспозиции, как это вызвало проблемы на нескольких устройствах багги </li>\n  <li> Другие мелкие исправления ошибка </li>\n</ul>\n<p>Перевод Google Translate.</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-zh-rCN/about1d.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> 关于一维条码 </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p> 传统的条形码，如产品包装上印刷，也被称为一维条形码。常用的有几种类型，包括UPC和EAN。大多数看起来像这样： </p>\n<p class=\"imgcenter\"><img src=\"../images/big-1d.png\"/></p>\n<p> 这些一维条码包含一个独特的代码，它通常描述了一种产品，如CD或一本书。你可以看一下这段代码，在互联网上找到价格，评论等。 </p>\n<p> 如果扫描一本书，你也可以为一个词或短语搜索本书的内容，它出现的地方找到的所有网页： </p>\n<p class=\"imgcenter\"><img src=\"../images/search-book-contents.jpg\"/></p>\n<p>谷歌翻译，译。</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-zh-rCN/about2d.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> 关于二维条码 </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p><strong> 条码扫描器 </strong> 还知道如何读取二维条形码，QR码和Data Matrix码。例如，下面的代码包含超链接的ZXing项目主页： </p>\n<p class=\"imgcenter\">\n  <img src=\"../images/big-qr.png\"/>\n  <img src=\"../images/big-datamatrix.png\"/>\n</p>\n<p> 您也可以在QR码代表的联系信息，并把它放在一张名片或网站。当您扫描，结果屏幕提供了一个可供选择的行动： </p>\n<p class=\"imgcenter\"><img src=\"../images/contact-results-screen.jpg\"/></p>\n<p> 除了网址和联系方式，QR码还可以包含以下内容： </p>\n<ul>\n  <li> 日历事件，您可以添加到您的日历 </li>\n  <li> 您可以拨打的电话号码， </li>\n  <li> 短信号码，您可以短信 </li>\n  <li> 您可以通过电子邮件的电子邮件地址， </li>\n  <li> 地理坐标，你可以打开地图 </li>\n  <li> 纯文本，你可以阅读，然后与朋友分享 </li>\n</ul>\n<p>谷歌翻译，译。</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-zh-rCN/index.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> 条码扫描器说明 </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p><strong>Barcode Scanner 4.3.1</strong></p>\n<p> 官方的Android应用程序的开源ZXing项目：<br/>\n<a href=\"http://code.google.com/p/zxing\"> http://code.google.com/p/zxing </a></p>\n<p> 条码扫描器在您的手机上使用摄像头读取条形码，查询产品的信息，如价格和评论。 </p>\n<p class=\"imgcenter\"><img src=\"../images/scan-example.png\"/></p>\n<p> 此外，还可以读取QR码和Data Matrix二维条码，如。这些都可以包含网站的链接，联系信息，如电话号码和电子邮件地址，以及更多。 </p>\n<ul class=\"touchable\">\n  <li><a href=\"whatsnew.html\"> 在这个版本中有什么新功能 </a></li>\n  <li><a href=\"scanning.html\"> 如何扫描 </a></li>\n  <li><a href=\"about1d.html\"> 关于一维条码 </a></li>\n  <li><a href=\"about2d.html\"> 关于二维条码 </a></li>\n  <li><a href=\"sharing.html\"> 如何创建QR码 </a></li>\n</ul>\n<p>谷歌翻译，译。</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-zh-rCN/scanning.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> 如何扫描 </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p> 持续不断地扫描条码扫描仪屏幕上显示的一个方形区域 - 只是了电话线，使条码是完全取景器内的矩形： </p>\n<p class=\"imgcenter\"><img src=\"../images/demo-yes.png\" style=\"padding:5px\"/><img src=\"../images/demo-no.png\" style=\"padding:5px\"/></p>\n<p> 一维条码的产品需要一个电话，支持自动对焦。如果没有它，QR码和Data Matrix码将被扫描。 </p>\n<p> 当条码阅读，蜂鸣声会玩，你会看到扫描的条形码包含的描述和选项的内容采取行动的结果。 </p>\n<p> 如果你有麻烦扫描，请一定要保持稳定的手机。如果相机无法对焦，尝试从条形码移动电话或接近的。 </p>\n<ul class=\"touchable\">\n  <li><a href=\"about1d.html\"> 关于一维条码 </a></li>\n  <li><a href=\"about2d.html\"> 关于二维条码 </a></li>\n</ul>\n<p>谷歌翻译，译。</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-zh-rCN/sharing.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> 如何创建QR码 </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p> 除了扫描二维条码，条码扫描仪还可以产生一个QR码，并将其显示在屏幕上。然后你就可以显示给朋友，让他们用自己的手机扫描条形码： </p>\n<p class=\"imgcenter\"><img src=\"../images/scan-from-phone.png\"/></p>\n<p> 要使用此功能，请从主扫描屏幕上的菜单按钮，并点击“分享”。然后选择是否要共享联系人，书签，应用程序，或将剪贴板的内容。将自动生成的QR码。当你完成后，按返回或家庭。 </p>\n<p> 要生成QR码从您的计算机，尝试的ZXing QR代码生成： <a href=\"http://zxing.appspot.com/generator/\"> http://zxing.appspot.com/generator/ </a></p>\n<p>谷歌翻译，译。</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-zh-rCN/whatsnew.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> 有什么新的条码扫描器 </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p> 新的版本4.3.1： </p>\n<ul>\n  <li> 残疾人曝光控制，它引起的问题在几个车设备 </li>\n  <li> 其他小的bug修复 </li>\n</ul>\n<p>谷歌翻译，译。</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-zh-rTW/about1d.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> 關於一維條碼 </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p> 傳統的條形碼，如產品包裝上印刷，也被稱為一維條形碼。常用的有幾種類型，包括UPC和EAN。大多數看起來像這樣： </p>\n<p class=\"imgcenter\"><img src=\"../images/big-1d.png\"/></p>\n<p> 這些一維條碼包含一個獨特的代碼，它通常描述了一種產品，如CD或一本書。你可以看一下這段代碼，在互聯網上找到價格，評論等。 </p>\n<p> 如果掃描一本書，你也可以為一個詞或短語搜索本書的內容，它出現的地方找到的所有網頁： </p>\n<p class=\"imgcenter\"><img src=\"../images/search-book-contents.jpg\"/></p>\n<p>谷歌翻譯，譯。</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-zh-rTW/about2d.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> 關於二維條碼 </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p><strong> 條碼掃描器 </strong> 還知道如何讀取二維條形碼，QR碼和Data Matrix碼。例如，下面的代碼包含超鏈接的ZXing項目主頁： </p>\n<p class=\"imgcenter\">\n  <img src=\"../images/big-qr.png\"/>\n  <img src=\"../images/big-datamatrix.png\"/>\n</p>\n<p> 您也可以在QR碼代表的聯繫信息，並把它放在一張名片或網站。當您掃描，結果屏幕提供了一個可供選擇的行動： </p>\n<p class=\"imgcenter\"><img src=\"../images/contact-results-screen.jpg\"/></p>\n<p> 除了網址和聯繫方式，QR碼還可以包含以下內容： </p>\n<ul>\n  <li> 日曆事件，您可以添加到您的日曆 </li>\n  <li> 您可以撥打的電話號碼， </li>\n  <li> 短信號碼，您可以短信 </li>\n  <li> 您可以通過電子郵件的電子郵件地址， </li>\n  <li> 地理坐標，你可以打開地圖 </li>\n  <li> 純文本，你可以閱讀，然後與朋友分享 </li>\n</ul>\n<p>谷歌翻譯，譯。</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-zh-rTW/index.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> 條碼掃描器說明 </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p><strong>Barcode Scanner 4.3.1</strong></p>\n<p> 官方的Android應用程序的開源ZXing項目：<br/>\n<a href=\"http://code.google.com/p/zxing\"> http://code.google.com/p/zxing </a></p>\n<p> 條碼掃描器在您的手機上使用攝像頭讀取條形碼，查詢產品的信息，如價格和評論。 </p>\n<p class=\"imgcenter\"><img src=\"../images/scan-example.png\"/></p>\n<p> 此外，還可以讀取QR碼和Data Matrix二維條碼，如。這些都可以包含網站的鏈接，聯繫信息，如電話號碼和電子郵件地址，以及更多。 </p>\n<ul class=\"touchable\">\n  <li><a href=\"whatsnew.html\"> 在這個版本中有什麼新功能 </a></li>\n  <li><a href=\"scanning.html\"> 如何掃描 </a></li>\n  <li><a href=\"about1d.html\"> 關於一維條碼 </a></li>\n  <li><a href=\"about2d.html\"> 關於二維條碼 </a></li>\n  <li><a href=\"sharing.html\"> 如何創建QR碼 </a></li>\n</ul>\n<p>谷歌翻譯，譯。</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-zh-rTW/scanning.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> 如何掃描 </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p> 持續不斷地掃描條碼掃描儀屏幕上顯示的一個方形區域 - 只是了電話線，使條碼是完全取景器內的矩形： </p>\n<p class=\"imgcenter\"><img src=\"../images/demo-yes.png\" style=\"padding:5px\"/><img src=\"../images/demo-no.png\" style=\"padding:5px\"/></p>\n<p> 一維條碼的產品需要一個電話，支持自動對焦。如果沒有它，QR碼和Data Matrix碼將被掃描。 </p>\n<p> 當條碼閱讀，蜂鳴聲會玩，你會看到掃描的條形碼包含的描述和選項的內容採取行動的結果。 </p>\n<p> 如果你有麻煩掃描，請一定要保持穩定的手機。如果相機無法對焦，嘗試從條形碼移動電話或接近的。 </p>\n<ul class=\"touchable\">\n  <li><a href=\"about1d.html\"> 關於一維條碼 </a></li>\n  <li><a href=\"about2d.html\"> 關於二維條碼 </a></li>\n</ul>\n<p>谷歌翻譯，譯。</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-zh-rTW/sharing.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> 如何創建QR碼 </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p> 除了掃描二維條碼，條碼掃描儀還可以產生一個QR碼，並將其顯示在屏幕上。然後你就可以顯示給朋友，讓他們用自己的手機掃描條形碼： </p>\n<p class=\"imgcenter\"><img src=\"../images/scan-from-phone.png\"/></p>\n<p> 要使用此功能，請從主掃描屏幕上的菜單按鈕，並點擊“分享”。然後選擇是否要共享聯繫人，書籤，應用程序，或將剪貼板的內容。將自動生成的QR碼。當你完成後，按返回或家庭。 </p>\n<p> 要生成QR碼從您的計算機，嘗試的ZXing QR代碼生成： <a href=\"http://zxing.appspot.com/generator/\"> http://zxing.appspot.com/generator/ </a></p>\n<p>谷歌翻譯，譯。</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/html-zh-rTW/whatsnew.html",
    "content": "<!DOCTYPE HTML>\n<html>\n<head>\n<meta charset=\"UTF-8\"/>\n<title> 有什麼新的條碼掃描器 </title>\n<link href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n</head>\n<body>\n<p> 新的版本4.3.1： </p>\n<ul>\n  <li> 殘疾人曝光控制，它引起的問題在幾個車設備 </li>\n  <li> 其他小的bug修復 </li>\n</ul>\n<p>谷歌翻譯，譯。</p></body>\n</html>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/assets/style.css",
    "content": "body {\n  font-family:sans-serif;\n}\nul.touchable li {\n  padding-top:8px;\n  padding-bottom:8px;\n}\np.imgcenter {\n  text-align:center;\n}"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/proguard-android-optimize.txt",
    "content": "# This is a configuration file for ProGuard.\n# http://proguard.sourceforge.net/index.html#manual/usage.html\n\n# Optimizations: If you don't want to optimize, use the\n# proguard-android.txt configuration file instead of this one, which\n# turns off the optimization flags.  Adding optimization introduces\n# certain risks, since for example not all optimizations performed by\n# ProGuard works on all versions of Dalvik.  The following flags turn\n# off various optimizations known to have issues, but the list may not\n# be complete or up to date. (The \"arithmetic\" optimization can be\n# used if you are only targeting Android 2.0 or later.)  Make sure you\n# test thoroughly if you go this route.\n-optimizations !code/simplification/cast,!code/allocation/*,!field/*,!class/merging/*\n-optimizationpasses 5\n-allowaccessmodification\n-dontpreverify\n\n# The remainder of this file is identical to the non-optimized version\n# of the Proguard configuration file (except that the other file has\n# flags to turn off optimization).\n\n-dontusemixedcaseclassnames\n-dontskipnonpubliclibraryclasses\n-verbose\n\n-keepattributes *Annotation*\n-keep public class com.google.vending.licensing.ILicensingService\n-keep public class com.android.vending.licensing.ILicensingService\n\n# ADDED\n-keep class com.google.zxing.client.android.camera.open.**\n#-keep class com.google.zxing.client.android.camera.exposure.**\n-keep class com.google.zxing.client.android.common.executor.**\n\n# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native\n-keepclasseswithmembernames class * {\n    native <methods>;\n}\n\n# keep setters in Views so that animations can still work.\n# see http://proguard.sourceforge.net/manual/examples.html#beans\n-keepclassmembers public class * extends android.view.View {\n   void set*(***);\n   *** get*();\n}\n\n# We want to keep methods in Activity that could be used in the XML attribute onClick\n-keepclassmembers class * extends android.app.Activity {\n   public void *(android.view.View);\n}\n\n# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations\n-keepclassmembers enum * {\n    public static **[] values();\n    public static ** valueOf(java.lang.String);\n}\n\n-keep class * implements android.os.Parcelable {\n  public static final android.os.Parcelable$Creator *;\n}\n\n-keepclassmembers class **.R$* {\n    public static <fields>;\n}\n\n# The support library contains references to newer platform versions.\n# Don't warn about those in case this app is linking against an older\n# platform version.  We know about them, and they are safe.\n-dontwarn android.support.**\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/project.properties",
    "content": "# This file is automatically generated by Android Tools.\n# Do not modify this file -- YOUR CHANGES WILL BE ERASED!\n#\n# This file must be checked in Version Control Systems.\n#\n# To customize properties used by the Ant build system edit\n# \"ant.properties\", and override values to adapt the script to your\n# project structure.\n#\n# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):\nproguard.config=proguard-android-optimize.txt\n\n# Project target.\ntarget=android-17\nandroid.library=true\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/layout/bookmark_picker_list_item.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2008 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<LinearLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:orientation=\"vertical\"\n    android:layout_width=\"fill_parent\"\n    android:layout_height=\"wrap_content\"\n    android:padding=\"@dimen/half_padding\">\n\n  <TextView android:id=\"@+id/bookmark_title\"\n            android:layout_width=\"fill_parent\"\n            android:layout_height=\"wrap_content\"\n            android:singleLine=\"true\"/>\n\n  <TextView android:id=\"@+id/bookmark_url\"\n            android:layout_width=\"fill_parent\"\n            android:layout_height=\"wrap_content\"\n            android:singleLine=\"false\"/>\n\n</LinearLayout>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/layout/capture.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2008 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n             android:layout_width=\"fill_parent\"\n             android:layout_height=\"fill_parent\">\n\n  <SurfaceView android:id=\"@+id/preview_view\"\n               android:layout_width=\"fill_parent\"\n               android:layout_height=\"fill_parent\"/>\n\n  <com.google.zxing.client.android.ViewfinderView\n      android:id=\"@+id/viewfinder_view\"\n      android:layout_width=\"fill_parent\"\n      android:layout_height=\"fill_parent\"/>\n\n  <LinearLayout android:id=\"@+id/result_view\"\n                android:orientation=\"vertical\"\n                android:layout_width=\"fill_parent\"\n                android:layout_height=\"fill_parent\"\n                android:background=\"@color/result_view\"\n                android:visibility=\"gone\"\n                android:baselineAligned=\"false\">\n\n    <LinearLayout\n        android:orientation=\"horizontal\"\n        android:layout_width=\"fill_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_weight=\"1\"\n        android:gravity=\"center\"\n        android:padding=\"@dimen/standard_padding\">\n\n      <LinearLayout\n          android:orientation=\"vertical\"\n          android:layout_width=\"wrap_content\"\n          android:layout_height=\"fill_parent\"\n          android:gravity=\"right|center_vertical\">\n\n        <ImageView android:id=\"@+id/barcode_image_view\"\n                   android:layout_width=\"160dip\"\n                   android:layout_height=\"wrap_content\"\n                   android:maxWidth=\"160dip\"\n                   android:maxHeight=\"160dip\"\n                   android:layout_marginBottom=\"@dimen/half_padding\"\n                   android:adjustViewBounds=\"true\"\n                   android:scaleType=\"centerInside\"/>\n\n        <LinearLayout\n          android:orientation=\"horizontal\"\n          android:layout_width=\"wrap_content\"\n          android:layout_height=\"wrap_content\">\n\n          <TextView android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:text=\"@string/msg_default_format\"\n                    android:textColor=\"@color/result_minor_text\"\n                    android:textStyle=\"bold\"\n                    android:paddingRight=\"@dimen/half_padding\"/>\n\n          <TextView android:id=\"@+id/format_text_view\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:textColor=\"@color/result_minor_text\"/>\n\n        </LinearLayout>\n\n        <LinearLayout\n          android:orientation=\"horizontal\"\n          android:layout_width=\"wrap_content\"\n          android:layout_height=\"wrap_content\">\n\n          <TextView android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:text=\"@string/msg_default_type\"\n                    android:textColor=\"@color/result_minor_text\"\n                    android:textStyle=\"bold\"\n                    android:paddingRight=\"@dimen/half_padding\"/>\n\n          <TextView android:id=\"@+id/type_text_view\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:textColor=\"@color/result_minor_text\"/>\n\n        </LinearLayout>\n\n        <LinearLayout\n          android:orientation=\"horizontal\"\n          android:layout_width=\"wrap_content\"\n          android:layout_height=\"wrap_content\">\n\n          <TextView android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:text=\"@string/msg_default_time\"\n                    android:textColor=\"@color/result_minor_text\"\n                    android:textStyle=\"bold\"\n                    android:paddingRight=\"@dimen/half_padding\"/>\n\n          <TextView android:id=\"@+id/time_text_view\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:textColor=\"@color/result_minor_text\"/>\n\n        </LinearLayout>\n\n        <LinearLayout\n          android:orientation=\"horizontal\"\n          android:layout_width=\"wrap_content\"\n          android:layout_height=\"wrap_content\">\n\n          <TextView android:id=\"@+id/meta_text_view_label\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:text=\"@string/msg_default_meta\"\n                    android:textColor=\"@color/result_minor_text\"\n                    android:textStyle=\"bold\"\n                    android:paddingRight=\"@dimen/half_padding\"/>\n\n          <TextView android:id=\"@+id/meta_text_view\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:textColor=\"@color/result_minor_text\"/>\n\n        </LinearLayout>\n\n      </LinearLayout>\n\n      <ScrollView\n          android:layout_width=\"wrap_content\"\n          android:layout_height=\"wrap_content\">\n\n        <LinearLayout\n          android:layout_width=\"wrap_content\"\n          android:layout_height=\"wrap_content\"\n          android:orientation=\"vertical\">\n\n          <TextView android:id=\"@+id/contents_text_view\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:textColor=\"@color/result_text\"\n                    android:textColorLink=\"@color/result_text\"\n                    android:textSize=\"22sp\"\n                    android:paddingLeft=\"12dip\"\n                    android:autoLink=\"web\"/>\n\n          <TextView android:id=\"@+id/contents_supplement_text_view\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:textColor=\"@color/result_text\"\n                    android:textColorLink=\"@color/result_text\"\n                    android:paddingLeft=\"12dip\"\n                    android:autoLink=\"web\"/>\n\n        </LinearLayout>\n\n      </ScrollView>\n\n    </LinearLayout>\n\n    <LinearLayout android:id=\"@+id/result_button_view\"\n                  android:layout_width=\"fill_parent\"\n                  android:layout_height=\"wrap_content\"\n                  android:orientation=\"horizontal\"\n                  android:gravity=\"center\">\n\n      <Button android:layout_width=\"0dip\"\n              android:layout_height=\"wrap_content\"\n              android:layout_weight=\"1\"\n              android:visibility=\"gone\"/>\n\n      <Button android:layout_width=\"0dip\"\n              android:layout_height=\"wrap_content\"\n              android:layout_weight=\"1\"\n              android:visibility=\"gone\"/>\n\n      <Button android:layout_width=\"0dip\"\n              android:layout_height=\"wrap_content\"\n              android:layout_weight=\"1\"\n              android:visibility=\"gone\"/>\n\n      <Button android:layout_width=\"0dip\"\n              android:layout_height=\"wrap_content\"\n              android:layout_weight=\"1\"\n              android:visibility=\"gone\"/>\n\n      <Button android:id=\"@+id/shopper_button\"\n              android:layout_width=\"0dip\"\n              android:layout_height=\"wrap_content\"\n              android:layout_weight=\"1\"\n              android:drawableLeft=\"@drawable/shopper_icon\"\n              android:text=\"@string/button_google_shopper\"\n              android:visibility=\"gone\"/>\n\n    </LinearLayout>\n\n  </LinearLayout>\n\n  <TextView android:id=\"@+id/status_view\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"bottom|center_horizontal\"\n            android:background=\"@color/transparent\"\n            android:text=\"@string/msg_default_status\"\n            android:textColor=\"@color/status_text\"/>\n\n</FrameLayout>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/layout/encode.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2008 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n              android:layout_width=\"fill_parent\"\n              android:layout_height=\"fill_parent\"\n              android:fillViewport=\"true\"\n              android:background=\"@color/encode_view\"\n              android:orientation=\"vertical\"\n              android:gravity=\"center\">\n\n  <ImageView android:id=\"@+id/image_view\"\n             android:layout_width=\"fill_parent\"\n             android:layout_height=\"wrap_content\"\n             android:layout_gravity=\"center_horizontal\"\n             android:scaleType=\"center\"/>\n\n  <ScrollView android:layout_width=\"fill_parent\"\n              android:layout_height=\"wrap_content\"\n              android:layout_gravity=\"center_horizontal\"\n              android:gravity=\"center\">\n\n    <TextView android:id=\"@+id/contents_text_view\"\n              android:layout_width=\"fill_parent\"\n              android:layout_height=\"wrap_content\"\n              android:layout_gravity=\"center_horizontal\"\n              android:gravity=\"center\"\n              android:textColor=\"@color/contents_text\"\n              android:paddingBottom=\"@dimen/standard_padding\"\n              android:paddingLeft=\"@dimen/standard_padding\"\n              android:paddingRight=\"@dimen/standard_padding\"/>\n\n  </ScrollView>\n\n</LinearLayout>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/layout/help.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2008 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n              android:layout_width=\"fill_parent\"\n              android:layout_height=\"fill_parent\"\n              android:orientation=\"vertical\">\n\n  <WebView android:id=\"@+id/help_contents\"\n           android:layout_width=\"fill_parent\"\n           android:layout_height=\"wrap_content\"\n           android:layout_weight=\"1\"/>\n\n  <LinearLayout\n      android:layout_width=\"fill_parent\"\n      android:layout_height=\"wrap_content\"\n      android:layout_weight=\"0\"\n      android:orientation=\"horizontal\"\n      android:gravity=\"center\"\n      android:paddingTop=\"@dimen/half_padding\"\n      android:weightSum=\"1\">\n\n    <Button android:id=\"@+id/back_button\"\n            android:layout_width=\"0dip\"\n            android:layout_height=\"wrap_content\"\n            android:layout_weight=\"0.5\"\n            android:text=\"@string/button_back\"/>\n\n    <Button android:id=\"@+id/done_button\"\n            android:layout_width=\"0dip\"\n            android:layout_height=\"wrap_content\"\n            android:layout_weight=\"0.5\"\n            android:text=\"@string/button_done\"/>\n\n  </LinearLayout>\n\n</LinearLayout>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/layout/history_list_item.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<LinearLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:orientation=\"vertical\"\n    android:layout_width=\"fill_parent\"\n    android:layout_height=\"wrap_content\"\n    android:padding=\"@dimen/standard_padding\">\n\n  <TextView android:id=\"@+id/history_title\"\n            android:layout_width=\"fill_parent\"\n            android:layout_height=\"wrap_content\"\n            android:textAppearance=\"?android:attr/textAppearanceLarge\"\n            android:singleLine=\"true\"/>\n\n  <TextView android:id=\"@+id/history_detail\"\n            android:layout_width=\"fill_parent\"\n            android:layout_height=\"wrap_content\"\n            android:textAppearance=\"?android:attr/textAppearanceSmall\"\n            android:singleLine=\"false\"/>\n\n</LinearLayout>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/layout/search_book_contents.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2008 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n              android:orientation=\"vertical\"\n              android:layout_width=\"fill_parent\"\n              android:layout_height=\"fill_parent\">\n\n  <LinearLayout\n      android:orientation=\"horizontal\"\n      android:layout_width=\"fill_parent\"\n      android:layout_height=\"wrap_content\"\n      android:layout_weight=\"0\">\n\n    <EditText android:id=\"@+id/query_text_view\"\n              android:layout_width=\"wrap_content\"\n              android:layout_height=\"wrap_content\"\n              android:layout_gravity=\"left|center_vertical\"\n              android:layout_weight=\"1\"\n              android:singleLine=\"true\"\n              android:selectAllOnFocus=\"true\"\n              android:inputType=\"text\"/>\n\n    <Button android:id=\"@+id/query_button\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_weight=\"0\"\n            android:text=\"@string/button_search_book_contents\"/>\n\n  </LinearLayout>\n\n\n  <ListView android:id=\"@+id/result_list_view\"\n            android:layout_width=\"fill_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_weight=\"1\"/>\n\n</LinearLayout>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/layout/search_book_contents_header.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2008 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<TextView xmlns:android=\"http://schemas.android.com/apk/res/android\"\n          android:layout_width=\"fill_parent\"\n          android:layout_height=\"wrap_content\"\n          android:paddingLeft=\"@dimen/standard_padding\"\n          android:paddingBottom=\"@dimen/half_padding\"\n          android:enabled=\"false\"\n          android:singleLine=\"true\"/>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/layout/search_book_contents_list_item.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2008 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<com.google.zxing.client.android.book.SearchBookContentsListItem\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:orientation=\"horizontal\"\n    android:layout_width=\"fill_parent\"\n    android:layout_height=\"wrap_content\"\n    android:padding=\"@dimen/standard_padding\">\n\n  <TextView android:id=\"@+id/page_number_view\"\n            android:layout_width=\"75dip\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"left|top\"\n            android:layout_marginRight=\"@dimen/standard_padding\"\n            android:singleLine=\"false\"\n            android:textStyle=\"bold\"/>\n\n  <TextView android:id=\"@+id/snippet_view\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"left|top\"\n            android:singleLine=\"false\"/>\n\n</com.google.zxing.client.android.book.SearchBookContentsListItem>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/layout/share.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2008 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n\n<!-- ScrollView wrapper is to accommodate small screens. -->\n<ScrollView xmlns:android=\"http://schemas.android.com/apk/res/android\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center\"\n            android:gravity=\"center\">\n\n  <!-- Must wrap the rest in one layout -->\n  <LinearLayout\n      android:layout_width=\"wrap_content\"\n      android:layout_height=\"wrap_content\"\n      android:gravity=\"center\"\n      android:orientation=\"vertical\"\n      android:padding=\"@dimen/standard_padding\">\n\n    <TextView\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:gravity=\"center\"\n        android:text=\"@string/msg_share_explanation\"\n        android:paddingBottom=\"@dimen/standard_padding\"/>\n\n    <ImageView\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:scaleType=\"center\"\n        android:src=\"@drawable/share_via_barcode\"\n        android:paddingBottom=\"@dimen/standard_padding\"/>\n\n    <LinearLayout\n        android:layout_width=\"fill_parent\"\n        android:layout_height=\"wrap_content\"\n        android:orientation=\"horizontal\"\n        android:paddingBottom=\"@dimen/standard_padding\">\n\n      <Button android:id=\"@+id/share_app_button\"\n              android:layout_width=\"fill_parent\"\n              android:layout_height=\"wrap_content\"\n              android:layout_weight=\"1\"\n              android:text=\"@string/button_share_app\"/>\n\n      <Button android:id=\"@+id/share_bookmark_button\"\n              android:layout_width=\"fill_parent\"\n              android:layout_height=\"wrap_content\"\n              android:layout_weight=\"1\"\n              android:text=\"@string/button_share_bookmark\"/>\n\n    </LinearLayout>\n\n    <LinearLayout\n        android:layout_width=\"fill_parent\"\n        android:layout_height=\"wrap_content\"\n        android:orientation=\"horizontal\"\n        android:paddingBottom=\"@dimen/standard_padding\">\n\n      <Button android:id=\"@+id/share_contact_button\"\n              android:layout_width=\"fill_parent\"\n              android:layout_height=\"wrap_content\"\n              android:layout_weight=\"1\"\n              android:text=\"@string/button_share_contact\"/>\n\n      <Button android:id=\"@+id/share_clipboard_button\"\n              android:layout_width=\"fill_parent\"\n              android:layout_height=\"wrap_content\"\n              android:layout_weight=\"1\"\n              android:text=\"@string/button_share_clipboard\"/>\n\n    </LinearLayout>\n\n    <EditText android:id=\"@+id/share_text_view\"\n              android:layout_width=\"fill_parent\"\n              android:layout_height=\"wrap_content\"\n              android:hint=\"@string/msg_share_text\"\n              android:singleLine=\"true\"\n              android:selectAllOnFocus=\"true\"/>\n\n  </LinearLayout>\n\n</ScrollView>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/layout-land/encode.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2008 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n              android:layout_width=\"fill_parent\"\n              android:layout_height=\"fill_parent\"\n              android:fillViewport=\"true\"\n              android:background=\"@color/encode_view\"\n              android:orientation=\"horizontal\"\n              android:gravity=\"center\">\n\n  <ImageView android:id=\"@+id/image_view\"\n             android:layout_width=\"wrap_content\"\n             android:layout_height=\"fill_parent\"\n             android:layout_gravity=\"center_vertical\"\n             android:scaleType=\"center\"/>\n\n  <ScrollView android:layout_width=\"wrap_content\"\n            android:layout_height=\"fill_parent\"\n            android:layout_gravity=\"center_vertical\"\n            android:gravity=\"center\">\n\n    <TextView android:id=\"@+id/contents_text_view\"\n              android:layout_width=\"wrap_content\"\n              android:layout_height=\"wrap_content\"\n              android:layout_gravity=\"center_vertical\"\n              android:gravity=\"center\"\n              android:textColor=\"@color/contents_text\"\n              android:paddingRight=\"8dip\"\n              android:paddingTop=\"8dip\"\n              android:paddingBottom=\"8dip\"/>\n\n  </ScrollView>\n\n</LinearLayout>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/layout-land/share.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2008 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n              android:layout_width=\"wrap_content\"\n              android:layout_height=\"wrap_content\"\n              android:layout_gravity=\"center\"\n              android:gravity=\"center\"\n              android:orientation=\"vertical\"\n              android:padding=\"8dip\">\n\n  <TextView\n      android:layout_width=\"fill_parent\"\n      android:layout_height=\"wrap_content\"\n      android:gravity=\"center\"\n      android:text=\"@string/msg_share_explanation\"\n      android:paddingBottom=\"12dip\"/>\n\n  <LinearLayout\n      android:layout_width=\"fill_parent\"\n      android:layout_height=\"wrap_content\"\n      android:orientation=\"horizontal\"\n      android:paddingBottom=\"12dip\">\n\n    <ImageView\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:scaleType=\"center\"\n        android:src=\"@drawable/share_via_barcode\"\n        android:paddingRight=\"24dip\"/>\n\n    <LinearLayout\n        android:layout_width=\"0dip\"\n        android:layout_height=\"wrap_content\"\n        android:layout_weight=\"1\"\n        android:orientation=\"vertical\">\n\n      <Button android:id=\"@+id/share_app_button\"\n              android:layout_width=\"fill_parent\"\n              android:layout_height=\"wrap_content\"\n              android:text=\"@string/button_share_app\"/>\n\n      <Button android:id=\"@+id/share_contact_button\"\n              android:layout_width=\"fill_parent\"\n              android:layout_height=\"wrap_content\"\n              android:text=\"@string/button_share_contact\"/>\n\n    </LinearLayout>\n\n    <LinearLayout\n        android:layout_width=\"0dip\"\n        android:layout_height=\"wrap_content\"\n        android:layout_weight=\"1\"\n        android:orientation=\"vertical\">\n\n      <Button android:id=\"@+id/share_bookmark_button\"\n              android:layout_width=\"fill_parent\"\n              android:layout_height=\"wrap_content\"\n              android:text=\"@string/button_share_bookmark\"/>\n\n      <Button android:id=\"@+id/share_clipboard_button\"\n              android:layout_width=\"fill_parent\"\n              android:layout_height=\"wrap_content\"\n              android:text=\"@string/button_share_clipboard\"/>\n\n    </LinearLayout>\n\n  </LinearLayout>\n\n  <EditText android:id=\"@+id/share_text_view\"\n            android:layout_width=\"fill_parent\"\n            android:layout_height=\"wrap_content\"\n            android:hint=\"@string/msg_share_text\"\n            android:singleLine=\"true\"\n            android:selectAllOnFocus=\"true\"/>\n\n</LinearLayout>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/layout-ldpi/capture.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2008 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n             android:layout_width=\"fill_parent\"\n             android:layout_height=\"fill_parent\">\n\n  <SurfaceView android:id=\"@+id/preview_view\"\n               android:layout_width=\"fill_parent\"\n               android:layout_height=\"fill_parent\"/>\n\n  <com.google.zxing.client.android.ViewfinderView\n      android:id=\"@+id/viewfinder_view\"\n      android:layout_width=\"fill_parent\"\n      android:layout_height=\"fill_parent\"/>\n\n  <LinearLayout android:id=\"@+id/result_view\"\n                android:orientation=\"vertical\"\n                android:layout_width=\"fill_parent\"\n                android:layout_height=\"fill_parent\"\n                android:background=\"@color/result_view\"\n                android:visibility=\"gone\"\n                android:baselineAligned=\"false\">\n\n    <LinearLayout\n        android:orientation=\"horizontal\"\n        android:layout_width=\"fill_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_weight=\"1\"\n        android:gravity=\"top\"\n        android:padding=\"@dimen/standard_padding\">\n\n      <LinearLayout\n          android:orientation=\"vertical\"\n          android:layout_width=\"wrap_content\"\n          android:layout_height=\"fill_parent\"\n          android:gravity=\"right\">\n\n        <ImageView android:id=\"@+id/barcode_image_view\"\n                   android:layout_width=\"150dip\"\n                   android:layout_height=\"wrap_content\"\n                   android:maxWidth=\"150dip\"\n                   android:maxHeight=\"150dip\"\n                   android:layout_marginBottom=\"@dimen/half_padding\"\n                   android:adjustViewBounds=\"true\"\n                   android:scaleType=\"centerInside\"/>\n\n        <LinearLayout\n          android:orientation=\"horizontal\"\n          android:layout_width=\"wrap_content\"\n          android:layout_height=\"wrap_content\">\n\n          <TextView android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:text=\"@string/msg_default_format\"\n                    android:textColor=\"@color/result_minor_text\"\n                    android:textStyle=\"bold\"\n                    android:paddingRight=\"@dimen/half_padding\"/>\n\n          <TextView android:id=\"@+id/format_text_view\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:textColor=\"@color/result_minor_text\"/>\n\n        </LinearLayout>\n\n        <LinearLayout\n          android:orientation=\"horizontal\"\n          android:layout_width=\"wrap_content\"\n          android:layout_height=\"wrap_content\">\n\n          <TextView android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:text=\"@string/msg_default_type\"\n                    android:textColor=\"@color/result_minor_text\"\n                    android:textStyle=\"bold\"\n                    android:paddingRight=\"@dimen/half_padding\"/>\n\n          <TextView android:id=\"@+id/type_text_view\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:textColor=\"@color/result_minor_text\"/>\n\n        </LinearLayout>\n\n        <LinearLayout\n          android:orientation=\"horizontal\"\n          android:layout_width=\"wrap_content\"\n          android:layout_height=\"wrap_content\">\n\n          <TextView android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:text=\"@string/msg_default_time\"\n                    android:textColor=\"@color/result_minor_text\"\n                    android:textStyle=\"bold\"\n                    android:paddingRight=\"@dimen/half_padding\"/>\n\n          <TextView android:id=\"@+id/time_text_view\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:textColor=\"@color/result_minor_text\"/>\n\n        </LinearLayout>\n\n        <LinearLayout\n          android:orientation=\"horizontal\"\n          android:layout_width=\"wrap_content\"\n          android:layout_height=\"wrap_content\">\n\n          <TextView android:id=\"@+id/meta_text_view_label\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:text=\"@string/msg_default_meta\"\n                    android:textColor=\"@color/result_minor_text\"\n                    android:textStyle=\"bold\"\n                    android:paddingRight=\"@dimen/half_padding\"/>\n\n          <TextView android:id=\"@+id/meta_text_view\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:textColor=\"@color/result_minor_text\"/>\n\n        </LinearLayout>\n\n      </LinearLayout>\n\n      <ScrollView\n          android:layout_width=\"fill_parent\"\n          android:layout_height=\"wrap_content\">\n\n        <LinearLayout\n          android:orientation=\"vertical\"\n          android:layout_width=\"wrap_content\"\n          android:layout_height=\"wrap_content\">\n\n          <TextView android:id=\"@+id/contents_text_view\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:textColor=\"@color/result_text\"\n                    android:textColorLink=\"@color/result_text\"\n                    android:textSize=\"22sp\"\n                    android:paddingLeft=\"12dip\"\n                    android:autoLink=\"web\"/>\n\n          <TextView android:id=\"@+id/contents_supplement_text_view\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:textColor=\"@color/result_text\"\n                    android:textColorLink=\"@color/result_text\"\n                    android:paddingLeft=\"12dip\"\n                    android:autoLink=\"web\"\n                    android:clickable=\"true\"/>\n\n        </LinearLayout>\n\n      </ScrollView>\n\n    </LinearLayout>\n\n    <LinearLayout android:id=\"@+id/result_button_view\"\n                  android:orientation=\"horizontal\"\n                  android:layout_width=\"fill_parent\"\n                  android:layout_height=\"wrap_content\"\n                  android:gravity=\"center\">\n\n      <Button android:layout_width=\"0dip\"\n              android:layout_height=\"wrap_content\"\n              android:layout_weight=\"1\"\n              android:visibility=\"gone\"/>\n\n      <Button android:layout_width=\"0dip\"\n              android:layout_height=\"wrap_content\"\n              android:layout_weight=\"1\"\n              android:visibility=\"gone\"/>\n\n      <Button android:layout_width=\"0dip\"\n              android:layout_height=\"wrap_content\"\n              android:layout_weight=\"1\"\n              android:visibility=\"gone\"/>\n\n      <Button android:layout_width=\"0dip\"\n              android:layout_height=\"wrap_content\"\n              android:layout_weight=\"1\"\n              android:visibility=\"gone\"/>\n\n      <Button android:id=\"@+id/shopper_button\"\n              android:layout_width=\"0dip\"\n              android:layout_height=\"wrap_content\"\n              android:layout_weight=\"1\"\n              android:drawableLeft=\"@drawable/shopper_icon\"\n              android:text=\"@string/button_google_shopper\"\n              android:visibility=\"gone\"/>\n\n    </LinearLayout>\n\n  </LinearLayout>\n\n  <TextView android:id=\"@+id/status_view\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"bottom|center_horizontal\"\n            android:background=\"@color/transparent\"\n            android:text=\"@string/msg_default_status\"\n            android:textColor=\"@color/status_text\"/>\n\n</FrameLayout>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/menu/capture.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2012 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\">\n  <!-- removed nonfunctional menu - see file history to retrieve -->\n</menu>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/menu/encode.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2012 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\">\n  <!-- removed nonfunctional menu - see file history to retrieve -->\n</menu>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/menu/history.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2012 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\">\n  <item android:id=\"@+id/menu_history_send\"\n        android:title=\"@string/history_send\"\n        android:icon=\"@android:drawable/ic_menu_share\"\n        android:orderInCategory=\"1\"/>\n  <item android:id=\"@+id/menu_history_clear_text\"\n        android:title=\"@string/history_clear_text\"\n        android:icon=\"@android:drawable/ic_menu_delete\"\n        android:orderInCategory=\"2\"/>\n</menu>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/values/arrays.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<resources>\n  <string-array name=\"country_codes\">\n    <item>-</item>\n    <item>AR</item>\n    <item>AU</item>\n    <item>BR</item>\n    <item>BG</item>\n    <item>CA</item>\n    <item>CN</item>\n    <item>CZ</item>\n    <item>DE</item>\n    <item>DK</item>\n    <item>ES</item>\n    <item>FI</item>\n    <item>FR</item>\n    <item>GB</item>\n    <item>GR</item>\n    <item>HU</item>\n    <item>ID</item>\n    <item>IT</item>\n    <item>JP</item>\n    <item>KR</item>\n    <item>NL</item>\n    <item>PL</item>\n    <item>PT</item>\n    <item>RU</item>\n    <item>SE</item>\n    <item>SK</item>\n    <item>SI</item>\n    <item>TR</item>\n    <item>TW</item>\n    <item>US</item>\n  </string-array>\n</resources>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2008 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<resources>\n  <color name=\"contents_text\">#ff000000</color>\n  <color name=\"encode_view\">#ffffffff</color>\n  <color name=\"possible_result_points\">#c0ffbd21</color> <!-- Android standard ICS color -->\n  <color name=\"result_minor_text\">#ffc0c0c0</color>\n  <color name=\"result_points\">#c099cc00</color> <!-- Android standard ICS color -->\n  <color name=\"result_text\">#ffffffff</color>\n  <color name=\"result_view\">#b0000000</color>\n  <color name=\"status_text\">#ffffffff</color>\n  <color name=\"transparent\">#00000000</color>\n  <color name=\"viewfinder_laser\">#ffcc0000</color> <!-- Android standard ICS color -->\n  <color name=\"viewfinder_mask\">#60000000</color>\n</resources>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/values/dimens.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<resources>\n  <dimen name=\"standard_padding\">8dip</dimen>\n  <dimen name=\"half_padding\">4dip</dimen>\n</resources>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/values/ids.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2008 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<resources>\n  <item type=\"id\" name=\"decode\"/>\n  <item type=\"id\" name=\"decode_failed\"/>\n  <item type=\"id\" name=\"decode_succeeded\"/>\n  <item type=\"id\" name=\"launch_product_query\"/>\n  <item type=\"id\" name=\"quit\"/>\n  <item type=\"id\" name=\"restart_preview\"/>\n  <item type=\"id\" name=\"return_scan_result\"/>\n</resources>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/values/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2010 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<resources>\n  <string name=\"app_name\">Barcode Scanner</string>\n  <string name=\"app_picker_name\">Applications</string>\n  <string name=\"bookmark_picker_name\">Bookmarks</string>\n  <string name=\"button_add_calendar\">Add to calendar</string>\n  <string name=\"button_add_contact\">Add contact</string>\n  <string name=\"button_back\">Back</string>\n  <string name=\"button_book_search\">Book Search</string>\n  <string name=\"button_cancel\">Cancel</string>\n  <string name=\"button_custom_product_search\">Custom search</string>\n  <string name=\"button_dial\">Dial number</string>\n  <string name=\"button_done\">Done</string>\n  <string name=\"button_email\">Send email</string>\n  <string name=\"button_get_directions\">Get directions</string>\n  <string name=\"button_google_shopper\">Shopper</string>\n  <string name=\"button_mms\">Send MMS</string>\n  <string name=\"button_ok\">OK</string>\n  <string name=\"button_open_browser\">Open browser</string>\n  <string name=\"button_product_search\">Product Search</string>\n  <string name=\"button_search_book_contents\">Search contents</string>\n  <string name=\"button_share_app\">Application</string>\n  <string name=\"button_share_bookmark\">Bookmark</string>\n  <string name=\"button_share_by_email\">Share via email</string>\n  <string name=\"button_share_by_sms\">Share via SMS</string>\n  <string name=\"button_share_clipboard\">Clipboard</string>\n  <string name=\"button_share_contact\">Contact</string>\n  <string name=\"button_show_map\">Show map</string>\n  <string name=\"button_sms\">Send SMS</string>\n  <string name=\"button_web_search\">Web search</string>\n  <string name=\"button_wifi\">Connect to Network</string>\n  <string name=\"contents_contact\">Contact info</string>\n  <string name=\"contents_email\">Email address</string>\n  <string name=\"contents_location\">Geographic coordinates</string>\n  <string name=\"contents_phone\">Phone number</string>\n  <string name=\"contents_sms\">SMS address</string>\n  <string name=\"contents_text\">Plain text</string>\n  <string name=\"history_clear_text\">Clear history</string>\n  <string name=\"history_clear_one_history_text\">Clear</string>\n  <string name=\"history_email_title\">Barcode Scanner history</string>\n  <string name=\"history_empty\">Empty</string>\n  <string name=\"history_empty_detail\">No barcode scans have been recorded</string>\n  <string name=\"history_send\">Send history</string>\n  <string name=\"history_title\">History</string>\n  <string name=\"menu_encode_mecard\">Use MECARD</string>\n  <string name=\"menu_encode_vcard\">Use vCard</string>\n  <string name=\"menu_help\">Help</string>\n  <string name=\"menu_history\">History</string>\n  <string name=\"menu_settings\">Settings</string>\n  <string name=\"menu_share\">Share</string>\n  <string name=\"msg_bulk_mode_scanned\">Bulk mode: barcode scanned and saved</string>\n  <string name=\"msg_camera_framework_bug\">Sorry, the Android camera encountered a problem. You may need to restart the device.</string>\n  <string name=\"msg_default_format\">Format</string>\n  <string name=\"msg_default_meta\">Metadata</string>\n  <string name=\"msg_default_mms_subject\">Hi</string>\n  <string name=\"msg_default_status\">Place a barcode inside the viewfinder rectangle to scan it.</string>\n  <string name=\"msg_default_time\">Time</string>\n  <string name=\"msg_default_type\">Type</string>\n  <string name=\"msg_encode_contents_failed\">Could not encode a barcode from the data provided.</string>\n  <string name=\"msg_google_books\">Google Books</string>\n  <string name=\"msg_google_product\">Google Product Search</string>\n  <string name=\"msg_google_shopper_missing\">Google Shopper is not installed</string>\n  <string name=\"msg_install_google_shopper\">Google Shopper combines barcode scanning with online and local prices, reviews and more without opening the browser. Would you like to try it?</string>\n  <string name=\"msg_intent_failed\">Sorry, the requested application could not be launched. The barcode contents may be invalid.</string>\n  <string name=\"msg_redirect\">Redirect</string>\n  <string name=\"msg_sbc_book_not_searchable\">Sorry, this book is not searchable.</string>\n  <string name=\"msg_sbc_failed\">Sorry, the search encountered a problem.</string>\n  <string name=\"msg_sbc_no_page_returned\">No page returned</string>\n  <string name=\"msg_sbc_page\">Page</string>\n  <string name=\"msg_sbc_results\">Results</string>\n  <string name=\"msg_sbc_searching_book\">Searching book\\u2026</string>\n  <string name=\"msg_sbc_snippet_unavailable\">Snippet not available</string>\n  <string name=\"msg_sbc_unknown_page\">Unknown page</string>\n  <string name=\"msg_share_explanation\">You can share data by displaying a barcode on your screen and scanning it with another phone.</string>\n  <string name=\"msg_share_subject_line\">Here are the contents of a barcode I scanned</string>\n  <string name=\"msg_share_text\">Or type some text and press Enter</string>\n  <string name=\"msg_sure\">Are you sure?</string>\n  <string name=\"msg_unmount_usb\">Sorry, the SD card is not accessible.</string>\n  <string name=\"preferences_actions_title\">When a barcode is found\\u2026</string>\n  <string name=\"preferences_auto_focus_title\">Use auto focus</string>\n  <string name=\"preferences_bulk_mode_summary\">Scan and save many barcodes continuously</string>\n  <string name=\"preferences_bulk_mode_title\">Bulk scan mode</string>\n  <string name=\"preferences_copy_to_clipboard_title\">Copy to clipboard</string>\n  <string name=\"preferences_custom_product_search_summary\" formatted=\"false\">Substitutions: %s = contents, %f = format, %t = type</string>\n  <string name=\"preferences_custom_product_search_title\">Custom search URL</string>\n  <string name=\"preferences_decode_1D_title\">1D barcodes</string>\n  <string name=\"preferences_decode_Data_Matrix_title\">Data Matrix</string>\n  <string name=\"preferences_decode_QR_title\">QR Codes</string>\n  <string name=\"preferences_device_bug_workarounds_title\">Device Bug Workarounds</string>\n  <string name=\"preferences_disable_continuous_focus_summary\">Use only standard focus mode</string>\n  <string name=\"preferences_disable_continuous_focus_title\">No continuous focus</string>\n  <string name=\"preferences_disable_exposure_title\">No exposure</string>\n  <string name=\"preferences_front_light_summary\">Improves scanning in low light on some phones, but may cause glare. Does not work on all phones.</string>\n  <string name=\"preferences_front_light_title\">Use front light</string>\n  <string name=\"preferences_general_title\">General settings</string>\n  <string name=\"preferences_name\">Settings</string>\n  <string name=\"preferences_play_beep_title\">Beep</string>\n  <string name=\"preferences_remember_duplicates_summary\">Store multiple scans of the same barcode in History</string>\n  <string name=\"preferences_remember_duplicates_title\">Remember duplicates</string>\n  <string name=\"preferences_result_title\">Result settings</string>\n  <string name=\"preferences_scanning_title\">When scanning for barcodes, decode\\u2026</string>\n  <string name=\"preferences_search_country\">Search country</string>\n  <string name=\"preferences_try_bsplus\">Try Barcode Scanner+</string>\n  <string name=\"preferences_try_bsplus_summary\">Enhanced with new features and interface</string>\n  <string name=\"preferences_supplemental_summary\">Try to retrieve more information about the barcode contents</string>\n  <string name=\"preferences_supplemental_title\">Retrieve more info</string>\n  <string name=\"preferences_vibrate_title\">Vibrate</string>\n  <string name=\"result_address_book\">Found contact info</string>\n  <string name=\"result_calendar\">Found calendar event</string>\n  <string name=\"result_email_address\">Found email address</string>\n  <string name=\"result_geo\">Found geographic coordinates</string>\n  <string name=\"result_isbn\">Found book</string>\n  <string name=\"result_product\">Found product</string>\n  <string name=\"result_sms\">Found SMS address</string>\n  <string name=\"result_tel\">Found phone number</string>\n  <string name=\"result_text\">Found plain text</string>\n  <string name=\"result_uri\">Found URL</string>\n  <string name=\"result_wifi\">Found WLAN Configuration</string>\n  <string name=\"sbc_name\">Google Book Search</string>\n  <string name=\"share_name\">Share via barcode</string>\n  <string name=\"wifi_changing_network\">Requesting connection to network\\u2026</string>\n  <string name=\"wifi_ssid_label\">Network Name</string>\n  <string name=\"wifi_type_label\">Type</string>\n</resources>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/values-ar/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2012 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<resources>\n  <!-- <string name=\"app_name\">ماسح الرمز الشريطي</string> -->\n  <string name=\"app_picker_name\">تطبيقات</string>\n  <string name=\"bookmark_picker_name\">إشارات مرجعية</string>\n  <string name=\"button_add_calendar\">إضافة إلى التقويم</string>\n  <string name=\"button_add_contact\">إضافة جهة اتصال</string>\n  <string name=\"button_back\">السابق</string>\n  <string name=\"button_book_search\">بحث في الكتب</string>\n  <string name=\"button_cancel\">إلغاء</string>\n  <string name=\"button_custom_product_search\">بحث مخصص</string>\n  <string name=\"button_dial\">طلب رقم</string>\n  <string name=\"button_done\">تم</string>\n  <string name=\"button_email\">إرسال بريد</string>\n  <string name=\"button_get_directions\">معرفة الاتجاهات</string>\n  <string name=\"button_google_shopper\">Shopper</string>\n  <string name=\"button_mms\">إرسال MMS</string>\n  <string name=\"button_ok\">موافق</string>\n  <string name=\"button_open_browser\">فتح المتصفح</string>\n  <string name=\"button_product_search\">بحث عن منتجات</string>\n  <string name=\"button_search_book_contents\">بحث في المحتويات</string>\n  <string name=\"button_share_app\">التطبيق</string>\n  <string name=\"button_share_bookmark\">إشارة مرجعية</string>\n  <string name=\"button_share_by_email\">مشاركة عبر البريد</string>\n  <string name=\"button_share_by_sms\">مشاركة عبر SMS</string>\n  <string name=\"button_share_clipboard\">حافظة</string>\n  <string name=\"button_share_contact\">جهة اتصال</string>\n  <string name=\"button_show_map\">عرض الخريطة</string>\n  <string name=\"button_sms\">إرسال SMS</string>\n  <string name=\"button_web_search\">بحث في الويب</string>\n  <string name=\"button_wifi\">الاتصال بشبك</string>\n  <string name=\"contents_contact\">معلومات جهة اتصال</string>\n  <string name=\"contents_email\">عنوان البريد</string>\n  <string name=\"contents_location\">إحداثيات جغرافية</string>\n  <string name=\"contents_phone\">رقم الهاتف</string>\n  <string name=\"contents_sms\">عنوان SMS</string>\n  <string name=\"contents_text\">نص عادي</string>\n  <string name=\"history_clear_one_history_text\">حذف</string>\n  <string name=\"history_clear_text\">مسح السجل</string>\n  <string name=\"history_email_title\">سجل ماسح الرموز الشريطية</string>\n  <string name=\"history_empty\">فارغ</string>\n  <string name=\"history_empty_detail\">لم تسجل حتى الآن بمسح الباركود</string>\n  <string name=\"history_send\">إرسال السجل</string>\n  <string name=\"history_title\">سجل</string>\n  <string name=\"menu_encode_mecard\">استخدام MECARD</string>\n  <string name=\"menu_encode_vcard\">استخدام vCard</string>\n  <string name=\"menu_help\">تعليمات</string>\n  <string name=\"menu_history\">سجل</string>\n  <string name=\"menu_settings\">إعدادات</string>\n  <string name=\"menu_share\">مشاركة</string>\n  <string name=\"msg_bulk_mode_scanned\">معظم الدراسي : الباركود الممسوحة ضوئيا وحفظها</string>\n  <string name=\"msg_camera_framework_bug\">عفوا، حدثت مشكلة في كاميرا جهاز Android. قد تحتاج إلى إعادة تشغيل الجهاز.</string>\n  <string name=\"msg_default_format\">التنسيق</string>\n  <string name=\"msg_default_meta\">البيانات الوصفية</string>\n  <string name=\"msg_default_mms_subject\">أهلا</string>\n  <string name=\"msg_default_status\">قم بوضع الرمز الشريطي داخل حدود صورة الكاميرا ليتم مسحه.</string>\n  <string name=\"msg_default_time\">الوقت</string>\n  <string name=\"msg_default_type\">النوع</string>\n  <string name=\"msg_encode_contents_failed\">تعذر ترميز رمز شريطي من البيانات المتوفرة.</string>\n  <string name=\"msg_google_books\">كتب جوجل</string>\n  <string name=\"msg_google_product\">بحث جوجل</string>\n  <string name=\"msg_google_shopper_missing\">لم يتم تثبيت Google Shopper</string>\n  <string name=\"msg_install_google_shopper\">يجمع Google Shopper بين مسح الرمز الشريطي مع الأسعار والتعليقات وغيرها بدون فتح المتصفح. هل تريد استخدامه؟</string>\n  <string name=\"msg_intent_failed\">عفوا، تعذر تشغيل التطبيق المطلوب. قد تكون محتويات الرمز الشريطي غير صحيحة.</string>\n  <string name=\"msg_redirect\">إعادة توجيه</string>\n  <string name=\"msg_sbc_book_not_searchable\">عفوا، لا يمكن البحث في هذا الكتاب.</string>\n  <string name=\"msg_sbc_failed\">عفوا، حدثت مشكلة في عملية البحث.</string>\n  <string name=\"msg_sbc_no_page_returned\">لم يتم إرجاع أية صفحة</string>\n  <string name=\"msg_sbc_page\">الصفحة</string>\n  <string name=\"msg_sbc_results\">النتائج</string>\n  <string name=\"msg_sbc_searching_book\">البحث في الكتاب</string>\n  <string name=\"msg_sbc_snippet_unavailable\">الأجزاء غير متاحة</string>\n  <string name=\"msg_sbc_unknown_page\">صفحة غير معروفة</string>\n  <string name=\"msg_share_explanation\">يمكنك مشاركة البيانات عن طريق عرض رمز شريطي على الشاشة ومسحه من خلال هاتف آخر.</string>\n  <string name=\"msg_share_subject_line\">توجد هنا محتويات الرمز الشريطي الذي قمت بمسحه</string>\n  <string name=\"msg_share_text\">أو اكتب بعض النص</string>\n  <string name=\"msg_sure\">هل أنت متأكد؟</string>\n  <string name=\"msg_unmount_usb\">رجاء إيقاف التخزين على USB للمتابعة.</string>\n  <string name=\"preferences_actions_title\">عند العثور على رمز شريطي</string>\n  <string name=\"preferences_auto_focus_title\">استخدام التركيز التلقائي</string>\n  <string name=\"preferences_bulk_mode_summary\">المسح الضوئي وحفظها بشكل مستمر العديد من الرموز الشريطية</string>\n  <string name=\"preferences_bulk_mode_title\">جل وضع المسح الضوئي</string>\n  <string name=\"preferences_copy_to_clipboard_title\">نسخ إلى الحافظة</string>\n  <string name=\"preferences_custom_product_search_summary\" formatted=\"false\">التبديلات : s٪ = المحتويات ،  f٪ = الشكل ، اكتب t٪ =</string>\n  <string name=\"preferences_custom_product_search_title\">عنوان بحث مخصص</string>\n  <string name=\"preferences_decode_1D_title\">فك الرموز الشريطية 1D</string>\n  <string name=\"preferences_decode_Data_Matrix_title\">فك رموز البيانات ماتريكس</string>\n  <string name=\"preferences_decode_QR_title\">فك رموز QR</string>\n  <string name=\"preferences_device_bug_workarounds_title\">الحلول جهاز علة</string>\n  <string name=\"preferences_disable_continuous_focus_summary\">استخدام وضع معيار التركيز فقط</string>\n  <string name=\"preferences_disable_continuous_focus_title\">لا التركيز المستمر</string>\n  <string name=\"preferences_disable_exposure_title\">لا تعرض</string>\n  <string name=\"preferences_front_light_summary\">تقوم بتحسين عملية المسح في إضاءة ضعيفة في بعض الهواتف، ولكن يمكن أن يتسبب في حدوث سطوع</string>\n  <string name=\"preferences_front_light_title\">استخدم إضاءة أمامية</string>\n  <string name=\"preferences_general_title\">إعدادات عامة</string>\n  <string name=\"preferences_name\">إعدادات</string>\n  <string name=\"preferences_play_beep_title\">صوت تنبيه</string>\n  <string name=\"preferences_remember_duplicates_summary\">بفحص مخزن متعددة من نفس الباركود في التاريخ</string>\n  <string name=\"preferences_remember_duplicates_title\">تذكر التكرارات</string>\n  <string name=\"preferences_result_title\">إعدادات النتائج</string>\n  <string name=\"preferences_scanning_title\">عندما لمسح الباركود</string>\n  <string name=\"preferences_search_country\">ابحث عن بلد</string>\n  <string name=\"preferences_supplemental_summary\">محاولة لاسترداد مزيد من المعلومات حول محتويات الباركود</string>\n  <string name=\"preferences_supplemental_title\">استرداد مزيد من المعلومات</string>\n  <string name=\"preferences_try_bsplus\">محاولة الباركود +</string>\n  <string name=\"preferences_try_bsplus_summary\">معززة مع الميزات الجديدة واجهة</string>\n  <string name=\"preferences_vibrate_title\">اهتزاز</string>\n  <string name=\"result_address_book\">تم العثور على معلومات جهة الاتصال</string>\n  <string name=\"result_calendar\">تم العثور على حدث التقويم</string>\n  <string name=\"result_email_address\">تم العثور على عنوان البريد</string>\n  <string name=\"result_geo\">تم العثور على الإحداثيات الجغرافية</string>\n  <string name=\"result_isbn\">تم العثور على الكتاب</string>\n  <string name=\"result_product\">تم العثور على المنتج</string>\n  <string name=\"result_sms\">تم العثور على عنوان SMS</string>\n  <string name=\"result_tel\">تم العثور على رقم الهاتف</string>\n  <string name=\"result_text\">تم العثور على نص عادي</string>\n  <string name=\"result_uri\">تم العثور على العنوان</string>\n  <string name=\"result_wifi\">العثور على التكوين اللاسلك</string>\n  <string name=\"sbc_name\">البحث في Google Book</string>\n  <string name=\"share_name\">مشاركة عبر الرمز الشريطي</string>\n  <string name=\"wifi_changing_network\">طلب الاتصال بالشبكة\\u2026</string>\n  <string name=\"wifi_ssid_label\">اسم الشبكة</string>\n  <string name=\"wifi_type_label\">نوع</string>\n</resources>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/values-bg/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2012 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<resources>\n  <!-- <string name=\"app_name\">Баркод Скенер</string> -->\n  <string name=\"app_picker_name\">Приложения</string>\n  <string name=\"bookmark_picker_name\">Отметки</string>\n  <string name=\"button_add_calendar\">Добави в календар</string>\n  <string name=\"button_add_contact\">Добави контакт</string>\n  <string name=\"button_back\">Обратно</string>\n  <string name=\"button_book_search\">Търси Книга</string>\n  <string name=\"button_cancel\">Отказ</string>\n  <string name=\"button_custom_product_search\">Потребителско търсене</string>\n  <string name=\"button_dial\">Набери телефон</string>\n  <string name=\"button_done\">Готово</string>\n  <string name=\"button_email\">Изпрати поща</string>\n  <string name=\"button_get_directions\">Навигация</string>\n  <string name=\"button_google_shopper\">Гугъл магазин</string>\n  <string name=\"button_mms\">Изпрати MMS</string>\n  <string name=\"button_ok\">ОК</string>\n  <string name=\"button_open_browser\">Отвори браузър</string>\n  <string name=\"button_product_search\">Търсене на продукт</string>\n  <string name=\"button_search_book_contents\">Търси в книга</string>\n  <string name=\"button_share_app\">Приложение</string>\n  <string name=\"button_share_bookmark\">Отметка</string>\n  <string name=\"button_share_by_email\">Сподели по поща</string>\n  <string name=\"button_share_by_sms\">Сподели чрез SMS</string>\n  <string name=\"button_share_clipboard\">Клипборд</string>\n  <string name=\"button_share_contact\">Контакт</string>\n  <string name=\"button_show_map\">Покажи карта</string>\n  <string name=\"button_sms\">Изпрати SMS</string>\n  <string name=\"button_web_search\">Интернет търсене</string>\n  <string name=\"button_wifi\">Свържи се в мрежата</string>\n  <string name=\"contents_contact\">Информация за контакт</string>\n  <string name=\"contents_email\">Електронна поща</string>\n  <string name=\"contents_location\">Географски координати</string>\n  <string name=\"contents_phone\">Телефон</string>\n  <string name=\"contents_sms\">SMS адрес</string>\n  <string name=\"contents_text\">Чист текст</string>\n  <string name=\"history_clear_one_history_text\">Изчисти</string>\n  <string name=\"history_clear_text\">Изчисти историята</string>\n  <string name=\"history_email_title\">История на Баркод Скенера</string>\n  <string name=\"history_empty\">Празно</string>\n  <string name=\"history_empty_detail\">Няма сканирани и записани бар-кодове все още</string>\n  <string name=\"history_send\">Изпрати историята</string>\n  <string name=\"history_title\">История</string>\n  <string name=\"menu_encode_mecard\">Използвай MECARD формат</string>\n  <string name=\"menu_encode_vcard\">Използвай vCard формат</string>\n  <string name=\"menu_help\">Помощ</string>\n  <string name=\"menu_history\">История</string>\n  <string name=\"menu_settings\">Настройки</string>\n  <string name=\"menu_share\">Сподели</string>\n  <string name=\"msg_bulk_mode_scanned\">Масов режим: баркодът е сканиран и записан</string>\n  <string name=\"msg_camera_framework_bug\">Съжаляваме, срещнахме проблем с камерата. Може да се наложи да рестартирате устройството си.</string>\n  <string name=\"msg_default_format\">Формат</string>\n  <string name=\"msg_default_meta\">Допълнение</string>\n  <string name=\"msg_default_mms_subject\">Здравейте</string>\n  <string name=\"msg_default_status\">Сложете баркода вътре в правоъгълника за да го сканирате.</string>\n  <string name=\"msg_default_time\">Време</string>\n  <string name=\"msg_default_type\">Тип</string>\n  <string name=\"msg_encode_contents_failed\">Неуспешно кодиране на подадените данни.</string>\n  <string name=\"msg_google_books\">Google Books</string>\n  <string name=\"msg_google_product\">Google Търсене на продукти</string>\n  <string name=\"msg_google_shopper_missing\">Гугъл Магазин не е инсталиран</string>\n  <string name=\"msg_install_google_shopper\">Гугъл Магазин комбинира сканирането на баркодове с онлайн и локални цени, отзиви и още много неща без да отваряте браузър. Желаете ли да опитате?</string>\n  <string name=\"msg_intent_failed\">Съжаляваме, но нужното приложение не успя да се стартира. Възможно е баркода или съдържанието му да са невалидни.</string>\n  <string name=\"msg_redirect\">Пренасочване</string>\n  <string name=\"msg_sbc_book_not_searchable\">Съжаляваме, тази книга не може да се претърсва.</string>\n  <string name=\"msg_sbc_failed\">Съжаляваме, срещнахме проблем при търсенето.</string>\n  <string name=\"msg_sbc_no_page_returned\">Няма страница</string>\n  <string name=\"msg_sbc_page\">Страница</string>\n  <string name=\"msg_sbc_results\">Резултати</string>\n  <string name=\"msg_sbc_searching_book\">Търсене на книга\\u2026</string>\n  <string name=\"msg_sbc_snippet_unavailable\">Изрезката не е достъпна</string>\n  <string name=\"msg_sbc_unknown_page\">Непозната страница</string>\n  <string name=\"msg_share_explanation\">Можете да споделяте информация като покажете баркод на екрана, и го сканирате от друг телефон.</string>\n  <string name=\"msg_share_subject_line\">Ето съдържанието на един баркод, който сканирах</string>\n  <string name=\"msg_share_text\">Или въведете някакъв текст</string>\n  <string name=\"msg_sure\">Сигурни ли сте?</string>\n  <string name=\"msg_unmount_usb\">Съжаляваме, но SD картата не е достъпна.</string>\n  <string name=\"preferences_actions_title\">При прочитане на баркод\\u2026</string>\n  <string name=\"preferences_auto_focus_title\">Използване на автоматично фокусиране</string>\n  <string name=\"preferences_bulk_mode_summary\">Сканирай и запомняй множество баркодове без прекъсване</string>\n  <string name=\"preferences_bulk_mode_title\">Масово сканиране</string>\n  <string name=\"preferences_copy_to_clipboard_title\">Копиране в клипборда</string>\n  <string name=\"preferences_custom_product_search_summary\" formatted=\"false\">Използвайте: %s за съдържанието,%f за форматa, %t за типа</string>\n  <string name=\"preferences_custom_product_search_title\">Потребителски адрес за търсене</string>\n  <string name=\"preferences_decode_1D_title\">1D Баркодове</string>\n  <string name=\"preferences_decode_Data_Matrix_title\">Data Matrix</string>\n  <string name=\"preferences_decode_QR_title\">QR Баркодове</string>\n  <string name=\"preferences_device_bug_workarounds_title\">Заобикаляне на проблеми</string>\n  <string name=\"preferences_disable_continuous_focus_summary\">Използване само на стандартен режим за фокусиране</string>\n  <string name=\"preferences_disable_continuous_focus_title\">Без непрекъснат фокус</string>\n  <string name=\"preferences_disable_exposure_title\">Никоя експозиция</string>\n  <string name=\"preferences_front_light_summary\">Подобрява четенето при лошо осветление, но предизвиква отблясъци. Само за някои модели.</string>\n  <string name=\"preferences_front_light_title\">Използвай фенерче</string>\n  <string name=\"preferences_general_title\">Общи настройки</string>\n  <string name=\"preferences_name\">Настройки</string>\n  <string name=\"preferences_play_beep_title\">Издаване на звук</string>\n  <string name=\"preferences_remember_duplicates_summary\">Записвай множество сканирания на един и същи баркод в историята</string>\n  <string name=\"preferences_remember_duplicates_title\">Запомняне на повторенията</string>\n  <string name=\"preferences_result_title\">Настройки за резултата</string>\n  <string name=\"preferences_scanning_title\">При сканиране да се декодират\\u2026</string>\n  <string name=\"preferences_search_country\">Държава при търсене</string>\n  <string name=\"preferences_supplemental_summary\">Опитай да получиш повече информация за баркода</string>\n  <string name=\"preferences_supplemental_title\">Търсене на разширения</string>\n  <string name=\"preferences_try_bsplus\">Опитайте Баркод Скенер+</string>\n  <string name=\"preferences_try_bsplus_summary\">Обогатен с нови характеристики и интерфейс</string>\n  <string name=\"preferences_vibrate_title\">Вибрация</string>\n  <string name=\"result_address_book\">Намерих информация за контакт</string>\n  <string name=\"result_calendar\">Намерих календарно събитие</string>\n  <string name=\"result_email_address\">Намерих адрес на електронна поща</string>\n  <string name=\"result_geo\">Намерих географски координати</string>\n  <string name=\"result_isbn\">Намерих книга</string>\n  <string name=\"result_product\">Намерих продукт</string>\n  <string name=\"result_sms\">Намерих адрес за SMS</string>\n  <string name=\"result_tel\">Намерих телефонен номер</string>\n  <string name=\"result_text\">Намерих чист текст</string>\n  <string name=\"result_uri\">Намерих Интернет Адрес</string>\n  <string name=\"result_wifi\">Намерих настройки за безжична мрежа</string>\n  <string name=\"sbc_name\">Гугъл търсене на книга</string>\n  <string name=\"share_name\">Сподели чрез баркод</string>\n  <string name=\"wifi_changing_network\">Запитване свързване към мрежата\\u2026</string>\n  <string name=\"wifi_ssid_label\">Име на мрежата</string>\n  <string name=\"wifi_type_label\">Тип</string>\n</resources>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/values-ca/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2012 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<resources>\n  <!-- <string name=\"app_name\">Barcode Scanner</string> -->\n  <string name=\"app_picker_name\">Aplicacions</string>\n  <string name=\"bookmark_picker_name\">Adreces d\\'interès</string>\n  <string name=\"button_add_calendar\">Afegeix a l\\'agenda</string>\n  <string name=\"button_add_contact\">Afegeix el contact</string>\n  <string name=\"button_back\">Enrere</string>\n  <string name=\"button_book_search\">Cerca el llibre</string>\n  <string name=\"button_cancel\">Cancel·la</string>\n  <string name=\"button_custom_product_search\">Cerca personalitzada</string>\n  <string name=\"button_dial\">Marca el número</string>\n  <string name=\"button_done\">Fet</string>\n  <string name=\"button_email\">Envia un correu electrònic</string>\n  <string name=\"button_get_directions\">Obté direccions</string>\n  <string name=\"button_google_shopper\">Shopper</string>\n  <string name=\"button_mms\">Envia MMS</string>\n  <string name=\"button_ok\">D\\'acord</string>\n  <string name=\"button_open_browser\">Obre el navegador</string>\n  <string name=\"button_product_search\">Cerca un producte</string>\n  <string name=\"button_search_book_contents\">Cerca continguts</string>\n  <string name=\"button_share_app\">Aplicació</string>\n  <string name=\"button_share_bookmark\">Adreça d\\'interès</string>\n  <string name=\"button_share_by_email\">Comparteix per correu-e</string>\n  <string name=\"button_share_by_sms\">Comparteix per SMS</string>\n  <string name=\"button_share_clipboard\">Porta-retalls</string>\n  <string name=\"button_share_contact\">Contacte</string>\n  <string name=\"button_show_map\">Mostra el mapa</string>\n  <string name=\"button_sms\">Envia SMS</string>\n  <string name=\"button_web_search\">Cerca al web</string>\n  <string name=\"button_wifi\">Connecta a la xarxa</string>\n  <string name=\"contents_contact\">Informació de contacte</string>\n  <string name=\"contents_email\">Adreça electrònica</string>\n  <string name=\"contents_location\">Coordenades geogràfiques</string>\n  <string name=\"contents_phone\">Número de telèfon</string>\n  <string name=\"contents_sms\">Adreça SMS</string>\n  <string name=\"contents_text\">Text pla</string>\n  <string name=\"history_clear_one_history_text\">Neteja</string>\n  <string name=\"history_clear_text\">Neteja l\\'historial</string>\n  <string name=\"history_email_title\">Historial del Barcode Scanner</string>\n  <string name=\"history_empty\">Buit</string>\n  <string name=\"history_empty_detail\">No escaneja codis de barres s\\'han registrat encara</string>\n  <string name=\"history_send\">Envia l\\'historial</string>\n  <string name=\"history_title\">Historial</string>\n  <string name=\"menu_encode_mecard\">Utilitza MECARD</string>\n  <string name=\"menu_encode_vcard\">Utilitza vCard</string>\n  <string name=\"menu_help\">Ajuda</string>\n  <string name=\"menu_history\">Historial</string>\n  <string name=\"menu_settings\">Configuració</string>\n  <string name=\"menu_share\">Comparteix</string>\n  <string name=\"msg_bulk_mode_scanned\">Mode en bloc: codi de barres escanejat i desat</string>\n  <string name=\"msg_camera_framework_bug\">S\\'ha produït un problema amb la càmera de l\\'Android. Potser haureu de reiniciar el dispositiu.</string>\n  <string name=\"msg_default_format\">Format</string>\n  <string name=\"msg_default_meta\">Metadadades</string>\n  <string name=\"msg_default_mms_subject\">Hola</string>\n  <string name=\"msg_default_status\">Poseu un codi de barres dins el rectable per escanejar-lo.</string>\n  <string name=\"msg_default_time\">Hora</string>\n  <string name=\"msg_default_type\">Tipus</string>\n  <string name=\"msg_encode_contents_failed\">No es pot codificar un codi de barres amb les dades proporcionades.</string>\n  <string name=\"msg_google_books\">Google Llibres</string>\n  <string name=\"msg_google_product\">Cerca a Google Product</string>\n  <string name=\"msg_google_shopper_missing\">Google Shopper no es troba instal·lat</string>\n  <string name=\"msg_install_google_shopper\">Google Shopper combina l\\'escaneig de codis de barres amb preus en línia i locals, comentaris de productes i molt més sense obrir el navegador. Moleu provar-lo?</string>\n  <string name=\"msg_intent_failed\">No es pot executar l\\'aplicació sol·licitada. És possible que el contingut del codi de barres no sigui vàlid.</string>\n  <string name=\"msg_redirect\">Redirecciona</string>\n  <string name=\"msg_sbc_book_not_searchable\">No es pot cercar en aquest llibre.</string>\n  <string name=\"msg_sbc_failed\">Hi ha hagut un problema en fer la cerca.</string>\n  <string name=\"msg_sbc_no_page_returned\">No s\\'ha retornat cap pàgina</string>\n  <string name=\"msg_sbc_page\">Pàgina</string>\n  <string name=\"msg_sbc_results\">Resultats</string>\n  <string name=\"msg_sbc_searching_book\">S\\'està cercant el llibre\\u2026</string>\n  <string name=\"msg_sbc_snippet_unavailable\">Fragment no disponible</string>\n  <string name=\"msg_sbc_unknown_page\">Pàgina desconeguda</string>\n  <string name=\"msg_share_explanation\">Podeu compartir dades mostrant un codi de barres a la pantalla i escanejant-lo amb un altre dispositiu.</string>\n  <string name=\"msg_share_subject_line\">Aquí hi ha el contingut d\\'un codi de barres que he escanejat</string>\n  <string name=\"msg_share_text\">O escriviu un text i pitgeu Retorn</string>\n  <string name=\"msg_sure\">N\\'esteu segur?</string>\n  <string name=\"msg_unmount_usb\">La targeta SD no es troba disponible.</string>\n  <string name=\"preferences_actions_title\">En trobar un codi de barres\\u2026</string>\n  <string name=\"preferences_auto_focus_title\">Utilitzeu l\\'enfocament automàtic</string>\n  <string name=\"preferences_bulk_mode_summary\">Escaneja i desa molts codis de barres de forma contínua</string>\n  <string name=\"preferences_bulk_mode_title\">Mode d\\'escaneig en bloc</string>\n  <string name=\"preferences_copy_to_clipboard_title\">Copia al porta-retalls</string>\n  <string name=\"preferences_custom_product_search_summary\" formatted=\"false\">Substitucions: %s = contingut, %f = format, %t = tipus</string>\n  <string name=\"preferences_custom_product_search_title\">URL de cerca personalitzat</string>\n  <string name=\"preferences_decode_1D_title\">Codis de barres 1D</string>\n  <string name=\"preferences_decode_Data_Matrix_title\">Matriu de dades</string>\n  <string name=\"preferences_decode_QR_title\">Codis QR</string>\n  <string name=\"preferences_device_bug_workarounds_title\">Solucions provisionals de dispositius d\\'errors</string>\n  <string name=\"preferences_disable_continuous_focus_summary\">Utilitzeu només la manera d\\'enfocament estàndard</string>\n  <string name=\"preferences_disable_continuous_focus_title\">No enfocament continu</string>\n  <string name=\"preferences_disable_exposure_title\">No hi ha exposició</string>\n  <string name=\"preferences_front_light_summary\">Millora l\\'escaneig amb poca llum en alguns dispositius, però pot produir enlluernament. No funciona en tots els dispositius.</string>\n  <string name=\"preferences_front_light_title\">Usa el llum frontal</string>\n  <string name=\"preferences_general_title\">Configuració general</string>\n  <string name=\"preferences_name\">Configuració</string>\n  <string name=\"preferences_play_beep_title\">Beep</string>\n  <string name=\"preferences_remember_duplicates_summary\">Desa diversos escanejos del mateix codi de barres a l\\'historial</string>\n  <string name=\"preferences_remember_duplicates_title\">Recorda els duplicats</string>\n  <string name=\"preferences_result_title\">Configuració dels resultats</string>\n  <string name=\"preferences_scanning_title\">En escanejar codis de barres, descodifica\\u2026</string>\n  <string name=\"preferences_search_country\">Cerca per país</string>\n  <string name=\"preferences_supplemental_summary\">Intenta obtenir més informació sobre els continguts del codi de barres</string>\n  <string name=\"preferences_supplemental_title\">Aconsegueix més informació</string>\n  <string name=\"preferences_try_bsplus\">Intenta Barcode Scanner+</string>\n  <string name=\"preferences_try_bsplus_summary\">Millorat amb noves característiques i la interfície de</string>\n  <string name=\"preferences_vibrate_title\">Vibració</string>\n  <string name=\"result_address_book\">S\\'ha trobat informació de contacte</string>\n  <string name=\"result_calendar\">S\\'ha trobat un esdeveniment</string>\n  <string name=\"result_email_address\">S\\'ha trobat una adreça electrònica</string>\n  <string name=\"result_geo\">S\\'han trobat coordenades geogràfiques</string>\n  <string name=\"result_isbn\">S\\'ha trobat un llibre</string>\n  <string name=\"result_product\">S\\'ha trobat un producte</string>\n  <string name=\"result_sms\">S\\'ha trobat una adreça SMS</string>\n  <string name=\"result_tel\">S\\'ha trobat un número de telèfon</string>\n  <string name=\"result_text\">S\\'ha trobat text pla</string>\n  <string name=\"result_uri\">S\\'ha trobat un URL</string>\n  <string name=\"result_wifi\">S\\'ha trobat configuració WLAN</string>\n  <string name=\"sbc_name\">Cerca a Google Llibres</string>\n  <string name=\"share_name\">Comparteix amb el codi de barres</string>\n  <string name=\"wifi_changing_network\">Sollicitant connexió a la xarxa\\u2026</string>\n  <string name=\"wifi_ssid_label\">Nom de la xarxa</string>\n  <string name=\"wifi_type_label\">Tipus</string>\n</resources>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/values-cs/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2012 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<resources>\n  <!-- <string name=\"app_name\">Barcode Scanner</string> -->\n  <string name=\"app_picker_name\">Aplikace</string>\n  <string name=\"bookmark_picker_name\">Záložky</string>\n  <string name=\"button_add_calendar\">Přidat do kalendáře</string>\n  <string name=\"button_add_contact\">Přidat kontakt</string>\n  <string name=\"button_back\">Zpět</string>\n  <string name=\"button_book_search\">Hledat knihu</string>\n  <string name=\"button_cancel\">Zrušit</string>\n  <string name=\"button_custom_product_search\">Vlastní vyhledávání</string>\n  <string name=\"button_dial\">Číselník</string>\n  <string name=\"button_done\">Hotovo</string>\n  <string name=\"button_email\">Poslat emailem</string>\n  <string name=\"button_get_directions\">Získat nastavení</string>\n  <string name=\"button_google_shopper\">Shopper</string>\n  <string name=\"button_mms\">Poslat přes MMS</string>\n  <string name=\"button_ok\">OK</string>\n  <string name=\"button_open_browser\">Otevřít prohlížeč</string>\n  <string name=\"button_product_search\">Vyhledat produkt</string>\n  <string name=\"button_search_book_contents\">Hledat obsah knihy</string>\n  <string name=\"button_share_app\">Aplikace</string>\n  <string name=\"button_share_bookmark\">Záložky</string>\n  <string name=\"button_share_by_email\">Sdílet pomocí Email</string>\n  <string name=\"button_share_by_sms\">Sdílet pomocí SMS</string>\n  <string name=\"button_share_clipboard\">Schránka</string>\n  <string name=\"button_share_contact\">Kontakty</string>\n  <string name=\"button_show_map\">Ukázat na mapě</string>\n  <string name=\"button_sms\">Poslat SMS</string>\n  <string name=\"button_web_search\">Hledat na webu</string>\n  <string name=\"button_wifi\">Připojení k síti</string>\n  <string name=\"contents_contact\">Info kontaktu</string>\n  <string name=\"contents_email\">Emailová adresa</string>\n  <string name=\"contents_location\">Zeměpisné údaje</string>\n  <string name=\"contents_phone\">Telefonní číslo</string>\n  <string name=\"contents_sms\">SMS číslo</string>\n  <string name=\"contents_text\">Ostatní</string>\n  <string name=\"history_clear_one_history_text\">Vyčistit</string>\n  <string name=\"history_clear_text\">Vyčistit historii</string>\n  <string name=\"history_email_title\">Barcode Scanner historie</string>\n  <string name=\"history_empty\">Prázdný</string>\n  <string name=\"history_empty_detail\">Žádný čárový kód vyšetření byly zaznamenány ještě</string>\n  <string name=\"history_send\">Poslat historii</string>\n  <string name=\"history_title\">Historie</string>\n  <string name=\"menu_encode_mecard\">Použití MECARD</string>\n  <string name=\"menu_encode_vcard\">Použití vCard</string>\n  <string name=\"menu_help\">Pomoc!</string>\n  <string name=\"menu_history\">Historie</string>\n  <string name=\"menu_settings\">Nastavení</string>\n  <string name=\"menu_share\">Sdílet</string>\n  <string name=\"msg_bulk_mode_scanned\">Bulk režimu: čárový kód naskenované a uložené</string>\n  <string name=\"msg_camera_framework_bug\">Omlouváme se, fotoaparát má problém. Možná bude nutné restartovat zařízení</string>\n  <string name=\"msg_default_format\">Formát</string>\n  <string name=\"msg_default_meta\">Metadata</string>\n  <string name=\"msg_default_mms_subject\">Ahoj</string>\n  <string name=\"msg_default_status\">Strefte se čtverečkem na čárový kód</string>\n  <string name=\"msg_default_time\">Čas</string>\n  <string name=\"msg_default_type\">Typ</string>\n  <string name=\"msg_encode_contents_failed\">Nepodařilo se rozkódovat čárový kód z poskytnutých údajů.</string>\n  <string name=\"msg_google_books\">Google Books</string>\n  <string name=\"msg_google_product\">Google Product Search</string>\n  <string name=\"msg_google_shopper_missing\">Google Shopper není nainstalován</string>\n  <string name=\"msg_install_google_shopper\">Google Shopper kombinuje technologie čárového kódu s cenami, recenze a více bez otevření prohlížeče. Chtěli byste to zkusit?</string>\n  <string name=\"msg_intent_failed\">Litujeme, požadovanou aplikaci nelze spustit. Čárový kód je nefunkční.</string>\n  <string name=\"msg_redirect\">Přesměrování</string>\n  <string name=\"msg_sbc_book_not_searchable\">Omlouváme se, tato kniha nelze nalézt.</string>\n  <string name=\"msg_sbc_failed\">Omlouváme se, narazili jsme na problém.</string>\n  <string name=\"msg_sbc_no_page_returned\">Stránka nenalezena.</string>\n  <string name=\"msg_sbc_page\">Stránka</string>\n  <string name=\"msg_sbc_results\">Výsledky</string>\n  <string name=\"msg_sbc_searching_book\">Hledání knihy\\u2026</string>\n  <string name=\"msg_sbc_snippet_unavailable\">Snippet není k dispozici</string>\n  <string name=\"msg_sbc_unknown_page\">Neznámá stránka</string>\n  <string name=\"msg_share_explanation\">Můžete sdílet čárový kód na vaší obrazovce a skenování, s jiným telefonem.</string>\n  <string name=\"msg_share_subject_line\">Zde je obsah čárového kódu I naskenovaný</string>\n  <string name=\"msg_share_text\">Nebo zadejte nějaký text</string>\n  <string name=\"msg_sure\">Jste si jisti?</string>\n  <string name=\"msg_unmount_usb\">Omlouváme se, karta SD není přístupná.</string>\n  <string name=\"preferences_actions_title\">Byl nalezen čárový kód.\\u2026</string>\n  <string name=\"preferences_auto_focus_title\">Automatické zaostření</string>\n  <string name=\"preferences_bulk_mode_summary\">Skenování více čárových kódú bez přerušení, vhodné na dávkové zpracování velkého množství čárových kódú</string>\n  <string name=\"preferences_bulk_mode_title\">Dávkový režim skenování</string>\n  <string name=\"preferences_copy_to_clipboard_title\">Kopírovat do schránky.</string>\n  <string name=\"preferences_custom_product_search_summary\" formatted=\"false\">Použijte: %s = obsah, %f = formát, %t = typ</string>\n  <string name=\"preferences_custom_product_search_title\">Vlastní vyhledávání URL</string>\n  <string name=\"preferences_decode_1D_title\">1D kódy</string>\n  <string name=\"preferences_decode_Data_Matrix_title\">Data Matrix</string>\n  <string name=\"preferences_decode_QR_title\">QR kódy</string>\n  <string name=\"preferences_device_bug_workarounds_title\">Možná zástupná řešení chyb zařízení</string>\n  <string name=\"preferences_disable_continuous_focus_summary\">Používejte pouze standardní zaostřování</string>\n  <string name=\"preferences_disable_continuous_focus_title\">Soustavné zaměření</string>\n  <string name=\"preferences_disable_exposure_title\">No expozice</string>\n  <string name=\"preferences_front_light_summary\">Zlepšuje skenování při slabém osvětlení na některých telefonech, ale může způsobit oslnění. Nefunguje na všech telefonech.</string>\n  <string name=\"preferences_front_light_title\">Použít světlo</string>\n  <string name=\"preferences_general_title\">Hlavní nastavení</string>\n  <string name=\"preferences_name\">Nastavení</string>\n  <string name=\"preferences_play_beep_title\">Zvuky</string>\n  <string name=\"preferences_remember_duplicates_summary\">Duplikáty čárových kódú v historii ukládat samostatně, nebo jako jeden čárový kód</string>\n  <string name=\"preferences_remember_duplicates_title\">Pamatovat všechny duplikáty</string>\n  <string name=\"preferences_result_title\">Výsledek nastavení</string>\n  <string name=\"preferences_scanning_title\">Při skenování čárových kódů pro, dekódovat\\u2026</string>\n  <string name=\"preferences_search_country\">Hledání země</string>\n  <string name=\"preferences_supplemental_summary\">Získat více informací o obsahu čárového kódu</string>\n  <string name=\"preferences_supplemental_title\">Získat více informací</string>\n  <string name=\"preferences_try_bsplus\">Zkuste Barcode Scanner+</string>\n  <string name=\"preferences_try_bsplus_summary\">Obohacen o nové funkce a rozhraní</string>\n  <string name=\"preferences_vibrate_title\">Vibrace</string>\n  <string name=\"result_address_book\">Našel jsem kontakt</string>\n  <string name=\"result_calendar\">Našel jsem kalendář</string>\n  <string name=\"result_email_address\">Našel jsem Email</string>\n  <string name=\"result_geo\">Našel jsem Zeměpisné informace</string>\n  <string name=\"result_isbn\">Našel jsem knihu</string>\n  <string name=\"result_product\">Našel jsem produkt</string>\n  <string name=\"result_sms\">Našel jsem SMS</string>\n  <string name=\"result_tel\">Našel jsem telefoní číslo</string>\n  <string name=\"result_text\">Našel jsem nějaký text</string>\n  <string name=\"result_uri\">Našel jsem URL</string>\n  <string name=\"result_wifi\">Nalezeno bezdrátová konfigurace</string>\n  <string name=\"sbc_name\">Google Knihy hledání</string>\n  <string name=\"share_name\">Sdílet pomocí čárového kódu</string>\n  <string name=\"wifi_changing_network\">Požadující připojení k síti\\u2026</string>\n  <string name=\"wifi_ssid_label\">Jméno sítě</string>\n  <string name=\"wifi_type_label\">Typ</string>\n</resources>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/values-da/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2012 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<resources>\n  <!-- <string name=\"app_name\">Barcode Scanner</string> -->\n  <string name=\"app_picker_name\">Applikationer</string>\n  <string name=\"bookmark_picker_name\">Bogmærker</string>\n  <string name=\"button_add_calendar\">Tilføj til kalendar</string>\n  <string name=\"button_add_contact\">Tilføj kontaktperson</string>\n  <string name=\"button_back\">Tilbage</string>\n  <string name=\"button_book_search\">Bogsøgning</string>\n  <string name=\"button_cancel\">Annullér</string>\n  <string name=\"button_custom_product_search\">Brugerdefineret søgning</string>\n  <string name=\"button_dial\">Ring til nummeret</string>\n  <string name=\"button_done\">Færdig</string>\n  <string name=\"button_email\">Send e-mail</string>\n  <string name=\"button_get_directions\">Få kørselsanvisninger</string>\n  <string name=\"button_google_shopper\">Shopper</string>\n  <string name=\"button_mms\">Send MMS</string>\n  <string name=\"button_ok\">OK</string>\n  <string name=\"button_open_browser\">Åben browser</string>\n  <string name=\"button_product_search\">Produktsøgning</string>\n  <string name=\"button_search_book_contents\">Søg efter indhold</string>\n  <string name=\"button_share_app\">Applikationer</string>\n  <string name=\"button_share_bookmark\">Bogmærker</string>\n  <string name=\"button_share_by_email\">Del via e-mail</string>\n  <string name=\"button_share_by_sms\">Del via SMS</string>\n  <string name=\"button_share_clipboard\">Udklipsholder</string>\n  <string name=\"button_share_contact\">Kontakter</string>\n  <string name=\"button_show_map\">Vis kort</string>\n  <string name=\"button_sms\">Send SMS</string>\n  <string name=\"button_web_search\">Internetsøgning</string>\n  <string name=\"button_wifi\">Forbind til netværk</string>\n  <string name=\"contents_contact\">Kontaktinfo</string>\n  <string name=\"contents_email\">E-mailadresse</string>\n  <string name=\"contents_location\">Geografiske koordinater</string>\n  <string name=\"contents_phone\">Telefonnummer</string>\n  <string name=\"contents_sms\">SMS-adresse</string>\n  <string name=\"contents_text\">Almindelig tekst</string>\n  <string name=\"history_clear_one_history_text\">Ryd</string>\n  <string name=\"history_clear_text\">Ryd historik</string>\n  <string name=\"history_email_title\">Barcode Scanner-historik</string>\n  <string name=\"history_empty\">Tom</string>\n  <string name=\"history_empty_detail\">Ingen stregkodescanninger er blevet registreret endnu</string>\n  <string name=\"history_send\">Send historik</string>\n  <string name=\"history_title\">Historik</string>\n  <string name=\"menu_encode_mecard\">Brug MECARD</string>\n  <string name=\"menu_encode_vcard\">Brug vCard</string>\n  <string name=\"menu_help\">Hjælp</string>\n  <string name=\"menu_history\">Historik</string>\n  <string name=\"menu_settings\">Indstillinger</string>\n  <string name=\"menu_share\">Del</string>\n  <string name=\"msg_bulk_mode_scanned\">Massetilstand: stregkode scannet og gemt</string>\n  <string name=\"msg_camera_framework_bug\">Beklager, Android-kameraet er stødt på et problem. Du skal muligvis genstarte enheden.</string>\n  <string name=\"msg_default_format\">Format</string>\n  <string name=\"msg_default_meta\">Metadata</string>\n  <string name=\"msg_default_mms_subject\">Hej</string>\n  <string name=\"msg_default_status\">Placér en stregkode inden i firkanten for at aflæse den.</string>\n  <string name=\"msg_default_time\">Tid</string>\n  <string name=\"msg_default_type\">Type</string>\n  <string name=\"msg_encode_contents_failed\">Kunne ikke indkode en stregkode fra oplysningerne givet.</string>\n  <string name=\"msg_google_books\">Google Bøger</string>\n  <string name=\"msg_google_product\">Google Product Search</string>\n  <string name=\"msg_google_shopper_missing\">Google Shopper er ikke installeret</string>\n  <string name=\"msg_install_google_shopper\">Google Shopper kombinerer stregkodescanning med priser, anmeldelser og meget mere uden at åbne en browser. Kunne du tænke dig at prøve det?</string>\n  <string name=\"msg_intent_failed\">Beklager, den ønskede applikation kunne ikke blive startet. Stregkodeindholdet er måsket ugyldigt.</string>\n  <string name=\"msg_redirect\">Omdirigér</string>\n  <string name=\"msg_sbc_book_not_searchable\">Beklager, denne bog er ikke søgbar.</string>\n  <string name=\"msg_sbc_failed\">Beklager, søgningen er stødt på et problem.</string>\n  <string name=\"msg_sbc_no_page_returned\">Ingen side returnerede</string>\n  <string name=\"msg_sbc_page\">Side</string>\n  <string name=\"msg_sbc_results\">Resultater</string>\n  <string name=\"msg_sbc_searching_book\">Søger bog\\u2026</string>\n  <string name=\"msg_sbc_snippet_unavailable\">Uddragsvisning ikke tilgængelig</string>\n  <string name=\"msg_sbc_unknown_page\">Ukendt side</string>\n  <string name=\"msg_share_explanation\">Du kan dele data ved at vise en stregkode på denne skærm, og derefter scanne den med en anden telefon.</string>\n  <string name=\"msg_share_subject_line\">Her er indholdet af en stregkode, jeg har scannet.</string>\n  <string name=\"msg_share_text\">Eller skriv noget tekst</string>\n  <string name=\"msg_sure\">Er du sikker?</string>\n  <string name=\"msg_unmount_usb\">Beklager, SD-kortet er ikke tilgængelig.</string>\n  <string name=\"preferences_actions_title\">Når en stregkode er fundet\\u2026</string>\n  <string name=\"preferences_auto_focus_title\">Brug autofokus</string>\n  <string name=\"preferences_bulk_mode_summary\">Scan og gem mange stregkoder uden afbrydelser</string>\n  <string name=\"preferences_bulk_mode_title\">Massescanningstilstand</string>\n  <string name=\"preferences_copy_to_clipboard_title\">Kopiér til udklipsholder</string>\n  <string name=\"preferences_custom_product_search_summary\" formatted=\"false\">Udskiftninger: %s = indhold, %f = format, %t = type</string>\n  <string name=\"preferences_custom_product_search_title\">Brugerdefineret søge-URL</string>\n  <string name=\"preferences_decode_1D_title\">Afkod 1D-stregkoder</string>\n  <string name=\"preferences_decode_Data_Matrix_title\">Afkod Data Matrix</string>\n  <string name=\"preferences_decode_QR_title\">Afkod QR-koder</string>\n  <string name=\"preferences_device_bug_workarounds_title\">Device Bug Løsninger</string>\n  <string name=\"preferences_disable_continuous_focus_summary\">Brug kun standard fokusindstilling</string>\n  <string name=\"preferences_disable_continuous_focus_title\">Ingen løbende fokus</string>\n  <string name=\"preferences_disable_exposure_title\">Ingen eksponering</string>\n  <string name=\"preferences_front_light_summary\">Forbedrer aflæsning i svagt lys på nogle telefoner, men kan medføre genskær. Virker ikke på alle telefoner.</string>\n  <string name=\"preferences_front_light_title\">Brug frontlys</string>\n  <string name=\"preferences_general_title\">Generelle indstillinger</string>\n  <string name=\"preferences_name\">Indstillinger</string>\n  <string name=\"preferences_play_beep_title\">Bip</string>\n  <string name=\"preferences_remember_duplicates_summary\">Gem flere scanninger af de samme stregkoder i Historik</string>\n  <string name=\"preferences_remember_duplicates_title\">Husk dubletter</string>\n  <string name=\"preferences_result_title\">Resultatindstillinger</string>\n  <string name=\"preferences_scanning_title\">Når der scannes efter stregkoder\\u2026</string>\n  <string name=\"preferences_search_country\">Søg efter land</string>\n  <string name=\"preferences_supplemental_summary\">Prøv at få flere oplysninger om stregkodens indhold</string>\n  <string name=\"preferences_supplemental_title\">Hent mere info</string>\n  <string name=\"preferences_try_bsplus\">Prøv Barcode Scanner+</string>\n  <string name=\"preferences_try_bsplus_summary\">Forbedret med nye funktioner og grænseflade</string>\n  <string name=\"preferences_vibrate_title\">Vibrér</string>\n  <string name=\"result_address_book\">Kontaktinfo fundet</string>\n  <string name=\"result_calendar\">Kalendarbegivenhed fundet</string>\n  <string name=\"result_email_address\">E-mailadresse fundet</string>\n  <string name=\"result_geo\">Geografiske koordinater fundet</string>\n  <string name=\"result_isbn\">Bog fundet</string>\n  <string name=\"result_product\">Produkt fundet</string>\n  <string name=\"result_sms\">SMS-adresse fundet</string>\n  <string name=\"result_tel\">Telefonnummer fundet</string>\n  <string name=\"result_text\">Almindelig tekst fundet</string>\n  <string name=\"result_uri\">URL fundet</string>\n  <string name=\"result_wifi\">WLAN-forbindelse fundet</string>\n  <string name=\"sbc_name\">Google Bøger-søgning</string>\n  <string name=\"share_name\">Del via stregkode</string>\n  <string name=\"wifi_changing_network\">Anmoder om tilslutning til netværk\\u2026</string>\n  <string name=\"wifi_ssid_label\">Netværksnavn</string>\n  <string name=\"wifi_type_label\">Type</string>\n</resources>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/values-de/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2012 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<resources>\n  <!-- <string name=\"app_name\">Barcode Scanner</string> -->\n  <string name=\"app_picker_name\">Anwendungen</string>\n  <string name=\"bookmark_picker_name\">Lesezeichen</string>\n  <string name=\"button_add_calendar\">Termin hinzufügen</string>\n  <string name=\"button_add_contact\">Kontakt hinzufügen</string>\n  <string name=\"button_back\">Zurück</string>\n  <string name=\"button_book_search\">Büchersuche</string>\n  <string name=\"button_cancel\">Abbruch</string>\n  <string name=\"button_custom_product_search\">Benutzersuche</string>\n  <string name=\"button_dial\">Nummer wählen</string>\n  <string name=\"button_done\">Fertig</string>\n  <string name=\"button_email\">E-Mail senden</string>\n  <string name=\"button_get_directions\">Route berechnen</string>\n  <string name=\"button_google_shopper\">Shopper</string>\n  <string name=\"button_mms\">MMS senden</string>\n  <string name=\"button_ok\">OK</string>\n  <string name=\"button_open_browser\">Browser öffnen</string>\n  <string name=\"button_product_search\">Produktsuche</string>\n  <string name=\"button_search_book_contents\">Buchinhalt durchsuchen</string>\n  <string name=\"button_share_app\">Anwendung</string>\n  <string name=\"button_share_bookmark\">Lesezeichen</string>\n  <string name=\"button_share_by_email\">Als E-Mail weitergeben</string>\n  <string name=\"button_share_by_sms\">Als SMS weitergeben</string>\n  <string name=\"button_share_clipboard\">Zwischenablage</string>\n  <string name=\"button_share_contact\">Kontakt</string>\n  <string name=\"button_show_map\">Karte anzeigen</string>\n  <string name=\"button_sms\">SMS senden</string>\n  <string name=\"button_web_search\">Im Web suchen</string>\n  <string name=\"button_wifi\">Mit diesem WLAN verbinden</string>\n  <string name=\"contents_contact\">Kontaktinfo</string>\n  <string name=\"contents_email\">E-Mail Adresse</string>\n  <string name=\"contents_location\">Koordinaten</string>\n  <string name=\"contents_phone\">Telefonnummer</string>\n  <string name=\"contents_sms\">SMS Adresse</string>\n  <string name=\"contents_text\">Text</string>\n  <string name=\"history_clear_one_history_text\">Löschen</string>\n  <string name=\"history_clear_text\">Verlauf löschen</string>\n  <string name=\"history_email_title\">Barcode Scanner Verlauf</string>\n  <string name=\"history_empty\">Leer</string>\n  <string name=\"history_empty_detail\">Es wurden keine Barcodes aufgezeichnet.</string>\n  <string name=\"history_send\">Verlauf senden</string>\n  <string name=\"history_title\">Verlauf</string>\n  <string name=\"menu_encode_mecard\">MECARD verwenden</string>\n  <string name=\"menu_encode_vcard\">vCard verwenden</string>\n  <string name=\"menu_help\">Hilfe</string>\n  <string name=\"menu_history\">Verlauf</string>\n  <string name=\"menu_settings\">Einstellungen</string>\n  <string name=\"menu_share\">Senden</string>\n  <string name=\"msg_bulk_mode_scanned\">Bulk-Modus: Barcode gescannt und gespeichert</string>\n  <string name=\"msg_camera_framework_bug\">Mit der Android-Kamera ist leider ein Fehler aufgetreten. Es könnte sein, dass Sie das Gerät neu starten müssen.</string>\n  <string name=\"msg_default_format\">Format</string>\n  <string name=\"msg_default_meta\">Metadaten</string>\n  <string name=\"msg_default_mms_subject\">Hi</string>\n  <string name=\"msg_default_status\">Positionieren Sie den Barcode innerhalb des Rechteckes.</string>\n  <string name=\"msg_default_time\">Zeit</string>\n  <string name=\"msg_default_type\">Typ</string>\n  <string name=\"msg_encode_contents_failed\">Aus den Daten kann kein Barcode erzeugt werden.</string>\n  <string name=\"msg_google_books\">Google Bücher</string>\n  <string name=\"msg_google_product\">Google Shopper</string>\n  <string name=\"msg_google_shopper_missing\">Google Shopper ist nicht installiert</string>\n  <string name=\"msg_install_google_shopper\">Google Shopper verbindet ohne Öffnen des Browsers Barcodes mit Preisen, Testberichten und mehr. Möchten Sie es ausprobieren?</string>\n  <string name=\"msg_intent_failed\">Die gewünschte Applikation kann nicht geöffnet werden. Der Barcode könnte ungültig sein.</string>\n  <string name=\"msg_redirect\">Umleiten</string>\n  <string name=\"msg_sbc_book_not_searchable\">Dieses Buch kann nicht durchsucht werden.</string>\n  <string name=\"msg_sbc_failed\">Bei der Suche ist ein Fehler aufgetreten.</string>\n  <string name=\"msg_sbc_no_page_returned\">Keine Seite zurückgeliefert.</string>\n  <string name=\"msg_sbc_page\">Seite</string>\n  <string name=\"msg_sbc_results\">Ergebnisse</string>\n  <string name=\"msg_sbc_searching_book\">Durchsuche Buch\\u2026</string>\n  <string name=\"msg_sbc_snippet_unavailable\">Textschnipsel nicht verfügbar.</string>\n  <string name=\"msg_sbc_unknown_page\">Unbekannte Seite</string>\n  <string name=\"msg_share_explanation\">Sie können Daten weitergeben, indem Sie einen Barcode auf Ihrem Bilschirm erzeugen und mit einem anderen Handy einscannen.</string>\n  <string name=\"msg_share_subject_line\">Hier ist der gescannte Barcode-Inhalt</string>\n  <string name=\"msg_share_text\">Oder geben Sie einen Text hier</string>\n  <string name=\"msg_sure\">Sind Sie sicher?</string>\n  <string name=\"msg_unmount_usb\">Leider kann nicht auf die SD-Karte zugegriffen werden.</string>\n  <string name=\"preferences_actions_title\">Wenn ein Barcode erkannt wurde\\u2026</string>\n  <string name=\"preferences_auto_focus_title\">Autofokus verwenden</string>\n  <string name=\"preferences_bulk_mode_summary\">Scannt und speichert mehrere Barcodes nacheinander</string>\n  <string name=\"preferences_bulk_mode_title\">Massenscan</string>\n  <string name=\"preferences_copy_to_clipboard_title\">In die Zwischenablage kopieren</string>\n  <string name=\"preferences_custom_product_search_summary\" formatted=\"false\">Platzhalter: %s = Inhalt, %f = Format, %t = Typ</string>\n  <string name=\"preferences_custom_product_search_title\">Eigene Such-URL</string>\n  <string name=\"preferences_decode_1D_title\">1D Barcodes</string>\n  <string name=\"preferences_decode_Data_Matrix_title\">Data Matrix</string>\n  <string name=\"preferences_decode_QR_title\">QR Codes</string>\n  <string name=\"preferences_device_bug_workarounds_title\">Geräteabhängige Problemumgehung</string>\n  <string name=\"preferences_disable_continuous_focus_summary\">Nur Standard-Fokus-Modus verwenden</string>\n  <string name=\"preferences_disable_continuous_focus_title\">Kein kontinuierlicher Fokus</string>\n  <string name=\"preferences_disable_exposure_title\">Keine Belichtungsmessung </string>\n  <string name=\"preferences_front_light_summary\">Verbessert bei einigen Mobiltelefonen das Scannen bei schwachem Licht, kann aber Überbelichtung verursachen. Funktioniert nicht mit allen Handys.</string>\n  <string name=\"preferences_front_light_title\">Foto LED einschalten</string>\n  <string name=\"preferences_general_title\">Allgemeine Einstellungen</string>\n  <string name=\"preferences_name\">Einstellungen</string>\n  <string name=\"preferences_play_beep_title\">Piepsen</string>\n  <string name=\"preferences_remember_duplicates_summary\">Speichern mehrerer Scans des gleichen Barcodes im Verlauf</string>\n  <string name=\"preferences_remember_duplicates_title\">Duplikate speichern</string>\n  <string name=\"preferences_result_title\">Ergebnis-Einstellungen</string>\n  <string name=\"preferences_scanning_title\">Beim Scannen von Barcodes, dekodieren\\u2026</string>\n  <string name=\"preferences_search_country\">Land für die Suche</string>\n  <string name=\"preferences_supplemental_summary\">Erfahren Sie mehr über Barcode</string>\n  <string name=\"preferences_supplemental_title\">Weitere Informationen abrufen</string>\n  <string name=\"preferences_try_bsplus\">Barcode Scanner+ testen</string>\n  <string name=\"preferences_try_bsplus_summary\">Mit mehr Funktionen und neuer Oberfläche.</string>\n  <string name=\"preferences_vibrate_title\">Vibrieren</string>\n  <string name=\"result_address_book\">Kontakt gefunden</string>\n  <string name=\"result_calendar\">Termin gefunden</string>\n  <string name=\"result_email_address\">E-Mail-Adresse gefunden</string>\n  <string name=\"result_geo\">Koordinaten gefunden</string>\n  <string name=\"result_isbn\">Buch gefunden</string>\n  <string name=\"result_product\">Produkt gefunden</string>\n  <string name=\"result_sms\">SMS-Adresse gefunden</string>\n  <string name=\"result_tel\">Telefonnummer gefunden</string>\n  <string name=\"result_text\">Text gefunden</string>\n  <string name=\"result_uri\">URL gefunden</string>\n  <string name=\"result_wifi\">WLAN-Konfiguration gefunden</string>\n  <string name=\"sbc_name\">Google Book Search</string>\n  <string name=\"share_name\">Weitergabe mittels Barcode</string>\n  <string name=\"wifi_changing_network\">Verbindung zum Netzwerk anfordern\\u2026</string>\n  <string name=\"wifi_ssid_label\">WLAN-Name:</string>\n  <string name=\"wifi_type_label\">Verschlüsselung:</string>\n</resources>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/values-el/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2012 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<resources>\n  <!-- <string name=\"app_name\">Barcode Scanner</string> -->\n  <string name=\"app_picker_name\">Εφαρμογές</string>\n  <string name=\"bookmark_picker_name\">Σελιδοδείκτες</string>\n  <string name=\"button_add_calendar\">Προσθήκη στο ημερολόγιο</string>\n  <string name=\"button_add_contact\">Προσθήκη στις επαφές</string>\n  <string name=\"button_back\">Πίσω</string>\n  <string name=\"button_book_search\">Αναζήτηση βιβλίων</string>\n  <string name=\"button_cancel\">Ακύρωση</string>\n  <string name=\"button_custom_product_search\">Σύνθετη αναζήτηση</string>\n  <string name=\"button_dial\">Κλήση αριθμού</string>\n  <string name=\"button_done\">Έγινε</string>\n  <string name=\"button_email\">Αποστολή email</string>\n  <string name=\"button_get_directions\">Λάβετε κατευθύνσεις</string>\n  <string name=\"button_google_shopper\">Shopper</string>\n  <string name=\"button_mms\">Αποστολή MMS</string>\n  <string name=\"button_ok\">OK</string>\n  <string name=\"button_open_browser\">Άνοιγμα browser</string>\n  <string name=\"button_product_search\">Αναζήτηση προϊόντων</string>\n  <string name=\"button_search_book_contents\">Αναζήτηση περιεχομένων</string>\n  <string name=\"button_share_app\">Εφαρμογή</string>\n  <string name=\"button_share_bookmark\">Σελιδοδείκτης</string>\n  <string name=\"button_share_by_email\">Μοιράσου με email</string>\n  <string name=\"button_share_by_sms\">Μοιράσου με SMS</string>\n  <string name=\"button_share_clipboard\">Πρόχειρο</string>\n  <string name=\"button_share_contact\">Επαφή</string>\n  <string name=\"button_show_map\">Δείξε χάρτη</string>\n  <string name=\"button_sms\">Στείλε SMS</string>\n  <string name=\"button_web_search\">Αναζήτηση ιστού</string>\n  <string name=\"button_wifi\">Σύνδεση σε Δίκτυο</string>\n  <string name=\"contents_contact\">Πληροφορίες επαφής</string>\n  <string name=\"contents_email\">Διεύθυνση email</string>\n  <string name=\"contents_location\">Γεωγραφικές συντεταγμένες</string>\n  <string name=\"contents_phone\">Τηλέφωνο</string>\n  <string name=\"contents_sms\">Διεύθνση SMS</string>\n  <string name=\"contents_text\">Απλό κείμενο</string>\n  <string name=\"history_clear_one_history_text\">Διαγραφή</string>\n  <string name=\"history_clear_text\">Διαγραφή ιστορικού</string>\n  <string name=\"history_email_title\">Ιστορικό Barcode Scanner</string>\n  <string name=\"history_empty\">Κενό</string>\n  <string name=\"history_empty_detail\">Δεν έχουν καταγραφεί σαρώσεις barcode</string>\n  <string name=\"history_send\">Αποστολή ιστορικού</string>\n  <string name=\"history_title\">Ιστορικό</string>\n  <string name=\"menu_encode_mecard\">Χρησιμοποιήστε MECARD</string>\n  <string name=\"menu_encode_vcard\">Χρησιμοποιήστε vCard</string>\n  <string name=\"menu_help\">Βοήθεια</string>\n  <string name=\"menu_history\">Ιστορικό</string>\n  <string name=\"menu_settings\">Ρυθμίσεις</string>\n  <string name=\"menu_share\">Κοινή χρήση</string>\n  <string name=\"msg_bulk_mode_scanned\">Μαζική λειτουργία: barcode σκαναρίστηκε και αποθηκεύτηκε</string>\n  <string name=\"msg_camera_framework_bug\">Συγνώμη, προέκυψε ένα πρόβλημα με την κάμερα. Ίσως χρειαστεί να επανεκιννήσετε τη συσκευή.</string>\n  <string name=\"msg_default_format\">Διαμόρφωση</string>\n  <string name=\"msg_default_meta\">Metadata</string>\n  <string name=\"msg_default_mms_subject\">Γεια</string>\n  <string name=\"msg_default_status\">Τοποθετήστε ένα barcode μέσα στο πλαίσιο για να το σκανάρετε.</string>\n  <string name=\"msg_default_time\">Ωρα</string>\n  <string name=\"msg_default_type\">Τύπος</string>\n  <string name=\"msg_encode_contents_failed\">Δεν γίνεται να παραχθεί barcode από αυτά τα δεδομένα.</string>\n  <string name=\"msg_google_books\">Google Books</string>\n  <string name=\"msg_google_product\">Αναζήτηση προϊόντων Google</string>\n  <string name=\"msg_google_shopper_missing\">Το Google Shopper δεν είναι εγκατεστημένο.</string>\n  <string name=\"msg_install_google_shopper\">Το Google Shopper συνδυάζει σκανάρισμα barcode με online και τοπικές τιμές, αξιολογήσεις και άλλα χωρίς να ανοίξετε τον browser. Θέλετε να το δοκιμάσετε;</string>\n  <string name=\"msg_intent_failed\">Συγνώμη, η ζητούμενη εφαρμογή δεν μπορεί να εκιννηθεί. Τα δεδομληνα του barcode ίσως δεν είναι έγκυρα.</string>\n  <string name=\"msg_redirect\">Ανακατεύθυνση</string>\n  <string name=\"msg_sbc_book_not_searchable\">Συγνώμη, αυτό το βιβλίο δεν βρέθηκε.</string>\n  <string name=\"msg_sbc_failed\">Συγνώμη, η αναζήτηση παρουσίασε πρόβλημα.</string>\n  <string name=\"msg_sbc_no_page_returned\">Δεν βρέθηκε σελίδα</string>\n  <string name=\"msg_sbc_page\">Σελίδα</string>\n  <string name=\"msg_sbc_results\">Αποτελέσματα</string>\n  <string name=\"msg_sbc_searching_book\">Άναζήτηση βιβλίου\\u2026</string>\n  <string name=\"msg_sbc_snippet_unavailable\">Απόσπασμα μη διαθέσιμο</string>\n  <string name=\"msg_sbc_unknown_page\">Άγνωστη σελίδα</string>\n  <string name=\"msg_share_explanation\">Μπορείς να μοιραστείς δεδομένα εμφανίζοντας ένα barcode στην οθόνη σου και σκανάροντάς το με ένα άλλο κινητό.</string>\n  <string name=\"msg_share_subject_line\">Αυτά είναι τα περιεχόμενα ενός barcode που σκάναρα</string>\n  <string name=\"msg_share_text\">Ή πληκτολογήστε εδώ κείμενο και πατήστε Enter</string>\n  <string name=\"msg_sure\">Είσαι σίγουρος;</string>\n  <string name=\"msg_unmount_usb\">Συγνώμη, η κάρτα SD δεν είναι προσβάσιμη.</string>\n  <string name=\"preferences_actions_title\">Όταν ένα barcode ανιχνεύεται\\u2026</string>\n  <string name=\"preferences_auto_focus_title\">Χρησιμοποιήστε την αυτόματη εστίαση</string>\n  <string name=\"preferences_bulk_mode_summary\">Σκανάρετε και αποθηκεύστε συνεχόμενα πολλά barcodes</string>\n  <string name=\"preferences_bulk_mode_title\">Λειτουργία μαζικού σκαναρίσματος</string>\n  <string name=\"preferences_copy_to_clipboard_title\">Αντιγραφή στο πρόχειρο</string>\n  <string name=\"preferences_custom_product_search_summary\" formatted=\"false\">Αντικαταστάσεις: %s = περιεχόμενο, %f = μορφή, %t = τύπος</string>\n  <string name=\"preferences_custom_product_search_title\">Σύνθετη αναζήτηση</string>\n  <string name=\"preferences_decode_1D_title\">1D barcodes</string>\n  <string name=\"preferences_decode_Data_Matrix_title\">Data Matrix</string>\n  <string name=\"preferences_decode_QR_title\">QR Codes</string>\n  <string name=\"preferences_device_bug_workarounds_title\">Λύσεις Bug συσκευής</string>\n  <string name=\"preferences_disable_continuous_focus_summary\">Χρησιμοποιείτε μόνο τυπική λειτουργία εστίασης</string>\n  <string name=\"preferences_disable_continuous_focus_title\">Δεν συνεχής εστίαση</string>\n  <string name=\"preferences_disable_exposure_title\">Δεν έκθεση</string>\n  <string name=\"preferences_front_light_summary\">Βελτιώνει το σκανάρισμα με χαμηλο φωτισμό σε μερικά κινητά, ίσως όμως προκαλέσει λάμψη. Δουλεύει σε μερικά κινητά.</string>\n  <string name=\"preferences_front_light_title\">Χρήση μπροστινού φακού</string>\n  <string name=\"preferences_general_title\">Γενικές ρυθμίσεις</string>\n  <string name=\"preferences_name\">Ρυθμίσεις</string>\n  <string name=\"preferences_play_beep_title\">Μπιπ</string>\n  <string name=\"preferences_remember_duplicates_summary\">Αποθήκευση πολλαπλών σκαναρισμάτων του ίδιου barcode στο ιστορικό</string>\n  <string name=\"preferences_remember_duplicates_title\">Απομνημόνευση διπλότυπων</string>\n  <string name=\"preferences_result_title\">Ρυθμίσεις αποτελεσμάτων</string>\n  <string name=\"preferences_scanning_title\">Όταν σκανάρεις barcodes, ψάχνε για\\u2026</string>\n  <string name=\"preferences_search_country\">Χώρα Αναζήτησης</string>\n  <string name=\"preferences_supplemental_summary\">Προσπάθησε να βρείς περισσότερες πληροφορίες για τα περιεχόμενα του barcode</string>\n  <string name=\"preferences_supplemental_title\">Αναζήτηση για επιπλέον πληροφορίες</string>\n  <string name=\"preferences_try_bsplus\">Δοκιμάστε Barcode Scanner+</string>\n  <string name=\"preferences_try_bsplus_summary\">Ενισχυμένη με νέα χαρακτηριστικά και διασύνδεση</string>\n  <string name=\"preferences_vibrate_title\">Δόνηση</string>\n  <string name=\"result_address_book\">Βρέθηκαν πληροφορίες επαφής</string>\n  <string name=\"result_calendar\">Βρέθηκε συμβάν ημερολογίου</string>\n  <string name=\"result_email_address\">Βρέθηκε email</string>\n  <string name=\"result_geo\">Βρέθηκαν γεωγραφικές συντεταγμένες</string>\n  <string name=\"result_isbn\">Βρέθηκε βιβλίο</string>\n  <string name=\"result_product\">Βρέθηκε προϊόν</string>\n  <string name=\"result_sms\">Βρέθηκε διεύθυνση SMS</string>\n  <string name=\"result_tel\">Βρέθηκε τηλέφωνο</string>\n  <string name=\"result_text\">Βρέθηκε κείμενο</string>\n  <string name=\"result_uri\">Βρέθηκε ηλ. διεύθυνση</string>\n  <string name=\"result_wifi\">Βρέθηκαν ρυθμίσεις Wi-Fi</string>\n  <string name=\"sbc_name\">Αναζήτηση βιβλίων Google</string>\n  <string name=\"share_name\">Κοινή χρήση μέσω barcode</string>\n  <string name=\"wifi_changing_network\">Αίτηση σύνδεσης με το δίκτυο\\u2026</string>\n  <string name=\"wifi_ssid_label\">Όνομα Δικτύου</string>\n  <string name=\"wifi_type_label\">Τύπος</string>\n</resources>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/values-es/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2012 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<resources>\n  <!-- <string name=\"app_name\">Barcode Scanner</string> -->\n  <string name=\"app_picker_name\">Aplicaciones</string>\n  <string name=\"bookmark_picker_name\">Marcadores</string>\n  <string name=\"button_add_calendar\">Añadir al calendario</string>\n  <string name=\"button_add_contact\">Añadir contacto</string>\n  <string name=\"button_back\">Regresar</string>\n  <string name=\"button_book_search\">Búsqueda de libros</string>\n  <string name=\"button_cancel\">Cancelar</string>\n  <string name=\"button_custom_product_search\">Búsqueda personalizada</string>\n  <string name=\"button_dial\">Marcar número</string>\n  <string name=\"button_done\">Terminar</string>\n  <string name=\"button_email\">Enviar correo electrónico</string>\n  <string name=\"button_get_directions\">Obtener direcciones</string>\n  <string name=\"button_google_shopper\">Shopper</string>\n  <string name=\"button_mms\">Enviar MMS</string>\n  <string name=\"button_ok\">OK</string>\n  <string name=\"button_open_browser\">Abrir navegador</string>\n  <string name=\"button_product_search\">Búsqueda de productos</string>\n  <string name=\"button_search_book_contents\">Buscar contenido del libro</string>\n  <string name=\"button_share_app\">Aplicación</string>\n  <string name=\"button_share_bookmark\">Marcador</string>\n  <string name=\"button_share_by_email\">Compartir por correo electrónico</string>\n  <string name=\"button_share_by_sms\">Compartir por SMS</string>\n  <string name=\"button_share_clipboard\">Portapapeles</string>\n  <string name=\"button_share_contact\">Contacto</string>\n  <string name=\"button_show_map\">Mostrar mapa</string>\n  <string name=\"button_sms\">Enviar SMS</string>\n  <string name=\"button_web_search\">Búsqueda Web</string>\n  <string name=\"button_wifi\">Conectarse a la red</string>\n  <string name=\"contents_contact\">Información de contacto</string>\n  <string name=\"contents_email\">Dirección de correo electrónico</string>\n  <string name=\"contents_location\">Coordenadas geográficas</string>\n  <string name=\"contents_phone\">Número de teléfono</string>\n  <string name=\"contents_sms\">Dirección SMS</string>\n  <string name=\"contents_text\">Texto</string>\n  <string name=\"history_clear_one_history_text\">Borrar</string>\n  <string name=\"history_clear_text\">Borrar historial</string>\n  <string name=\"history_email_title\">Historial de Escáner de código de barras</string>\n  <string name=\"history_empty\">Vacío</string>\n  <string name=\"history_empty_detail\">Ningún escanea de códigos de barras se han registrado aún</string>\n  <string name=\"history_send\">Enviar historial</string>\n  <string name=\"history_title\">Historial</string>\n  <string name=\"menu_encode_mecard\">Usar MECARD</string>\n  <string name=\"menu_encode_vcard\">Usar vCard</string>\n  <string name=\"menu_help\">Ayuda</string>\n  <string name=\"menu_history\">Historial</string>\n  <string name=\"menu_settings\">Configuración</string>\n  <string name=\"menu_share\">Compartir</string>\n  <string name=\"msg_bulk_mode_scanned\">Modo Masivo: código de barras escaneado y guardado</string>\n  <string name=\"msg_camera_framework_bug\">Lo sentimos, la cámara de Android ha encontrado un problema. Es posible que necesite reiniciar el dispositivo.</string>\n  <string name=\"msg_default_format\">Formato</string>\n  <string name=\"msg_default_meta\">Metadata</string>\n  <string name=\"msg_default_mms_subject\">Hola</string>\n  <string name=\"msg_default_status\">Coloque un código de barras en el interior del rectángulo del visor para escanear.</string>\n  <string name=\"msg_default_time\">Tiempo</string>\n  <string name=\"msg_default_type\">Tipo</string>\n  <string name=\"msg_encode_contents_failed\">No se pudo codificar un código de barras a partir de los datos facilitados.</string>\n  <string name=\"msg_google_books\">Google Libros</string>\n  <string name=\"msg_google_product\">Buscador de Google Product</string>\n  <string name=\"msg_google_shopper_missing\">Google Shopper no está instalado</string>\n  <string name=\"msg_install_google_shopper\">Google Shopper combina el escaneo de código de barras con los precios en linea y local, comentarios y más, sin tener que abrir el navegador. ¿Le gustaría probarlo?</string>\n  <string name=\"msg_intent_failed\">Lo sentimos, la aplicación solicitada no pudo ser lanzada. El contenido de código de barras puede ser inválida.</string>\n  <string name=\"msg_redirect\">Redirigir</string>\n  <string name=\"msg_sbc_book_not_searchable\">Lo sentimos, no se puede buscar en este libro.</string>\n  <string name=\"msg_sbc_failed\">Lo sentimos, la búsqueda ha detectado un problema.</string>\n  <string name=\"msg_sbc_no_page_returned\">Página no encontrada</string>\n  <string name=\"msg_sbc_page\">Página</string>\n  <string name=\"msg_sbc_results\">Resultados</string>\n  <string name=\"msg_sbc_searching_book\">Buscando libro\\u2026</string>\n  <string name=\"msg_sbc_snippet_unavailable\">Fragmentos no están disponibles</string>\n  <string name=\"msg_sbc_unknown_page\">Página desconocida</string>\n  <string name=\"msg_share_explanation\">Usted puede compartir los datos mostrando un código de barras en su pantalla y escanearlo con otro teléfono.</string>\n  <string name=\"msg_share_subject_line\">Estos son los contenidos del código de barras que he escaneado</string>\n  <string name=\"msg_share_text\">O escriba algún texto y presione Enter</string>\n  <string name=\"msg_sure\">¿Está seguro?</string>\n  <string name=\"msg_unmount_usb\">Lo sentimos, la tarjeta SD no está accesible.</string>\n  <string name=\"preferences_actions_title\">Cuando encuentra un código de barras\\u2026</string>\n  <string name=\"preferences_auto_focus_title\">Utilizar el enfoque automático</string>\n  <string name=\"preferences_bulk_mode_summary\">Escanear y guardar muchos códigos de barras de forma continua</string>\n  <string name=\"preferences_bulk_mode_title\">Modo masivo de escaneo</string>\n  <string name=\"preferences_copy_to_clipboard_title\">Copiar al portapapeles</string>\n  <string name=\"preferences_custom_product_search_summary\" formatted=\"false\">Sustituciones: %s = contenido, %f = formato, %t = tipo</string>\n  <string name=\"preferences_custom_product_search_title\">Búsqueda de productos con URL personalizada</string>\n  <string name=\"preferences_decode_1D_title\">Códigos de barras 1D</string>\n  <string name=\"preferences_decode_Data_Matrix_title\">Data Matrix</string>\n  <string name=\"preferences_decode_QR_title\">Códigos QR</string>\n  <string name=\"preferences_device_bug_workarounds_title\">Soluciones provisionales para dispositivos con errores</string>\n  <string name=\"preferences_disable_continuous_focus_summary\">Utilice sólo el modo de enfoque estándar</string>\n  <string name=\"preferences_disable_continuous_focus_title\">No enfoque continuo</string>\n  <string name=\"preferences_disable_exposure_title\">No exposición</string>\n  <string name=\"preferences_front_light_summary\">Mejora la exploración en condiciones de poca luz en algunos teléfonos, pero puede causar deslumbramiento. No funciona en todos los teléfonos.</string>\n  <string name=\"preferences_front_light_title\">Utilizar luz delantera</string>\n  <string name=\"preferences_general_title\">Configuración general</string>\n  <string name=\"preferences_name\">Configuración</string>\n  <string name=\"preferences_play_beep_title\">Bip</string>\n  <string name=\"preferences_remember_duplicates_summary\">Almacenar múltiples escáneres del mismo código de barras en el Historial.</string>\n  <string name=\"preferences_remember_duplicates_title\">Recuerde duplicados</string>\n  <string name=\"preferences_result_title\">Configuración de resultados</string>\n  <string name=\"preferences_scanning_title\">Al escanear códigos de barras, descodificar\\u2026</string>\n  <string name=\"preferences_search_country\">Buscar país</string>\n  <string name=\"preferences_supplemental_summary\">Trata de recuperar más información sobre el contenido del código de barras.</string>\n  <string name=\"preferences_supplemental_title\">Recuperar más información</string>\n  <string name=\"preferences_try_bsplus\">Trate Barcode Scanner+</string>\n  <string name=\"preferences_try_bsplus_summary\">Mejorado con nuevas características y la interfaz de</string>\n  <string name=\"preferences_vibrate_title\">Vibrar</string>\n  <string name=\"result_address_book\">Información de contacto encontrada</string>\n  <string name=\"result_calendar\">Evento de calendario encontrado</string>\n  <string name=\"result_email_address\">Dirección de correo electrónico encontrado</string>\n  <string name=\"result_geo\">Coordenadas geográficas encontradas</string>\n  <string name=\"result_isbn\">Libro encontrado</string>\n  <string name=\"result_product\">Producto encontrado</string>\n  <string name=\"result_sms\">Dirección de SMS encontrado</string>\n  <string name=\"result_tel\">Número de teléfono encontrado</string>\n  <string name=\"result_text\">Texto encontrado</string>\n  <string name=\"result_uri\">URL encontrada</string>\n  <string name=\"result_wifi\">Configuración de WLAN encontrada</string>\n  <string name=\"sbc_name\">Búsqueda de libros de Google</string>\n  <string name=\"share_name\">Compartir por códigos de barras</string>\n  <string name=\"wifi_changing_network\">Solicitando conexión a la red\\u2026</string>\n  <string name=\"wifi_ssid_label\">Nombre de red</string>\n  <string name=\"wifi_type_label\">Tipo</string>\n</resources>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/values-eu/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2012 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<resources>\n  <!-- <string name=\"app_name\">Barra-kode Eskanerra</string> -->\n  <string name=\"app_picker_name\">Aplikazioak</string>\n  <string name=\"bookmark_picker_name\">Laster-markak</string>\n  <string name=\"button_add_calendar\">Gehitu egutegian</string>\n  <string name=\"button_add_contact\">Gehitu kontaktua</string>\n  <string name=\"button_back\">Atzera</string>\n  <string name=\"button_book_search\">Bilatu liburua</string>\n  <string name=\"button_cancel\">Utzi</string>\n  <string name=\"button_custom_product_search\">Bilaketa pertsonalizatua</string>\n  <string name=\"button_dial\">Markatu zenbakia</string>\n  <string name=\"button_done\">Eginda</string>\n  <string name=\"button_email\">Bidali e-posta</string>\n  <string name=\"button_get_directions\">Lortu jarraibideak</string>\n  <string name=\"button_google_shopper\">Shopper</string>\n  <string name=\"button_mms\">Bidali MMS-a</string>\n  <string name=\"button_ok\">Ados</string>\n  <string name=\"button_open_browser\">Ireki arakatzailea</string>\n  <string name=\"button_product_search\">Produktu bilaketa</string>\n  <string name=\"button_search_book_contents\">Bilatu edukiak</string>\n  <string name=\"button_share_app\">Aplikazioa</string>\n  <string name=\"button_share_bookmark\">Laster-marka</string>\n  <string name=\"button_share_by_email\">Partekatu e-posta bidez</string>\n  <string name=\"button_share_by_sms\">Partekatu SMS bidez</string>\n  <string name=\"button_share_clipboard\">Arbela</string>\n  <string name=\"button_share_contact\">Kontaktua</string>\n  <string name=\"button_show_map\">Erakutsi mapa</string>\n  <string name=\"button_sms\">Bidali SMS-a</string>\n  <string name=\"button_web_search\">Web bilaketa</string>\n  <string name=\"button_wifi\">Konektatu sarera</string>\n  <string name=\"contents_contact\">Kontaktuaren informazioa</string>\n  <string name=\"contents_email\">E-posta helbidea</string>\n  <string name=\"contents_location\">Koordenatu geografikoak</string>\n  <string name=\"contents_phone\">Telefono zenbakia</string>\n  <string name=\"contents_sms\">SMS helbidea</string>\n  <string name=\"contents_text\">Testu laua</string>\n  <string name=\"history_clear_one_history_text\">Garbitu</string>\n  <string name=\"history_clear_text\">Garbitu historia</string>\n  <string name=\"history_email_title\">Barra-kode Eskanerraren historia</string>\n  <string name=\"history_empty\">Hutsik</string>\n  <string name=\"history_empty_detail\">Ez da inoiz barra-koderik gorde</string>\n  <string name=\"history_send\">Bidali historia</string>\n  <string name=\"history_title\">Historia</string>\n  <string name=\"menu_encode_mecard\">Erabili MECARD</string>\n  <string name=\"menu_encode_vcard\">Erabili vCard</string>\n  <string name=\"menu_help\">Laguntza</string>\n  <string name=\"menu_history\">Historia</string>\n  <string name=\"menu_settings\">Ezarpenak</string>\n  <string name=\"menu_share\">Partekatu</string>\n  <string name=\"msg_bulk_mode_scanned\">Handizkako modua: barra-kodea eskaneatuta eta gordeta</string>\n  <string name=\"msg_camera_framework_bug\">Barkatu, Android kamerak arazo bat izan du. Behar bada gailua berrabiarazi beharko duzu.</string>\n  <string name=\"msg_default_format\">Formatua</string>\n  <string name=\"msg_default_meta\">Metadatuak</string>\n  <string name=\"msg_default_mms_subject\">Kaixo</string>\n  <string name=\"msg_default_status\">Kokatu barra-kode bat laukizuzenaren barruan eskaneatzeko.</string>\n  <string name=\"msg_default_time\">Denbora</string>\n  <string name=\"msg_default_type\">Mota</string>\n  <string name=\"msg_encode_contents_failed\">Ezin izan da barra-kode bat kodetu emandako datuetatik.</string>\n  <string name=\"msg_google_books\">Google Books</string>\n  <string name=\"msg_google_product\">Google Product Bilaketa</string>\n  <string name=\"msg_google_shopper_missing\">Google Shopper ez dago instalatuta</string>\n  <string name=\"msg_install_google_shopper\">Google Shopper-ek barra-kodeak eskaneatzea eta lineako salneurriak eta salneurri lokalak, balorazioak eta abar konbinatzen ditu, arakatzailea irekitzeko beharrik gabe. Probatu nahi duzu?</string>\n  <string name=\"msg_intent_failed\">Barkatu, eskatutako aplikazioa ezin izan da abiarazi. Behar bada barra-kodearen edukiak baliogabeak dira.</string>\n  <string name=\"msg_redirect\">Berbideratu</string>\n  <string name=\"msg_sbc_book_not_searchable\">Barkatu, liburu honetan ezin da bilaketarik egin.</string>\n  <string name=\"msg_sbc_failed\">Barkatu, bilaketak arazo bat izan du.</string>\n  <string name=\"msg_sbc_no_page_returned\">Ez da orririk itzuli</string>\n  <string name=\"msg_sbc_page\">Orria</string>\n  <string name=\"msg_sbc_results\">Emaitzak</string>\n  <string name=\"msg_sbc_searching_book\">Liburua arakatzen\\u2026</string>\n  <string name=\"msg_sbc_snippet_unavailable\">Lagina ez dago eskuragarri</string>\n  <string name=\"msg_sbc_unknown_page\">Orri ezezaguna</string>\n  <string name=\"msg_share_explanation\">Datuak parteka ditzakezu zure pantailan barra-kode bat bistaratu eta beste telefono batekin eskaneatuz.</string>\n  <string name=\"msg_share_subject_line\">Hemen daude eskaneatu dudan barra-kodearen edukiak</string>\n  <string name=\"msg_share_text\">Edo idatzi zerbait eta sakatu Enter</string>\n  <string name=\"msg_sure\">Ziur zaude?</string>\n  <string name=\"msg_unmount_usb\">Barkatu, SD txartela ez dago eskuragarri.</string>\n  <string name=\"preferences_actions_title\">Barra kode bat aurkitzean\\u2026</string>\n  <string name=\"preferences_auto_focus_title\">Erabili auto foku</string>\n  <string name=\"preferences_bulk_mode_summary\">Eskaneatu eta gorde hainbat barra-kode jarraian</string>\n  <string name=\"preferences_bulk_mode_title\">Handizkako eskaneatze modua</string>\n  <string name=\"preferences_copy_to_clipboard_title\">Kopiatu arbelera</string>\n  <string name=\"preferences_custom_product_search_summary\" formatted=\"false\">Ordezkapenak: %s = edukiak, %f = formatua, %t = mota</string>\n  <string name=\"preferences_custom_product_search_title\">Bilaketa URL pertsonalizatua</string>\n  <string name=\"preferences_decode_1D_title\">1D barra-kodeak</string>\n  <string name=\"preferences_decode_Data_Matrix_title\">Datu Matrizeak</string>\n  <string name=\"preferences_decode_QR_title\">QR Kodeak</string>\n  <string name=\"preferences_device_bug_workarounds_title\">Gailuak Bug konponbidea</string>\n  <string name=\"preferences_disable_continuous_focus_summary\">Erabili estandarrean soilik fokuaren modua</string>\n  <string name=\"preferences_disable_continuous_focus_title\">Etengabeko foku No</string>\n  <string name=\"preferences_disable_exposure_title\">Esposizio No</string>\n  <string name=\"preferences_front_light_summary\">Eskaneatzea hobetzen du zenbait telefonotan argiztapena txikia denean, baina distirak eragin ditzake. Ez du telefono guztietan funtzionatzen.</string>\n  <string name=\"preferences_front_light_title\">Erabili aurreko argia</string>\n  <string name=\"preferences_general_title\">Ezarpen orokorrak</string>\n  <string name=\"preferences_name\">Ezarpenak</string>\n  <string name=\"preferences_play_beep_title\">Soinu-seinalea</string>\n  <string name=\"preferences_remember_duplicates_summary\">Gorde barra-kode beraren hainbat eskaneatze Historian</string>\n  <string name=\"preferences_remember_duplicates_title\">Gogoratu errepikatuak</string>\n  <string name=\"preferences_result_title\">Emaitzen ezarpenak</string>\n  <string name=\"preferences_scanning_title\">Barra-kodeak eskaneatzean, deskodetu\\u2026</string>\n  <string name=\"preferences_search_country\">Bilatu herrialdea</string>\n  <string name=\"preferences_supplemental_summary\">Saiatu barra-kodearen edukiei buruzko informazio gehiago eskuratzen</string>\n  <string name=\"preferences_supplemental_title\">Eskuratu informazio gehiago</string>\n  <string name=\"preferences_try_bsplus\">Saiatu Barcode Scanner+</string>\n  <string name=\"preferences_try_bsplus_summary\">Ezaugarri berri eta interfaze indartu</string>\n  <string name=\"preferences_vibrate_title\">Bibratu</string>\n  <string name=\"result_address_book\">Kontaktu-informazioa aurkitu da</string>\n  <string name=\"result_calendar\">Egutegiko gertaera aurkitu da</string>\n  <string name=\"result_email_address\">E-posta helbidea aurkitu da</string>\n  <string name=\"result_geo\">Koordenatu geografikoak aurkitu dira</string>\n  <string name=\"result_isbn\">Liburua aurkitu da</string>\n  <string name=\"result_product\">Produktua aurkitu da</string>\n  <string name=\"result_sms\">SMS helbidea aurkitu da</string>\n  <string name=\"result_tel\">Telefono zenbakia aurkitu da</string>\n  <string name=\"result_text\">Testu laua aurkitu da</string>\n  <string name=\"result_uri\">URL-a aurkitu da</string>\n  <string name=\"result_wifi\">WLAN Konfigurazioa aurkitu da</string>\n  <string name=\"sbc_name\">Google Book Bilaketa</string>\n  <string name=\"share_name\">Partekatu barra-kode bidez</string>\n  <string name=\"wifi_changing_network\">Sarerako konexioa eskatzen\\u2026</string>\n  <string name=\"wifi_ssid_label\">Sarearen Izena</string>\n  <string name=\"wifi_type_label\">Mota</string>\n</resources>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/values-fi/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2012 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<resources>\n  <!-- <string name=\"app_name\">Barcode Scanner</string> -->\n  <string name=\"app_picker_name\">Ohjelmat</string>\n  <string name=\"bookmark_picker_name\">Kirjanmerkit</string>\n  <string name=\"button_add_calendar\">Lisää kalenteriin</string>\n  <string name=\"button_add_contact\">Lisää yhteystieto</string>\n  <string name=\"button_back\">Takaisin</string>\n  <string name=\"button_book_search\">Kirjahaku</string>\n  <string name=\"button_cancel\">Peruuta</string>\n  <string name=\"button_custom_product_search\">Mukautettu haku</string>\n  <string name=\"button_dial\">Soita numeroon</string>\n  <string name=\"button_done\">Valmis</string>\n  <string name=\"button_email\">Lähetä sähköpostia</string>\n  <string name=\"button_get_directions\">Hae ajo-ohjeet</string>\n  <string name=\"button_google_shopper\">Shopper</string>\n  <string name=\"button_mms\">Lähetä multimediaviesti</string>\n  <string name=\"button_ok\">OK</string>\n  <string name=\"button_open_browser\">Avaa selain</string>\n  <string name=\"button_product_search\">Tuotehaku</string>\n  <string name=\"button_search_book_contents\">Hae kirjan sisältö</string>\n  <string name=\"button_share_app\">Ohjelma</string>\n  <string name=\"button_share_bookmark\">Kirjanmerkki</string>\n  <string name=\"button_share_by_email\">Jaa sähköpostilla</string>\n  <string name=\"button_share_by_sms\">Jaa tekstiviestillä</string>\n  <string name=\"button_share_clipboard\">Leikepöytä</string>\n  <string name=\"button_share_contact\">Kontakti</string>\n  <string name=\"button_show_map\">Näytä kartta</string>\n  <string name=\"button_sms\">Lähetä tekstiviesti</string>\n  <string name=\"button_web_search\">Verkkohaku</string>\n  <string name=\"button_wifi\">Yhdistä verkkoon</string>\n  <string name=\"contents_contact\">Yhteystiedon tiedot</string>\n  <string name=\"contents_email\">Sähköpostiosoite</string>\n  <string name=\"contents_location\">Maantieteelliset koordinaatit</string>\n  <string name=\"contents_phone\">Puhelinnumero</string>\n  <string name=\"contents_sms\">Tekstiviestin osoite</string>\n  <string name=\"contents_text\">Teksti</string>\n  <string name=\"history_clear_one_history_text\">Tyhjennä</string>\n  <string name=\"history_clear_text\">Tyhjennä historia</string>\n  <string name=\"history_email_title\">Viivakoodien historia</string>\n  <string name=\"history_empty\">Tyhjä</string>\n  <string name=\"history_empty_detail\">Ei tallennettuja viivakoodeja</string>\n  <string name=\"history_send\">Lähetä historia</string>\n  <string name=\"history_title\">Historia</string>\n  <string name=\"menu_encode_mecard\">Käytä MECARD:ia</string>\n  <string name=\"menu_encode_vcard\">Käytä vCard:ia</string>\n  <string name=\"menu_help\">Ohje</string>\n  <string name=\"menu_history\">Historia</string>\n  <string name=\"menu_settings\">Asetukset</string>\n  <string name=\"menu_share\">Jaa</string>\n  <string name=\"msg_bulk_mode_scanned\">Toistotila: viivakoodi luettu ja tallennetttu</string>\n  <string name=\"msg_camera_framework_bug\">Formaatti</string>\n  <string name=\"msg_default_format\">Muoto</string>\n  <string name=\"msg_default_meta\">Metatiedot</string>\n  <string name=\"msg_default_mms_subject\">Hei</string>\n  <string name=\"msg_default_status\">Aseta viivakoodi neliön sisälle skannataksesi sen.</string>\n  <string name=\"msg_default_time\">Aika</string>\n  <string name=\"msg_default_type\">Tyyppi</string>\n  <string name=\"msg_encode_contents_failed\">Viivakoodia ei voitu muodostaa annetusta datasta.</string>\n  <string name=\"msg_google_books\">Google-kirjat</string>\n  <string name=\"msg_google_product\">Google-tuotehaku</string>\n  <string name=\"msg_google_shopper_missing\">Google Shopperia ei ole asennettu</string>\n  <string name=\"msg_install_google_shopper\">Google Shopper yhdistää viivakoodinlukuun tuotteiden hintatiedot verkossa ja paikallisesti, arvostelut ja muut tiedot ilman tarvetta avata selainta erikseen. Haluaisitko kokeilla sitä?</string>\n  <string name=\"msg_intent_failed\">Valitettavasti pyydettyä sovellusta ei voitu käynnistää. Viivakoodin sisältö voi olla virheellinen.</string>\n  <string name=\"msg_redirect\">Uudelleenohjaus</string>\n  <string name=\"msg_sbc_book_not_searchable\">Valitettavasti tämä kirja ei ole haettavissa.</string>\n  <string name=\"msg_sbc_failed\">Valitettavasti haussa tapahtui virhe.</string>\n  <string name=\"msg_sbc_no_page_returned\">Sivulta ei vastausta</string>\n  <string name=\"msg_sbc_page\">Sivu</string>\n  <string name=\"msg_sbc_results\">Tulokset</string>\n  <string name=\"msg_sbc_searching_book\">Haetaan kirjaa\\u2026</string>\n  <string name=\"msg_sbc_snippet_unavailable\">Kappaletta ei saatavilla</string>\n  <string name=\"msg_sbc_unknown_page\">Tuntematon sivu</string>\n  <string name=\"msg_share_explanation\">Voit jakaa dataa näyttämällä viivakoodin laitteesi näytöllä ja lukemalla sen toisella laitteella.</string>\n  <string name=\"msg_share_subject_line\">Tässä on viivakoodin skannattu sisältö</string>\n  <string name=\"msg_share_text\">Tai kirjoita tekstiä</string>\n  <string name=\"msg_sure\">Oletko varma?</string>\n  <string name=\"msg_unmount_usb\">SD-kortti ei ole käytettävissä.</string>\n  <string name=\"preferences_actions_title\">Kun viivakoodi löytyy\\u2026</string>\n  <string name=\"preferences_auto_focus_title\">Käytä automaattista tarkennusta</string>\n  <string name=\"preferences_bulk_mode_summary\">Skannaa ja tallenna viivakoodeja jatkuvasti</string>\n  <string name=\"preferences_bulk_mode_title\">Toistotila</string>\n  <string name=\"preferences_copy_to_clipboard_title\">Kopioi leikepöydälle</string>\n  <string name=\"preferences_custom_product_search_summary\" formatted=\"false\">Seuraavat korvataan: %s = sisältö, %f = formaatti, %t = tyyppi</string>\n  <string name=\"preferences_custom_product_search_title\">Mukautettu hakukone</string>\n  <string name=\"preferences_decode_1D_title\">1D-viivakoodit</string>\n  <string name=\"preferences_decode_Data_Matrix_title\">Data Matrix</string>\n  <string name=\"preferences_decode_QR_title\">QR-koodit</string>\n  <string name=\"preferences_device_bug_workarounds_title\">Laitteen vikojen kiertäminen</string>\n  <string name=\"preferences_disable_continuous_focus_summary\">Käytä vain vakiotarkennusta</string>\n  <string name=\"preferences_disable_continuous_focus_title\">Ei jatkuvaa tarkennusta</string>\n  <string name=\"preferences_disable_exposure_title\">Ei valotusta</string>\n  <string name=\"preferences_front_light_summary\">Salamavalon käyttö saattaa auttaa hämärässä, mutta se saattaa aiheuttaa myös häikäisyä. Ei toimi kaikissa puhelimissa.</string>\n  <string name=\"preferences_front_light_title\">Käytä valoa</string>\n  <string name=\"preferences_general_title\">Yleiset asetukset</string>\n  <string name=\"preferences_name\">Asetukset</string>\n  <string name=\"preferences_play_beep_title\">Piippaus</string>\n  <string name=\"preferences_remember_duplicates_summary\">Jos sama viivakoodi skannetaan useasti, tallenna jokainen skannauskerta historiaan</string>\n  <string name=\"preferences_remember_duplicates_title\">Muista kaksoiskappaleet</string>\n  <string name=\"preferences_result_title\">Tuloksien asetukset</string>\n  <string name=\"preferences_scanning_title\">Kun skannataan viivakoodeja, dekoodaa\\u2026</string>\n  <string name=\"preferences_search_country\">Etsi maasta</string>\n  <string name=\"preferences_supplemental_summary\">Yritä hakea lisätietoja viivakoodin sisällöstä</string>\n  <string name=\"preferences_supplemental_title\">Hae lisää tietoa</string>\n  <string name=\"preferences_try_bsplus\">Kokeile Barcode Scanner+</string>\n  <string name=\"preferences_try_bsplus_summary\">Parannettu uusilla ominaisuuksilla ja käyttöliittymällä</string>\n  <string name=\"preferences_vibrate_title\">Värinä</string>\n  <string name=\"result_address_book\">Löydettiin yhteystietoja</string>\n  <string name=\"result_calendar\">Löydettiin kalenteritapahtuma</string>\n  <string name=\"result_email_address\">Löydettiin sähköpostiosoite</string>\n  <string name=\"result_geo\">Löydettiin koordinaatteja</string>\n  <string name=\"result_isbn\">Löydettiin kirja</string>\n  <string name=\"result_product\">Löydettiin tuote</string>\n  <string name=\"result_sms\">Löydettiin tekstiviestinumero</string>\n  <string name=\"result_tel\">Löydettiin puhelinnumero</string>\n  <string name=\"result_text\">Löydettiin teksti</string>\n  <string name=\"result_uri\">Löydettin URL-osoite</string>\n  <string name=\"result_wifi\">Löydettiin asetukset langattomalle yhteydelle</string>\n  <string name=\"sbc_name\">Googlen kirjahaku</string>\n  <string name=\"share_name\">Jaa viivakoodilla</string>\n  <string name=\"wifi_changing_network\">Pyydetään yhteyttä verkkoon\\u2026</string>\n  <string name=\"wifi_ssid_label\">Verkon nimi</string>\n  <string name=\"wifi_type_label\">Tyyppi</string>\n</resources>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/values-fr/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2012 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<resources>\n  <!-- <string name=\"app_name\">Barcode Scanner</string> -->\n  <string name=\"app_picker_name\">Applications</string>\n  <string name=\"bookmark_picker_name\">Marques-pages</string>\n  <string name=\"button_add_calendar\">Ajouter à l\\'agenda</string>\n  <string name=\"button_add_contact\">Ajouter un contact</string>\n  <string name=\"button_back\">Retour</string>\n  <string name=\"button_book_search\">Recherche de livres</string>\n  <string name=\"button_cancel\">Annuler</string>\n  <string name=\"button_custom_product_search\">Recherche personalisée</string>\n  <string name=\"button_dial\">Composer numéro</string>\n  <string name=\"button_done\">Terminé</string>\n  <string name=\"button_email\">Envoyer email</string>\n  <string name=\"button_get_directions\">Obtenir adresses</string>\n  <string name=\"button_google_shopper\">Shopper</string>\n  <string name=\"button_mms\">Envoyer MMS</string>\n  <string name=\"button_ok\">OK</string>\n  <string name=\"button_open_browser\">Ouvrir le navigateur</string>\n  <string name=\"button_product_search\">Recherche de produits</string>\n  <string name=\"button_search_book_contents\">Recherche contenu du livre</string>\n  <string name=\"button_share_app\">Application</string>\n  <string name=\"button_share_bookmark\">Marques-pages</string>\n  <string name=\"button_share_by_email\">Partager par email</string>\n  <string name=\"button_share_by_sms\">Partager par SMS</string>\n  <string name=\"button_share_clipboard\">Presse papier</string>\n  <string name=\"button_share_contact\">Contact</string>\n  <string name=\"button_show_map\">Montrer la carte</string>\n  <string name=\"button_sms\">Envoyer SMS</string>\n  <string name=\"button_web_search\">Recherche Web</string>\n  <string name=\"button_wifi\">Se connecter au réseau WLAN</string>\n  <string name=\"contents_contact\">Informations sur le contact</string>\n  <string name=\"contents_email\">Adresse email</string>\n  <string name=\"contents_location\">Coordonnées géographiques</string>\n  <string name=\"contents_phone\">Numéro de téléphone</string>\n  <string name=\"contents_sms\">Adresse SMS</string>\n  <string name=\"contents_text\">Texte</string>\n  <string name=\"history_clear_one_history_text\">Effacer</string>\n  <string name=\"history_clear_text\">Vider l\\'historique</string>\n  <string name=\"history_email_title\">Historique de Barcode Scanner</string>\n  <string name=\"history_empty\">Vide</string>\n  <string name=\"history_empty_detail\">Aucun code-barres scanné n\\'a encore été enregistré</string>\n  <string name=\"history_send\">Envoyer historique</string>\n  <string name=\"history_title\">Historique</string>\n  <string name=\"menu_encode_mecard\">Format MECARD</string>\n  <string name=\"menu_encode_vcard\">Format vCard</string>\n  <string name=\"menu_help\">Aide</string>\n  <string name=\"menu_history\">Historique</string>\n  <string name=\"menu_settings\">Paramètres</string>\n  <string name=\"menu_share\">Partager</string>\n  <string name=\"msg_bulk_mode_scanned\">Mode lecture en rafale : code-barres scanné et enregistré</string>\n  <string name=\"msg_camera_framework_bug\">Désolé, la caméra Android rencontré un problème. Un redémarrage de l\\'appareil est peut-être nécessaire.</string>\n  <string name=\"msg_default_format\">Format</string>\n  <string name=\"msg_default_meta\">Métadonnées</string>\n  <string name=\"msg_default_mms_subject\">Salut</string>\n  <string name=\"msg_default_status\">Placer un code barre à l\\'intérieur du rectangle pour le scanner.</string>\n  <string name=\"msg_default_time\">Temps</string>\n  <string name=\"msg_default_type\">Type</string>\n  <string name=\"msg_encode_contents_failed\">Impossible de créer le code-barres à partir des données fournies.</string>\n  <string name=\"msg_google_books\">Google Livres</string>\n  <string name=\"msg_google_product\">Google Shopping</string>\n  <string name=\"msg_google_shopper_missing\">Google Shopper n\\'est pas installé</string>\n  <string name=\"msg_install_google_shopper\">Google Shopper associe la lecture de codes-barres avec des prix, des commentaires et plus encore sans ouvrir le navigateur. Désirez-vous l\\'essayer maintenant ?</string>\n  <string name=\"msg_intent_failed\">Désolé, l\\'application demandée n\\'a pas pu être lancée. Le contenu du code-barres est peut-être invalide.</string>\n  <string name=\"msg_redirect\">Redirection</string>\n  <string name=\"msg_sbc_book_not_searchable\">Désolé, ce livre est introuvable.</string>\n  <string name=\"msg_sbc_failed\">Désolé, la recherche a rencontré un problème.</string>\n  <string name=\"msg_sbc_no_page_returned\">Page non trouvée</string>\n  <string name=\"msg_sbc_page\">Page</string>\n  <string name=\"msg_sbc_results\">Résultats</string>\n  <string name=\"msg_sbc_searching_book\">Recherche du livre\\u2026</string>\n  <string name=\"msg_sbc_snippet_unavailable\">Extrait non disponible</string>\n  <string name=\"msg_sbc_unknown_page\">Page inconnue</string>\n  <string name=\"msg_share_explanation\">Vous pouvez partager des données en affichant un code-barres sur votre écran et en le scannant avec un autre téléphone.</string>\n  <string name=\"msg_share_subject_line\">Voici le contenu d\\'un code-barres que j\\'ai scanné</string>\n  <string name=\"msg_share_text\">Ou tapez du texte</string>\n  <string name=\"msg_sure\">Êtes-vous sûr ?</string>\n  <string name=\"msg_unmount_usb\">Désolé, la carte SD n\\'est pas accessible.</string>\n  <string name=\"preferences_actions_title\">Quand un code-barres est trouvé\\u2026</string>\n  <string name=\"preferences_auto_focus_title\">Utiliser l\\'autofocus</string>\n  <string name=\"preferences_bulk_mode_summary\">Scanner et enregistrer plusieurs codes-barres d\\'affilée</string>\n  <string name=\"preferences_bulk_mode_title\">Mode de lecture en rafale</string>\n  <string name=\"preferences_copy_to_clipboard_title\">Copier dans le presse papier</string>\n  <string name=\"preferences_custom_product_search_summary\" formatted=\"false\">Remplacements : %s = contenu, %f = format, %t = type</string>\n  <string name=\"preferences_custom_product_search_title\">URL de recherche personnalisée</string>\n  <string name=\"preferences_decode_1D_title\">Unidimensionnels (1D)</string>\n  <string name=\"preferences_decode_Data_Matrix_title\">Data Matrix</string>\n  <string name=\"preferences_decode_QR_title\">QR</string>\n  <string name=\"preferences_device_bug_workarounds_title\">Solutions de contournement de bogues périphériques</string>\n  <string name=\"preferences_disable_continuous_focus_summary\">Utiliser uniquement le mode de mise au point standard</string>\n  <string name=\"preferences_disable_continuous_focus_title\">Pas de mise au point continue</string>\n  <string name=\"preferences_disable_exposure_title\">Pas d\\'exposition</string>\n  <string name=\"preferences_front_light_summary\">Allumer la lampe derrière le téléphone quand la lumière ambiante est faible. Peut provoquer des reflets et ne fonctionne pas sur tous les téléphones.</string>\n  <string name=\"preferences_front_light_title\">Flash</string>\n  <string name=\"preferences_general_title\">Paramètres généraux</string>\n  <string name=\"preferences_name\">Paramètres</string>\n  <string name=\"preferences_play_beep_title\">Bip</string>\n  <string name=\"preferences_remember_duplicates_summary\">Enregistrer dans l\\'historique les lectures multiples d\\'un même code-barres</string>\n  <string name=\"preferences_remember_duplicates_title\">Enregistrer les doublons</string>\n  <string name=\"preferences_result_title\">Paramètres de résultat</string>\n  <string name=\"preferences_scanning_title\">Pendant la numérisation, lire les codes\\u2026</string>\n  <string name=\"preferences_search_country\">Pays de recherche</string>\n  <string name=\"preferences_supplemental_summary\">Essayer de trouver plus d\\'informations sur le contenu des codes-barres scannés</string>\n  <string name=\"preferences_supplemental_title\">Trouver plus d\\'informations</string>\n  <string name=\"preferences_try_bsplus\">Essayez Barcode Scanner+</string>\n  <string name=\"preferences_try_bsplus_summary\">Amélioré avec de nouvelles fonctionnalités et de l\\'interface</string>\n  <string name=\"preferences_vibrate_title\">Vibrer</string>\n  <string name=\"result_address_book\">Information de contact trouvée</string>\n  <string name=\"result_calendar\">Événement de l\\'agenda trouvé</string>\n  <string name=\"result_email_address\">Adresse email trouvée</string>\n  <string name=\"result_geo\">Coordonnées géographiques trouvées</string>\n  <string name=\"result_isbn\">Livre trouvé</string>\n  <string name=\"result_product\">Produit trouvé</string>\n  <string name=\"result_sms\">Adresse SMS trouvée</string>\n  <string name=\"result_tel\">Numéro de téléphone trouvé</string>\n  <string name=\"result_text\">Texte trouvé</string>\n  <string name=\"result_uri\">URL trouvée</string>\n  <string name=\"result_wifi\">Configuration du réseau WLAN trouvée</string>\n  <string name=\"sbc_name\">Recherche Google Livres</string>\n  <string name=\"share_name\">Partager par code-barres</string>\n  <string name=\"wifi_changing_network\">Demande de connexion au réseau\\u2026</string>\n  <string name=\"wifi_ssid_label\">Nom du réseau WLAN</string>\n  <string name=\"wifi_type_label\">Type</string>\n</resources>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/values-he/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2012 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<resources>\n  <!-- <string name=\"app_name\">סורק ברקודים</string> -->\n  <string name=\"app_picker_name\">יישומים</string>\n  <string name=\"bookmark_picker_name\">סימניות</string>\n  <string name=\"button_add_calendar\">הוסף ללוח שנה</string>\n  <string name=\"button_add_contact\">הוספת איש קשר</string>\n  <string name=\"button_back\">חזרה</string>\n  <string name=\"button_book_search\">חיפוש ספר</string>\n  <string name=\"button_cancel\">ביטול</string>\n  <string name=\"button_custom_product_search\">חיפוש מותאם אישית</string>\n  <string name=\"button_dial\">חייג מספר</string>\n  <string name=\"button_done\">סיים</string>\n  <string name=\"button_email\">שלח דואר אלקטרוני</string>\n  <string name=\"button_get_directions\">קבל הוראות הגעה</string>\n  <string name=\"button_google_shopper\">Shopper</string>\n  <string name=\"button_mms\">שלח הודעת מולטימדיה</string>\n  <string name=\"button_ok\">אישור</string>\n  <string name=\"button_open_browser\">פתח את הדפדפן</string>\n  <string name=\"button_product_search\">חיפוש מוצר</string>\n  <string name=\"button_search_book_contents\">חיפוש בתוכן</string>\n  <string name=\"button_share_app\">יישום</string>\n  <string name=\"button_share_bookmark\">סימניה</string>\n  <string name=\"button_share_by_email\">שתף בדואר אלקטרוני</string>\n  <string name=\"button_share_by_sms\">שתף בהודעה</string>\n  <string name=\"button_share_clipboard\">לוח עריכה</string>\n  <string name=\"button_share_contact\">איש קשר</string>\n  <string name=\"button_show_map\">הצג מפה</string>\n  <string name=\"button_sms\">שלח הודעה</string>\n  <string name=\"button_web_search\">חיפוש באינטרנט</string>\n  <string name=\"button_wifi\">התחבר לרשת</string>\n  <string name=\"contents_contact\">פרטי איש קשר</string>\n  <string name=\"contents_email\">כתובת דואר אלקטרוני</string>\n  <string name=\"contents_location\">קואורדינטות גאוגרפיות</string>\n  <string name=\"contents_phone\">מספר טלפון</string>\n  <string name=\"contents_sms\">כתובת SMS</string>\n  <string name=\"contents_text\">טקסט רגיל</string>\n  <string name=\"history_clear_one_history_text\">נקה</string>\n  <string name=\"history_clear_text\">נקה היסטוריה</string>\n  <string name=\"history_email_title\">היסטוריית סורק הברקודים</string>\n  <string name=\"history_empty\">ריק</string>\n  <string name=\"history_empty_detail\">ברקודים לא נרשמו</string>\n  <string name=\"history_send\">שלח היסטוריה</string>\n  <string name=\"history_title\">היסטוריה</string>\n  <string name=\"menu_encode_mecard\">השתמש MECARD</string>\n  <string name=\"menu_encode_vcard\">השתמש vCard</string>\n  <string name=\"menu_help\">עזרה</string>\n  <string name=\"menu_history\">היסטוריה</string>\n  <string name=\"menu_settings\">הגדרות</string>\n  <string name=\"menu_share\">שתף</string>\n  <string name=\"msg_bulk_mode_scanned\">מצב קבוצה: ברקוד נסרק ונשמר</string>\n  <string name=\"msg_camera_framework_bug\">סליחה, מצלמת האנדרואיד נתקלה בבעיה. ייתכן שיהיה עליך להפעיל מחדש את המכשיר.</string>\n  <string name=\"msg_default_format\">פורמט</string>\n  <string name=\"msg_default_meta\">מטה-נתונים</string>\n  <string name=\"msg_default_mms_subject\">היי</string>\n  <string name=\"msg_default_status\">הצב ברקוד בתוך המלבן כדי לסרוק אותו.</string>\n  <string name=\"msg_default_time\">זמן</string>\n  <string name=\"msg_default_type\">סוג</string>\n  <string name=\"msg_encode_contents_failed\">לא היתה אפשרות לקודד ברקוד מהנתונים שסופקו.</string>\n  <string name=\"msg_google_books\">Google Books</string>\n  <string name=\"msg_google_product\">Google Product Search</string>\n  <string name=\"msg_google_shopper_missing\">Google Shopper לא מותקן.</string>\n  <string name=\"msg_install_google_shopper\">Google Shopper משלבת סריקת ברקודים עם מחירים מקוונים, חוות דעת ועוד בלי לפתוח את הדפדפן. האם ברצונך לנסות זאת?</string>\n  <string name=\"msg_intent_failed\">סליחה, לא ניתן להפעיל את היישום המבוקש. ייתכן שתוכן הברקוד לא תקין.</string>\n  <string name=\"msg_redirect\">נתב מחדש</string>\n  <string name=\"msg_sbc_book_not_searchable\">סליחה, ספר זה אינו ניתן לחיפוש.</string>\n  <string name=\"msg_sbc_failed\">סליחה, החיפוש נתקל בבעיה.</string>\n  <string name=\"msg_sbc_no_page_returned\">לא הוחזר דף</string>\n  <string name=\"msg_sbc_page\">דף</string>\n  <string name=\"msg_sbc_results\">תוצאות</string>\n  <string name=\"msg_sbc_searching_book\">מחפש ספר\\u2026</string>\n  <string name=\"msg_sbc_snippet_unavailable\">גזיר לא זמין</string>\n  <string name=\"msg_sbc_unknown_page\">דף לא ידוע</string>\n  <string name=\"msg_share_explanation\">באפשרותך לשתף נתונים על-ידי הצגת ברקוד על המסך וסריקתו עם טלפון אחר.</string>\n  <string name=\"msg_share_subject_line\">הנה התוכן של הברקוד שסרקתי</string>\n  <string name=\"msg_share_text\">או הקלד טקסט כלשהו</string>\n  <string name=\"msg_sure\">האם אתה בטוח?</string>\n  <string name=\"msg_unmount_usb\">סליחה, כרטיס הזכרון אינו נגיש.</string>\n  <string name=\"preferences_actions_title\">כאשר ברקוד נמצא\\u2026</string>\n  <string name=\"preferences_auto_focus_title\">להשתמש במיקוד האוטומטי</string>\n  <string name=\"preferences_bulk_mode_summary\">סורק ושומר ברקודים באופן רציף</string>\n  <string name=\"preferences_bulk_mode_title\">מצב סריקה מרובה</string>\n  <string name=\"preferences_copy_to_clipboard_title\">העתק ללוח</string>\n  <string name=\"preferences_custom_product_search_summary\" formatted=\"false\">החלפות: s% = התוכן, f% = הפורמט, t% = סוג</string>\n  <string name=\"preferences_custom_product_search_title\">כתובת לחיפוש מותאם אישית</string>\n  <string name=\"preferences_decode_1D_title\">ברקודים חד מימדיים</string>\n  <string name=\"preferences_decode_Data_Matrix_title\">מטריצת נתונים</string>\n  <string name=\"preferences_decode_QR_title\">קודי QR</string>\n  <string name=\"preferences_device_bug_workarounds_title\">באג במכשיר דרכים לעקיפת הבעיה</string>\n  <string name=\"preferences_disable_continuous_focus_summary\">השתמש רק במצב רגיל פוקוס</string>\n  <string name=\"preferences_disable_continuous_focus_title\">המיקוד לא רציפה</string>\n  <string name=\"preferences_disable_exposure_title\">אין חשיפה</string>\n  <string name=\"preferences_front_light_summary\">משפר את הסריקה בתאורה נמוכה בטלפונים מסוימים, אך עשוי לגרום לסנוור. לא עובד בכל הטלפונים.</string>\n  <string name=\"preferences_front_light_title\">השתמש באור הקדמי</string>\n  <string name=\"preferences_general_title\">הגדרות כלליות</string>\n  <string name=\"preferences_name\">הגדרות</string>\n  <string name=\"preferences_play_beep_title\">צפצוף</string>\n  <string name=\"preferences_remember_duplicates_summary\">אחסן מספר סריקות של אותו הברקוד בהיסטוריה</string>\n  <string name=\"preferences_remember_duplicates_title\">זכור כפילויות</string>\n  <string name=\"preferences_result_title\">הגדרות תוצאה</string>\n  <string name=\"preferences_scanning_title\">בעת סריקת ברקודים, קודד\\u2026</string>\n  <string name=\"preferences_search_country\">חיפוש הארץ</string>\n  <string name=\"preferences_supplemental_summary\">נסה למצא מידע נוסף על תוכן הברקוד</string>\n  <string name=\"preferences_supplemental_title\">מצא מידע נוסף</string>\n  <string name=\"preferences_try_bsplus\">נסה סורק ברקודים+</string>\n  <string name=\"preferences_try_bsplus_summary\">משופר עם תכונות וממשק חדשים</string>\n  <string name=\"preferences_vibrate_title\">רטט</string>\n  <string name=\"result_address_book\">נמצא מידע של איש קשר</string>\n  <string name=\"result_calendar\">נמצא אירוע</string>\n  <string name=\"result_email_address\">נמצאה כתובת דוא\"ל</string>\n  <string name=\"result_geo\">נמצאו קואורדינטות גיאוגרפיות</string>\n  <string name=\"result_isbn\">נמצא ספר</string>\n  <string name=\"result_product\">נמצא מוצר</string>\n  <string name=\"result_sms\">נמצאה כתובת הודעה</string>\n  <string name=\"result_tel\">נמצא מספר טלפון</string>\n  <string name=\"result_text\">נמצא טקסט</string>\n  <string name=\"result_uri\">נמצאה כתובת אינטרנט</string>\n  <string name=\"result_wifi\">נמצאו הגדרות רשת אל חוטית</string>\n  <string name=\"sbc_name\">Google חיפוש ספרים</string>\n  <string name=\"share_name\">שתף באמצעות ברקוד</string>\n  <string name=\"wifi_changing_network\">בקשת חיבור לרשת \\u2026</string>\n  <string name=\"wifi_ssid_label\">שם רשת</string>\n  <string name=\"wifi_type_label\">סוג</string>\n</resources>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/values-hi/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2012 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<resources>\n  <!-- <string name=\"app_name\">बारकोड स्कैनर</string> -->\n  <string name=\"app_picker_name\">अनुप्रयोगों</string>\n  <string name=\"bookmark_picker_name\">बुकमार्क्स</string>\n  <string name=\"button_add_calendar\">कैलेंडर के लिए जोड़ें</string>\n  <string name=\"button_add_contact\">संपर्क जोड़ें</string>\n  <string name=\"button_back\">वापस</string>\n  <string name=\"button_book_search\">पुस्तक खोज</string>\n  <string name=\"button_cancel\">रद्द करना</string>\n  <string name=\"button_custom_product_search\">कस्टम खोज</string>\n  <string name=\"button_dial\">डायल नंबर</string>\n  <string name=\"button_done\">ठीक है</string>\n  <string name=\"button_email\">ईमेल भेजें</string>\n  <string name=\"button_get_directions\">निर्देश प्राप्त करें</string>\n  <string name=\"button_google_shopper\">गूगल शॉपर</string>\n  <string name=\"button_mms\">एमएमएस भेजें</string>\n  <string name=\"button_ok\">ठीक है</string>\n  <string name=\"button_open_browser\">ओपन ब्राउज़र</string>\n  <string name=\"button_product_search\">उत्पाद खोज</string>\n  <string name=\"button_search_book_contents\">खोज सामग्री</string>\n  <string name=\"button_share_app\">आवेदन</string>\n  <string name=\"button_share_bookmark\">बुकमार्क</string>\n  <string name=\"button_share_by_email\">ईमेल के माध्यम से साझा करें</string>\n  <string name=\"button_share_by_sms\">एसएमएस के जरिए शेयर</string>\n  <string name=\"button_share_clipboard\">क्लिपबोर्ड</string>\n  <string name=\"button_share_contact\">संपर्क</string>\n  <string name=\"button_show_map\">नक्शा दिखाएँ</string>\n  <string name=\"button_sms\">एसएमएस भेजें</string>\n  <string name=\"button_web_search\">वेब खोज</string>\n  <string name=\"button_wifi\">नेटवर्क कनेक्ट करें</string>\n  <string name=\"contents_contact\">संपर्क जानकारी</string>\n  <string name=\"contents_email\">ईमेल पता</string>\n  <string name=\"contents_location\">भौगोलिक निर्देशांक</string>\n  <string name=\"contents_phone\">फ़ोन नंबर</string>\n  <string name=\"contents_sms\">एसएमएस पता</string>\n  <string name=\"contents_text\">सादा पाठ</string>\n  <string name=\"history_clear_one_history_text\">हटाएँ</string>\n  <string name=\"history_clear_text\">इतिहास हटाएँ</string>\n  <string name=\"history_email_title\">बारकोड स्कैनर इतिहास</string>\n  <string name=\"history_empty\">खाली</string>\n  <string name=\"history_empty_detail\">अभी तक कोई बारकोड स्कैन दर्ज किया गया है</string>\n  <string name=\"history_send\">इतिहास भेजें</string>\n  <string name=\"history_title\">इतिहास</string>\n  <string name=\"menu_encode_mecard\">MECARD का प्रयोग करें</string>\n  <string name=\"menu_encode_vcard\">vCard का प्रयोग करें</string>\n  <string name=\"menu_help\">मदद</string>\n  <string name=\"menu_history\">इतिहास</string>\n  <string name=\"menu_settings\">सेटिंग्स</string>\n  <string name=\"menu_share\">शेयर</string>\n  <string name=\"msg_bulk_mode_scanned\">थोक मोड: बारकोड स्कैन और बचाया</string>\n  <string name=\"msg_camera_framework_bug\">क्षमा करें, Android कैमरा एक समस्या का सामना करना पड़ा. आप डिवाइस को पुनरारंभ करने की आवश्यकता हो सकती है.</string>\n  <string name=\"msg_default_format\">प्रारूप</string>\n  <string name=\"msg_default_meta\">मेटाडाटा</string>\n  <string name=\"msg_default_mms_subject\">हाय</string>\n  <string name=\"msg_default_status\">दृश्यदर्शी आयत के अंदर एक बारकोड प्लेस इसे स्कैन.</string>\n  <string name=\"msg_default_time\">समय</string>\n  <string name=\"msg_default_type\">टाइप</string>\n  <string name=\"msg_encode_contents_failed\">उपलब्ध कराए गए आंकड़ों से एक बारकोड सांकेतिक शब्दों में बदलना नहीं कर सका.</string>\n  <string name=\"msg_google_books\">Google पुस्तक</string>\n  <string name=\"msg_google_product\">Google उत्पाद खोज</string>\n  <string name=\"msg_google_shopper_missing\">गूगल शॉपर्स स्थापित नहीं है</string>\n  <string name=\"msg_install_google_shopper\">Google शॉपर्स ब्राउज़र खोले बिना ऑनलाइन और स्थानीय कीमतों, समीक्षाएँ और अधिक के साथ स्कैनिंग बारकोड को जोड़ती है. तुम यह कोशिश करना चाहेंगे?</string>\n  <string name=\"msg_intent_failed\">क्षमा करें, अनुरोध आवेदन शुरू नहीं किया जा सका. बारकोड सामग्री अमान्य हो सकता है.</string>\n  <string name=\"msg_redirect\">पुनर्निर्देशन</string>\n  <string name=\"msg_sbc_book_not_searchable\">क्षमा करें, इस किताब को खोजा नहीं है.</string>\n  <string name=\"msg_sbc_failed\">क्षमा करें, खोज एक समस्या का सामना करना पड़ा.</string>\n  <string name=\"msg_sbc_no_page_returned\">कोई पृष्ठ लौटे</string>\n  <string name=\"msg_sbc_page\">पेज</string>\n  <string name=\"msg_sbc_results\">परिणाम</string>\n  <string name=\"msg_sbc_searching_book\">खोज पुस्तक\\u2026</string>\n  <string name=\"msg_sbc_snippet_unavailable\">उपलब्ध स्निपेट नहीं</string>\n  <string name=\"msg_sbc_unknown_page\">अज्ञात पृष्ठ</string>\n  <string name=\"msg_share_explanation\">आप अपनी स्क्रीन पर प्रदर्शित बारकोड और यह अन्य फोन के साथ स्कैनिंग द्वारा डेटा साझा कर सकते हैं.</string>\n  <string name=\"msg_share_subject_line\">यहाँ मैं एक बारकोड स्कैन की सामग्री</string>\n  <string name=\"msg_share_text\">या कुछ पाठ टाइप करें और प्रेस दर्ज करें</string>\n  <string name=\"msg_sure\">तुम्हें यकीन है?</string>\n  <string name=\"msg_unmount_usb\">क्षमा करें, एसडी कार्ड सुलभ नहीं है.</string>\n  <string name=\"preferences_actions_title\">जब एक बारकोड पाया जाता है\\u2026</string>\n  <string name=\"preferences_auto_focus_title\">ऑटो फोकस का उपयोग करें</string>\n  <string name=\"preferences_bulk_mode_summary\">स्कैन और कई बारकोड लगातार बचाने के</string>\n  <string name=\"preferences_bulk_mode_title\">थोक स्कैन मोड</string>\n  <string name=\"preferences_copy_to_clipboard_title\">क्लिपबोर्ड पर कॉपी</string>\n  <string name=\"preferences_custom_product_search_summary\" formatted=\"false\">स्थानापन्न: %s = सामग्री, %f = प्रारूप, %t = टाइप</string>\n  <string name=\"preferences_custom_product_search_title\">कस्टम खोज यूआरएल</string>\n  <string name=\"preferences_decode_1D_title\">1D बारकोड</string>\n  <string name=\"preferences_decode_Data_Matrix_title\">डाटा मैट्रिक्स</string>\n  <string name=\"preferences_decode_QR_title\">QR कोड</string>\n  <string name=\"preferences_device_bug_workarounds_title\">युक्ति बग वर्कअराउन्ड</string>\n  <string name=\"preferences_disable_continuous_focus_summary\">केवल मानक फोकस मोड का उपयोग करें</string>\n  <string name=\"preferences_disable_continuous_focus_title\">कोई निरंतर ध्यान</string>\n  <string name=\"preferences_disable_exposure_title\">कोई जोखिम</string>\n  <string name=\"preferences_front_light_summary\">कुछ फोन पर कम रोशनी में स्कैनिंग बढ़ाता है, लेकिन चमक का कारण हो सकता है. सभी फोन पर काम नहीं करता.</string>\n  <string name=\"preferences_front_light_title\">सामने प्रकाश का उपयोग करें</string>\n  <string name=\"preferences_general_title\">सामान्य सेटिंग्स</string>\n  <string name=\"preferences_name\">सेटिंग्स</string>\n  <string name=\"preferences_play_beep_title\">भोंपू</string>\n  <string name=\"preferences_remember_duplicates_summary\">इतिहास में एक ही बारकोड के स्टोर एकाधिक स्कैन</string>\n  <string name=\"preferences_remember_duplicates_title\">डुप्लिकेट याद रखें</string>\n  <string name=\"preferences_result_title\">नतीजे सेटिंग्स</string>\n  <string name=\"preferences_scanning_title\">जब बारकोड स्कैनिंग के लिए व्याख्या करना\\u2026</string>\n  <string name=\"preferences_search_country\">खोज देश</string>\n  <string name=\"preferences_supplemental_summary\">बारकोड सामग्री के बारे में में अधिक जानकारी पुनः प्राप्त करने की कोशिश करो</string>\n  <string name=\"preferences_supplemental_title\">अधिक जानकारी पुनर्प्राप्त</string>\n  <string name=\"preferences_try_bsplus\">बारकोड स्कैनर की कोशिश +</string>\n  <string name=\"preferences_try_bsplus_summary\">नई सुविधाओं और इंटरफेस के साथ बढ़ाया</string>\n  <string name=\"preferences_vibrate_title\">कांपना</string>\n  <string name=\"result_address_book\">मिला संपर्क जानकारी</string>\n  <string name=\"result_calendar\">मिला कैलेंडर घटना</string>\n  <string name=\"result_email_address\">मिला ईमेल पते</string>\n  <string name=\"result_geo\">मिला भौगोलिक निर्देशांक</string>\n  <string name=\"result_isbn\">मिला किताब</string>\n  <string name=\"result_product\">मिला उत्पाद</string>\n  <string name=\"result_sms\">मिला एसएमएस पता</string>\n  <string name=\"result_tel\">मिला फोन नंबर</string>\n  <string name=\"result_text\">मिला सादा पाठ</string>\n  <string name=\"result_uri\">मिला यूआरएल</string>\n  <string name=\"result_wifi\">मिला WLAN विन्यास</string>\n  <string name=\"sbc_name\">Google पुस्तक खोज</string>\n  <string name=\"share_name\">बारकोड के माध्यम से साझा करें</string>\n  <string name=\"wifi_changing_network\">नेटवर्क के लिए कनेक्शन का अनुरोध कर रहा है \\u2026</string>\n  <string name=\"wifi_ssid_label\">नेटवर्क नाम</string>\n  <string name=\"wifi_type_label\">टाइप</string>\n</resources>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/values-hu/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2012 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<resources>\n  <!-- <string name=\"app_name\">Barcode Scanner</string> -->\n  <string name=\"app_picker_name\">Alkalmazások</string>\n  <string name=\"bookmark_picker_name\">Könyvjelzők</string>\n  <string name=\"button_add_calendar\">Hozzáadás a naptárhoz</string>\n  <string name=\"button_add_contact\">Névjegy hozzáadása</string>\n  <string name=\"button_back\">Vissza</string>\n  <string name=\"button_book_search\">Könyv keresése</string>\n  <string name=\"button_cancel\">Mégse</string>\n  <string name=\"button_custom_product_search\">Egyedi keresés</string>\n  <string name=\"button_dial\">Telefonszám tárcsázása</string>\n  <string name=\"button_done\">Kész</string>\n  <string name=\"button_email\">E-mail küldése</string>\n  <string name=\"button_get_directions\">Útvonaltervezés</string>\n  <string name=\"button_google_shopper\">Shopper</string>\n  <string name=\"button_mms\">MMS küldése</string>\n  <string name=\"button_ok\">OK</string>\n  <string name=\"button_open_browser\">Böngésző megnyitása</string>\n  <string name=\"button_product_search\">Termék keresése</string>\n  <string name=\"button_search_book_contents\">Tartalom keresése</string>\n  <string name=\"button_share_app\">Alkalmazás</string>\n  <string name=\"button_share_bookmark\">Könyvjelző</string>\n  <string name=\"button_share_by_email\">Megosztás e-mailben</string>\n  <string name=\"button_share_by_sms\">Megosztás SMS-ben</string>\n  <string name=\"button_share_clipboard\">Vágólap</string>\n  <string name=\"button_share_contact\">Névjegy</string>\n  <string name=\"button_show_map\">Térkép mutatása</string>\n  <string name=\"button_sms\">SMS küldése</string>\n  <string name=\"button_web_search\">Keresés a weben</string>\n  <string name=\"button_wifi\">Kapcsolódás hálózathoz</string>\n  <string name=\"contents_contact\">Névjegy információ</string>\n  <string name=\"contents_email\">E-mail cím</string>\n  <string name=\"contents_location\">Földrajzi koordináták</string>\n  <string name=\"contents_phone\">Telefonszám</string>\n  <string name=\"contents_sms\">SMS szám</string>\n  <string name=\"contents_text\">Egyszerű szöveg</string>\n  <string name=\"history_clear_one_history_text\">Törlése</string>\n  <string name=\"history_clear_text\">Előzmények törlése</string>\n  <string name=\"history_email_title\">Barcode Scanner előzmények</string>\n  <string name=\"history_empty\">Üres</string>\n  <string name=\"history_empty_detail\">Nem vonalkód szkennelés lett felvéve még</string>\n  <string name=\"history_send\">Előzmények küldése</string>\n  <string name=\"history_title\">Előzmények</string>\n  <string name=\"menu_encode_mecard\">Használja MECARD</string>\n  <string name=\"menu_encode_vcard\">Használja vCard</string>\n  <string name=\"menu_help\">Súgó</string>\n  <string name=\"menu_history\">Előzmények</string>\n  <string name=\"menu_settings\">Beállítások</string>\n  <string name=\"menu_share\">Megosztás</string>\n  <string name=\"msg_bulk_mode_scanned\">Tömeges beolvasás: vonalkód beszkennelve és mentve</string>\n  <string name=\"msg_camera_framework_bug\">Android kamera hiba. Lehet, hogy újra kell indítania a készüléket.</string>\n  <string name=\"msg_default_format\">Formátum</string>\n  <string name=\"msg_default_meta\">Metaadatok</string>\n  <string name=\"msg_default_mms_subject\">Szia</string>\n  <string name=\"msg_default_status\">Pozícionálja a vonalkódot a kereső téglalapba a szkenneléshez.</string>\n  <string name=\"msg_default_time\">Idő</string>\n  <string name=\"msg_default_type\">Típus</string>\n  <string name=\"msg_encode_contents_failed\">Nem sikerült létrehozni a vonalkódot a megadott adatokból.</string>\n  <string name=\"msg_google_books\">Google Könyvek</string>\n  <string name=\"msg_google_product\">Google Termék Kereső</string>\n  <string name=\"msg_google_shopper_missing\">A Google Shopper nincs telepítve</string>\n  <string name=\"msg_install_google_shopper\">A Google Shopper kombinálja a vonalkód szkennelést árakkal, értékelésekkel és más dolgokkal, böngésző megnyitása nélkül. Ki szeretné próbálni?</string>\n  <string name=\"msg_intent_failed\">A kért alkalmazást nem lehet elindítani. A vonalkód tartalma lehet, hogy érvénytelen.</string>\n  <string name=\"msg_redirect\">Átirányítás</string>\n  <string name=\"msg_sbc_book_not_searchable\">Ez a könyv nem kereshető.</string>\n  <string name=\"msg_sbc_failed\">A keresés problémába ütközött.</string>\n  <string name=\"msg_sbc_no_page_returned\">Nincs visszakapott oldal</string>\n  <string name=\"msg_sbc_page\">Oldal</string>\n  <string name=\"msg_sbc_results\">Eredmények</string>\n  <string name=\"msg_sbc_searching_book\">Könyv keresése\\u2026</string>\n  <string name=\"msg_sbc_snippet_unavailable\">Kódrészlet nem elérhető</string>\n  <string name=\"msg_sbc_unknown_page\">Ismeretlen oldal</string>\n  <string name=\"msg_share_explanation\">Meg tud osztani adatot úgy, hogy egy vonalkódot jelenít meg a képernyőjén, melyet egy másik telefon beszkennel.</string>\n  <string name=\"msg_share_subject_line\">Itt a beolvasott vonalkód tartalma</string>\n  <string name=\"msg_share_text\">Vagy írja be a szöveget és nyomjon Enter-t</string>\n  <string name=\"msg_sure\">Biztos benne?</string>\n  <string name=\"msg_unmount_usb\">Az SD kártya nem elérhető.</string>\n  <string name=\"preferences_actions_title\">Amikor a vonalkód megvan\\u2026</string>\n  <string name=\"preferences_auto_focus_title\">Használja autofókusz</string>\n  <string name=\"preferences_bulk_mode_summary\">Több vonalkód folyamatos szkennelése és mentése</string>\n  <string name=\"preferences_bulk_mode_title\">Tömeges beolvasás</string>\n  <string name=\"preferences_copy_to_clipboard_title\">Másolás a vágólapra</string>\n  <string name=\"preferences_custom_product_search_summary\" formatted=\"false\">Használjon: %s = tartalom, %f = formátum, %t = típus</string>\n  <string name=\"preferences_custom_product_search_title\">Egyedi kereső URL</string>\n  <string name=\"preferences_decode_1D_title\">1D vonalkódok</string>\n  <string name=\"preferences_decode_Data_Matrix_title\">Data Matrix</string>\n  <string name=\"preferences_decode_QR_title\">QR kódok</string>\n  <string name=\"preferences_device_bug_workarounds_title\">Eszköz Bug Lehetséges megoldások</string>\n  <string name=\"preferences_disable_continuous_focus_summary\">Csak a normál élességállítási mód</string>\n  <string name=\"preferences_disable_continuous_focus_title\">Nincs folyamatos fókusz</string>\n  <string name=\"preferences_disable_exposure_title\">No expozíció</string>\n  <string name=\"preferences_front_light_summary\">Javítja a szkennelést kevés fény mellett néhány telefonon, de csillogást okozhat. Nem minden telefonon működik.</string>\n  <string name=\"preferences_front_light_title\">Kamera LED használata</string>\n  <string name=\"preferences_general_title\">Általános beállítások</string>\n  <string name=\"preferences_name\">Beállítások</string>\n  <string name=\"preferences_play_beep_title\">Sípolás</string>\n  <string name=\"preferences_remember_duplicates_summary\">Ugyanannak a vonalkódnak több szkennelt képét is tárolja az Előzményekben</string>\n  <string name=\"preferences_remember_duplicates_title\">Duplikációk megjegyzése</string>\n  <string name=\"preferences_result_title\">Találati beállítások</string>\n  <string name=\"preferences_scanning_title\">Vonalkód szkennelésekor, dekódoláskor\\u2026</string>\n  <string name=\"preferences_search_country\">Ország keresése</string>\n  <string name=\"preferences_supplemental_summary\">A vonalkóddal jelzett tartalomról megpróbál több információt letölteni.</string>\n  <string name=\"preferences_supplemental_title\">További információk letöltése</string>\n  <string name=\"preferences_try_bsplus\">Próbálja Barcode Scanner+</string>\n  <string name=\"preferences_try_bsplus_summary\">Továbbfejlesztett új jellemzők és interfész</string>\n  <string name=\"preferences_vibrate_title\">Rezgés</string>\n  <string name=\"result_address_book\">Névjegy találat</string>\n  <string name=\"result_calendar\">Naptár esemény találat</string>\n  <string name=\"result_email_address\">E-mail cím találat</string>\n  <string name=\"result_geo\">Földrajzi koordináták találat</string>\n  <string name=\"result_isbn\">Könyv találat</string>\n  <string name=\"result_product\">Termék találat</string>\n  <string name=\"result_sms\">SMS szám találat</string>\n  <string name=\"result_tel\">Telefonszám találat</string>\n  <string name=\"result_text\">Egyszerű szöveg találat</string>\n  <string name=\"result_uri\">URL találat</string>\n  <string name=\"result_wifi\">WLAN konfiguráció találat</string>\n  <string name=\"sbc_name\">Google Könyvek keresés</string>\n  <string name=\"share_name\">Megosztás vonalkóddal</string>\n  <string name=\"wifi_changing_network\">Kérése kapcsolat hálózati\\u2026</string>\n  <string name=\"wifi_ssid_label\">Hálózat neve</string>\n  <string name=\"wifi_type_label\">Típus</string>\n</resources>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/values-id/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2012 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<resources>\n  <!-- <string name=\"app_name\">Barcode Scanner</string> -->\n  <string name=\"app_picker_name\">Aplikasi</string>\n  <string name=\"bookmark_picker_name\">Bookmarks</string>\n  <string name=\"button_add_calendar\">Tambah ke kalendar</string>\n  <string name=\"button_add_contact\">Tambah kontak</string>\n  <string name=\"button_back\">Kembali</string>\n  <string name=\"button_book_search\">Cari Buku</string>\n  <string name=\"button_cancel\">Batal</string>\n  <string name=\"button_custom_product_search\">Pencarian kustom</string>\n  <string name=\"button_dial\">Panggil nomor</string>\n  <string name=\"button_done\">Selesai</string>\n  <string name=\"button_email\">Kirim surel</string>\n  <string name=\"button_get_directions\">Dapatkan petunjuk arah</string>\n  <string name=\"button_google_shopper\">Shopper</string>\n  <string name=\"button_mms\">Kirim MMS</string>\n  <string name=\"button_ok\">OK</string>\n  <string name=\"button_open_browser\">Buka browser</string>\n  <string name=\"button_product_search\">Cari Produk</string>\n  <string name=\"button_search_book_contents\">Cari isi</string>\n  <string name=\"button_share_app\">Aplikasi</string>\n  <string name=\"button_share_bookmark\">Bookmark</string>\n  <string name=\"button_share_by_email\">Bagikan melalui surel</string>\n  <string name=\"button_share_by_sms\">Bagikan melalui SMS</string>\n  <string name=\"button_share_clipboard\">Clipboard</string>\n  <string name=\"button_share_contact\">Kontak</string>\n  <string name=\"button_show_map\">Lihat peta</string>\n  <string name=\"button_sms\">Kirim SMS</string>\n  <string name=\"button_web_search\">Pencarian web</string>\n  <string name=\"button_wifi\">Hubungkan ke Jaringan</string>\n  <string name=\"contents_contact\">Informasi kontak</string>\n  <string name=\"contents_email\">Alamat surel</string>\n  <string name=\"contents_location\">Koordinat geografis</string>\n  <string name=\"contents_phone\">Nomor telepon</string>\n  <string name=\"contents_sms\">Alamat SMS</string>\n  <string name=\"contents_text\">Teks biasa</string>\n  <string name=\"history_clear_one_history_text\">Hapus</string>\n  <string name=\"history_clear_text\">Hapus riwayat</string>\n  <string name=\"history_email_title\">Riwayat Barcode Scanner</string>\n  <string name=\"history_empty\">Kosong</string>\n  <string name=\"history_empty_detail\">Tidak ada scan barcode telah dicatat belum</string>\n  <string name=\"history_send\">Kirim riwayat</string>\n  <string name=\"history_title\">Riwayat</string>\n  <string name=\"menu_encode_mecard\">Gunakan MECARD</string>\n  <string name=\"menu_encode_vcard\">Gunakan vCard</string>\n  <string name=\"menu_help\">Bantuan</string>\n  <string name=\"menu_history\">Riwayat</string>\n  <string name=\"menu_settings\">Pengaturan</string>\n  <string name=\"menu_share\">Bagikan</string>\n  <string name=\"msg_bulk_mode_scanned\">Bulk mode: barcode sudah dipindai dan disimpan</string>\n  <string name=\"msg_camera_framework_bug\">Maaf, kamera pada Android mengalami masalah. Anda mungkin perlu me-restart perangkat.</string>\n  <string name=\"msg_default_format\">Bentuk</string>\n  <string name=\"msg_default_meta\">Metadata</string>\n  <string name=\"msg_default_mms_subject\">Hai</string>\n  <string name=\"msg_default_status\">Letakkan barcode di dalam kotak jendela untuk memindai.</string>\n  <string name=\"msg_default_time\">Waktu</string>\n  <string name=\"msg_default_type\">Tipe</string>\n  <string name=\"msg_encode_contents_failed\">Tidak dapat meng-encode barcode dari data yang diberikan.</string>\n  <string name=\"msg_google_books\">Google Books</string>\n  <string name=\"msg_google_product\">Google Product Search</string>\n  <string name=\"msg_google_shopper_missing\">Google Shopper belum dipasang</string>\n  <string name=\"msg_install_google_shopper\">Google Shopper menggabungkan hasil pemindaian barcode dengan harga online dan lokal, tinjauan dan lain sebagainya tanpa harus membuka browser. Apakah Anda akan mencobanya?</string>\n  <string name=\"msg_intent_failed\">Maaf, aplikasi yang diminta tidak dapat dijalankan. Mungkin ada kesalahan isi barcode.</string>\n  <string name=\"msg_redirect\">Pengalihan</string>\n  <string name=\"msg_sbc_book_not_searchable\">Maaf, buku ini tidak dapat dicari.</string>\n  <string name=\"msg_sbc_failed\">Maaf, pencarian mengalami masalah.</string>\n  <string name=\"msg_sbc_no_page_returned\">Tidak ada halaman kembali</string>\n  <string name=\"msg_sbc_page\">Halaman</string>\n  <string name=\"msg_sbc_results\">Hasil</string>\n  <string name=\"msg_sbc_searching_book\">Mencari buku\\u2026</string>\n  <string name=\"msg_sbc_snippet_unavailable\">Snippet tidak tersedia</string>\n  <string name=\"msg_sbc_unknown_page\">Halaman tidak dikenal</string>\n  <string name=\"msg_share_explanation\">Anda dapat berbagi data dengan menampilkan barcode di layar Anda dan dapat dipindai oleh phone lain.</string>\n  <string name=\"msg_share_subject_line\">Ini adalah isi barcode yang saya pindai</string>\n  <string name=\"msg_share_text\">Atau masukkan beberapa kata dan tekan Enter</string>\n  <string name=\"msg_sure\">Apakah Anda yakin?</string>\n  <string name=\"msg_unmount_usb\">Maaf, SD card tidak dapat diakses.</string>\n  <string name=\"preferences_actions_title\">Ketika barcode sudah ditemukan\\u2026</string>\n  <string name=\"preferences_auto_focus_title\">Menggunakan fokus otomatis</string>\n  <string name=\"preferences_bulk_mode_summary\">Pindai dan simpan beberapa barcode terus-menerus</string>\n  <string name=\"preferences_bulk_mode_title\">Mode pemindaian bulk</string>\n  <string name=\"preferences_copy_to_clipboard_title\">Salin ke clipboard</string>\n  <string name=\"preferences_custom_product_search_summary\" formatted=\"false\">Substitusi: %s = isi, %f = format, %t = jenis</string>\n  <string name=\"preferences_custom_product_search_title\">Pencarian URL kustom</string>\n  <string name=\"preferences_decode_1D_title\">1D barcode</string>\n  <string name=\"preferences_decode_Data_Matrix_title\">Data Matriks</string>\n  <string name=\"preferences_decode_QR_title\">QR Codes</string>\n  <string name=\"preferences_device_bug_workarounds_title\">Perangkat Bug Workarounds</string>\n  <string name=\"preferences_disable_continuous_focus_summary\">Gunakan hanya modus fokus standar</string>\n  <string name=\"preferences_disable_continuous_focus_title\">Tidak ada fokus terus menerus</string>\n  <string name=\"preferences_disable_exposure_title\">Eksposur ada</string>\n  <string name=\"preferences_front_light_summary\">Meningkatkan scanning dalam cahaya rendah pada beberapa ponsel, namun dapat menyebabkan silau. Tidak bekerja pada semua ponsel.</string>\n  <string name=\"preferences_front_light_title\">Gunakan lampu depan</string>\n  <string name=\"preferences_general_title\">Pengaturan umum</string>\n  <string name=\"preferences_name\">Pengaturan</string>\n  <string name=\"preferences_play_beep_title\">Beep</string>\n  <string name=\"preferences_remember_duplicates_summary\">Simpan beberapa pindaian dari barcode yang sama di dalam Riwayat</string>\n  <string name=\"preferences_remember_duplicates_title\">Ingat duplikasi</string>\n  <string name=\"preferences_result_title\">Hasil pengaturan</string>\n  <string name=\"preferences_scanning_title\">Ketika memindai barcode, decode\\u2026</string>\n  <string name=\"preferences_search_country\">Pencarian negara</string>\n  <string name=\"preferences_supplemental_summary\">Mencoba mendapatkan beberapa informasi mengenai isi barcode</string>\n  <string name=\"preferences_supplemental_title\">Ambil informasi lebih lanjut</string>\n  <string name=\"preferences_try_bsplus\">Cobalah Scanner Barcode+</string>\n  <string name=\"preferences_try_bsplus_summary\">Ditingkatkan dengan fitur baru dan antarmuka</string>\n  <string name=\"preferences_vibrate_title\">Bergetar</string>\n  <string name=\"result_address_book\">Informasi kontak ditemukan</string>\n  <string name=\"result_calendar\">Kalendar acara ditemukan</string>\n  <string name=\"result_email_address\">Alamat surel ditemukan</string>\n  <string name=\"result_geo\">Koordinat geografis ditemukan</string>\n  <string name=\"result_isbn\">Buku ditemukan</string>\n  <string name=\"result_product\">Produk ditemukan</string>\n  <string name=\"result_sms\">Alamat SMS ditemukan</string>\n  <string name=\"result_tel\">Nomor telepon ditemukan</string>\n  <string name=\"result_text\">Teks biasa ditemukan</string>\n  <string name=\"result_uri\">URL ditemukan</string>\n  <string name=\"result_wifi\">Konfigurasi WLAN ditemukan</string>\n  <string name=\"sbc_name\">Pencarian Google Book</string>\n  <string name=\"share_name\">Bagian melalui barcode</string>\n  <string name=\"wifi_changing_network\">Meminta koneksi ke jaringan\\u2026</string>\n  <string name=\"wifi_ssid_label\">Nama Jaringan</string>\n  <string name=\"wifi_type_label\">Tipe</string>\n</resources>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/values-it/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2012 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<resources>\n  <!-- <string name=\"app_name\">Barcode Scanner</string> -->\n  <string name=\"app_picker_name\">Applicazioni</string>\n  <string name=\"bookmark_picker_name\">Segnalibri</string>\n  <string name=\"button_add_calendar\">Aggiungi al calendario</string>\n  <string name=\"button_add_contact\">Aggiungi ai contatti</string>\n  <string name=\"button_back\">Indietro</string>\n  <string name=\"button_book_search\">Cerca libro</string>\n  <string name=\"button_cancel\">Annulla</string>\n  <string name=\"button_custom_product_search\">Ricerca personalizzata</string>\n  <string name=\"button_dial\">Componi numero</string>\n  <string name=\"button_done\">Fatto</string>\n  <string name=\"button_email\">Invia email</string>\n  <string name=\"button_get_directions\">Ottieni indirizzi</string>\n  <string name=\"button_google_shopper\">Shopper</string>\n  <string name=\"button_mms\">Invia MMS</string>\n  <string name=\"button_ok\">OK</string>\n  <string name=\"button_open_browser\">Apri browser</string>\n  <string name=\"button_product_search\">Cerca prodotto</string>\n  <string name=\"button_search_book_contents\">Cerca contenuti</string>\n  <string name=\"button_share_app\">Applicazione</string>\n  <string name=\"button_share_bookmark\">Segnalibro</string>\n  <string name=\"button_share_by_email\">Condividi tramite email</string>\n  <string name=\"button_share_by_sms\">Condividi tramite SMS</string>\n  <string name=\"button_share_clipboard\">Appunti</string>\n  <string name=\"button_share_contact\">Contatti</string>\n  <string name=\"button_show_map\">Mostra mappa</string>\n  <string name=\"button_sms\">Invia SMS</string>\n  <string name=\"button_web_search\">Ricerca web</string>\n  <string name=\"button_wifi\">Connessione a rete</string>\n  <string name=\"contents_contact\">Info contatto</string>\n  <string name=\"contents_email\">Indirizzo email</string>\n  <string name=\"contents_location\">Coordinate geografiche</string>\n  <string name=\"contents_phone\">Numero di telefono</string>\n  <string name=\"contents_sms\">Numero SMS</string>\n  <string name=\"contents_text\">Testo puro</string>\n  <string name=\"history_clear_one_history_text\">Cancella</string>\n  <string name=\"history_clear_text\">Cancella cronologia</string>\n  <string name=\"history_email_title\">Cronologia scansioni codici a barre</string>\n  <string name=\"history_empty\">Vuoto</string>\n  <string name=\"history_empty_detail\">Nessun scansioni di codici a barre sono stati registrati</string>\n  <string name=\"history_send\">Invia cronologia</string>\n  <string name=\"history_title\">Cronologia</string>\n  <string name=\"menu_encode_mecard\">Usa MECARD</string>\n  <string name=\"menu_encode_vcard\">Usa vCard</string>\n  <string name=\"menu_help\">Aiuto</string>\n  <string name=\"menu_history\">Cronologia</string>\n  <string name=\"menu_settings\">Impostazioni</string>\n  <string name=\"menu_share\">Condividi</string>\n  <string name=\"msg_bulk_mode_scanned\">Modalità di gruppo: codici a barre scansionati e salvati</string>\n  <string name=\"msg_camera_framework_bug\">Spiacenti, la fotocamera Android ha riscontrato un problema. Potrebbe essere necessario riavviare il dispositivo.</string>\n  <string name=\"msg_default_format\">Formato</string>\n  <string name=\"msg_default_meta\">Metadati</string>\n  <string name=\"msg_default_mms_subject\">Ciao</string>\n  <string name=\"msg_default_status\">Posiziona un codice a barre dentro il mirino rettangolare per la scansione.</string>\n  <string name=\"msg_default_time\">Tempo</string>\n  <string name=\"msg_default_type\">Tipo</string>\n  <string name=\"msg_encode_contents_failed\">Impossibile codificare un codice a barre dai dati forniti.</string>\n  <string name=\"msg_google_books\">Google Libri</string>\n  <string name=\"msg_google_product\">Google Shopping</string>\n  <string name=\"msg_google_shopper_missing\">Google Shopper non è installato</string>\n  <string name=\"msg_install_google_shopper\">Google Shopper combina la scansione dei codici a barre con prezzi locali e online, recensioni e altro senza dover aprire il browser. Vuoi provare?</string>\n  <string name=\"msg_intent_failed\">Spiacenti, l\\'applicazione richiesta non può essere avviata. Il contenuto del codice a barre può essere non valido.</string>\n  <string name=\"msg_redirect\">Inoltra</string>\n  <string name=\"msg_sbc_book_not_searchable\">Spiacenti, questo libro non è ricercabile.</string>\n  <string name=\"msg_sbc_failed\">Spiacenti, la ricerca ha avuto un problema.</string>\n  <string name=\"msg_sbc_no_page_returned\">Nessuna pagina restitiuta</string>\n  <string name=\"msg_sbc_page\">Pagina</string>\n  <string name=\"msg_sbc_results\">Risultati</string>\n  <string name=\"msg_sbc_searching_book\">Ricerca libro\\u2026</string>\n  <string name=\"msg_sbc_snippet_unavailable\">Ritaglio non disponibile</string>\n  <string name=\"msg_sbc_unknown_page\">Pagina sconosciuta</string>\n  <string name=\"msg_share_explanation\">Puoi condividere i dati mostrando un codice a barre sullo schermo e facendo la scansione con un altro telefono.</string>\n  <string name=\"msg_share_subject_line\">Questo è il contenuto di un codice a barre di prova</string>\n  <string name=\"msg_share_text\">O digitare un testo</string>\n  <string name=\"msg_sure\">Sei sicuro?</string>\n  <string name=\"msg_unmount_usb\">Spiacenti, la scheda SD non è accessibile.</string>\n  <string name=\"preferences_actions_title\">Quando viene trovato un codice a barre\\u2026</string>\n  <string name=\"preferences_auto_focus_title\">Utilizzare messa a fuoco automatica</string>\n  <string name=\"preferences_bulk_mode_summary\">Scansiona e salva diversi codici a barre in sequenza</string>\n  <string name=\"preferences_bulk_mode_title\">Modalità scansione di gruppo</string>\n  <string name=\"preferences_copy_to_clipboard_title\">Copia negli appunti</string>\n  <string name=\"preferences_custom_product_search_summary\" formatted=\"false\">Sostituzioni: %s = contenuti, %f = formato, %t = tipo</string>\n  <string name=\"preferences_custom_product_search_title\">URL ricerca personalizzata</string>\n  <string name=\"preferences_decode_1D_title\">Codice a barre 1D</string>\n  <string name=\"preferences_decode_Data_Matrix_title\">Matrice dati</string>\n  <string name=\"preferences_decode_QR_title\">Codici QR</string>\n  <string name=\"preferences_device_bug_workarounds_title\">Soluzioni alternative dispositivo Bug</string>\n  <string name=\"preferences_disable_continuous_focus_summary\">Utilizzare solo modalità standard messa a fuoco</string>\n  <string name=\"preferences_disable_continuous_focus_title\">No continua attenzione</string>\n  <string name=\"preferences_disable_exposure_title\">Nessuna esposizione</string>\n  <string name=\"preferences_front_light_summary\">Migliora la scansione con poca luminosità su alcuni telefoni, ma può provocare abbagliamento. Non funziona su tutti i telefoni.</string>\n  <string name=\"preferences_front_light_title\">Usa luce frontale</string>\n  <string name=\"preferences_general_title\">Impostazioni generali</string>\n  <string name=\"preferences_name\">Impostazioni</string>\n  <string name=\"preferences_play_beep_title\">Suona</string>\n  <string name=\"preferences_remember_duplicates_summary\">Mantieni scansioni multiple del codice a barre nella stessa Cronologia</string>\n  <string name=\"preferences_remember_duplicates_title\">Ricorda duplicati</string>\n  <string name=\"preferences_result_title\">Impostazioni risultato</string>\n  <string name=\"preferences_scanning_title\">Durante la scansione di codici a barre, decodifica\\u2026</string>\n  <string name=\"preferences_search_country\">Cerca paese</string>\n  <string name=\"preferences_supplemental_summary\">Prova a cercare ulteriori informazioni sul contenuto del codice a barre</string>\n  <string name=\"preferences_supplemental_title\">Recupera altre informazioni</string>\n  <string name=\"preferences_try_bsplus\">Prova Barcode Scanner+</string>\n  <string name=\"preferences_try_bsplus_summary\">Arricchito con nuove funzionalità e interfaccia</string>\n  <string name=\"preferences_vibrate_title\">Vibra</string>\n  <string name=\"result_address_book\">Info contatto trovata</string>\n  <string name=\"result_calendar\">Evento calendario trovato</string>\n  <string name=\"result_email_address\">Indirizzo email trovato</string>\n  <string name=\"result_geo\">Coordinate geografiche trovate</string>\n  <string name=\"result_isbn\">Libro trovato</string>\n  <string name=\"result_product\">Prodotto trovato</string>\n  <string name=\"result_sms\">Numero SMS trovato</string>\n  <string name=\"result_tel\">Numero di telefono trovato</string>\n  <string name=\"result_text\">Testo puro trovato</string>\n  <string name=\"result_uri\">URL trovato</string>\n  <string name=\"result_wifi\">Configurazione WLAN trovata</string>\n  <string name=\"sbc_name\">Ricerca Google Book</string>\n  <string name=\"share_name\">Condividi tramite codice a barre</string>\n  <string name=\"wifi_changing_network\">Richiesta di connessione alla rete\\u2026</string>\n  <string name=\"wifi_ssid_label\">Nome rete</string>\n  <string name=\"wifi_type_label\">Tipo</string>\n</resources>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/values-iw/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2012 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<resources>\n  <!-- <string name=\"app_name\">סורק ברקודים</string> -->\n  <string name=\"app_picker_name\">יישומים</string>\n  <string name=\"bookmark_picker_name\">סימניות</string>\n  <string name=\"button_add_calendar\">הוסף ללוח שנה</string>\n  <string name=\"button_add_contact\">הוספת איש קשר</string>\n  <string name=\"button_back\">חזרה</string>\n  <string name=\"button_book_search\">חיפוש ספר</string>\n  <string name=\"button_cancel\">ביטול</string>\n  <string name=\"button_custom_product_search\">חיפוש מותאם אישית</string>\n  <string name=\"button_dial\">חייג מספר</string>\n  <string name=\"button_done\">סיים</string>\n  <string name=\"button_email\">שלח דואר אלקטרוני</string>\n  <string name=\"button_get_directions\">קבל הוראות הגעה</string>\n  <string name=\"button_google_shopper\">Shopper</string>\n  <string name=\"button_mms\">שלח הודעת מולטימדיה</string>\n  <string name=\"button_ok\">אישור</string>\n  <string name=\"button_open_browser\">פתח את הדפדפן</string>\n  <string name=\"button_product_search\">חיפוש מוצר</string>\n  <string name=\"button_search_book_contents\">חיפוש בתוכן</string>\n  <string name=\"button_share_app\">יישום</string>\n  <string name=\"button_share_bookmark\">סימניה</string>\n  <string name=\"button_share_by_email\">שתף בדואר אלקטרוני</string>\n  <string name=\"button_share_by_sms\">שתף בהודעה</string>\n  <string name=\"button_share_clipboard\">לוח עריכה</string>\n  <string name=\"button_share_contact\">איש קשר</string>\n  <string name=\"button_show_map\">הצג מפה</string>\n  <string name=\"button_sms\">שלח הודעה</string>\n  <string name=\"button_web_search\">חיפוש באינטרנט</string>\n  <string name=\"button_wifi\">התחבר לרשת</string>\n  <string name=\"contents_contact\">פרטי איש קשר</string>\n  <string name=\"contents_email\">כתובת דואר אלקטרוני</string>\n  <string name=\"contents_location\">קואורדינטות גאוגרפיות</string>\n  <string name=\"contents_phone\">מספר טלפון</string>\n  <string name=\"contents_sms\">כתובת SMS</string>\n  <string name=\"contents_text\">טקסט רגיל</string>\n  <string name=\"history_clear_one_history_text\">נקה</string>\n  <string name=\"history_clear_text\">נקה היסטוריה</string>\n  <string name=\"history_email_title\">היסטוריית סורק הברקודים</string>\n  <string name=\"history_empty\">ריק</string>\n  <string name=\"history_empty_detail\">ברקודים לא נרשמו</string>\n  <string name=\"history_send\">שלח היסטוריה</string>\n  <string name=\"history_title\">היסטוריה</string>\n  <string name=\"menu_encode_mecard\">השתמש MECARD</string>\n  <string name=\"menu_encode_vcard\">השתמש vCard</string>\n  <string name=\"menu_help\">עזרה</string>\n  <string name=\"menu_history\">היסטוריה</string>\n  <string name=\"menu_settings\">הגדרות</string>\n  <string name=\"menu_share\">שתף</string>\n  <string name=\"msg_bulk_mode_scanned\">מצב קבוצה: ברקוד נסרק ונשמר</string>\n  <string name=\"msg_camera_framework_bug\">סליחה, מצלמת האנדרואיד נתקלה בבעיה. ייתכן שיהיה עליך להפעיל מחדש את המכשיר.</string>\n  <string name=\"msg_default_format\">פורמט</string>\n  <string name=\"msg_default_meta\">מטה-נתונים</string>\n  <string name=\"msg_default_mms_subject\">היי</string>\n  <string name=\"msg_default_status\">הצב ברקוד בתוך המלבן כדי לסרוק אותו.</string>\n  <string name=\"msg_default_time\">זמן</string>\n  <string name=\"msg_default_type\">סוג</string>\n  <string name=\"msg_encode_contents_failed\">לא היתה אפשרות לקודד ברקוד מהנתונים שסופקו.</string>\n  <string name=\"msg_google_books\">Google Books</string>\n  <string name=\"msg_google_product\">Google Product Search</string>\n  <string name=\"msg_google_shopper_missing\">Google Shopper לא מותקן.</string>\n  <string name=\"msg_install_google_shopper\">Google Shopper משלבת סריקת ברקודים עם מחירים מקוונים, חוות דעת ועוד בלי לפתוח את הדפדפן. האם ברצונך לנסות זאת?</string>\n  <string name=\"msg_intent_failed\">סליחה, לא ניתן להפעיל את היישום המבוקש. ייתכן שתוכן הברקוד לא תקין.</string>\n  <string name=\"msg_redirect\">נתב מחדש</string>\n  <string name=\"msg_sbc_book_not_searchable\">סליחה, ספר זה אינו ניתן לחיפוש.</string>\n  <string name=\"msg_sbc_failed\">סליחה, החיפוש נתקל בבעיה.</string>\n  <string name=\"msg_sbc_no_page_returned\">לא הוחזר דף</string>\n  <string name=\"msg_sbc_page\">דף</string>\n  <string name=\"msg_sbc_results\">תוצאות</string>\n  <string name=\"msg_sbc_searching_book\">מחפש ספר\\u2026</string>\n  <string name=\"msg_sbc_snippet_unavailable\">גזיר לא זמין</string>\n  <string name=\"msg_sbc_unknown_page\">דף לא ידוע</string>\n  <string name=\"msg_share_explanation\">באפשרותך לשתף נתונים על-ידי הצגת ברקוד על המסך וסריקתו עם טלפון אחר.</string>\n  <string name=\"msg_share_subject_line\">הנה התוכן של הברקוד שסרקתי</string>\n  <string name=\"msg_share_text\">או הקלד טקסט כלשהו</string>\n  <string name=\"msg_sure\">האם אתה בטוח?</string>\n  <string name=\"msg_unmount_usb\">סליחה, כרטיס הזכרון אינו נגיש.</string>\n  <string name=\"preferences_actions_title\">כאשר ברקוד נמצא\\u2026</string>\n  <string name=\"preferences_auto_focus_title\">להשתמש במיקוד האוטומטי</string>\n  <string name=\"preferences_bulk_mode_summary\">סורק ושומר ברקודים באופן רציף</string>\n  <string name=\"preferences_bulk_mode_title\">מצב סריקה מרובה</string>\n  <string name=\"preferences_copy_to_clipboard_title\">העתק ללוח</string>\n  <string name=\"preferences_custom_product_search_summary\" formatted=\"false\">החלפות: s% = התוכן, f% = הפורמט, t% = סוג</string>\n  <string name=\"preferences_custom_product_search_title\">כתובת לחיפוש מותאם אישית</string>\n  <string name=\"preferences_decode_1D_title\">ברקודים חד מימדיים</string>\n  <string name=\"preferences_decode_Data_Matrix_title\">מטריצת נתונים</string>\n  <string name=\"preferences_decode_QR_title\">קודי QR</string>\n  <string name=\"preferences_device_bug_workarounds_title\">באג במכשיר דרכים לעקיפת הבעיה</string>\n  <string name=\"preferences_disable_continuous_focus_summary\">השתמש רק במצב רגיל פוקוס</string>\n  <string name=\"preferences_disable_continuous_focus_title\">המיקוד לא רציפה</string>\n  <string name=\"preferences_disable_exposure_title\">אין חשיפה</string>\n  <string name=\"preferences_front_light_summary\">משפר את הסריקה בתאורה נמוכה בטלפונים מסוימים, אך עשוי לגרום לסנוור. לא עובד בכל הטלפונים.</string>\n  <string name=\"preferences_front_light_title\">השתמש באור הקדמי</string>\n  <string name=\"preferences_general_title\">הגדרות כלליות</string>\n  <string name=\"preferences_name\">הגדרות</string>\n  <string name=\"preferences_play_beep_title\">צפצוף</string>\n  <string name=\"preferences_remember_duplicates_summary\">אחסן מספר סריקות של אותו הברקוד בהיסטוריה</string>\n  <string name=\"preferences_remember_duplicates_title\">זכור כפילויות</string>\n  <string name=\"preferences_result_title\">הגדרות תוצאה</string>\n  <string name=\"preferences_scanning_title\">בעת סריקת ברקודים, קודד\\u2026</string>\n  <string name=\"preferences_search_country\">חיפוש הארץ</string>\n  <string name=\"preferences_supplemental_summary\">נסה למצא מידע נוסף על תוכן הברקוד</string>\n  <string name=\"preferences_supplemental_title\">מצא מידע נוסף</string>\n  <string name=\"preferences_try_bsplus\">נסה סורק ברקודים+</string>\n  <string name=\"preferences_try_bsplus_summary\">משופר עם תכונות וממשק חדשים</string>\n  <string name=\"preferences_vibrate_title\">רטט</string>\n  <string name=\"result_address_book\">נמצא מידע של איש קשר</string>\n  <string name=\"result_calendar\">נמצא אירוע</string>\n  <string name=\"result_email_address\">נמצאה כתובת דוא\"ל</string>\n  <string name=\"result_geo\">נמצאו קואורדינטות גיאוגרפיות</string>\n  <string name=\"result_isbn\">נמצא ספר</string>\n  <string name=\"result_product\">נמצא מוצר</string>\n  <string name=\"result_sms\">נמצאה כתובת הודעה</string>\n  <string name=\"result_tel\">נמצא מספר טלפון</string>\n  <string name=\"result_text\">נמצא טקסט</string>\n  <string name=\"result_uri\">נמצאה כתובת אינטרנט</string>\n  <string name=\"result_wifi\">נמצאו הגדרות רשת אל חוטית</string>\n  <string name=\"sbc_name\">Google חיפוש ספרים</string>\n  <string name=\"share_name\">שתף באמצעות ברקוד</string>\n  <string name=\"wifi_changing_network\">בקשת חיבור לרשת \\u2026</string>\n  <string name=\"wifi_ssid_label\">שם רשת</string>\n  <string name=\"wifi_type_label\">סוג</string>\n</resources>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/values-ja/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2012 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<resources>\n  <!-- <string name=\"app_name\">QRコードスキャナー</string> -->\n  <string name=\"app_picker_name\">アプリケーション</string>\n  <string name=\"bookmark_picker_name\">ブックマーク</string>\n  <string name=\"button_add_calendar\">カレンダーに追加</string>\n  <string name=\"button_add_contact\">連絡先を追加</string>\n  <string name=\"button_back\">戻る</string>\n  <string name=\"button_book_search\">書籍を検索</string>\n  <string name=\"button_cancel\">キャンセル</string>\n  <string name=\"button_custom_product_search\">カスタム サーチ</string>\n  <string name=\"button_dial\">発信</string>\n  <string name=\"button_done\">完了</string>\n  <string name=\"button_email\">メール送信</string>\n  <string name=\"button_get_directions\">道案内</string>\n  <string name=\"button_google_shopper\">Google ショッパー</string>\n  <string name=\"button_mms\">MMS 送信</string>\n  <string name=\"button_ok\">OK</string>\n  <string name=\"button_open_browser\">ブラウザ起動</string>\n  <string name=\"button_product_search\">商品検索</string>\n  <string name=\"button_search_book_contents\">書籍の内容を検索する</string>\n  <string name=\"button_share_app\">アプリを共有</string>\n  <string name=\"button_share_bookmark\">ブックマーク</string>\n  <string name=\"button_share_by_email\">メールで共有</string>\n  <string name=\"button_share_by_sms\">SMSで共有</string>\n  <string name=\"button_share_clipboard\">クリップボードを共有</string>\n  <string name=\"button_share_contact\">連絡先を共有</string>\n  <string name=\"button_show_map\">地図を表示する</string>\n  <string name=\"button_sms\">SMS送信</string>\n  <string name=\"button_web_search\">インターネット検索</string>\n  <string name=\"button_wifi\">ネットワークに接続</string>\n  <string name=\"contents_contact\">連絡先</string>\n  <string name=\"contents_email\">メールアドレス</string>\n  <string name=\"contents_location\">位置情報</string>\n  <string name=\"contents_phone\">電話番号</string>\n  <string name=\"contents_sms\">SMSアドレス</string>\n  <string name=\"contents_text\">テキストデータ</string>\n  <string name=\"history_clear_one_history_text\">削除</string>\n  <string name=\"history_clear_text\">履歴の削除</string>\n  <string name=\"history_email_title\">QRコードスキャナーの履歴</string>\n  <string name=\"history_empty\">空</string>\n  <string name=\"history_empty_detail\">QRコードスキャンが記録されていません</string>\n  <string name=\"history_send\">履歴を送信</string>\n  <string name=\"history_title\">履歴</string>\n  <string name=\"menu_encode_mecard\">MECARDを使用</string>\n  <string name=\"menu_encode_vcard\">vCardを使用</string>\n  <string name=\"menu_help\">ヘルプ</string>\n  <string name=\"menu_history\">履歴</string>\n  <string name=\"menu_settings\">設定</string>\n  <string name=\"menu_share\">共有</string>\n  <string name=\"msg_bulk_mode_scanned\">連続モード:スキャンして保存しました</string>\n  <string name=\"msg_camera_framework_bug\">Androidのカメラに問題が発生しました。デバイスを再起動する必要があります。</string>\n  <string name=\"msg_default_format\">フォーマット</string>\n  <string name=\"msg_default_meta\">メタデータ</string>\n  <string name=\"msg_default_mms_subject\">こんにちは！</string>\n  <string name=\"msg_default_status\">QRコードを画面の読み取り範囲内に写すとスキャンします。</string>\n  <string name=\"msg_default_time\">時間</string>\n  <string name=\"msg_default_type\">タイプ</string>\n  <string name=\"msg_encode_contents_failed\">このデータからQRコードを作成できませんでした。</string>\n  <string name=\"msg_google_books\">Google書籍</string>\n  <string name=\"msg_google_product\">Googleショッピング</string>\n  <string name=\"msg_google_shopper_missing\">Google ショッパーがインストールされていません</string>\n  <string name=\"msg_install_google_shopper\">Google ショッパーは、ブラウザを使わなくても、価格やレビューなどを見ることができます。試しますか？</string>\n  <string name=\"msg_intent_failed\">指定されたアプリケーションを起動できませんでした。QRコードの内容が無効である可能性があります。</string>\n  <string name=\"msg_redirect\">リダイレクト</string>\n  <string name=\"msg_sbc_book_not_searchable\">この書籍は検索できません。</string>\n  <string name=\"msg_sbc_failed\">検索中に問題が発生しました。</string>\n  <string name=\"msg_sbc_no_page_returned\">検索結果はありません</string>\n  <string name=\"msg_sbc_page\">ページ</string>\n  <string name=\"msg_sbc_results\">結果</string>\n  <string name=\"msg_sbc_searching_book\">書籍を検索中</string>\n  <string name=\"msg_sbc_snippet_unavailable\">要約文はありません</string>\n  <string name=\"msg_sbc_unknown_page\">不明なページ</string>\n  <string name=\"msg_share_explanation\">画面にQRコードを表示させ、別の端末でスキャンすれば データを共有することができます。</string>\n  <string name=\"msg_share_subject_line\">スキャンしたQRコードの内容を送信します。</string>\n  <string name=\"msg_share_text\">またはテキストを入力してください</string>\n  <string name=\"msg_sure\">よろしいですか？</string>\n  <string name=\"msg_unmount_usb\">SDカードにアクセスできません。</string>\n  <string name=\"preferences_actions_title\">QRコード発見時</string>\n  <string name=\"preferences_auto_focus_title\">ｵｰﾄﾌｫｰｶｽを使用</string>\n  <string name=\"preferences_bulk_mode_summary\">QRコードを連続スキャンして保存します</string>\n  <string name=\"preferences_bulk_mode_title\">連続モードでスキャン</string>\n  <string name=\"preferences_copy_to_clipboard_title\">ｸﾘｯﾌﾟﾎﾞｰﾄﾞにｺﾋﾟｰ</string>\n  <string name=\"preferences_custom_product_search_summary\" formatted=\"false\">置換：％s=コンテンツ、％f=フォーマット、％t=タイプ</string>\n  <string name=\"preferences_custom_product_search_title\">カスタム商品サーチ URL</string>\n  <string name=\"preferences_decode_1D_title\">1Dバーコードを読み取る</string>\n  <string name=\"preferences_decode_Data_Matrix_title\">ﾃﾞｰﾀﾏﾄﾘｯｸｽｺｰﾄﾞを読み取る</string>\n  <string name=\"preferences_decode_QR_title\">QRコードを読み取る</string>\n  <string name=\"preferences_device_bug_workarounds_title\">デバイスの不具合回避</string>\n  <string name=\"preferences_disable_continuous_focus_summary\">標準フォーカスモードのみ使用します</string>\n  <string name=\"preferences_disable_continuous_focus_title\">連続フォーカスしない</string>\n  <string name=\"preferences_disable_exposure_title\">露出しない</string>\n  <string name=\"preferences_front_light_summary\">暗い場所でのスキャンを向上させるためフロントライトを有効にします</string>\n  <string name=\"preferences_front_light_title\">フロントライト</string>\n  <string name=\"preferences_general_title\">一般設定</string>\n  <string name=\"preferences_name\">設定</string>\n  <string name=\"preferences_play_beep_title\">通知音</string>\n  <string name=\"preferences_remember_duplicates_summary\">同じQRコードでも履歴に記録する</string>\n  <string name=\"preferences_remember_duplicates_title\">重複する履歴の記録</string>\n  <string name=\"preferences_result_title\">検索結果の設定</string>\n  <string name=\"preferences_scanning_title\">QRコードスキャン時</string>\n  <string name=\"preferences_search_country\">検索国コード</string>\n  <string name=\"preferences_supplemental_summary\">QRコード内容の詳細情報を取得します</string>\n  <string name=\"preferences_supplemental_title\">詳細情報を取得</string>\n  <string name=\"preferences_try_bsplus\">QRコード+を試す</string>\n  <string name=\"preferences_try_bsplus_summary\">新機能と強化されたインターフェース</string>\n  <string name=\"preferences_vibrate_title\">バイブ</string>\n  <string name=\"result_address_book\">連絡先がヒットしました</string>\n  <string name=\"result_calendar\">カレンダーの予定がヒットしました</string>\n  <string name=\"result_email_address\">メールアドレスがヒットしました</string>\n  <string name=\"result_geo\">地理座標がヒットしました</string>\n  <string name=\"result_isbn\">書籍がヒットしました</string>\n  <string name=\"result_product\">商品がヒットしました</string>\n  <string name=\"result_sms\">SMS 連絡先がヒットしました</string>\n  <string name=\"result_tel\">電話番号がヒットしました</string>\n  <string name=\"result_text\">テキストデータがヒットしました</string>\n  <string name=\"result_uri\">URL がヒットしました</string>\n  <string name=\"result_wifi\">ネットワーク構成がヒットしました</string>\n  <string name=\"sbc_name\">Google ブックス</string>\n  <string name=\"share_name\">QRコードで共有する</string>\n  <string name=\"wifi_changing_network\">ネットワークへ接続しています\\u2026</string>\n  <string name=\"wifi_ssid_label\">ネットワーク名</string>\n  <string name=\"wifi_type_label\">タイプ</string>\n</resources>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/values-ko/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2012 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<resources>\n  <!-- <string name=\"app_name\">바코드 스캐너</string> -->\n  <string name=\"app_picker_name\">어플리케이션</string>\n  <string name=\"bookmark_picker_name\">즐겨찾기</string>\n  <string name=\"button_add_calendar\">일정에 추가하기</string>\n  <string name=\"button_add_contact\">연락처에 추가하기</string>\n  <string name=\"button_back\">뒤로</string>\n  <string name=\"button_book_search\">책 검색</string>\n  <string name=\"button_cancel\">취소</string>\n  <string name=\"button_custom_product_search\">사용자 지정 검색</string>\n  <string name=\"button_dial\">전화 걸기</string>\n  <string name=\"button_done\">완료</string>\n  <string name=\"button_email\">이메일 보내기</string>\n  <string name=\"button_get_directions\">방향을 찾기</string>\n  <string name=\"button_google_shopper\">Shopper</string>\n  <string name=\"button_mms\">MMS 보내기</string>\n  <string name=\"button_ok\">확인</string>\n  <string name=\"button_open_browser\">웹브라우저로 열기</string>\n  <string name=\"button_product_search\">제품 검색</string>\n  <string name=\"button_search_book_contents\">책 내용 검색</string>\n  <string name=\"button_share_app\">어플리케이션</string>\n  <string name=\"button_share_bookmark\">즐겨찾기</string>\n  <string name=\"button_share_by_email\">이메일로 공유</string>\n  <string name=\"button_share_by_sms\">SMS로 공유</string>\n  <string name=\"button_share_clipboard\">복사된 항목</string>\n  <string name=\"button_share_contact\">연락처</string>\n  <string name=\"button_show_map\">지도 보기</string>\n  <string name=\"button_sms\">SMS 보내기</string>\n  <string name=\"button_web_search\">인터넷 검색</string>\n  <string name=\"button_wifi\">네트워크에 연결</string>\n  <string name=\"contents_contact\">연락처 정보</string>\n  <string name=\"contents_email\">이메일 주소</string>\n  <string name=\"contents_location\">GPS 좌표</string>\n  <string name=\"contents_phone\">전화번호</string>\n  <string name=\"contents_sms\">전화번호</string>\n  <string name=\"contents_text\">단문</string>\n  <string name=\"history_clear_one_history_text\">삭제</string>\n  <string name=\"history_clear_text\">기록 삭제</string>\n  <string name=\"history_email_title\">바코드 스캐너 기록</string>\n  <string name=\"history_empty\">빈</string>\n  <string name=\"history_empty_detail\">아무 바코드 스캔이 기록되지 않았습니다</string>\n  <string name=\"history_send\">기록 보내기</string>\n  <string name=\"history_title\">기록</string>\n  <string name=\"menu_encode_mecard\">MECARD를 사용하여</string>\n  <string name=\"menu_encode_vcard\">vCard를 사용하여</string>\n  <string name=\"menu_help\">도움말</string>\n  <string name=\"menu_history\">기록</string>\n  <string name=\"menu_settings\">설정</string>\n  <string name=\"menu_share\">공유</string>\n  <string name=\"msg_bulk_mode_scanned\">일괄 스캔 모드: 바코드가 읽히고 저장됩니다.</string>\n  <string name=\"msg_camera_framework_bug\">죄송합니다. 기기의 카메라에 오류가 생겼습니다. 기기를 재시작 해야될 수도 있습니다.</string>\n  <string name=\"msg_default_format\">포맷</string>\n  <string name=\"msg_default_meta\">메타데이터</string>\n  <string name=\"msg_default_mms_subject\">안녕하세요</string>\n  <string name=\"msg_default_status\">바코드를 사각형 안에 비춰주세요.</string>\n  <string name=\"msg_default_time\">시간</string>\n  <string name=\"msg_default_type\">종류</string>\n  <string name=\"msg_encode_contents_failed\">주어진 데이터로 바코드를 만들지 못하였습니다.</string>\n  <string name=\"msg_google_books\">Google 도서</string>\n  <string name=\"msg_google_product\">Google 상품 검색</string>\n  <string name=\"msg_google_shopper_missing\">Google Shopper가 설치되어 있지 않습니다.</string>\n  <string name=\"msg_install_google_shopper\">Google Shopper는 바코드 스캐닝을 이용하여 인터넷을 열지 않고 가격, 리뷰 등을 열람하는 기능을 제공합니다. 사용해 보시겠습니까?</string>\n  <string name=\"msg_intent_failed\">죄송합니다. 어플리케이션이 실행되지 않습니다. 바코드 내용이 잘못 되었을 수도 있습니다.</string>\n  <string name=\"msg_redirect\">리디렉션</string>\n  <string name=\"msg_sbc_book_not_searchable\">죄송합니다. 이 책은 검색이 되지 않습니다.</string>\n  <string name=\"msg_sbc_failed\">죄송합니다. 검색 도중 문제가 발생했습니다.</string>\n  <string name=\"msg_sbc_no_page_returned\">수신받은 페이지가 없습니다.</string>\n  <string name=\"msg_sbc_page\">페이지</string>\n  <string name=\"msg_sbc_results\">결과</string>\n  <string name=\"msg_sbc_searching_book\">책 검색중\\u2026</string>\n  <string name=\"msg_sbc_snippet_unavailable\">내용이 열람되지 않습니다.</string>\n  <string name=\"msg_sbc_unknown_page\">알수 없는 페이지</string>\n  <string name=\"msg_share_explanation\">해당 기기의 바코드를 다른 기기로 스캔해서 데이터를 공유할 수 있습니다.</string>\n  <string name=\"msg_share_subject_line\">제가 스캔한 바코드 목록입니다.</string>\n  <string name=\"msg_share_text\">입력하거나 텍스트</string>\n  <string name=\"msg_sure\">계속하시겠습니까?</string>\n  <string name=\"msg_unmount_usb\">죄송합니다. SD카드를 사용할 수 없습니다.</string>\n  <string name=\"preferences_actions_title\">바코드를 스캔했을때\\u2026</string>\n  <string name=\"preferences_auto_focus_title\">자동 초점을 사용하여</string>\n  <string name=\"preferences_bulk_mode_summary\">다수의 바코드를 스캔하고 저장합니다.</string>\n  <string name=\"preferences_bulk_mode_title\">일괄 스캔 모드</string>\n  <string name=\"preferences_copy_to_clipboard_title\">복사하기</string>\n  <string name=\"preferences_custom_product_search_summary\" formatted=\"false\">자리 표시자: %s = 내용, %f = 포맷, %t = 유형</string>\n  <string name=\"preferences_custom_product_search_title\">사용자 지정 검색 주소</string>\n  <string name=\"preferences_decode_1D_title\">1차원 바코드를 읽기</string>\n  <string name=\"preferences_decode_Data_Matrix_title\">데이터 행렬(Data Matrix)을 해석하기</string>\n  <string name=\"preferences_decode_QR_title\">QR 코드를 읽기</string>\n  <string name=\"preferences_device_bug_workarounds_title\">장치 버그 해결</string>\n  <string name=\"preferences_disable_continuous_focus_summary\">전용 표준 초점 모드를 사용</string>\n  <string name=\"preferences_disable_continuous_focus_title\">아무 연속 초점 없음</string>\n  <string name=\"preferences_disable_exposure_title\">더 노출하지</string>\n  <string name=\"preferences_front_light_summary\">특정 기기에서는 어두운 환경에서의 스캐닝 기능을 향상 시키지만 너무 밝을 수도 있습니다. 모든 기기에서 작동되지 않습니다.</string>\n  <string name=\"preferences_front_light_title\">플래시 사용하기</string>\n  <string name=\"preferences_general_title\">일반 설정</string>\n  <string name=\"preferences_name\">설정</string>\n  <string name=\"preferences_play_beep_title\">전자음</string>\n  <string name=\"preferences_remember_duplicates_summary\">복수의 같은 바코드를 기록에 저장</string>\n  <string name=\"preferences_remember_duplicates_title\">중복된 바코드 저장</string>\n  <string name=\"preferences_result_title\">결과 설정</string>\n  <string name=\"preferences_scanning_title\">바코드 스캐닝 시\\u2026</string>\n  <string name=\"preferences_search_country\">국가별 검색</string>\n  <string name=\"preferences_supplemental_summary\">바코드 내용에 대한 자세한 정보를 검색하려고</string>\n  <string name=\"preferences_supplemental_title\">검색 상세 정보</string>\n  <string name=\"preferences_try_bsplus\">바코드 스캐너를 사용해보십시오 +</string>\n  <string name=\"preferences_try_bsplus_summary\">새로운 기능 및 인터페이스 개선</string>\n  <string name=\"preferences_vibrate_title\">진동</string>\n  <string name=\"result_address_book\">연락처 정보를 찾았습니다</string>\n  <string name=\"result_calendar\">일정 이벤트를 찾았습니다</string>\n  <string name=\"result_email_address\">이메일 주소를 찾았습니다</string>\n  <string name=\"result_geo\">GPS 좌표를 찾았습니다</string>\n  <string name=\"result_isbn\">책을 찾았습니다</string>\n  <string name=\"result_product\">제품을 찾았습니</string>\n  <string name=\"result_sms\">전화번호를 찾았습니다</string>\n  <string name=\"result_tel\">전화번호를 찾았습니다</string>\n  <string name=\"result_text\">단문을 찾았습니다</string>\n  <string name=\"result_uri\">인터넷 주소를 찾았습니다</string>\n  <string name=\"result_wifi\">WiFi 설정을 찾았습니다</string>\n  <string name=\"sbc_name\">구글 책 검색</string>\n  <string name=\"share_name\">바코드로 공유</string>\n  <string name=\"wifi_changing_network\">네트워크에 연결을 요청\\u2026</string>\n  <string name=\"wifi_ssid_label\">네트워크 이름</string>\n  <string name=\"wifi_type_label\">종류</string>\n</resources>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/values-nl/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2012 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<resources>\n  <!-- <string name=\"app_name\">Barcode Scanner</string> -->\n  <string name=\"app_picker_name\">Applicaties</string>\n  <string name=\"bookmark_picker_name\">Bladwijzers</string>\n  <string name=\"button_add_calendar\">Toevoegen aan agenda</string>\n  <string name=\"button_add_contact\">Toevoegen aan contactpersonen</string>\n  <string name=\"button_back\">Terug</string>\n  <string name=\"button_book_search\">Boeken zoeken</string>\n  <string name=\"button_cancel\">Annuleren</string>\n  <string name=\"button_custom_product_search\">Aangepast zoeken</string>\n  <string name=\"button_dial\">Nummer bellen</string>\n  <string name=\"button_done\">Gereed</string>\n  <string name=\"button_email\">E-mail versturen</string>\n  <string name=\"button_get_directions\">Routebeschrijving opvragen</string>\n  <string name=\"button_google_shopper\">Shopper</string>\n  <string name=\"button_mms\">MMS versturen</string>\n  <string name=\"button_ok\">OK</string>\n  <string name=\"button_open_browser\">Browser openen</string>\n  <string name=\"button_product_search\">Producten zoeken</string>\n  <string name=\"button_search_book_contents\">Boekinhoud zoeken</string>\n  <string name=\"button_share_app\">Applicatie</string>\n  <string name=\"button_share_bookmark\">Bladwijzer</string>\n  <string name=\"button_share_by_email\">Delen via e-mail</string>\n  <string name=\"button_share_by_sms\">Delen via sms</string>\n  <string name=\"button_share_clipboard\">Klembord</string>\n  <string name=\"button_share_contact\">Contactpersoon</string>\n  <string name=\"button_show_map\">Kaart weergeven</string>\n  <string name=\"button_sms\">Sms versturen</string>\n  <string name=\"button_web_search\">Zoeken op internet</string>\n  <string name=\"button_wifi\">Verbinden met netwerk</string>\n  <string name=\"contents_contact\">Contactpersooninformatie</string>\n  <string name=\"contents_email\">E-mailadres</string>\n  <string name=\"contents_location\">Geografische coördinaten</string>\n  <string name=\"contents_phone\">Telefoonnummer</string>\n  <string name=\"contents_sms\">Sms-adres</string>\n  <string name=\"contents_text\">Platte tekst</string>\n  <string name=\"history_clear_one_history_text\">Wissen</string>\n  <string name=\"history_clear_text\">Geschiedenis wissen</string>\n  <string name=\"history_email_title\">Barcode Scanner-geschiedenis</string>\n  <string name=\"history_empty\">Leeg</string>\n  <string name=\"history_empty_detail\">Er zijn geen barcodes gescand</string>\n  <string name=\"history_send\">Geschiedenis versturen</string>\n  <string name=\"history_title\">Geschiedenis</string>\n  <string name=\"menu_encode_mecard\">MECARD gebruiken</string>\n  <string name=\"menu_encode_vcard\">vCard gebruiken</string>\n  <string name=\"menu_help\">Help</string>\n  <string name=\"menu_history\">Geschiedenis</string>\n  <string name=\"menu_settings\">Instellingen</string>\n  <string name=\"menu_share\">Delen</string>\n  <string name=\"msg_bulk_mode_scanned\">Bulkmodus: barcode gescand en opgeslagen</string>\n  <string name=\"msg_camera_framework_bug\">Sorry, er is een probleem met de Android-camera. Probeer je telefoon opnieuw op te starten.</string>\n  <string name=\"msg_default_format\">Formaat</string>\n  <string name=\"msg_default_meta\">Metadata</string>\n  <string name=\"msg_default_mms_subject\">Hallo</string>\n  <string name=\"msg_default_status\">Plaats een barcode binnen de rechthoek om deze te scannen.</string>\n  <string name=\"msg_default_time\">Tijd</string>\n  <string name=\"msg_default_type\">Type</string>\n  <string name=\"msg_encode_contents_failed\">Kan geen barcode genereren op basis van de opgegeven gegevens.</string>\n  <string name=\"msg_google_books\">Google Boeken</string>\n  <string name=\"msg_google_product\">Google Product Search</string>\n  <string name=\"msg_google_shopper_missing\">Google Shopper is niet geïnstalleerd</string>\n  <string name=\"msg_install_google_shopper\">Google Shopper combineert het scannen van barcodes met online en lokale prijzen, recensies en meer zonder de browser te openen. Wil je dit proberen?</string>\n  <string name=\"msg_intent_failed\">Sorry, de opgevraagde applicatie kan niet worden gestart. De barcode is mogelijk ongeldig.</string>\n  <string name=\"msg_redirect\">Doorverwijzing</string>\n  <string name=\"msg_sbc_book_not_searchable\">Sorry, dit boek kan niet worden doorzocht.</string>\n  <string name=\"msg_sbc_failed\">Sorry, er is een fout opgetreden bij het zoeken.</string>\n  <string name=\"msg_sbc_no_page_returned\">Geen pagina ontvangen</string>\n  <string name=\"msg_sbc_page\">Pagina</string>\n  <string name=\"msg_sbc_results\">Resultaten</string>\n  <string name=\"msg_sbc_searching_book\">Boek doorzoeken\\u2026</string>\n  <string name=\"msg_sbc_snippet_unavailable\">Fragment niet beschikbaar</string>\n  <string name=\"msg_sbc_unknown_page\">Onbekende pagina</string>\n  <string name=\"msg_share_explanation\">Je kunt gegevens delen door een barcode op je scherm te laten zien en deze met een andere telefoon te scannen.</string>\n  <string name=\"msg_share_subject_line\">Hier is de inhoud van een barcode die ik heb gescand</string>\n  <string name=\"msg_share_text\">Of typ wat tekst en druk op Enter</string>\n  <string name=\"msg_sure\">Weet je het zeker?</string>\n  <string name=\"msg_unmount_usb\">Sorry, de SD-kaart is niet toegankelijk.</string>\n  <string name=\"preferences_actions_title\">Wanneer een barcode is gevonden\\u2026</string>\n  <string name=\"preferences_auto_focus_title\">Autofocus gebruiken</string>\n  <string name=\"preferences_bulk_mode_summary\">Continu barcodes scannen en opslaan</string>\n  <string name=\"preferences_bulk_mode_title\">Bulkmodus</string>\n  <string name=\"preferences_copy_to_clipboard_title\">Kopiëren naar klembord</string>\n  <string name=\"preferences_custom_product_search_summary\" formatted=\"false\">Vervanginen: %s = inhoud, %f = formaat, %t = type</string>\n  <string name=\"preferences_custom_product_search_title\">Aangepaste zoek-URL</string>\n  <string name=\"preferences_decode_1D_title\">1D-barcodes</string>\n  <string name=\"preferences_decode_Data_Matrix_title\">Datamatrix</string>\n  <string name=\"preferences_decode_QR_title\">QR-codes</string>\n  <string name=\"preferences_device_bug_workarounds_title\">Apparaat Bug Tijdelijke oplossingen</string>\n  <string name=\"preferences_disable_continuous_focus_summary\">Gebruik alleen standaard focus modus</string>\n  <string name=\"preferences_disable_continuous_focus_title\">Geen continue focus</string>\n  <string name=\"preferences_disable_exposure_title\">Geen blootstelling</string>\n  <string name=\"preferences_front_light_summary\">Verbetert het scannen bij weinig licht bij sommige telefoons, maar kan schittering veroorzaken. Werkt niet op alle telefoons.</string>\n  <string name=\"preferences_front_light_title\">Flitser gebruiken</string>\n  <string name=\"preferences_general_title\">Algemene instellingen</string>\n  <string name=\"preferences_name\">Instellingen</string>\n  <string name=\"preferences_play_beep_title\">Piepen</string>\n  <string name=\"preferences_remember_duplicates_summary\">Meerdere scans van dezelfde barcode opslaan in de geschiedenis</string>\n  <string name=\"preferences_remember_duplicates_title\">Dubbele onthouden</string>\n  <string name=\"preferences_result_title\">Instellingen voor resultaten</string>\n  <string name=\"preferences_scanning_title\">Bij het scannen van barcodes, decodeer\\u2026</string>\n  <string name=\"preferences_search_country\">Zoeken op land</string>\n  <string name=\"preferences_supplemental_summary\">Meer informatie over de inhoud van de barcode proberen op te halen</string>\n  <string name=\"preferences_supplemental_title\">Meer informatie ophalen</string>\n  <string name=\"preferences_try_bsplus\">Probeer Barcode Scanner+</string>\n  <string name=\"preferences_try_bsplus_summary\">Uitgebreid met nieuwe functies en interface</string>\n  <string name=\"preferences_vibrate_title\">Trillen</string>\n  <string name=\"result_address_book\">Contactpersooninformatie gevonden</string>\n  <string name=\"result_calendar\">Agendagebeurtenis gevonden</string>\n  <string name=\"result_email_address\">E-mailadres gevonden</string>\n  <string name=\"result_geo\">Geografische coördinaten gevonden</string>\n  <string name=\"result_isbn\">Boek gevonden</string>\n  <string name=\"result_product\">Product gevonden</string>\n  <string name=\"result_sms\">Sms-adres gevonden</string>\n  <string name=\"result_tel\">Telefoonnummer gevonden</string>\n  <string name=\"result_text\">Platte tekst gevonden</string>\n  <string name=\"result_uri\">URL gevonden</string>\n  <string name=\"result_wifi\">WLAN-configuratie gevonden</string>\n  <string name=\"sbc_name\">Zoeken op Google Boeken</string>\n  <string name=\"share_name\">Delen via barcode</string>\n  <string name=\"wifi_changing_network\">Verbinding met netwerk opvragen\\u2026</string>\n  <string name=\"wifi_ssid_label\">Netwerknaam</string>\n  <string name=\"wifi_type_label\">Type</string>\n</resources>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/values-pl/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2012 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<resources>\n  <!-- <string name=\"app_name\">Barcode Scanner</string> -->\n  <string name=\"app_picker_name\">Aplikacje</string>\n  <string name=\"bookmark_picker_name\">Zakładki</string>\n  <string name=\"button_add_calendar\">Dodaj do kalendarza</string>\n  <string name=\"button_add_contact\">Dodaj kontakt</string>\n  <string name=\"button_back\">Wstecz</string>\n  <string name=\"button_book_search\">Szukaj książek</string>\n  <string name=\"button_cancel\">Anuluj</string>\n  <string name=\"button_custom_product_search\">Wyszukiwanie indywidualne</string>\n  <string name=\"button_dial\">Wykręć numer</string>\n  <string name=\"button_done\">Gotowe</string>\n  <string name=\"button_email\">Wyślij email</string>\n  <string name=\"button_get_directions\">Otrzymaj wskazówki</string>\n  <string name=\"button_google_shopper\">Shopper</string>\n  <string name=\"button_mms\">Wyślij MMS</string>\n  <string name=\"button_ok\">OK</string>\n  <string name=\"button_open_browser\">Otwórz przeglądarkę</string>\n  <string name=\"button_product_search\">Szukaj produktów</string>\n  <string name=\"button_search_book_contents\">Przeszukaj zawartość</string>\n  <string name=\"button_share_app\">Aplikacja</string>\n  <string name=\"button_share_bookmark\">Zakładka</string>\n  <string name=\"button_share_by_email\">Udostępnij przez email</string>\n  <string name=\"button_share_by_sms\">Udostępnij przez SMS</string>\n  <string name=\"button_share_clipboard\">Schowek</string>\n  <string name=\"button_share_contact\">Kontakt</string>\n  <string name=\"button_show_map\">Pokaż mapę</string>\n  <string name=\"button_sms\">Wyślij SMS</string>\n  <string name=\"button_web_search\">Szukaj w sieci</string>\n  <string name=\"button_wifi\">Podłączyć do sieci</string>\n  <string name=\"contents_contact\">Informacje o kontakcie</string>\n  <string name=\"contents_email\">Adres email</string>\n  <string name=\"contents_location\">Współrzędne geograficzne</string>\n  <string name=\"contents_phone\">Numer telefonu</string>\n  <string name=\"contents_sms\">Adres SMS</string>\n  <string name=\"contents_text\">Zwykły tekst</string>\n  <string name=\"history_clear_one_history_text\">Wyczyść</string>\n  <string name=\"history_clear_text\">Wyczyść historię</string>\n  <string name=\"history_email_title\">Historia Skanera Kodów Paskowych</string>\n  <string name=\"history_empty\">Pusty</string>\n  <string name=\"history_empty_detail\">Brak skanowania kodów kreskowych zostały zarejestrowane</string>\n  <string name=\"history_send\">Wyślij historię</string>\n  <string name=\"history_title\">Historia</string>\n  <string name=\"menu_encode_mecard\">Użyj MECARD</string>\n  <string name=\"menu_encode_vcard\">Użyj vCard</string>\n  <string name=\"menu_help\">Pomoc</string>\n  <string name=\"menu_history\">Historia</string>\n  <string name=\"menu_settings\">Ustawienia</string>\n  <string name=\"menu_share\">Udostępnij</string>\n  <string name=\"msg_bulk_mode_scanned\">Tryb zbiorcze: skanowania kodów kreskowych i zapisaniu</string>\n  <string name=\"msg_camera_framework_bug\">Przepraszamy, aparat Android napotkał problem. Może wystąpić potrzeba ponownego uruchomienia urządzenia.</string>\n  <string name=\"msg_default_format\">Format</string>\n  <string name=\"msg_default_meta\">Metadanych</string>\n  <string name=\"msg_default_mms_subject\">Cześć</string>\n  <string name=\"msg_default_status\">Umieść kod paskowy w prostokącie wizjera aby zeskanować.</string>\n  <string name=\"msg_default_time\">Czas</string>\n  <string name=\"msg_default_type\">Typ</string>\n  <string name=\"msg_encode_contents_failed\">Nie można zakodować kodu paskowego z dostarczonych danych.</string>\n  <string name=\"msg_google_books\">Google Książki</string>\n  <string name=\"msg_google_product\">Wyszukiwarka produktów Google</string>\n  <string name=\"msg_google_shopper_missing\">Google Shopper nie jest zainstalowany</string>\n  <string name=\"msg_install_google_shopper\">Google Shopper łączy skanowanie kodów paskowych z cenami, recenzjami, itp bez otwierania przeglądarki. Czy chciał/a byś go wypróbować?</string>\n  <string name=\"msg_intent_failed\">Przepraszamy, żadana aplikacja nie może zostać uruchomiona. Zawartość kodu paskowego może być nieprawidłowa.</string>\n  <string name=\"msg_redirect\">Przekierowanie</string>\n  <string name=\"msg_sbc_book_not_searchable\">Przepraszamy, ta książka nie jest przeszukiwalna.</string>\n  <string name=\"msg_sbc_failed\">Przepraszamy, wyszukiwania napotkało problem.</string>\n  <string name=\"msg_sbc_no_page_returned\">Nie zwrócono żadnej strony</string>\n  <string name=\"msg_sbc_page\">Strona</string>\n  <string name=\"msg_sbc_results\">Wyniki</string>\n  <string name=\"msg_sbc_searching_book\">Przeszukiwanie książki\\u2026</string>\n  <string name=\"msg_sbc_snippet_unavailable\">Wycinek niedostępny</string>\n  <string name=\"msg_sbc_unknown_page\">Nieznana strona</string>\n  <string name=\"msg_share_explanation\">Możesz udostępniać dane wyświetlając kod paskowy na swoim ekranie, skanując go innym telefonem.</string>\n  <string name=\"msg_share_subject_line\">Oto zawartość kodu paskowego który został zeskanowany</string>\n  <string name=\"msg_share_text\">Albo wpisz tekst</string>\n  <string name=\"msg_sure\">Czy na pewno?</string>\n  <string name=\"msg_unmount_usb\">Niestety, karta SD nie jest dostępny.</string>\n  <string name=\"preferences_actions_title\">Kiedy kod paskowy zostaje odnaleziony\\u2026</string>\n  <string name=\"preferences_auto_focus_title\">Ustawić ostrość</string>\n  <string name=\"preferences_bulk_mode_summary\">Skanowanie i zapisywanie wielu kodów kreskowych ciągle</string>\n  <string name=\"preferences_bulk_mode_title\">Luzem tryb skanowania</string>\n  <string name=\"preferences_copy_to_clipboard_title\">Kopiuj do schowka</string>\n  <string name=\"preferences_custom_product_search_summary\" formatted=\"false\">Zastępstwa: %s = zawartość, %f = format, %t = typ</string>\n  <string name=\"preferences_custom_product_search_title\">Własny URL wyszukiwania</string>\n  <string name=\"preferences_decode_1D_title\">Dekoduj kody 1D</string>\n  <string name=\"preferences_decode_Data_Matrix_title\">Dekoduj Decode Matrix</string>\n  <string name=\"preferences_decode_QR_title\">Dekoduj kody QR</string>\n  <string name=\"preferences_device_bug_workarounds_title\">Obejścia błędów urządzeń</string>\n  <string name=\"preferences_disable_continuous_focus_summary\">Używaj tylko standardowego trybu ostrości</string>\n  <string name=\"preferences_disable_continuous_focus_title\">Nie ciągły nacisk</string>\n  <string name=\"preferences_disable_exposure_title\">Żadna ekspozycja</string>\n  <string name=\"preferences_front_light_summary\">Polepsza skanowanie przy małej ilości światła w niektórych telefonach, ale może powodować odbłysk. Nie działa na wszystkich telefonach.</string>\n  <string name=\"preferences_front_light_title\">Używaj lampy frontowej</string>\n  <string name=\"preferences_general_title\">Ustawienia ogólne</string>\n  <string name=\"preferences_name\">Ustawienia</string>\n  <string name=\"preferences_play_beep_title\">Piszcz</string>\n  <string name=\"preferences_remember_duplicates_summary\">Przechowywanie wielu skanowanie kodów kreskowych w tej samej historii</string>\n  <string name=\"preferences_remember_duplicates_title\">Pamiętaj, duplikaty</string>\n  <string name=\"preferences_result_title\">Ustawienia rezultatów</string>\n  <string name=\"preferences_scanning_title\">Podczas skanowania kodów kreskowych\\u2026</string>\n  <string name=\"preferences_search_country\">Szukaj kraju</string>\n  <string name=\"preferences_supplemental_summary\">Prosimy spróbować wyszukać więcej informacji na temat kodów kreskowych treści</string>\n  <string name=\"preferences_supplemental_title\">Pobierz więcej informacji</string>\n  <string name=\"preferences_try_bsplus\">Spróbuj Barcode Scanner+</string>\n  <string name=\"preferences_try_bsplus_summary\">Wzbogacony o nowe funkcje i interfejs</string>\n  <string name=\"preferences_vibrate_title\">Wibruj</string>\n  <string name=\"result_address_book\">Znaleziono dane kontaktu</string>\n  <string name=\"result_calendar\">Znaleziono wydarzenie kalendarza</string>\n  <string name=\"result_email_address\">Znaleziono adres email</string>\n  <string name=\"result_geo\">Znaleziono współrzędne geograficzne</string>\n  <string name=\"result_isbn\">Znaleziono książkę</string>\n  <string name=\"result_product\">Znaleziono produkt</string>\n  <string name=\"result_sms\">Znaleziono adres SMS</string>\n  <string name=\"result_tel\">Znaleziono numer telefonu</string>\n  <string name=\"result_text\">Znaleziono zwykły tekst</string>\n  <string name=\"result_uri\">Znaleziono URL</string>\n  <string name=\"result_wifi\">Znaleziono konfiguracji sieci</string>\n  <string name=\"sbc_name\">Wyszukiwanie książek Google</string>\n  <string name=\"share_name\">Udostępnij przez kod paskowy</string>\n  <string name=\"wifi_changing_network\">Ubiegającymi się o przyłączenie do sieci\\u2026</string>\n  <string name=\"wifi_ssid_label\">Nazwa sieci</string>\n  <string name=\"wifi_type_label\">Typ</string>\n</resources>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/values-pt/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2012 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<resources>\n  <!-- <string name=\"app_name\">Barcode Scanner</string> -->\n  <string name=\"app_picker_name\">Aplicações</string>\n  <string name=\"bookmark_picker_name\">Favoritos</string>\n  <string name=\"button_add_calendar\">Adicionar ao calendário</string>\n  <string name=\"button_add_contact\">Adicionar contacto</string>\n  <string name=\"button_back\">Voltar</string>\n  <string name=\"button_book_search\">Procurar livro</string>\n  <string name=\"button_cancel\">Cancelar</string>\n  <string name=\"button_custom_product_search\">Pesquisa Personalizada</string>\n  <string name=\"button_dial\">Marcar número</string>\n  <string name=\"button_done\">Feito</string>\n  <string name=\"button_email\">Enviar e-mail</string>\n  <string name=\"button_get_directions\">Obter direcções</string>\n  <string name=\"button_google_shopper\">Shopper</string>\n  <string name=\"button_mms\">Enviar MMS</string>\n  <string name=\"button_ok\">OK</string>\n  <string name=\"button_open_browser\">Abrir navegador</string>\n  <string name=\"button_product_search\">Procurar produto</string>\n  <string name=\"button_search_book_contents\">Pesquisar conteúdos</string>\n  <string name=\"button_share_app\">Aplicação</string>\n  <string name=\"button_share_bookmark\">Favorito</string>\n  <string name=\"button_share_by_email\">Partilhar via e-mail</string>\n  <string name=\"button_share_by_sms\">Partilhar via SMS</string>\n  <string name=\"button_share_clipboard\">Área de transferência</string>\n  <string name=\"button_share_contact\">Contacto</string>\n  <string name=\"button_show_map\">Visualizar mapa</string>\n  <string name=\"button_sms\">Enviar SMS</string>\n  <string name=\"button_web_search\">Pesquisa na Web</string>\n  <string name=\"button_wifi\">Conectar à rede</string>\n  <string name=\"contents_contact\">Informação de contacto</string>\n  <string name=\"contents_email\">Endereço de e-mail</string>\n  <string name=\"contents_location\">Coordenadas geográficas</string>\n  <string name=\"contents_phone\">Número de telefone</string>\n  <string name=\"contents_sms\">Endereço SMS</string>\n  <string name=\"contents_text\">Texto simples</string>\n  <string name=\"history_clear_one_history_text\">Limpar</string>\n  <string name=\"history_clear_text\">Limpar histórico</string>\n  <string name=\"history_email_title\">Histórico do Barcode Scanner</string>\n  <string name=\"history_empty\">Vazio</string>\n  <string name=\"history_empty_detail\">Não código de barras foram registrados</string>\n  <string name=\"history_send\">Enviar histórico</string>\n  <string name=\"history_title\">Histórico</string>\n  <string name=\"menu_encode_mecard\">Usar MECARD</string>\n  <string name=\"menu_encode_vcard\">Usar vCard</string>\n  <string name=\"menu_help\">Ajuda</string>\n  <string name=\"menu_history\">Histórico</string>\n  <string name=\"menu_settings\">Definições</string>\n  <string name=\"menu_share\">Partilhar</string>\n  <string name=\"msg_bulk_mode_scanned\">Modo em massa: código de barras lido e guardado</string>\n  <string name=\"msg_camera_framework_bug\">Desculpe, a câmera do Android encontrou um problema. Poderá precisar de reiniciar o dispositivo.</string>\n  <string name=\"msg_default_format\">Formato</string>\n  <string name=\"msg_default_meta\">Metadata</string>\n  <string name=\"msg_default_mms_subject\">Olá</string>\n  <string name=\"msg_default_status\">Alinhar código de barras com o exemplo para ser lido.</string>\n  <string name=\"msg_default_time\">Tempo</string>\n  <string name=\"msg_default_type\">Tipo</string>\n  <string name=\"msg_encode_contents_failed\">Não foi possível codificar o código de barradas apartir dos dados fornecidos.</string>\n  <string name=\"msg_google_books\">Google Livros</string>\n  <string name=\"msg_google_product\">Google Product Search</string>\n  <string name=\"msg_google_shopper_missing\">Google Shopper não está instalado.</string>\n  <string name=\"msg_install_google_shopper\">Google Shopper combina leituras de códigos de barras com preços online e locais, análises e mais sem abrir o navegador. Gostaria de experimentar?</string>\n  <string name=\"msg_intent_failed\">Desculpe, a aplicação solicitada não pode ser iniciada. O conteúdo do código de barras poderá ser inválido.</string>\n  <string name=\"msg_redirect\">Redirecionar</string>\n  <string name=\"msg_sbc_book_not_searchable\">Desculpe, este livro não é pesquisável.</string>\n  <string name=\"msg_sbc_failed\">Desculpe, foi encontrado um erro na pesquisa.</string>\n  <string name=\"msg_sbc_no_page_returned\">Nenhuma página obtida</string>\n  <string name=\"msg_sbc_page\">Página</string>\n  <string name=\"msg_sbc_results\">Resultados</string>\n  <string name=\"msg_sbc_searching_book\">A procurar livro\\u2026</string>\n  <string name=\"msg_sbc_snippet_unavailable\">Trecho não disponível</string>\n  <string name=\"msg_sbc_unknown_page\">Página desconhecida</string>\n  <string name=\"msg_share_explanation\">Pode partilhar dados exibindo um código de barras no seu ecrã e lendo-o com outro telemóvel</string>\n  <string name=\"msg_share_subject_line\">Aqui estão os conteúdos do código de barras lido</string>\n  <string name=\"msg_share_text\">Ou introduza algum texto e pressione Enter</string>\n  <string name=\"msg_sure\">Tem a certeza?</string>\n  <string name=\"msg_unmount_usb\">Desculpe, o cartão SD não está disponível.</string>\n  <string name=\"preferences_actions_title\">Quando o código de barras é encontrado\\u2026</string>\n  <string name=\"preferences_auto_focus_title\">Usar foco automático</string>\n  <string name=\"preferences_bulk_mode_summary\">Ler e guardar códigos de barras continuamente</string>\n  <string name=\"preferences_bulk_mode_title\">Modo em massa</string>\n  <string name=\"preferences_copy_to_clipboard_title\">Copiar para a área de transferência</string>\n  <string name=\"preferences_custom_product_search_summary\" formatted=\"false\">Substituições: %s = conteúdos, %f = formato, %t = tipo</string>\n  <string name=\"preferences_custom_product_search_title\">Pesquisa personalizada de URL</string>\n  <string name=\"preferences_decode_1D_title\">Código de barras 1D</string>\n  <string name=\"preferences_decode_Data_Matrix_title\">Data Matrix</string>\n  <string name=\"preferences_decode_QR_title\">QR Codes</string>\n  <string name=\"preferences_device_bug_workarounds_title\">Soluções alternativas de dispositivos com erros</string>\n  <string name=\"preferences_disable_continuous_focus_summary\">Use apenas o modo de focagem padrão</string>\n  <string name=\"preferences_disable_continuous_focus_title\">No foco contínuo</string>\n  <string name=\"preferences_disable_exposure_title\">Nenhuma exposição</string>\n  <string name=\"preferences_front_light_summary\">Melhora a leitura em luz fraca em alguns telefones, mas pode causar clarões. Não disponível em certos dispositivos.</string>\n  <string name=\"preferences_front_light_title\">Usar luz da frente</string>\n  <string name=\"preferences_general_title\">Definições Gerais</string>\n  <string name=\"preferences_name\">Definições</string>\n  <string name=\"preferences_play_beep_title\">Apitar</string>\n  <string name=\"preferences_remember_duplicates_summary\">Guardar pesquisas múltiplas do mesmo código de barras no histórico</string>\n  <string name=\"preferences_remember_duplicates_title\">Lembrar duplicados</string>\n  <string name=\"preferences_result_title\">Definições do resultado</string>\n  <string name=\"preferences_scanning_title\">Quando procurar por códigos de barras, descodificar\\u2026</string>\n  <string name=\"preferences_search_country\">País busca</string>\n  <string name=\"preferences_supplemental_summary\">Tentar recuperar mais informação sobre os conteúdos dos códigos de barras</string>\n  <string name=\"preferences_supplemental_title\">Recuperar mais informação</string>\n  <string name=\"preferences_try_bsplus\">Tente Barcode Scanner+</string>\n  <string name=\"preferences_try_bsplus_summary\">Aprimorado com novos recursos e interface</string>\n  <string name=\"preferences_vibrate_title\">Vibrar</string>\n  <string name=\"result_address_book\">Info de contacto encontrada</string>\n  <string name=\"result_calendar\">Evento de calendário encontrado</string>\n  <string name=\"result_email_address\">Endereço de e-mail encontrado</string>\n  <string name=\"result_geo\">Coordenadas geográficas encontradas</string>\n  <string name=\"result_isbn\">Livro encontrado</string>\n  <string name=\"result_product\">Produto encontrado</string>\n  <string name=\"result_sms\">Endereço SMS encontrado</string>\n  <string name=\"result_tel\">Número de telefone encontrado</string>\n  <string name=\"result_text\">Texto simples encontrado</string>\n  <string name=\"result_uri\">URL encontrado</string>\n  <string name=\"result_wifi\">Configuração WLAN encontrados</string>\n  <string name=\"sbc_name\">Pesquisa Google Book</string>\n  <string name=\"share_name\">Partilhar por código de barras</string>\n  <string name=\"wifi_changing_network\">Solicitando ligação à rede\\u2026</string>\n  <string name=\"wifi_ssid_label\">Nome da Rede</string>\n  <string name=\"wifi_type_label\">Tipo</string>\n</resources>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/values-ru/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2012 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<resources>\n  <!-- <string name=\"app_name\">Сканер штрих-кодов</string> -->\n  <string name=\"app_picker_name\">Программы</string>\n  <string name=\"bookmark_picker_name\">Закладки</string>\n  <string name=\"button_add_calendar\">Добавить в календарь</string>\n  <string name=\"button_add_contact\">Добавить контакт</string>\n  <string name=\"button_back\">Назад</string>\n  <string name=\"button_book_search\">Поиск книги</string>\n  <string name=\"button_cancel\">Отмена</string>\n  <string name=\"button_custom_product_search\">Пользовательский поиск</string>\n  <string name=\"button_dial\">Набрать номер</string>\n  <string name=\"button_done\">Готово</string>\n  <string name=\"button_email\">Отправить e-mail</string>\n  <string name=\"button_get_directions\">Проложить маршрут</string>\n  <string name=\"button_google_shopper\">Shopper</string>\n  <string name=\"button_mms\">Послать MMS</string>\n  <string name=\"button_ok\">OK</string>\n  <string name=\"button_open_browser\">Открыть браузер</string>\n  <string name=\"button_product_search\">Поиск товара</string>\n  <string name=\"button_search_book_contents\">Поиск содержания книги</string>\n  <string name=\"button_share_app\">Программа</string>\n  <string name=\"button_share_bookmark\">Закладка</string>\n  <string name=\"button_share_by_email\">Поделиться через эл. почту</string>\n  <string name=\"button_share_by_sms\">Поделиться через SMS</string>\n  <string name=\"button_share_clipboard\">Буфер обмена</string>\n  <string name=\"button_share_contact\">Контакт</string>\n  <string name=\"button_show_map\">Показать карту</string>\n  <string name=\"button_sms\">Отправить SMS</string>\n  <string name=\"button_web_search\">Поиск в интернете</string>\n  <string name=\"button_wifi\">Подключиться к сети</string>\n  <string name=\"contents_contact\">Контактная информация</string>\n  <string name=\"contents_email\">Адрес эл. почты</string>\n  <string name=\"contents_location\">Географические координаты</string>\n  <string name=\"contents_phone\">Номер телефона</string>\n  <string name=\"contents_sms\">Адрес для SMS</string>\n  <string name=\"contents_text\">Текст</string>\n  <string name=\"history_clear_one_history_text\">Удалить</string>\n  <string name=\"history_clear_text\">Удалить историю</string>\n  <string name=\"history_email_title\">История сканирования</string>\n  <string name=\"history_empty\">Пусто</string>\n  <string name=\"history_empty_detail\">Нет сохраненных штрих-кодов</string>\n  <string name=\"history_send\">Отправить историю</string>\n  <string name=\"history_title\">История</string>\n  <string name=\"menu_encode_mecard\">Используйте MECARD</string>\n  <string name=\"menu_encode_vcard\">Используйте vCard</string>\n  <string name=\"menu_help\">Помощь</string>\n  <string name=\"menu_history\">История</string>\n  <string name=\"menu_settings\">Настройки</string>\n  <string name=\"menu_share\">Поделиться</string>\n  <string name=\"msg_bulk_mode_scanned\">Массовый режим: сохранять историю сканирования</string>\n  <string name=\"msg_camera_framework_bug\">К сожалению, возникла ошибка камеры. Вам может потребоваться перезагрузка устройства.</string>\n  <string name=\"msg_default_format\">Формат</string>\n  <string name=\"msg_default_meta\">Метаданные</string>\n  <string name=\"msg_default_mms_subject\">Привет</string>\n  <string name=\"msg_default_status\">Чтобы сканировать штрих-код, поместите его в прямоугольник видоискателя.</string>\n  <string name=\"msg_default_time\">Время</string>\n  <string name=\"msg_default_type\">Тип</string>\n  <string name=\"msg_encode_contents_failed\">Невозможно создать штрих-код из текущих данных.</string>\n  <string name=\"msg_google_books\">Google Books</string>\n  <string name=\"msg_google_product\">Google Product Search</string>\n  <string name=\"msg_google_shopper_missing\">Приложение \"Google Shopper\" не установлено</string>\n  <string name=\"msg_install_google_shopper\">Приложение \"Google Shopper\" объединяет сканирование штрих-кодов с online-поиском товаров, цен, отзывов и т.д., не открывая браузер. Хотите попробовать?</string>\n  <string name=\"msg_intent_failed\">К сожалению, запрошенное приложение не может быть запущенно. Возможно, содержимое штрих-кода повреждено.</string>\n  <string name=\"msg_redirect\">Переслать</string>\n  <string name=\"msg_sbc_book_not_searchable\">К сожалению, поиск книги не удался.</string>\n  <string name=\"msg_sbc_failed\">К сожалению, возникла ошибка поиска.</string>\n  <string name=\"msg_sbc_no_page_returned\">Ни одна страница не возвращена.</string>\n  <string name=\"msg_sbc_page\">Страница</string>\n  <string name=\"msg_sbc_results\">Результаты</string>\n  <string name=\"msg_sbc_searching_book\">Поиск книги\\u2026</string>\n  <string name=\"msg_sbc_snippet_unavailable\">Фрагмент недоступен</string>\n  <string name=\"msg_sbc_unknown_page\">Неизвестная страница</string>\n  <string name=\"msg_share_explanation\">Вы можете поделиться данными, сканируя штрих-код с вашего экрана другим телефоном.</string>\n  <string name=\"msg_share_subject_line\">Данные отсканированных Вами штрих-кодов</string>\n  <string name=\"msg_share_text\">Или введите текст</string>\n  <string name=\"msg_sure\">Вы уверены?</string>\n  <string name=\"msg_unmount_usb\">К сожалению, SD-карта не доступна.</string>\n  <string name=\"preferences_actions_title\">Когда штрих-код найден\\u2026</string>\n  <string name=\"preferences_auto_focus_title\">Использовать автофокус</string>\n  <string name=\"preferences_bulk_mode_summary\">Постоянно сканировать и сохранять штрих-коды</string>\n  <string name=\"preferences_bulk_mode_title\">Массовое сканирование</string>\n  <string name=\"preferences_copy_to_clipboard_title\">Копировать в буфер обмена</string>\n  <string name=\"preferences_custom_product_search_summary\" formatted=\"false\">Замены: %s = содержание, %f = формат, %t = тип</string>\n  <string name=\"preferences_custom_product_search_title\">URL пользовательского поиска</string>\n  <string name=\"preferences_decode_1D_title\">Распознавать линейные штрих-коды</string>\n  <string name=\"preferences_decode_Data_Matrix_title\">Распознавать Data Matrix</string>\n  <string name=\"preferences_decode_QR_title\">Распознавать QR-коды</string>\n  <string name=\"preferences_device_bug_workarounds_title\">Обходные пути устройства ошибка</string>\n  <string name=\"preferences_disable_continuous_focus_summary\">Используйте только стандартный режим фокусировки</string>\n  <string name=\"preferences_disable_continuous_focus_title\">Нет постоянное внимание</string>\n  <string name=\"preferences_disable_exposure_title\">Нет экспозиции</string>\n  <string name=\"preferences_front_light_summary\">Улучшает распознавание в условиях низкой освещенности, но может вызвать блики. Работает не на всех устройствах.</string>\n  <string name=\"preferences_front_light_title\">Фонарик</string>\n  <string name=\"preferences_general_title\">Общие настройки</string>\n  <string name=\"preferences_name\">Настройки</string>\n  <string name=\"preferences_play_beep_title\">Пищать</string>\n  <string name=\"preferences_remember_duplicates_summary\">Сохранять в истории результат сканирования одного и того же штрих-кода</string>\n  <string name=\"preferences_remember_duplicates_title\">Запоминать дубликаты</string>\n  <string name=\"preferences_result_title\">Настройки результатов</string>\n  <string name=\"preferences_scanning_title\">При сканировании штрих-кодов\\u2026</string>\n  <string name=\"preferences_search_country\">Поиск страны</string>\n  <string name=\"preferences_supplemental_summary\">Показывать подробную информацию о штрих-коде</string>\n  <string name=\"preferences_supplemental_title\">Подробности</string>\n  <string name=\"preferences_try_bsplus\">Попробуйте Сканер штрих-кодов+</string>\n  <string name=\"preferences_try_bsplus_summary\">Расширение с новыми функциями и интерфейсом</string>\n  <string name=\"preferences_vibrate_title\">Вибрировать</string>\n  <string name=\"result_address_book\">Найдены контактные данные</string>\n  <string name=\"result_calendar\">Найдено событие для календаря</string>\n  <string name=\"result_email_address\">Найден адрес эл. почты</string>\n  <string name=\"result_geo\">Найдены географические координаты</string>\n  <string name=\"result_isbn\">Найдена книга</string>\n  <string name=\"result_product\">Найден товар</string>\n  <string name=\"result_sms\">Найден адрес для SMS</string>\n  <string name=\"result_tel\">Найден номер телефона</string>\n  <string name=\"result_text\">Найден текст</string>\n  <string name=\"result_uri\">Найден URL</string>\n  <string name=\"result_wifi\">Найдена конфигурация сети</string>\n  <string name=\"sbc_name\">Поиск книг Google</string>\n  <string name=\"share_name\">Поделиться штрих-кодом</string>\n  <string name=\"wifi_changing_network\">Запрос подключения к сети\\u2026</string>\n  <string name=\"wifi_ssid_label\">Имя сети</string>\n  <string name=\"wifi_type_label\">Тип</string>\n</resources>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/values-sk/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2012 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<resources>\n  <!-- <string name=\"app_name\">Barcode Scanner</string> -->\n  <string name=\"app_picker_name\">Aplikácie</string>\n  <string name=\"bookmark_picker_name\">Záložky</string>\n  <string name=\"button_add_calendar\">Pridať do kalendára</string>\n  <string name=\"button_add_contact\">Pridať kontakt</string>\n  <string name=\"button_back\">Späť</string>\n  <string name=\"button_book_search\">Hľadať knihu</string>\n  <string name=\"button_cancel\">Zrušiť</string>\n  <string name=\"button_custom_product_search\">Prispôsobené vyhľadávanie</string>\n  <string name=\"button_dial\">Vytočiť číslo</string>\n  <string name=\"button_done\">Hotovo</string>\n  <string name=\"button_email\">Poslať e-mail</string>\n  <string name=\"button_get_directions\">Získať pokyny</string>\n  <string name=\"button_google_shopper\">Nakupovanie</string>\n  <string name=\"button_mms\">Poslať MMS</string>\n  <string name=\"button_ok\">OK</string>\n  <string name=\"button_open_browser\">Otvoriť prehliadač</string>\n  <string name=\"button_product_search\">Vyhľadať produkt</string>\n  <string name=\"button_search_book_contents\">Vyhľadať obsah</string>\n  <string name=\"button_share_app\">Aplikácia</string>\n  <string name=\"button_share_bookmark\">Záložka</string>\n  <string name=\"button_share_by_email\">Zdieľať cez e-mail</string>\n  <string name=\"button_share_by_sms\">Zdieľať cez SMS</string>\n  <string name=\"button_share_clipboard\">Schránka</string>\n  <string name=\"button_share_contact\">Kontakt</string>\n  <string name=\"button_show_map\">Zobraziť mapu</string>\n  <string name=\"button_sms\">Poslať SMS</string>\n  <string name=\"button_web_search\">Hľadať na webe</string>\n  <string name=\"button_wifi\">Pripojiť sa sieti</string>\n  <string name=\"contents_contact\">Informácie o kontakte</string>\n  <string name=\"contents_email\">E-mailová adresa</string>\n  <string name=\"contents_location\">Geografické súradnice</string>\n  <string name=\"contents_phone\">Telefónne číslo</string>\n  <string name=\"contents_sms\">SMS adresa</string>\n  <string name=\"contents_text\">Obyčajný text</string>\n  <string name=\"history_clear_one_history_text\">Vymazať</string>\n  <string name=\"history_clear_text\">Vymazať históriu</string>\n  <string name=\"history_email_title\">História Barcode Scanneru</string>\n  <string name=\"history_empty\">Prázdna</string>\n  <string name=\"history_empty_detail\">Žiadne čiarové kódy neboli zaznamenané</string>\n  <string name=\"history_send\">Poslať históriu</string>\n  <string name=\"history_title\">História</string>\n  <string name=\"menu_encode_mecard\">Použiť MECARD</string>\n  <string name=\"menu_encode_vcard\">Použiť vCard</string>\n  <string name=\"menu_help\">Nápoveda</string>\n  <string name=\"menu_history\">História</string>\n  <string name=\"menu_settings\">Nastavenia</string>\n  <string name=\"menu_share\">Zdieľať</string>\n  <string name=\"msg_bulk_mode_scanned\">Hromadný režim: skenovanie a ukladanie čiarových kódov</string>\n  <string name=\"msg_camera_framework_bug\">Ospravedlňujeme sa, fotoaparát narazil na problém. Možno bude potrebné reštartovať zariadenie.</string>\n  <string name=\"msg_default_format\">Formát</string>\n  <string name=\"msg_default_meta\">Metadáta</string>\n  <string name=\"msg_default_mms_subject\">Ahoj</string>\n  <string name=\"msg_default_status\">Umiestnite čiarový kód do vnútra obdĺžnika hľadáčiku pre skenovanie.</string>\n  <string name=\"msg_default_time\">Čas</string>\n  <string name=\"msg_default_type\">Typ</string>\n  <string name=\"msg_encode_contents_failed\">Nie je možné zakódovať čiarový kód z poskytnutých údajov.</string>\n  <string name=\"msg_google_books\">Google Knihy</string>\n  <string name=\"msg_google_product\">Hľadať produkty Google</string>\n  <string name=\"msg_google_shopper_missing\">Nie je nainštalované Google Nakupovanie.</string>\n  <string name=\"msg_install_google_shopper\">Google Nakupovanie kombinuje v sebe skenovanie čiarových kódov s miestnymi cenami on-line, recenzie a oveľa viac bez otvorenia prehliadača. Chceli by ste ho vyskúšať?</string>\n  <string name=\"msg_intent_failed\">Ospravedlňujeme sa, požadovaná aplikácia nemohla byť spustená. Obsah čiarového kódu je možno neplatný.</string>\n  <string name=\"msg_redirect\">Presmerovať</string>\n  <string name=\"msg_sbc_book_not_searchable\">Ospravedlňujeme sa, táto kniha nie je prehliadateľná.</string>\n  <string name=\"msg_sbc_failed\">Ospravedlňujeme sa, vyhľadávanie narazilo na problém.</string>\n  <string name=\"msg_sbc_no_page_returned\">Nenašla sa žiadna stránka</string>\n  <string name=\"msg_sbc_page\">Stránka</string>\n  <string name=\"msg_sbc_results\">Výsledky</string>\n  <string name=\"msg_sbc_searching_book\">Vyhľadáva sa kniha\\u2026</string>\n  <string name=\"msg_sbc_snippet_unavailable\">Úryvok nie je k dispozícii</string>\n  <string name=\"msg_sbc_unknown_page\">Neznáma stránka</string>\n  <string name=\"msg_share_explanation\">Môžete zdieľať dáta zobrazením čiarového kódu na displeji vášho zariadenia a jeho zoskenovaním iným zariadením</string>\n  <string name=\"msg_share_subject_line\">Tu je obsah naskenovaného čiarového kódu</string>\n  <string name=\"msg_share_text\">Alebo zadajte nejaký text</string>\n  <string name=\"msg_sure\">Ste si istí?</string>\n  <string name=\"msg_unmount_usb\">Ospravedlňujeme sa, SD karta nie je prístupná.</string>\n  <string name=\"preferences_actions_title\">Pri zistení čiarového kódu</string>\n  <string name=\"preferences_auto_focus_title\">Použiť automatické zaostrenie</string>\n  <string name=\"preferences_bulk_mode_summary\">Skenovať a ukladať veľa čiarových kódov bez prerušenia</string>\n  <string name=\"preferences_bulk_mode_title\">Hromadný režim skenovania</string>\n  <string name=\"preferences_copy_to_clipboard_title\">Kopírovať do schránky</string>\n  <string name=\"preferences_custom_product_search_summary\" formatted=\"false\">Nahradiť: %s = obsah, %f = formát, %t = typ</string>\n  <string name=\"preferences_custom_product_search_title\">Vlastné vyhľadávanie URL</string>\n  <string name=\"preferences_decode_1D_title\">1D čiarové kódy</string>\n  <string name=\"preferences_decode_Data_Matrix_title\">Dáta Matrix</string>\n  <string name=\"preferences_decode_QR_title\">QR kódy</string>\n  <string name=\"preferences_device_bug_workarounds_title\">Možné chyby zariadenia</string>\n  <string name=\"preferences_disable_continuous_focus_summary\">Použiť iba štandardné zaostrenie</string>\n  <string name=\"preferences_disable_continuous_focus_title\">Nezaostrovať nepretržite</string>\n  <string name=\"preferences_disable_exposure_title\">Bez expozície</string>\n  <string name=\"preferences_front_light_summary\">Na niektorých zariadeniach zlepšuje snímanie za zhoršených svetelných podmienok, ale môže spôsobiť odlesk. Nefunguje na všetkých zariadeniach.</string>  <string name=\"preferences_front_light_title\">Použiť prisvetlenie</string>\n  <string name=\"preferences_general_title\">Všeobecné nastavenia</string>\n  <string name=\"preferences_name\">Nastavenia</string>\n  <string name=\"preferences_play_beep_title\">Zvuková signalizácia</string>\n  <string name=\"preferences_remember_duplicates_summary\">Uložiť viacnásobné skenovanie do jednej histórie čiarového kódu</string>\n  <string name=\"preferences_remember_duplicates_title\">Zapamätať si duplikáty</string>\n  <string name=\"preferences_result_title\">Nastavenia výsledku</string>\n  <string name=\"preferences_scanning_title\">Dekódovať čiarové kódy</string>\n  <string name=\"preferences_search_country\">Vyhľadávať v krajine</string>\n  <string name=\"preferences_supplemental_summary\">Skúsiť získať viac informácií o obsahu čiarového kódu</string>\n  <string name=\"preferences_supplemental_title\">Získať viac informácií</string>\n  <string name=\"preferences_try_bsplus\">Vyskúšajte Barcode Scanner+</string>\n  <string name=\"preferences_try_bsplus_summary\">Rozšírený o nové funkcie a prostredie</string>\n  <string name=\"preferences_vibrate_title\">Vibrovať</string>\n  <string name=\"result_address_book\">Nájdená informácia o kontakte</string>\n  <string name=\"result_calendar\">Nájdená udalosť kalendára</string>\n  <string name=\"result_email_address\">Nájdená e-mailová adresa</string>\n  <string name=\"result_geo\">Nájdená zemepisná súradnica</string>\n  <string name=\"result_isbn\">Nájdená kniha</string>\n  <string name=\"result_product\">Nájdený tovar</string>\n  <string name=\"result_sms\">Nájdená SMS adresa</string>\n  <string name=\"result_tel\">Nájdené telefónne číslo</string>\n  <string name=\"result_text\">Nájdený obyčajný text</string>\n  <string name=\"result_uri\">Nájdená URL</string>\n  <string name=\"result_wifi\">Nájdená konfigurácia WLAN</string>\n  <string name=\"sbc_name\">Vyhľadať v Google Knihy</string>\n  <string name=\"share_name\">Zdieľať cez čiarový kód</string>\n  <string name=\"wifi_changing_network\">Požiadavka na pripojenie k sieti\\u2026</string>\n  <string name=\"wifi_ssid_label\">Názov sieťového pripojenia</string>\n  <string name=\"wifi_type_label\">Typ</string>\n</resources>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/values-sl/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2012 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<resources>\n  <!-- <string name=\"app_name\">Barcode Scanner</string> -->\n  <string name=\"app_picker_name\">Aplikacije</string>\n  <string name=\"bookmark_picker_name\">Zaznamki</string>\n  <string name=\"button_add_calendar\">Dodaj v koledar</string>\n  <string name=\"button_add_contact\">Dodaj kontakt</string>\n  <string name=\"button_back\">Nazaj</string>\n  <string name=\"button_book_search\">Išči knjigo</string>\n  <string name=\"button_cancel\">Prekliči</string>\n  <string name=\"button_custom_product_search\">Iskanje po meri</string>\n  <string name=\"button_dial\">Pokliči številko</string>\n  <string name=\"button_done\">Končano</string>\n  <string name=\"button_email\">Pošlji e-mail</string>\n  <string name=\"button_get_directions\">Dobi smer</string>\n  <string name=\"button_google_shopper\">Shopper</string>\n  <string name=\"button_mms\">Pošlji MMS</string>\n  <string name=\"button_ok\">V redu</string>\n  <string name=\"button_open_browser\">Odpri brskalnik</string>\n  <string name=\"button_product_search\">Iskanje po izdelkih</string>\n  <string name=\"button_search_book_contents\">Išči vsebino</string>\n  <string name=\"button_share_app\">Aplikacija</string>\n  <string name=\"button_share_bookmark\">Zaznamek</string>\n  <string name=\"button_share_by_email\">Deli preko e-maila</string>\n  <string name=\"button_share_by_sms\">Deli preko SMS</string>\n  <string name=\"button_share_clipboard\">Odložišče</string>\n  <string name=\"button_share_contact\">Kontakt</string>\n  <string name=\"button_show_map\">Pokaži zemljevid</string>\n  <string name=\"button_sms\">Pošlji SMS</string>\n  <string name=\"button_web_search\">Spletno iskanje</string>\n  <string name=\"button_wifi\">Poveži se na omrežje</string>\n  <string name=\"contents_contact\">Informacije o kontaktu</string>\n  <string name=\"contents_email\">E-naslov</string>\n  <string name=\"contents_location\">Geografske koordinate</string>\n  <string name=\"contents_phone\">Telefonska številka</string>\n  <string name=\"contents_sms\">SMS naslov</string>\n  <string name=\"contents_text\">Tekst</string>\n  <string name=\"history_clear_one_history_text\">Pobriši</string>\n  <string name=\"history_clear_text\">Pobriši zgodovino</string>\n  <string name=\"history_email_title\">Barcode Scanner zgodovina</string>\n  <string name=\"history_empty\">Prazne</string>\n  <string name=\"history_empty_detail\">Št črtne kode scans so bile zabeležene</string>\n  <string name=\"history_send\">Pošlji zgodovino</string>\n  <string name=\"history_title\">Zgodovina</string>\n  <string name=\"menu_encode_mecard\">Uporaba MECARD</string>\n  <string name=\"menu_encode_vcard\">Uporaba vCard</string>\n  <string name=\"menu_help\">Pomoč</string>\n  <string name=\"menu_history\">Zgodovina</string>\n  <string name=\"menu_settings\">Nastavitve</string>\n  <string name=\"menu_share\">Deli</string>\n  <string name=\"msg_bulk_mode_scanned\">Slikanje na debelo: črtna koda prebrana in shranjena</string>\n  <string name=\"msg_camera_framework_bug\">Oprostite, Android kamera je naletela na težave. Mogoče boste morali ponovno zagnati napravo.</string>\n  <string name=\"msg_default_format\">Format</string>\n  <string name=\"msg_default_meta\">Metapodatki</string>\n  <string name=\"msg_default_mms_subject\">Živjo</string>\n  <string name=\"msg_default_status\">Za branje postavite črtno kodo znotraj iskala.</string>\n  <string name=\"msg_default_time\">Čas</string>\n  <string name=\"msg_default_type\">Tip</string>\n  <string name=\"msg_encode_contents_failed\">Ni bilo mogoče narediti črtne kode iz podanih podatkov</string>\n  <string name=\"msg_google_books\">Google Books</string>\n  <string name=\"msg_google_product\">Google Product Search</string>\n  <string name=\"msg_google_shopper_missing\">Google Shopper ni nameščen</string>\n  <string name=\"msg_install_google_shopper\">Google Shopper kombinira branje črtnih kod s cenami lokalnih ter spletnih trgovin, ocenami izdelkov in več brez odpiranja spletnega brskalnika. Ga želite preizkusiti?</string>\n  <string name=\"msg_intent_failed\">Oprostite, zahtevana aplikacija se ne more zagnati. Lahko da gre za napačno vsebino črtne kode.</string>\n  <string name=\"msg_redirect\">Preusmeritev</string>\n  <string name=\"msg_sbc_book_not_searchable\">Oprostite, po tej knjigi se ne da iskati.</string>\n  <string name=\"msg_sbc_failed\">Oprostite, iskanje je naletelo na napako.</string>\n  <string name=\"msg_sbc_no_page_returned\">Brez vrnjene strani.</string>\n  <string name=\"msg_sbc_page\">Stran</string>\n  <string name=\"msg_sbc_results\">Rezultati</string>\n  <string name=\"msg_sbc_searching_book\">Iščem knjigo\\u2026</string>\n  <string name=\"msg_sbc_snippet_unavailable\">Košček ni na voljo</string>\n  <string name=\"msg_sbc_unknown_page\">Neznana stran</string>\n  <string name=\"msg_share_explanation\">Lahko delite podatke s prikazom črtne kode na vašem zaslonu in branju le-te z drugim mobilnim telefonom.</string>\n  <string name=\"msg_share_subject_line\">Tu je vsebina prebrane črtne kode</string>\n  <string name=\"msg_share_text\">Ali vnesite nekaj besedila</string>\n  <string name=\"msg_sure\">Ali ste prepričani?</string>\n  <string name=\"msg_unmount_usb\">Oprostite, do SD kartice ni možno dostopati</string>\n  <string name=\"preferences_actions_title\">Ko je črtna koda najdena\\u2026</string>\n  <string name=\"preferences_auto_focus_title\">Uporabite samodejno ostrenje</string>\n  <string name=\"preferences_bulk_mode_summary\">Beri in shrani več črtnih kod zaporedoma</string>\n  <string name=\"preferences_bulk_mode_title\">Branje črtnih kod na debelo</string>\n  <string name=\"preferences_copy_to_clipboard_title\">Kopiraj v beležnico</string>\n  <string name=\"preferences_custom_product_search_summary\" formatted=\"false\">Zamenjave: %s = vsebin, %f = format, %t = vrsta</string>\n  <string name=\"preferences_custom_product_search_title\">URL za iskanje po meri</string>\n  <string name=\"preferences_decode_1D_title\">1D črtno kodo</string>\n  <string name=\"preferences_decode_Data_Matrix_title\">Data Matrix</string>\n  <string name=\"preferences_decode_QR_title\">QR kodo</string>\n  <string name=\"preferences_device_bug_workarounds_title\">Naprava Bug Rešitve</string>\n  <string name=\"preferences_disable_continuous_focus_summary\">Uporabljajte samo standardni način ostrenja</string>\n  <string name=\"preferences_disable_continuous_focus_title\">Št stalna osredotočenost</string>\n  <string name=\"preferences_disable_exposure_title\">Nobena izpostavljenost</string>\n  <string name=\"preferences_front_light_summary\">Izboljša branje pri slabi svetlobi na nekaterih telefonih, a lahko povzroči blesk. Ne deluje na vseh telefonih.</string>\n  <string name=\"preferences_front_light_title\">Uporabite sprednjo luč</string>\n  <string name=\"preferences_general_title\">Splošne nastavitve</string>\n  <string name=\"preferences_name\">Nastavitve</string>\n  <string name=\"preferences_play_beep_title\">Pisk</string>\n  <string name=\"preferences_remember_duplicates_summary\">Shranjevanje več skandiranje iste črtne kode v zgodovini</string>\n  <string name=\"preferences_remember_duplicates_title\">Zapomni si dvojnikov</string>\n  <string name=\"preferences_result_title\">Nastavitve rezultatov branja</string>\n  <string name=\"preferences_scanning_title\">Ko berete črtne kode, preberi\\u2026</string>\n  <string name=\"preferences_search_country\">Išči po državi</string>\n  <string name=\"preferences_supplemental_summary\">Poskusite pridobiti več informacij o vsebini črtne kode</string>\n  <string name=\"preferences_supplemental_title\">Naloži Več info</string>\n  <string name=\"preferences_try_bsplus\">Poskusite Barcode Scanner+</string>\n  <string name=\"preferences_try_bsplus_summary\">Izboljšan z novimi funkcijami in vmesnikom</string>\n  <string name=\"preferences_vibrate_title\">Vibriraj</string>\n  <string name=\"result_address_book\">Najdene informacije o kontaktu</string>\n  <string name=\"result_calendar\">Najden koledarski dogodek</string>\n  <string name=\"result_email_address\">Najden e-naslov</string>\n  <string name=\"result_geo\">Najdene geografske koordinate</string>\n  <string name=\"result_isbn\">Najdena knjiga</string>\n  <string name=\"result_product\">Najden produkt</string>\n  <string name=\"result_sms\">Najden SMS naslov</string>\n  <string name=\"result_tel\">Najdena telefonska številka</string>\n  <string name=\"result_text\">Najden tekst</string>\n  <string name=\"result_uri\">Najden URL</string>\n  <string name=\"result_wifi\">Najdene WLAN nastavitve</string>\n  <string name=\"sbc_name\">Iskanje z Google Book Search</string>\n  <string name=\"share_name\">Deli preko črtne kode</string>\n  <string name=\"wifi_changing_network\">Zahteva priključitev na omrežje\\u2026</string>\n  <string name=\"wifi_ssid_label\">Ime omrežja</string>\n  <string name=\"wifi_type_label\">Tip</string>\n</resources>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/values-sv/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2012 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<resources>\n  <!-- <string name=\"app_name\">Barcode Scanner</string> -->\n  <string name=\"app_picker_name\">Applikationer</string>\n  <string name=\"bookmark_picker_name\">Bokmärken</string>\n  <string name=\"button_add_calendar\">Lägg till i kalender</string>\n  <string name=\"button_add_contact\">Lägg till kontakt</string>\n  <string name=\"button_back\">Tillbaka</string>\n  <string name=\"button_book_search\">Boksökning</string>\n  <string name=\"button_cancel\">Avbryt</string>\n  <string name=\"button_custom_product_search\">Anpassad sökning</string>\n  <string name=\"button_dial\">Slå nummer</string>\n  <string name=\"button_done\">Klar</string>\n  <string name=\"button_email\">Skicka e-post</string>\n  <string name=\"button_get_directions\">Få anvisningar</string>\n  <string name=\"button_google_shopper\">Shopper</string>\n  <string name=\"button_mms\">Skicka MMS</string>\n  <string name=\"button_ok\">OK</string>\n  <string name=\"button_open_browser\">Öppna webbläsare</string>\n  <string name=\"button_product_search\">Produktsök</string>\n  <string name=\"button_search_book_contents\">Sökinnehåll</string>\n  <string name=\"button_share_app\">Applikation</string>\n  <string name=\"button_share_bookmark\">Bokmärke</string>\n  <string name=\"button_share_by_email\">Dela via e-post</string>\n  <string name=\"button_share_by_sms\">Dela via SMS</string>\n  <string name=\"button_share_clipboard\">Klippbord</string>\n  <string name=\"button_share_contact\">Kontakt</string>\n  <string name=\"button_show_map\">Visa karta</string>\n  <string name=\"button_sms\">Skicka SMS</string>\n  <string name=\"button_web_search\">Webbsök</string>\n  <string name=\"button_wifi\">Anslut till nätverk</string>\n  <string name=\"contents_contact\">Kontaktinfo</string>\n  <string name=\"contents_email\">E-postadress</string>\n  <string name=\"contents_location\">Geografiska koordinater</string>\n  <string name=\"contents_phone\">Telefonnummer</string>\n  <string name=\"contents_sms\">SMS-adress</string>\n  <string name=\"contents_text\">Vanlig text</string>\n  <string name=\"history_clear_one_history_text\">Rensa</string>\n  <string name=\"history_clear_text\">Rensa historik</string>\n  <string name=\"history_email_title\">Historik inskannade streckkoder</string>\n  <string name=\"history_empty\">Tom</string>\n  <string name=\"history_empty_detail\">Inga inskannade streckkoder har registrerats</string>\n  <string name=\"history_send\">Skicka historik</string>\n  <string name=\"history_title\">Historik</string>\n  <string name=\"menu_encode_mecard\">Använd MECARD</string>\n  <string name=\"menu_encode_vcard\">Använd vCard</string>\n  <string name=\"menu_help\">Hjälp</string>\n  <string name=\"menu_history\">Historik</string>\n  <string name=\"menu_settings\">Inställningar</string>\n  <string name=\"menu_share\">Dela</string>\n  <string name=\"msg_bulk_mode_scanned\">Bulk-läge: streckkod har inskannats och sparats</string>\n  <string name=\"msg_camera_framework_bug\">Det uppstod tyvärr ett fel med Androidkameran.</string>\n  <string name=\"msg_default_format\">Format</string>\n  <string name=\"msg_default_meta\">Metadata</string>\n  <string name=\"msg_default_mms_subject\">Hej</string>\n  <string name=\"msg_default_status\">Placera steckkoden inom sökarens rektangel för att läsa den.</string>\n  <string name=\"msg_default_time\">Tid</string>\n  <string name=\"msg_default_type\">Typ</string>\n  <string name=\"msg_encode_contents_failed\">Det gick inte att avkoda en streckkod från den erhållna informationen.</string>\n  <string name=\"msg_google_books\">Google Books</string>\n  <string name=\"msg_google_product\">Google Product Search</string>\n  <string name=\"msg_google_shopper_missing\">Google Shopper är inte installerad</string>\n  <string name=\"msg_install_google_shopper\">Google Shopper kombinerar inkodning av streckkoder med lokala priser och priser på nätet, recensioner och mycket mer utan att du behöver öppna webbläsaren. Vill du testa det?</string>\n  <string name=\"msg_intent_failed\">Den begärda applikationen kunde tyvärr inte startas. Streckkodens innehåll kan vara ogiltigt.</string>\n  <string name=\"msg_redirect\">Omdirigering</string>\n  <string name=\"msg_sbc_book_not_searchable\">Den här boken är tyvärr inte sökbar.</string>\n  <string name=\"msg_sbc_failed\">Det uppstod tyvärr ett fel vid sökning. </string>\n  <string name=\"msg_sbc_no_page_returned\">Ingen sida funnen</string>\n  <string name=\"msg_sbc_page\">Sida</string>\n  <string name=\"msg_sbc_results\">Resultat</string>\n  <string name=\"msg_sbc_searching_book\">Söker bok\\u2026</string>\n  <string name=\"msg_sbc_snippet_unavailable\">Utdrag ej tillgängligt</string>\n  <string name=\"msg_sbc_unknown_page\">Okänd sida</string>\n  <string name=\"msg_share_explanation\">Du kan dela information genom att visa en streckkod på din skärm och sedan skanna in den med en annan telefon.</string>\n  <string name=\"msg_share_subject_line\">Här är innehållet i en streckkod som jag har skannat in</string>\n  <string name=\"msg_share_text\">Eller skriv in text och tryck Enter</string>\n  <string name=\"msg_sure\">Är du säker?</string>\n  <string name=\"msg_unmount_usb\">SD-kortet är tyvärr inte tillgängligt.</string>\n  <string name=\"preferences_actions_title\">När en streckkod hittas\\u2026</string>\n  <string name=\"preferences_auto_focus_title\">Använd autofokus</string>\n  <string name=\"preferences_bulk_mode_summary\">Skanna och spara flera streckkoder samtidigt</string>\n  <string name=\"preferences_bulk_mode_title\">Bulk-inskanningläge</string>\n  <string name=\"preferences_copy_to_clipboard_title\">Kopiera till urklipp</string>\n  <string name=\"preferences_custom_product_search_summary\" formatted=\"false\">Ersättningar: %s = innehåll, %f = format, %t = typ</string>\n  <string name=\"preferences_custom_product_search_title\">Anpassad sökning URL</string>\n  <string name=\"preferences_decode_1D_title\">1D steckkod</string>\n  <string name=\"preferences_decode_Data_Matrix_title\">Data Matrix</string>\n  <string name=\"preferences_decode_QR_title\">QR Code</string>\n  <string name=\"preferences_device_bug_workarounds_title\">Bugglösningar för enhet</string>\n  <string name=\"preferences_disable_continuous_focus_summary\">Använd endast standardfokusläge</string>\n  <string name=\"preferences_disable_continuous_focus_title\">Ingen kontinuerlig fokus</string>\n  <string name=\"preferences_disable_exposure_title\">Ingen exponering</string>\n  <string name=\"preferences_front_light_summary\">Förbättrar inskanning i svag belysing på vissa telefoner, men kan orsaka bländning. Ej tillgängligt på vissa enheter.</string>\n  <string name=\"preferences_front_light_title\">Använd frontljus</string>\n  <string name=\"preferences_general_title\">Grundläggande inställningar</string>\n  <string name=\"preferences_name\">Inställningar</string>\n  <string name=\"preferences_play_beep_title\">Ton</string>\n  <string name=\"preferences_remember_duplicates_summary\">Lagra flera inskanningar av samma streckkod i historik</string>\n  <string name=\"preferences_remember_duplicates_title\">Kom ihåg dubletter</string>\n  <string name=\"preferences_result_title\">Resultatinställningar</string>\n  <string name=\"preferences_scanning_title\">När du skannar in streckkoder, avkoda\\u2026</string>\n  <string name=\"preferences_search_country\">Sök land</string>\n  <string name=\"preferences_supplemental_summary\">Försök hämta mer information om streckkodens innehåll</string>\n  <string name=\"preferences_supplemental_title\">Hämta mer info</string>\n  <string name=\"preferences_try_bsplus\">Prova Barcode Scanner+</string>\n  <string name=\"preferences_try_bsplus_summary\">Förstärkt med nya funktioner och gränssnitt</string>\n  <string name=\"preferences_vibrate_title\">Vibrera</string>\n  <string name=\"result_address_book\">Hittade kontaktinformation</string>\n  <string name=\"result_calendar\">Hittade kalenderhändelser</string>\n  <string name=\"result_email_address\">Hittade e-postadress</string>\n  <string name=\"result_geo\">Hittade geografiska koordinater</string>\n  <string name=\"result_isbn\">Hittade bok</string>\n  <string name=\"result_product\">Hittade produkt</string>\n  <string name=\"result_sms\">Hittade SMS-adress</string>\n  <string name=\"result_tel\">Hittade telefonnummer</string>\n  <string name=\"result_text\">Hittade vanlig text</string>\n  <string name=\"result_uri\">Hittade URL</string>\n  <string name=\"result_wifi\">Hittade WLAN-konfiguration</string>\n  <string name=\"sbc_name\">Google Book Search</string>\n  <string name=\"share_name\">Dela via streckkod</string>\n  <string name=\"wifi_changing_network\">Begär anslutning till nätverk\\u2026</string>\n  <string name=\"wifi_ssid_label\">Nätverksnamn</string>\n  <string name=\"wifi_type_label\">Typ</string>\n</resources>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/values-tr/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2012 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<resources>\n  <!-- <string name=\"app_name\">Barkod Tarayıcısı</string> -->\n  <string name=\"app_picker_name\">Uygulamalar</string>\n  <string name=\"bookmark_picker_name\">Yer imleri</string>\n  <string name=\"button_add_calendar\">Takvime ekle</string>\n  <string name=\"button_add_contact\">Kişi ekle</string>\n  <string name=\"button_back\">Geri</string>\n  <string name=\"button_book_search\">Kitap Arama</string>\n  <string name=\"button_cancel\">İptal</string>\n  <string name=\"button_custom_product_search\">Özel arama</string>\n  <string name=\"button_dial\">Numaraya çağrı</string>\n  <string name=\"button_done\">Tamam</string>\n  <string name=\"button_email\">Email gönder</string>\n  <string name=\"button_get_directions\">Yön bilgisi al</string>\n  <string name=\"button_google_shopper\">Shopper</string>\n  <string name=\"button_mms\">MMS gönder</string>\n  <string name=\"button_ok\">Tamam</string>\n  <string name=\"button_open_browser\">Tarayıcıyı aç</string>\n  <string name=\"button_product_search\">Ürün arama</string>\n  <string name=\"button_search_book_contents\">İçerik arama</string>\n  <string name=\"button_share_app\">Uygulama paylaş</string>\n  <string name=\"button_share_bookmark\">Yer imi paylaş</string>\n  <string name=\"button_share_by_email\">Email ile paylaş</string>\n  <string name=\"button_share_by_sms\">SMS ile paylaş</string>\n  <string name=\"button_share_clipboard\">Pano</string>\n  <string name=\"button_share_contact\">Kişi</string>\n  <string name=\"button_show_map\">Haritayı göster</string>\n  <string name=\"button_sms\">SMS gönder</string>\n  <string name=\"button_web_search\">Webde ara</string>\n  <string name=\"button_wifi\">Ağa bağlan</string>\n  <string name=\"contents_contact\">Kişi bilgisi</string>\n  <string name=\"contents_email\">Email adresi</string>\n  <string name=\"contents_location\">Coğrafi koordinatlar</string>\n  <string name=\"contents_phone\">Telefon numarası</string>\n  <string name=\"contents_sms\">SMS adresi</string>\n  <string name=\"contents_text\">Düz metin</string>\n  <string name=\"history_clear_one_history_text\">Temizle</string>\n  <string name=\"history_clear_text\">Geçmişi temizle</string>\n  <string name=\"history_email_title\">Barkod Tarayıcı geçmişi</string>\n  <string name=\"history_empty\">Boş</string>\n  <string name=\"history_empty_detail\">Yok barkod taramaları kaydedildi</string>\n  <string name=\"history_send\">Geçmişi gönder</string>\n  <string name=\"history_title\">Geçmiş</string>\n  <string name=\"menu_encode_mecard\">MECARD kullanın</string>\n  <string name=\"menu_encode_vcard\">VCard kullanın</string>\n  <string name=\"menu_help\">Yardım</string>\n  <string name=\"menu_history\">Geçmiş</string>\n  <string name=\"menu_settings\">Ayarlar</string>\n  <string name=\"menu_share\">Paylaş</string>\n  <string name=\"msg_bulk_mode_scanned\">Toplu modu: taranan ve kaydedilen barkodlar</string>\n  <string name=\"msg_camera_framework_bug\">Üzgünüz, Android kamera bir sorunla karşılaştı. Cihazı yeniden başlatmanız gerekebilir.</string>\n  <string name=\"msg_default_format\">Biçim</string>\n  <string name=\"msg_default_meta\">Metadata</string>\n  <string name=\"msg_default_mms_subject\">Merhaba</string>\n  <string name=\"msg_default_status\">Barkodu taramak için vizördeki dikdörtgenin içerisine yerleştirin.</string>\n  <string name=\"msg_default_time\">Süre</string>\n  <string name=\"msg_default_type\">Tür</string>\n  <string name=\"msg_encode_contents_failed\">Sağlanan verilerden bir barkod kodlanamadı.</string>\n  <string name=\"msg_google_books\">Google Kitap Arama</string>\n  <string name=\"msg_google_product\">Google Ürün Arama</string>\n  <string name=\"msg_google_shopper_missing\">Google Shopper yüklü değil</string>\n  <string name=\"msg_install_google_shopper\">Google Shopper, tarayıcıyı açmanıza gerek kalmadan barkod taraması, çevrimiçi ve yerel fiyatlar ile gözden geçirme ve diğer özellikten yararlanmanızı sağlar. Denemek ister misiniz?</string>\n  <string name=\"msg_intent_failed\">Üzgünüz, istenen uygulama başlatılamadı. Barkod içeriği geçersiz olabilir.</string>\n  <string name=\"msg_redirect\">Yönlendirme</string>\n  <string name=\"msg_sbc_book_not_searchable\">Üzgünüz, bu kitapla ilgili arama yapılamıyor.</string>\n  <string name=\"msg_sbc_failed\">Üzgünüz, arama esnasında bir sorun oluştu.</string>\n  <string name=\"msg_sbc_no_page_returned\">Dönen sayfa yok</string>\n  <string name=\"msg_sbc_page\">Sayfa</string>\n  <string name=\"msg_sbc_results\">Sonuçlar</string>\n  <string name=\"msg_sbc_searching_book\">Kitap aranıyor\\u2026</string>\n  <string name=\"msg_sbc_snippet_unavailable\">Parçacık yok</string>\n  <string name=\"msg_sbc_unknown_page\">Bilinmeyen sayfa</string>\n  <string name=\"msg_share_explanation\">Ekranınızda görüntülediğiniz barkodu başka bir telefonla tarayarak veri paylaşabilirsiniz.</string>\n  <string name=\"msg_share_subject_line\">Taranan barkodun içeriği</string>\n  <string name=\"msg_share_text\">Veya yazın bazı metin</string>\n  <string name=\"msg_sure\">Emin misin?</string>\n  <string name=\"msg_unmount_usb\">Lütfen USB depolamayı devre dışı bırakın.</string>\n  <string name=\"preferences_actions_title\">Bir barkod bulunduğu zaman\\u2026</string>\n  <string name=\"preferences_auto_focus_title\">Otomatik odaklama kullanın</string>\n  <string name=\"preferences_bulk_mode_summary\">Birden fazla barkodu toplu olarak taramak ve kaydetmek için</string>\n  <string name=\"preferences_bulk_mode_title\">Toplu tarama modu</string>\n  <string name=\"preferences_copy_to_clipboard_title\">Panoya kopyala</string>\n  <string name=\"preferences_custom_product_search_summary\" formatted=\"false\">Yerine Koyma: %s = içeriği, %f = biçim, %t = tip</string>\n  <string name=\"preferences_custom_product_search_title\">Özel arama adresi</string>\n  <string name=\"preferences_decode_1D_title\">1D barkodları</string>\n  <string name=\"preferences_decode_Data_Matrix_title\">Data Matrix</string>\n  <string name=\"preferences_decode_QR_title\">QR barkodları</string>\n  <string name=\"preferences_device_bug_workarounds_title\">Cihaz Hata Geçici Çözümler</string>\n  <string name=\"preferences_disable_continuous_focus_summary\">Sadece standart odaklama modunu kullanın</string>\n  <string name=\"preferences_disable_continuous_focus_title\">Hayır sürekli odak</string>\n  <string name=\"preferences_disable_exposure_title\">Maruziyet</string>\n  <string name=\"preferences_front_light_summary\">Bazı telefonlarda düşük ışıkta taramayı iyileştirir, ancak parlamaya neden olabilir. Tüm telefonlarda sonuç vermez.</string>\n  <string name=\"preferences_front_light_title\">Ön ışığı kullan</string>\n  <string name=\"preferences_general_title\">Genel ayarlar</string>\n  <string name=\"preferences_name\">Ayarlar</string>\n  <string name=\"preferences_play_beep_title\">Bip</string>\n  <string name=\"preferences_remember_duplicates_summary\">Aynı barkoda ait farklı taramaları kayıtlarda depola</string>\n  <string name=\"preferences_remember_duplicates_title\">Aynı barkodları hatırla</string>\n  <string name=\"preferences_result_title\">Sonuç ayarları</string>\n  <string name=\"preferences_scanning_title\">Barkodlar taraması \\u2026</string>\n  <string name=\"preferences_search_country\">Arama Ülke</string>\n  <string name=\"preferences_supplemental_summary\">Barkod içeriği hakkında daha fazla bilgi almayı dene</string>\n  <string name=\"preferences_supplemental_title\">Daha fazla bilgi </string>\n  <string name=\"preferences_try_bsplus\">Barkod Tarayıcısı+ deneyin</string>\n  <string name=\"preferences_try_bsplus_summary\">Yeni özellikler ve arayüz ile gelişmiş</string>\n  <string name=\"preferences_vibrate_title\">Titreşim </string>\n  <string name=\"result_address_book\">Bulunan kişi bilgisi</string>\n  <string name=\"result_calendar\">Bulunan takvim etkinliği</string>\n  <string name=\"result_email_address\">Bulunan Email adresi</string>\n  <string name=\"result_geo\">Bulunan coğrafi koordinatlar</string>\n  <string name=\"result_isbn\">Bulunan kitap</string>\n  <string name=\"result_product\">Bulunan ürün</string>\n  <string name=\"result_sms\">Bulunan SMS adresi</string>\n  <string name=\"result_tel\">Bulunan telefon numarası</string>\n  <string name=\"result_text\">Bulunan düz metin</string>\n  <string name=\"result_uri\">Bulunan URL</string>\n  <string name=\"result_wifi\">Bulunan Wi-Fi konfigürasyonu</string>\n  <string name=\"sbc_name\">Google Kitap Arama</string>\n  <string name=\"share_name\">Barkod ile paylaş</string>\n  <string name=\"wifi_changing_network\">Ağa bir bağlantı isteğinde\\u2026</string>\n  <string name=\"wifi_ssid_label\">Ağ adı</string>\n  <string name=\"wifi_type_label\">Tip</string>\n</resources>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/values-zh-rCN/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2012 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<resources>\n  <!-- <string name=\"app_name\">条码扫描器</string> -->\n  <string name=\"app_picker_name\">应用</string>\n  <string name=\"bookmark_picker_name\">书签</string>\n  <string name=\"button_add_calendar\">添加事件至日历</string>\n  <string name=\"button_add_contact\">添加联系人</string>\n  <string name=\"button_back\">返回</string>\n  <string name=\"button_book_search\">打开图书搜索</string>\n  <string name=\"button_cancel\">取消</string>\n  <string name=\"button_custom_product_search\">自定义搜索</string>\n  <string name=\"button_dial\">拨号</string>\n  <string name=\"button_done\">完成</string>\n  <string name=\"button_email\">发送email</string>\n  <string name=\"button_get_directions\">获取地址</string>\n  <string name=\"button_google_shopper\">谷歌购物</string>\n  <string name=\"button_mms\">发送彩信</string>\n  <string name=\"button_ok\">确定</string>\n  <string name=\"button_open_browser\">打开浏览器</string>\n  <string name=\"button_product_search\">打开产品搜索</string>\n  <string name=\"button_search_book_contents\">搜索图书内容</string>\n  <string name=\"button_share_app\">共享应用</string>\n  <string name=\"button_share_bookmark\">分享书签</string>\n  <string name=\"button_share_by_email\">通过email分享</string>\n  <string name=\"button_share_by_sms\">通过短信分享</string>\n  <string name=\"button_share_clipboard\">分享剪切板</string>\n  <string name=\"button_share_contact\">分享联系人</string>\n  <string name=\"button_show_map\">显示地图</string>\n  <string name=\"button_sms\">发送短信</string>\n  <string name=\"button_web_search\">网页搜索</string>\n  <string name=\"button_wifi\">连接到网络</string>\n  <string name=\"contents_contact\">联系人信息</string>\n  <string name=\"contents_email\">Email地址</string>\n  <string name=\"contents_location\">地理坐标</string>\n  <string name=\"contents_phone\">电话号码</string>\n  <string name=\"contents_sms\">短信地址</string>\n  <string name=\"contents_text\">纯文本</string>\n  <string name=\"history_clear_one_history_text\">删除</string>\n  <string name=\"history_clear_text\">删除历史</string>\n  <string name=\"history_email_title\">条码扫描器历史</string>\n  <string name=\"history_empty\">空的</string>\n  <string name=\"history_empty_detail\">没有条码扫描已记录</string>\n  <string name=\"history_send\">发送历史</string>\n  <string name=\"history_title\">历史</string>\n  <string name=\"menu_encode_mecard\">使用MECARD</string>\n  <string name=\"menu_encode_vcard\">使用vCard</string>\n  <string name=\"menu_help\">帮助</string>\n  <string name=\"menu_history\">历史</string>\n  <string name=\"menu_settings\">设置</string>\n  <string name=\"menu_share\">分享</string>\n  <string name=\"msg_bulk_mode_scanned\">批量扫描：找到条码，已保存</string>\n  <string name=\"msg_camera_framework_bug\">抱歉，Android相机出现问题。您可能需要重启设备。</string>\n  <string name=\"msg_default_format\">格式</string>\n  <string name=\"msg_default_meta\">元数据</string>\n  <string name=\"msg_default_mms_subject\">Hi</string>\n  <string name=\"msg_default_status\">请将条码置于取景框内扫描。  </string>\n  <string name=\"msg_default_time\">时间</string>\n  <string name=\"msg_default_type\">类型</string>\n  <string name=\"msg_encode_contents_failed\">无法根据已有数据生成条码。   </string>\n  <string name=\"msg_google_books\">谷歌图书</string>\n  <string name=\"msg_google_product\">谷歌购物</string>\n  <string name=\"msg_google_shopper_missing\">谷歌购物未安装</string>\n  <string name=\"msg_install_google_shopper\">谷歌购物是一款将条码扫描和商品比价相结合的应用，谷歌购物不使用浏览器，您想尝试吗？</string>\n  <string name=\"msg_intent_failed\">抱歉，无法打开所需软件。 条码内容可能无效。</string>\n  <string name=\"msg_redirect\">重定向</string>\n  <string name=\"msg_sbc_book_not_searchable\">抱歉，无法找到此图书。</string>\n  <string name=\"msg_sbc_failed\">抱歉，搜索时遇到错误。</string>\n  <string name=\"msg_sbc_no_page_returned\">无页面返回</string>\n  <string name=\"msg_sbc_page\">页面</string>\n  <string name=\"msg_sbc_results\">结果</string>\n  <string name=\"msg_sbc_searching_book\">搜索图书…</string>\n  <string name=\"msg_sbc_snippet_unavailable\">摘录不可用</string>\n  <string name=\"msg_sbc_unknown_page\">未知页面</string>\n  <string name=\"msg_share_explanation\">您可以通过在自己的手机上显示条码，并使用其它手机扫描此条码的方式进行分享</string>\n  <string name=\"msg_share_subject_line\">这是我所扫描条码的内容</string>\n  <string name=\"msg_share_text\">或键入一些文字</string>\n  <string name=\"msg_sure\">你肯定吗？</string>\n  <string name=\"msg_unmount_usb\">抱歉，SD卡不可访问。</string>\n  <string name=\"preferences_actions_title\">找到条码时</string>\n  <string name=\"preferences_auto_focus_title\">使用自动对焦</string>\n  <string name=\"preferences_bulk_mode_summary\">连续扫描并保存多个条形码</string>\n  <string name=\"preferences_bulk_mode_title\">批量扫描模式</string>\n  <string name=\"preferences_copy_to_clipboard_title\">复制到剪切板</string>\n  <string name=\"preferences_custom_product_search_summary\" formatted=\"false\">替换：％s=内容，％f=格式，％t=类型</string>\n  <string name=\"preferences_custom_product_search_title\">自定义搜索网址</string>\n  <string name=\"preferences_decode_1D_title\">扫描 一维条码</string>\n  <string name=\"preferences_decode_Data_Matrix_title\">扫描 DM码</string>\n  <string name=\"preferences_decode_QR_title\">扫描 QR码</string>\n  <string name=\"preferences_device_bug_workarounds_title\">设备问题解决办法</string>\n  <string name=\"preferences_disable_continuous_focus_summary\">只使用标准对焦模式</string>\n  <string name=\"preferences_disable_continuous_focus_title\">没有持续关注</string>\n  <string name=\"preferences_disable_exposure_title\">无曝光</string>\n  <string name=\"preferences_front_light_summary\">前灯可用时，打开前灯</string>\n  <string name=\"preferences_front_light_title\">前灯</string>\n  <string name=\"preferences_general_title\">一般设置</string>\n  <string name=\"preferences_name\">设置</string>\n  <string name=\"preferences_play_beep_title\">提示音</string>\n  <string name=\"preferences_remember_duplicates_summary\">在历史记录中保存重复记录</string>\n  <string name=\"preferences_remember_duplicates_title\">记住重复</string>\n  <string name=\"preferences_result_title\">结果设置</string>\n  <string name=\"preferences_scanning_title\">条码类型选择</string>\n  <string name=\"preferences_search_country\">搜索国家</string>\n  <string name=\"preferences_supplemental_summary\">尝试检索关于条码内容的更多信息</string>\n  <string name=\"preferences_supplemental_title\">检索更多信息</string>\n  <string name=\"preferences_try_bsplus\">尝试条码扫描器+</string>\n  <string name=\"preferences_try_bsplus_summary\">增强新的功能和接口</string>\n  <string name=\"preferences_vibrate_title\">振动</string>\n  <string name=\"result_address_book\">找到联系人信息</string>\n  <string name=\"result_calendar\">找到日历事件</string>\n  <string name=\"result_email_address\">找到email地址</string>\n  <string name=\"result_geo\">找到地理坐标</string>\n  <string name=\"result_isbn\">找到图书</string>\n  <string name=\"result_product\">找到产品</string>\n  <string name=\"result_sms\">找到短信地址</string>\n  <string name=\"result_tel\">找到电话号码</string>\n  <string name=\"result_text\">找到纯文本</string>\n  <string name=\"result_uri\">找到URL</string>\n  <string name=\"result_wifi\">发现网络配置</string>\n  <string name=\"sbc_name\">Google图书搜索</string>\n  <string name=\"share_name\">通过条码分享</string>\n  <string name=\"wifi_changing_network\">请求连接到网络\\u2026</string>\n  <string name=\"wifi_ssid_label\">网络SSID</string>\n  <string name=\"wifi_type_label\">类型</string>\n</resources>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/values-zh-rTW/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Copyright (C) 2012 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<resources>\n  <!-- <string name=\"app_name\">條碼掃描器</string> -->\n  <string name=\"app_picker_name\">應用程式</string>\n  <string name=\"bookmark_picker_name\">書籤</string>\n  <string name=\"button_add_calendar\">加入事件至日曆</string>\n  <string name=\"button_add_contact\">加入聯絡人</string>\n  <string name=\"button_back\">返回</string>\n  <string name=\"button_book_search\">打開圖書搜索</string>\n  <string name=\"button_cancel\">取消</string>\n  <string name=\"button_custom_product_search\">自定義搜索</string>\n  <string name=\"button_dial\">撥號</string>\n  <string name=\"button_done\">完成</string>\n  <string name=\"button_email\">發送電子郵件</string>\n  <string name=\"button_get_directions\">路線規劃</string>\n  <string name=\"button_google_shopper\">Google 購物</string>\n  <string name=\"button_mms\">發送 MMS</string>\n  <string name=\"button_ok\">確定</string>\n  <string name=\"button_open_browser\">打開瀏覽器</string>\n  <string name=\"button_product_search\">打開產品搜索</string>\n  <string name=\"button_search_book_contents\">搜索圖書內容</string>\n  <string name=\"button_share_app\">分享應用程式</string>\n  <string name=\"button_share_bookmark\">分享書籤</string>\n  <string name=\"button_share_by_email\">透過電子郵件分享</string>\n  <string name=\"button_share_by_sms\">透過簡訊分享</string>\n  <string name=\"button_share_clipboard\">分享剪貼簿</string>\n  <string name=\"button_share_contact\">分享聯絡人</string>\n  <string name=\"button_show_map\">顯示地圖</string>\n  <string name=\"button_sms\">發送簡訊</string>\n  <string name=\"button_web_search\">網頁搜索</string>\n  <string name=\"button_wifi\">連接到網路</string>\n  <string name=\"contents_contact\">聯絡人資訊</string>\n  <string name=\"contents_email\">電子郵件地址</string>\n  <string name=\"contents_location\">地理座標</string>\n  <string name=\"contents_phone\">電話號碼</string>\n  <string name=\"contents_sms\">簡訊地址</string>\n  <string name=\"contents_text\">純文字</string>\n  <string name=\"history_clear_one_history_text\">刪除</string>\n  <string name=\"history_clear_text\">刪除紀錄</string>\n  <string name=\"history_email_title\">條碼掃描器紀錄</string>\n  <string name=\"history_empty\">空的</string>\n  <string name=\"history_empty_detail\">沒有條碼掃描記錄</string>\n  <string name=\"history_send\">發送紀錄</string>\n  <string name=\"history_title\">紀錄</string>\n  <string name=\"menu_encode_mecard\">使用MECARD</string>\n  <string name=\"menu_encode_vcard\">使用vCard</string>\n  <string name=\"menu_help\">說明</string>\n  <string name=\"menu_history\">紀錄</string>\n  <string name=\"menu_settings\">設定</string>\n  <string name=\"menu_share\">分享</string>\n  <string name=\"msg_bulk_mode_scanned\">大量掃描模式：條碼掃描並儲存</string>\n  <string name=\"msg_camera_framework_bug\">很抱歉，相機出現問題。您可能需要重新啟動設備。</string>\n  <string name=\"msg_default_format\">格式</string>\n  <string name=\"msg_default_meta\">後設資料</string>\n  <string name=\"msg_default_mms_subject\">哈囉</string>\n  <string name=\"msg_default_status\">將條碼置於鏡頭範圍內以進行掃描。</string>\n  <string name=\"msg_default_time\">時間</string>\n  <string name=\"msg_default_type\">類型</string>\n  <string name=\"msg_encode_contents_failed\">無法讀取條碼。</string>\n  <string name=\"msg_google_books\">Google 圖書</string>\n  <string name=\"msg_google_product\">Google 產品搜索</string>\n  <string name=\"msg_google_shopper_missing\">未安裝 Google 購物</string>\n  <string name=\"msg_install_google_shopper\">Google 購物結合條碼掃描價格，評論，無需打開瀏覽器。您想試用嗎？</string>\n  <string name=\"msg_intent_failed\">抱歉，無法打開所需軟體。條碼內容可能無效。</string>\n  <string name=\"msg_redirect\">重定向</string>\n  <string name=\"msg_sbc_book_not_searchable\">無法找到此圖書。</string>\n  <string name=\"msg_sbc_failed\">搜尋時發生錯誤。</string>\n  <string name=\"msg_sbc_no_page_returned\">沒有取得頁面</string>\n  <string name=\"msg_sbc_page\">頁面</string>\n  <string name=\"msg_sbc_results\">結果</string>\n  <string name=\"msg_sbc_searching_book\">搜尋圖書中\\u2026</string>\n  <string name=\"msg_sbc_snippet_unavailable\">無法取得摘要</string>\n  <string name=\"msg_sbc_unknown_page\">未知的頁面</string>\n  <string name=\"msg_share_explanation\">你可以在你的手機螢幕上顯示條碼，並使用其他手機掃描此條碼藉此分享給朋友</string>\n  <string name=\"msg_share_subject_line\">這是我所掃描的條碼的內容</string>\n  <string name=\"msg_share_text\">或輸入一些文字並按 Enter</string>\n  <string name=\"msg_sure\">你確定嗎？</string>\n  <string name=\"msg_unmount_usb\">無法讀取 SD 卡。</string>\n  <string name=\"preferences_actions_title\">找到條碼時</string>\n  <string name=\"preferences_auto_focus_title\">使用自動對焦</string>\n  <string name=\"preferences_bulk_mode_summary\">連續掃描並儲存多個條碼</string>\n  <string name=\"preferences_bulk_mode_title\">大量掃描模式</string>\n  <string name=\"preferences_copy_to_clipboard_title\">複製到剪貼簿</string>\n  <string name=\"preferences_custom_product_search_summary\" formatted=\"false\">替換：％s=內容，％f=格式，％t=類型</string>\n  <string name=\"preferences_custom_product_search_title\">自訂搜尋網址</string>\n  <string name=\"preferences_decode_1D_title\">解碼一維條碼</string>\n  <string name=\"preferences_decode_Data_Matrix_title\">解碼 Data Matrix 條碼</string>\n  <string name=\"preferences_decode_QR_title\">解碼 QR Code</string>\n  <string name=\"preferences_device_bug_workarounds_title\">設備問題解決辦法</string>\n  <string name=\"preferences_disable_continuous_focus_summary\">只使用標準對焦模式</string>\n  <string name=\"preferences_disable_continuous_focus_title\">無連續對焦</string>\n  <string name=\"preferences_disable_exposure_title\">無曝光</string>\n  <string name=\"preferences_front_light_summary\">改善在低光源的環境下掃描的成功率，但有可能造成過度曝光的現象</string>\n  <string name=\"preferences_front_light_title\">使用前光源</string>\n  <string name=\"preferences_general_title\">一般設定</string>\n  <string name=\"preferences_name\">設定</string>\n  <string name=\"preferences_play_beep_title\">提示音</string>\n  <string name=\"preferences_remember_duplicates_summary\">在紀錄中重複儲存相同的條碼</string>\n  <string name=\"preferences_remember_duplicates_title\">記錄重複的條碼</string>\n  <string name=\"preferences_result_title\">結果設定</string>\n  <string name=\"preferences_scanning_title\">當掃描條碼時</string>\n  <string name=\"preferences_search_country\">搜索國家</string>\n  <string name=\"preferences_supplemental_summary\">嘗試透過條碼搜尋更多的資訊</string>\n  <string name=\"preferences_supplemental_title\">搜尋更多資訊</string>\n  <string name=\"preferences_try_bsplus\">嘗試條碼掃描器+</string>\n  <string name=\"preferences_try_bsplus_summary\">增強新的功能和接口</string>\n  <string name=\"preferences_vibrate_title\">震動</string>\n  <string name=\"result_address_book\">找到聯絡人</string>\n  <string name=\"result_calendar\">找到日曆事件</string>\n  <string name=\"result_email_address\">找到電子郵件地址</string>\n  <string name=\"result_geo\">找到座標</string>\n  <string name=\"result_isbn\">找到圖書</string>\n  <string name=\"result_product\">找到產品</string>\n  <string name=\"result_sms\">找到簡訊</string>\n  <string name=\"result_tel\">找到電話號碼</string>\n  <string name=\"result_text\">找到純文字</string>\n  <string name=\"result_uri\">找到 URL</string>\n  <string name=\"result_wifi\">找到網路設定</string>\n  <string name=\"sbc_name\">Google 圖書搜尋</string>\n  <string name=\"share_name\">透過條碼分享</string>\n  <string name=\"wifi_changing_network\">請求連接到網絡\\u2026</string>\n  <string name=\"wifi_ssid_label\">網路名稱</string>\n  <string name=\"wifi_type_label\">類型</string>\n</resources>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/res/xml/preferences.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n Copyright (C) 2008 ZXing authors\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n -->\n<PreferenceScreen xmlns:android=\"http://schemas.android.com/apk/res/android\">\n  <PreferenceCategory android:title=\"@string/preferences_scanning_title\">\n    <CheckBoxPreference\n        android:key=\"preferences_decode_1D\"\n        android:defaultValue=\"true\"\n        android:title=\"@string/preferences_decode_1D_title\"/>\n    <CheckBoxPreference\n        android:key=\"preferences_decode_QR\"\n        android:defaultValue=\"true\"\n        android:title=\"@string/preferences_decode_QR_title\"/>\n    <CheckBoxPreference\n        android:key=\"preferences_decode_Data_Matrix\"\n        android:defaultValue=\"true\"\n        android:title=\"@string/preferences_decode_Data_Matrix_title\"/>\n  </PreferenceCategory>\n  <PreferenceCategory android:title=\"@string/preferences_actions_title\">\n    <CheckBoxPreference\n        android:key=\"preferences_play_beep\"\n        android:defaultValue=\"true\"\n        android:title=\"@string/preferences_play_beep_title\"/>\n    <CheckBoxPreference\n        android:key=\"preferences_vibrate\"\n        android:defaultValue=\"false\"\n        android:title=\"@string/preferences_vibrate_title\"/>\n    <CheckBoxPreference\n        android:key=\"preferences_copy_to_clipboard\"\n        android:defaultValue=\"true\"\n        android:title=\"@string/preferences_copy_to_clipboard_title\"/>\n    <CheckBoxPreference\n        android:key=\"preferences_remember_duplicates\"\n        android:defaultValue=\"false\"\n        android:title=\"@string/preferences_remember_duplicates_title\"\n        android:summary=\"@string/preferences_remember_duplicates_summary\"/>\n    <CheckBoxPreference\n        android:key=\"preferences_supplemental\"\n        android:defaultValue=\"true\"\n        android:title=\"@string/preferences_supplemental_title\"\n        android:summary=\"@string/preferences_supplemental_summary\"/>\n  </PreferenceCategory>\n  <PreferenceCategory android:title=\"@string/preferences_result_title\">\n    <EditTextPreference\n        android:key=\"preferences_custom_product_search\"\n        android:title=\"@string/preferences_custom_product_search_title\"\n        android:summary=\"@string/preferences_custom_product_search_summary\"/>\n  </PreferenceCategory>\n  <PreferenceCategory android:title=\"@string/preferences_general_title\">\n    <CheckBoxPreference\n        android:key=\"preferences_front_light\"\n        android:defaultValue=\"false\"\n        android:title=\"@string/preferences_front_light_title\"\n        android:summary=\"@string/preferences_front_light_summary\"/>\n    <CheckBoxPreference\n        android:key=\"preferences_auto_focus\"\n        android:defaultValue=\"true\"\n        android:title=\"@string/preferences_auto_focus_title\"/>\n    <CheckBoxPreference\n        android:key=\"preferences_bulk_mode\"\n        android:defaultValue=\"false\"\n        android:title=\"@string/preferences_bulk_mode_title\"\n        android:summary=\"@string/preferences_bulk_mode_summary\"/>\n    <ListPreference\n        android:key=\"preferences_search_country\"\n        android:defaultValue=\"-\"\n        android:entries=\"@array/country_codes\"\n        android:entryValues=\"@array/country_codes\"\n        android:title=\"@string/preferences_search_country\"/>\n  </PreferenceCategory>\n  <PreferenceCategory android:title=\"@string/preferences_device_bug_workarounds_title\">\n    <CheckBoxPreference\n        android:key=\"preferences_disable_continuous_focus\"\n        android:defaultValue=\"true\"\n        android:title=\"@string/preferences_disable_continuous_focus_title\"\n        android:summary=\"@string/preferences_disable_continuous_focus_summary\"/>\n    <!--\n    <CheckBoxPreference\n        android:key=\"preferences_disable_exposure\"\n        android:defaultValue=\"false\"\n        android:title=\"@string/preferences_disable_exposure_title\"/>\n     -->\n  </PreferenceCategory>\n  <PreferenceCategory android:title=\"@string/preferences_try_bsplus\">\n    <com.google.zxing.client.android.pref.BSPlusPreference\n        android:title=\"@string/preferences_try_bsplus\"\n        android:summary=\"@string/preferences_try_bsplus_summary\"/>\n  </PreferenceCategory>\n</PreferenceScreen>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/BarcodeFormat.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing;\n\n/**\n * Enumerates barcode formats known to this package. Please keep alphabetized.\n *\n * @author Sean Owen\n */\npublic enum BarcodeFormat {\n\n  /** Aztec 2D barcode format. */\n  AZTEC,\n\n  /** CODABAR 1D format. */\n  CODABAR,\n\n  /** Code 39 1D format. */\n  CODE_39,\n\n  /** Code 93 1D format. */\n  CODE_93,\n\n  /** Code 128 1D format. */\n  CODE_128,\n\n  /** Data Matrix 2D barcode format. */\n  DATA_MATRIX,\n\n  /** EAN-8 1D format. */\n  EAN_8,\n\n  /** EAN-13 1D format. */\n  EAN_13,\n\n  /** ITF (Interleaved Two of Five) 1D format. */\n  ITF,\n\n  /** MaxiCode 2D barcode format. */\n  MAXICODE,\n\n  /** PDF417 format. */\n  PDF_417,\n\n  /** QR Code 2D barcode format. */\n  QR_CODE,\n\n  /** RSS 14 */\n  RSS_14,\n\n  /** RSS EXPANDED */\n  RSS_EXPANDED,\n\n  /** UPC-A 1D format. */\n  UPC_A,\n\n  /** UPC-E 1D format. */\n  UPC_E,\n\n  /** UPC/EAN extension format. Not a stand-alone format. */\n  UPC_EAN_EXTENSION\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/Binarizer.java",
    "content": "/*\n * Copyright 2009 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing;\n\nimport com.google.zxing.common.BitArray;\nimport com.google.zxing.common.BitMatrix;\n\n/**\n * This class hierarchy provides a set of methods to convert luminance data to 1 bit data.\n * It allows the algorithm to vary polymorphically, for example allowing a very expensive\n * thresholding technique for servers and a fast one for mobile. It also permits the implementation\n * to vary, e.g. a JNI version for Android and a Java fallback version for other platforms.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n */\npublic abstract class Binarizer {\n\n  private final LuminanceSource source;\n\n  protected Binarizer(LuminanceSource source) {\n    this.source = source;\n  }\n\n  public final LuminanceSource getLuminanceSource() {\n    return source;\n  }\n\n  /**\n   * Converts one row of luminance data to 1 bit data. May actually do the conversion, or return\n   * cached data. Callers should assume this method is expensive and call it as seldom as possible.\n   * This method is intended for decoding 1D barcodes and may choose to apply sharpening.\n   * For callers which only examine one row of pixels at a time, the same BitArray should be reused\n   * and passed in with each call for performance. However it is legal to keep more than one row\n   * at a time if needed.\n   *\n   * @param y The row to fetch, 0 <= y < bitmap height.\n   * @param row An optional preallocated array. If null or too small, it will be ignored.\n   *            If used, the Binarizer will call BitArray.clear(). Always use the returned object.\n   * @return The array of bits for this row (true means black).\n   */\n  public abstract BitArray getBlackRow(int y, BitArray row) throws NotFoundException;\n\n  /**\n   * Converts a 2D array of luminance data to 1 bit data. As above, assume this method is expensive\n   * and do not call it repeatedly. This method is intended for decoding 2D barcodes and may or\n   * may not apply sharpening. Therefore, a row from this matrix may not be identical to one\n   * fetched using getBlackRow(), so don't mix and match between them.\n   *\n   * @return The 2D array of bits for the image (true means black).\n   */\n  public abstract BitMatrix getBlackMatrix() throws NotFoundException;\n\n  /**\n   * Creates a new object with the same type as this Binarizer implementation, but with pristine\n   * state. This is needed because Binarizer implementations may be stateful, e.g. keeping a cache\n   * of 1 bit data. See Effective Java for why we can't use Java's clone() method.\n   *\n   * @param source The LuminanceSource this Binarizer will operate on.\n   * @return A new concrete Binarizer implementation object.\n   */\n  public abstract Binarizer createBinarizer(LuminanceSource source);\n\n  public final int getWidth() {\n    return source.getWidth();\n  }\n\n  public final int getHeight() {\n    return source.getHeight();\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/BinaryBitmap.java",
    "content": "/*\n * Copyright 2009 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing;\n\nimport com.google.zxing.common.BitArray;\nimport com.google.zxing.common.BitMatrix;\n\n/**\n * This class is the core bitmap class used by ZXing to represent 1 bit data. Reader objects\n * accept a BinaryBitmap and attempt to decode it.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n */\npublic final class BinaryBitmap {\n\n  private final Binarizer binarizer;\n  private BitMatrix matrix;\n\n  public BinaryBitmap(Binarizer binarizer) {\n    if (binarizer == null) {\n      throw new IllegalArgumentException(\"Binarizer must be non-null.\");\n    }\n    this.binarizer = binarizer;\n  }\n\n  /**\n   * @return The width of the bitmap.\n   */\n  public int getWidth() {\n    return binarizer.getWidth();\n  }\n\n  /**\n   * @return The height of the bitmap.\n   */\n  public int getHeight() {\n    return binarizer.getHeight();\n  }\n\n  /**\n   * Converts one row of luminance data to 1 bit data. May actually do the conversion, or return\n   * cached data. Callers should assume this method is expensive and call it as seldom as possible.\n   * This method is intended for decoding 1D barcodes and may choose to apply sharpening.\n   *\n   * @param y The row to fetch, 0 <= y < bitmap height.\n   * @param row An optional preallocated array. If null or too small, it will be ignored.\n   *            If used, the Binarizer will call BitArray.clear(). Always use the returned object.\n   * @return The array of bits for this row (true means black).\n   */\n  public BitArray getBlackRow(int y, BitArray row) throws NotFoundException {\n    return binarizer.getBlackRow(y, row);\n  }\n\n  /**\n   * Converts a 2D array of luminance data to 1 bit. As above, assume this method is expensive\n   * and do not call it repeatedly. This method is intended for decoding 2D barcodes and may or\n   * may not apply sharpening. Therefore, a row from this matrix may not be identical to one\n   * fetched using getBlackRow(), so don't mix and match between them.\n   *\n   * @return The 2D array of bits for the image (true means black).\n   */\n  public BitMatrix getBlackMatrix() throws NotFoundException {\n    // The matrix is created on demand the first time it is requested, then cached. There are two\n    // reasons for this:\n    // 1. This work will never be done if the caller only installs 1D Reader objects, or if a\n    //    1D Reader finds a barcode before the 2D Readers run.\n    // 2. This work will only be done once even if the caller installs multiple 2D Readers.\n    if (matrix == null) {\n      matrix = binarizer.getBlackMatrix();\n    }\n    return matrix;\n  }\n\n  /**\n   * @return Whether this bitmap can be cropped.\n   */\n  public boolean isCropSupported() {\n    return binarizer.getLuminanceSource().isCropSupported();\n  }\n\n  /**\n   * Returns a new object with cropped image data. Implementations may keep a reference to the\n   * original data rather than a copy. Only callable if isCropSupported() is true.\n   *\n   * @param left The left coordinate, 0 <= left < getWidth().\n   * @param top The top coordinate, 0 <= top <= getHeight().\n   * @param width The width of the rectangle to crop.\n   * @param height The height of the rectangle to crop.\n   * @return A cropped version of this object.\n   */\n  public BinaryBitmap crop(int left, int top, int width, int height) {\n    LuminanceSource newSource = binarizer.getLuminanceSource().crop(left, top, width, height);\n    return new BinaryBitmap(binarizer.createBinarizer(newSource));\n  }\n\n  /**\n   * @return Whether this bitmap supports counter-clockwise rotation.\n   */\n  public boolean isRotateSupported() {\n    return binarizer.getLuminanceSource().isRotateSupported();\n  }\n\n  /**\n   * Returns a new object with rotated image data by 90 degrees counterclockwise.\n   * Only callable if {@link #isRotateSupported()} is true.\n   *\n   * @return A rotated version of this object.\n   */\n  public BinaryBitmap rotateCounterClockwise() {\n    LuminanceSource newSource = binarizer.getLuminanceSource().rotateCounterClockwise();\n    return new BinaryBitmap(binarizer.createBinarizer(newSource));\n  }\n\n  /**\n   * Returns a new object with rotated image data by 45 degrees counterclockwise.\n   * Only callable if {@link #isRotateSupported()} is true.\n   *\n   * @return A rotated version of this object.\n   */\n  public BinaryBitmap rotateCounterClockwise45() {\n    LuminanceSource newSource = binarizer.getLuminanceSource().rotateCounterClockwise45();\n    return new BinaryBitmap(binarizer.createBinarizer(newSource));\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/ChecksumException.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing;\n\n/**\n * Thrown when a barcode was successfully detected and decoded, but\n * was not returned because its checksum feature failed.\n *\n * @author Sean Owen\n */\npublic final class ChecksumException extends ReaderException {\n\n  private static final ChecksumException instance = new ChecksumException();\n\n  private ChecksumException() {\n    // do nothing\n  }\n\n  public static ChecksumException getChecksumInstance() {\n    return instance;\n  }\n\n}"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/DecodeHintType.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing;\n\n/**\n * Encapsulates a type of hint that a caller may pass to a barcode reader to help it\n * more quickly or accurately decode it. It is up to implementations to decide what,\n * if anything, to do with the information that is supplied.\n *\n * @author Sean Owen\n * @author dswitkin@google.com (Daniel Switkin)\n * @see Reader#decode(BinaryBitmap,java.util.Map)\n */\npublic enum DecodeHintType {\n\n  /**\n   * Unspecified, application-specific hint. Maps to an unspecified {@link Object}.\n   */\n OTHER,\n\n  /**\n   * Image is a pure monochrome image of a barcode. Doesn't matter what it maps to;\n   * use {@link Boolean#TRUE}.\n   */\n  PURE_BARCODE,\n\n  /**\n   * Image is known to be of one of a few possible formats.\n   * Maps to a {@link java.util.List} of {@link BarcodeFormat}s.\n   */\n  POSSIBLE_FORMATS,\n\n  /**\n   * Spend more time to try to find a barcode; optimize for accuracy, not speed.\n   * Doesn't matter what it maps to; use {@link Boolean#TRUE}.\n   */\n  TRY_HARDER,\n\n  /**\n   * Specifies what character encoding to use when decoding, where applicable (type String)\n   */\n  CHARACTER_SET,\n\n  /**\n   * Allowed lengths of encoded data -- reject anything else. Maps to an int[].\n   */\n  ALLOWED_LENGTHS,\n\n  /**\n   * Assume Code 39 codes employ a check digit. Maps to {@link Boolean}.\n   */\n  ASSUME_CODE_39_CHECK_DIGIT,\n\n  /**\n   * The caller needs to be notified via callback when a possible {@link ResultPoint}\n   * is found. Maps to a {@link ResultPointCallback}.\n   */\n  NEED_RESULT_POINT_CALLBACK,\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/EncodeHintType.java",
    "content": "/*\n * Copyright 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing;\n\n/**\n * These are a set of hints that you may pass to Writers to specify their behavior.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n */\npublic enum EncodeHintType {\n\n  /**\n   * Specifies what degree of error correction to use, for example in QR Codes.\n   * Type depends on the encoder. For example for QR codes it's type\n   * {@link com.google.zxing.qrcode.decoder.ErrorCorrectionLevel ErrorCorrectionLevel}.\n   */\n  ERROR_CORRECTION,\n\n  /**\n   * Specifies what character encoding to use where applicable (type {@link String})\n   */\n  CHARACTER_SET,\n\n  /**\n   * Specifies margin, in pixels, to use when generating the barcode. The meaning can vary\n   * by format; for example it controls margin before and after the barcode horizontally for\n   * most 1D formats. (Type {@link Integer}).\n   */\n  MARGIN,\n\n  /**\n   * Specifies whether to use compact mode for PDF417 (type {@link Boolean}).\n   */\n  PDF417_COMPACT,\n\n  /**\n   * Specifies what compaction mode to use for PDF417 (type\n   * {@link com.google.zxing.pdf417.encoder.Compaction Compaction}).\n   */\n  PDF417_COMPACTION,\n\n  /**\n   * Specifies the minimum and maximum number of rows and columns for PDF417 (type\n   * {@link com.google.zxing.pdf417.encoder.Dimensions Dimensions}).\n   */\n  PDF417_DIMENSIONS,\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/FakeR.java",
    "content": "package com.google.zxing;\r\n\r\nimport android.app.Activity;\r\nimport android.content.Context;\r\n\r\n/**\r\n * R replacement for PhoneGap Build.\r\n *\r\n * ([^.\\w])R\\.(\\w+)\\.(\\w+)\r\n * $1fakeR(\"$2\", \"$3\")\r\n *\r\n * @author Maciej Nux Jaros\r\n */\r\npublic class FakeR {\r\n\tprivate Context context;\r\n\tprivate String packageName;\r\n\r\n\tpublic FakeR(Activity activity) {\r\n\t\tcontext = activity.getApplicationContext();\r\n\t\tpackageName = context.getPackageName();\r\n\t}\r\n\r\n\tpublic FakeR(Context context) {\r\n\t\tthis.context = context;\r\n\t\tpackageName = context.getPackageName();\r\n\t}\r\n\r\n\tpublic int getId(String group, String key) {\r\n\t\treturn context.getResources().getIdentifier(key, group, packageName);\r\n\t}\r\n\r\n\tpublic static int getId(Context context, String group, String key) {\r\n\t\treturn context.getResources().getIdentifier(key, group, context.getPackageName());\r\n\t}\r\n}\r\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/FormatException.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing;\n\n/**\n * Thrown when a barcode was successfully detected, but some aspect of\n * the content did not conform to the barcode's format rules. This could have\n * been due to a mis-detection.\n *\n * @author Sean Owen\n */\npublic final class FormatException extends ReaderException {\n\n  private static final FormatException instance = new FormatException();\n\n  private FormatException() {\n    // do nothing\n  }\n\n  public static FormatException getFormatInstance() {\n    return instance;\n  }\n\n}"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/LuminanceSource.java",
    "content": "/*\n * Copyright 2009 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing;\n\n/**\n * The purpose of this class hierarchy is to abstract different bitmap implementations across\n * platforms into a standard interface for requesting greyscale luminance values. The interface\n * only provides immutable methods; therefore crop and rotation create copies. This is to ensure\n * that one Reader does not modify the original luminance source and leave it in an unknown state\n * for other Readers in the chain.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n */\npublic abstract class LuminanceSource {\n\n  private final int width;\n  private final int height;\n\n  protected LuminanceSource(int width, int height) {\n    this.width = width;\n    this.height = height;\n  }\n\n  /**\n   * Fetches one row of luminance data from the underlying platform's bitmap. Values range from\n   * 0 (black) to 255 (white). Because Java does not have an unsigned byte type, callers will have\n   * to bitwise and with 0xff for each value. It is preferable for implementations of this method\n   * to only fetch this row rather than the whole image, since no 2D Readers may be installed and\n   * getMatrix() may never be called.\n   *\n   * @param y The row to fetch, 0 <= y < getHeight().\n   * @param row An optional preallocated array. If null or too small, it will be ignored.\n   *            Always use the returned object, and ignore the .length of the array.\n   * @return An array containing the luminance data.\n   */\n  public abstract byte[] getRow(int y, byte[] row);\n\n  /**\n   * Fetches luminance data for the underlying bitmap. Values should be fetched using:\n   * int luminance = array[y * width + x] & 0xff;\n   *\n   * @return A row-major 2D array of luminance values. Do not use result.length as it may be\n   *         larger than width * height bytes on some platforms. Do not modify the contents\n   *         of the result.\n   */\n  public abstract byte[] getMatrix();\n\n  /**\n   * @return The width of the bitmap.\n   */\n  public final int getWidth() {\n    return width;\n  }\n\n  /**\n   * @return The height of the bitmap.\n   */\n  public final int getHeight() {\n    return height;\n  }\n\n  /**\n   * @return Whether this subclass supports cropping.\n   */\n  public boolean isCropSupported() {\n    return false;\n  }\n\n  /**\n   * Returns a new object with cropped image data. Implementations may keep a reference to the\n   * original data rather than a copy. Only callable if isCropSupported() is true.\n   *\n   * @param left The left coordinate, 0 <= left < getWidth().\n   * @param top The top coordinate, 0 <= top <= getHeight().\n   * @param width The width of the rectangle to crop.\n   * @param height The height of the rectangle to crop.\n   * @return A cropped version of this object.\n   */\n  public LuminanceSource crop(int left, int top, int width, int height) {\n    throw new UnsupportedOperationException(\"This luminance source does not support cropping.\");\n  }\n\n  /**\n   * @return Whether this subclass supports counter-clockwise rotation.\n   */\n  public boolean isRotateSupported() {\n    return false;\n  }\n\n  /**\n   * Returns a new object with rotated image data by 90 degrees counterclockwise.\n   * Only callable if {@link #isRotateSupported()} is true.\n   *\n   * @return A rotated version of this object.\n   */\n  public LuminanceSource rotateCounterClockwise() {\n    throw new UnsupportedOperationException(\"This luminance source does not support rotation by 90 degrees.\");\n  }\n\n  /**\n   * Returns a new object with rotated image data by 45 degrees counterclockwise.\n   * Only callable if {@link #isRotateSupported()} is true.\n   *\n   * @return A rotated version of this object.\n   */\n  public LuminanceSource rotateCounterClockwise45() {\n    throw new UnsupportedOperationException(\"This luminance source does not support rotation by 45 degrees.\");\n  }\n\n  @Override\n  public final String toString() {\n    byte[] row = new byte[width];\n    StringBuilder result = new StringBuilder(height * (width + 1));\n    for (int y = 0; y < height; y++) {\n      row = getRow(y, row);\n      for (int x = 0; x < width; x++) {\n        int luminance = row[x] & 0xFF;\n        char c;\n        if (luminance < 0x40) {\n          c = '#';\n        } else if (luminance < 0x80) {\n          c = '+';\n        } else if (luminance < 0xC0) {\n          c = '.';\n        } else {\n          c = ' ';\n        }\n        result.append(c);\n      }\n      result.append('\\n');\n    }\n    return result.toString();\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/MultiFormatReader.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing;\n\nimport com.google.zxing.aztec.AztecReader;\nimport com.google.zxing.datamatrix.DataMatrixReader;\nimport com.google.zxing.maxicode.MaxiCodeReader;\nimport com.google.zxing.oned.MultiFormatOneDReader;\nimport com.google.zxing.pdf417.PDF417Reader;\nimport com.google.zxing.qrcode.QRCodeReader;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Map;\n\n/**\n * MultiFormatReader is a convenience class and the main entry point into the library for most uses.\n * By default it attempts to decode all barcode formats that the library supports. Optionally, you\n * can provide a hints object to request different behavior, for example only decoding QR codes.\n *\n * @author Sean Owen\n * @author dswitkin@google.com (Daniel Switkin)\n */\npublic final class MultiFormatReader implements Reader {\n\n  private Map<DecodeHintType,?> hints;\n  private Reader[] readers;\n\n  /**\n   * This version of decode honors the intent of Reader.decode(BinaryBitmap) in that it\n   * passes null as a hint to the decoders. However, that makes it inefficient to call repeatedly.\n   * Use setHints() followed by decodeWithState() for continuous scan applications.\n   *\n   * @param image The pixel data to decode\n   * @return The contents of the image\n   * @throws NotFoundException Any errors which occurred\n   */\n  @Override\n  public Result decode(BinaryBitmap image) throws NotFoundException {\n    setHints(null);\n    return decodeInternal(image);\n  }\n\n  /**\n   * Decode an image using the hints provided. Does not honor existing state.\n   *\n   * @param image The pixel data to decode\n   * @param hints The hints to use, clearing the previous state.\n   * @return The contents of the image\n   * @throws NotFoundException Any errors which occurred\n   */\n  @Override\n  public Result decode(BinaryBitmap image, Map<DecodeHintType,?> hints) throws NotFoundException {\n    setHints(hints);\n    return decodeInternal(image);\n  }\n\n  /**\n   * Decode an image using the state set up by calling setHints() previously. Continuous scan\n   * clients will get a <b>large</b> speed increase by using this instead of decode().\n   *\n   * @param image The pixel data to decode\n   * @return The contents of the image\n   * @throws NotFoundException Any errors which occurred\n   */\n  public Result decodeWithState(BinaryBitmap image) throws NotFoundException {\n    // Make sure to set up the default state so we don't crash\n    if (readers == null) {\n      setHints(null);\n    }\n    return decodeInternal(image);\n  }\n\n  /**\n   * This method adds state to the MultiFormatReader. By setting the hints once, subsequent calls\n   * to decodeWithState(image) can reuse the same set of readers without reallocating memory. This\n   * is important for performance in continuous scan clients.\n   *\n   * @param hints The set of hints to use for subsequent calls to decode(image)\n   */\n  public void setHints(Map<DecodeHintType,?> hints) {\n    this.hints = hints;\n\n    boolean tryHarder = hints != null && hints.containsKey(DecodeHintType.TRY_HARDER);\n    Collection<BarcodeFormat> formats =\n        hints == null ? null : (Collection<BarcodeFormat>) hints.get(DecodeHintType.POSSIBLE_FORMATS);\n    Collection<Reader> readers = new ArrayList<Reader>();\n    if (formats != null) {\n      boolean addOneDReader =\n          formats.contains(BarcodeFormat.UPC_A) ||\n          formats.contains(BarcodeFormat.UPC_E) ||\n          formats.contains(BarcodeFormat.EAN_13) ||\n          formats.contains(BarcodeFormat.EAN_8) ||\n          formats.contains(BarcodeFormat.CODABAR) ||\n          formats.contains(BarcodeFormat.CODE_39) ||\n          formats.contains(BarcodeFormat.CODE_93) ||\n          formats.contains(BarcodeFormat.CODE_128) ||\n          formats.contains(BarcodeFormat.ITF) ||\n          formats.contains(BarcodeFormat.RSS_14) ||\n          formats.contains(BarcodeFormat.RSS_EXPANDED);\n      // Put 1D readers upfront in \"normal\" mode\n      if (addOneDReader && !tryHarder) {\n        readers.add(new MultiFormatOneDReader(hints));\n      }\n      if (formats.contains(BarcodeFormat.QR_CODE)) {\n        readers.add(new QRCodeReader());\n      }\n      if (formats.contains(BarcodeFormat.DATA_MATRIX)) {\n        readers.add(new DataMatrixReader());\n      }\n      if (formats.contains(BarcodeFormat.AZTEC)) {\n        readers.add(new AztecReader());\n      }\n      if (formats.contains(BarcodeFormat.PDF_417)) {\n         readers.add(new PDF417Reader());\n      }\n      if (formats.contains(BarcodeFormat.MAXICODE)) {\n         readers.add(new MaxiCodeReader());\n      }\n      // At end in \"try harder\" mode\n      if (addOneDReader && tryHarder) {\n        readers.add(new MultiFormatOneDReader(hints));\n      }\n    }\n    if (readers.isEmpty()) {\n      if (!tryHarder) {\n        readers.add(new MultiFormatOneDReader(hints));\n      }\n\n      readers.add(new QRCodeReader());\n      readers.add(new DataMatrixReader());\n      readers.add(new AztecReader());\n      readers.add(new PDF417Reader());\n      readers.add(new MaxiCodeReader());\n\n      if (tryHarder) {\n        readers.add(new MultiFormatOneDReader(hints));\n      }\n    }\n    this.readers = readers.toArray(new Reader[readers.size()]);\n  }\n\n  @Override\n  public void reset() {\n    if (readers != null) {\n      for (Reader reader : readers) {\n        reader.reset();\n      }\n    }\n  }\n\n  private Result decodeInternal(BinaryBitmap image) throws NotFoundException {\n    if (readers != null) {\n      for (Reader reader : readers) {\n        try {\n          return reader.decode(image, hints);\n        } catch (ReaderException re) {\n          // continue\n        }\n      }\n    }\n    throw NotFoundException.getNotFoundInstance();\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/MultiFormatWriter.java",
    "content": "/*\n * Copyright 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing;\n\nimport com.google.zxing.common.BitMatrix;\nimport com.google.zxing.oned.CodaBarWriter;\nimport com.google.zxing.oned.Code128Writer;\nimport com.google.zxing.oned.Code39Writer;\nimport com.google.zxing.oned.EAN13Writer;\nimport com.google.zxing.oned.EAN8Writer;\nimport com.google.zxing.oned.ITFWriter;\nimport com.google.zxing.oned.UPCAWriter;\nimport com.google.zxing.pdf417.encoder.PDF417Writer;\nimport com.google.zxing.qrcode.QRCodeWriter;\n\nimport java.util.Map;\n\n/**\n * This is a factory class which finds the appropriate Writer subclass for the BarcodeFormat\n * requested and encodes the barcode with the supplied contents.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n */\npublic final class MultiFormatWriter implements Writer {\n\n  @Override\n  public BitMatrix encode(String contents,\n                          BarcodeFormat format,\n                          int width,\n                          int height) throws WriterException {\n    return encode(contents, format, width, height, null);\n  }\n\n  @Override\n  public BitMatrix encode(String contents,\n                          BarcodeFormat format,\n                          int width, int height,\n                          Map<EncodeHintType,?> hints) throws WriterException {\n\n    Writer writer;\n    switch (format) {\n      case EAN_8:\n        writer = new EAN8Writer();\n        break;\n      case EAN_13:\n        writer = new EAN13Writer();\n        break;\n      case UPC_A:\n        writer = new UPCAWriter();\n        break;\n      case QR_CODE:\n        writer = new QRCodeWriter();\n        break;\n      case CODE_39:\n        writer = new Code39Writer();\n        break;\n      case CODE_128:\n        writer = new Code128Writer();\n        break;\n      case ITF:\n        writer = new ITFWriter();\n        break;\n      case PDF_417:\n        writer = new PDF417Writer();\n        break;\n      case CODABAR:\n        writer = new CodaBarWriter();\n        break;\n      default:\n        throw new IllegalArgumentException(\"No encoder available for format \" + format);\n    }\n    return writer.encode(contents, format, width, height, hints);\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/NotFoundException.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing;\n\n/**\n * Thrown when a barcode was not found in the image. It might have been\n * partially detected but could not be confirmed.\n *\n * @author Sean Owen\n */\npublic final class NotFoundException extends ReaderException {\n\n  private static final NotFoundException instance = new NotFoundException();\n\n  private NotFoundException() {\n    // do nothing\n  }\n\n  public static NotFoundException getNotFoundInstance() {\n    return instance;\n  }\n\n}"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/PlanarYUVLuminanceSource.java",
    "content": "/*\n * Copyright 2009 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing;\n\n/**\n * This object extends LuminanceSource around an array of YUV data returned from the camera driver,\n * with the option to crop to a rectangle within the full data. This can be used to exclude\n * superfluous pixels around the perimeter and speed up decoding.\n *\n * It works for any pixel format where the Y channel is planar and appears first, including\n * YCbCr_420_SP and YCbCr_422_SP.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n */\npublic final class PlanarYUVLuminanceSource extends LuminanceSource {\n\n  private final byte[] yuvData;\n  private final int dataWidth;\n  private final int dataHeight;\n  private final int left;\n  private final int top;\n\n  public PlanarYUVLuminanceSource(byte[] yuvData,\n                                  int dataWidth,\n                                  int dataHeight,\n                                  int left,\n                                  int top,\n                                  int width,\n                                  int height,\n                                  boolean reverseHorizontal) {\n    super(width, height);\n\n    if (left + width > dataWidth || top + height > dataHeight) {\n//      throw new IllegalArgumentException(\"Crop rectangle does not fit within image data. Left:\" + left + \", width:\" + width + \", dataWidth:\" + dataWidth + \", top:\" + top + \", height:\" + height + \", dataHeight:\" + dataHeight);\n    }\n\n    this.yuvData = yuvData;\n    this.dataWidth = dataWidth;\n    this.dataHeight = dataHeight;\n    this.left = left;\n    this.top = top;\n    if (reverseHorizontal) {\n      reverseHorizontal(width, height);\n    }\n  }\n\n  @Override\n  public byte[] getRow(int y, byte[] row) {\n    if (y < 0 || y >= getHeight()) {\n      throw new IllegalArgumentException(\"Requested row is outside the image: \" + y);\n    }\n    int width = getWidth();\n    if (row == null || row.length < width) {\n      row = new byte[width];\n    }\n    int offset = (y + top) * dataWidth + left;\n    System.arraycopy(yuvData, offset, row, 0, width);\n    return row;\n  }\n\n  @Override\n  public byte[] getMatrix() {\n    int width = getWidth();\n    int height = getHeight();\n\n    // If the caller asks for the entire underlying image, save the copy and give them the\n    // original data. The docs specifically warn that result.length must be ignored.\n    if (width == dataWidth && height == dataHeight) {\n      return yuvData;\n    }\n\n    int area = width * height;\n    byte[] matrix = new byte[area];\n    int inputOffset = top * dataWidth + left;\n\n    // If the width matches the full width of the underlying data, perform a single copy.\n    if (width == dataWidth) {\n      System.arraycopy(yuvData, inputOffset, matrix, 0, area);\n      return matrix;\n    }\n\n    // Otherwise copy one cropped row at a time.\n    byte[] yuv = yuvData;\n    for (int y = 0; y < height; y++) {\n      int outputOffset = y * width;\n      System.arraycopy(yuv, inputOffset, matrix, outputOffset, width);\n      inputOffset += dataWidth;\n    }\n    return matrix;\n  }\n\n  @Override\n  public boolean isCropSupported() {\n    return true;\n  }\n\n  @Override\n  public LuminanceSource crop(int left, int top, int width, int height) {\n    return new PlanarYUVLuminanceSource(yuvData,\n                                        dataWidth,\n                                        dataHeight,\n                                        this.left + left,\n                                        this.top + top,\n                                        width,\n                                        height,\n                                        false);\n  }\n\n  public int[] renderCroppedGreyscaleBitmap() {\n    int width = getWidth();\n    int height = getHeight();\n    int[] pixels = new int[width * height];\n    byte[] yuv = yuvData;\n    int inputOffset = top * dataWidth + left;\n\n    for (int y = 0; y < height; y++) {\n      int outputOffset = y * width;\n      for (int x = 0; x < width; x++) {\n        int grey = yuv[inputOffset + x] & 0xff;\n        pixels[outputOffset + x] = 0xFF000000 | (grey * 0x00010101);\n      }\n      inputOffset += dataWidth;\n    }\n    return pixels;\n  }\n\n  private void reverseHorizontal(int width, int height) {\n    byte[] yuvData = this.yuvData;\n    for (int y = 0, rowStart = top * dataWidth + left; y < height; y++, rowStart += dataWidth) {\n      int middle = rowStart + width / 2;\n      for (int x1 = rowStart, x2 = rowStart + width - 1; x1 < middle; x1++, x2--) {\n        byte temp = yuvData[x1];\n        yuvData[x1] = yuvData[x2];\n        yuvData[x2] = temp;\n      }\n    }\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/RGBLuminanceSource.java",
    "content": "/*\n * Copyright 2009 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing;\n\n/**\n * This class is used to help decode images from files which arrive as RGB data from\n * an ARGB pixel array. It does not support rotation.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n * @author Betaminos\n */\npublic final class RGBLuminanceSource extends LuminanceSource {\n\n  private final byte[] luminances;\n  private final int dataWidth;\n  private final int dataHeight;\n  private final int left;\n  private final int top;\n\n  public RGBLuminanceSource(int width, int height, int[] pixels) {\n    super(width, height);\n\n    dataWidth = width;\n    dataHeight = height;\n    left = 0;\n    top = 0;\n\n    // In order to measure pure decoding speed, we convert the entire image to a greyscale array\n    // up front, which is the same as the Y channel of the YUVLuminanceSource in the real app.\n    luminances = new byte[width * height];\n    for (int y = 0; y < height; y++) {\n      int offset = y * width;\n      for (int x = 0; x < width; x++) {\n        int pixel = pixels[offset + x];\n        int r = (pixel >> 16) & 0xff;\n        int g = (pixel >> 8) & 0xff;\n        int b = pixel & 0xff;\n        if (r == g && g == b) {\n          // Image is already greyscale, so pick any channel.\n          luminances[offset + x] = (byte) r;\n        } else {\n          // Calculate luminance cheaply, favoring green.\n          luminances[offset + x] = (byte) ((r + g + g + b) >> 2);\n        }\n      }\n    }\n  }\n  \n  private RGBLuminanceSource(byte[] pixels,\n                             int dataWidth,\n                             int dataHeight,\n                             int left,\n                             int top,\n                             int width,\n                             int height) {\n    super(width, height);\n    if (left + width > dataWidth || top + height > dataHeight) {\n      throw new IllegalArgumentException(\"Crop rectangle does not fit within image data.\");\n    }\n    this.luminances = pixels;\n    this.dataWidth = dataWidth;\n    this.dataHeight = dataHeight;\n    this.left = left;\n    this.top = top;\n  }\n\n  @Override\n  public byte[] getRow(int y, byte[] row) {\n    if (y < 0 || y >= getHeight()) {\n      throw new IllegalArgumentException(\"Requested row is outside the image: \" + y);\n    }\n    int width = getWidth();\n    if (row == null || row.length < width) {\n      row = new byte[width];\n    }\n    int offset = (y + top) * dataWidth + left;\n    System.arraycopy(luminances, offset, row, 0, width);\n    return row;\n  }\n\n  @Override\n  public byte[] getMatrix() {\n    int width = getWidth();\n    int height = getHeight();\n\n    // If the caller asks for the entire underlying image, save the copy and give them the\n    // original data. The docs specifically warn that result.length must be ignored.\n    if (width == dataWidth && height == dataHeight) {\n      return luminances;\n    }\n\n    int area = width * height;\n    byte[] matrix = new byte[area];\n    int inputOffset = top * dataWidth + left;\n\n    // If the width matches the full width of the underlying data, perform a single copy.\n    if (width == dataWidth) {\n      System.arraycopy(luminances, inputOffset, matrix, 0, area);\n      return matrix;\n    }\n\n    // Otherwise copy one cropped row at a time.\n    byte[] rgb = luminances;\n    for (int y = 0; y < height; y++) {\n      int outputOffset = y * width;\n      System.arraycopy(rgb, inputOffset, matrix, outputOffset, width);\n      inputOffset += dataWidth;\n    }\n    return matrix;\n  }\n  \n  @Override\n  public boolean isCropSupported() {\n    return true;\n  }\n\n  @Override\n  public LuminanceSource crop(int left, int top, int width, int height) {\n    return new RGBLuminanceSource(luminances,\n                                  dataWidth,\n                                  dataHeight,\n                                  this.left + left,\n                                  this.top + top,\n                                  width,\n                                  height);\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/Reader.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing;\n\nimport java.util.Map;\n\n/**\n * Implementations of this interface can decode an image of a barcode in some format into\n * the String it encodes. For example, {@link com.google.zxing.qrcode.QRCodeReader} can\n * decode a QR code. The decoder may optionally receive hints from the caller which may help\n * it decode more quickly or accurately.\n *\n * See {@link com.google.zxing.MultiFormatReader}, which attempts to determine what barcode\n * format is present within the image as well, and then decodes it accordingly.\n *\n * @author Sean Owen\n * @author dswitkin@google.com (Daniel Switkin)\n */\npublic interface Reader {\n\n  /**\n   * Locates and decodes a barcode in some format within an image.\n   *\n   * @param image image of barcode to decode\n   * @return String which the barcode encodes\n   * @throws NotFoundException if the barcode cannot be located or decoded for any reason\n   */\n  Result decode(BinaryBitmap image) throws NotFoundException, ChecksumException, FormatException;\n\n  /**\n   * Locates and decodes a barcode in some format within an image. This method also accepts\n   * hints, each possibly associated to some data, which may help the implementation decode.\n   *\n   * @param image image of barcode to decode\n   * @param hints passed as a {@link java.util.Map} from {@link com.google.zxing.DecodeHintType}\n   * to arbitrary data. The\n   * meaning of the data depends upon the hint type. The implementation may or may not do\n   * anything with these hints.\n   * @return String which the barcode encodes\n   * @throws NotFoundException if the barcode cannot be located or decoded for any reason\n   */\n  Result decode(BinaryBitmap image, Map<DecodeHintType,?> hints)\n      throws NotFoundException, ChecksumException, FormatException;\n\n  /**\n   * Resets any internal state the implementation has after a decode, to prepare it\n   * for reuse.\n   */\n  void reset();\n\n}"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/ReaderException.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing;\n\n/**\n * The general exception class throw when something goes wrong during decoding of a barcode.\n * This includes, but is not limited to, failing checksums / error correction algorithms, being\n * unable to locate finder timing patterns, and so on.\n *\n * @author Sean Owen\n */\npublic abstract class ReaderException extends Exception {\n\n  ReaderException() {\n    // do nothing\n  }\n\n  // Prevent stack traces from being taken\n  // srowen says: huh, my IDE is saying this is not an override. native methods can't be overridden?\n  // This, at least, does not hurt. Because we use a singleton pattern here, it doesn't matter anyhow.\n  @Override\n  public final Throwable fillInStackTrace() {\n    return null;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/Result.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing;\n\nimport java.util.EnumMap;\nimport java.util.Map;\n\n/**\n * <p>Encapsulates the result of decoding a barcode within an image.</p>\n *\n * @author Sean Owen\n */\npublic final class Result {\n\n  private final String text;\n  private final byte[] rawBytes;\n  private ResultPoint[] resultPoints;\n  private final BarcodeFormat format;\n  private Map<ResultMetadataType,Object> resultMetadata;\n  private final long timestamp;\n\n  public Result(String text,\n                byte[] rawBytes,\n                ResultPoint[] resultPoints,\n                BarcodeFormat format) {\n    this(text, rawBytes, resultPoints, format, System.currentTimeMillis());\n  }\n\n  public Result(String text,\n                byte[] rawBytes,\n                ResultPoint[] resultPoints,\n                BarcodeFormat format,\n                long timestamp) {\n    this.text = text;\n    this.rawBytes = rawBytes;\n    this.resultPoints = resultPoints;\n    this.format = format;\n    this.resultMetadata = null;\n    this.timestamp = timestamp;\n  }\n\n  /**\n   * @return raw text encoded by the barcode\n   */\n  public String getText() {\n    return text;\n  }\n\n  /**\n   * @return raw bytes encoded by the barcode, if applicable, otherwise {@code null}\n   */\n  public byte[] getRawBytes() {\n    return rawBytes;\n  }\n\n  /**\n   * @return points related to the barcode in the image. These are typically points\n   *         identifying finder patterns or the corners of the barcode. The exact meaning is\n   *         specific to the type of barcode that was decoded.\n   */\n  public ResultPoint[] getResultPoints() {\n    return resultPoints;\n  }\n\n  /**\n   * @return {@link BarcodeFormat} representing the format of the barcode that was decoded\n   */\n  public BarcodeFormat getBarcodeFormat() {\n    return format;\n  }\n\n  /**\n   * @return {@link Map} mapping {@link ResultMetadataType} keys to values. May be\n   *   {@code null}. This contains optional metadata about what was detected about the barcode,\n   *   like orientation.\n   */\n  public Map<ResultMetadataType,Object> getResultMetadata() {\n    return resultMetadata;\n  }\n\n  public void putMetadata(ResultMetadataType type, Object value) {\n    if (resultMetadata == null) {\n      resultMetadata = new EnumMap<ResultMetadataType,Object>(ResultMetadataType.class);\n    }\n    resultMetadata.put(type, value);\n  }\n\n  public void putAllMetadata(Map<ResultMetadataType,Object> metadata) {\n    if (metadata != null) {\n      if (resultMetadata == null) {\n        resultMetadata = metadata;\n      } else {\n        resultMetadata.putAll(metadata);\n      }\n    }\n  }\n\n  public void addResultPoints(ResultPoint[] newPoints) {\n    ResultPoint[] oldPoints = resultPoints;\n    if (oldPoints == null) {\n      resultPoints = newPoints;\n    } else if (newPoints != null && newPoints.length > 0) {\n      ResultPoint[] allPoints = new ResultPoint[oldPoints.length + newPoints.length];\n      System.arraycopy(oldPoints, 0, allPoints, 0, oldPoints.length);\n      System.arraycopy(newPoints, 0, allPoints, oldPoints.length, newPoints.length);\n      resultPoints = allPoints;\n    }\n  }\n\n  public long getTimestamp() {\n    return timestamp;\n  }\n\n  @Override\n  public String toString() {\n    return text;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/ResultMetadataType.java",
    "content": "/*\n * Copyright 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing;\n\n/**\n * Represents some type of metadata about the result of the decoding that the decoder\n * wishes to communicate back to the caller.\n *\n * @author Sean Owen\n */\npublic enum ResultMetadataType {\n\n  /**\n   * Unspecified, application-specific metadata. Maps to an unspecified {@link Object}.\n   */\n  OTHER,\n\n  /**\n   * Denotes the likely approximate orientation of the barcode in the image. This value\n   * is given as degrees rotated clockwise from the normal, upright orientation.\n   * For example a 1D barcode which was found by reading top-to-bottom would be\n   * said to have orientation \"90\". This key maps to an {@link Integer} whose\n   * value is in the range [0,360).\n   */\n  ORIENTATION,\n\n  /**\n   * <p>2D barcode formats typically encode text, but allow for a sort of 'byte mode'\n   * which is sometimes used to encode binary data. While {@link Result} makes available\n   * the complete raw bytes in the barcode for these formats, it does not offer the bytes\n   * from the byte segments alone.</p>\n   *\n   * <p>This maps to a {@link java.util.List} of byte arrays corresponding to the\n   * raw bytes in the byte segments in the barcode, in order.</p>\n   */\n  BYTE_SEGMENTS,\n\n  /**\n   * Error correction level used, if applicable. The value type depends on the\n   * format, but is typically a String.\n   */\n  ERROR_CORRECTION_LEVEL,\n\n  /**\n   * For some periodicals, indicates the issue number as an {@link Integer}.\n   */\n  ISSUE_NUMBER,\n\n  /**\n   * For some products, indicates the suggested retail price in the barcode as a\n   * formatted {@link String}.\n   */\n  SUGGESTED_PRICE ,\n\n  /**\n   * For some products, the possible country of manufacture as a {@link String} denoting the\n   * ISO country code. Some map to multiple possible countries, like \"US/CA\".\n   */\n  POSSIBLE_COUNTRY,\n\n  /**\n   * For some products, the extension text\n   */\n  UPC_EAN_EXTENSION,\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/ResultPoint.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing;\n\nimport com.google.zxing.common.detector.MathUtils;\n\n/**\n * <p>Encapsulates a point of interest in an image containing a barcode. Typically, this\n * would be the location of a finder pattern or the corner of the barcode, for example.</p>\n *\n * @author Sean Owen\n */\npublic class ResultPoint {\n\n  private final float x;\n  private final float y;\n\n  public ResultPoint(float x, float y) {\n    this.x = x;\n    this.y = y;\n  }\n\n  public final float getX() {\n    return x;\n  }\n\n  public final float getY() {\n    return y;\n  }\n\n  @Override\n  public final boolean equals(Object other) {\n    if (other instanceof ResultPoint) {\n      ResultPoint otherPoint = (ResultPoint) other;\n      return x == otherPoint.x && y == otherPoint.y;\n    }\n    return false;\n  }\n\n  @Override\n  public final int hashCode() {\n    return 31 * Float.floatToIntBits(x) + Float.floatToIntBits(y);\n  }\n\n  @Override\n  public final String toString() {\n    StringBuilder result = new StringBuilder(25);\n    result.append('(');\n    result.append(x);\n    result.append(',');\n    result.append(y);\n    result.append(')');\n    return result.toString();\n  }\n\n  /**\n   * <p>Orders an array of three ResultPoints in an order [A,B,C] such that AB < AC and\n   * BC < AC and the angle between BC and BA is less than 180 degrees.\n   */\n  public static void orderBestPatterns(ResultPoint[] patterns) {\n\n    // Find distances between pattern centers\n    float zeroOneDistance = distance(patterns[0], patterns[1]);\n    float oneTwoDistance = distance(patterns[1], patterns[2]);\n    float zeroTwoDistance = distance(patterns[0], patterns[2]);\n\n    ResultPoint pointA;\n    ResultPoint pointB;\n    ResultPoint pointC;\n    // Assume one closest to other two is B; A and C will just be guesses at first\n    if (oneTwoDistance >= zeroOneDistance && oneTwoDistance >= zeroTwoDistance) {\n      pointB = patterns[0];\n      pointA = patterns[1];\n      pointC = patterns[2];\n    } else if (zeroTwoDistance >= oneTwoDistance && zeroTwoDistance >= zeroOneDistance) {\n      pointB = patterns[1];\n      pointA = patterns[0];\n      pointC = patterns[2];\n    } else {\n      pointB = patterns[2];\n      pointA = patterns[0];\n      pointC = patterns[1];\n    }\n\n    // Use cross product to figure out whether A and C are correct or flipped.\n    // This asks whether BC x BA has a positive z component, which is the arrangement\n    // we want for A, B, C. If it's negative, then we've got it flipped around and\n    // should swap A and C.\n    if (crossProductZ(pointA, pointB, pointC) < 0.0f) {\n      ResultPoint temp = pointA;\n      pointA = pointC;\n      pointC = temp;\n    }\n\n    patterns[0] = pointA;\n    patterns[1] = pointB;\n    patterns[2] = pointC;\n  }\n\n\n  /**\n   * @return distance between two points\n   */\n  public static float distance(ResultPoint pattern1, ResultPoint pattern2) {\n    return MathUtils.distance(pattern1.x, pattern1.y, pattern2.x, pattern2.y);\n  }\n\n  /**\n   * Returns the z component of the cross product between vectors BC and BA.\n   */\n  private static float crossProductZ(ResultPoint pointA,\n                                     ResultPoint pointB,\n                                     ResultPoint pointC) {\n    float bX = pointB.x;\n    float bY = pointB.y;\n    return ((pointC.x - bX) * (pointA.y - bY)) - ((pointC.y - bY) * (pointA.x - bX));\n  }\n\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/ResultPointCallback.java",
    "content": "/*\n * Copyright 2009 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing;\n\n/**\n * Callback which is invoked when a possible result point (significant\n * point in the barcode image such as a corner) is found.\n *\n * @see DecodeHintType#NEED_RESULT_POINT_CALLBACK\n */\npublic interface ResultPointCallback {\n\n  void foundPossibleResultPoint(ResultPoint point);\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/Writer.java",
    "content": "/*\n * Copyright 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing;\n\nimport com.google.zxing.common.BitMatrix;\n\nimport java.util.Map;\n\n/**\n * The base class for all objects which encode/generate a barcode image.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n */\npublic interface Writer {\n\n  /**\n   * Encode a barcode using the default settings.\n   *\n   * @param contents The contents to encode in the barcode\n   * @param format The barcode format to generate\n   * @param width The preferred width in pixels\n   * @param height The preferred height in pixels\n   */\n  BitMatrix encode(String contents, BarcodeFormat format, int width, int height)\n      throws WriterException;\n\n  /**\n   *\n   * @param contents The contents to encode in the barcode\n   * @param format The barcode format to generate\n   * @param width The preferred width in pixels\n   * @param height The preferred height in pixels\n   * @param hints Additional parameters to supply to the encoder\n   */\n  BitMatrix encode(String contents,\n                   BarcodeFormat format,\n                   int width,\n                   int height,\n                   Map<EncodeHintType,?> hints)\n      throws WriterException;\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/WriterException.java",
    "content": "/*\n * Copyright 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing;\n\n/**\n * A base class which covers the range of exceptions which may occur when encoding a barcode using\n * the Writer framework.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n */\npublic final class WriterException extends Exception {\n\n  public WriterException() {\n  }\n\n  public WriterException(String message) {\n    super(message);\n  }\n  \n  public WriterException(Throwable cause) {\n    super(cause);\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/aztec/AztecDetectorResult.java",
    "content": "/*\r\n * Copyright 2010 ZXing authors\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage com.google.zxing.aztec;\r\n\r\nimport com.google.zxing.ResultPoint;\r\nimport com.google.zxing.common.BitMatrix;\r\nimport com.google.zxing.common.DetectorResult;\r\n\r\npublic final class AztecDetectorResult extends DetectorResult {\r\n\r\n  private final boolean compact;\r\n  private final int nbDatablocks;\r\n  private final int nbLayers;\r\n\r\n  public AztecDetectorResult(BitMatrix bits,\r\n                             ResultPoint[] points,\r\n                             boolean compact,\r\n                             int nbDatablocks,\r\n                             int nbLayers) {\r\n    super(bits, points);\r\n    this.compact = compact;\r\n    this.nbDatablocks = nbDatablocks;\r\n    this.nbLayers = nbLayers;\r\n  }\r\n\r\n  public int getNbLayers() {\r\n    return nbLayers;\r\n  }\r\n\r\n  public int getNbDatablocks() {\r\n    return nbDatablocks;\r\n  }\r\n\r\n  public boolean isCompact() {\r\n    return compact;\r\n  }\r\n\r\n}\r\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/aztec/AztecReader.java",
    "content": "/*\n * Copyright 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.aztec;\n\nimport com.google.zxing.BarcodeFormat;\nimport com.google.zxing.BinaryBitmap;\nimport com.google.zxing.DecodeHintType;\nimport com.google.zxing.FormatException;\nimport com.google.zxing.NotFoundException;\nimport com.google.zxing.Reader;\nimport com.google.zxing.Result;\nimport com.google.zxing.ResultMetadataType;\nimport com.google.zxing.ResultPoint;\nimport com.google.zxing.ResultPointCallback;\nimport com.google.zxing.common.DecoderResult;\nimport com.google.zxing.aztec.decoder.Decoder;\nimport com.google.zxing.aztec.detector.Detector;\n\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * This implementation can detect and decode Aztec codes in an image.\n *\n * @author David Olivier\n */\npublic final class AztecReader implements Reader {\n\n  /**\n   * Locates and decodes a Data Matrix code in an image.\n   *\n   * @return a String representing the content encoded by the Data Matrix code\n   * @throws NotFoundException if a Data Matrix code cannot be found\n   * @throws FormatException if a Data Matrix code cannot be decoded\n   * @throws com.google.zxing.ChecksumException if error correction fails\n   */\n  @Override\n  public Result decode(BinaryBitmap image) throws NotFoundException, FormatException {\n    return decode(image, null);\n  }\n\n  @Override\n  public Result decode(BinaryBitmap image, Map<DecodeHintType,?> hints)\n      throws NotFoundException, FormatException {\n\n    AztecDetectorResult detectorResult = new Detector(image.getBlackMatrix()).detect();\n    ResultPoint[] points = detectorResult.getPoints();\n\n    if (hints != null) {\n      ResultPointCallback rpcb = (ResultPointCallback) hints.get(DecodeHintType.NEED_RESULT_POINT_CALLBACK);\n      if (rpcb != null) {\n        for (ResultPoint point : points) {\n          rpcb.foundPossibleResultPoint(point);\n        }\n      }\n    }\n\n    DecoderResult decoderResult = new Decoder().decode(detectorResult);\n\n    Result result = new Result(decoderResult.getText(), decoderResult.getRawBytes(), points, BarcodeFormat.AZTEC);\n    \n    List<byte[]> byteSegments = decoderResult.getByteSegments();\n    if (byteSegments != null) {\n      result.putMetadata(ResultMetadataType.BYTE_SEGMENTS, byteSegments);\n    }\n    String ecLevel = decoderResult.getECLevel();\n    if (ecLevel != null) {\n      result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, ecLevel);\n    }\n    \n    return result;\n  }\n\n  @Override\n  public void reset() {\n    // do nothing\n  }\n\n}"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/aztec/decoder/Decoder.java",
    "content": "/*\r\n * Copyright 2010 ZXing authors\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage com.google.zxing.aztec.decoder;\r\n\r\nimport com.google.zxing.FormatException;\r\nimport com.google.zxing.aztec.AztecDetectorResult;\r\nimport com.google.zxing.common.BitMatrix;\r\nimport com.google.zxing.common.DecoderResult;\r\nimport com.google.zxing.common.reedsolomon.GenericGF;\r\nimport com.google.zxing.common.reedsolomon.ReedSolomonDecoder;\r\nimport com.google.zxing.common.reedsolomon.ReedSolomonException;\r\n\r\n/**\r\n * <p>The main class which implements Aztec Code decoding -- as opposed to locating and extracting\r\n * the Aztec Code from an image.</p>\r\n *\r\n * @author David Olivier\r\n */\r\npublic final class Decoder {\r\n\r\n  private enum Table {\r\n    UPPER,\r\n    LOWER,\r\n    MIXED,\r\n    DIGIT,\r\n    PUNCT,\r\n    BINARY\r\n  }\r\n\r\n  private static final int[] NB_BITS_COMPACT = {\r\n      0, 104, 240, 408, 608\r\n  };\r\n\r\n  private static final int[] NB_BITS = {\r\n      0, 128, 288, 480, 704, 960, 1248, 1568, 1920, 2304, 2720, 3168, 3648, 4160, 4704, 5280, 5888, 6528,\r\n      7200, 7904, 8640, 9408, 10208, 11040, 11904, 12800, 13728, 14688, 15680, 16704, 17760, 18848, 19968\r\n  };\r\n\r\n  private static final int[] NB_DATABLOCK_COMPACT = {\r\n      0, 17, 40, 51, 76\r\n  };\r\n\r\n  private static final int[] NB_DATABLOCK = {\r\n      0, 21, 48, 60, 88, 120, 156, 196, 240, 230, 272, 316, 364, 416, 470, 528, 588, 652, 720, 790, 864,\r\n      940, 1020, 920, 992, 1066, 1144, 1224, 1306, 1392, 1480, 1570, 1664\r\n  };\r\n\r\n  private static final String[] UPPER_TABLE = {\r\n      \"CTRL_PS\", \" \", \"A\", \"B\", \"C\", \"D\", \"E\", \"F\", \"G\", \"H\", \"I\", \"J\", \"K\", \"L\", \"M\", \"N\", \"O\", \"P\",\r\n      \"Q\", \"R\", \"S\", \"T\", \"U\", \"V\", \"W\", \"X\", \"Y\", \"Z\", \"CTRL_LL\", \"CTRL_ML\", \"CTRL_DL\", \"CTRL_BS\"\r\n  };\r\n\r\n  private static final String[] LOWER_TABLE = {\r\n      \"CTRL_PS\", \" \", \"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\", \"h\", \"i\", \"j\", \"k\", \"l\", \"m\", \"n\", \"o\", \"p\",\r\n      \"q\", \"r\", \"s\", \"t\", \"u\", \"v\", \"w\", \"x\", \"y\", \"z\", \"CTRL_US\", \"CTRL_ML\", \"CTRL_DL\", \"CTRL_BS\"\r\n  };\r\n\r\n  private static final String[] MIXED_TABLE = {\r\n      \"CTRL_PS\", \" \", \"\\1\", \"\\2\", \"\\3\", \"\\4\", \"\\5\", \"\\6\", \"\\7\", \"\\b\", \"\\t\", \"\\n\",\r\n      \"\\13\", \"\\f\", \"\\r\", \"\\33\", \"\\34\", \"\\35\", \"\\36\", \"\\37\", \"@\", \"\\\\\", \"^\", \"_\",\r\n      \"`\", \"|\", \"~\", \"\\177\", \"CTRL_LL\", \"CTRL_UL\", \"CTRL_PL\", \"CTRL_BS\"\r\n  };\r\n\r\n  private static final String[] PUNCT_TABLE = {\r\n      \"\", \"\\r\", \"\\r\\n\", \". \", \", \", \": \", \"!\", \"\\\"\", \"#\", \"$\", \"%\", \"&\", \"'\", \"(\", \")\",\r\n      \"*\", \"+\", \",\", \"-\", \".\", \"/\", \":\", \";\", \"<\", \"=\", \">\", \"?\", \"[\", \"]\", \"{\", \"}\", \"CTRL_UL\"\r\n  };\r\n\r\n  private static final String[] DIGIT_TABLE = {\r\n      \"CTRL_PS\", \" \", \"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \",\", \".\", \"CTRL_UL\", \"CTRL_US\"\r\n  };\r\n\r\n  private int numCodewords;\r\n  private int codewordSize;\r\n  private AztecDetectorResult ddata;\r\n  private int invertedBitCount;\r\n\r\n  public DecoderResult decode(AztecDetectorResult detectorResult) throws FormatException {\r\n    ddata = detectorResult;\r\n    BitMatrix matrix = detectorResult.getBits();\r\n\r\n    if (!ddata.isCompact()) {\r\n      matrix = removeDashedLines(ddata.getBits());\r\n    }\r\n\r\n    boolean[] rawbits = extractBits(matrix);\r\n\r\n    boolean[] correctedBits = correctBits(rawbits);\r\n\r\n    String result = getEncodedData(correctedBits);\r\n\r\n    return new DecoderResult(null, result, null, null);\r\n  }\r\n\r\n  /**\r\n   * Gets the string encoded in the aztec code bits\r\n   *\r\n   * @return the decoded string\r\n   * @throws FormatException if the input is not valid\r\n   */\r\n  private String getEncodedData(boolean[] correctedBits) throws FormatException {\r\n\r\n    int endIndex = codewordSize * ddata.getNbDatablocks() - invertedBitCount;\r\n    if (endIndex > correctedBits.length) {\r\n      throw FormatException.getFormatInstance();\r\n    }\r\n\r\n    Table lastTable = Table.UPPER;\r\n    Table table = Table.UPPER;\r\n    int startIndex = 0;\r\n    StringBuilder result = new StringBuilder(20);\r\n    boolean end = false;\r\n    boolean shift = false;\r\n    boolean switchShift = false;\r\n    boolean binaryShift = false;\r\n\r\n    while (!end) {\r\n\r\n      if (shift) {\r\n        // the table is for the next character only\r\n        switchShift = true;\r\n      } else {\r\n        // save the current table in case next one is a shift\r\n        lastTable = table;\r\n      }\r\n\r\n      int code;\r\n      if (binaryShift) {\r\n        if (endIndex - startIndex < 5) {\r\n          break;\r\n        }\r\n\r\n        int length = readCode(correctedBits, startIndex, 5);\r\n        startIndex += 5;\r\n        if (length == 0) {\r\n          if (endIndex - startIndex < 11) {\r\n            break;\r\n          }\r\n\r\n          length = readCode(correctedBits, startIndex, 11) + 31;\r\n          startIndex += 11;\r\n        }\r\n        for (int charCount = 0; charCount < length; charCount++) {\r\n          if (endIndex - startIndex < 8) {\r\n            end = true;\r\n            break;\r\n          }\r\n\r\n          code = readCode(correctedBits, startIndex, 8);\r\n          result.append((char) code);\r\n          startIndex += 8;\r\n        }\r\n        binaryShift = false;\r\n      } else {\r\n        if (table == Table.BINARY) {\r\n          if (endIndex - startIndex < 8) {\r\n            break;\r\n          }\r\n          code = readCode(correctedBits, startIndex, 8);\r\n          startIndex += 8;\r\n\r\n          result.append((char) code);\r\n\r\n        } else {\r\n          int size = 5;\r\n\r\n          if (table == Table.DIGIT) {\r\n            size = 4;\r\n          }\r\n\r\n          if (endIndex - startIndex < size) {\r\n            break;\r\n          }\r\n\r\n          code = readCode(correctedBits, startIndex, size);\r\n          startIndex += size;\r\n\r\n          String str = getCharacter(table, code);\r\n          if (str.startsWith(\"CTRL_\")) {\r\n            // Table changes\r\n            table = getTable(str.charAt(5));\r\n\r\n            if (str.charAt(6) == 'S') {\r\n              shift = true;\r\n              if (str.charAt(5) == 'B') {\r\n                binaryShift = true;\r\n              }\r\n            }\r\n          } else {\r\n            result.append(str);\r\n          }\r\n\r\n\r\n        }\r\n      }\r\n\r\n      if (switchShift) {\r\n        table = lastTable;\r\n        shift = false;\r\n        switchShift = false;\r\n      }\r\n\r\n    }\r\n    return result.toString();\r\n  }\r\n\r\n\r\n  /**\r\n   * gets the table corresponding to the char passed\r\n   */\r\n  private static Table getTable(char t) {\r\n    switch (t) {\r\n      case 'L':\r\n        return Table.LOWER;\r\n      case 'P':\r\n        return Table.PUNCT;\r\n      case 'M':\r\n        return Table.MIXED;\r\n      case 'D':\r\n        return Table.DIGIT;\r\n      case 'B':\r\n        return Table.BINARY;\r\n      case 'U':\r\n      default:\r\n        return Table.UPPER;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Gets the character (or string) corresponding to the passed code in the given table\r\n   *\r\n   * @param table the table used\r\n   * @param code the code of the character\r\n   */\r\n  private static String getCharacter(Table table, int code) {\r\n    switch (table) {\r\n      case UPPER:\r\n        return UPPER_TABLE[code];\r\n      case LOWER:\r\n        return LOWER_TABLE[code];\r\n      case MIXED:\r\n        return MIXED_TABLE[code];\r\n      case PUNCT:\r\n        return PUNCT_TABLE[code];\r\n      case DIGIT:\r\n        return DIGIT_TABLE[code];\r\n      default:\r\n        return \"\";\r\n    }\r\n  }\r\n\r\n  /**\r\n   * <p>Performs RS error correction on an array of bits.</p>\r\n   *\r\n   * @return the corrected array\r\n   * @throws FormatException if the input contains too many errors\r\n   */\r\n  private boolean[] correctBits(boolean[] rawbits) throws FormatException {\r\n    GenericGF gf;\r\n\r\n    if (ddata.getNbLayers() <= 2) {\r\n      codewordSize = 6;\r\n      gf = GenericGF.AZTEC_DATA_6;\r\n    } else if (ddata.getNbLayers() <= 8) {\r\n      codewordSize = 8;\r\n      gf = GenericGF.AZTEC_DATA_8;\r\n    } else if (ddata.getNbLayers() <= 22) {\r\n      codewordSize = 10;\r\n      gf = GenericGF.AZTEC_DATA_10;\r\n    } else {\r\n      codewordSize = 12;\r\n      gf = GenericGF.AZTEC_DATA_12;\r\n    }\r\n\r\n    int numDataCodewords = ddata.getNbDatablocks();\r\n    int numECCodewords;\r\n    int offset;\r\n\r\n    if (ddata.isCompact()) {\r\n      offset = NB_BITS_COMPACT[ddata.getNbLayers()] - numCodewords * codewordSize;\r\n      numECCodewords = NB_DATABLOCK_COMPACT[ddata.getNbLayers()] - numDataCodewords;\r\n    } else {\r\n      offset = NB_BITS[ddata.getNbLayers()] - numCodewords * codewordSize;\r\n      numECCodewords = NB_DATABLOCK[ddata.getNbLayers()] - numDataCodewords;\r\n    }\r\n\r\n    int[] dataWords = new int[numCodewords];\r\n    for (int i = 0; i < numCodewords; i++) {\r\n      int flag = 1;\r\n      for (int j = 1; j <= codewordSize; j++) {\r\n        if (rawbits[codewordSize * i + codewordSize - j + offset]) {\r\n          dataWords[i] += flag;\r\n        }\r\n        flag <<= 1;\r\n      }\r\n\r\n      //if (dataWords[i] >= flag) {\r\n      //  flag++;\r\n      //}\r\n    }\r\n\r\n    try {\r\n      ReedSolomonDecoder rsDecoder = new ReedSolomonDecoder(gf);\r\n      rsDecoder.decode(dataWords, numECCodewords);\r\n    } catch (ReedSolomonException rse) {\r\n      throw FormatException.getFormatInstance();\r\n    }\r\n\r\n    offset = 0;\r\n    invertedBitCount = 0;\r\n\r\n    boolean[] correctedBits = new boolean[numDataCodewords * codewordSize];\r\n    for (int i = 0; i < numDataCodewords; i++) {\r\n\r\n      boolean seriesColor = false;\r\n      int seriesCount = 0;\r\n      int flag = 1 << (codewordSize - 1);\r\n\r\n      for (int j = 0; j < codewordSize; j++) {\r\n\r\n        boolean color = (dataWords[i] & flag) == flag;\r\n\r\n        if (seriesCount == codewordSize - 1) {\r\n\r\n          if (color == seriesColor) {\r\n            //bit must be inverted\r\n            throw FormatException.getFormatInstance();\r\n          }\r\n\r\n          seriesColor = false;\r\n          seriesCount = 0;\r\n          offset++;\r\n          invertedBitCount++;\r\n        } else {\r\n\r\n          if (seriesColor == color) {\r\n            seriesCount++;\r\n          } else {\r\n            seriesCount = 1;\r\n            seriesColor = color;\r\n          }\r\n\r\n          correctedBits[i * codewordSize + j - offset] = color;\r\n\r\n        }\r\n\r\n        flag >>>= 1;\r\n      }\r\n    }\r\n\r\n    return correctedBits;\r\n  }\r\n\r\n  /**\r\n   * Gets the array of bits from an Aztec Code matrix\r\n   *\r\n   * @return the array of bits\r\n   * @throws FormatException if the matrix is not a valid aztec code\r\n   */\r\n  private boolean[] extractBits(BitMatrix matrix) throws FormatException {\r\n\r\n    boolean[] rawbits;\r\n    if (ddata.isCompact()) {\r\n      if (ddata.getNbLayers() > NB_BITS_COMPACT.length) {\r\n        throw FormatException.getFormatInstance();\r\n      }\r\n      rawbits = new boolean[NB_BITS_COMPACT[ddata.getNbLayers()]];\r\n      numCodewords = NB_DATABLOCK_COMPACT[ddata.getNbLayers()];\r\n    } else {\r\n      if (ddata.getNbLayers() > NB_BITS.length) {\r\n        throw FormatException.getFormatInstance();\r\n      }\r\n      rawbits = new boolean[NB_BITS[ddata.getNbLayers()]];\r\n      numCodewords = NB_DATABLOCK[ddata.getNbLayers()];\r\n    }\r\n\r\n    int layer = ddata.getNbLayers();\r\n    int size = matrix.getHeight();\r\n    int rawbitsOffset = 0;\r\n    int matrixOffset = 0;\r\n\r\n    while (layer != 0) {\r\n\r\n      int flip = 0;\r\n      for (int i = 0; i < 2 * size - 4; i++) {\r\n        rawbits[rawbitsOffset + i] = matrix.get(matrixOffset + flip, matrixOffset + i / 2);\r\n        rawbits[rawbitsOffset + 2 * size - 4 + i] = matrix.get(matrixOffset + i / 2, matrixOffset + size - 1 - flip);\r\n        flip = (flip + 1) % 2;\r\n      }\r\n\r\n      flip = 0;\r\n      for (int i = 2 * size + 1; i > 5; i--) {\r\n        rawbits[rawbitsOffset + 4 * size - 8 + (2 * size - i) + 1] =\r\n            matrix.get(matrixOffset + size - 1 - flip, matrixOffset + i / 2 - 1);\r\n        rawbits[rawbitsOffset + 6 * size - 12 + (2 * size - i) + 1] =\r\n            matrix.get(matrixOffset + i / 2 - 1, matrixOffset + flip);\r\n        flip = (flip + 1) % 2;\r\n      }\r\n\r\n      matrixOffset += 2;\r\n      rawbitsOffset += 8 * size - 16;\r\n      layer--;\r\n      size -= 4;\r\n    }\r\n\r\n    return rawbits;\r\n  }\r\n\r\n  /**\r\n   * Transforms an Aztec code matrix by removing the control dashed lines\r\n   */\r\n  private static BitMatrix removeDashedLines(BitMatrix matrix) {\r\n    int nbDashed = 1 + 2 * ((matrix.getWidth() - 1) / 2 / 16);\r\n    BitMatrix newMatrix = new BitMatrix(matrix.getWidth() - nbDashed, matrix.getHeight() - nbDashed);\r\n\r\n    int nx = 0;\r\n\r\n    for (int x = 0; x < matrix.getWidth(); x++) {\r\n\r\n      if ((matrix.getWidth() / 2 - x) % 16 == 0) {\r\n        continue;\r\n      }\r\n\r\n      int ny = 0;\r\n      for (int y = 0; y < matrix.getHeight(); y++) {\r\n\r\n        if ((matrix.getWidth() / 2 - y) % 16 == 0) {\r\n          continue;\r\n        }\r\n\r\n        if (matrix.get(x, y)) {\r\n          newMatrix.set(nx, ny);\r\n        }\r\n        ny++;\r\n      }\r\n      nx++;\r\n    }\r\n\r\n    return newMatrix;\r\n  }\r\n\r\n  /**\r\n   * Reads a code of given length and at given index in an array of bits\r\n   */\r\n  private static int readCode(boolean[] rawbits, int startIndex, int length) {\r\n    int res = 0;\r\n\r\n    for (int i = startIndex; i < startIndex + length; i++) {\r\n      res <<= 1;\r\n      if (rawbits[i]) {\r\n        res++;\r\n      }\r\n    }\r\n\r\n    return res;\r\n  }\r\n\r\n}\r\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/aztec/detector/Detector.java",
    "content": "/*\n * Copyright 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.aztec.detector;\n\nimport com.google.zxing.NotFoundException;\nimport com.google.zxing.ResultPoint;\nimport com.google.zxing.aztec.AztecDetectorResult;\nimport com.google.zxing.common.BitMatrix;\nimport com.google.zxing.common.GridSampler;\nimport com.google.zxing.common.detector.MathUtils;\nimport com.google.zxing.common.detector.WhiteRectangleDetector;\nimport com.google.zxing.common.reedsolomon.GenericGF;\nimport com.google.zxing.common.reedsolomon.ReedSolomonDecoder;\nimport com.google.zxing.common.reedsolomon.ReedSolomonException;\n\n/**\n * <p>Encapsulates logic that can detect an Aztec Code in an image, even if the Aztec Code\n * is rotated or skewed, or partially obscured.</p>\n *\n * @author David Olivier\n */\npublic final class Detector {\n\n  private final BitMatrix image;\n\n  private boolean compact;\n  private int nbLayers;\n  private int nbDataBlocks;\n  private int nbCenterLayers;\n  private int shift;\n\n  public Detector(BitMatrix image) {\n    this.image = image;\n  }\n\n  /**\n   * <p>Detects an Aztec Code in an image.</p>\n   *\n   * @return {@link AztecDetectorResult} encapsulating results of detecting an Aztec Code\n   * @throws NotFoundException if no Aztec Code can be found\n   */\n  public AztecDetectorResult detect() throws NotFoundException {\n\n    // 1. Get the center of the aztec matrix\n     Point pCenter = getMatrixCenter();\n\n     // 2. Get the corners of the center bull's eye\n     Point[] bullEyeCornerPoints = getBullEyeCornerPoints(pCenter);\n\n     // 3. Get the size of the matrix from the bull's eye\n    extractParameters(bullEyeCornerPoints);\n    \n    // 4. Get the corners of the matrix\n    ResultPoint[] corners = getMatrixCornerPoints(bullEyeCornerPoints);\n    \n    // 5. Sample the grid\n    BitMatrix bits = sampleGrid(image, corners[shift%4], corners[(shift+3)%4], corners[(shift+2)%4], corners[(shift+1)%4]);\n    \n    return new AztecDetectorResult(bits, corners, compact, nbDataBlocks, nbLayers);\n  }\n\n  /**\n   * <p> Extracts the number of data layers and data blocks from the layer around the bull's eye </p>\n   *\n   * @param bullEyeCornerPoints the array of bull's eye corners\n   * @throws NotFoundException in case of too many errors or invalid parameters\n   */\n  private void extractParameters(Point[] bullEyeCornerPoints)\n      throws NotFoundException {\n\n    // Get the bits around the bull's eye\n    boolean[] resab = sampleLine(bullEyeCornerPoints[0], bullEyeCornerPoints[1], 2*nbCenterLayers+1);\n    boolean[] resbc = sampleLine(bullEyeCornerPoints[1], bullEyeCornerPoints[2], 2*nbCenterLayers+1);\n    boolean[] rescd = sampleLine(bullEyeCornerPoints[2], bullEyeCornerPoints[3], 2*nbCenterLayers+1);\n    boolean[] resda = sampleLine(bullEyeCornerPoints[3], bullEyeCornerPoints[0], 2*nbCenterLayers+1);\n\n    // Determine the orientation of the matrix\n    if (resab[0] && resab[2 * nbCenterLayers]) {\n      shift = 0;\n    } else if (resbc[0] && resbc[2 * nbCenterLayers]) {\n      shift = 1;\n    } else if (rescd[0] && rescd[2 * nbCenterLayers]) {\n      shift = 2;\n    } else if (resda[0] && resda[2 * nbCenterLayers]) {\n      shift = 3;\n    } else {\n      throw NotFoundException.getNotFoundInstance();\n    }\n    \n    //d      a\n    //\n    //c      b\n    \n    // Flatten the bits in a single array\n    boolean[] parameterData;\n    boolean[] shiftedParameterData;\n    if (compact) {\n      shiftedParameterData = new boolean[28];\n      for (int i = 0; i < 7; i++) {\n        shiftedParameterData[i] = resab[2+i];\n        shiftedParameterData[i+7] = resbc[2+i];\n        shiftedParameterData[i+14] = rescd[2+i];\n        shiftedParameterData[i+21] = resda[2+i];\n      }\n        \n      parameterData = new boolean[28];\n        for (int i = 0; i < 28; i++) {\n          parameterData[i] = shiftedParameterData[(i+shift*7)%28];\n        }\n    } else {\n      shiftedParameterData = new boolean[40];\n      for (int i = 0; i < 11; i++) {\n        if (i < 5) {\n          shiftedParameterData[i] = resab[2+i];\n          shiftedParameterData[i+10] = resbc[2+i];\n          shiftedParameterData[i+20] = rescd[2+i];\n          shiftedParameterData[i+30] = resda[2+i];\n        }\n        if (i > 5) {\n          shiftedParameterData[i-1] = resab[2+i];\n          shiftedParameterData[i+10-1] = resbc[2+i];\n          shiftedParameterData[i+20-1] = rescd[2+i];\n          shiftedParameterData[i+30-1] = resda[2+i];\n        }\n      }\n        \n      parameterData = new boolean[40];\n        for (int i = 0; i < 40; i++) {\n          parameterData[i] = shiftedParameterData[(i+shift*10)%40];\n        }\n    }\n    \n    // corrects the error using RS algorithm\n    correctParameterData(parameterData, compact);\n    \n    // gets the parameters from the bit array\n    getParameters(parameterData);\n  }\n\n  /**\n   *\n   * <p>Gets the Aztec code corners from the bull's eye corners and the parameters </p>\n   *\n   * @param bullEyeCornerPoints the array of bull's eye corners\n   * @return the array of aztec code corners\n   * @throws NotFoundException if the corner points do not fit in the image\n   */\n  private ResultPoint[] getMatrixCornerPoints(Point[] bullEyeCornerPoints) throws NotFoundException {\n\n    float ratio = (2 * nbLayers + (nbLayers > 4 ? 1 : 0) + (nbLayers - 4) / 8)\n        / (2.0f * nbCenterLayers);\n\n    int dx = bullEyeCornerPoints[0].x-bullEyeCornerPoints[2].x;\n    dx+=dx>0?1:-1;\n    int dy = bullEyeCornerPoints[0].y-bullEyeCornerPoints[2].y;\n    dy+=dy>0?1:-1;\n    \n    int targetcx = MathUtils.round(bullEyeCornerPoints[2].x - ratio * dx);\n    int targetcy = MathUtils.round(bullEyeCornerPoints[2].y - ratio * dy);\n    \n    int targetax = MathUtils.round(bullEyeCornerPoints[0].x + ratio * dx);\n    int targetay = MathUtils.round(bullEyeCornerPoints[0].y + ratio * dy);\n    \n    dx = bullEyeCornerPoints[1].x-bullEyeCornerPoints[3].x;\n    dx+=dx>0?1:-1;\n    dy = bullEyeCornerPoints[1].y-bullEyeCornerPoints[3].y;\n    dy+=dy>0?1:-1;\n    \n    int targetdx = MathUtils.round(bullEyeCornerPoints[3].x - ratio * dx);\n    int targetdy = MathUtils.round(bullEyeCornerPoints[3].y - ratio * dy);\n    int targetbx = MathUtils.round(bullEyeCornerPoints[1].x + ratio * dx);\n    int targetby = MathUtils.round(bullEyeCornerPoints[1].y+ratio*dy);\n    \n    if (!isValid(targetax, targetay) || !isValid(targetbx, targetby) || !isValid(targetcx, targetcy) || !isValid(targetdx, targetdy)) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n    \n    return new ResultPoint[]{new ResultPoint(targetax, targetay), new ResultPoint(targetbx, targetby), new ResultPoint(targetcx, targetcy), new ResultPoint(targetdx, targetdy)}; \n  }\n\n  /**\n   *\n   * <p> Corrects the parameter bits using Reed-Solomon algorithm </p>\n   *\n   * @param parameterData paremeter bits\n   * @param compact true if this is a compact Aztec code\n   * @throws NotFoundException if the array contains too many errors\n   */\n  private static void correctParameterData(boolean[] parameterData, boolean compact) throws NotFoundException {\n\n    int numCodewords;\n    int numDataCodewords;\n\n    if (compact) {\n      numCodewords = 7;\n      numDataCodewords = 2;\n    } else {\n      numCodewords = 10;\n      numDataCodewords = 4;\n    }\n\n    int numECCodewords = numCodewords - numDataCodewords;\n    int[] parameterWords = new int[numCodewords];\n\n    int codewordSize = 4;\n    for (int i = 0; i < numCodewords; i++) {\n      int flag = 1;\n      for (int j = 1; j <= codewordSize; j++) {\n        if (parameterData[codewordSize*i + codewordSize - j]) {\n          parameterWords[i] += flag;\n        }\n        flag <<= 1;\n      }\n    }\n\n    try {\n      ReedSolomonDecoder rsDecoder = new ReedSolomonDecoder(GenericGF.AZTEC_PARAM);\n      rsDecoder.decode(parameterWords, numECCodewords);\n    } catch (ReedSolomonException rse) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n    \n    for (int i = 0; i < numDataCodewords; i ++) {\n        int flag = 1;\n        for (int j = 1; j <= codewordSize; j++) {\n          parameterData[i*codewordSize+codewordSize-j] = (parameterWords[i] & flag) == flag;\n          flag <<= 1;\n        }\n    }\n  }\n  \n  /**\n   * \n   * <p> Finds the corners of a bull-eye centered on the passed point </p>\n   * \n   * @param pCenter Center point\n   * @return The corners of the bull-eye\n   * @throws NotFoundException If no valid bull-eye can be found\n   */\n  private Point[] getBullEyeCornerPoints(Point pCenter) throws NotFoundException {\n    \n    Point pina = pCenter;\n    Point pinb = pCenter;\n    Point pinc = pCenter;\n    Point pind = pCenter;\n\n    boolean color = true;\n    \n    for (nbCenterLayers = 1; nbCenterLayers < 9; nbCenterLayers++) {\n      Point pouta = getFirstDifferent(pina, color, 1, -1);\n      Point poutb = getFirstDifferent(pinb, color, 1, 1);\n      Point poutc = getFirstDifferent(pinc, color, -1, 1);\n      Point poutd = getFirstDifferent(pind, color, -1, -1);\n\n      //d      a\n      //\n      //c      b\n\n      if (nbCenterLayers>2) {\n        float q = distance(poutd, pouta)*nbCenterLayers/(distance(pind, pina)*(nbCenterLayers+2));\n        if ( q < 0.75 || q > 1.25 || !isWhiteOrBlackRectangle(pouta, poutb, poutc, poutd)) {\n          break;\n        }\n      }\n\n      pina = pouta;\n      pinb = poutb;\n      pinc = poutc;\n      pind = poutd;\n\n      color = !color;\n    }\n\n    if (nbCenterLayers != 5 && nbCenterLayers != 7) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n    \n    compact = nbCenterLayers==5;\n    \n    float ratio = 0.75f*2/(2*nbCenterLayers-3);\n    \n    int dx = pina.x-pinc.x;\n    int dy = pina.y-pinc.y;\n    int targetcx = MathUtils.round(pinc.x-ratio*dx);\n    int targetcy = MathUtils.round(pinc.y-ratio*dy);\n    int targetax = MathUtils.round(pina.x+ratio*dx);\n    int targetay = MathUtils.round(pina.y+ratio*dy);\n    \n    dx = pinb.x-pind.x;\n    dy = pinb.y-pind.y;\n    \n    int targetdx = MathUtils.round(pind.x-ratio*dx);\n    int targetdy = MathUtils.round(pind.y-ratio*dy);\n    int targetbx = MathUtils.round(pinb.x+ratio*dx);\n    int targetby = MathUtils.round(pinb.y+ratio*dy);\n    \n    if (!isValid(targetax, targetay) || !isValid(targetbx, targetby)\n        || !isValid(targetcx, targetcy) || !isValid(targetdx, targetdy)) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n    \n    Point pa = new Point(targetax,targetay);\n    Point pb = new Point(targetbx,targetby);\n    Point pc = new Point(targetcx,targetcy);\n    Point pd = new Point(targetdx,targetdy);\n    \n    return new Point[]{pa, pb, pc, pd};\n  }\n\n  /**\n   *\n   * Finds a candidate center point of an Aztec code from an image\n   *\n   * @return the center point\n   */\n  private Point getMatrixCenter() {\n\n    ResultPoint pointA;\n    ResultPoint pointB;\n    ResultPoint pointC;\n    ResultPoint pointD;\n\n    //Get a white rectangle that can be the border of the matrix in center bull's eye or\n    try {\n\n      ResultPoint[] cornerPoints = new WhiteRectangleDetector(image).detect();\n      pointA = cornerPoints[0];\n      pointB = cornerPoints[1];\n      pointC = cornerPoints[2];\n      pointD = cornerPoints[3];\n\n    } catch (NotFoundException e) {\n\n      // This exception can be in case the initial rectangle is white\n      // In that case, surely in the bull's eye, we try to expand the rectangle.\n      int cx = image.getWidth()/2;\n      int cy = image.getHeight()/2;\n      pointA = getFirstDifferent(new Point(cx+15/2, cy-15/2), false, 1, -1).toResultPoint();\n      pointB = getFirstDifferent(new Point(cx+15/2, cy+15/2), false, 1, 1).toResultPoint();\n      pointC = getFirstDifferent(new Point(cx-15/2, cy+15/2), false, -1, 1).toResultPoint();\n      pointD = getFirstDifferent(new Point(cx-15/2, cy-15/2), false, -1, -1).toResultPoint();\n\n    }\n    \n    //Compute the center of the rectangle\n    int cx = MathUtils.round((pointA.getX() + pointD.getX() + pointB.getX() + pointC.getX())/4);\n    int cy = MathUtils.round((pointA.getY() + pointD.getY() + pointB.getY() + pointC.getY())/4);\n\n    // Redetermine the white rectangle starting from previously computed center.\n    // This will ensure that we end up with a white rectangle in center bull's eye\n    // in order to compute a more accurate center.\n    try {\n      ResultPoint[] cornerPoints = new WhiteRectangleDetector(image, 15, cx, cy).detect();\n      pointA = cornerPoints[0];\n      pointB = cornerPoints[1];\n      pointC = cornerPoints[2];\n      pointD = cornerPoints[3];\n    } catch (NotFoundException e) {\n\n      // This exception can be in case the initial rectangle is white\n      // In that case we try to expand the rectangle.\n      pointA = getFirstDifferent(new Point(cx+15/2, cy-15/2), false, 1, -1).toResultPoint();\n      pointB = getFirstDifferent(new Point(cx+15/2, cy+15/2), false, 1, 1).toResultPoint();\n      pointC = getFirstDifferent(new Point(cx-15/2, cy+15/2), false, -1, 1).toResultPoint();\n      pointD = getFirstDifferent(new Point(cx-15/2, cy-15/2), false, -1, -1).toResultPoint();\n\n    }\n    \n    // Recompute the center of the rectangle\n    cx = MathUtils.round((pointA.getX() + pointD.getX() + pointB.getX() + pointC.getX())/4);\n    cy = MathUtils.round((pointA.getY() + pointD.getY() + pointB.getY() + pointC.getY())/4);\n\n    return new Point(cx, cy);\n  }\n\n  /**\n   * Samples an Aztec matrix from an image\n   */\n  private BitMatrix sampleGrid(BitMatrix image,\n                               ResultPoint topLeft,\n                               ResultPoint bottomLeft,\n                               ResultPoint bottomRight,\n                               ResultPoint topRight) throws NotFoundException {\n\n    int dimension;\n    if (compact) {\n      dimension = 4*nbLayers+11;\n    } else {\n      if (nbLayers <= 4) {\n        dimension = 4*nbLayers + 15;\n      } else {\n        dimension = 4*nbLayers + 2*((nbLayers-4)/8 + 1) + 15 ;\n      }\n    }\n\n    GridSampler sampler = GridSampler.getInstance();\n\n    return sampler.sampleGrid(image,\n      dimension,\n      dimension,\n      0.5f,\n      0.5f,\n      dimension - 0.5f,\n      0.5f,\n      dimension - 0.5f,\n      dimension - 0.5f,\n      0.5f,\n      dimension - 0.5f,\n      topLeft.getX(),\n      topLeft.getY(),\n      topRight.getX(),\n      topRight.getY(),\n      bottomRight.getX(),\n      bottomRight.getY(),\n      bottomLeft.getX(),\n      bottomLeft.getY());\n  }\n  \n  /**\n   * Sets number of layers and number of datablocks from parameter bits\n   */\n  private void getParameters(boolean[] parameterData) {\n\n    int nbBitsForNbLayers;\n    int nbBitsForNbDatablocks;\n\n    if (compact) {\n      nbBitsForNbLayers = 2;\n      nbBitsForNbDatablocks = 6;\n    } else {\n      nbBitsForNbLayers = 5;\n      nbBitsForNbDatablocks = 11;\n    }\n\n    for (int i = 0; i < nbBitsForNbLayers; i++) {\n      nbLayers <<= 1;\n      if (parameterData[i]) {\n        nbLayers += 1;\n      }\n    }\n\n    for (int i = nbBitsForNbLayers; i < nbBitsForNbLayers + nbBitsForNbDatablocks; i++) {\n      nbDataBlocks <<= 1;\n      if (parameterData[i]) {\n        nbDataBlocks += 1;\n      }\n    }\n\n    nbLayers ++;\n    nbDataBlocks ++;\n\n  }\n\n  /**\n   *\n   * Samples a line\n   *\n   * @param p1 first point\n   * @param p2 second point\n   * @param size number of bits\n   * @return the array of bits\n   */\n  private boolean[] sampleLine(Point p1, Point p2, int size) {\n\n    boolean[] res = new boolean[size];\n    float d = distance(p1,p2);\n    float moduleSize = d/(size-1);\n    float dx = moduleSize*(p2.x - p1.x)/d;\n    float dy = moduleSize*(p2.y - p1.y)/d;\n\n    float px = p1.x;\n    float py = p1.y;\n\n    for (int i = 0; i < size; i++) {\n      res[i] = image.get(MathUtils.round(px), MathUtils.round(py));\n      px+=dx;\n      py+=dy;\n    }\n\n    return res;\n  }\n\n  /**\n   * @return true if the border of the rectangle passed in parameter is compound of white points only\n   * or black points only\n   */\n  private boolean isWhiteOrBlackRectangle(Point p1,\n                                          Point p2,\n                                          Point p3,\n                                          Point p4) {\n\n    int corr = 3;\n\n    p1 = new Point(p1.x-corr, p1.y+corr);\n    p2 = new Point(p2.x-corr, p2.y-corr);\n    p3 = new Point(p3.x+corr, p3.y-corr);\n    p4 = new Point(p4.x+corr, p4.y+corr);\n\n    int cInit = getColor(p4, p1);\n\n    if (cInit == 0) {\n      return false;\n    }\n\n    int c = getColor(p1, p2);\n\n    if (c != cInit) {\n      return false;\n    }\n\n    c = getColor(p2, p3);\n\n    if (c != cInit) {\n      return false;\n    }\n\n    c = getColor(p3, p4);\n\n    return c == cInit;\n\n  }\n\n  /**\n   * Gets the color of a segment\n   *\n   * @return 1 if segment more than 90% black, -1 if segment is more than 90% white, 0 else\n   */\n  private int getColor(Point p1, Point p2) {\n    float d = distance(p1,p2);\n    float dx = (p2.x - p1.x)/d;\n    float dy = (p2.y - p1.y)/d;\n    int error = 0;\n\n    float px = p1.x;\n    float py = p1.y;\n\n    boolean colorModel = image.get(p1.x, p1.y);\n\n    for (int i = 0; i < d; i++) {\n      px+=dx;\n      py+=dy;\n      if (image.get(MathUtils.round(px), MathUtils.round(py)) != colorModel) {\n        error++;\n      }\n    }\n\n    float errRatio = (float)error/d;\n\n    if (errRatio > 0.1 && errRatio < 0.9) {\n      return 0;\n    }\n\n    if (errRatio <= 0.1) {\n      return colorModel?1:-1;\n    } else {\n      return colorModel?-1:1;\n    }\n  }\n\n  /**\n   * Gets the coordinate of the first point with a different color in the given direction\n   */\n  private Point getFirstDifferent(Point init, boolean color, int dx, int dy) {\n    int x = init.x+dx;\n    int y = init.y+dy;\n\n    while(isValid(x,y) && image.get(x,y) == color) {\n      x+=dx;\n      y+=dy;\n    }\n\n    x-=dx;\n    y-=dy;\n\n    while(isValid(x,y) && image.get(x, y) == color) {\n      x+=dx;\n    }\n    x-=dx;\n\n    while(isValid(x,y) && image.get(x, y) == color) {\n      y+=dy;\n    }\n    y-=dy;\n\n    return new Point(x,y);\n  }\n  \n  private static final class Point {\n    public final int x;\n    public final int y;\n\n    public ResultPoint toResultPoint() {\n      return new ResultPoint(x, y);\n    }\n\n    private Point(int x, int y) {\n      this.x = x;\n      this.y = y;\n    }\n  }\n\n  private boolean isValid(int x, int y) {\n    return x >= 0 && x < image.getWidth() && y > 0 && y < image.getHeight();\n  }\n\n  private static float distance(Point a, Point b) {\n    return MathUtils.distance(a.x, a.y, b.x, b.y);\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/BeepManager.java",
    "content": "/*\n * Copyright (C) 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android;\n\nimport android.app.Activity;\nimport android.content.Context;\nimport android.content.SharedPreferences;\nimport android.content.res.AssetFileDescriptor;\nimport android.media.AudioManager;\nimport android.media.MediaPlayer;\nimport android.os.Vibrator;\nimport android.preference.PreferenceManager;\nimport android.util.Log;\nimport com.google.zxing.FakeR;\n\nimport java.io.IOException;\n\n/**\n * Manages beeps and vibrations for {@link CaptureActivity}.\n */\nfinal class BeepManager {\n\n  private static final String TAG = BeepManager.class.getSimpleName();\n\n  private static final float BEEP_VOLUME = 0.10f;\n  private static final long VIBRATE_DURATION = 200L;\n\n  private final Activity activity;\n  private MediaPlayer mediaPlayer;\n  private boolean playBeep;\n  private boolean vibrate;\n\n  private static FakeR fakeR;\n  BeepManager(Activity activity) {\n\tfakeR = new FakeR(activity);\n    this.activity = activity;\n    this.mediaPlayer = null;\n    updatePrefs();\n  }\n\n  void updatePrefs() {\n    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);\n    playBeep = shouldBeep(prefs, activity);\n    vibrate = prefs.getBoolean(PreferencesActivity.KEY_VIBRATE, false);\n    if (playBeep && mediaPlayer == null) {\n      // The volume on STREAM_SYSTEM is not adjustable, and users found it too loud,\n      // so we now play on the music stream.\n      activity.setVolumeControlStream(AudioManager.STREAM_MUSIC);\n      mediaPlayer = buildMediaPlayer(activity);\n    }\n  }\n\n  void playBeepSoundAndVibrate() {\n    if (playBeep && mediaPlayer != null) {\n      mediaPlayer.start();\n    }\n    if (vibrate) {\n      Vibrator vibrator = (Vibrator) activity.getSystemService(Context.VIBRATOR_SERVICE);\n      vibrator.vibrate(VIBRATE_DURATION);\n    }\n  }\n\n  private static boolean shouldBeep(SharedPreferences prefs, Context activity) {\n    boolean shouldPlayBeep = prefs.getBoolean(PreferencesActivity.KEY_PLAY_BEEP, true);\n    if (shouldPlayBeep) {\n      // See if sound settings overrides this\n      AudioManager audioService = (AudioManager) activity.getSystemService(Context.AUDIO_SERVICE);\n      if (audioService.getRingerMode() != AudioManager.RINGER_MODE_NORMAL) {\n        shouldPlayBeep = false;\n      }\n    }\n    return shouldPlayBeep;\n  }\n\n  private static MediaPlayer buildMediaPlayer(Context activity) {\n    MediaPlayer mediaPlayer = new MediaPlayer();\n    mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);\n    // When the beep has finished playing, rewind to queue up another one.\n    mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {\n      @Override\n      public void onCompletion(MediaPlayer player) {\n        player.seekTo(0);\n      }\n    });\n\n    AssetFileDescriptor file = activity.getResources().openRawResourceFd(fakeR.getId(\"raw\", \"beep\"));\n    try {\n      mediaPlayer.setDataSource(file.getFileDescriptor(), file.getStartOffset(), file.getLength());\n      file.close();\n      mediaPlayer.setVolume(BEEP_VOLUME, BEEP_VOLUME);\n      mediaPlayer.prepare();\n    } catch (IOException ioe) {\n      Log.w(TAG, ioe);\n      mediaPlayer = null;\n    }\n    return mediaPlayer;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/CaptureActivity.java",
    "content": "/*\n * Copyright (C) 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android;\n\nimport android.content.pm.ActivityInfo;\nimport android.content.res.Configuration;\nimport android.hardware.Camera;\nimport android.widget.Button;\nimport com.google.zxing.BarcodeFormat;\nimport com.google.zxing.Result;\nimport com.google.zxing.ResultMetadataType;\nimport com.google.zxing.ResultPoint;\nimport com.google.zxing.client.android.camera.CameraManager;\nimport com.google.zxing.client.android.history.HistoryActivity;\nimport com.google.zxing.client.android.history.HistoryItem;\nimport com.google.zxing.client.android.history.HistoryManager;\nimport com.google.zxing.client.android.result.ResultButtonListener;\nimport com.google.zxing.client.android.result.ResultHandler;\nimport com.google.zxing.client.android.result.ResultHandlerFactory;\nimport com.google.zxing.client.android.result.supplement.SupplementalInfoRetriever;\nimport com.google.zxing.client.android.share.BookmarkPickerActivity;\nimport com.google.zxing.client.android.share.ShareActivity;\n\nimport android.app.Activity;\nimport android.app.AlertDialog;\nimport android.content.Intent;\nimport android.content.SharedPreferences;\nimport android.content.pm.PackageInfo;\nimport android.content.pm.PackageManager;\nimport android.graphics.Bitmap;\nimport android.graphics.BitmapFactory;\nimport android.graphics.Canvas;\nimport android.graphics.Paint;\nimport android.net.Uri;\nimport android.os.Bundle;\nimport android.os.Handler;\nimport android.os.Message;\nimport android.preference.PreferenceManager;\nimport android.text.ClipboardManager;\nimport android.util.Log;\nimport android.util.TypedValue;\nimport android.view.KeyEvent;\nimport android.view.Menu;\nimport android.view.MenuInflater;\nimport android.view.MenuItem;\nimport android.view.SurfaceHolder;\nimport android.view.SurfaceView;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.view.Window;\nimport android.view.WindowManager;\nimport android.widget.ImageView;\nimport android.widget.TextView;\nimport android.widget.Toast;\nimport com.google.zxing.FakeR;\n\nimport java.io.IOException;\nimport java.io.UnsupportedEncodingException;\nimport java.net.URLEncoder;\nimport java.text.DateFormat;\nimport java.util.Collection;\nimport java.util.Date;\nimport java.util.EnumSet;\nimport java.util.Map;\nimport java.util.Set;\n\n/**\n * This activity opens the camera and does the actual scanning on a background thread. It draws a\n * viewfinder to help the user place the barcode correctly, shows feedback as the image processing\n * is happening, and then overlays the results when a scan is successful.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n * @author Sean Owen\n */\npublic final class CaptureActivity extends Activity implements SurfaceHolder.Callback {\n  private static FakeR fakeR;\n\n  private static final String TAG = CaptureActivity.class.getSimpleName();\n\n  private static final long DEFAULT_INTENT_RESULT_DURATION_MS = 1500L;\n  private static final long BULK_MODE_SCAN_DELAY_MS = 1000L;\n\n  private static final String PACKAGE_NAME = \"com.google.zxing.client.android\";\n  private static final String PRODUCT_SEARCH_URL_PREFIX = \"http://www.google\";\n  private static final String PRODUCT_SEARCH_URL_SUFFIX = \"/m/products/scan\";\n  private static final String[] ZXING_URLS = { \"http://zxing.appspot.com/scan\", \"zxing://scan/\" };\n  private static final String RETURN_CODE_PLACEHOLDER = \"{CODE}\";\n  private static final String RETURN_URL_PARAM = \"ret\";\n  private static final String RAW_PARAM = \"raw\";\n\n  public static final int HISTORY_REQUEST_CODE = 0x0000bacc;\n\n  private static final Set<ResultMetadataType> DISPLAYABLE_METADATA_TYPES =\n      EnumSet.of(ResultMetadataType.ISSUE_NUMBER,\n                 ResultMetadataType.SUGGESTED_PRICE,\n                 ResultMetadataType.ERROR_CORRECTION_LEVEL,\n                 ResultMetadataType.POSSIBLE_COUNTRY);\n\n  private CameraManager cameraManager;\n  private CaptureActivityHandler handler;\n  private Result savedResultToShow;\n  private ViewfinderView viewfinderView;\n  private TextView statusView;\n  private Button flipButton;\n  private View resultView;\n  private Result lastResult;\n  private boolean hasSurface;\n  private boolean copyToClipboard;\n  private IntentSource source;\n  private String sourceUrl;\n  private String returnUrlTemplate;\n  private boolean returnRaw;\n  private Collection<BarcodeFormat> decodeFormats;\n  private String characterSet;\n  private HistoryManager historyManager;\n  private InactivityTimer inactivityTimer;\n  private BeepManager beepManager;\n\n  ViewfinderView getViewfinderView() {\n    return viewfinderView;\n  }\n\n  public Handler getHandler() {\n    return handler;\n  }\n\n  CameraManager getCameraManager() {\n    return cameraManager;\n  }\n\n  @Override\n  public void onConfigurationChanged(Configuration newConfig) {\n    super.onConfigurationChanged(newConfig);\n    // recreate is required for cases when no targetSdkVersion has been set in AndroidManifest.xml\n    // and the orientation has changed\n    recreate();\n  }\n\n  @Override\n  public void onCreate(Bundle icicle) {\n    super.onCreate(icicle);\n\n\tfakeR = new FakeR(this);\n\n    Window window = getWindow();\n    window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);\n    setContentView(fakeR.getId(\"layout\", \"capture\"));\n\n    hasSurface = false;\n    historyManager = new HistoryManager(this);\n    historyManager.trimHistory();\n    inactivityTimer = new InactivityTimer(this);\n    beepManager = new BeepManager(this);\n\n    PreferenceManager.setDefaultValues(this, fakeR.getId(\"xml\", \"preferences\"), false);\n\n    //showHelpOnFirstLaunch();\n  }\n\n  @Override\n  protected void onResume() {\n    super.onResume();\n\n    // CameraManager must be initialized here, not in onCreate(). This is necessary because we don't\n    // want to open the camera driver and measure the screen size if we're going to show the help on\n    // first launch. That led to bugs where the scanning rectangle was the wrong size and partially\n    // off screen.\n    cameraManager = new CameraManager(getApplication());\n\n    viewfinderView = (ViewfinderView) findViewById(fakeR.getId(\"id\", \"viewfinder_view\"));\n    viewfinderView.setCameraManager(cameraManager);\n\n    resultView = findViewById(fakeR.getId(\"id\", \"result_view\"));\n    statusView = (TextView) findViewById(fakeR.getId(\"id\", \"status_view\"));\n\n    handler = null;\n    lastResult = null;\n\n    resetStatusView();\n\n    SurfaceView surfaceView = (SurfaceView) findViewById(fakeR.getId(\"id\", \"preview_view\"));\n    SurfaceHolder surfaceHolder = surfaceView.getHolder();\n    if (hasSurface) {\n      // The activity was paused but not stopped, so the surface still exists. Therefore\n      // surfaceCreated() won't be called, so init the camera here.\n      initCamera(surfaceHolder);\n    } else {\n      // Install the callback and wait for surfaceCreated() to init the camera.\n      surfaceHolder.addCallback(this);\n      surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);\n    }\n\n    beepManager.updatePrefs();\n\n    inactivityTimer.onResume();\n\n    Intent intent = getIntent();\n\n    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);\n    copyToClipboard = prefs.getBoolean(PreferencesActivity.KEY_COPY_TO_CLIPBOARD, true)\n        && (intent == null || intent.getBooleanExtra(Intents.Scan.SAVE_HISTORY, true));\n\n    // source = IntentSource.NONE;\n    source = IntentSource.NATIVE_APP_INTENT;\n    decodeFormats = null;\n    characterSet = null;\n\n    if (intent != null) {\n\n      String action = intent.getAction();\n      String dataString = intent.getDataString();\n\n      if (Intents.Scan.ACTION.equals(action)) {\n\n        // Scan the formats the intent requested, and return the result to the calling activity.\n        source = IntentSource.NATIVE_APP_INTENT;\n        decodeFormats = DecodeFormatManager.parseDecodeFormats(intent);\n\n        if (intent.hasExtra(Intents.Scan.WIDTH) && intent.hasExtra(Intents.Scan.HEIGHT)) {\n          int width = intent.getIntExtra(Intents.Scan.WIDTH, 0);\n          int height = intent.getIntExtra(Intents.Scan.HEIGHT, 0);\n          if (width > 0 && height > 0) {\n            cameraManager.setManualFramingRect(width, height);\n          }\n        }\n        \n        String customPromptMessage = intent.getStringExtra(Intents.Scan.PROMPT_MESSAGE);\n        if (customPromptMessage != null) {\n          statusView.setText(customPromptMessage);\n        }\n\n      } else if (dataString != null &&\n                 dataString.contains(PRODUCT_SEARCH_URL_PREFIX) &&\n                 dataString.contains(PRODUCT_SEARCH_URL_SUFFIX)) {\n\n        // Scan only products and send the result to mobile Product Search.\n        source = IntentSource.PRODUCT_SEARCH_LINK;\n        sourceUrl = dataString;\n        decodeFormats = DecodeFormatManager.PRODUCT_FORMATS;\n\n      } else if (isZXingURL(dataString)) {\n\n        // Scan formats requested in query string (all formats if none specified).\n        // If a return URL is specified, send the results there. Otherwise, handle it ourselves.\n        source = IntentSource.ZXING_LINK;\n        sourceUrl = dataString;\n        Uri inputUri = Uri.parse(sourceUrl);\n        returnUrlTemplate = inputUri.getQueryParameter(RETURN_URL_PARAM);\n        returnRaw = inputUri.getQueryParameter(RAW_PARAM) != null;\n        decodeFormats = DecodeFormatManager.parseDecodeFormats(inputUri);\n\n      }\n\n      characterSet = intent.getStringExtra(Intents.Scan.CHARACTER_SET);\n\n    }\n  }\n  \n  private static boolean isZXingURL(String dataString) {\n    if (dataString == null) {\n      return false;\n    }\n    for (String url : ZXING_URLS) {\n      if (dataString.startsWith(url)) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  @Override\n  protected void onPause() {\n    if (handler != null) {\n      handler.quitSynchronously();\n      handler = null;\n    }\n    inactivityTimer.onPause();\n    cameraManager.closeDriver();\n    if (!hasSurface) {\n      SurfaceView surfaceView = (SurfaceView) findViewById(fakeR.getId(\"id\", \"preview_view\"));\n      SurfaceHolder surfaceHolder = surfaceView.getHolder();\n      surfaceHolder.removeCallback(this);\n    }\n    super.onPause();\n  }\n\n  @Override\n  protected void onDestroy() {\n    inactivityTimer.shutdown();\n    super.onDestroy();\n  }\n\n  @Override\n  public boolean onKeyDown(int keyCode, KeyEvent event) {\n    switch (keyCode) {\n      case KeyEvent.KEYCODE_BACK:\n        if (source == IntentSource.NATIVE_APP_INTENT) {\n          setResult(RESULT_CANCELED);\n          finish();\n          return true;\n        }\n        if ((source == IntentSource.NONE || source == IntentSource.ZXING_LINK) && lastResult != null) {\n          restartPreviewAfterDelay(0L);\n          return true;\n        }\n        break;\n      case KeyEvent.KEYCODE_FOCUS:\n      case KeyEvent.KEYCODE_CAMERA:\n        // Handle these events so they don't launch the Camera app\n        return true;\n      // Use volume up/down to turn on light\n      case KeyEvent.KEYCODE_VOLUME_DOWN:\n        cameraManager.setTorch(false);\n        return true;\n      case KeyEvent.KEYCODE_VOLUME_UP:\n        cameraManager.setTorch(true);\n        return true;\n    }\n    return super.onKeyDown(keyCode, event);\n  }\n\n  @Override\n  public boolean onCreateOptionsMenu(Menu menu) {\n    MenuInflater menuInflater = getMenuInflater();\n    menuInflater.inflate(fakeR.getId(\"menu\", \"capture\"), menu);\n    return super.onCreateOptionsMenu(menu);\n  }\n\n  @Override\n  public boolean onOptionsItemSelected(MenuItem item) {\n    Intent intent = new Intent(Intent.ACTION_VIEW);\n    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);\n    int itemId = item.getItemId();\n    if (itemId == fakeR.getId(\"id\", \"menu_share\")) {\n        intent.setClassName(this, ShareActivity.class.getName());\n        startActivity(intent);\n    } else if (itemId == fakeR.getId(\"id\", \"menu_history\")) {\n        intent.setClassName(this, HistoryActivity.class.getName());\n        startActivityForResult(intent, HISTORY_REQUEST_CODE);\n    } else if (itemId == fakeR.getId(\"id\", \"menu_settings\")) {\n        intent.setClassName(this, PreferencesActivity.class.getName());\n        startActivity(intent);\n    } else if (itemId == fakeR.getId(\"id\", \"menu_help\")) {\n        intent.setClassName(this, HelpActivity.class.getName());\n        startActivity(intent);\n    } else {\n        return super.onOptionsItemSelected(item);\n    }\n    return true;\n  }\n\n  @Override\n  public void onActivityResult(int requestCode, int resultCode, Intent intent) {\n    if (resultCode == RESULT_OK) {\n      if (requestCode == HISTORY_REQUEST_CODE) {\n        int itemNumber = intent.getIntExtra(Intents.History.ITEM_NUMBER, -1);\n        if (itemNumber >= 0) {\n          HistoryItem historyItem = historyManager.buildHistoryItem(itemNumber);\n          decodeOrStoreSavedBitmap(null, historyItem.getResult());\n        }\n      }\n    }\n  }\n\n  private void decodeOrStoreSavedBitmap(Bitmap bitmap, Result result) {\n    // Bitmap isn't used yet -- will be used soon\n    if (handler == null) {\n      savedResultToShow = result;\n    } else {\n      if (result != null) {\n        savedResultToShow = result;\n      }\n      if (savedResultToShow != null) {\n        Message message = Message.obtain(handler, fakeR.getId(\"id\", \"decode_succeeded\"), savedResultToShow);\n        handler.sendMessage(message);\n      }\n      savedResultToShow = null;\n    }\n  }\n\n  @Override\n  public void surfaceCreated(SurfaceHolder holder) {\n    if (holder == null) {\n      Log.e(TAG, \"*** WARNING *** surfaceCreated() gave us a null surface!\");\n    }\n    if (!hasSurface) {\n      hasSurface = true;\n      initCamera(holder);\n    }\n  }\n\n  @Override\n  public void surfaceDestroyed(SurfaceHolder holder) {\n    hasSurface = false;\n  }\n\n  @Override\n  public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {\n\n  }\n\n  /**\n   * A valid barcode has been found, so give an indication of success and show the results.\n   *\n   * @param rawResult The contents of the barcode.\n   * @param barcode   A greyscale bitmap of the camera data which was decoded.\n   */\n  public void handleDecode(Result rawResult, Bitmap barcode) {\n    inactivityTimer.onActivity();\n    lastResult = rawResult;\n    ResultHandler resultHandler = ResultHandlerFactory.makeResultHandler(this, rawResult);\n\n    boolean fromLiveScan = barcode != null;\n    if (fromLiveScan) {\n      historyManager.addHistoryItem(rawResult, resultHandler);\n      // Then not from history, so beep/vibrate and we have an image to draw on\n      beepManager.playBeepSoundAndVibrate();\n      drawResultPoints(barcode, rawResult);\n    }\n\n    switch (source) {\n      case NATIVE_APP_INTENT:\n      case PRODUCT_SEARCH_LINK:\n        handleDecodeExternally(rawResult, resultHandler, barcode);\n        break;\n      case ZXING_LINK:\n        if (returnUrlTemplate == null){\n          handleDecodeInternally(rawResult, resultHandler, barcode);\n        } else {\n          handleDecodeExternally(rawResult, resultHandler, barcode);\n        }\n        break;\n      case NONE:\n        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);\n        if (fromLiveScan && prefs.getBoolean(PreferencesActivity.KEY_BULK_MODE, false)) {\n          String message = getResources().getString(fakeR.getId(\"string\", \"msg_bulk_mode_scanned\"))\n              + \" (\" + rawResult.getText() + ')';\n          Toast.makeText(this, message, Toast.LENGTH_SHORT).show();\n          // Wait a moment or else it will scan the same barcode continuously about 3 times\n          restartPreviewAfterDelay(BULK_MODE_SCAN_DELAY_MS);\n        } else {\n          handleDecodeInternally(rawResult, resultHandler, barcode);\n        }\n        break;\n    }\n  }\n\n  /**\n   * Superimpose a line for 1D or dots for 2D to highlight the key features of the barcode.\n   *\n   * @param barcode   A bitmap of the captured image.\n   * @param rawResult The decoded results which contains the points to draw.\n   */\n  private void drawResultPoints(Bitmap barcode, Result rawResult) {\n    ResultPoint[] points = rawResult.getResultPoints();\n    if (points != null && points.length > 0) {\n      Canvas canvas = new Canvas(barcode);\n      Paint paint = new Paint();\n      paint.setColor(getResources().getColor(fakeR.getId(\"color\", \"result_points\")));\n      if (points.length == 2) {\n        paint.setStrokeWidth(4.0f);\n        drawLine(canvas, paint, points[0], points[1]);\n      } else if (points.length == 4 &&\n                 (rawResult.getBarcodeFormat() == BarcodeFormat.UPC_A ||\n                  rawResult.getBarcodeFormat() == BarcodeFormat.EAN_13)) {\n        // Hacky special case -- draw two lines, for the barcode and metadata\n        drawLine(canvas, paint, points[0], points[1]);\n        drawLine(canvas, paint, points[2], points[3]);\n      } else {\n        paint.setStrokeWidth(10.0f);\n        for (ResultPoint point : points) {\n          canvas.drawPoint(point.getX(), point.getY(), paint);\n        }\n      }\n    }\n  }\n\n  private static void drawLine(Canvas canvas, Paint paint, ResultPoint a, ResultPoint b) {\n    canvas.drawLine(a.getX(), a.getY(), b.getX(), b.getY(), paint);\n  }\n\n  // Put up our own UI for how to handle the decoded contents.\n  private void handleDecodeInternally(Result rawResult, ResultHandler resultHandler, Bitmap barcode) {\n    statusView.setVisibility(View.GONE);\n    viewfinderView.setVisibility(View.GONE);\n    resultView.setVisibility(View.VISIBLE);\n\n    ImageView barcodeImageView = (ImageView) findViewById(fakeR.getId(\"id\", \"barcode_image_view\"));\n    if (barcode == null) {\n      barcodeImageView.setImageBitmap(BitmapFactory.decodeResource(getResources(),\n          fakeR.getId(\"drawable\", \"launcher_icon\")));\n    } else {\n      barcodeImageView.setImageBitmap(barcode);\n    }\n\n    TextView formatTextView = (TextView) findViewById(fakeR.getId(\"id\", \"format_text_view\"));\n    formatTextView.setText(rawResult.getBarcodeFormat().toString());\n\n    TextView typeTextView = (TextView) findViewById(fakeR.getId(\"id\", \"type_text_view\"));\n    typeTextView.setText(resultHandler.getType().toString());\n\n    DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);\n    String formattedTime = formatter.format(new Date(rawResult.getTimestamp()));\n    TextView timeTextView = (TextView) findViewById(fakeR.getId(\"id\", \"time_text_view\"));\n    timeTextView.setText(formattedTime);\n\n\n    TextView metaTextView = (TextView) findViewById(fakeR.getId(\"id\", \"meta_text_view\"));\n    View metaTextViewLabel = findViewById(fakeR.getId(\"id\", \"meta_text_view_label\"));\n    metaTextView.setVisibility(View.GONE);\n    metaTextViewLabel.setVisibility(View.GONE);\n    Map<ResultMetadataType,Object> metadata = rawResult.getResultMetadata();\n    if (metadata != null) {\n      StringBuilder metadataText = new StringBuilder(20);\n      for (Map.Entry<ResultMetadataType,Object> entry : metadata.entrySet()) {\n        if (DISPLAYABLE_METADATA_TYPES.contains(entry.getKey())) {\n          metadataText.append(entry.getValue()).append('\\n');\n        }\n      }\n      if (metadataText.length() > 0) {\n        metadataText.setLength(metadataText.length() - 1);\n        metaTextView.setText(metadataText);\n        metaTextView.setVisibility(View.VISIBLE);\n        metaTextViewLabel.setVisibility(View.VISIBLE);\n      }\n    }\n\n    TextView contentsTextView = (TextView) findViewById(fakeR.getId(\"id\", \"contents_text_view\"));\n    CharSequence displayContents = resultHandler.getDisplayContents();\n    contentsTextView.setText(displayContents);\n    // Crudely scale betweeen 22 and 32 -- bigger font for shorter text\n    int scaledSize = Math.max(22, 32 - displayContents.length() / 4);\n    contentsTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, scaledSize);\n\n    TextView supplementTextView = (TextView) findViewById(fakeR.getId(\"id\", \"contents_supplement_text_view\"));\n    supplementTextView.setText(\"\");\n    supplementTextView.setOnClickListener(null);\n    if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean(\n        PreferencesActivity.KEY_SUPPLEMENTAL, true)) {\n      SupplementalInfoRetriever.maybeInvokeRetrieval(supplementTextView,\n                                                     resultHandler.getResult(),\n                                                     historyManager,\n                                                     this);\n    }\n\n    int buttonCount = resultHandler.getButtonCount();\n    ViewGroup buttonView = (ViewGroup) findViewById(fakeR.getId(\"id\", \"result_button_view\"));\n    buttonView.requestFocus();\n    for (int x = 0; x < ResultHandler.MAX_BUTTON_COUNT; x++) {\n      TextView button = (TextView) buttonView.getChildAt(x);\n      if (x < buttonCount) {\n        button.setVisibility(View.VISIBLE);\n        button.setText(resultHandler.getButtonText(x));\n        button.setOnClickListener(new ResultButtonListener(resultHandler, x));\n      } else {\n        button.setVisibility(View.GONE);\n      }\n    }\n\n    if (copyToClipboard && !resultHandler.areContentsSecure()) {\n      ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);\n      if (displayContents != null) {\n        clipboard.setText(displayContents);\n      }\n    }\n  }\n\n  // Briefly show the contents of the barcode, then handle the result outside Barcode Scanner.\n  private void handleDecodeExternally(Result rawResult, ResultHandler resultHandler, Bitmap barcode) {\n    if (barcode != null) {\n      viewfinderView.drawResultBitmap(barcode);\n    }\n\n    long resultDurationMS;\n    if (getIntent() == null) {\n      resultDurationMS = DEFAULT_INTENT_RESULT_DURATION_MS;\n    } else {\n      resultDurationMS = getIntent().getLongExtra(Intents.Scan.RESULT_DISPLAY_DURATION_MS,\n                                                  DEFAULT_INTENT_RESULT_DURATION_MS);\n    }\n\n    // Since this message will only be shown for a second, just tell the user what kind of\n    // barcode was found (e.g. contact info) rather than the full contents, which they won't\n    // have time to read.\n    if (resultDurationMS > 0) {\n      statusView.setText(getString(resultHandler.getDisplayTitle()));\n    }\n\n    if (copyToClipboard && !resultHandler.areContentsSecure()) {\n      ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);\n      CharSequence text = resultHandler.getDisplayContents();\n      if (text != null) {\n        clipboard.setText(text);\n      }\n    }\n\n    if (source == IntentSource.NATIVE_APP_INTENT) {\n      \n      // Hand back whatever action they requested - this can be changed to Intents.Scan.ACTION when\n      // the deprecated intent is retired.\n      Intent intent = new Intent(getIntent().getAction());\n      intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);\n      intent.putExtra(Intents.Scan.RESULT, rawResult.toString());\n      intent.putExtra(Intents.Scan.RESULT_FORMAT, rawResult.getBarcodeFormat().toString());\n      byte[] rawBytes = rawResult.getRawBytes();\n      if (rawBytes != null && rawBytes.length > 0) {\n        intent.putExtra(Intents.Scan.RESULT_BYTES, rawBytes);\n      }\n      Map<ResultMetadataType,?> metadata = rawResult.getResultMetadata();\n      if (metadata != null) {\n        if (metadata.containsKey(ResultMetadataType.UPC_EAN_EXTENSION)) {\n          intent.putExtra(Intents.Scan.RESULT_UPC_EAN_EXTENSION,\n                          metadata.get(ResultMetadataType.UPC_EAN_EXTENSION).toString());\n        }\n        Integer orientation = (Integer) metadata.get(ResultMetadataType.ORIENTATION);\n        if (orientation != null) {\n          intent.putExtra(Intents.Scan.RESULT_ORIENTATION, orientation.intValue());\n        }\n        String ecLevel = (String) metadata.get(ResultMetadataType.ERROR_CORRECTION_LEVEL);\n        if (ecLevel != null) {\n          intent.putExtra(Intents.Scan.RESULT_ERROR_CORRECTION_LEVEL, ecLevel);\n        }\n        Iterable<byte[]> byteSegments = (Iterable<byte[]>) metadata.get(ResultMetadataType.BYTE_SEGMENTS);\n        if (byteSegments != null) {\n          int i = 0;\n          for (byte[] byteSegment : byteSegments) {\n            intent.putExtra(Intents.Scan.RESULT_BYTE_SEGMENTS_PREFIX + i, byteSegment);\n            i++;\n          }\n        }\n      }\n      sendReplyMessage(fakeR.getId(\"id\", \"return_scan_result\"), intent, resultDurationMS);\n      \n    } else if (source == IntentSource.PRODUCT_SEARCH_LINK) {\n      \n      // Reformulate the URL which triggered us into a query, so that the request goes to the same\n      // TLD as the scan URL.\n      int end = sourceUrl.lastIndexOf(\"/scan\");\n      String replyURL = sourceUrl.substring(0, end) + \"?q=\" + resultHandler.getDisplayContents() + \"&source=zxing\";      \n      sendReplyMessage(fakeR.getId(\"id\", \"launch_product_query\"), replyURL, resultDurationMS);\n      \n    } else if (source == IntentSource.ZXING_LINK) {\n      \n      // Replace each occurrence of RETURN_CODE_PLACEHOLDER in the returnUrlTemplate\n      // with the scanned code. This allows both queries and REST-style URLs to work.\n      if (returnUrlTemplate != null) {\n        CharSequence codeReplacement = returnRaw ? rawResult.getText() : resultHandler.getDisplayContents();\n        try {\n          codeReplacement = URLEncoder.encode(codeReplacement.toString(), \"UTF-8\");\n        } catch (UnsupportedEncodingException e) {\n          // can't happen; UTF-8 is always supported. Continue, I guess, without encoding\n        }\n        String replyURL = returnUrlTemplate.replace(RETURN_CODE_PLACEHOLDER, codeReplacement);\n        sendReplyMessage(fakeR.getId(\"id\", \"launch_product_query\"), replyURL, resultDurationMS);\n      }\n      \n    }\n  }\n  \n  private void sendReplyMessage(int id, Object arg, long delayMS) {\n    Message message = Message.obtain(handler, id, arg);\n    if (delayMS > 0L) {\n      handler.sendMessageDelayed(message, delayMS);\n    } else {\n      handler.sendMessage(message);\n    }\n  }\n\n  /**\n   * We want the help screen to be shown automatically the first time a new version of the app is\n   * run. The easiest way to do this is to check android:versionCode from the manifest, and compare\n   * it to a value stored as a preference.\n   */\n  private boolean showHelpOnFirstLaunch() {\n    try {\n      PackageInfo info = getPackageManager().getPackageInfo(PACKAGE_NAME, 0);\n      int currentVersion = info.versionCode;\n      SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);\n      int lastVersion = prefs.getInt(PreferencesActivity.KEY_HELP_VERSION_SHOWN, 0);\n      if (currentVersion > lastVersion) {\n        prefs.edit().putInt(PreferencesActivity.KEY_HELP_VERSION_SHOWN, currentVersion).commit();\n        Intent intent = new Intent(this, HelpActivity.class);\n        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);\n        // Show the default page on a clean install, and the what's new page on an upgrade.\n        String page = lastVersion == 0 ? HelpActivity.DEFAULT_PAGE : HelpActivity.WHATS_NEW_PAGE;\n        intent.putExtra(HelpActivity.REQUESTED_PAGE_KEY, page);\n        startActivity(intent);\n        return true;\n      }\n    } catch (PackageManager.NameNotFoundException e) {\n      Log.w(TAG, e);\n    }\n    return false;\n  }\n\n  private void initCamera(SurfaceHolder surfaceHolder) {\n    if (surfaceHolder == null) {\n      throw new IllegalStateException(\"No SurfaceHolder provided\");\n    }\n    if (cameraManager.isOpen()) {\n      Log.w(TAG, \"initCamera() while already open -- late SurfaceView callback?\");\n      return;\n    }\n    try {\n      cameraManager.openDriver(surfaceHolder);\n      // Creating the handler starts the preview, which can also throw a RuntimeException.\n      if (handler == null) {\n        handler = new CaptureActivityHandler(this, decodeFormats, characterSet, cameraManager);\n      }\n      decodeOrStoreSavedBitmap(null, null);\n    } catch (IOException ioe) {\n      Log.w(TAG, ioe);\n      displayFrameworkBugMessageAndExit();\n    } catch (RuntimeException e) {\n      // Barcode Scanner has seen crashes in the wild of this variety:\n      // java.?lang.?RuntimeException: Fail to connect to camera service\n      Log.w(TAG, \"Unexpected error initializing camera\", e);\n      displayFrameworkBugMessageAndExit();\n    }\n  }\n\n  private void displayFrameworkBugMessageAndExit() {\n    AlertDialog.Builder builder = new AlertDialog.Builder(this);\n    builder.setTitle(getString(fakeR.getId(\"string\", \"app_name\")));\n    builder.setMessage(getString(fakeR.getId(\"string\", \"msg_camera_framework_bug\")));\n    builder.setPositiveButton(fakeR.getId(\"string\", \"button_ok\"), new FinishListener(this));\n    builder.setOnCancelListener(new FinishListener(this));\n    builder.show();\n  }\n\n  public void restartPreviewAfterDelay(long delayMS) {\n    if (handler != null) {\n      handler.sendEmptyMessageDelayed(fakeR.getId(\"id\", \"restart_preview\"), delayMS);\n    }\n    resetStatusView();\n  }\n\n  private void resetStatusView() {\n    resultView.setVisibility(View.GONE);\n    statusView.setText(fakeR.getId(\"string\", \"msg_default_status\"));\n    statusView.setVisibility(View.VISIBLE);\n    viewfinderView.setVisibility(View.VISIBLE);\n    lastResult = null;\n  }\n\n  public void drawViewfinder() {\n    viewfinderView.drawViewfinder();\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/CaptureActivityHandler.java",
    "content": "/*\n * Copyright (C) 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android;\n\nimport android.content.ActivityNotFoundException;\nimport android.content.pm.PackageManager;\nimport android.content.pm.ResolveInfo;\nimport android.provider.Browser;\nimport com.google.zxing.BarcodeFormat;\nimport com.google.zxing.Result;\nimport com.google.zxing.client.android.camera.CameraManager;\n\nimport android.app.Activity;\nimport android.content.Intent;\nimport android.graphics.Bitmap;\nimport android.net.Uri;\nimport android.os.Bundle;\nimport android.os.Handler;\nimport android.os.Message;\nimport android.util.Log;\nimport com.google.zxing.FakeR;\n\nimport java.util.Collection;\n\n/**\n * This class handles all the messaging which comprises the state machine for capture.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n */\npublic final class CaptureActivityHandler extends Handler {\n\n  private static final String TAG = CaptureActivityHandler.class.getSimpleName();\n\n  private final CaptureActivity activity;\n  private final DecodeThread decodeThread;\n  private State state;\n  private final CameraManager cameraManager;\n\n  private enum State {\n    PREVIEW,\n    SUCCESS,\n    DONE\n  }\n\n  private static FakeR fakeR;\n\n  CaptureActivityHandler(CaptureActivity activity,\n                         Collection<BarcodeFormat> decodeFormats,\n                         String characterSet,\n                         CameraManager cameraManager) {\n\tfakeR = new FakeR(activity);\n    this.activity = activity;\n    decodeThread = new DecodeThread(activity, decodeFormats, characterSet,\n        new ViewfinderResultPointCallback(activity.getViewfinderView()));\n    decodeThread.start();\n    state = State.SUCCESS;\n\n    // Start ourselves capturing previews and decoding.\n    this.cameraManager = cameraManager;\n    cameraManager.startPreview();\n    restartPreviewAndDecode();\n  }\n\n  @Override\n  public void handleMessage(Message message) {\n    if (message.what == fakeR.getId(\"id\", \"restart_preview\")) {\n        Log.d(TAG, \"Got restart preview message\");\n        restartPreviewAndDecode();\n    } else if (message.what == fakeR.getId(\"id\", \"decode_succeeded\")) {\n        Log.d(TAG, \"Got decode succeeded message\");\n        state = State.SUCCESS;\n        Bundle bundle = message.getData();\n        Bitmap barcode = bundle == null ? null :\n            (Bitmap) bundle.getParcelable(DecodeThread.BARCODE_BITMAP);\n        activity.handleDecode((Result) message.obj, barcode);\n    } else if (message.what == fakeR.getId(\"id\", \"decode_failed\")) {\n        // We're decoding as fast as possible, so when one decode fails, start another.\n        state = State.PREVIEW;\n        cameraManager.requestPreviewFrame(decodeThread.getHandler(), fakeR.getId(\"id\", \"decode\"));\n    } else if (message.what == fakeR.getId(\"id\", \"return_scan_result\")) {\n        Log.d(TAG, \"Got return scan result message\");\n        activity.setResult(Activity.RESULT_OK, (Intent) message.obj);\n        activity.finish();\n    } else if (message.what == fakeR.getId(\"id\", \"launch_product_query\")) {\n        Log.d(TAG, \"Got product query message\");\n        String url = (String) message.obj;\n        Intent intent = new Intent(Intent.ACTION_VIEW);\n        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);\n        intent.setData(Uri.parse(url));\n        ResolveInfo resolveInfo =\n            activity.getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);\n        String browserPackageName = null;\n        if (resolveInfo.activityInfo != null) {\n          browserPackageName = resolveInfo.activityInfo.packageName;\n          Log.d(TAG, \"Using browser in package \" + browserPackageName);\n        }\n        // Needed for default Android browser only apparently\n        if (\"com.android.browser\".equals(browserPackageName)) {\n          intent.setPackage(browserPackageName);\n          intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);\n          intent.putExtra(Browser.EXTRA_APPLICATION_ID, browserPackageName);\n        }\n        try {\n          activity.startActivity(intent);\n        } catch (ActivityNotFoundException anfe) {\n          Log.w(TAG, \"Can't find anything to handle VIEW of URI \" + url);\n        }\n    }\n  }\n\n  public void quitSynchronously() {\n    state = State.DONE;\n    cameraManager.stopPreview();\n    Message quit = Message.obtain(decodeThread.getHandler(), fakeR.getId(\"id\", \"quit\"));\n    quit.sendToTarget();\n    try {\n      // Wait at most half a second; should be enough time, and onPause() will timeout quickly\n      decodeThread.join(500L);\n    } catch (InterruptedException e) {\n      // continue\n    }\n\n    // Be absolutely sure we don't send any queued up messages\n    removeMessages(fakeR.getId(\"id\", \"decode_succeeded\"));\n    removeMessages(fakeR.getId(\"id\", \"decode_failed\"));\n  }\n\n  private void restartPreviewAndDecode() {\n    if (state == State.SUCCESS) {\n      state = State.PREVIEW;\n      cameraManager.requestPreviewFrame(decodeThread.getHandler(), fakeR.getId(\"id\", \"decode\"));\n      activity.drawViewfinder();\n    }\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/Contents.java",
    "content": "/*\n * Copyright (C) 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android;\n\nimport android.provider.ContactsContract;\n\n/**\n * The set of constants to use when sending Barcode Scanner an Intent which requests a barcode\n * to be encoded.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n */\npublic final class Contents {\n  private Contents() {\n  }\n\n  public static final class Type {\n    /**\n     * Plain text. Use Intent.putExtra(DATA, string). This can be used for URLs too, but string\n     * must include \"http://\" or \"https://\".\n     */\n    public static final String TEXT = \"TEXT_TYPE\";\n\n    /**\n     * An email type. Use Intent.putExtra(DATA, string) where string is the email address.\n     */\n    public static final String EMAIL = \"EMAIL_TYPE\";\n\n    /**\n     * Use Intent.putExtra(DATA, string) where string is the phone number to call.\n     */\n    public static final String PHONE = \"PHONE_TYPE\";\n\n    /**\n     * An SMS type. Use Intent.putExtra(DATA, string) where string is the number to SMS.\n     */\n    public static final String SMS = \"SMS_TYPE\";\n\n    /**\n     * A contact. Send a request to encode it as follows:\n     * <p/>\n     * import android.provider.Contacts;\n     * <p/>\n     * Intent intent = new Intent(Intents.Encode.ACTION);\n     * intent.putExtra(Intents.Encode.TYPE, CONTACT);\n     * Bundle bundle = new Bundle();\n     * bundle.putString(Contacts.Intents.Insert.NAME, \"Jenny\");\n     * bundle.putString(Contacts.Intents.Insert.PHONE, \"8675309\");\n     * bundle.putString(Contacts.Intents.Insert.EMAIL, \"jenny@the80s.com\");\n     * bundle.putString(Contacts.Intents.Insert.POSTAL, \"123 Fake St. San Francisco, CA 94102\");\n     * intent.putExtra(Intents.Encode.DATA, bundle);\n     */\n    public static final String CONTACT = \"CONTACT_TYPE\";\n\n    /**\n     * A geographic location. Use as follows:\n     * Bundle bundle = new Bundle();\n     * bundle.putFloat(\"LAT\", latitude);\n     * bundle.putFloat(\"LONG\", longitude);\n     * intent.putExtra(Intents.Encode.DATA, bundle);\n     */\n    public static final String LOCATION = \"LOCATION_TYPE\";\n\n    private Type() {\n    }\n  }\n\n  public static final String URL_KEY = \"URL_KEY\";\n\n  public static final String NOTE_KEY = \"NOTE_KEY\";\n\n  /**\n   * When using Type.CONTACT, these arrays provide the keys for adding or retrieving multiple\n   * phone numbers and addresses.\n   */\n  public static final String[] PHONE_KEYS = {\n      ContactsContract.Intents.Insert.PHONE,\n      ContactsContract.Intents.Insert.SECONDARY_PHONE,\n      ContactsContract.Intents.Insert.TERTIARY_PHONE\n  };\n\n  public static final String[] PHONE_TYPE_KEYS = {\n      ContactsContract.Intents.Insert.PHONE_TYPE,\n      ContactsContract.Intents.Insert.SECONDARY_PHONE_TYPE,\n      ContactsContract.Intents.Insert.TERTIARY_PHONE_TYPE\n  };\n\n  public static final String[] EMAIL_KEYS = {\n      ContactsContract.Intents.Insert.EMAIL,\n      ContactsContract.Intents.Insert.SECONDARY_EMAIL,\n      ContactsContract.Intents.Insert.TERTIARY_EMAIL\n  };\n\n  public static final String[] EMAIL_TYPE_KEYS = {\n      ContactsContract.Intents.Insert.EMAIL_TYPE,\n      ContactsContract.Intents.Insert.SECONDARY_EMAIL_TYPE,\n      ContactsContract.Intents.Insert.TERTIARY_EMAIL_TYPE\n  };\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/DecodeFormatManager.java",
    "content": "/*\n * Copyright (C) 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android;\n\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.EnumSet;\nimport java.util.List;\nimport java.util.regex.Pattern;\n\nimport android.content.Intent;\nimport android.net.Uri;\nimport com.google.zxing.BarcodeFormat;\n\nfinal class DecodeFormatManager {\n\n  private static final Pattern COMMA_PATTERN = Pattern.compile(\",\");\n\n  static final Collection<BarcodeFormat> PRODUCT_FORMATS;\n  static final Collection<BarcodeFormat> ONE_D_FORMATS;\n  static final Collection<BarcodeFormat> QR_CODE_FORMATS = EnumSet.of(BarcodeFormat.QR_CODE);\n  static final Collection<BarcodeFormat> DATA_MATRIX_FORMATS = EnumSet.of(BarcodeFormat.DATA_MATRIX);\n  static {\n    PRODUCT_FORMATS = EnumSet.of(BarcodeFormat.UPC_A,\n                                 BarcodeFormat.UPC_E,\n                                 BarcodeFormat.EAN_13,\n                                 BarcodeFormat.EAN_8,\n                                 BarcodeFormat.RSS_14);\n    ONE_D_FORMATS = EnumSet.of(BarcodeFormat.CODE_39,\n                               BarcodeFormat.CODE_93,\n                               BarcodeFormat.CODE_128,\n                               BarcodeFormat.ITF,\n                               BarcodeFormat.CODABAR);\n    ONE_D_FORMATS.addAll(PRODUCT_FORMATS);\n  }\n\n  private DecodeFormatManager() {}\n\n  static Collection<BarcodeFormat> parseDecodeFormats(Intent intent) {\n    List<String> scanFormats = null;\n    String scanFormatsString = intent.getStringExtra(Intents.Scan.FORMATS);\n    if (scanFormatsString != null) {\n      scanFormats = Arrays.asList(COMMA_PATTERN.split(scanFormatsString));\n    }\n    return parseDecodeFormats(scanFormats, intent.getStringExtra(Intents.Scan.MODE));\n  }\n\n  static Collection<BarcodeFormat> parseDecodeFormats(Uri inputUri) {\n    List<String> formats = inputUri.getQueryParameters(Intents.Scan.FORMATS);\n    if (formats != null && formats.size() == 1 && formats.get(0) != null){\n      formats = Arrays.asList(COMMA_PATTERN.split(formats.get(0)));\n    }\n    return parseDecodeFormats(formats, inputUri.getQueryParameter(Intents.Scan.MODE));\n  }\n\n  private static Collection<BarcodeFormat> parseDecodeFormats(Iterable<String> scanFormats,\n                                                              String decodeMode) {\n    if (scanFormats != null) {\n      Collection<BarcodeFormat> formats = EnumSet.noneOf(BarcodeFormat.class);\n      try {\n        for (String format : scanFormats) {\n          formats.add(BarcodeFormat.valueOf(format));\n        }\n        return formats;\n      } catch (IllegalArgumentException iae) {\n        // ignore it then\n      }\n    }\n    if (decodeMode != null) {\n      if (Intents.Scan.PRODUCT_MODE.equals(decodeMode)) {\n        return PRODUCT_FORMATS;\n      }\n      if (Intents.Scan.QR_CODE_MODE.equals(decodeMode)) {\n        return QR_CODE_FORMATS;\n      }\n      if (Intents.Scan.DATA_MATRIX_MODE.equals(decodeMode)) {\n        return DATA_MATRIX_FORMATS;\n      }\n      if (Intents.Scan.ONE_D_MODE.equals(decodeMode)) {\n        return ONE_D_FORMATS;\n      }\n    }\n    return null;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/DecodeHandler.java",
    "content": "/*\n * Copyright (C) 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android;\n\nimport android.graphics.Bitmap;\nimport com.google.zxing.BinaryBitmap;\nimport com.google.zxing.DecodeHintType;\nimport com.google.zxing.LuminanceSource;\nimport com.google.zxing.MultiFormatReader;\nimport com.google.zxing.PlanarYUVLuminanceSource;\nimport com.google.zxing.ReaderException;\nimport com.google.zxing.Result;\nimport com.google.zxing.common.HybridBinarizer;\n\nimport android.os.Bundle;\nimport android.os.Handler;\nimport android.os.Looper;\nimport android.os.Message;\nimport android.util.Log;\nimport com.google.zxing.FakeR;\n\nimport java.util.Map;\n\nfinal class DecodeHandler extends Handler {\n\n  private static final String TAG = DecodeHandler.class.getSimpleName();\n\n  private final CaptureActivity activity;\n  private final MultiFormatReader multiFormatReader;\n  private boolean running = true;\n\n  private static FakeR fakeR;\n  DecodeHandler(CaptureActivity activity, Map<DecodeHintType,Object> hints) {\n\tfakeR = new FakeR(activity);\n    multiFormatReader = new MultiFormatReader();\n    multiFormatReader.setHints(hints);\n    this.activity = activity;\n  }\n\n  @Override\n  public void handleMessage(Message message) {\n    if (!running) {\n      return;\n    }\n    if (message.what == fakeR.getId(\"id\", \"decode\")) {\n        decode((byte[]) message.obj, message.arg1, message.arg2);\n    } else if (message.what == fakeR.getId(\"id\", \"quit\")) {\n        running = false;\n        Looper.myLooper().quit();\n    }\n  }\n\n  /**\n   * Decode the data within the viewfinder rectangle, and time how long it took. For efficiency,\n   * reuse the same reader objects from one decode to the next.\n   *\n   * @param data   The YUV preview frame.\n   * @param width  The width of the preview frame.\n   * @param height The height of the preview frame.\n   */\n  private void decode(byte[] data, int width, int height) {\n    long start = System.currentTimeMillis();\n    Result rawResult = null;\n    PlanarYUVLuminanceSource source = activity.getCameraManager().buildLuminanceSource(data, width, height);\n    if (source != null) {\n      BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));\n      try {\n        rawResult = multiFormatReader.decodeWithState(bitmap);\n      } catch (ReaderException re) {\n        // continue\n      } finally {\n        multiFormatReader.reset();\n      }\n    }\n\n    Handler handler = activity.getHandler();\n    if (rawResult != null) {\n      // Don't log the barcode contents for security.\n      long end = System.currentTimeMillis();\n      Log.d(TAG, \"Found barcode in \" + (end - start) + \" ms\");\n      if (handler != null) {\n        Message message = Message.obtain(handler, fakeR.getId(\"id\", \"decode_succeeded\"), rawResult);\n        Bundle bundle = new Bundle();\n        Bitmap grayscaleBitmap = toBitmap(source, source.renderCroppedGreyscaleBitmap());\n        bundle.putParcelable(DecodeThread.BARCODE_BITMAP, grayscaleBitmap);\n        message.setData(bundle);\n        message.sendToTarget();\n      }\n    } else {\n      if (handler != null) {\n        Message message = Message.obtain(handler, fakeR.getId(\"id\", \"decode_failed\"));\n        message.sendToTarget();\n      }\n    }\n  }\n\n  private static Bitmap toBitmap(LuminanceSource source, int[] pixels) {\n    int width = source.getWidth();\n    int height = source.getHeight();\n    Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);\n    bitmap.setPixels(pixels, 0, width, 0, 0, width, height);\n    return bitmap;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/DecodeThread.java",
    "content": "/*\n * Copyright (C) 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android;\n\nimport com.google.zxing.BarcodeFormat;\nimport com.google.zxing.DecodeHintType;\nimport com.google.zxing.ResultPointCallback;\n\nimport android.content.SharedPreferences;\nimport android.os.Handler;\nimport android.os.Looper;\nimport android.preference.PreferenceManager;\n\nimport java.util.Collection;\nimport java.util.EnumMap;\nimport java.util.EnumSet;\nimport java.util.Map;\nimport java.util.concurrent.CountDownLatch;\n\n/**\n * This thread does all the heavy lifting of decoding the images.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n */\nfinal class DecodeThread extends Thread {\n\n  public static final String BARCODE_BITMAP = \"barcode_bitmap\";\n\n  private final CaptureActivity activity;\n  private final Map<DecodeHintType,Object> hints;\n  private Handler handler;\n  private final CountDownLatch handlerInitLatch;\n\n  DecodeThread(CaptureActivity activity,\n               Collection<BarcodeFormat> decodeFormats,\n               String characterSet,\n               ResultPointCallback resultPointCallback) {\n\n    this.activity = activity;\n    handlerInitLatch = new CountDownLatch(1);\n\n    hints = new EnumMap<DecodeHintType,Object>(DecodeHintType.class);\n\n    // The prefs can't change while the thread is running, so pick them up once here.\n    if (decodeFormats == null || decodeFormats.isEmpty()) {\n      SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);\n      decodeFormats = EnumSet.noneOf(BarcodeFormat.class);\n      if (prefs.getBoolean(PreferencesActivity.KEY_DECODE_1D, false)) {\n        decodeFormats.addAll(DecodeFormatManager.ONE_D_FORMATS);\n      }\n      if (prefs.getBoolean(PreferencesActivity.KEY_DECODE_QR, false)) {\n        decodeFormats.addAll(DecodeFormatManager.QR_CODE_FORMATS);\n      }\n      if (prefs.getBoolean(PreferencesActivity.KEY_DECODE_DATA_MATRIX, false)) {\n        decodeFormats.addAll(DecodeFormatManager.DATA_MATRIX_FORMATS);\n      }\n    }\n    hints.put(DecodeHintType.POSSIBLE_FORMATS, decodeFormats);\n\n    if (characterSet != null) {\n      hints.put(DecodeHintType.CHARACTER_SET, characterSet);\n    }\n    hints.put(DecodeHintType.NEED_RESULT_POINT_CALLBACK, resultPointCallback);\n  }\n\n  Handler getHandler() {\n    try {\n      handlerInitLatch.await();\n    } catch (InterruptedException ie) {\n      // continue?\n    }\n    return handler;\n  }\n\n  @Override\n  public void run() {\n    Looper.prepare();\n    handler = new DecodeHandler(activity, hints);\n    handlerInitLatch.countDown();\n    Looper.loop();\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/FinishListener.java",
    "content": "/*\n * Copyright (C) 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android;\n\nimport android.app.Activity;\nimport android.content.DialogInterface;\n\n/**\n * Simple listener used to exit the app in a few cases.\n *\n * @author Sean Owen\n */\npublic final class FinishListener implements DialogInterface.OnClickListener, DialogInterface.OnCancelListener {\n\n  private final Activity activityToFinish;\n\n  public FinishListener(Activity activityToFinish) {\n    this.activityToFinish = activityToFinish;\n  }\n\n  @Override\n  public void onCancel(DialogInterface dialogInterface) {\n    run();\n  }\n\n  @Override\n  public void onClick(DialogInterface dialogInterface, int i) {\n    run();\n  }\n\n  private void run() {\n    activityToFinish.finish();\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/HelpActivity.java",
    "content": "/*\n * Copyright 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android;\n\nimport android.app.Activity;\nimport android.content.Intent;\nimport android.net.Uri;\nimport android.os.Bundle;\nimport android.view.View;\nimport android.view.KeyEvent;\nimport android.webkit.WebView;\nimport android.webkit.WebViewClient;\nimport android.widget.Button;\nimport com.google.zxing.FakeR;\n\n/**\n * An HTML-based help screen with Back and Done buttons at the bottom.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n */\npublic final class HelpActivity extends Activity {\n\n  // Use this key and one of the values below when launching this activity via intent. If not\n  // present, the default page will be loaded.\n  public static final String REQUESTED_PAGE_KEY = \"requested_page_key\";\n  public static final String DEFAULT_PAGE = \"index.html\";\n  public static final String WHATS_NEW_PAGE = \"whatsnew.html\";\n\n  private static final String BASE_URL =\n      \"file:///android_asset/html-\" + LocaleManager.getTranslatedAssetLanguage() + '/';\n  private static final String WEBVIEW_STATE_PRESENT = \"webview_state_present\";\n\n  private WebView webView;\n  private Button backButton;\n\n  private static FakeR fakeR;\n\n  private final Button.OnClickListener backListener = new Button.OnClickListener() {\n    @Override\n    public void onClick(View view) {\n      webView.goBack();\n    }\n  };\n\n  private final Button.OnClickListener doneListener = new Button.OnClickListener() {\n    @Override\n    public void onClick(View view) {\n      finish();\n    }\n  };\n\n  @Override\n  protected void onCreate(Bundle icicle) {\n    super.onCreate(icicle);\n\n\tfakeR = new FakeR(this);\n\n    setContentView(fakeR.getId(\"layout\", \"help\"));\n\n    webView = (WebView)findViewById(fakeR.getId(\"id\", \"help_contents\"));\n    webView.setWebViewClient(new HelpClient());\n\n    // Froyo has a bug with calling onCreate() twice in a row, which causes the What's New page\n    // that's auto-loaded on first run to appear blank. As a workaround we only call restoreState()\n    // if a valid URL was loaded at the time the previous activity was torn down.\n    Intent intent = getIntent();\n    if (icicle != null && icicle.getBoolean(WEBVIEW_STATE_PRESENT, false)) {\n      webView.restoreState(icicle);\n    } else if (intent != null) {\n      String page = intent.getStringExtra(REQUESTED_PAGE_KEY);\n      if (page != null && page.length() > 0) {\n        webView.loadUrl(BASE_URL + page);\n      } else {\n        webView.loadUrl(BASE_URL + DEFAULT_PAGE);\n      }\n    } else {\n      webView.loadUrl(BASE_URL + DEFAULT_PAGE);\n    }\n\n    backButton = (Button) findViewById(fakeR.getId(\"id\", \"back_button\"));\n    backButton.setOnClickListener(backListener);\n    View doneButton = findViewById(fakeR.getId(\"id\", \"done_button\"));\n    doneButton.setOnClickListener(doneListener);\n  }\n\n  @Override\n  protected void onSaveInstanceState(Bundle state) {\n    String url = webView.getUrl();\n    if (url != null && url.length() > 0) {\n      webView.saveState(state);\n      state.putBoolean(WEBVIEW_STATE_PRESENT, true);\n    }\n  }\n\n  @Override\n  public boolean onKeyDown(int keyCode, KeyEvent event) {\n    if (keyCode == KeyEvent.KEYCODE_BACK) {\n      if (webView.canGoBack()) {\n        webView.goBack();\n        return true;\n      }\n    }\n    return super.onKeyDown(keyCode, event);\n  }\n\n  private final class HelpClient extends WebViewClient {\n    @Override\n    public void onPageFinished(WebView view, String url) {\n      setTitle(view.getTitle());\n      backButton.setEnabled(view.canGoBack());\n    }\n\n    @Override\n    public boolean shouldOverrideUrlLoading(WebView view, String url) {\n      if (url.startsWith(\"file\")) {\n        // Keep local assets in this WebView.\n        return false;\n      } else {\n        // Open external URLs in Browser.\n        startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));\n        return true;\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/HttpHelper.java",
    "content": "/*\n * Copyright 2011 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android;\n\nimport android.util.Log;\n\nimport java.io.IOException;\nimport java.io.InputStreamReader;\nimport java.io.Reader;\nimport java.net.HttpURLConnection;\nimport java.net.URI;\nimport java.net.URISyntaxException;\nimport java.net.URL;\nimport java.net.URLConnection;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.HashSet;\n\n/**\n * Utility methods for retrieving content over HTTP using the more-supported {@code java.net} classes\n * in Android.\n */\npublic final class HttpHelper {\n\n  private static final String TAG = HttpHelper.class.getSimpleName();\n\n  private static final Collection<String> REDIRECTOR_DOMAINS = new HashSet<String>(Arrays.asList(\n    \"amzn.to\", \"bit.ly\", \"bitly.com\", \"fb.me\", \"goo.gl\", \"is.gd\", \"j.mp\", \"lnkd.in\", \"ow.ly\",\n    \"R.BEETAGG.COM\", \"r.beetagg.com\", \"SCN.BY\", \"su.pr\", \"t.co\", \"tinyurl.com\", \"tr.im\"\n  ));\n\n  private HttpHelper() {\n  }\n  \n  public enum ContentType {\n    /** HTML-like content type, including HTML, XHTML, etc. */\n    HTML,\n    /** JSON content */\n    JSON,\n    /** Plain text content */\n    TEXT,\n  }\n\n  /**\n   * Downloads the entire resource instead of part.\n   *\n   * @see #downloadViaHttp(String, HttpHelper.ContentType, int)\n   */\n  public static CharSequence downloadViaHttp(String uri, ContentType type) throws IOException {\n    return downloadViaHttp(uri, type, Integer.MAX_VALUE);\n  }\n\n  /**\n   * @param uri URI to retrieve\n   * @param type expected text-like MIME type of that content\n   * @param maxChars approximate maximum characters to read from the source\n   * @return content as a {@code String}\n   * @throws IOException if the content can't be retrieved because of a bad URI, network problem, etc.\n   */\n  public static CharSequence downloadViaHttp(String uri, ContentType type, int maxChars) throws IOException {\n    String contentTypes;\n    switch (type) {\n      case HTML:\n        contentTypes = \"application/xhtml+xml,text/html,text/*,*/*\";\n        break;\n      case JSON:\n        contentTypes = \"application/json,text/*,*/*\";\n        break;\n      case TEXT:\n      default:\n        contentTypes = \"text/*,*/*\";\n    }\n    return downloadViaHttp(uri, contentTypes, maxChars);\n  }\n\n  private static CharSequence downloadViaHttp(String uri, String contentTypes, int maxChars) throws IOException {\n    Log.i(TAG, \"Downloading \" + uri);\n    URL url = new URL(uri);\n    URLConnection conn = url.openConnection();\n    if (!(conn instanceof HttpURLConnection)) {\n      throw new IOException();\n    }\n    HttpURLConnection connection = (HttpURLConnection) conn;\n    connection.setRequestProperty(\"Accept\", contentTypes);\n    connection.setRequestProperty(\"Accept-Charset\", \"utf-8,*\");\n    connection.setRequestProperty(\"User-Agent\", \"ZXing (Android)\");\n    try {\n      try {\n        connection.connect();\n      } catch (NullPointerException npe) {\n        // this is an Android bug: http://code.google.com/p/android/issues/detail?id=16895\n        Log.w(TAG, \"Bad URI? \" + uri);\n        throw new IOException(npe);\n      } catch (IllegalArgumentException iae) {\n        // Also seen this in the wild, not sure what to make of it. Probably a bad URL\n        Log.w(TAG, \"Bad URI? \" + uri);\n        throw new IOException(iae);\n      }\n      int responseCode;\n      try {\n        responseCode = connection.getResponseCode();\n      } catch (NullPointerException npe) {\n        // this is maybe this Android bug: http://code.google.com/p/android/issues/detail?id=15554\n        Log.w(TAG, \"Bad URI? \" + uri);\n        throw new IOException(npe);\n      }\n      if (responseCode != HttpURLConnection.HTTP_OK) {\n        throw new IOException(\"Bad HTTP response: \" + responseCode);\n      }\n      Log.i(TAG, \"Consuming \" + uri);\n      return consume(connection, maxChars);\n    } finally {\n      connection.disconnect();\n    }\n  }\n\n  private static String getEncoding(URLConnection connection) {\n    String contentTypeHeader = connection.getHeaderField(\"Content-Type\");\n    if (contentTypeHeader != null) {\n      int charsetStart = contentTypeHeader.indexOf(\"charset=\");\n      if (charsetStart >= 0) {\n        return contentTypeHeader.substring(charsetStart + \"charset=\".length());\n      }\n    }\n    return \"UTF-8\";\n  }\n\n  private static CharSequence consume(URLConnection connection, int maxChars) throws IOException {\n    String encoding = getEncoding(connection);\n    StringBuilder out = new StringBuilder();\n    Reader in = null;\n    try {\n      in = new InputStreamReader(connection.getInputStream(), encoding);\n      char[] buffer = new char[1024];\n      int charsRead;\n      while (out.length() < maxChars && (charsRead = in.read(buffer)) > 0) {\n        out.append(buffer, 0, charsRead);\n      }\n    } finally {\n      if (in != null) {\n        try {\n          in.close();\n        } catch (IOException ioe) {\n          // continue\n        } catch (NullPointerException npe) {\n          // another apparent Android / Harmony bug; continue\n        }\n      }\n    }\n    return out;\n  }\n\n  public static URI unredirect(URI uri) throws IOException {\n    if (!REDIRECTOR_DOMAINS.contains(uri.getHost())) {\n      return uri;\n    }\n    URL url = uri.toURL();\n\n    URLConnection conn = url.openConnection();\n    if (!(conn instanceof HttpURLConnection)) {\n      throw new IOException();\n    }\n    HttpURLConnection connection = (HttpURLConnection) conn;\n    connection.setInstanceFollowRedirects(false);\n    connection.setDoInput(false);\n    connection.setRequestMethod(\"HEAD\");\n    connection.setRequestProperty(\"User-Agent\", \"ZXing (Android)\");\n    try {\n      try {\n        connection.connect();\n      } catch (NullPointerException npe) {\n        // this is an Android bug: http://code.google.com/p/android/issues/detail?id=16895\n        Log.w(TAG, \"Bad URI? \" + uri);\n        throw new IOException(npe);\n      } catch (IllegalArgumentException iae) {\n        // Also seen this in the wild, not sure what to make of it. Probably a bad URL\n        Log.w(TAG, \"Bad URI? \" + uri);\n        throw new IOException(iae);\n      }\n      int responseCode;\n      try {\n        responseCode = connection.getResponseCode();\n      } catch (NullPointerException npe) {\n        // this is maybe this Android bug: http://code.google.com/p/android/issues/detail?id=15554\n        Log.w(TAG, \"Bad URI? \" + uri);\n        throw new IOException(npe);\n      }\n      switch (responseCode) {\n        case HttpURLConnection.HTTP_MULT_CHOICE:\n        case HttpURLConnection.HTTP_MOVED_PERM:\n        case HttpURLConnection.HTTP_MOVED_TEMP:\n        case HttpURLConnection.HTTP_SEE_OTHER:\n        case 307: // No constant for 307 Temporary Redirect ?\n          String location = connection.getHeaderField(\"Location\");\n          if (location != null) {\n            try {\n              return new URI(location);\n            } catch (URISyntaxException e) {\n              // nevermind\n            }\n          }\n      }\n      return uri;\n    } finally {\n      connection.disconnect();\n    }\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/InactivityTimer.java",
    "content": "/*\n * Copyright (C) 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android;\n\nimport android.app.Activity;\nimport android.content.BroadcastReceiver;\nimport android.content.Context;\nimport android.content.Intent;\nimport android.content.IntentFilter;\nimport android.os.AsyncTask;\nimport android.os.BatteryManager;\nimport android.util.Log;\n\nimport com.google.zxing.client.android.common.executor.AsyncTaskExecInterface;\nimport com.google.zxing.client.android.common.executor.AsyncTaskExecManager;\n\n/**\n * Finishes an activity after a period of inactivity if the device is on battery power.\n */\nfinal class InactivityTimer {\n\n  private static final String TAG = InactivityTimer.class.getSimpleName();\n\n  private static final long INACTIVITY_DELAY_MS = 5 * 60 * 1000L;\n\n  private final Activity activity;\n  private final AsyncTaskExecInterface taskExec;\n  private final BroadcastReceiver powerStatusReceiver;\n  private InactivityAsyncTask inactivityTask;\n\n  InactivityTimer(Activity activity) {\n    this.activity = activity;\n    taskExec = new AsyncTaskExecManager().build();\n    powerStatusReceiver = new PowerStatusReceiver();\n    onActivity();\n  }\n\n  synchronized void onActivity() {\n    cancel();\n    inactivityTask = new InactivityAsyncTask();\n    taskExec.execute(inactivityTask);\n  }\n\n  public void onPause() {\n    cancel();\n    activity.unregisterReceiver(powerStatusReceiver);\n  }\n\n  public void onResume(){\n    activity.registerReceiver(powerStatusReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));\n    onActivity();\n  }\n\n  private synchronized  void cancel() {\n    AsyncTask<?,?,?> task = inactivityTask;\n    if (task != null) {\n      task.cancel(true);\n      inactivityTask = null;\n    }\n  }\n\n  void shutdown() {\n    cancel();\n  }\n\n  private final class PowerStatusReceiver extends BroadcastReceiver {\n    @Override\n    public void onReceive(Context context, Intent intent){\n      if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {\n        // 0 indicates that we're on battery\n        boolean onBatteryNow = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) <= 0;\n        if (onBatteryNow) {\n          InactivityTimer.this.onActivity();\n        } else {\n          InactivityTimer.this.cancel();\n        }\n      }\n    }\n  }\n\n  private final class InactivityAsyncTask extends AsyncTask<Object,Object,Object> {\n    @Override\n    protected Object doInBackground(Object... objects) {\n      try {\n        Thread.sleep(INACTIVITY_DELAY_MS);\n        Log.i(TAG, \"Finishing activity due to inactivity\");\n        activity.finish();\n      } catch (InterruptedException e) {\n        // continue without killing\n      }\n      return null;\n    }\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/IntentSource.java",
    "content": "/*\n * Copyright (C) 2011 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android;\n\nenum IntentSource {\n\n  NATIVE_APP_INTENT,\n  PRODUCT_SEARCH_LINK,\n  ZXING_LINK,\n  NONE\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/Intents.java",
    "content": "/*\n * Copyright (C) 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android;\n\n/**\n * This class provides the constants to use when sending an Intent to Barcode Scanner.\n * These strings are effectively API and cannot be changed.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n */\npublic final class Intents {\n  private Intents() {\n  }\n\n  public static final class Scan {\n    /**\n     * Send this intent to open the Barcodes app in scanning mode, find a barcode, and return\n     * the results.\n     */\n    public static final String ACTION = \"com.google.zxing.client.android.SCAN\";\n\n    /**\n     * By default, sending this will decode all barcodes that we understand. However it\n     * may be useful to limit scanning to certain formats. Use\n     * {@link android.content.Intent#putExtra(String, String)} with one of the values below.\n     *\n     * Setting this is effectively shorthand for setting explicit formats with {@link #FORMATS}.\n     * It is overridden by that setting.\n     */\n    public static final String MODE = \"SCAN_MODE\";\n\n    /**\n     * Decode only UPC and EAN barcodes. This is the right choice for shopping apps which get\n     * prices, reviews, etc. for products.\n     */\n    public static final String PRODUCT_MODE = \"PRODUCT_MODE\";\n\n    /**\n     * Decode only 1D barcodes.\n     */\n    public static final String ONE_D_MODE = \"ONE_D_MODE\";\n\n    /**\n     * Decode only QR codes.\n     */\n    public static final String QR_CODE_MODE = \"QR_CODE_MODE\";\n\n    /**\n     * Decode only Data Matrix codes.\n     */\n    public static final String DATA_MATRIX_MODE = \"DATA_MATRIX_MODE\";\n\n    /**\n     * Comma-separated list of formats to scan for. The values must match the names of\n     * {@link com.google.zxing.BarcodeFormat}s, e.g. {@link com.google.zxing.BarcodeFormat#EAN_13}.\n     * Example: \"EAN_13,EAN_8,QR_CODE\". This overrides {@link #MODE}.\n     */\n    public static final String FORMATS = \"SCAN_FORMATS\";\n\n    /**\n     * @see com.google.zxing.DecodeHintType#CHARACTER_SET\n     */\n    public static final String CHARACTER_SET = \"CHARACTER_SET\";\n\n    /**\n     * Optional parameters to specify the width and height of the scanning rectangle in pixels.\n     * The app will try to honor these, but will clamp them to the size of the preview frame.\n     * You should specify both or neither, and pass the size as an int.\n     */\n    public static final String WIDTH = \"SCAN_WIDTH\";\n    public static final String HEIGHT = \"SCAN_HEIGHT\";\n\n    /**\n     * Desired duration in milliseconds for which to pause after a successful scan before\n     * returning to the calling intent. Specified as a long, not an integer!\n     * For example: 1000L, not 1000.\n     */\n    public static final String RESULT_DISPLAY_DURATION_MS = \"RESULT_DISPLAY_DURATION_MS\";\n\n    /**\n     * Prompt to show on-screen when scanning by intent. Specified as a {@link String}.\n     */\n    public static final String PROMPT_MESSAGE = \"PROMPT_MESSAGE\";\n\n    /**\n     * If a barcode is found, Barcodes returns {@link android.app.Activity#RESULT_OK} to\n     * {@link android.app.Activity#onActivityResult(int, int, android.content.Intent)}\n     * of the app which requested the scan via\n     * {@link android.app.Activity#startActivityForResult(android.content.Intent, int)}\n     * The barcodes contents can be retrieved with\n     * {@link android.content.Intent#getStringExtra(String)}. \n     * If the user presses Back, the result code will be {@link android.app.Activity#RESULT_CANCELED}.\n     */\n    public static final String RESULT = \"SCAN_RESULT\";\n\n    /**\n     * Call {@link android.content.Intent#getStringExtra(String)} with {@link #RESULT_FORMAT}\n     * to determine which barcode format was found.\n     * See {@link com.google.zxing.BarcodeFormat} for possible values.\n     */\n    public static final String RESULT_FORMAT = \"SCAN_RESULT_FORMAT\";\n\n    /**\n     * Call {@link android.content.Intent#getStringExtra(String)} with {@link #RESULT_UPC_EAN_EXTENSION}\n     * to return the content of any UPC extension barcode that was also found. Only applicable\n     * to {@link com.google.zxing.BarcodeFormat#UPC_A} and {@link com.google.zxing.BarcodeFormat#EAN_13}\n     * formats.\n     */\n    public static final String RESULT_UPC_EAN_EXTENSION = \"SCAN_RESULT_UPC_EAN_EXTENSION\";\n\n    /**\n     * Call {@link android.content.Intent#getByteArrayExtra(String)} with {@link #RESULT_BYTES}\n     * to get a {@code byte[]} of raw bytes in the barcode, if available.\n     */\n    public static final String RESULT_BYTES = \"SCAN_RESULT_BYTES\";\n\n    /**\n     * Key for the value of {@link com.google.zxing.ResultMetadataType#ORIENTATION}, if available.\n     * Call {@link android.content.Intent#getIntArrayExtra(String)} with {@link #RESULT_ORIENTATION}.\n     */\n    public static final String RESULT_ORIENTATION = \"SCAN_RESULT_ORIENTATION\";\n\n    /**\n     * Key for the value of {@link com.google.zxing.ResultMetadataType#ERROR_CORRECTION_LEVEL}, if available.\n     * Call {@link android.content.Intent#getStringExtra(String)} with {@link #RESULT_ERROR_CORRECTION_LEVEL}.\n     */\n    public static final String RESULT_ERROR_CORRECTION_LEVEL = \"SCAN_RESULT_ERROR_CORRECTION_LEVEL\";\n\n    /**\n     * Prefix for keys that map to the values of {@link com.google.zxing.ResultMetadataType#BYTE_SEGMENTS},\n     * if available. The actual values will be set under a series of keys formed by adding 0, 1, 2, ...\n     * to this prefix. So the first byte segment is under key \"SCAN_RESULT_BYTE_SEGMENTS_0\" for example.\n     * Call {@link android.content.Intent#getByteArrayExtra(String)} with these keys.\n     */\n    public static final String RESULT_BYTE_SEGMENTS_PREFIX = \"SCAN_RESULT_BYTE_SEGMENTS_\";\n\n    /**\n     * Setting this to false will not save scanned codes in the history. Specified as a {@code boolean}.\n     */\n    public static final String SAVE_HISTORY = \"SAVE_HISTORY\";\n\n    private Scan() {\n    }\n  }\n\n  public static final class History {\n\n    public static final String ITEM_NUMBER = \"ITEM_NUMBER\";\n\n    private History() {\n    }\n  }\n\n  public static final class Encode {\n    /**\n     * Send this intent to encode a piece of data as a QR code and display it full screen, so\n     * that another person can scan the barcode from your screen.\n     */\n    public static final String ACTION = \"com.google.zxing.client.android.ENCODE\";\n\n    /**\n     * The data to encode. Use {@link android.content.Intent#putExtra(String, String)} or\n     * {@link android.content.Intent#putExtra(String, android.os.Bundle)}, \n     * depending on the type and format specified. Non-QR Code formats should\n     * just use a String here. For QR Code, see Contents for details.\n     */\n    public static final String DATA = \"ENCODE_DATA\";\n\n    /**\n     * The type of data being supplied if the format is QR Code. Use\n     * {@link android.content.Intent#putExtra(String, String)} with one of {@link Contents.Type}.\n     */\n    public static final String TYPE = \"ENCODE_TYPE\";\n\n    /**\n     * The barcode format to be displayed. If this isn't specified or is blank,\n     * it defaults to QR Code. Use {@link android.content.Intent#putExtra(String, String)}, where\n     * format is one of {@link com.google.zxing.BarcodeFormat}.\n     */\n    public static final String FORMAT = \"ENCODE_FORMAT\";\n\n    /**\n     * Normally the contents of the barcode are displayed to the user in a TextView. Setting this\n     * boolean to false will hide that TextView, showing only the encode barcode.\n     */\n    public static final String SHOW_CONTENTS = \"ENCODE_SHOW_CONTENTS\";\n\n    private Encode() {\n    }\n  }\n\n  public static final class SearchBookContents {\n    /**\n     * Use Google Book Search to search the contents of the book provided.\n     */\n    public static final String ACTION = \"com.google.zxing.client.android.SEARCH_BOOK_CONTENTS\";\n\n    /**\n     * The book to search, identified by ISBN number.\n     */\n    public static final String ISBN = \"ISBN\";\n\n    /**\n     * An optional field which is the text to search for.\n     */\n    public static final String QUERY = \"QUERY\";\n\n    private SearchBookContents() {\n    }\n  }\n\n  public static final class WifiConnect {\n    /**\n     * Internal intent used to trigger connection to a wi-fi network.\n     */\n    public static final String ACTION = \"com.google.zxing.client.android.WIFI_CONNECT\";\n\n    /**\n     * The network to connect to, all the configuration provided here.\n     */\n    public static final String SSID = \"SSID\";\n\n    /**\n     * The network to connect to, all the configuration provided here.\n     */\n    public static final String TYPE = \"TYPE\";\n\n    /**\n     * The network to connect to, all the configuration provided here.\n     */\n    public static final String PASSWORD = \"PASSWORD\";\n\n    private WifiConnect() {\n    }\n  }\n\n  public static final class Share {\n    /**\n     * Give the user a choice of items to encode as a barcode, then render it as a QR Code and\n     * display onscreen for a friend to scan with their phone.\n     */\n    public static final String ACTION = \"com.google.zxing.client.android.SHARE\";\n\n    private Share() {\n    }\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/LocaleManager.java",
    "content": "/*\n * Copyright (C) 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android;\n\nimport android.content.Context;\nimport android.content.SharedPreferences;\nimport android.preference.PreferenceManager;\n\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.Locale;\nimport java.util.Map;\nimport java.util.HashMap;\n\n/**\n * Handles any locale-specific logic for the client.\n *\n * @author Sean Owen\n */\npublic final class LocaleManager {\n\n  private static final String DEFAULT_TLD = \"com\";\n  private static final String DEFAULT_COUNTRY = \"US\";\n  private static final String DEFAULT_LANGUAGE = \"en\";\n\n  /**\n   * Locales (well, countries) where Google web search is available.\n   * These should be kept in sync with our translations.\n   */\n  private static final Map<String,String> GOOGLE_COUNTRY_TLD;\n  static {\n    GOOGLE_COUNTRY_TLD = new HashMap<String,String>();\n    GOOGLE_COUNTRY_TLD.put(\"AR\", \"com.ar\"); // ARGENTINA\n    GOOGLE_COUNTRY_TLD.put(\"AU\", \"com.au\"); // AUSTRALIA\n    GOOGLE_COUNTRY_TLD.put(\"BR\", \"com.br\"); // BRAZIL\n    GOOGLE_COUNTRY_TLD.put(\"BG\", \"bg\"); // BULGARIA\n    GOOGLE_COUNTRY_TLD.put(Locale.CANADA.getCountry(), \"ca\");\n    GOOGLE_COUNTRY_TLD.put(Locale.CHINA.getCountry(), \"cn\");\n    GOOGLE_COUNTRY_TLD.put(\"CZ\", \"cz\"); // CZECH REPUBLIC\n    GOOGLE_COUNTRY_TLD.put(\"DK\", \"dk\"); // DENMARK\n    GOOGLE_COUNTRY_TLD.put(\"FI\", \"fi\"); // FINLAND\n    GOOGLE_COUNTRY_TLD.put(Locale.FRANCE.getCountry(), \"fr\");\n    GOOGLE_COUNTRY_TLD.put(Locale.GERMANY.getCountry(), \"de\");\n    GOOGLE_COUNTRY_TLD.put(\"GR\", \"gr\"); // GREECE\n    GOOGLE_COUNTRY_TLD.put(\"HU\", \"hu\"); // HUNGARY\n    GOOGLE_COUNTRY_TLD.put(\"ID\", \"co.id\"); // INDONESIA\n    GOOGLE_COUNTRY_TLD.put(\"IL\", \"co.il\"); // ISRAEL\n    GOOGLE_COUNTRY_TLD.put(Locale.ITALY.getCountry(), \"it\");\n    GOOGLE_COUNTRY_TLD.put(Locale.JAPAN.getCountry(), \"co.jp\");\n    GOOGLE_COUNTRY_TLD.put(Locale.KOREA.getCountry(), \"co.kr\");\n    GOOGLE_COUNTRY_TLD.put(\"NL\", \"nl\"); // NETHERLANDS\n    GOOGLE_COUNTRY_TLD.put(\"PL\", \"pl\"); // POLAND\n    GOOGLE_COUNTRY_TLD.put(\"PT\", \"pt\"); // PORTUGAL\n    GOOGLE_COUNTRY_TLD.put(\"RU\", \"ru\"); // RUSSIA\n    GOOGLE_COUNTRY_TLD.put(\"SK\", \"sk\"); // SLOVAK REPUBLIC\n    GOOGLE_COUNTRY_TLD.put(\"SI\", \"si\"); // SLOVENIA\n    GOOGLE_COUNTRY_TLD.put(\"ES\", \"es\"); // SPAIN\n    GOOGLE_COUNTRY_TLD.put(\"SE\", \"se\"); // SWEDEN\n    GOOGLE_COUNTRY_TLD.put(Locale.TAIWAN.getCountry(), \"tw\");\n    GOOGLE_COUNTRY_TLD.put(\"TR\", \"com.tr\"); // TURKEY\n    GOOGLE_COUNTRY_TLD.put(Locale.UK.getCountry(), \"co.uk\");\n    GOOGLE_COUNTRY_TLD.put(Locale.US.getCountry(), \"com\");\n  }\n\n  /**\n   * Google Product Search for mobile is available in fewer countries than web search. See here:\n   * http://www.google.com/support/merchants/bin/answer.py?answer=160619\n   */\n  private static final Map<String,String> GOOGLE_PRODUCT_SEARCH_COUNTRY_TLD;\n  static {\n    GOOGLE_PRODUCT_SEARCH_COUNTRY_TLD = new HashMap<String,String>();\n    GOOGLE_PRODUCT_SEARCH_COUNTRY_TLD.put(\"AU\", \"com.au\"); // AUSTRALIA\n    GOOGLE_PRODUCT_SEARCH_COUNTRY_TLD.put(Locale.CHINA.getCountry(), \"cn\");\n    GOOGLE_PRODUCT_SEARCH_COUNTRY_TLD.put(Locale.FRANCE.getCountry(), \"fr\");\n    GOOGLE_PRODUCT_SEARCH_COUNTRY_TLD.put(Locale.GERMANY.getCountry(), \"de\");\n    GOOGLE_PRODUCT_SEARCH_COUNTRY_TLD.put(Locale.ITALY.getCountry(), \"it\");\n    GOOGLE_PRODUCT_SEARCH_COUNTRY_TLD.put(Locale.JAPAN.getCountry(), \"co.jp\");\n    GOOGLE_PRODUCT_SEARCH_COUNTRY_TLD.put(\"NL\", \"nl\"); // NETHERLANDS\n    GOOGLE_PRODUCT_SEARCH_COUNTRY_TLD.put(\"ES\", \"es\"); // SPAIN\n    GOOGLE_PRODUCT_SEARCH_COUNTRY_TLD.put(Locale.UK.getCountry(), \"co.uk\");\n    GOOGLE_PRODUCT_SEARCH_COUNTRY_TLD.put(Locale.US.getCountry(), \"com\");\n  }\n\n  /**\n   * Book search is offered everywhere that web search is available.\n   */\n  private static final Map<String,String> GOOGLE_BOOK_SEARCH_COUNTRY_TLD = GOOGLE_COUNTRY_TLD;\n\n  private static final Collection<String> TRANSLATED_HELP_ASSET_LANGUAGES =\n      Arrays.asList(\"de\", \"en\", \"es\", \"fr\", \"it\", \"ja\", \"ko\", \"nl\", \"pt\", \"ru\", \"zh-rCN\", \"zh-rTW\");\n\n  private LocaleManager() {}\n\n  /**\n   * @return country-specific TLD suffix appropriate for the current default locale\n   *  (e.g. \"co.uk\" for the United Kingdom)\n   */\n  public static String getCountryTLD(Context context) {\n    return doGetTLD(GOOGLE_COUNTRY_TLD, context);\n  }\n\n  /**\n   * The same as above, but specifically for Google Product Search.\n   * @return The top-level domain to use.\n   */\n  public static String getProductSearchCountryTLD(Context context) {\n    return doGetTLD(GOOGLE_PRODUCT_SEARCH_COUNTRY_TLD, context);\n  }\n\n  /**\n   * The same as above, but specifically for Google Book Search.\n   * @return The top-level domain to use.\n   */\n  public static String getBookSearchCountryTLD(Context context) {\n    return doGetTLD(GOOGLE_BOOK_SEARCH_COUNTRY_TLD, context);\n  }\n\n  /**\n   * Does a given URL point to Google Book Search, regardless of domain.\n   *\n   * @param url The address to check.\n   * @return True if this is a Book Search URL.\n   */\n  public static boolean isBookSearchUrl(String url) {\n    return url.startsWith(\"http://google.com/books\") || url.startsWith(\"http://books.google.\");\n  }\n\n  private static String getSystemCountry() {\n    Locale locale = Locale.getDefault();\n    return locale == null ? DEFAULT_COUNTRY : locale.getCountry();\n  }\n\n  private static String getSystemLanguage() {\n    Locale locale = Locale.getDefault();\n    if (locale == null) {\n      return DEFAULT_LANGUAGE;\n    }\n    String language = locale.getLanguage();\n    // Special case Chinese\n    if (Locale.SIMPLIFIED_CHINESE.getLanguage().equals(language)) {\n      return language + \"-r\" + getSystemCountry();\n    }\n    return language;\n  }\n\n  public static String getTranslatedAssetLanguage() {\n    String language = getSystemLanguage();\n    return TRANSLATED_HELP_ASSET_LANGUAGES.contains(language) ? language : DEFAULT_LANGUAGE;\n  }\n\n  private static String doGetTLD(Map<String,String> map, Context context) {\n    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);\n    String countryOverride = prefs.getString(PreferencesActivity.KEY_SEARCH_COUNTRY, null);\n    if (countryOverride != null && countryOverride.length() > 0 && !\"-\".equals(countryOverride)) {\n      String tld = map.get(countryOverride);\n      if (tld != null) {\n        return tld;\n      }\n    }\n    String tld = map.get(getSystemCountry());\n    return tld == null ? DEFAULT_TLD : tld;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/PreferencesActivity.java",
    "content": "/*\n * Copyright (C) 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android;\n\nimport android.content.SharedPreferences;\nimport android.content.SharedPreferences.OnSharedPreferenceChangeListener;\nimport android.os.Bundle;\nimport android.preference.CheckBoxPreference;\nimport android.preference.PreferenceActivity;\nimport android.preference.PreferenceScreen;\nimport com.google.zxing.FakeR;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\n\n/**\n * The main settings activity.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n */\npublic final class PreferencesActivity extends PreferenceActivity\n    implements OnSharedPreferenceChangeListener {\n\n  public static final String KEY_DECODE_1D = \"preferences_decode_1D\";\n  public static final String KEY_DECODE_QR = \"preferences_decode_QR\";\n  public static final String KEY_DECODE_DATA_MATRIX = \"preferences_decode_Data_Matrix\";\n  public static final String KEY_CUSTOM_PRODUCT_SEARCH = \"preferences_custom_product_search\";\n\n  public static final String KEY_PLAY_BEEP = \"preferences_play_beep\";\n  public static final String KEY_VIBRATE = \"preferences_vibrate\";\n  public static final String KEY_COPY_TO_CLIPBOARD = \"preferences_copy_to_clipboard\";\n  public static final String KEY_FRONT_LIGHT = \"preferences_front_light\";\n  public static final String KEY_BULK_MODE = \"preferences_bulk_mode\";\n  public static final String KEY_REMEMBER_DUPLICATES = \"preferences_remember_duplicates\";\n  public static final String KEY_SUPPLEMENTAL = \"preferences_supplemental\";\n  public static final String KEY_AUTO_FOCUS = \"preferences_auto_focus\";\n  public static final String KEY_SEARCH_COUNTRY = \"preferences_search_country\";\n\n  public static final String KEY_DISABLE_CONTINUOUS_FOCUS = \"preferences_disable_continuous_focus\";\n  //public static final String KEY_DISABLE_EXPOSURE = \"preferences_disable_exposure\";\n\n  public static final String KEY_HELP_VERSION_SHOWN = \"preferences_help_version_shown\";\n\n  private CheckBoxPreference decode1D;\n  private CheckBoxPreference decodeQR;\n  private CheckBoxPreference decodeDataMatrix;\n\n  private static FakeR fakeR;\n\n  @Override\n  protected void onCreate(Bundle icicle) {\n    super.onCreate(icicle);\n\tfakeR = new FakeR(this);\n    addPreferencesFromResource(fakeR.getId(\"xml\", \"preferences\"));\n\n    PreferenceScreen preferences = getPreferenceScreen();\n    preferences.getSharedPreferences().registerOnSharedPreferenceChangeListener(this);\n    decode1D = (CheckBoxPreference) preferences.findPreference(KEY_DECODE_1D);\n    decodeQR = (CheckBoxPreference) preferences.findPreference(KEY_DECODE_QR);\n    decodeDataMatrix = (CheckBoxPreference) preferences.findPreference(KEY_DECODE_DATA_MATRIX);\n    disableLastCheckedPref();\n  }\n\n  @Override\n  public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {\n    disableLastCheckedPref();\n  }\n\n  private void disableLastCheckedPref() {\n    Collection<CheckBoxPreference> checked = new ArrayList<CheckBoxPreference>(3);\n    if (decode1D.isChecked()) {\n      checked.add(decode1D);\n    }\n    if (decodeQR.isChecked()) {\n      checked.add(decodeQR);\n    }\n    if (decodeDataMatrix.isChecked()) {\n      checked.add(decodeDataMatrix);\n    }\n    boolean disable = checked.size() < 2;\n    CheckBoxPreference[] checkBoxPreferences = {decode1D, decodeQR, decodeDataMatrix};\n    for (CheckBoxPreference pref : checkBoxPreferences) {\n      pref.setEnabled(!(disable && checked.contains(pref)));\n    }\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/ViewfinderResultPointCallback.java",
    "content": "/*\n * Copyright (C) 2009 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android;\n\nimport com.google.zxing.ResultPoint;\nimport com.google.zxing.ResultPointCallback;\n\nfinal class ViewfinderResultPointCallback implements ResultPointCallback {\n\n  private final ViewfinderView viewfinderView;\n\n  ViewfinderResultPointCallback(ViewfinderView viewfinderView) {\n    this.viewfinderView = viewfinderView;\n  }\n\n  @Override\n  public void foundPossibleResultPoint(ResultPoint point) {\n    viewfinderView.addPossibleResultPoint(point);\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/ViewfinderView.java",
    "content": "/*\n * Copyright (C) 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android;\n\nimport com.google.zxing.ResultPoint;\nimport com.google.zxing.client.android.camera.CameraManager;\n\nimport android.content.Context;\nimport android.content.res.Resources;\nimport android.graphics.Bitmap;\nimport android.graphics.Canvas;\nimport android.graphics.Paint;\nimport android.graphics.Rect;\nimport android.util.AttributeSet;\nimport android.view.View;\nimport com.google.zxing.FakeR;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * This view is overlaid on top of the camera preview. It adds the viewfinder rectangle and partial\n * transparency outside it, as well as the laser scanner animation and result points.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n */\npublic final class ViewfinderView extends View {\n\n  private static final int[] SCANNER_ALPHA = {0, 64, 128, 192, 255, 192, 128, 64};\n  private static final long ANIMATION_DELAY = 80L;\n  private static final int CURRENT_POINT_OPACITY = 0xA0;\n  private static final int MAX_RESULT_POINTS = 20;\n  private static final int POINT_SIZE = 6;\n\n  private CameraManager cameraManager;\n  private final Paint paint;\n  private Bitmap resultBitmap;\n  private final int maskColor;\n  private final int resultColor;\n  private final int laserColor;\n  private final int resultPointColor;\n  private int scannerAlpha;\n  private List<ResultPoint> possibleResultPoints;\n  private List<ResultPoint> lastPossibleResultPoints;\n\n  private static FakeR fakeR;\n\n  // This constructor is used when the class is built from an XML resource.\n  public ViewfinderView(Context context, AttributeSet attrs) {\n    super(context, attrs);\n\n\tfakeR = new FakeR(context);\n\n    // Initialize these once for performance rather than calling them every time in onDraw().\n    paint = new Paint(Paint.ANTI_ALIAS_FLAG);\n    Resources resources = getResources();\n    maskColor = resources.getColor(fakeR.getId(\"color\", \"viewfinder_mask\"));\n    resultColor = resources.getColor(fakeR.getId(\"color\", \"result_view\"));\n    laserColor = resources.getColor(fakeR.getId(\"color\", \"viewfinder_laser\"));\n    resultPointColor = resources.getColor(fakeR.getId(\"color\", \"possible_result_points\"));\n    scannerAlpha = 0;\n    possibleResultPoints = new ArrayList<ResultPoint>(5);\n    lastPossibleResultPoints = null;\n  }\n\n  public void setCameraManager(CameraManager cameraManager) {\n    this.cameraManager = cameraManager;\n  }\n\n  @Override\n  public void onDraw(Canvas canvas) {\n    if (cameraManager == null) {\n      return; // not ready yet, early draw before done configuring\n    }\n    Rect frame = cameraManager.getFramingRect();\n    if (frame == null) {\n      return;\n    }\n    int width = canvas.getWidth();\n    int height = canvas.getHeight();\n\n    // Draw the exterior (i.e. outside the framing rect) darkened\n    paint.setColor(resultBitmap != null ? resultColor : maskColor);\n    canvas.drawRect(0, 0, width, frame.top, paint);\n    canvas.drawRect(0, frame.top, frame.left, frame.bottom + 1, paint);\n    canvas.drawRect(frame.right + 1, frame.top, width, frame.bottom + 1, paint);\n    canvas.drawRect(0, frame.bottom + 1, width, height, paint);\n\n    if (resultBitmap != null) {\n      // Draw the opaque result bitmap over the scanning rectangle\n      paint.setAlpha(CURRENT_POINT_OPACITY);\n      canvas.drawBitmap(resultBitmap, null, frame, paint);\n    } else {\n\n      // Draw a red \"laser scanner\" line through the middle to show decoding is active\n      paint.setColor(laserColor);\n      paint.setAlpha(SCANNER_ALPHA[scannerAlpha]);\n      scannerAlpha = (scannerAlpha + 1) % SCANNER_ALPHA.length;\n      int middle = frame.height() / 2 + frame.top;\n      canvas.drawRect(frame.left + 2, middle - 1, frame.right - 1, middle + 2, paint);\n      \n      Rect previewFrame = cameraManager.getFramingRectInPreview();\n      float scaleX = frame.width() / (float) previewFrame.width();\n      float scaleY = frame.height() / (float) previewFrame.height();\n\n      List<ResultPoint> currentPossible = possibleResultPoints;\n      List<ResultPoint> currentLast = lastPossibleResultPoints;\n      int frameLeft = frame.left;\n      int frameTop = frame.top;\n      if (currentPossible.isEmpty()) {\n        lastPossibleResultPoints = null;\n      } else {\n        possibleResultPoints = new ArrayList<ResultPoint>(5);\n        lastPossibleResultPoints = currentPossible;\n        paint.setAlpha(CURRENT_POINT_OPACITY);\n        paint.setColor(resultPointColor);\n        synchronized (currentPossible) {\n          for (ResultPoint point : currentPossible) {\n            canvas.drawCircle(frameLeft + (int) (point.getX() * scaleX),\n                              frameTop + (int) (point.getY() * scaleY),\n                              POINT_SIZE, paint);\n          }\n        }\n      }\n      if (currentLast != null) {\n        paint.setAlpha(CURRENT_POINT_OPACITY / 2);\n        paint.setColor(resultPointColor);\n        synchronized (currentLast) {\n          float radius = POINT_SIZE / 2.0f;\n          for (ResultPoint point : currentLast) {\n            canvas.drawCircle(frameLeft + (int) (point.getX() * scaleX),\n                              frameTop + (int) (point.getY() * scaleY),\n                              radius, paint);\n          }\n        }\n      }\n\n      // Request another update at the animation interval, but only repaint the laser line,\n      // not the entire viewfinder mask.\n      postInvalidateDelayed(ANIMATION_DELAY,\n                            frame.left - POINT_SIZE,\n                            frame.top - POINT_SIZE,\n                            frame.right + POINT_SIZE,\n                            frame.bottom + POINT_SIZE);\n    }\n  }\n\n  public void drawViewfinder() {\n    Bitmap resultBitmap = this.resultBitmap;\n    this.resultBitmap = null;\n    if (resultBitmap != null) {\n      resultBitmap.recycle();\n    }\n    invalidate();\n  }\n\n  /**\n   * Draw a bitmap with the result points highlighted instead of the live scanning display.\n   *\n   * @param barcode An image of the decoded barcode.\n   */\n  public void drawResultBitmap(Bitmap barcode) {\n    resultBitmap = barcode;\n    invalidate();\n  }\n\n  public void addPossibleResultPoint(ResultPoint point) {\n    List<ResultPoint> points = possibleResultPoints;\n    synchronized (points) {\n      points.add(point);\n      int size = points.size();\n      if (size > MAX_RESULT_POINTS) {\n        // trim it\n        points.subList(0, size - MAX_RESULT_POINTS / 2).clear();\n      }\n    }\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/book/BrowseBookListener.java",
    "content": "/*\n * Copyright (C) 2009 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.book;\n\nimport android.content.Intent;\nimport android.net.Uri;\nimport android.view.View;\nimport android.widget.AdapterView;\nimport com.google.zxing.client.android.LocaleManager;\n\nimport java.util.List;\n\nfinal class BrowseBookListener implements AdapterView.OnItemClickListener {\n\n  private final SearchBookContentsActivity activity;\n  private final List<SearchBookContentsResult> items;\n\n  BrowseBookListener(SearchBookContentsActivity activity, List<SearchBookContentsResult> items) {\n    this.activity = activity;\n    this.items = items;\n  }\n\n  @Override\n  public void onItemClick(AdapterView<?> parent, View v, int position, long id) {\n    if (position < 1) {\n      // Clicked header, ignore it\n      return;\n    }\n    int itemOffset = position - 1;\n    if (itemOffset >= items.size()) {\n      return;\n    }\n    String pageId = items.get(itemOffset).getPageId();\n    String query = SearchBookContentsResult.getQuery();\n    if (LocaleManager.isBookSearchUrl(activity.getISBN()) && pageId.length() > 0) {\n      String uri = activity.getISBN();\n      int equals = uri.indexOf('=');\n      String volumeId = uri.substring(equals + 1);\n      String readBookURI = \"http://books.google.\" +\n          LocaleManager.getBookSearchCountryTLD(activity) +\n          \"/books?id=\" + volumeId + \"&pg=\" + pageId + \"&vq=\" + query;\n      Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(readBookURI));\n      intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);                    \n      activity.startActivity(intent);\n    }\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/book/SearchBookContentsActivity.java",
    "content": "/*\n * Copyright (C) 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.book;\n\nimport android.app.Activity;\nimport android.content.Intent;\nimport android.os.AsyncTask;\nimport android.os.Bundle;\nimport android.util.Log;\nimport android.view.KeyEvent;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.webkit.CookieManager;\nimport android.webkit.CookieSyncManager;\nimport android.widget.Button;\nimport android.widget.EditText;\nimport android.widget.ListView;\nimport android.widget.TextView;\nimport com.google.zxing.FakeR;\n\nimport org.json.JSONArray;\nimport org.json.JSONException;\nimport org.json.JSONObject;\n\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.regex.Pattern;\n\nimport com.google.zxing.client.android.Intents;\nimport com.google.zxing.client.android.HttpHelper;\nimport com.google.zxing.client.android.LocaleManager;\nimport com.google.zxing.client.android.R;\nimport com.google.zxing.client.android.common.executor.AsyncTaskExecInterface;\nimport com.google.zxing.client.android.common.executor.AsyncTaskExecManager;\n\n/**\n * Uses Google Book Search to find a word or phrase in the requested book.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n */\npublic final class SearchBookContentsActivity extends Activity {\n\n  private static final String TAG = SearchBookContentsActivity.class.getSimpleName();\n\n  private static final Pattern TAG_PATTERN = Pattern.compile(\"\\\\<.*?\\\\>\");\n  private static final Pattern LT_ENTITY_PATTERN = Pattern.compile(\"&lt;\");\n  private static final Pattern GT_ENTITY_PATTERN = Pattern.compile(\"&gt;\");\n  private static final Pattern QUOTE_ENTITY_PATTERN = Pattern.compile(\"&#39;\");\n  private static final Pattern QUOT_ENTITY_PATTERN = Pattern.compile(\"&quot;\");\n\n  private String isbn;\n  private EditText queryTextView;\n  private Button queryButton;\n  private ListView resultListView;\n  private TextView headerView;\n  private NetworkTask networkTask;\n  private final AsyncTaskExecInterface taskExec;\n\n  public SearchBookContentsActivity() {\n    taskExec = new AsyncTaskExecManager().build();\n  }\n\n  private final Button.OnClickListener buttonListener = new Button.OnClickListener() {\n    @Override\n    public void onClick(View view) {\n      launchSearch();\n    }\n  };\n\n  private final View.OnKeyListener keyListener = new View.OnKeyListener() {\n    @Override\n    public boolean onKey(View view, int keyCode, KeyEvent event) {\n      if (keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_DOWN) {\n        launchSearch();\n        return true;\n      }\n      return false;\n    }\n  };\n\n  String getISBN() {\n    return isbn;\n  }\n\n  private static FakeR fakeR;\n\n  @Override\n  public void onCreate(Bundle icicle) {\n    super.onCreate(icicle);\n\n\tfakeR = new FakeR(this);\n\n    // Make sure that expired cookies are removed on launch.\n    CookieSyncManager.createInstance(this);\n    CookieManager.getInstance().removeExpiredCookie();\n\n    Intent intent = getIntent();\n    if (intent == null || !intent.getAction().equals(Intents.SearchBookContents.ACTION)) {\n      finish();\n      return;\n    }\n\n    isbn = intent.getStringExtra(Intents.SearchBookContents.ISBN);\n    if (LocaleManager.isBookSearchUrl(isbn)) {\n      setTitle(getString(fakeR.getId(\"string\", \"sbc_name\")));\n    } else {\n      setTitle(getString(fakeR.getId(\"string\", \"sbc_name\")) + \": ISBN \" + isbn);\n    }\n\n    setContentView(fakeR.getId(\"layout\", \"search_book_contents\"));\n    queryTextView = (EditText) findViewById(fakeR.getId(\"id\", \"query_text_view\"));\n\n    String initialQuery = intent.getStringExtra(Intents.SearchBookContents.QUERY);\n    if (initialQuery != null && initialQuery.length() > 0) {\n      // Populate the search box but don't trigger the search\n      queryTextView.setText(initialQuery);\n    }\n    queryTextView.setOnKeyListener(keyListener);\n\n    queryButton = (Button) findViewById(fakeR.getId(\"id\", \"query_button\"));\n    queryButton.setOnClickListener(buttonListener);\n\n    resultListView = (ListView) findViewById(fakeR.getId(\"id\", \"result_list_view\"));\n    LayoutInflater factory = LayoutInflater.from(this);\n    headerView = (TextView) factory.inflate(fakeR.getId(\"layout\", \"search_book_contents_header\"),\n        resultListView, false);\n    resultListView.addHeaderView(headerView);\n  }\n\n  @Override\n  protected void onResume() {\n    super.onResume();\n    queryTextView.selectAll();\n  }\n\n  @Override\n  protected void onPause() {\n    NetworkTask oldTask = networkTask;\n    if (oldTask != null) {\n      oldTask.cancel(true);\n      networkTask = null;\n    }\n    super.onPause();\n  }\n\n  private void launchSearch() {\n    String query = queryTextView.getText().toString();\n    if (query != null && query.length() > 0) {\n      NetworkTask oldTask = networkTask;\n      if (oldTask != null) {\n        oldTask.cancel(true);\n      }\n      networkTask = new NetworkTask();\n      taskExec.execute(networkTask, query, isbn);\n      headerView.setText(fakeR.getId(\"string\", \"msg_sbc_searching_book\"));\n      resultListView.setAdapter(null);\n      queryTextView.setEnabled(false);\n      queryButton.setEnabled(false);\n    }\n  }\n\n  private final class NetworkTask extends AsyncTask<String,Object,JSONObject> {\n\n    @Override\n    protected JSONObject doInBackground(String... args) {\n      try {\n        // These return a JSON result which describes if and where the query was found. This API may\n        // break or disappear at any time in the future. Since this is an API call rather than a\n        // website, we don't use LocaleManager to change the TLD.\n        String theQuery = args[0];\n        String theIsbn = args[1];\n        String uri;\n        if (LocaleManager.isBookSearchUrl(theIsbn)) {\n          int equals = theIsbn.indexOf('=');\n          String volumeId = theIsbn.substring(equals + 1);\n          uri = \"http://www.google.com/books?id=\" + volumeId + \"&jscmd=SearchWithinVolume2&q=\" + theQuery;\n        } else {\n          uri = \"http://www.google.com/books?vid=isbn\" + theIsbn + \"&jscmd=SearchWithinVolume2&q=\" + theQuery;\n        }\n        CharSequence content = HttpHelper.downloadViaHttp(uri, HttpHelper.ContentType.JSON);\n        return new JSONObject(content.toString());\n      } catch (IOException ioe) {\n        Log.w(TAG, \"Error accessing book search\", ioe);\n        return null;\n      } catch (JSONException je) {\n        Log.w(TAG, \"Error accessing book search\", je);\n        return null;\n      }\n    }\n\n    @Override\n    protected void onPostExecute(JSONObject result) {\n      if (result == null) {\n        headerView.setText(fakeR.getId(\"string\", \"msg_sbc_failed\"));\n      } else {\n        handleSearchResults(result);\n      }\n      queryTextView.setEnabled(true);\n      queryTextView.selectAll();\n      queryButton.setEnabled(true);\n    }\n\n    // Currently there is no way to distinguish between a query which had no results and a book\n    // which is not searchable - both return zero results.\n    private void handleSearchResults(JSONObject json) {\n      try {\n        int count = json.getInt(\"number_of_results\");\n        headerView.setText(getString(fakeR.getId(\"string\", \"msg_sbc_results\")) + \" : \" + count);\n        if (count > 0) {\n          JSONArray results = json.getJSONArray(\"search_results\");\n          SearchBookContentsResult.setQuery(queryTextView.getText().toString());\n          List<SearchBookContentsResult> items = new ArrayList<SearchBookContentsResult>(count);\n          for (int x = 0; x < count; x++) {\n            items.add(parseResult(results.getJSONObject(x)));\n          }\n          resultListView.setOnItemClickListener(new BrowseBookListener(SearchBookContentsActivity.this, items));\n          resultListView.setAdapter(new SearchBookContentsAdapter(SearchBookContentsActivity.this, items));\n        } else {\n          String searchable = json.optString(\"searchable\");\n          if (\"false\".equals(searchable)) {\n            headerView.setText(fakeR.getId(\"string\", \"msg_sbc_book_not_searchable\"));\n          }\n          resultListView.setAdapter(null);\n        }\n      } catch (JSONException e) {\n        Log.w(TAG, \"Bad JSON from book search\", e);\n        resultListView.setAdapter(null);\n        headerView.setText(fakeR.getId(\"string\", \"msg_sbc_failed\"));\n      }\n    }\n\n    // Available fields: page_id, page_number, page_url, snippet_text\n    private SearchBookContentsResult parseResult(JSONObject json) {\n      try {\n        String pageId = json.getString(\"page_id\");\n        String pageNumber = json.getString(\"page_number\");\n        if (pageNumber.length() > 0) {\n          pageNumber = getString(fakeR.getId(\"string\", \"msg_sbc_page\")) + ' ' + pageNumber;\n        } else {\n          // This can happen for text on the jacket, and possibly other reasons.\n          pageNumber = getString(fakeR.getId(\"string\", \"msg_sbc_unknown_page\"));\n        }\n\n        // Remove all HTML tags and encoded characters. Ideally the server would do this.\n        String snippet = json.optString(\"snippet_text\");\n        boolean valid = true;\n        if (snippet.length() > 0) {\n          snippet = TAG_PATTERN.matcher(snippet).replaceAll(\"\");\n          snippet = LT_ENTITY_PATTERN.matcher(snippet).replaceAll(\"<\");\n          snippet = GT_ENTITY_PATTERN.matcher(snippet).replaceAll(\">\");\n          snippet = QUOTE_ENTITY_PATTERN.matcher(snippet).replaceAll(\"'\");\n          snippet = QUOT_ENTITY_PATTERN.matcher(snippet).replaceAll(\"\\\"\");\n        } else {\n          snippet = '(' + getString(fakeR.getId(\"string\", \"msg_sbc_snippet_unavailable\")) + ')';\n          valid = false;\n        }\n        return new SearchBookContentsResult(pageId, pageNumber, snippet, valid);\n      } catch (JSONException e) {\n        // Never seen in the wild, just being complete.\n        return new SearchBookContentsResult(getString(fakeR.getId(\"string\", \"msg_sbc_no_page_returned\")), \"\", \"\", false);\n      }\n    }\n\n\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/book/SearchBookContentsAdapter.java",
    "content": "/*\n * Copyright (C) 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.book;\n\nimport android.content.Context;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.ArrayAdapter;\nimport com.google.zxing.FakeR;\n\nimport java.util.List;\n\nimport com.google.zxing.client.android.R;\n\n/**\n * Manufactures list items which represent SBC results.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n */\nfinal class SearchBookContentsAdapter extends ArrayAdapter<SearchBookContentsResult> {\n\n  private static FakeR fakeR;\n\n  SearchBookContentsAdapter(Context context, List<SearchBookContentsResult> items) {\n    super(context, fakeR.getId(\"layout\", \"search_book_contents_list_item\"), 0, items);\n\tfakeR = new FakeR(context);\n  }\n\n  @Override\n  public View getView(int position, View view, ViewGroup viewGroup) {\n    SearchBookContentsListItem listItem;\n\n    if (view == null) {\n      LayoutInflater factory = LayoutInflater.from(getContext());\n      listItem = (SearchBookContentsListItem) factory.inflate(\n          fakeR.getId(\"layout\", \"search_book_contents_list_item\"), viewGroup, false);\n    } else {\n      if (view instanceof SearchBookContentsListItem) {\n        listItem = (SearchBookContentsListItem) view;\n      } else {\n        return view;\n      }\n    }\n\n    SearchBookContentsResult result = getItem(position);\n    listItem.set(result);\n    return listItem;\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/book/SearchBookContentsListItem.java",
    "content": "/*\n * Copyright (C) 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.book;\n\nimport com.google.zxing.client.android.R;\n\nimport android.content.Context;\nimport android.graphics.Typeface;\nimport android.text.Spannable;\nimport android.text.SpannableString;\nimport android.text.style.StyleSpan;\nimport android.util.AttributeSet;\nimport android.widget.LinearLayout;\nimport android.widget.TextView;\nimport com.google.zxing.FakeR;\n\nimport java.util.Locale;\n\n/**\n * A list item which displays the page number and snippet of this search result.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n */\npublic final class SearchBookContentsListItem extends LinearLayout {\n  private TextView pageNumberView;\n  private TextView snippetView;\n\n  private static FakeR fakeR;\n  SearchBookContentsListItem(Context context) {\n    super(context);\n\tfakeR = new FakeR(context);\n  }\n\n  public SearchBookContentsListItem(Context context, AttributeSet attrs) {\n    super(context, attrs);\n  }\n\n  @Override\n  protected void onFinishInflate() {\n    super.onFinishInflate();\n    pageNumberView = (TextView) findViewById(fakeR.getId(\"id\", \"page_number_view\"));\n    snippetView = (TextView) findViewById(fakeR.getId(\"id\", \"snippet_view\"));\n  }\n\n  public void set(SearchBookContentsResult result) {\n    pageNumberView.setText(result.getPageNumber());\n    String snippet = result.getSnippet();\n    if (snippet.length() > 0) {\n      if (result.getValidSnippet()) {\n        String lowerQuery = SearchBookContentsResult.getQuery().toLowerCase(Locale.getDefault());\n        String lowerSnippet = snippet.toLowerCase(Locale.getDefault());\n        Spannable styledSnippet = new SpannableString(snippet);\n        StyleSpan boldSpan = new StyleSpan(Typeface.BOLD);\n        int queryLength = lowerQuery.length();\n        int offset = 0;\n        while (true) {\n          int pos = lowerSnippet.indexOf(lowerQuery, offset);\n          if (pos < 0) {\n            break;\n          }\n          styledSnippet.setSpan(boldSpan, pos, pos + queryLength, 0);\n          offset = pos + queryLength;\n        }\n        snippetView.setText(styledSnippet);\n      } else {\n        // This may be an error message, so don't try to bold the query terms within it\n        snippetView.setText(snippet);\n      }\n    } else {\n      snippetView.setText(\"\");\n    }\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/book/SearchBookContentsResult.java",
    "content": "/*\n * Copyright (C) 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.book;\n\n/**\n * The underlying data for a SBC result.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n */\nfinal class SearchBookContentsResult {\n\n  private static String query;\n\n  private final String pageId;\n  private final String pageNumber;\n  private final String snippet;\n  private final boolean validSnippet;\n\n    SearchBookContentsResult(String pageId,\n                             String pageNumber,\n                             String snippet,\n                             boolean validSnippet) {\n    this.pageId = pageId;\n    this.pageNumber = pageNumber;\n    this.snippet = snippet;\n    this.validSnippet = validSnippet;\n  }\n\n  public static void setQuery(String query) {\n    SearchBookContentsResult.query = query;\n  }\n\n  public String getPageId() {\n    return pageId;\n  }\n\n  public String getPageNumber() {\n    return pageNumber;\n  }\n\n  public String getSnippet() {\n    return snippet;\n  }\n\n  public boolean getValidSnippet() {\n    return validSnippet;\n  }\n\n  public static String getQuery() {\n    return query;\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/camera/AutoFocusManager.java",
    "content": "/*\n * Copyright (C) 2012 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.camera;\n\nimport android.content.Context;\nimport android.content.SharedPreferences;\nimport android.hardware.Camera;\nimport android.os.AsyncTask;\nimport android.preference.PreferenceManager;\nimport android.util.Log;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\n\nimport com.google.zxing.client.android.PreferencesActivity;\nimport com.google.zxing.client.android.common.executor.AsyncTaskExecInterface;\nimport com.google.zxing.client.android.common.executor.AsyncTaskExecManager;\n\nfinal class AutoFocusManager implements Camera.AutoFocusCallback {\n\n  private static final String TAG = AutoFocusManager.class.getSimpleName();\n\n  private static final long AUTO_FOCUS_INTERVAL_MS = 2000L;\n  private static final Collection<String> FOCUS_MODES_CALLING_AF;\n  static {\n    FOCUS_MODES_CALLING_AF = new ArrayList<String>(2);\n    FOCUS_MODES_CALLING_AF.add(Camera.Parameters.FOCUS_MODE_AUTO);\n    FOCUS_MODES_CALLING_AF.add(Camera.Parameters.FOCUS_MODE_MACRO);\n  }\n\n  private boolean active;\n  private final boolean useAutoFocus;\n  private final Camera camera;\n  private AutoFocusTask outstandingTask;\n  private final AsyncTaskExecInterface taskExec;\n\n  AutoFocusManager(Context context, Camera camera) {\n    this.camera = camera;\n    taskExec = new AsyncTaskExecManager().build();\n    SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);\n    String currentFocusMode = camera.getParameters().getFocusMode();\n    useAutoFocus =\n        sharedPrefs.getBoolean(PreferencesActivity.KEY_AUTO_FOCUS, true) &&\n        FOCUS_MODES_CALLING_AF.contains(currentFocusMode);\n    Log.i(TAG, \"Current focus mode '\" + currentFocusMode + \"'; use auto focus? \" + useAutoFocus);\n    start();\n  }\n\n  @Override\n  public synchronized void onAutoFocus(boolean success, Camera theCamera) {\n    if (active) {\n      outstandingTask = new AutoFocusTask();\n      taskExec.execute(outstandingTask);\n    }\n  }\n\n  synchronized void start() {\n    if (useAutoFocus) {\n      active = true;\n      try {\n        camera.autoFocus(this);\n      } catch (RuntimeException re) {\n        // Have heard RuntimeException reported in Android 4.0.x+; continue?\n        Log.w(TAG, \"Unexpected exception while focusing\", re);\n      }\n    }\n  }\n\n  synchronized void stop() {\n    if (useAutoFocus) {\n      try {\n        camera.cancelAutoFocus();\n      } catch (RuntimeException re) {\n        // Have heard RuntimeException reported in Android 4.0.x+; continue?\n        Log.w(TAG, \"Unexpected exception while cancelling focusing\", re);\n      }\n    }\n    if (outstandingTask != null) {\n      outstandingTask.cancel(true);\n      outstandingTask = null;\n    }\n    active = false;\n  }\n\n  private final class AutoFocusTask extends AsyncTask<Object,Object,Object> {\n    @Override\n    protected Object doInBackground(Object... voids) {\n      try {\n        Thread.sleep(AUTO_FOCUS_INTERVAL_MS);\n      } catch (InterruptedException e) {\n        // continue\n      }\n      synchronized (AutoFocusManager.this) {\n        if (active) {\n          start();\n        }\n      }\n      return null;\n    }\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/camera/CameraConfigurationManager.java",
    "content": "/*\n * Copyright (C) 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.camera;\n\nimport android.content.Context;\nimport android.content.SharedPreferences;\nimport android.content.res.Configuration;\nimport android.graphics.Point;\nimport android.hardware.Camera;\nimport android.preference.PreferenceManager;\nimport android.util.DisplayMetrics;\nimport android.util.Log;\nimport android.util.TypedValue;\nimport android.view.Display;\nimport android.view.Surface;\nimport android.view.WindowManager;\nimport com.google.zxing.client.android.PreferencesActivity;\n\nimport java.util.*;\n\n/**\n * A class which deals with reading, parsing, and setting the camera parameters which are used to\n * configure the camera hardware.\n */\nfinal class CameraConfigurationManager {\n\n  private static final String TAG = \"CameraConfiguration\";\n\n  // This is bigger than the size of a small screen, which is still supported. The routine\n  // below will still select the default (presumably 320x240) size for these. This prevents\n  // accidental selection of very low resolution on some devices.\n  private static final int MIN_PREVIEW_PIXELS = 470 * 320; // normal screen\n  private static final int MAX_PREVIEW_PIXELS = 1280 * 720;\n\n  private final Context context;\n  //  private final Activity activity;\n  private Point screenResolution;\n  private Point cameraResolution;\n\n  CameraConfigurationManager(Context context) {\n    this.context = context.getApplicationContext();\n//    this.activity = (Activity) context;\n  }\n\n  /**\n   * Reads, one time, values from the camera that are needed by the app.\n   */\n  void initFromCameraParameters(Camera camera) {\n    Camera.Parameters parameters = camera.getParameters();\n    WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);\n    Display display = manager.getDefaultDisplay();\n    DisplayMetrics metrics = new DisplayMetrics();\n    display.getMetrics(metrics);\n\n    screenResolution = new Point();\n    int width = metrics.widthPixels;\n    int height = metrics.heightPixels;\n\n    // Remove action bar height\n    TypedValue typedValue = new TypedValue();\n    DisplayMetrics displayMetrics = this.context.getResources().getDisplayMetrics();\n    if (this.context.getTheme().resolveAttribute(android.R.attr.actionBarSize, typedValue, true)) {\n      height -= TypedValue.complexToDimensionPixelSize(typedValue.data, displayMetrics);\n    } else {\n      int rotation = context.getApplicationContext().getResources().getConfiguration().orientation;\n      if (rotation == Configuration.ORIENTATION_PORTRAIT) {\n        height -= 40 * displayMetrics.density;\n      } else {\n        height -= 48 * displayMetrics.density;\n      }\n    }\n//    height -= statusBarHeight();\n    height -= 50;\n\n    screenResolution.set(width, height);\n\n    Log.i(TAG, \"Screen resolution: \" + screenResolution);\n    cameraResolution = findBestPreviewSizeValue(parameters, screenResolution);\n    Log.i(TAG, \"Camera resolution: \" + cameraResolution);\n  }\n\n  void setDesiredCameraParameters(Camera camera, boolean safeMode) {\n    // Checkout screen orientation\n    int rotation = context.getApplicationContext().getResources().getConfiguration().orientation;\n\n    WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);\n    Display display = windowManager.getDefaultDisplay();\n    int deviceSpecificRotation = display.getRotation();\n\n    if (rotation == Configuration.ORIENTATION_PORTRAIT) {\n      if (deviceSpecificRotation == Surface.ROTATION_0 || deviceSpecificRotation == Surface.ROTATION_90) {\n        camera.setDisplayOrientation(90);\n      } else {\n        camera.setDisplayOrientation(270);\n      }\n    } else {\n      // landscape\n      if (deviceSpecificRotation == Surface.ROTATION_180 || deviceSpecificRotation == Surface.ROTATION_270) {\n        camera.setDisplayOrientation(180);\n      }\n    }\n\n    Camera.Parameters parameters = camera.getParameters();\n\n    if (parameters == null) {\n      Log.w(TAG, \"Device error: no camera parameters are available. Proceeding without configuration.\");\n      return;\n    }\n\n    Log.i(TAG, \"Initial camera parameters: \" + parameters.flatten());\n\n    if (safeMode) {\n      Log.w(TAG, \"In camera config safe mode -- most settings will not be honored\");\n    }\n\n    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);\n\n    initializeTorch(parameters, prefs, safeMode);\n\n    String focusMode = null;\n    if (prefs.getBoolean(PreferencesActivity.KEY_AUTO_FOCUS, true)) {\n      if (safeMode || prefs.getBoolean(PreferencesActivity.KEY_DISABLE_CONTINUOUS_FOCUS, false)) {\n        focusMode = findSettableValue(parameters.getSupportedFocusModes(),\n            Camera.Parameters.FOCUS_MODE_AUTO);\n      } else {\n        focusMode = findSettableValue(parameters.getSupportedFocusModes(),\n            \"continuous-picture\", // Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE in 4.0+\n            \"continuous-video\",   // Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO in 4.0+\n            Camera.Parameters.FOCUS_MODE_AUTO);\n      }\n    }\n    // Maybe selected auto-focus but not available, so fall through here:\n    if (!safeMode && focusMode == null) {\n      focusMode = findSettableValue(parameters.getSupportedFocusModes(),\n          Camera.Parameters.FOCUS_MODE_MACRO,\n          \"edof\"); // Camera.Parameters.FOCUS_MODE_EDOF in 2.2+\n    }\n    if (focusMode != null) {\n      parameters.setFocusMode(focusMode);\n    }\n\n    parameters.setPreviewSize(cameraResolution.x, cameraResolution.y);\n    camera.setParameters(parameters);\n  }\n\n  Point getCameraResolution() {\n    return cameraResolution;\n  }\n\n  Point getScreenResolution() {\n    return screenResolution;\n  }\n\n  void setTorch(Camera camera, boolean newSetting) {\n    Camera.Parameters parameters = camera.getParameters();\n    doSetTorch(parameters, newSetting, false);\n    camera.setParameters(parameters);\n    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);\n    boolean currentSetting = prefs.getBoolean(PreferencesActivity.KEY_FRONT_LIGHT, false);\n    if (currentSetting != newSetting) {\n      SharedPreferences.Editor editor = prefs.edit();\n      editor.putBoolean(PreferencesActivity.KEY_FRONT_LIGHT, newSetting);\n      editor.commit();\n    }\n  }\n\n  private void initializeTorch(Camera.Parameters parameters, SharedPreferences prefs, boolean safeMode) {\n    boolean currentSetting = prefs.getBoolean(PreferencesActivity.KEY_FRONT_LIGHT, false);\n    doSetTorch(parameters, currentSetting, safeMode);\n  }\n\n  private void doSetTorch(Camera.Parameters parameters, boolean newSetting, boolean safeMode) {\n    String flashMode;\n    if (newSetting) {\n      flashMode = findSettableValue(parameters.getSupportedFlashModes(),\n          Camera.Parameters.FLASH_MODE_TORCH,\n          Camera.Parameters.FLASH_MODE_ON);\n    } else {\n      flashMode = findSettableValue(parameters.getSupportedFlashModes(),\n          Camera.Parameters.FLASH_MODE_OFF);\n    }\n    if (flashMode != null) {\n      parameters.setFlashMode(flashMode);\n    }\n\n    /*\n    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);\n    if (!prefs.getBoolean(PreferencesActivity.KEY_DISABLE_EXPOSURE, false)) {\n      if (!safeMode) {\n        ExposureInterface exposure = new ExposureManager().build();\n        exposure.setExposure(parameters, newSetting);\n      }\n    }\n     */\n  }\n\n  private Point findBestPreviewSizeValue(Camera.Parameters parameters, Point screenResolution) {\n\n    List<Camera.Size> rawSupportedSizes = parameters.getSupportedPreviewSizes();\n    if (rawSupportedSizes == null) {\n      Log.w(TAG, \"Device returned no supported preview sizes; using default\");\n      Camera.Size defaultSize = parameters.getPreviewSize();\n      return new Point(defaultSize.width, defaultSize.height);\n    }\n\n    // Sort by size, descending\n    List<Camera.Size> supportedPreviewSizes = new ArrayList<Camera.Size>(rawSupportedSizes);\n    Collections.sort(supportedPreviewSizes, new Comparator<Camera.Size>() {\n      @Override\n      public int compare(Camera.Size a, Camera.Size b) {\n        int aPixels = a.height * a.width;\n        int bPixels = b.height * b.width;\n        if (bPixels < aPixels) {\n          return -1;\n        }\n        if (bPixels > aPixels) {\n          return 1;\n        }\n        return 0;\n      }\n    });\n\n    if (Log.isLoggable(TAG, Log.INFO)) {\n      StringBuilder previewSizesString = new StringBuilder();\n      for (Camera.Size supportedPreviewSize : supportedPreviewSizes) {\n        previewSizesString.append(supportedPreviewSize.width).append('x')\n            .append(supportedPreviewSize.height).append(' ');\n      }\n      Log.i(TAG, \"Supported preview sizes: \" + previewSizesString);\n    }\n\n    Point bestSize = null;\n    float screenAspectRatio = (float) screenResolution.x / (float) screenResolution.y;\n\n    float diff = Float.POSITIVE_INFINITY;\n    for (Camera.Size supportedPreviewSize : supportedPreviewSizes) {\n      int realWidth = supportedPreviewSize.width;\n      int realHeight = supportedPreviewSize.height;\n      int pixels = realWidth * realHeight;\n      if (pixels < MIN_PREVIEW_PIXELS || pixels > MAX_PREVIEW_PIXELS) {\n        continue;\n      }\n      boolean isCandidatePortrait = realWidth < realHeight;\n      int maybeFlippedWidth = isCandidatePortrait ? realHeight : realWidth;\n      int maybeFlippedHeight = isCandidatePortrait ? realWidth : realHeight;\n      if (maybeFlippedWidth == screenResolution.x && maybeFlippedHeight == screenResolution.y) {\n        Point exactPoint = new Point(realWidth, realHeight);\n        Log.i(TAG, \"Found preview size exactly matching screen size: \" + exactPoint);\n        return exactPoint;\n      }\n      float aspectRatio = (float) maybeFlippedWidth / (float) maybeFlippedHeight;\n      float newDiff = Math.abs(aspectRatio - screenAspectRatio);\n      if (newDiff < diff) {\n        bestSize = new Point(realWidth, realHeight);\n        diff = newDiff;\n      }\n    }\n\n    if (bestSize == null) {\n      Camera.Size defaultSize = parameters.getPreviewSize();\n      bestSize = new Point(defaultSize.width, defaultSize.height);\n      Log.i(TAG, \"No suitable preview sizes, using default: \" + bestSize);\n    }\n\n    WindowManager manager = (WindowManager) this.context.getSystemService(Context.WINDOW_SERVICE);\n    int rotation = manager.getDefaultDisplay().getRotation();\n\n    Log.i(TAG, \"Found best approximate preview size: \" + bestSize);\n    return bestSize;\n  }\n\n  private static String findSettableValue(Collection<String> supportedValues,\n                                          String... desiredValues) {\n    Log.i(TAG, \"Supported values: \" + supportedValues);\n    String result = null;\n    if (supportedValues != null) {\n      for (String desiredValue : desiredValues) {\n        if (supportedValues.contains(desiredValue)) {\n          result = desiredValue;\n          break;\n        }\n      }\n    }\n    Log.i(TAG, \"Settable value: \" + result);\n    return result;\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/camera/CameraManager.java",
    "content": "/*\n * Copyright (C) 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.camera;\n\nimport android.content.Context;\nimport android.content.res.Configuration;\nimport android.graphics.Point;\nimport android.graphics.Rect;\nimport android.hardware.Camera;\nimport android.os.Handler;\nimport android.util.Log;\nimport android.view.SurfaceHolder;\nimport android.view.WindowManager;\nimport com.google.zxing.PlanarYUVLuminanceSource;\nimport com.google.zxing.client.android.camera.open.OpenCameraManager;\n\nimport java.io.IOException;\n\n/**\n * This object wraps the Camera service object and expects to be the only one talking to it. The\n * implementation encapsulates the steps needed to take preview-sized images, which are used for\n * both preview and decoding.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n */\npublic final class CameraManager {\n\n  private static final String TAG = CameraManager.class.getSimpleName();\n\n  private static final int MIN_FRAME_WIDTH = 220;\n  private static final int MIN_FRAME_HEIGHT = 220;\n  private static final int MAX_FRAME_WIDTH = 880;\n  private static final int MAX_FRAME_HEIGHT = 680;\n\n  private final Context context;\n  private final CameraConfigurationManager configManager;\n  private Camera camera;\n  private AutoFocusManager autoFocusManager;\n  private Rect framingRect;\n  private Rect framingRectInPreview;\n  private boolean initialized;\n  private boolean previewing;\n  private int requestedFramingRectWidth;\n  private int requestedFramingRectHeight;\n  private WindowManager windowManager;\n\n  /**\n   * Preview frames are delivered here, which we pass on to the registered handler. Make sure to\n   * clear the handler so it will only receive one message.\n   */\n  private final PreviewCallback previewCallback;\n\n  public CameraManager(Context context) {\n    this.context = context.getApplicationContext();\n    this.configManager = new CameraConfigurationManager(context);\n    previewCallback = new PreviewCallback(configManager);\n    windowManager = (WindowManager) this.context.getSystemService(Context.WINDOW_SERVICE);\n  }\n\n  /**\n   * Opens the camera driver and initializes the hardware parameters.\n   *\n   * @param holder The surface object which the camera will draw preview frames into.\n   * @throws IOException Indicates the camera driver failed to open.\n   */\n  public synchronized void openDriver(SurfaceHolder holder) throws IOException {\n    Camera theCamera = camera;\n    if (theCamera == null) {\n      theCamera = new OpenCameraManager().build().open();\n      if (theCamera == null) {\n        throw new IOException();\n      }\n      camera = theCamera;\n    }\n    theCamera.setPreviewDisplay(holder);\n\n    if (!initialized) {\n      initialized = true;\n      configManager.initFromCameraParameters(theCamera);\n      if (requestedFramingRectWidth > 0 && requestedFramingRectHeight > 0) {\n        setManualFramingRect(requestedFramingRectWidth, requestedFramingRectHeight);\n        requestedFramingRectWidth = 0;\n        requestedFramingRectHeight = 0;\n      }\n    }\n\n    Camera.Parameters parameters = theCamera.getParameters();\n    String parametersFlattened = parameters == null ? null : parameters.flatten(); // Save these, temporarily\n    try {\n      configManager.setDesiredCameraParameters(theCamera, false);\n    } catch (RuntimeException re) {\n      // Driver failed\n      Log.w(TAG, \"Camera rejected parameters. Setting only minimal safe-mode parameters\");\n      Log.i(TAG, \"Resetting to saved camera params: \" + parametersFlattened);\n      // Reset:\n      if (parametersFlattened != null) {\n        parameters = theCamera.getParameters();\n        parameters.unflatten(parametersFlattened);\n        try {\n          theCamera.setParameters(parameters);\n          configManager.setDesiredCameraParameters(theCamera, true);\n        } catch (RuntimeException re2) {\n          // Well, darn. Give up\n          Log.w(TAG, \"Camera rejected even safe-mode parameters! No configuration\");\n        }\n      }\n    }\n\n  }\n\n  public synchronized boolean isOpen() {\n    return camera != null;\n  }\n\n  /**\n   * Closes the camera driver if still in use.\n   */\n  public synchronized void closeDriver() {\n    if (camera != null) {\n      camera.release();\n      camera = null;\n      // Make sure to clear these each time we close the camera, so that any scanning rect\n      // requested by intent is forgotten.\n      framingRect = null;\n      framingRectInPreview = null;\n    }\n  }\n\n  /**\n   * Asks the camera hardware to begin drawing preview frames to the screen.\n   */\n  public synchronized void startPreview() {\n    Camera theCamera = camera;\n    if (theCamera != null && !previewing) {\n      theCamera.startPreview();\n      previewing = true;\n      autoFocusManager = new AutoFocusManager(context, camera);\n    }\n  }\n\n  /**\n   * Tells the camera to stop drawing preview frames.\n   */\n  public synchronized void stopPreview() {\n    if (autoFocusManager != null) {\n      autoFocusManager.stop();\n      autoFocusManager = null;\n    }\n    if (camera != null && previewing) {\n      camera.stopPreview();\n      previewCallback.setHandler(null, 0);\n      previewing = false;\n    }\n  }\n\n  /**\n   * Convenience method for {@link com.google.zxing.client.android.CaptureActivity}\n   */\n  public synchronized void setTorch(boolean newSetting) {\n    if (camera != null) {\n      if (autoFocusManager != null) {\n        autoFocusManager.stop();\n      }\n      configManager.setTorch(camera, newSetting);\n      if (autoFocusManager != null) {\n        autoFocusManager.start();\n      }\n    }\n  }\n\n  /**\n   * A single preview frame will be returned to the handler supplied. The data will arrive as byte[]\n   * in the message.obj field, with width and height encoded as message.arg1 and message.arg2,\n   * respectively.\n   *\n   * @param handler The handler to send the message to.\n   * @param message The what field of the message to be sent.\n   */\n  public synchronized void requestPreviewFrame(Handler handler, int message) {\n    Camera theCamera = camera;\n    if (theCamera != null && previewing) {\n      previewCallback.setHandler(handler, message);\n      theCamera.setOneShotPreviewCallback(previewCallback);\n    }\n  }\n\n  /**\n   * Calculates the framing rect which the UI should draw to show the user where to place the\n   * barcode. This target helps with alignment as well as forces the user to hold the device\n   * far enough away to ensure the image will be in focus.\n   *\n   * @return The rectangle to draw on screen in window coordinates.\n   */\n  public synchronized Rect getFramingRect() {\n    if (framingRect == null) {\n      if (camera == null) {\n        return null;\n      }\n      Point screenResolution = configManager.getScreenResolution();\n      if (screenResolution == null) {\n        // Called early, before init even finished\n        return null;\n      }\n      int width = screenResolution.x * 3 / 4;\n      if (width < MIN_FRAME_WIDTH) {\n        width = MIN_FRAME_WIDTH;\n      } else if (width > MAX_FRAME_WIDTH) {\n        width = MAX_FRAME_WIDTH;\n      }\n      int height = screenResolution.y * 3 / 4;\n      if (height < MIN_FRAME_HEIGHT) {\n        height = MIN_FRAME_HEIGHT;\n      } else if (height > MAX_FRAME_HEIGHT) {\n        height = MAX_FRAME_HEIGHT;\n      }\n      int leftOffset = (screenResolution.x - width) / 2;\n      int topOffset, bottomOffset;\n      topOffset = (screenResolution.y - height) / 2;\n      bottomOffset =  topOffset + height;\n      framingRect = new Rect(leftOffset, topOffset, leftOffset + width, bottomOffset);\n      Log.d(TAG, \"Calculated framing rect: \" + framingRect);\n    }\n    return framingRect;\n  }\n\n  /**\n   * Like {@link #getFramingRect} but coordinates are in terms of the preview frame,\n   * not UI / screen.\n   */\n  public synchronized Rect getFramingRectInPreview() {\n    if (framingRectInPreview == null) {\n      Rect framingRect = getFramingRect();\n      if (framingRect == null) {\n        return null;\n      }\n      Rect rect = new Rect(framingRect);\n      Point cameraResolution = configManager.getCameraResolution();\n      Point screenResolution = configManager.getScreenResolution();\n      if (cameraResolution == null || screenResolution == null) {\n        // Called early, before init even finished\n        return null;\n      }\n\n      int rotation = context.getApplicationContext().getResources().getConfiguration().orientation;\n      if (rotation == Configuration.ORIENTATION_PORTRAIT) {\n        rect.left = rect.left * cameraResolution.y / screenResolution.x;\n        rect.right = rect.right * cameraResolution.y / screenResolution.x;\n        rect.top = rect.top * cameraResolution.x / screenResolution.y;\n        rect.bottom = rect.bottom * cameraResolution.x / screenResolution.y;\n      } else {\n        rect.left = rect.left * cameraResolution.x / screenResolution.x;\n        rect.right = rect.right * cameraResolution.x / screenResolution.x;\n        rect.top = rect.top * cameraResolution.y / screenResolution.y;\n        rect.bottom = rect.bottom * cameraResolution.y / screenResolution.y;\n      }\n\n      framingRectInPreview = rect;\n    }\n    return framingRectInPreview;\n  }\n\n  /**\n   * Allows third party apps to specify the scanning rectangle dimensions, rather than determine\n   * them automatically based on screen resolution.\n   *\n   * @param width The width in pixels to scan.\n   * @param height The height in pixels to scan.\n   */\n  public synchronized void setManualFramingRect(int width, int height) {\n    if (initialized) {\n      framingRect = getFramingRect();\n      Log.d(TAG, \"Calculated manual framing rect: \" + framingRect);\n      framingRectInPreview = null;\n    } else {\n      requestedFramingRectWidth = width;\n      requestedFramingRectHeight = height;\n    }\n  }\n\n  public PlanarYUVLuminanceSource buildLuminanceSource(byte[] data, int width, int height) {\n    byte[] rotatedData = new byte[data.length];\n    int rotation = context.getApplicationContext().getResources().getConfiguration().orientation;\n    if (rotation == Configuration.ORIENTATION_PORTRAIT) {\n      for (int y = 0; y < height; y++) {\n        for (int x = 0; x < width; x++) {\n          rotatedData[x * height + height - y - 1] = data[x + y * width];\n        }\n      }\n      int tmp = width;\n      width = height;\n      height = tmp;\n    } else {\n      rotatedData = null;\n    }\n\n    Rect rect = getFramingRectInPreview();\n    if (rect == null) {\n      return null;\n    }\n    // Go ahead and assume it's YUV rather than die.\n    return new PlanarYUVLuminanceSource(rotation == Configuration.ORIENTATION_PORTRAIT ? rotatedData : data, width, height, rect.left, rect.top,\n        rect.width(), rect.height(), false);\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/camera/PreviewCallback.java",
    "content": "/*\n * Copyright (C) 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.camera;\n\nimport android.graphics.Point;\nimport android.hardware.Camera;\nimport android.os.Handler;\nimport android.os.Message;\nimport android.util.Log;\n\nfinal class PreviewCallback implements Camera.PreviewCallback {\n\n  private static final String TAG = PreviewCallback.class.getSimpleName();\n\n  private final CameraConfigurationManager configManager;\n  private Handler previewHandler;\n  private int previewMessage;\n\n  PreviewCallback(CameraConfigurationManager configManager) {\n    this.configManager = configManager;\n  }\n\n  void setHandler(Handler previewHandler, int previewMessage) {\n    this.previewHandler = previewHandler;\n    this.previewMessage = previewMessage;\n  }\n\n  @Override\n  public void onPreviewFrame(byte[] data, Camera camera) {\n    Point cameraResolution = configManager.getCameraResolution();\n    Handler thePreviewHandler = previewHandler;\n    if (cameraResolution != null && thePreviewHandler != null) {\n      Message message = thePreviewHandler.obtainMessage(previewMessage, cameraResolution.x,\n          cameraResolution.y, data);\n      message.sendToTarget();\n      previewHandler = null;\n    } else {\n      Log.d(TAG, \"Got preview callback, but no handler or resolution available\");\n    }\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/camera/exposure/DefaultExposureInterface.java",
    "content": "/*\n * Copyright (C) 2012 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.camera.exposure;\n\nimport android.hardware.Camera;\n\npublic final class DefaultExposureInterface implements ExposureInterface {\n\n  @Override\n  public void setExposure(Camera.Parameters parameters, boolean lightOn) {\n    // Do nothing\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/camera/exposure/ExposureInterface.java",
    "content": "/*\n * Copyright (C) 2012 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.camera.exposure;\n\nimport android.hardware.Camera;\n\n/**\n * Implementations control auto-exposure settings of the camera, if available.\n * \n * @author Sean Owen\n */\npublic interface ExposureInterface {\n\n  void setExposure(Camera.Parameters parameters, boolean lightOn);\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/camera/exposure/ExposureManager.java",
    "content": "/*\n * Copyright (C) 2012 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.camera.exposure;\n\nimport com.google.zxing.client.android.common.PlatformSupportManager;\n\npublic final class ExposureManager extends PlatformSupportManager<ExposureInterface> {\n\n  public ExposureManager() {\n    super(ExposureInterface.class, new DefaultExposureInterface());\n    addImplementationClass(8, \"com.google.zxing.client.android.camera.exposure.FroyoExposureInterface\");\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/camera/exposure/FroyoExposureInterface.java",
    "content": "/*\n * Copyright (C) 2012 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.camera.exposure;\n\nimport android.annotation.TargetApi;\nimport android.hardware.Camera;\nimport android.util.Log;\n\n@TargetApi(8)\npublic final class FroyoExposureInterface implements ExposureInterface {\n\n  private static final String TAG = FroyoExposureInterface.class.getSimpleName();\n\n  private static final float MAX_EXPOSURE_COMPENSATION = 1.5f;\n  private static final float MIN_EXPOSURE_COMPENSATION = 0.0f;\n\n  @Override\n  public void setExposure(Camera.Parameters parameters, boolean lightOn) {\n    int minExposure = parameters.getMinExposureCompensation();\n    int maxExposure = parameters.getMaxExposureCompensation();\n    if (minExposure != 0 || maxExposure != 0) {\n      float step = parameters.getExposureCompensationStep();\n      int desiredCompensation;\n      if (lightOn) {\n        // Light on; set low exposue compensation\n        desiredCompensation = Math.max((int) (MIN_EXPOSURE_COMPENSATION / step), minExposure);\n      } else {\n        // Light off; set high compensation\n        desiredCompensation = Math.min((int) (MAX_EXPOSURE_COMPENSATION / step), maxExposure);\n      }\n      Log.i(TAG, \"Setting exposure compensation to \" + desiredCompensation + \" / \" + (step * desiredCompensation));\n      parameters.setExposureCompensation(desiredCompensation);\n    } else {\n      Log.i(TAG, \"Camera does not support exposure compensation\");\n    }\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/camera/open/DefaultOpenCameraInterface.java",
    "content": "/*\n * Copyright (C) 2012 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.camera.open;\n\nimport android.hardware.Camera;\n\n/**\n * Default implementation for Android before API 9 / Gingerbread.\n */\nfinal class DefaultOpenCameraInterface implements OpenCameraInterface {\n\n  /**\n   * Calls {@link Camera#open()}.\n   */\n  @Override\n  public Camera open() {\n    return Camera.open();\n  }\n  \n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/camera/open/GingerbreadOpenCameraInterface.java",
    "content": "/*\n * Copyright (C) 2012 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.camera.open;\n\nimport android.annotation.TargetApi;\nimport android.hardware.Camera;\nimport android.util.Log;\n\n/**\n * Implementation for Android API 9 (Gingerbread) and later. This opens up the possibility of accessing\n * front cameras, and rotated cameras.\n */\n@TargetApi(9)\npublic final class GingerbreadOpenCameraInterface implements OpenCameraInterface {\n\n  private static final String TAG = \"GingerbreadOpenCamera\";\n\n  /**\n   * Opens a rear-facing camera with {@link Camera#open(int)}, if one exists, or opens camera 0.\n   */\n  @Override\n  public Camera open() {\n    \n    int numCameras = Camera.getNumberOfCameras();\n    if (numCameras == 0) {\n      Log.w(TAG, \"No cameras!\");\n      return null;\n    }\n\n    int index = 0;\n    while (index < numCameras) {\n      Camera.CameraInfo cameraInfo = new Camera.CameraInfo();\n      Camera.getCameraInfo(index, cameraInfo);\n      if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {\n        break;\n      }\n      index++;\n    }\n    \n    Camera camera;\n    if (index < numCameras) {\n      Log.i(TAG, \"Opening camera #\" + index);\n      camera = Camera.open(index);\n    } else {\n      Log.i(TAG, \"No camera facing back; returning camera #0\");\n      camera = Camera.open(0);\n    }\n\n    return camera;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/camera/open/OpenCameraInterface.java",
    "content": "/*\n * Copyright (C) 2012 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.camera.open;\n\nimport android.hardware.Camera;\n\n/**\n * Provides an abstracted means to open a {@link Camera}. The API changes over Android API versions and\n * this allows the app to use newer API methods while retaining backwards-compatible behavior.\n */\npublic interface OpenCameraInterface {\n\n  Camera open();\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/camera/open/OpenCameraManager.java",
    "content": "/*\n * Copyright (C) 2012 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.camera.open;\n\nimport com.google.zxing.client.android.common.PlatformSupportManager;\n\n/**\n * Selects an appropriate implementation of {@link OpenCameraInterface} based on the device's\n * API level.\n */\npublic final class OpenCameraManager extends PlatformSupportManager<OpenCameraInterface> {\n\n  public OpenCameraManager() {\n    super(OpenCameraInterface.class, new DefaultOpenCameraInterface());\n    addImplementationClass(9, \"com.google.zxing.client.android.camera.open.GingerbreadOpenCameraInterface\");\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/common/PlatformSupportManager.java",
    "content": "/*\n * Copyright (C) 2012 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.common;\n\nimport android.os.Build;\nimport android.util.Log;\n\nimport java.lang.reflect.InvocationTargetException;\nimport java.util.Collections;\nimport java.util.SortedMap;\nimport java.util.TreeMap;\n\n/**\n * <p>Sometimes the application wants to access advanced functionality exposed by Android APIs that are only available\n * in later versions of the platform. While {@code Build.VERSION} can be used to determine the device's API level\n * and alter behavior accordingly, and it is possible to write code that uses both old and new APIs selectively,\n * such code would fail to load on older devices that do not have the new API methods.</p>\n *\n * <p>It is necessary to only load classes that use newer APIs than the device may support after the app\n * has checked the API level. This requires reflection, loading one of several implementations based on the\n * API level.</p>\n *\n * <p>This class manages that process. Subclasses of this class manage access to implementations of a given interface\n * in an API-level-aware way. Subclasses implementation classes <em>by name</em>, and the minimum API level that\n * the implementation is compatible with. They also provide a default implementation.</p>\n *\n * <p>At runtime an appropriate implementation is then chosen, instantiated and returned from {@link #build()}.</p>\n *\n * @param <T> the interface which managed implementations implement\n */\npublic abstract class PlatformSupportManager<T> {\n  \n  private static final String TAG = PlatformSupportManager.class.getSimpleName();\n\n  private final Class<T> managedInterface;\n  private final T defaultImplementation;\n  private final SortedMap<Integer,String> implementations;\n  \n  protected PlatformSupportManager(Class<T> managedInterface, T defaultImplementation) {\n    if (!managedInterface.isInterface()) {\n      throw new IllegalArgumentException();\n    }\n    if (!managedInterface.isInstance(defaultImplementation)) {\n      throw new IllegalArgumentException();\n    }\n    this.managedInterface = managedInterface;\n    this.defaultImplementation = defaultImplementation;\n    this.implementations = new TreeMap<Integer,String>(Collections.reverseOrder());\n  }\n  \n  protected void addImplementationClass(int minVersion, String className) {\n    implementations.put(minVersion, className);\n  }\n\n  public T build() {\n    for (Integer minVersion : implementations.keySet()) {\n      if (Build.VERSION.SDK_INT >= minVersion) {\n        String className = implementations.get(minVersion);\n        try {\n          Class<? extends T> clazz = Class.forName(className).asSubclass(managedInterface);\n          Log.i(TAG, \"Using implementation \" + clazz + \" of \" + managedInterface + \" for SDK \" + minVersion);\n          return clazz.getConstructor().newInstance();\n        } catch (ClassNotFoundException cnfe) {\n          Log.w(TAG, cnfe);\n        } catch (IllegalAccessException iae) {\n          Log.w(TAG, iae);\n        } catch (InstantiationException ie) {\n          Log.w(TAG, ie);\n        } catch (NoSuchMethodException nsme) {\n          Log.w(TAG, nsme);\n        } catch (InvocationTargetException ite) {\n          Log.w(TAG, ite);\n        }\n      }\n    }\n    Log.i(TAG, \"Using default implementation \" + defaultImplementation.getClass() + \" of \" + managedInterface);\n    return defaultImplementation;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/common/executor/AsyncTaskExecInterface.java",
    "content": "/*\n * Copyright (C) 2012 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.common.executor;\n\nimport android.os.AsyncTask;\n\npublic interface AsyncTaskExecInterface {\n\n  <T> void execute(AsyncTask<T,?,?> task, T... args);\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/common/executor/AsyncTaskExecManager.java",
    "content": "/*\n * Copyright (C) 2012 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.common.executor;\n\nimport com.google.zxing.client.android.common.PlatformSupportManager;\n\npublic final class AsyncTaskExecManager extends PlatformSupportManager<AsyncTaskExecInterface> {\n\n  public AsyncTaskExecManager() {\n    super(AsyncTaskExecInterface.class, new DefaultAsyncTaskExecInterface());\n    addImplementationClass(11, \"com.google.zxing.client.android.common.executor.HoneycombAsyncTaskExecInterface\");\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/common/executor/DefaultAsyncTaskExecInterface.java",
    "content": "/*\n * Copyright (C) 2012 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.common.executor;\n\nimport android.os.AsyncTask;\n\n/**\n * Before Honeycomb, {@link AsyncTask} uses parallel execution by default, which is desired. Good thing\n * too since there is no API to request otherwise.\n */\npublic final class DefaultAsyncTaskExecInterface implements AsyncTaskExecInterface {\n\n  @Override\n  public <T> void execute(AsyncTask<T,?,?> task, T... args) {\n    task.execute(args);\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/common/executor/HoneycombAsyncTaskExecInterface.java",
    "content": "/*\n * Copyright (C) 2012 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.common.executor;\n\nimport android.annotation.TargetApi;\nimport android.os.AsyncTask;\n\n/**\n * On Honeycomb and later, {@link AsyncTask} returns to serial execution by default which is undesirable.\n * This calls Honeycomb-only APIs to request parallel execution.\n */\n@TargetApi(11)\npublic final class HoneycombAsyncTaskExecInterface implements AsyncTaskExecInterface {\n\n  @Override\n  public <T> void execute(AsyncTask<T,?,?> task, T... args) {\n    task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, args);\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/encode/ContactEncoder.java",
    "content": "/*\n * Copyright (C) 2011 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.encode;\n\nimport java.util.Collection;\nimport java.util.HashSet;\n\n/**\n * Implementations encode according to some scheme for encoding contact information, like VCard or\n * MECARD.\n *\n * @author Sean Owen\n */\nabstract class ContactEncoder {\n\n  /**\n   * @return first, the best effort encoding of all data in the appropriate format; second, a\n   *   display-appropriate version of the contact information\n   */\n  abstract String[] encode(Iterable<String> names,\n                           String organization,\n                           Iterable<String> addresses,\n                           Iterable<String> phones,\n                           Iterable<String> emails,\n                           String url,\n                           String note);\n\n  /**\n   * @return null if s is null or empty, or result of s.trim() otherwise\n   */\n  static String trim(String s) {\n    if (s == null) {\n      return null;\n    }\n    String result = s.trim();\n    return result.length() == 0 ? null : result;\n  }\n\n  static void doAppend(StringBuilder newContents,\n                             StringBuilder newDisplayContents,\n                             String prefix,\n                             String value,\n                             Formatter fieldFormatter,\n                             char terminator) {\n    String trimmed = trim(value);\n    if (trimmed != null) {\n      newContents.append(prefix).append(':').append(fieldFormatter.format(trimmed)).append(terminator);\n      newDisplayContents.append(trimmed).append('\\n');\n    }\n  }\n\n  static void doAppendUpToUnique(StringBuilder newContents,\n                                 StringBuilder newDisplayContents,\n                                 String prefix,\n                                 Iterable<String> values,\n                                 int max,\n                                 Formatter formatter,\n                                 Formatter fieldFormatter,\n                                 char terminator) {\n    if (values == null) {\n      return;\n    }\n    int count = 0;\n    Collection<String> uniques = new HashSet<String>(2);\n    for (String value : values) {\n      String trimmed = trim(value);\n      if (trimmed != null && !uniques.contains(trimmed)) {\n        newContents.append(prefix).append(':').append(fieldFormatter.format(trimmed)).append(terminator);\n        String display = formatter == null ? trimmed : formatter.format(trimmed);\n        newDisplayContents.append(display).append('\\n');\n        if (++count == max) {\n          break;\n        }\n        uniques.add(trimmed);\n      }\n    }\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/encode/EncodeActivity.java",
    "content": "/*\n * Copyright (C) 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.encode;\n\nimport android.view.Display;\nimport android.view.MenuInflater;\nimport android.view.WindowManager;\nimport com.google.zxing.WriterException;\nimport com.google.zxing.client.android.Contents;\nimport com.google.zxing.client.android.FinishListener;\nimport com.google.zxing.client.android.Intents;\nimport com.google.zxing.client.android.R;\n\nimport android.app.Activity;\nimport android.app.AlertDialog;\nimport android.content.Intent;\nimport android.graphics.Bitmap;\nimport android.net.Uri;\nimport android.os.Bundle;\nimport android.os.Environment;\nimport android.util.Log;\nimport android.view.Menu;\nimport android.view.MenuItem;\nimport android.widget.ImageView;\nimport android.widget.TextView;\nimport com.google.zxing.FakeR;\n\nimport java.io.File;\nimport java.io.FileNotFoundException;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.util.regex.Pattern;\n\n/**\n * This class encodes data from an Intent into a QR code, and then displays it full screen so that\n * another person can scan it with their device.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n */\npublic final class EncodeActivity extends Activity {\n\n  private static final String TAG = EncodeActivity.class.getSimpleName();\n\n  private static final int MAX_BARCODE_FILENAME_LENGTH = 24;\n  private static final Pattern NOT_ALPHANUMERIC = Pattern.compile(\"[^A-Za-z0-9]\");\n  private static final String USE_VCARD_KEY = \"USE_VCARD\";\n\n  private QRCodeEncoder qrCodeEncoder;\n\n  private static FakeR fakeR;\n  @Override\n  public void onCreate(Bundle icicle) {\n    super.onCreate(icicle);\n    fakeR = new FakeR(this);\n    Intent intent = getIntent();\n    if (intent == null) {\n      finish();\n    } else {\n//      String action = intent.getAction();\n//      if (Intents.Encode.ACTION.equals(action) || Intent.ACTION_SEND.equals(action)) {\n        setContentView(fakeR.getId(\"layout\", \"encode\"));\n//      } else {\n//        finish();\n//      }\n    }\n  }\n\n  @Override\n  public boolean onCreateOptionsMenu(Menu menu) {\n    MenuInflater menuInflater = getMenuInflater();\n    menuInflater.inflate(fakeR.getId(\"menu\", \"encode\"), menu);\n    boolean useVcard = qrCodeEncoder != null && qrCodeEncoder.isUseVCard();\n    int encodeNameResource = useVcard ? fakeR.getId(\"string\", \"menu_encode_mecard\") : fakeR.getId(\"string\", \"menu_encode_vcard\");\n    MenuItem encodeItem = menu.findItem(fakeR.getId(\"id\", \"menu_encode\"));\n    encodeItem.setTitle(encodeNameResource);\n    Intent intent = getIntent();\n    if (intent != null) {\n      String type = intent.getStringExtra(Intents.Encode.TYPE);\n      encodeItem.setVisible(Contents.Type.CONTACT.equals(type));\n    }\n    return super.onCreateOptionsMenu(menu);\n  }\n\n  @Override\n  public boolean onOptionsItemSelected(MenuItem item) {\n    int itemId = item.getItemId();\n    if (itemId == fakeR.getId(\"id\", \"menu_share\")) {\n        share();\n        return true;\n    } else if (itemId == fakeR.getId(\"id\", \"menu_encode\")) {\n        Intent intent = getIntent();\n        if (intent == null) {\n          return false;\n        }\n        intent.putExtra(USE_VCARD_KEY, !qrCodeEncoder.isUseVCard());\n        startActivity(intent);\n        finish();\n        return true;\n    } else {\n        return false;\n    }\n  }\n  \n  private void share() {\n    QRCodeEncoder encoder = qrCodeEncoder;\n    if (encoder == null) { // Odd\n      Log.w(TAG, \"No existing barcode to send?\");\n      return;\n    }\n\n    String contents = encoder.getContents();\n    if (contents == null) {\n      Log.w(TAG, \"No existing barcode to send?\");\n      return;\n    }\n\n    Bitmap bitmap;\n    try {\n      bitmap = encoder.encodeAsBitmap();\n    } catch (WriterException we) {\n      Log.w(TAG, we);\n      return;\n    }\n    if (bitmap == null) {\n      return;\n    }\n\n    File bsRoot = new File(Environment.getExternalStorageDirectory(), \"BarcodeScanner\");\n    File barcodesRoot = new File(bsRoot, \"Barcodes\");\n    if (!barcodesRoot.exists() && !barcodesRoot.mkdirs()) {\n      Log.w(TAG, \"Couldn't make dir \" + barcodesRoot);\n      showErrorMessage(fakeR.getId(\"string\", \"msg_unmount_usb\"));\n      return;\n    }\n    File barcodeFile = new File(barcodesRoot, makeBarcodeFileName(contents) + \".png\");\n    barcodeFile.delete();\n    FileOutputStream fos = null;\n    try {\n      fos = new FileOutputStream(barcodeFile);\n      bitmap.compress(Bitmap.CompressFormat.PNG, 0, fos);\n    } catch (FileNotFoundException fnfe) {\n      Log.w(TAG, \"Couldn't access file \" + barcodeFile + \" due to \" + fnfe);\n      showErrorMessage(fakeR.getId(\"string\", \"msg_unmount_usb\"));\n      return;\n    } finally {\n      if (fos != null) {\n        try {\n          fos.close();\n        } catch (IOException ioe) {\n          // do nothing\n        }\n      }\n    }\n\n    Intent intent = new Intent(Intent.ACTION_SEND, Uri.parse(\"mailto:\"));\n    intent.putExtra(Intent.EXTRA_SUBJECT, getString(fakeR.getId(\"string\", \"app_name\")) + \" - \" + encoder.getTitle());\n    intent.putExtra(Intent.EXTRA_TEXT, contents);\n    intent.putExtra(Intent.EXTRA_STREAM, Uri.parse(\"file://\" + barcodeFile.getAbsolutePath()));\n    intent.setType(\"image/png\");\n    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);\n    startActivity(Intent.createChooser(intent, null));\n  }\n\n  private static CharSequence makeBarcodeFileName(CharSequence contents) {\n    String fileName = NOT_ALPHANUMERIC.matcher(contents).replaceAll(\"_\");\n    if (fileName.length() > MAX_BARCODE_FILENAME_LENGTH) {\n      fileName = fileName.substring(0, MAX_BARCODE_FILENAME_LENGTH);\n    }\n    return fileName;\n  }\n\n  @Override\n  protected void onResume() {\n    super.onResume();\n    // This assumes the view is full screen, which is a good assumption\n    WindowManager manager = (WindowManager) getSystemService(WINDOW_SERVICE);\n    Display display = manager.getDefaultDisplay();\n    int width = display.getWidth();\n    int height = display.getHeight();\n    int smallerDimension = width < height ? width : height;\n    smallerDimension = smallerDimension * 7 / 8;\n\n    Intent intent = getIntent();\n    if (intent == null) {\n      return;\n    }\n\n    try {\n      boolean useVCard = intent.getBooleanExtra(USE_VCARD_KEY, false);\n      qrCodeEncoder = new QRCodeEncoder(this, intent, smallerDimension, useVCard);\n      Bitmap bitmap = qrCodeEncoder.encodeAsBitmap();\n      if (bitmap == null) {\n        Log.w(TAG, \"Could not encode barcode\");\n        showErrorMessage(fakeR.getId(\"string\", \"msg_encode_contents_failed\"));\n        qrCodeEncoder = null;\n        return;\n      }\n\n      ImageView view = (ImageView) findViewById(fakeR.getId(\"id\", \"image_view\"));\n      view.setImageBitmap(bitmap);\n\n      TextView contents = (TextView) findViewById(fakeR.getId(\"id\", \"contents_text_view\"));\n      if (intent.getBooleanExtra(Intents.Encode.SHOW_CONTENTS, true)) {\n        contents.setText(qrCodeEncoder.getDisplayContents());\n        setTitle(qrCodeEncoder.getTitle());\n      } else {\n        contents.setText(\"\");\n        setTitle(\"\");\n      }\n    } catch (WriterException e) {\n      Log.w(TAG, \"Could not encode barcode\", e);\n      showErrorMessage(fakeR.getId(\"string\", \"msg_encode_contents_failed\"));\n      qrCodeEncoder = null;\n    }\n  }\n\n  private void showErrorMessage(int message) {\n    AlertDialog.Builder builder = new AlertDialog.Builder(this);\n    builder.setMessage(message);\n    builder.setPositiveButton(fakeR.getId(\"string\", \"button_ok\"), new FinishListener(this));\n    builder.setOnCancelListener(new FinishListener(this));\n    builder.show();\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/encode/Formatter.java",
    "content": "/*\n * Copyright (C) 2011 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.encode;\n\n/**\n * Encapsulates some simple formatting logic, to aid refactoring in {@link ContactEncoder}.\n *\n * @author Sean Owen\n */\ninterface Formatter {\n  \n  String format(String source);\n  \n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/encode/MECARDContactEncoder.java",
    "content": "/*\n * Copyright (C) 2011 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.encode;\n\nimport android.telephony.PhoneNumberUtils;\n\nimport java.util.regex.Pattern;\n\n/**\n * Encodes contact information according to the MECARD format.\n *\n * @author Sean Owen\n */\nfinal class MECARDContactEncoder extends ContactEncoder {\n\n  private static final Pattern RESERVED_MECARD_CHARS = Pattern.compile(\"([\\\\\\\\:;])\");\n  private static final Pattern NEWLINE = Pattern.compile(\"\\\\n\");\n  private static final Pattern COMMA = Pattern.compile(\",\");\n  private static final Formatter MECARD_FIELD_FORMATTER = new Formatter() {\n    @Override\n    public String format(String source) {\n      return NEWLINE.matcher(RESERVED_MECARD_CHARS.matcher(source).replaceAll(\"\\\\\\\\$1\")).replaceAll(\"\");\n    }\n  };\n  private static final char TERMINATOR = ';';\n\n  @Override\n  public String[] encode(Iterable<String> names,\n                         String organization,\n                         Iterable<String> addresses,\n                         Iterable<String> phones,\n                         Iterable<String> emails,\n                         String url,\n                         String note) {\n    StringBuilder newContents = new StringBuilder(100);\n    StringBuilder newDisplayContents = new StringBuilder(100);\n    newContents.append(\"MECARD:\");\n    appendUpToUnique(newContents, newDisplayContents, \"N\", names, 1, new Formatter() {\n      @Override\n      public String format(String source) {\n        return source == null ? null : COMMA.matcher(source).replaceAll(\"\");\n      }\n    });\n    append(newContents, newDisplayContents, \"ORG\", organization);\n    appendUpToUnique(newContents, newDisplayContents, \"ADR\", addresses, 1, null);\n    appendUpToUnique(newContents, newDisplayContents, \"TEL\", phones, Integer.MAX_VALUE, new Formatter() {\n      @Override\n      public String format(String source) {\n        return PhoneNumberUtils.formatNumber(source);\n      }\n    });\n    appendUpToUnique(newContents, newDisplayContents, \"EMAIL\", emails, Integer.MAX_VALUE, null);\n    append(newContents, newDisplayContents, \"URL\", url);\n    append(newContents, newDisplayContents, \"NOTE\", note);\n    newContents.append(';');\n    return new String[] { newContents.toString(), newDisplayContents.toString() };\n  }\n  \n  private static void append(StringBuilder newContents, \n                             StringBuilder newDisplayContents,\n                             String prefix, \n                             String value) {\n    doAppend(newContents, newDisplayContents, prefix, value, MECARD_FIELD_FORMATTER, TERMINATOR);\n  }\n  \n  private static void appendUpToUnique(StringBuilder newContents, \n                                       StringBuilder newDisplayContents,\n                                       String prefix, \n                                       Iterable<String> values, \n                                       int max,\n                                       Formatter formatter) {\n    doAppendUpToUnique(newContents,\n                       newDisplayContents,\n                       prefix,\n                       values,\n                       max,\n                       formatter,\n                       MECARD_FIELD_FORMATTER,\n                       TERMINATOR);\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/encode/QRCodeEncoder.java",
    "content": "/*\n * Copyright (C) 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.encode;\n\nimport android.provider.ContactsContract;\nimport com.google.zxing.BarcodeFormat;\nimport com.google.zxing.EncodeHintType;\nimport com.google.zxing.MultiFormatWriter;\nimport com.google.zxing.Result;\nimport com.google.zxing.WriterException;\nimport com.google.zxing.client.android.Contents;\nimport com.google.zxing.client.android.Intents;\nimport com.google.zxing.client.android.R;\nimport com.google.zxing.client.result.AddressBookParsedResult;\nimport com.google.zxing.client.result.ParsedResult;\nimport com.google.zxing.client.result.ResultParser;\nimport com.google.zxing.common.BitMatrix;\n\nimport android.app.Activity;\nimport android.content.Intent;\nimport android.graphics.Bitmap;\nimport android.net.Uri;\nimport android.os.Bundle;\nimport android.telephony.PhoneNumberUtils;\nimport android.util.Log;\nimport com.google.zxing.FakeR;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.EnumMap;\nimport java.util.Map;\n\n/**\n * This class does the work of decoding the user's request and extracting all the data\n * to be encoded in a barcode.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n */\nfinal class QRCodeEncoder {\n\n  private static final String TAG = QRCodeEncoder.class.getSimpleName();\n\n  private static final int WHITE = 0xFFFFFFFF;\n  private static final int BLACK = 0xFF000000;\n\n  private final Activity activity;\n  private String contents;\n  private String displayContents;\n  private String title;\n  private BarcodeFormat format;\n  private final int dimension;\n  private final boolean useVCard;\n\n  private static FakeR fakeR;\n  QRCodeEncoder(Activity activity, Intent intent, int dimension, boolean useVCard) throws WriterException {\n    fakeR = new FakeR(activity);\n    this.activity = activity;\n    this.dimension = dimension;\n    this.useVCard = useVCard;\n    String action = intent.getAction();\n    //if (action.equals(Intents.Encode.ACTION)) {\n      encodeContentsFromZXingIntent(intent);\n    //} else if (action.equals(Intent.ACTION_SEND)) {\n    //  encodeContentsFromShareIntent(intent);\n    //}\n  }\n\n  String getContents() {\n    return contents;\n  }\n\n  String getDisplayContents() {\n    return displayContents;\n  }\n\n  String getTitle() {\n    return title;\n  }\n\n  boolean isUseVCard() {\n    return useVCard;\n  }\n\n  // It would be nice if the string encoding lived in the core ZXing library,\n  // but we use platform specific code like PhoneNumberUtils, so it can't.\n  private boolean encodeContentsFromZXingIntent(Intent intent) {\n     // Default to QR_CODE if no format given.\n    String formatString = intent.getStringExtra(Intents.Encode.FORMAT);\n    format = null;\n    if (formatString != null) {\n      try {\n        format = BarcodeFormat.valueOf(formatString);\n      } catch (IllegalArgumentException iae) {\n        // Ignore it then\n      }\n    }\n    if (format == null || format == BarcodeFormat.QR_CODE) {\n      String type = intent.getStringExtra(Intents.Encode.TYPE);\n      if (type == null || type.length() == 0) {\n        return false;\n      }\n      this.format = BarcodeFormat.QR_CODE;\n      encodeQRCodeContents(intent, type);\n    } else {\n      String data = intent.getStringExtra(Intents.Encode.DATA);\n      if (data != null && data.length() > 0) {\n        contents = data;\n        displayContents = data;\n        title = activity.getString(fakeR.getId(\"string\", \"contents_text\"));\n      }\n    }\n    return contents != null && contents.length() > 0;\n  }\n\n  // Handles send intents from multitude of Android applications\n  private void encodeContentsFromShareIntent(Intent intent) throws WriterException {\n    // Check if this is a plain text encoding, or contact\n    if (intent.hasExtra(Intent.EXTRA_STREAM)) {\n      encodeFromStreamExtra(intent);\n    } else {\n      encodeFromTextExtras(intent);\n    }\n  }\n\n  private void encodeFromTextExtras(Intent intent) throws WriterException {\n    // Notice: Google Maps shares both URL and details in one text, bummer!\n    String theContents = ContactEncoder.trim(intent.getStringExtra(Intent.EXTRA_TEXT));\n    if (theContents == null) {\n      theContents = ContactEncoder.trim(intent.getStringExtra(\"android.intent.extra.HTML_TEXT\"));\n      // Intent.EXTRA_HTML_TEXT\n      if (theContents == null) {\n        theContents = ContactEncoder.trim(intent.getStringExtra(Intent.EXTRA_SUBJECT));\n        if (theContents == null) {\n          String[] emails = intent.getStringArrayExtra(Intent.EXTRA_EMAIL);\n          if (emails != null) {\n            theContents = ContactEncoder.trim(emails[0]);\n          } else {\n            theContents = \"?\";\n          }\n        }\n      }\n    }\n\n    // Trim text to avoid URL breaking.\n    if (theContents == null || theContents.length() == 0) {\n      throw new WriterException(\"Empty EXTRA_TEXT\");\n    }\n    contents = theContents;\n    // We only do QR code.\n    format = BarcodeFormat.QR_CODE;\n    if (intent.hasExtra(Intent.EXTRA_SUBJECT)) {\n      displayContents = intent.getStringExtra(Intent.EXTRA_SUBJECT);\n    } else if (intent.hasExtra(Intent.EXTRA_TITLE)) {\n      displayContents = intent.getStringExtra(Intent.EXTRA_TITLE);\n    } else {\n      displayContents = contents;\n    }\n    title = activity.getString(fakeR.getId(\"string\", \"contents_text\"));\n  }\n\n  // Handles send intents from the Contacts app, retrieving a contact as a VCARD.\n  private void encodeFromStreamExtra(Intent intent) throws WriterException {\n    format = BarcodeFormat.QR_CODE;\n    Bundle bundle = intent.getExtras();\n    if (bundle == null) {\n      throw new WriterException(\"No extras\");\n    }\n    Uri uri = (Uri) bundle.getParcelable(Intent.EXTRA_STREAM);\n    if (uri == null) {\n      throw new WriterException(\"No EXTRA_STREAM\");\n    }\n    byte[] vcard;\n    String vcardString;\n    try {\n      InputStream stream = activity.getContentResolver().openInputStream(uri);\n      ByteArrayOutputStream baos = new ByteArrayOutputStream();\n      byte[] buffer = new byte[2048];\n      int bytesRead;\n      while ((bytesRead = stream.read(buffer)) > 0) {\n        baos.write(buffer, 0, bytesRead);\n      }\n      vcard = baos.toByteArray();\n      vcardString = new String(vcard, 0, vcard.length, \"UTF-8\");\n    } catch (IOException ioe) {\n      throw new WriterException(ioe);\n    }\n    Log.d(TAG, \"Encoding share intent content:\");\n    Log.d(TAG, vcardString);\n    Result result = new Result(vcardString, vcard, null, BarcodeFormat.QR_CODE);\n    ParsedResult parsedResult = ResultParser.parseResult(result);\n    if (!(parsedResult instanceof AddressBookParsedResult)) {\n      throw new WriterException(\"Result was not an address\");\n    }\n    encodeQRCodeContents((AddressBookParsedResult) parsedResult);\n    if (contents == null || contents.length() == 0) {\n      throw new WriterException(\"No content to encode\");\n    }\n  }\n\n  private void encodeQRCodeContents(Intent intent, String type) {\n    if (type.equals(Contents.Type.TEXT)) {\n      String data = intent.getStringExtra(Intents.Encode.DATA);\n      if (data != null && data.length() > 0) {\n        contents = data;\n        displayContents = data;\n        title = activity.getString(fakeR.getId(\"string\", \"contents_text\"));\n      }\n    } else if (type.equals(Contents.Type.EMAIL)) {\n      String data = ContactEncoder.trim(intent.getStringExtra(Intents.Encode.DATA));\n      if (data != null) {\n        contents = \"mailto:\" + data;\n        displayContents = data;\n        title = activity.getString(fakeR.getId(\"string\", \"contents_email\"));\n      }\n    } else if (type.equals(Contents.Type.PHONE)) {\n      String data = ContactEncoder.trim(intent.getStringExtra(Intents.Encode.DATA));\n      if (data != null) {\n        contents = \"tel:\" + data;\n        displayContents = PhoneNumberUtils.formatNumber(data);\n        title = activity.getString(fakeR.getId(\"string\", \"contents_phone\"));\n      }\n    } else if (type.equals(Contents.Type.SMS)) {\n      String data = ContactEncoder.trim(intent.getStringExtra(Intents.Encode.DATA));\n      if (data != null) {\n        contents = \"sms:\" + data;\n        displayContents = PhoneNumberUtils.formatNumber(data);\n        title = activity.getString(fakeR.getId(\"string\", \"contents_sms\"));\n      }\n    } else if (type.equals(Contents.Type.CONTACT)) {\n\n      Bundle bundle = intent.getBundleExtra(Intents.Encode.DATA);\n      if (bundle != null) {\n\n        String name = bundle.getString(ContactsContract.Intents.Insert.NAME);\n        String organization = bundle.getString(ContactsContract.Intents.Insert.COMPANY);\n        String address = bundle.getString(ContactsContract.Intents.Insert.POSTAL);\n        Collection<String> phones = new ArrayList<String>(Contents.PHONE_KEYS.length);\n        for (int x = 0; x < Contents.PHONE_KEYS.length; x++) {\n          phones.add(bundle.getString(Contents.PHONE_KEYS[x]));\n        }\n        Collection<String> emails = new ArrayList<String>(Contents.EMAIL_KEYS.length);\n        for (int x = 0; x < Contents.EMAIL_KEYS.length; x++) {\n          emails.add(bundle.getString(Contents.EMAIL_KEYS[x]));\n        }\n        String url = bundle.getString(Contents.URL_KEY);\n        String note = bundle.getString(Contents.NOTE_KEY);\n\n        ContactEncoder mecardEncoder = useVCard ? new VCardContactEncoder() : new MECARDContactEncoder();\n        String[] encoded = mecardEncoder.encode(Collections.singleton(name),\n                                                organization,\n                                                Collections.singleton(address),\n                                                phones,\n                                                emails,\n                                                url,\n                                                note);\n        // Make sure we've encoded at least one field.\n        if (encoded[1].length() > 0) {\n          contents = encoded[0];\n          displayContents = encoded[1];\n          title = activity.getString(fakeR.getId(\"string\", \"contents_contact\"));\n        }\n\n      }\n\n    } else if (type.equals(Contents.Type.LOCATION)) {\n      Bundle bundle = intent.getBundleExtra(Intents.Encode.DATA);\n      if (bundle != null) {\n        // These must use Bundle.getFloat(), not getDouble(), it's part of the API.\n        float latitude = bundle.getFloat(\"LAT\", Float.MAX_VALUE);\n        float longitude = bundle.getFloat(\"LONG\", Float.MAX_VALUE);\n        if (latitude != Float.MAX_VALUE && longitude != Float.MAX_VALUE) {\n          contents = \"geo:\" + latitude + ',' + longitude;\n          displayContents = latitude + \",\" + longitude;\n          title = activity.getString(fakeR.getId(\"string\", \"contents_location\"));\n        }\n      }\n    }\n  }\n\n  private void encodeQRCodeContents(AddressBookParsedResult contact) {\n    ContactEncoder encoder = useVCard ? new VCardContactEncoder() : new MECARDContactEncoder();\n    String[] encoded = encoder.encode(toIterable(contact.getNames()),\n                                      contact.getOrg(),\n                                      toIterable(contact.getAddresses()),\n                                      toIterable(contact.getPhoneNumbers()),\n                                      toIterable(contact.getEmails()),\n                                      contact.getURL(),\n                                      null);\n    // Make sure we've encoded at least one field.\n    if (encoded[1].length() > 0) {\n      contents = encoded[0];\n      displayContents = encoded[1];\n      title = activity.getString(fakeR.getId(\"string\", \"contents_contact\"));\n    }\n  }\n\n  private static Iterable<String> toIterable(String[] values) {\n    return values == null ? null : Arrays.asList(values);\n  }\n\n  Bitmap encodeAsBitmap() throws WriterException {\n    String contentsToEncode = contents;\n    if (contentsToEncode == null) {\n      return null;\n    }\n    Map<EncodeHintType,Object> hints = null;\n    String encoding = guessAppropriateEncoding(contentsToEncode);\n    if (encoding != null) {\n      hints = new EnumMap<EncodeHintType,Object>(EncodeHintType.class);\n      hints.put(EncodeHintType.CHARACTER_SET, encoding);\n    }\n    MultiFormatWriter writer = new MultiFormatWriter();\n    BitMatrix result;\n    try {\n      result = writer.encode(contentsToEncode, format, dimension, dimension, hints);\n    } catch (IllegalArgumentException iae) {\n      // Unsupported format\n      return null;\n    }\n    int width = result.getWidth();\n    int height = result.getHeight();\n    int[] pixels = new int[width * height];\n    for (int y = 0; y < height; y++) {\n      int offset = y * width;\n      for (int x = 0; x < width; x++) {\n        pixels[offset + x] = result.get(x, y) ? BLACK : WHITE;\n      }\n    }\n\n    Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);\n    bitmap.setPixels(pixels, 0, width, 0, 0, width, height);\n    return bitmap;\n  }\n\n  private static String guessAppropriateEncoding(CharSequence contents) {\n    // Very crude at the moment\n    for (int i = 0; i < contents.length(); i++) {\n      if (contents.charAt(i) > 0xFF) {\n        return \"UTF-8\";\n      }\n    }\n    return null;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/encode/VCardContactEncoder.java",
    "content": "/*\n * Copyright (C) 2011 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.encode;\n\nimport android.telephony.PhoneNumberUtils;\n\nimport java.util.regex.Pattern;\n\n/**\n * Encodes contact information according to the vCard format.\n *\n * @author Sean Owen\n */\nfinal class VCardContactEncoder extends ContactEncoder {\n\n  private static final Pattern RESERVED_VCARD_CHARS = Pattern.compile(\"([\\\\\\\\,;])\");\n  private static final Pattern NEWLINE = Pattern.compile(\"\\\\n\");\n  private static final Formatter VCARD_FIELD_FORMATTER = new Formatter() {\n    @Override\n    public String format(String source) {\n      return NEWLINE.matcher(RESERVED_VCARD_CHARS.matcher(source).replaceAll(\"\\\\\\\\$1\")).replaceAll(\"\");\n    }\n  };\n  private static final char TERMINATOR = '\\n';\n\n  @Override\n  public String[] encode(Iterable<String> names,\n                         String organization,\n                         Iterable<String> addresses,\n                         Iterable<String> phones,\n                         Iterable<String> emails,\n                         String url,\n                         String note) {\n    StringBuilder newContents = new StringBuilder(100);\n    StringBuilder newDisplayContents = new StringBuilder(100);\n    newContents.append(\"BEGIN:VCARD\").append(TERMINATOR);\n    appendUpToUnique(newContents, newDisplayContents, \"N\", names, 1, null);\n    append(newContents, newDisplayContents, \"ORG\", organization);\n    appendUpToUnique(newContents, newDisplayContents, \"ADR\", addresses, 1, null);\n    appendUpToUnique(newContents, newDisplayContents, \"TEL\", phones, Integer.MAX_VALUE, new Formatter() {\n      @Override\n      public String format(String source) {\n        return PhoneNumberUtils.formatNumber(source);\n      }\n    });\n    appendUpToUnique(newContents, newDisplayContents, \"EMAIL\", emails, Integer.MAX_VALUE, null);\n    append(newContents, newDisplayContents, \"URL\", url);\n    append(newContents, newDisplayContents, \"NOTE\", note);\n    newContents.append(\"END:VCARD\").append(TERMINATOR);\n    return new String[] { newContents.toString(), newDisplayContents.toString() };\n  }\n  \n  private static void append(StringBuilder newContents, \n                             StringBuilder newDisplayContents,\n                             String prefix, \n                             String value) {\n    doAppend(newContents, newDisplayContents, prefix, value, VCARD_FIELD_FORMATTER, TERMINATOR);\n  }\n  \n  private static void appendUpToUnique(StringBuilder newContents, \n                                       StringBuilder newDisplayContents,\n                                       String prefix, \n                                       Iterable<String> values, \n                                       int max,\n                                       Formatter formatter) {\n    doAppendUpToUnique(newContents,\n                       newDisplayContents,\n                       prefix,\n                       values,\n                       max,\n                       formatter,\n                       VCARD_FIELD_FORMATTER,\n                       TERMINATOR);\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/history/DBHelper.java",
    "content": "/*\n * Copyright (C) 2009 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.history;\n\nimport android.database.sqlite.SQLiteOpenHelper;\nimport android.database.sqlite.SQLiteDatabase;\nimport android.content.Context;\n\n/**\n * @author Sean Owen\n */\nfinal class DBHelper extends SQLiteOpenHelper {\n\n  private static final int DB_VERSION = 5;\n  private static final String DB_NAME = \"barcode_scanner_history.db\";\n  static final String TABLE_NAME = \"history\";\n  static final String ID_COL = \"id\";\n  static final String TEXT_COL = \"text\";\n  static final String FORMAT_COL = \"format\";\n  static final String DISPLAY_COL = \"display\";\n  static final String TIMESTAMP_COL = \"timestamp\";\n  static final String DETAILS_COL = \"details\";\n\n  DBHelper(Context context) {\n    super(context, DB_NAME, null, DB_VERSION);\n  }\n\n  @Override\n  public void onCreate(SQLiteDatabase sqLiteDatabase) {\n    sqLiteDatabase.execSQL(\n            \"CREATE TABLE \" + TABLE_NAME + \" (\" +\n            ID_COL + \" INTEGER PRIMARY KEY, \" +\n            TEXT_COL + \" TEXT, \" +\n            FORMAT_COL + \" TEXT, \" +\n            DISPLAY_COL + \" TEXT, \" +\n            TIMESTAMP_COL + \" INTEGER, \" +\n            DETAILS_COL + \" TEXT);\");\n  }\n\n  @Override\n  public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {\n    sqLiteDatabase.execSQL(\"DROP TABLE IF EXISTS \" + TABLE_NAME);\n    onCreate(sqLiteDatabase);\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/history/HistoryActivity.java",
    "content": "/*\n * Copyright 2012 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.history;\n\nimport android.app.Activity;\nimport android.app.AlertDialog;\nimport android.app.ListActivity;\nimport android.content.ActivityNotFoundException;\nimport android.content.DialogInterface;\nimport android.content.Intent;\nimport android.net.Uri;\nimport android.os.Bundle;\nimport android.util.Log;\nimport android.view.ContextMenu;\nimport android.view.Menu;\nimport android.view.MenuInflater;\nimport android.view.MenuItem;\nimport android.view.View;\nimport android.widget.AdapterView;\nimport android.widget.ListView;\nimport com.google.zxing.FakeR;\nimport com.google.zxing.client.android.CaptureActivity;\nimport com.google.zxing.client.android.Intents;\nimport com.google.zxing.client.android.R;\n\nimport java.util.List;\n\npublic final class HistoryActivity extends ListActivity {\n\n  private static final String TAG = HistoryActivity.class.getSimpleName();\n\n  private HistoryManager historyManager;\n  private HistoryItemAdapter adapter;\n  \n  private static FakeR fakeR;\n  @Override\n  protected void onCreate(Bundle icicle) {\n    super.onCreate(icicle);\n    fakeR = new FakeR(this);\n    this.historyManager = new HistoryManager(this);  \n    adapter = new HistoryItemAdapter(this);\n    setListAdapter(adapter);\n    ListView listview = getListView();\n    registerForContextMenu(listview);\n  }\n\n  @Override\n  protected void onResume() {\n    super.onResume();\n    reloadHistoryItems();\n  }\n\n  private void reloadHistoryItems() {\n    List<HistoryItem> items = historyManager.buildHistoryItems();\n    adapter.clear();\n    for (HistoryItem item : items) {\n      adapter.add(item);\n    }\n    if (adapter.isEmpty()) {\n      adapter.add(new HistoryItem(null, null, null));\n    }\n  }\n\n  @Override\n  protected void onListItemClick(ListView l, View v, int position, long id) {\n    if (adapter.getItem(position).getResult() != null) {\n      Intent intent = new Intent(this, CaptureActivity.class);\n      intent.putExtra(Intents.History.ITEM_NUMBER, position);\n      setResult(Activity.RESULT_OK, intent);\n      finish();\n    }\n  }\n\n  @Override\n  public void onCreateContextMenu(ContextMenu menu,\n                                  View v,\n                                  ContextMenu.ContextMenuInfo menuInfo) {\n    int position = ((AdapterView.AdapterContextMenuInfo) menuInfo).position;\n    if (position >= adapter.getCount() || adapter.getItem(position).getResult() != null) {\n      menu.add(Menu.NONE, position, position, fakeR.getId(\"string\", \"history_clear_one_history_text\"));\n    } // else it's just that dummy \"Empty\" message\n  }\n\n  @Override\n  public boolean onContextItemSelected(MenuItem item) {\n    int position = item.getItemId();\n    historyManager.deleteHistoryItem(position);\n    reloadHistoryItems();\n    return true;\n  }\n\n  @Override\n  public boolean onCreateOptionsMenu(Menu menu) {\n    if (historyManager.hasHistoryItems()) {\n      MenuInflater menuInflater = getMenuInflater();\n      menuInflater.inflate(fakeR.getId(\"menu\", \"history\"), menu);\n    }\n    return super.onCreateOptionsMenu(menu);\n  }\n\n  @Override\n  public boolean onOptionsItemSelected(MenuItem item) {\n    int itemId = item.getItemId();\n    if (itemId == fakeR.getId(\"id\", \"menu_history_send\")) {\n        CharSequence history = historyManager.buildHistory();\n        Uri historyFile = HistoryManager.saveHistory(history.toString());\n        if (historyFile == null) {\n          AlertDialog.Builder builder = new AlertDialog.Builder(this);\n          builder.setMessage(fakeR.getId(\"string\", \"msg_unmount_usb\"));\n          builder.setPositiveButton(fakeR.getId(\"string\", \"button_ok\"), null);\n          builder.show();\n        } else {\n          Intent intent = new Intent(Intent.ACTION_SEND, Uri.parse(\"mailto:\"));\n          intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);\n          String subject = getResources().getString(fakeR.getId(\"string\", \"history_email_title\"));\n          intent.putExtra(Intent.EXTRA_SUBJECT, subject);\n          intent.putExtra(Intent.EXTRA_TEXT, subject);\n          intent.putExtra(Intent.EXTRA_STREAM, historyFile);\n          intent.setType(\"text/csv\");\n          try {\n            startActivity(intent);\n          } catch (ActivityNotFoundException anfe) {\n            Log.w(TAG, anfe.toString());\n          }\n        }\n    } else if (itemId == fakeR.getId(\"id\", \"menu_history_clear_text\")) {\n        AlertDialog.Builder builder = new AlertDialog.Builder(this);\n        builder.setMessage(fakeR.getId(\"string\", \"msg_sure\"));\n        builder.setCancelable(true);\n        builder.setPositiveButton(fakeR.getId(\"string\", \"button_ok\"), new DialogInterface.OnClickListener() {\n          @Override\n          public void onClick(DialogInterface dialog, int i2) {\n            historyManager.clearHistory();\n            dialog.dismiss();\n            finish();\n          }\n        });\n        builder.setNegativeButton(fakeR.getId(\"string\", \"button_cancel\"), null);\n        builder.show();\n    } else {\n        return super.onOptionsItemSelected(item);\n    }\n    return true;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/history/HistoryItem.java",
    "content": "/*\n * Copyright 2012 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.history;\n\nimport com.google.zxing.Result;\n\npublic final class HistoryItem {\n\n  private final Result result;\n  private final String display;\n  private final String details;\n  \n  HistoryItem(Result result, String display, String details) {\n    this.result = result;\n    this.display = display;\n    this.details = details;\n  }\n\n  public Result getResult() {\n    return result;\n  }\n\n  public String getDisplayAndDetails() {\n    StringBuilder displayResult = new StringBuilder();\n    if (display == null || display.length() == 0) {\n      displayResult.append(result.getText());\n    } else {\n      displayResult.append(display);\n    }\n    if (details != null && details.length() > 0) {\n      displayResult.append(\" : \").append(details);\n    }\n    return displayResult.toString();\n  }\n  \n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/history/HistoryItemAdapter.java",
    "content": "/*\n * Copyright 2012 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.history;\n\nimport android.app.Activity;\nimport android.content.res.Resources;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.ArrayAdapter;\nimport android.widget.LinearLayout;\nimport android.widget.TextView;\nimport com.google.zxing.FakeR;\nimport com.google.zxing.Result;\nimport com.google.zxing.client.android.R;\n\nimport java.util.ArrayList;\n\nfinal class HistoryItemAdapter extends ArrayAdapter<HistoryItem> {\n\n  private final Activity activity;\n\n  private static FakeR fakeR;\n  HistoryItemAdapter(Activity activity) {\n    super(activity, activity.getApplicationContext().getResources().getIdentifier(\"history_list_item\", \"layout\", activity.getApplicationContext().getPackageName()), new ArrayList<HistoryItem>());\n\tfakeR = new FakeR(activity);\n    this.activity = activity;\n  }\n\n  @Override\n  public View getView(int position, View view, ViewGroup viewGroup) {\n    LinearLayout layout;\n    if (view instanceof LinearLayout) {\n      layout = (LinearLayout) view;\n    } else {\n      LayoutInflater factory = LayoutInflater.from(activity);\n      layout = (LinearLayout) factory.inflate(fakeR.getId(\"layout\", \"history_list_item\"), viewGroup, false);\n    }\n\n    HistoryItem item = getItem(position);\n    Result result = item.getResult();\n\n    String title;\n    String detail;\n    if (result != null) {\n      title = result.getText();\n      detail = item.getDisplayAndDetails();      \n    } else {\n      Resources resources = getContext().getResources();\n      title = resources.getString(fakeR.getId(\"string\", \"history_empty\"));\n      detail = resources.getString(fakeR.getId(\"string\", \"history_empty_detail\"));\n    }\n\n    ((TextView) layout.findViewById(fakeR.getId(\"id\", \"history_title\"))).setText(title);    \n    ((TextView) layout.findViewById(fakeR.getId(\"id\", \"history_detail\"))).setText(detail);\n\n    return layout;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/history/HistoryManager.java",
    "content": "/*\n * Copyright (C) 2009 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.history;\n\nimport android.database.sqlite.SQLiteException;\nimport com.google.zxing.BarcodeFormat;\nimport com.google.zxing.Result;\nimport com.google.zxing.client.android.Intents;\nimport com.google.zxing.client.android.PreferencesActivity;\nimport com.google.zxing.client.android.result.ResultHandler;\n\nimport android.app.Activity;\nimport android.content.ContentValues;\nimport android.content.SharedPreferences;\nimport android.database.Cursor;\nimport android.database.sqlite.SQLiteDatabase;\nimport android.database.sqlite.SQLiteOpenHelper;\nimport android.net.Uri;\nimport android.os.Environment;\nimport android.preference.PreferenceManager;\nimport android.util.Log;\n\nimport java.io.File;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.OutputStreamWriter;\nimport java.nio.charset.Charset;\nimport java.text.DateFormat;\nimport java.util.ArrayList;\nimport java.util.Date;\nimport java.util.List;\n\n/**\n * <p>Manages functionality related to scan history.</p>\n *\n * @author Sean Owen\n */\npublic final class HistoryManager {\n\n  private static final String TAG = HistoryManager.class.getSimpleName();\n\n  private static final int MAX_ITEMS = 500;\n\n  private static final String[] COLUMNS = {\n      DBHelper.TEXT_COL,\n      DBHelper.DISPLAY_COL,\n      DBHelper.FORMAT_COL,\n      DBHelper.TIMESTAMP_COL,\n      DBHelper.DETAILS_COL,\n  };\n\n  private static final String[] COUNT_COLUMN = { \"COUNT(1)\" };\n\n  private static final String[] ID_COL_PROJECTION = { DBHelper.ID_COL };\n  private static final String[] ID_DETAIL_COL_PROJECTION = { DBHelper.ID_COL, DBHelper.DETAILS_COL };\n  private static final DateFormat EXPORT_DATE_TIME_FORMAT =\n      DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);\n\n  private final Activity activity;\n\n  public HistoryManager(Activity activity) {\n    this.activity = activity;\n  }\n\n  public boolean hasHistoryItems() {\n    SQLiteOpenHelper helper = new DBHelper(activity);\n    SQLiteDatabase db = null;\n    Cursor cursor = null;\n    try {\n      db = helper.getReadableDatabase();\n      cursor = db.query(DBHelper.TABLE_NAME, COUNT_COLUMN, null, null, null, null, null);\n      cursor.moveToFirst();\n      return cursor.getInt(0) > 0;\n    } finally {\n      close(cursor, db);\n    }\n  }\n\n  public List<HistoryItem> buildHistoryItems() {\n    SQLiteOpenHelper helper = new DBHelper(activity);\n    List<HistoryItem> items = new ArrayList<HistoryItem>();\n    SQLiteDatabase db = null;\n    Cursor cursor = null;\n    try {\n      db = helper.getReadableDatabase();\n      cursor = db.query(DBHelper.TABLE_NAME, COLUMNS, null, null, null, null, DBHelper.TIMESTAMP_COL + \" DESC\");\n      while (cursor.moveToNext()) {\n        String text = cursor.getString(0);\n        String display = cursor.getString(1);\n        String format = cursor.getString(2);\n        long timestamp = cursor.getLong(3);\n        String details = cursor.getString(4);\n        Result result = new Result(text, null, null, BarcodeFormat.valueOf(format), timestamp);\n        items.add(new HistoryItem(result, display, details));\n      }\n    } finally {\n      close(cursor, db);\n    }\n    return items;\n  }\n\n  public HistoryItem buildHistoryItem(int number) {\n    SQLiteOpenHelper helper = new DBHelper(activity);\n    SQLiteDatabase db = null;\n    Cursor cursor = null;\n    try {\n      db = helper.getReadableDatabase();\n      cursor = db.query(DBHelper.TABLE_NAME, COLUMNS, null, null, null, null, DBHelper.TIMESTAMP_COL + \" DESC\");\n      cursor.move(number + 1);\n      String text = cursor.getString(0);\n      String display = cursor.getString(1);\n      String format = cursor.getString(2);\n      long timestamp = cursor.getLong(3);\n      String details = cursor.getString(4);\n      Result result = new Result(text, null, null, BarcodeFormat.valueOf(format), timestamp);\n      return new HistoryItem(result, display, details);\n    } finally {\n      close(cursor, db);\n    }\n  }\n  \n  public void deleteHistoryItem(int number) {\n    SQLiteOpenHelper helper = new DBHelper(activity);\n    SQLiteDatabase db = null;\n    Cursor cursor = null;\n    try {\n      db = helper.getWritableDatabase();      \n      cursor = db.query(DBHelper.TABLE_NAME,\n                        ID_COL_PROJECTION,\n                        null, null, null, null,\n                        DBHelper.TIMESTAMP_COL + \" DESC\");\n      cursor.move(number + 1);\n      db.delete(DBHelper.TABLE_NAME, DBHelper.ID_COL + '=' + cursor.getString(0), null);\n    } finally {\n      close(cursor, db);\n    }\n  }\n\n  public void addHistoryItem(Result result, ResultHandler handler) {\n    // Do not save this item to the history if the preference is turned off, or the contents are\n    // considered secure.\n    if (!activity.getIntent().getBooleanExtra(Intents.Scan.SAVE_HISTORY, true) ||\n        handler.areContentsSecure()) {\n      return;\n    }\n\n    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);\n    if (!prefs.getBoolean(PreferencesActivity.KEY_REMEMBER_DUPLICATES, false)) {\n      deletePrevious(result.getText());\n    }\n\n    ContentValues values = new ContentValues();\n    values.put(DBHelper.TEXT_COL, result.getText());\n    values.put(DBHelper.FORMAT_COL, result.getBarcodeFormat().toString());\n    values.put(DBHelper.DISPLAY_COL, handler.getDisplayContents().toString());\n    values.put(DBHelper.TIMESTAMP_COL, System.currentTimeMillis());\n\n    SQLiteOpenHelper helper = new DBHelper(activity);\n    SQLiteDatabase db = null;\n    try {\n      db = helper.getWritableDatabase();      \n      // Insert the new entry into the DB.\n      db.insert(DBHelper.TABLE_NAME, DBHelper.TIMESTAMP_COL, values);\n    } finally {\n      close(null, db);\n    }\n  }\n\n  public void addHistoryItemDetails(String itemID, String itemDetails) {\n    // As we're going to do an update only we don't need need to worry\n    // about the preferences; if the item wasn't saved it won't be udpated\n    SQLiteOpenHelper helper = new DBHelper(activity);\n    SQLiteDatabase db = null;    \n    Cursor cursor = null;\n    try {\n      db = helper.getWritableDatabase();\n      cursor = db.query(DBHelper.TABLE_NAME,\n                        ID_DETAIL_COL_PROJECTION,\n                        DBHelper.TEXT_COL + \"=?\",\n                        new String[] { itemID },\n                        null,\n                        null,\n                        DBHelper.TIMESTAMP_COL + \" DESC\",\n                        \"1\");\n      String oldID = null;\n      String oldDetails = null;\n      if (cursor.moveToNext()) {\n        oldID = cursor.getString(0);\n        oldDetails = cursor.getString(1);\n      }\n\n      if (oldID != null) {\n        String newDetails = oldDetails == null ? itemDetails : oldDetails + \" : \" + itemDetails;\n        ContentValues values = new ContentValues();\n        values.put(DBHelper.DETAILS_COL, newDetails);\n        db.update(DBHelper.TABLE_NAME, values, DBHelper.ID_COL + \"=?\", new String[] { oldID });\n      }\n\n    } finally {\n      close(cursor, db);\n    }\n  }\n\n  private void deletePrevious(String text) {\n    SQLiteOpenHelper helper = new DBHelper(activity);\n    SQLiteDatabase db = null;\n    try {\n      db = helper.getWritableDatabase();      \n      db.delete(DBHelper.TABLE_NAME, DBHelper.TEXT_COL + \"=?\", new String[] { text });\n    } finally {\n      close(null, db);\n    }\n  }\n\n  public void trimHistory() {\n    SQLiteOpenHelper helper = new DBHelper(activity);\n    SQLiteDatabase db = null;\n    Cursor cursor = null;\n    try {\n      db = helper.getWritableDatabase();      \n      cursor = db.query(DBHelper.TABLE_NAME,\n                        ID_COL_PROJECTION,\n                        null, null, null, null,\n                        DBHelper.TIMESTAMP_COL + \" DESC\");\n      cursor.move(MAX_ITEMS);\n      while (cursor.moveToNext()) {\n        db.delete(DBHelper.TABLE_NAME, DBHelper.ID_COL + '=' + cursor.getString(0), null);\n      }\n    } catch (SQLiteException sqle) {\n      // We're seeing an error here when called in CaptureActivity.onCreate() in rare cases\n      // and don't understand it. First theory is that it's transient so can be safely ignored.\n      // TODO revisit this after live in a future version to see if it 'worked'\n      Log.w(TAG, sqle);\n      // continue\n    } finally {\n      close(cursor, db);\n    }\n  }\n\n  /**\n   * <p>Builds a text representation of the scanning history. Each scan is encoded on one\n   * line, terminated by a line break (\\r\\n). The values in each line are comma-separated,\n   * and double-quoted. Double-quotes within values are escaped with a sequence of two\n   * double-quotes. The fields output are:</p>\n   *\n   * <ul>\n   *  <li>Raw text</li>\n   *  <li>Display text</li>\n   *  <li>Format (e.g. QR_CODE)</li>\n   *  <li>Timestamp</li>\n   *  <li>Formatted version of timestamp</li>\n   * </ul>\n   */\n  CharSequence buildHistory() {\n    StringBuilder historyText = new StringBuilder(1000);\n    SQLiteOpenHelper helper = new DBHelper(activity);\n    SQLiteDatabase db = null;\n    Cursor cursor = null;\n    try {\n      db = helper.getWritableDatabase();\n      cursor = db.query(DBHelper.TABLE_NAME,\n                        COLUMNS,\n                        null, null, null, null,\n                        DBHelper.TIMESTAMP_COL + \" DESC\");\n\n      while (cursor.moveToNext()) {\n\n        historyText.append('\"').append(massageHistoryField(cursor.getString(0))).append(\"\\\",\");\n        historyText.append('\"').append(massageHistoryField(cursor.getString(1))).append(\"\\\",\");\n        historyText.append('\"').append(massageHistoryField(cursor.getString(2))).append(\"\\\",\");\n        historyText.append('\"').append(massageHistoryField(cursor.getString(3))).append(\"\\\",\");\n\n        // Add timestamp again, formatted\n        long timestamp = cursor.getLong(3);\n        historyText.append('\"').append(massageHistoryField(\n            EXPORT_DATE_TIME_FORMAT.format(new Date(timestamp)))).append(\"\\\",\");\n\n        // Above we're preserving the old ordering of columns which had formatted data in position 5\n\n        historyText.append('\"').append(massageHistoryField(cursor.getString(4))).append(\"\\\"\\r\\n\");\n      }\n      return historyText;\n    } finally {\n      close(cursor, db);\n    }\n  }\n  \n  void clearHistory() {\n    SQLiteOpenHelper helper = new DBHelper(activity);\n    SQLiteDatabase db = null;\n    try {\n      db = helper.getWritableDatabase();      \n      db.delete(DBHelper.TABLE_NAME, null, null);\n    } finally {\n      close(null, db);\n    }\n  }\n\n  static Uri saveHistory(String history) {\n    File bsRoot = new File(Environment.getExternalStorageDirectory(), \"BarcodeScanner\");\n    File historyRoot = new File(bsRoot, \"History\");\n    if (!historyRoot.exists() && !historyRoot.mkdirs()) {\n      Log.w(TAG, \"Couldn't make dir \" + historyRoot);\n      return null;\n    }\n    File historyFile = new File(historyRoot, \"history-\" + System.currentTimeMillis() + \".csv\");\n    OutputStreamWriter out = null;\n    try {\n      out = new OutputStreamWriter(new FileOutputStream(historyFile), Charset.forName(\"UTF-8\"));\n      out.write(history);\n      return Uri.parse(\"file://\" + historyFile.getAbsolutePath());\n    } catch (IOException ioe) {\n      Log.w(TAG, \"Couldn't access file \" + historyFile + \" due to \" + ioe);\n      return null;\n    } finally {\n      if (out != null) {\n        try {\n          out.close();\n        } catch (IOException ioe) {\n          // do nothing\n        }\n      }\n    }\n  }\n\n  private static String massageHistoryField(String value) {\n    return value == null ? \"\" : value.replace(\"\\\"\",\"\\\"\\\"\");\n  }\n  \n  private static void close(Cursor cursor, SQLiteDatabase database) {\n    if (cursor != null) {\n      cursor.close();\n    }\n    if (database != null) {\n      database.close();\n    }\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/pref/BSPlusPreference.java",
    "content": "/*\n * Copyright (C) 2012 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.pref;\n\nimport android.content.Context;\nimport android.content.Intent;\nimport android.net.Uri;\nimport android.preference.Preference;\nimport android.util.AttributeSet;\n\n/**\n * A dummy pref that launches Play to the BS+ page.\n *\n * @author Sean Owen\n */\npublic final class BSPlusPreference extends Preference {\n\n  private static final String MARKET_URL = \"market://details?id=com.srowen.bs.android\";\n\n  public BSPlusPreference(Context context, AttributeSet attrs, int defStyle) {\n    super(context, attrs, defStyle);\n    configureClickListener();\n  }\n\n  public BSPlusPreference(Context context, AttributeSet attrs) {\n    super(context, attrs);\n    configureClickListener();\n  }\n\n  public BSPlusPreference(Context context) {\n    super(context);\n    configureClickListener();\n  }\n\n  private void configureClickListener() {\n    setOnPreferenceClickListener(new OnPreferenceClickListener() {\n      @Override\n      public boolean onPreferenceClick(Preference preference) {\n        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(MARKET_URL));\n        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);\n        getContext().startActivity(intent);\n        return true;\n      }\n    });\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/result/AddressBookResultHandler.java",
    "content": "/*\n * Copyright (C) 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.result;\n\nimport com.google.zxing.client.android.R;\nimport com.google.zxing.client.result.AddressBookParsedResult;\nimport com.google.zxing.client.result.ParsedResult;\n\nimport android.app.Activity;\nimport android.telephony.PhoneNumberUtils;\nimport android.text.Spannable;\nimport android.text.SpannableString;\nimport android.text.style.StyleSpan;\n\nimport java.text.DateFormat;\nimport java.text.ParseException;\nimport java.text.SimpleDateFormat;\nimport java.util.Date;\nimport java.util.Locale;\n\n/**\n * Handles address book entries.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n */\npublic final class AddressBookResultHandler extends ResultHandler {\n\n  private static final DateFormat[] DATE_FORMATS = {\n    new SimpleDateFormat(\"yyyyMMdd\", Locale.ENGLISH),\n    new SimpleDateFormat(\"yyyyMMdd'T'HHmmss\", Locale.ENGLISH),\n    new SimpleDateFormat(\"yyyy-MM-dd\", Locale.ENGLISH),\n    new SimpleDateFormat(\"yyyy-MM-dd'T'HH:mm:ss\", Locale.ENGLISH),\n  };\n  static {\n    for (DateFormat format : DATE_FORMATS) {\n      format.setLenient(false);\n    }\n  }\n\n  private static int[] BUTTON_TEXTS;\n\n  private final boolean[] fields;\n  private int buttonCount;\n\n  // This takes all the work out of figuring out which buttons/actions should be in which\n  // positions, based on which fields are present in this barcode.\n  private int mapIndexToAction(int index) {\n    if (index < buttonCount) {\n      int count = -1;\n      for (int x = 0; x < MAX_BUTTON_COUNT; x++) {\n        if (fields[x]) {\n          count++;\n        }\n        if (count == index) {\n          return x;\n        }\n      }\n    }\n    return -1;\n  }\n\n  public AddressBookResultHandler(Activity activity, ParsedResult result) {\n    super(activity, result);\n\tBUTTON_TEXTS = new int[]{\n      fakeR.getId(\"string\", \"button_add_contact\"),\n      fakeR.getId(\"string\", \"button_show_map\"),\n      fakeR.getId(\"string\", \"button_dial\"),\n      fakeR.getId(\"string\", \"button_email\"),\n    };\n    AddressBookParsedResult addressResult = (AddressBookParsedResult) result;\n    String[] addresses = addressResult.getAddresses();\n    boolean hasAddress = addresses != null && addresses.length > 0 && addresses[0].length() > 0;\n    String[] phoneNumbers = addressResult.getPhoneNumbers();\n    boolean hasPhoneNumber = phoneNumbers != null && phoneNumbers.length > 0;\n    String[] emails = addressResult.getEmails();\n    boolean hasEmailAddress = emails != null && emails.length > 0;\n\n    fields = new boolean[MAX_BUTTON_COUNT];\n    fields[0] = true; // Add contact is always available\n    fields[1] = hasAddress;\n    fields[2] = hasPhoneNumber;\n    fields[3] = hasEmailAddress;\n\n    buttonCount = 0;\n    for (int x = 0; x < MAX_BUTTON_COUNT; x++) {\n      if (fields[x]) {\n        buttonCount++;\n      }\n    }\n  }\n\n  @Override\n  public int getButtonCount() {\n    return buttonCount;\n  }\n\n  @Override\n  public int getButtonText(int index) {\n    return BUTTON_TEXTS[mapIndexToAction(index)];\n  }\n\n  @Override\n  public void handleButtonPress(int index) {\n    AddressBookParsedResult addressResult = (AddressBookParsedResult) getResult();\n    String[] addresses = addressResult.getAddresses();\n    String address1 = addresses == null || addresses.length < 1 ? null : addresses[0];\n    String[] addressTypes = addressResult.getAddressTypes();\n    String address1Type = addressTypes == null || addressTypes.length < 1 ? null : addressTypes[0];\n    int action = mapIndexToAction(index);\n    switch (action) {\n      case 0:\n        addContact(addressResult.getNames(),\n                   addressResult.getPronunciation(),\n                   addressResult.getPhoneNumbers(),\n                   addressResult.getPhoneTypes(),\n                   addressResult.getEmails(),\n                   addressResult.getEmailTypes(),\n                   addressResult.getNote(),\n                   addressResult.getInstantMessenger(),\n                   address1,\n                   address1Type,\n                   addressResult.getOrg(),\n                   addressResult.getTitle(),\n                   addressResult.getURL(),\n                   addressResult.getBirthday());\n        break;\n      case 1:\n        String[] names = addressResult.getNames();\n        String title = names != null ? names[0] : null;\n        searchMap(address1, title);\n        break;\n      case 2:\n        dialPhone(addressResult.getPhoneNumbers()[0]);\n        break;\n      case 3:\n        sendEmail(addressResult.getEmails()[0], null, null);\n        break;\n      default:\n        break;\n    }\n  }\n\n  private static Date parseDate(String s) {\n    for (DateFormat currentFormat : DATE_FORMATS) {\n      try {\n        return currentFormat.parse(s);\n      } catch (ParseException e) {\n        // continue\n      }\n    }\n    return null;\n  }\n\n  // Overriden so we can hyphenate phone numbers, format birthdays, and bold the name.\n  @Override\n  public CharSequence getDisplayContents() {\n    AddressBookParsedResult result = (AddressBookParsedResult) getResult();\n    StringBuilder contents = new StringBuilder(100);\n    ParsedResult.maybeAppend(result.getNames(), contents);\n    int namesLength = contents.length();\n\n    String pronunciation = result.getPronunciation();\n    if (pronunciation != null && pronunciation.length() > 0) {\n      contents.append(\"\\n(\");\n      contents.append(pronunciation);\n      contents.append(')');\n    }\n\n    ParsedResult.maybeAppend(result.getTitle(), contents);\n    ParsedResult.maybeAppend(result.getOrg(), contents);\n    ParsedResult.maybeAppend(result.getAddresses(), contents);\n    String[] numbers = result.getPhoneNumbers();\n    if (numbers != null) {\n      for (String number : numbers) {\n        ParsedResult.maybeAppend(PhoneNumberUtils.formatNumber(number), contents);\n      }\n    }\n    ParsedResult.maybeAppend(result.getEmails(), contents);\n    ParsedResult.maybeAppend(result.getURL(), contents);\n\n    String birthday = result.getBirthday();\n    if (birthday != null && birthday.length() > 0) {\n      Date date = parseDate(birthday);\n      if (date != null) {\n        ParsedResult.maybeAppend(DateFormat.getDateInstance(DateFormat.MEDIUM).format(date.getTime()), contents);\n      }\n    }\n    ParsedResult.maybeAppend(result.getNote(), contents);\n\n    if (namesLength > 0) {\n      // Bold the full name to make it stand out a bit.\n      Spannable styled = new SpannableString(contents.toString());\n      styled.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), 0, namesLength, 0);\n      return styled;\n    } else {\n      return contents.toString();\n    }\n  }\n\n  @Override\n  public int getDisplayTitle() {\n    return fakeR.getId(\"string\", \"result_address_book\");\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/result/CalendarResultHandler.java",
    "content": "/*\n * Copyright (C) 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.result;\n\nimport android.content.ActivityNotFoundException;\nimport android.util.Log;\nimport com.google.zxing.client.android.R;\nimport com.google.zxing.client.result.CalendarParsedResult;\nimport com.google.zxing.client.result.ParsedResult;\n\nimport android.app.Activity;\nimport android.content.Intent;\n\nimport java.text.DateFormat;\nimport java.util.Date;\n\n/**\n * Handles calendar entries encoded in QR Codes.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n * @author Sean Owen\n */\npublic final class CalendarResultHandler extends ResultHandler {\n\n  private static final String TAG = CalendarResultHandler.class.getSimpleName();\n\n  private static int[] buttons;\n\n  public CalendarResultHandler(Activity activity, ParsedResult result) {\n    super(activity, result);\n\n\tbuttons = new int[]{\n\t\tfakeR.getId(\"string\", \"button_add_calendar\")\n\t};\n  }\n\n  @Override\n  public int getButtonCount() {\n    return buttons.length;\n  }\n\n  @Override\n  public int getButtonText(int index) {\n    return buttons[index];\n  }\n\n  @Override\n  public void handleButtonPress(int index) {\n    if (index == 0) {\n      CalendarParsedResult calendarResult = (CalendarParsedResult) getResult();\n\n      String description = calendarResult.getDescription();\n      String organizer = calendarResult.getOrganizer();\n      if (organizer != null) { // No separate Intent key, put in description\n        if (description == null) {\n          description = organizer;\n        } else {\n          description = description + '\\n' + organizer;\n        }\n      }\n\n      addCalendarEvent(calendarResult.getSummary(),\n                       calendarResult.getStart(),\n                       calendarResult.isStartAllDay(),\n                       calendarResult.getEnd(),\n                       calendarResult.getLocation(),\n                       description,\n                       calendarResult.getAttendees());\n    }\n  }\n\n  /**\n   * Sends an intent to create a new calendar event by prepopulating the Add Event UI. Older\n   * versions of the system have a bug where the event title will not be filled out.\n   *\n   * @param summary A description of the event\n   * @param start   The start time\n   * @param allDay  if true, event is considered to be all day starting from start time\n   * @param end     The end time (optional)\n   * @param location a text description of the event location\n   * @param description a text description of the event itself\n   * @param attendees attendees to invite\n   */\n  private void addCalendarEvent(String summary,\n                                Date start,\n                                boolean allDay,\n                                Date end,\n                                String location,\n                                String description,\n                                String[] attendees) {\n    Intent intent = new Intent(Intent.ACTION_INSERT);\n    intent.setType(\"vnd.android.cursor.item/event\");\n    long startMilliseconds = start.getTime();\n    intent.putExtra(\"beginTime\", startMilliseconds);\n    if (allDay) {\n      intent.putExtra(\"allDay\", true);\n    }\n    long endMilliseconds;\n    if (end == null) {\n      if (allDay) {\n        // + 1 day\n        endMilliseconds = startMilliseconds + 24 * 60 * 60 * 1000;\n      } else {\n        endMilliseconds = startMilliseconds;\n      }\n    } else {\n      endMilliseconds = end.getTime();\n    }\n    intent.putExtra(\"endTime\", endMilliseconds);\n    intent.putExtra(\"title\", summary);\n    intent.putExtra(\"eventLocation\", location);\n    intent.putExtra(\"description\", description);\n    if (attendees != null) {\n      intent.putExtra(Intent.EXTRA_EMAIL, attendees);\n      // Documentation says this is either a String[] or comma-separated String, which is right?\n    }\n\n    try {\n      // Do this manually at first\n      rawLaunchIntent(intent);\n    } catch (ActivityNotFoundException anfe) {\n      Log.w(TAG, \"No calendar app available that responds to \" + Intent.ACTION_INSERT);\n      // For calendar apps that don't like \"INSERT\":\n      intent.setAction(Intent.ACTION_EDIT);\n      launchIntent(intent); // Fail here for real if nothing can handle it\n    }\n  }\n\n\n  @Override\n  public CharSequence getDisplayContents() {\n\n    CalendarParsedResult calResult = (CalendarParsedResult) getResult();\n    StringBuilder result = new StringBuilder(100);\n\n    ParsedResult.maybeAppend(calResult.getSummary(), result);\n\n    Date start = calResult.getStart();\n    ParsedResult.maybeAppend(format(calResult.isStartAllDay(), start), result);\n\n    Date end = calResult.getEnd();\n    if (end != null) {\n      if (calResult.isEndAllDay() && !start.equals(end)) {\n        // Show only year/month/day\n        // if it's all-day and this is the end date, it's exclusive, so show the user\n        // that it ends on the day before to make more intuitive sense.\n        // But don't do it if the event already (incorrectly?) specifies the same start/end\n        end = new Date(end.getTime() - 24 * 60 * 60 * 1000);\n      }\n      ParsedResult.maybeAppend(format(calResult.isEndAllDay(), end), result);\n    }\n\n    ParsedResult.maybeAppend(calResult.getLocation(), result);\n    ParsedResult.maybeAppend(calResult.getOrganizer(), result);\n    ParsedResult.maybeAppend(calResult.getAttendees(), result);\n    ParsedResult.maybeAppend(calResult.getDescription(), result);\n    return result.toString();\n  }\n\n  private static String format(boolean allDay, Date date) {\n    if (date == null) {\n      return null;\n    }\n    DateFormat format = allDay\n        ? DateFormat.getDateInstance(DateFormat.MEDIUM)\n        : DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);\n    return format.format(date);\n  }\n\n  @Override\n  public int getDisplayTitle() {\n    return fakeR.getId(\"string\", \"result_calendar\");\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/result/EmailAddressResultHandler.java",
    "content": "/*\n * Copyright (C) 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.result;\n\nimport com.google.zxing.client.android.R;\nimport com.google.zxing.client.result.EmailAddressParsedResult;\nimport com.google.zxing.client.result.ParsedResult;\n\nimport android.app.Activity;\n\n/**\n * Handles email addresses.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n */\npublic final class EmailAddressResultHandler extends ResultHandler {\n  private static int[] buttons;\n\n  public EmailAddressResultHandler(Activity activity, ParsedResult result) {\n    super(activity, result);\n\tbuttons = new int[]{\n\t\tfakeR.getId(\"string\", \"button_email\"),\n\t\tfakeR.getId(\"string\", \"button_add_contact\")\n\t};\n  }\n\n  @Override\n  public int getButtonCount() {\n    return buttons.length;\n  }\n\n  @Override\n  public int getButtonText(int index) {\n    return buttons[index];\n  }\n\n  @Override\n  public void handleButtonPress(int index) {\n    EmailAddressParsedResult emailResult = (EmailAddressParsedResult) getResult();\n    switch (index) {\n      case 0:\n        sendEmailFromUri(emailResult.getMailtoURI(),\n                         emailResult.getEmailAddress(),\n                         emailResult.getSubject(),\n                         emailResult.getBody());\n        break;\n      case 1:\n        String[] addresses = new String[1];\n        addresses[0] = emailResult.getEmailAddress();\n        addEmailOnlyContact(addresses, null);\n        break;\n    }\n  }\n\n  @Override\n  public int getDisplayTitle() {\n    return fakeR.getId(\"string\", \"result_email_address\");\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/result/GeoResultHandler.java",
    "content": "/*\n * Copyright (C) 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.result;\n\nimport com.google.zxing.client.android.R;\nimport com.google.zxing.client.result.GeoParsedResult;\nimport com.google.zxing.client.result.ParsedResult;\n\nimport android.app.Activity;\n\n/**\n * Handles geographic coordinates (typically encoded as geo: URLs).\n *\n * @author dswitkin@google.com (Daniel Switkin)\n */\npublic final class GeoResultHandler extends ResultHandler {\n  private static int[] buttons;\n\n  public GeoResultHandler(Activity activity, ParsedResult result) {\n    super(activity, result);\n\tbuttons = new int[]{\n\t\tfakeR.getId(\"string\", \"button_show_map\"),\n\t\tfakeR.getId(\"string\", \"button_get_directions\")\n\t};\n  }\n\n  @Override\n  public int getButtonCount() {\n    return buttons.length;\n  }\n\n  @Override\n  public int getButtonText(int index) {\n    return buttons[index];\n  }\n\n  @Override\n  public void handleButtonPress(int index) {\n    GeoParsedResult geoResult = (GeoParsedResult) getResult();\n    switch (index) {\n      case 0:\n        openMap(geoResult.getGeoURI());\n        break;\n      case 1:\n        getDirections(geoResult.getLatitude(), geoResult.getLongitude());\n        break;\n    }\n  }\n\n  @Override\n  public int getDisplayTitle() {\n    return fakeR.getId(\"string\", \"result_geo\");\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/result/ISBNResultHandler.java",
    "content": "/*\n * Copyright (C) 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.result;\n\nimport com.google.zxing.Result;\nimport com.google.zxing.client.android.R;\nimport com.google.zxing.client.result.ISBNParsedResult;\nimport com.google.zxing.client.result.ParsedResult;\n\nimport android.app.Activity;\nimport android.view.View;\n\n/**\n * Handles books encoded by their ISBN values.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n */\npublic final class ISBNResultHandler extends ResultHandler {\n  private static int[] buttons;\n\n  public ISBNResultHandler(Activity activity, ParsedResult result, Result rawResult) {\n    super(activity, result, rawResult);\n\tbuttons = new int[]{\n\t\tfakeR.getId(\"string\", \"button_product_search\"),\n\t\tfakeR.getId(\"string\", \"button_book_search\"),\n\t\tfakeR.getId(\"string\", \"button_search_book_contents\"),\n\t\tfakeR.getId(\"string\", \"button_custom_product_search\")\n\t};\n    showGoogleShopperButton(new View.OnClickListener() {\n      @Override\n      public void onClick(View view) {\n        ISBNParsedResult isbnResult = (ISBNParsedResult) getResult();\n        openGoogleShopper(isbnResult.getISBN());\n      }\n    });\n  }\n\n  @Override\n  public int getButtonCount() {\n    return hasCustomProductSearch() ? buttons.length : buttons.length - 1;\n  }\n\n  @Override\n  public int getButtonText(int index) {\n    return buttons[index];\n  }\n\n  @Override\n  public void handleButtonPress(int index) {\n    ISBNParsedResult isbnResult = (ISBNParsedResult) getResult();\n    switch (index) {\n      case 0:\n        openProductSearch(isbnResult.getISBN());\n        break;\n      case 1:\n        openBookSearch(isbnResult.getISBN());\n        break;\n      case 2:\n        searchBookContents(isbnResult.getISBN());\n        break;\n      case 3:\n        openURL(fillInCustomSearchURL(isbnResult.getISBN()));\n        break;\n    }\n  }\n\n  @Override\n  public int getDisplayTitle() {\n    return fakeR.getId(\"string\", \"result_isbn\");\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/result/ProductResultHandler.java",
    "content": "/*\n * Copyright (C) 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.result;\n\nimport com.google.zxing.Result;\nimport com.google.zxing.client.android.R;\nimport com.google.zxing.client.result.ParsedResult;\nimport com.google.zxing.client.result.ProductParsedResult;\n\nimport android.app.Activity;\nimport android.view.View;\n\n/**\n * Handles generic products which are not books.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n */\npublic final class ProductResultHandler extends ResultHandler {\n  private static int[] buttons;\n\n  public ProductResultHandler(Activity activity, ParsedResult result, Result rawResult) {\n    super(activity, result, rawResult);\n\tbuttons = new int[]{\n\t\tfakeR.getId(\"string\", \"button_product_search\"),\n\t\tfakeR.getId(\"string\", \"button_web_search\"),\n\t\tfakeR.getId(\"string\", \"button_custom_product_search\")\n\t};\n    showGoogleShopperButton(new View.OnClickListener() {\n      @Override\n      public void onClick(View view) {\n        ProductParsedResult productResult = (ProductParsedResult) getResult();\n        openGoogleShopper(productResult.getNormalizedProductID());\n      }\n    });\n  }\n\n  @Override\n  public int getButtonCount() {\n    return hasCustomProductSearch() ? buttons.length : buttons.length - 1;\n  }\n\n  @Override\n  public int getButtonText(int index) {\n    return buttons[index];\n  }\n\n  @Override\n  public void handleButtonPress(int index) {\n    ProductParsedResult productResult = (ProductParsedResult) getResult();\n    switch (index) {\n      case 0:\n        openProductSearch(productResult.getNormalizedProductID());\n        break;\n      case 1:\n        webSearch(productResult.getNormalizedProductID());\n        break;\n      case 2:\n        openURL(fillInCustomSearchURL(productResult.getNormalizedProductID()));\n        break;\n    }\n  }\n\n  @Override\n  public int getDisplayTitle() {\n    return fakeR.getId(\"string\", \"result_product\");\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/result/ResultButtonListener.java",
    "content": "/*\n * Copyright (C) 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.result;\n\nimport android.view.View;\nimport android.widget.Button;\n\n/**\n * Handles the result of barcode decoding in the context of the Android platform, by dispatching the\n * proper intents to open other activities like GMail, Maps, etc.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n */\npublic final class ResultButtonListener implements Button.OnClickListener {\n  private final ResultHandler resultHandler;\n  private final int index;\n\n  public ResultButtonListener(ResultHandler resultHandler, int index) {\n    this.resultHandler = resultHandler;\n    this.index = index;\n  }\n\n  @Override\n  public void onClick(View view) {\n    resultHandler.handleButtonPress(index);\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/result/ResultHandler.java",
    "content": "/*\n * Copyright (C) 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.result;\n\nimport com.google.zxing.Result;\nimport com.google.zxing.client.android.Contents;\nimport com.google.zxing.client.android.Intents;\nimport com.google.zxing.client.android.LocaleManager;\nimport com.google.zxing.client.android.PreferencesActivity;\nimport com.google.zxing.client.android.R;\nimport com.google.zxing.client.android.book.SearchBookContentsActivity;\nimport com.google.zxing.client.result.ParsedResult;\nimport com.google.zxing.client.result.ParsedResultType;\nimport com.google.zxing.client.result.ResultParser;\n\nimport android.app.Activity;\nimport android.app.AlertDialog;\nimport android.app.SearchManager;\nimport android.content.ActivityNotFoundException;\nimport android.content.DialogInterface;\nimport android.content.Intent;\nimport android.content.SharedPreferences;\nimport android.content.pm.PackageManager;\nimport android.net.Uri;\nimport android.preference.PreferenceManager;\nimport android.provider.ContactsContract;\nimport android.util.Log;\nimport android.view.View;\nimport com.google.zxing.FakeR;\n\nimport java.util.Collection;\nimport java.util.Locale;\n\n/**\n * A base class for the Android-specific barcode handlers. These allow the app to polymorphically\n * suggest the appropriate actions for each data type.\n *\n * This class also contains a bunch of utility methods to take common actions like opening a URL.\n * They could easily be moved into a helper object, but it can't be static because the Activity\n * instance is needed to launch an intent.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n * @author Sean Owen\n */\npublic abstract class ResultHandler {\n\n  private static final String TAG = ResultHandler.class.getSimpleName();\n\n  private static final String GOOGLE_SHOPPER_PACKAGE = \"com.google.android.apps.shopper\";\n  private static final String GOOGLE_SHOPPER_ACTIVITY = GOOGLE_SHOPPER_PACKAGE +\n      \".results.SearchResultsActivity\";\n  private static final String MARKET_URI_PREFIX = \"market://details?id=\";\n  private static final String MARKET_REFERRER_SUFFIX =\n      \"&referrer=utm_source%3Dbarcodescanner%26utm_medium%3Dapps%26utm_campaign%3Dscan\";\n\n  private static final String[] EMAIL_TYPE_STRINGS = {\"home\", \"work\", \"mobile\"};\n  private static final String[] PHONE_TYPE_STRINGS = {\"home\", \"work\", \"mobile\", \"fax\", \"pager\", \"main\"};\n  private static final String[] ADDRESS_TYPE_STRINGS = {\"home\", \"work\"};\n  private static final int[] EMAIL_TYPE_VALUES = {\n      ContactsContract.CommonDataKinds.Email.TYPE_HOME,\n      ContactsContract.CommonDataKinds.Email.TYPE_WORK,\n      ContactsContract.CommonDataKinds.Email.TYPE_MOBILE,\n  };\n  private static final int[] PHONE_TYPE_VALUES = {\n      ContactsContract.CommonDataKinds.Phone.TYPE_HOME,\n      ContactsContract.CommonDataKinds.Phone.TYPE_WORK,\n      ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE,\n      ContactsContract.CommonDataKinds.Phone.TYPE_FAX_WORK,\n      ContactsContract.CommonDataKinds.Phone.TYPE_PAGER,\n      ContactsContract.CommonDataKinds.Phone.TYPE_MAIN,\n  };\n  private static final int[] ADDRESS_TYPE_VALUES = {\n      ContactsContract.CommonDataKinds.StructuredPostal.TYPE_HOME,\n      ContactsContract.CommonDataKinds.StructuredPostal.TYPE_WORK,\n  };\n  private static final int NO_TYPE = -1;\n\n  public static final int MAX_BUTTON_COUNT = 4;\n\n  private final ParsedResult result;\n  private final Activity activity;\n  private final Result rawResult;\n  private final String customProductSearch;\n\n  private final DialogInterface.OnClickListener shopperMarketListener =\n      new DialogInterface.OnClickListener() {\n    @Override\n    public void onClick(DialogInterface dialogInterface, int which) {\n      launchIntent(new Intent(Intent.ACTION_VIEW, Uri.parse(MARKET_URI_PREFIX +\n          GOOGLE_SHOPPER_PACKAGE + MARKET_REFERRER_SUFFIX)));\n    }\n  };\n\n  protected static FakeR fakeR;\n\n  ResultHandler(Activity activity, ParsedResult result) {\n    this(activity, result, null);\n  }\n\n  ResultHandler(Activity activity, ParsedResult result, Result rawResult) {\n    this.result = result;\n    this.activity = activity;\n    this.rawResult = rawResult;\n    this.customProductSearch = parseCustomSearchURL();\n\n\tfakeR = new FakeR(activity);\n\n\t// Make sure the Shopper button is hidden by default. Without this, scanning a product followed\n    // by a QR Code would leave the button on screen among the QR Code actions.\n    View shopperButton = activity.findViewById(fakeR.getId(\"id\", \"shopper_button\"));\n    shopperButton.setVisibility(View.GONE);\n  }\n\n  public ParsedResult getResult() {\n    return result;\n  }\n\n  boolean hasCustomProductSearch() {\n    return customProductSearch != null;\n  }\n\n  Activity getActivity() {\n    return activity;\n  }\n\n  /**\n   * Indicates how many buttons the derived class wants shown.\n   *\n   * @return The integer button count.\n   */\n  public abstract int getButtonCount();\n\n  /**\n   * The text of the nth action button.\n   *\n   * @param index From 0 to getButtonCount() - 1\n   * @return The button text as a resource ID\n   */\n  public abstract int getButtonText(int index);\n\n\n  /**\n   * Execute the action which corresponds to the nth button.\n   *\n   * @param index The button that was clicked.\n   */\n  public abstract void handleButtonPress(int index);\n\n  /**\n   * Some barcode contents are considered secure, and should not be saved to history, copied to\n   * the clipboard, or otherwise persisted.\n   *\n   * @return If true, do not create any permanent record of these contents.\n   */\n  public boolean areContentsSecure() {\n    return false;\n  }\n\n  /**\n   * The Google Shopper button is special and is not handled by the abstract button methods above.\n   *\n   * @param listener The on click listener to install for this button.\n   */\n  void showGoogleShopperButton(View.OnClickListener listener) {\n    View shopperButton = activity.findViewById(fakeR.getId(\"id\", \"shopper_button\"));\n    shopperButton.setVisibility(View.VISIBLE);\n    shopperButton.setOnClickListener(listener);\n  }\n\n  /**\n   * Create a possibly styled string for the contents of the current barcode.\n   *\n   * @return The text to be displayed.\n   */\n  public CharSequence getDisplayContents() {\n    String contents = result.getDisplayResult();\n    return contents.replace(\"\\r\", \"\");\n  }\n\n  /**\n   * A string describing the kind of barcode that was found, e.g. \"Found contact info\".\n   *\n   * @return The resource ID of the string.\n   */\n  public abstract int getDisplayTitle();\n\n  /**\n   * A convenience method to get the parsed type. Should not be overridden.\n   *\n   * @return The parsed type, e.g. URI or ISBN\n   */\n  public final ParsedResultType getType() {\n    return result.getType();\n  }\n\n  final void addPhoneOnlyContact(String[] phoneNumbers,String[] phoneTypes) {\n    addContact(null, null, phoneNumbers, phoneTypes, null, null, null, null, null, null, null, null, null, null);\n  }\n\n  final void addEmailOnlyContact(String[] emails, String[] emailTypes) {\n    addContact(null, null, null, null, emails, emailTypes, null, null, null, null, null, null, null, null);\n  }\n\n  final void addContact(String[] names,\n                        String pronunciation,\n                        String[] phoneNumbers,\n                        String[] phoneTypes,\n                        String[] emails,\n                        String[] emailTypes,\n                        String note,\n                        String instantMessenger,\n                        String address,\n                        String addressType,\n                        String org,\n                        String title,\n                        String url,\n                        String birthday) {\n\n    // Only use the first name in the array, if present.\n    Intent intent = new Intent(Intent.ACTION_INSERT_OR_EDIT, ContactsContract.Contacts.CONTENT_URI);\n    intent.setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE);\n    putExtra(intent, ContactsContract.Intents.Insert.NAME, names != null ? names[0] : null);\n\n    putExtra(intent, ContactsContract.Intents.Insert.PHONETIC_NAME, pronunciation);\n\n    int phoneCount = Math.min(phoneNumbers != null ? phoneNumbers.length : 0, Contents.PHONE_KEYS.length);\n    for (int x = 0; x < phoneCount; x++) {\n      putExtra(intent, Contents.PHONE_KEYS[x], phoneNumbers[x]);\n      if (phoneTypes != null && x < phoneTypes.length) {\n        int type = toPhoneContractType(phoneTypes[x]);\n        if (type >= 0) {\n          intent.putExtra(Contents.PHONE_TYPE_KEYS[x], type);\n        }\n      }\n    }\n\n    int emailCount = Math.min(emails != null ? emails.length : 0, Contents.EMAIL_KEYS.length);\n    for (int x = 0; x < emailCount; x++) {\n      putExtra(intent, Contents.EMAIL_KEYS[x], emails[x]);\n      if (emailTypes != null && x < emailTypes.length) {\n        int type = toEmailContractType(emailTypes[x]);\n        if (type >= 0) {\n          intent.putExtra(Contents.EMAIL_TYPE_KEYS[x], type);\n        }\n      }\n    }\n\n    // No field for URL, birthday; use notes\n    StringBuilder aggregatedNotes = new StringBuilder();\n    for (String aNote : new String[] { url, birthday, note }) {\n      if (aNote != null) {\n        if (aggregatedNotes.length() > 0) {\n          aggregatedNotes.append('\\n');\n        }\n        aggregatedNotes.append(aNote);\n      }\n    }\n    if (aggregatedNotes.length() > 0) {\n      putExtra(intent, ContactsContract.Intents.Insert.NOTES, aggregatedNotes.toString());\n    }\n    \n    putExtra(intent, ContactsContract.Intents.Insert.IM_HANDLE, instantMessenger);\n    putExtra(intent, ContactsContract.Intents.Insert.POSTAL, address);\n    if (addressType != null) {\n      int type = toAddressContractType(addressType);\n      if (type >= 0) {\n        intent.putExtra(ContactsContract.Intents.Insert.POSTAL_TYPE, type);\n      }\n    }\n    putExtra(intent, ContactsContract.Intents.Insert.COMPANY, org);\n    putExtra(intent, ContactsContract.Intents.Insert.JOB_TITLE, title);\n    launchIntent(intent);\n  }\n\n  private static int toEmailContractType(String typeString) {\n    return doToContractType(typeString, EMAIL_TYPE_STRINGS, EMAIL_TYPE_VALUES);\n  }\n\n  private static int toPhoneContractType(String typeString) {\n    return doToContractType(typeString, PHONE_TYPE_STRINGS, PHONE_TYPE_VALUES);\n  }\n\n  private static int toAddressContractType(String typeString) {\n    return doToContractType(typeString, ADDRESS_TYPE_STRINGS, ADDRESS_TYPE_VALUES);\n  }\n\n  private static int doToContractType(String typeString, String[] types, int[] values) {\n    if (typeString == null) {\n      return NO_TYPE;\n    }\n    for (int i = 0; i < types.length; i++) {\n      String type = types[i];\n      if (typeString.startsWith(type) || typeString.startsWith(type.toUpperCase(Locale.ENGLISH))) {\n        return values[i];\n      }\n    }\n    return NO_TYPE;\n  }\n\n  final void shareByEmail(String contents) {\n    sendEmailFromUri(\"mailto:\", null, activity.getString(fakeR.getId(\"string\", \"msg_share_subject_line\")),\n        contents);\n  }\n\n  final void sendEmail(String address, String subject, String body) {\n    sendEmailFromUri(\"mailto:\" + address, address, subject, body);\n  }\n\n  // Use public Intent fields rather than private GMail app fields to specify subject and body.\n  final void sendEmailFromUri(String uri, String email, String subject, String body) {\n    Intent intent = new Intent(Intent.ACTION_SEND, Uri.parse(uri));\n    if (email != null) {\n      intent.putExtra(Intent.EXTRA_EMAIL, new String[] {email});\n    }\n    putExtra(intent, Intent.EXTRA_SUBJECT, subject);\n    putExtra(intent, Intent.EXTRA_TEXT, body);\n    intent.setType(\"text/plain\");\n    launchIntent(intent);\n  }\n\n  final void shareBySMS(String contents) {\n    sendSMSFromUri(\"smsto:\", activity.getString(fakeR.getId(\"string\", \"msg_share_subject_line\")) + \":\\n\" +\n        contents);\n  }\n\n  final void sendSMS(String phoneNumber, String body) {\n    sendSMSFromUri(\"smsto:\" + phoneNumber, body);\n  }\n\n  final void sendSMSFromUri(String uri, String body) {\n    Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.parse(uri));\n    putExtra(intent, \"sms_body\", body);\n    // Exit the app once the SMS is sent\n    intent.putExtra(\"compose_mode\", true);\n    launchIntent(intent);\n  }\n\n  final void sendMMS(String phoneNumber, String subject, String body) {\n    sendMMSFromUri(\"mmsto:\" + phoneNumber, subject, body);\n  }\n\n  final void sendMMSFromUri(String uri, String subject, String body) {\n    Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.parse(uri));\n    // The Messaging app needs to see a valid subject or else it will treat this an an SMS.\n    if (subject == null || subject.length() == 0) {\n      putExtra(intent, \"subject\", activity.getString(fakeR.getId(\"string\", \"msg_default_mms_subject\")));\n    } else {\n      putExtra(intent, \"subject\", subject);\n    }\n    putExtra(intent, \"sms_body\", body);\n    intent.putExtra(\"compose_mode\", true);\n    launchIntent(intent);\n  }\n\n  final void dialPhone(String phoneNumber) {\n    launchIntent(new Intent(Intent.ACTION_DIAL, Uri.parse(\"tel:\" + phoneNumber)));\n  }\n\n  final void dialPhoneFromUri(String uri) {\n    launchIntent(new Intent(Intent.ACTION_DIAL, Uri.parse(uri)));\n  }\n\n  final void openMap(String geoURI) {\n    launchIntent(new Intent(Intent.ACTION_VIEW, Uri.parse(geoURI)));\n  }\n\n  /**\n   * Do a geo search using the address as the query.\n   *\n   * @param address The address to find\n   * @param title An optional title, e.g. the name of the business at this address\n   */\n  final void searchMap(String address, CharSequence title) {\n    String query = address;\n    if (title != null && title.length() > 0) {\n      query += \" (\" + title + ')';\n    }\n    launchIntent(new Intent(Intent.ACTION_VIEW, Uri.parse(\"geo:0,0?q=\" + Uri.encode(query))));\n  }\n\n  final void getDirections(double latitude, double longitude) {\n    launchIntent(new Intent(Intent.ACTION_VIEW, Uri.parse(\"http://maps.google.\" +\n        LocaleManager.getCountryTLD(activity) + \"/maps?f=d&daddr=\" + latitude + ',' + longitude)));\n  }\n\n  // Uses the mobile-specific version of Product Search, which is formatted for small screens.\n  final void openProductSearch(String upc) {\n    Uri uri = Uri.parse(\"http://www.google.\" + LocaleManager.getProductSearchCountryTLD(activity) +\n        \"/m/products?q=\" + upc + \"&source=zxing\");\n    launchIntent(new Intent(Intent.ACTION_VIEW, uri));\n  }\n\n  final void openBookSearch(String isbn) {\n    Uri uri = Uri.parse(\"http://books.google.\" + LocaleManager.getBookSearchCountryTLD(activity) +\n        \"/books?vid=isbn\" + isbn);\n    launchIntent(new Intent(Intent.ACTION_VIEW, uri));\n  }\n\n  final void searchBookContents(String isbnOrUrl) {\n    Intent intent = new Intent(Intents.SearchBookContents.ACTION);\n    intent.setClassName(activity, SearchBookContentsActivity.class.getName());\n    putExtra(intent, Intents.SearchBookContents.ISBN, isbnOrUrl);\n    launchIntent(intent);\n  }\n\n  final void openURL(String url) {\n    // Strangely, some Android browsers don't seem to register to handle HTTP:// or HTTPS://.\n    // Lower-case these as it should always be OK to lower-case these schemes.\n    if (url.startsWith(\"HTTP://\")) {\n      url = \"http\" + url.substring(4);\n    } else if (url.startsWith(\"HTTPS://\")) {\n      url = \"https\" + url.substring(5);\n    }\n    Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));\n    try {\n      launchIntent(intent);\n    } catch (ActivityNotFoundException anfe) {\n      Log.w(TAG, \"Nothing available to handle \" + intent);\n    }\n  }\n\n  final void webSearch(String query) {\n    Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);\n    intent.putExtra(\"query\", query);\n    launchIntent(intent);\n  }\n\n  final void openGoogleShopper(String query) {\n\n    // Construct Intent to launch Shopper\n    Intent intent = new Intent(Intent.ACTION_SEARCH);\n    intent.setClassName(GOOGLE_SHOPPER_PACKAGE, GOOGLE_SHOPPER_ACTIVITY);\n    intent.putExtra(SearchManager.QUERY, query);\n\n    // Is it available?\n    PackageManager pm = activity.getPackageManager();\n    Collection<?> availableApps = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);\n\n    if (availableApps != null && !availableApps.isEmpty()) {\n      // If something can handle it, start it\n      activity.startActivity(intent);\n    } else {\n      // Otherwise offer to install it from Market.\n      AlertDialog.Builder builder = new AlertDialog.Builder(activity);\n      builder.setTitle(fakeR.getId(\"string\", \"msg_google_shopper_missing\"));\n      builder.setMessage(fakeR.getId(\"string\", \"msg_install_google_shopper\"));\n      builder.setIcon(fakeR.getId(\"drawable\", \"shopper_icon\"));\n      builder.setPositiveButton(fakeR.getId(\"string\", \"button_ok\"), shopperMarketListener);\n      builder.setNegativeButton(fakeR.getId(\"string\", \"button_cancel\"), null);\n      builder.show();\n    }\n  }\n\n  /**\n   * Like {@link #launchIntent(Intent)} but will tell you if it is not handle-able\n   * via {@link ActivityNotFoundException}.\n   *\n   * @throws ActivityNotFoundException\n   */\n  void rawLaunchIntent(Intent intent) {\n    if (intent != null) {\n      intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);\n      Log.d(TAG, \"Launching intent: \" + intent + \" with extras: \" + intent.getExtras());\n      activity.startActivity(intent);\n    }\n  }\n\n  /**\n   * Like {@link #rawLaunchIntent(Intent)} but will show a user dialog if nothing is available to handle.\n   */\n  void launchIntent(Intent intent) {\n    try {\n      rawLaunchIntent(intent);\n    } catch (ActivityNotFoundException e) {\n      AlertDialog.Builder builder = new AlertDialog.Builder(activity);\n      builder.setTitle(fakeR.getId(\"string\", \"app_name\"));\n      builder.setMessage(fakeR.getId(\"string\", \"msg_intent_failed\"));\n      builder.setPositiveButton(fakeR.getId(\"string\", \"button_ok\"), null);\n      builder.show();\n    }\n  }\n\n  private static void putExtra(Intent intent, String key, String value) {\n    if (value != null && value.length() > 0) {\n      intent.putExtra(key, value);\n    }\n  }\n\n  private String parseCustomSearchURL() {\n    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);\n    String customProductSearch = prefs.getString(PreferencesActivity.KEY_CUSTOM_PRODUCT_SEARCH,\n        null);\n    if (customProductSearch != null && customProductSearch.trim().length() == 0) {\n      return null;\n    }\n    return customProductSearch;\n  }\n\n  String fillInCustomSearchURL(String text) {\n    if (customProductSearch == null) {\n      return text; // ?\n    }\n    String url = customProductSearch.replace(\"%s\", text);\n    if (rawResult != null) {\n      url = url.replace(\"%f\", rawResult.getBarcodeFormat().toString());\n      if (url.contains(\"%t\")) {\n        ParsedResult parsedResultAgain = ResultParser.parseResult(rawResult);\n        url = url.replace(\"%t\", parsedResultAgain.getType().toString());\n      }\n    }\n    return url;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/result/ResultHandlerFactory.java",
    "content": "/*\n * Copyright (C) 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.result;\n\nimport com.google.zxing.Result;\nimport com.google.zxing.client.android.CaptureActivity;\nimport com.google.zxing.client.result.ParsedResult;\nimport com.google.zxing.client.result.ResultParser;\n\n/**\n * Manufactures Android-specific handlers based on the barcode content's type.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n */\npublic final class ResultHandlerFactory {\n  private ResultHandlerFactory() {\n  }\n\n  public static ResultHandler makeResultHandler(CaptureActivity activity, Result rawResult) {\n    ParsedResult result = parseResult(rawResult);\n    switch (result.getType()) {\n      case ADDRESSBOOK:\n        return new AddressBookResultHandler(activity, result);\n      case EMAIL_ADDRESS:\n        return new EmailAddressResultHandler(activity, result);\n      case PRODUCT:\n        return new ProductResultHandler(activity, result, rawResult);\n      case URI:\n        return new URIResultHandler(activity, result);\n      case WIFI:\n        return new WifiResultHandler(activity, result);\n      case GEO:\n        return new GeoResultHandler(activity, result);\n      case TEL:\n        return new TelResultHandler(activity, result);\n      case SMS:\n        return new SMSResultHandler(activity, result);\n      case CALENDAR:\n        return new CalendarResultHandler(activity, result);\n      case ISBN:\n        return new ISBNResultHandler(activity, result, rawResult);\n      default:\n        return new TextResultHandler(activity, result, rawResult);\n    }\n  }\n\n  private static ParsedResult parseResult(Result rawResult) {\n    return ResultParser.parseResult(rawResult);\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/result/SMSResultHandler.java",
    "content": "/*\n * Copyright (C) 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.result;\n\nimport com.google.zxing.client.android.R;\nimport com.google.zxing.client.result.ParsedResult;\nimport com.google.zxing.client.result.SMSParsedResult;\n\nimport android.app.Activity;\nimport android.telephony.PhoneNumberUtils;\n\n/**\n * Handles SMS addresses, offering a choice of composing a new SMS or MMS message.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n */\npublic final class SMSResultHandler extends ResultHandler {\n  private static int[] buttons;\n\n  public SMSResultHandler(Activity activity, ParsedResult result) {\n    super(activity, result);\n\tbuttons = new int[]{\n\t\tfakeR.getId(\"string\", \"button_sms\"),\n\t\tfakeR.getId(\"string\", \"button_mms\")\n\t};\n  }\n\n  @Override\n  public int getButtonCount() {\n    return buttons.length;\n  }\n\n  @Override\n  public int getButtonText(int index) {\n    return buttons[index];\n  }\n\n  @Override\n  public void handleButtonPress(int index) {\n    SMSParsedResult smsResult = (SMSParsedResult) getResult();\n    switch (index) {\n      case 0:\n        // Don't know of a way yet to express a SENDTO intent with multiple recipients\n        sendSMS(smsResult.getNumbers()[0], smsResult.getBody());\n        break;\n      case 1:\n        sendMMS(smsResult.getNumbers()[0], smsResult.getSubject(), smsResult.getBody());\n        break;\n    }\n  }\n\n  @Override\n  public CharSequence getDisplayContents() {\n    SMSParsedResult smsResult = (SMSParsedResult) getResult();\n    StringBuilder contents = new StringBuilder(50);\n    String[] rawNumbers = smsResult.getNumbers();\n    String[] formattedNumbers = new String[rawNumbers.length];\n    for (int i = 0; i < rawNumbers.length; i++) {\n      formattedNumbers[i] = PhoneNumberUtils.formatNumber(rawNumbers[i]);\n    }\n    ParsedResult.maybeAppend(formattedNumbers, contents);\n    ParsedResult.maybeAppend(smsResult.getSubject(), contents);\n    ParsedResult.maybeAppend(smsResult.getBody(), contents);\n    return contents.toString();\n  }\n\n  @Override\n  public int getDisplayTitle() {\n    return fakeR.getId(\"string\", \"result_sms\");\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/result/TelResultHandler.java",
    "content": "/*\n * Copyright (C) 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.result;\n\nimport com.google.zxing.client.android.R;\nimport com.google.zxing.client.result.ParsedResult;\nimport com.google.zxing.client.result.TelParsedResult;\n\nimport android.app.Activity;\nimport android.telephony.PhoneNumberUtils;\n\n/**\n * Offers relevant actions for telephone numbers.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n */\npublic final class TelResultHandler extends ResultHandler {\n  private static int[] buttons;\n\n  public TelResultHandler(Activity activity, ParsedResult result) {\n    super(activity, result);\n\tbuttons = new int[]{\n\t\tfakeR.getId(\"string\", \"button_dial\"),\n\t\tfakeR.getId(\"string\", \"button_add_contact\")\n\t};\n  }\n\n  @Override\n  public int getButtonCount() {\n    return buttons.length;\n  }\n\n  @Override\n  public int getButtonText(int index) {\n    return buttons[index];\n  }\n\n  @Override\n  public void handleButtonPress(int index) {\n    TelParsedResult telResult = (TelParsedResult) getResult();\n    switch (index) {\n      case 0:\n        dialPhoneFromUri(telResult.getTelURI());\n        // When dialer comes up, it allows underlying display activity to continue or something,\n        // but app can't get camera in this state. Avoid issues by just quitting, only in the\n        // case of a phone number\n        getActivity().finish();\n        break;\n      case 1:\n        String[] numbers = new String[1];\n        numbers[0] = telResult.getNumber();\n        addPhoneOnlyContact(numbers, null);\n        break;\n    }\n  }\n\n  // Overriden so we can take advantage of Android's phone number hyphenation routines.\n  @Override\n  public CharSequence getDisplayContents() {\n    String contents = getResult().getDisplayResult();\n    contents = contents.replace(\"\\r\", \"\");\n    return PhoneNumberUtils.formatNumber(contents);\n  }\n\n  @Override\n  public int getDisplayTitle() {\n    return fakeR.getId(\"string\", \"result_tel\");\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/result/TextResultHandler.java",
    "content": "/*\n * Copyright (C) 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.result;\n\nimport com.google.zxing.Result;\nimport com.google.zxing.client.android.R;\nimport com.google.zxing.client.result.ParsedResult;\n\nimport android.app.Activity;\n\n/**\n * This class handles TextParsedResult as well as unknown formats. It's the fallback handler.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n */\npublic final class TextResultHandler extends ResultHandler {\n\n  private static int[] buttons;\n\n  public TextResultHandler(Activity activity, ParsedResult result, Result rawResult) {\n    super(activity, result, rawResult);\n\tbuttons = new int[]{\n\t\tfakeR.getId(\"string\", \"button_web_search\"),\n\t\tfakeR.getId(\"string\", \"button_share_by_email\"),\n\t\tfakeR.getId(\"string\", \"button_share_by_sms\"),\n\t\tfakeR.getId(\"string\", \"button_custom_product_search\"),\n\t};\n  }\n\n  @Override\n  public int getButtonCount() {\n    return hasCustomProductSearch() ? buttons.length : buttons.length - 1;\n  }\n\n  @Override\n  public int getButtonText(int index) {\n    return buttons[index];\n  }\n\n  @Override\n  public void handleButtonPress(int index) {\n    String text = getResult().getDisplayResult();\n    switch (index) {\n      case 0:\n        webSearch(text);\n        break;\n      case 1:\n        shareByEmail(text);\n        break;\n      case 2:\n        shareBySMS(text);\n        break;\n      case 3:\n        openURL(fillInCustomSearchURL(text));\n        break;\n    }\n  }\n\n  @Override\n  public int getDisplayTitle() {\n    return fakeR.getId(\"string\", \"result_text\");\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/result/URIResultHandler.java",
    "content": "/*\n * Copyright (C) 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.result;\n\nimport com.google.zxing.client.android.LocaleManager;\nimport com.google.zxing.client.android.R;\nimport com.google.zxing.client.result.ParsedResult;\nimport com.google.zxing.client.result.URIParsedResult;\n\nimport android.app.Activity;\n\nimport java.util.Locale;\n\n/**\n * Offers appropriate actions for URLS.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n */\npublic final class URIResultHandler extends ResultHandler {\n  // URIs beginning with entries in this array will not be saved to history or copied to the\n  // clipboard for security.\n  private static final String[] SECURE_PROTOCOLS = {\n    \"otpauth:\"\n  };\n\n  private static int[] buttons;\n\n  public URIResultHandler(Activity activity, ParsedResult result) {\n    super(activity, result);\n\tbuttons = new int[]{\n\t\t  fakeR.getId(\"string\", \"button_open_browser\"),\n\t\t  fakeR.getId(\"string\", \"button_share_by_email\"),\n\t\t  fakeR.getId(\"string\", \"button_share_by_sms\"),\n\t\t  fakeR.getId(\"string\", \"button_search_book_contents\"),\n    };\n  }\n\n  @Override\n  public int getButtonCount() {\n    if (LocaleManager.isBookSearchUrl(((URIParsedResult) getResult()).getURI())) {\n      return buttons.length;\n    }\n    return buttons.length - 1;\n  }\n\n  @Override\n  public int getButtonText(int index) {\n    return buttons[index];\n  }\n\n  @Override\n  public void handleButtonPress(int index) {\n    URIParsedResult uriResult = (URIParsedResult) getResult();\n    String uri = uriResult.getURI();\n    switch (index) {\n      case 0:\n        openURL(uri);\n        break;\n      case 1:\n        shareByEmail(uri);\n        break;\n      case 2:\n        shareBySMS(uri);\n        break;\n      case 3:\n        searchBookContents(uri);\n        break;\n    }\n  }\n\n  @Override\n  public int getDisplayTitle() {\n    return fakeR.getId(\"string\", \"result_uri\");\n  }\n\n  @Override\n  public boolean areContentsSecure() {\n    URIParsedResult uriResult = (URIParsedResult) getResult();\n    String uri = uriResult.getURI().toLowerCase(Locale.ENGLISH);\n    for (String secure : SECURE_PROTOCOLS) {\n      if (uri.startsWith(secure)) {\n        return true;\n      }\n    }\n    return false;\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/result/WifiResultHandler.java",
    "content": "/*\n * Copyright (C) 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.result;\n\nimport android.content.Context;\nimport android.net.wifi.WifiManager;\nimport android.widget.Toast;\n\nimport com.google.zxing.client.android.CaptureActivity;\nimport com.google.zxing.client.android.R;\nimport com.google.zxing.client.android.common.executor.AsyncTaskExecInterface;\nimport com.google.zxing.client.android.common.executor.AsyncTaskExecManager;\nimport com.google.zxing.client.android.wifi.WifiConfigManager;\nimport com.google.zxing.client.result.ParsedResult;\nimport com.google.zxing.client.result.WifiParsedResult;\n\n/**\n * Handles address book entries.\n *\n * @author Vikram Aggarwal\n * @author Sean Owen\n */\npublic final class WifiResultHandler extends ResultHandler {\n\n  private final CaptureActivity parent;\n  private final AsyncTaskExecInterface taskExec;\n\n  public WifiResultHandler(CaptureActivity activity, ParsedResult result) {\n    super(activity, result);\n    parent = activity;\n    taskExec = new AsyncTaskExecManager().build();\n  }\n\n  @Override\n  public int getButtonCount() {\n    // We just need one button, and that is to configure the wireless.  This could change in the future.\n    return 1;\n  }\n\n  @Override\n  public int getButtonText(int index) {\n    return fakeR.getId(\"string\", \"button_wifi\");\n  }\n\n  @Override\n  public void handleButtonPress(int index) {\n    if (index == 0) {\n      WifiParsedResult wifiResult = (WifiParsedResult) getResult();\n      WifiManager wifiManager = (WifiManager) getActivity().getSystemService(Context.WIFI_SERVICE);\n      Toast.makeText(getActivity(), fakeR.getId(\"string\", \"wifi_changing_network\"), Toast.LENGTH_LONG).show();\n      taskExec.execute(new WifiConfigManager(wifiManager), wifiResult);\n      parent.restartPreviewAfterDelay(0L);\n    }\n  }\n\n  // Display the name of the network and the network type to the user.\n  @Override\n  public CharSequence getDisplayContents() {\n    WifiParsedResult wifiResult = (WifiParsedResult) getResult();\n    StringBuilder contents = new StringBuilder(50);\n    String wifiLabel = parent.getString(fakeR.getId(\"string\", \"wifi_ssid_label\"));\n    ParsedResult.maybeAppend(wifiLabel + '\\n' + wifiResult.getSsid(), contents);\n    String typeLabel = parent.getString(fakeR.getId(\"string\", \"wifi_type_label\"));\n    ParsedResult.maybeAppend(typeLabel + '\\n' + wifiResult.getNetworkEncryption(), contents);\n    return contents.toString();\n  }\n\n  @Override\n  public int getDisplayTitle() {\n    return fakeR.getId(\"string\", \"result_wifi\");\n  }\n}"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/result/supplement/BookResultInfoRetriever.java",
    "content": "/*\n * Copyright 2011 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.result.supplement;\n\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Collection;\n\nimport android.content.Context;\nimport android.widget.TextView;\nimport com.google.zxing.FakeR;\nimport com.google.zxing.client.android.HttpHelper;\nimport com.google.zxing.client.android.LocaleManager;\nimport com.google.zxing.client.android.R;\nimport org.json.JSONArray;\nimport org.json.JSONException;\nimport org.json.JSONObject;\nimport org.json.JSONTokener;\n\nimport com.google.zxing.client.android.history.HistoryManager;\n\n/**\n * @author Kamil Kaczmarczyk\n * @author Sean Owen\n */\nfinal class BookResultInfoRetriever extends SupplementalInfoRetriever {\n\n  private final String isbn;\n  private final String source;\n  private final Context context;\n  \n  BookResultInfoRetriever(TextView textView, String isbn, HistoryManager historyManager, Context context) {\n    super(textView, historyManager);\n    this.isbn = isbn;\n    this.source = context.getString(FakeR.getId(context, \"string\", \"msg_google_books\"));\n    this.context = context;\n  }\n\n  @Override\n  void retrieveSupplementalInfo() throws IOException {\n\n    CharSequence contents = HttpHelper.downloadViaHttp(\"https://www.googleapis.com/books/v1/volumes?q=isbn:\" + isbn,\n                                                       HttpHelper.ContentType.JSON);\n\n    if (contents.length() == 0) {\n      return;\n    }\n\n    String title;\n    String pages;\n    Collection<String> authors = null;\n\n    try {\n\n      JSONObject topLevel = (JSONObject) new JSONTokener(contents.toString()).nextValue();\n      JSONArray items = topLevel.optJSONArray(\"items\");\n      if (items == null || items.isNull(0)) {\n        return;\n      }\n\n      JSONObject volumeInfo = ((JSONObject) items.get(0)).getJSONObject(\"volumeInfo\");\n      if (volumeInfo == null) {\n        return;\n      }\n\n      title = volumeInfo.optString(\"title\");\n      pages = volumeInfo.optString(\"pageCount\");\n\n      JSONArray authorsArray = volumeInfo.optJSONArray(\"authors\");\n      if (authorsArray != null && !authorsArray.isNull(0)) {\n        authors = new ArrayList<String>(authorsArray.length());\n        for (int i = 0; i < authorsArray.length(); i++) {\n          authors.add(authorsArray.getString(i));\n        }\n      }\n\n    } catch (JSONException e) {\n      throw new IOException(e.toString());\n    }\n\n    Collection<String> newTexts = new ArrayList<String>();\n\n    if (title != null && title.length() > 0) {\n      newTexts.add(title);\n    }\n\n    if (authors != null && !authors.isEmpty()) {\n      boolean first = true;\n      StringBuilder authorsText = new StringBuilder();\n      for (String author : authors) {\n        if (first) {\n          first = false;\n        } else {\n          authorsText.append(\", \");\n        }\n        authorsText.append(author);\n      }\n      newTexts.add(authorsText.toString());\n    }\n\n    if (pages != null && pages.length() > 0) {\n      newTexts.add(pages + \"pp.\");\n    }\n    \n    String baseBookUri = \"http://www.google.\" + LocaleManager.getBookSearchCountryTLD(context)\n        + \"/search?tbm=bks&source=zxing&q=\";\n\n    append(isbn, source, newTexts.toArray(new String[newTexts.size()]), baseBookUri + isbn);\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/result/supplement/ProductResultInfoRetriever.java",
    "content": "/*\n * Copyright (C) 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.result.supplement;\n\nimport android.content.Context;\nimport android.text.Html;\nimport android.widget.TextView;\nimport com.google.zxing.FakeR;\nimport com.google.zxing.client.android.HttpHelper;\nimport com.google.zxing.client.android.R;\nimport com.google.zxing.client.android.history.HistoryManager;\nimport com.google.zxing.client.android.LocaleManager;\n\nimport java.io.IOException;\nimport java.net.URLEncoder;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\nfinal class ProductResultInfoRetriever extends SupplementalInfoRetriever {\n\n  private static final Pattern[] PRODUCT_NAME_PRICE_PATTERNS = {\n    Pattern.compile(\",event\\\\)\\\">([^<]+)</a></h3>.+<span class=psrp>([^<]+)</span>\"),\n    Pattern.compile(\"owb63p\\\">([^<]+).+zdi3pb\\\">([^<]+)\"),\n  };\n\n  private final String productID;\n  private final String source;\n  private final Context context;\n\n  ProductResultInfoRetriever(TextView textView, String productID, HistoryManager historyManager, Context context) {\n    super(textView, historyManager);\n    this.productID = productID;\n    this.source = context.getString(FakeR.getId(context, \"string\", \"msg_google_product\"));\n    this.context = context;\n  }\n\n  @Override\n  void retrieveSupplementalInfo() throws IOException {\n\n    String encodedProductID = URLEncoder.encode(productID, \"UTF-8\");\n    String uri = \"http://www.google.\" + LocaleManager.getProductSearchCountryTLD(context)\n            + \"/m/products?ie=utf8&oe=utf8&scoring=p&source=zxing&q=\" + encodedProductID;\n    CharSequence content = HttpHelper.downloadViaHttp(uri, HttpHelper.ContentType.HTML);\n\n    for (Pattern p : PRODUCT_NAME_PRICE_PATTERNS) {\n      Matcher matcher = p.matcher(content);\n      if (matcher.find()) {\n        append(productID,\n               source,\n               new String[] { unescapeHTML(matcher.group(1)), unescapeHTML(matcher.group(2)) },\n               uri);\n        break;\n      }\n    }\n  }\n\n  private static String unescapeHTML(String raw) {\n    return Html.fromHtml(raw).toString();\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/result/supplement/SupplementalInfoRetriever.java",
    "content": "/*\n * Copyright (C) 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.result.supplement;\n\nimport android.content.Context;\nimport android.os.AsyncTask;\nimport android.text.Spannable;\nimport android.text.SpannableString;\nimport android.text.Spanned;\nimport android.text.method.LinkMovementMethod;\nimport android.text.style.URLSpan;\nimport android.util.Log;\nimport android.widget.TextView;\n\nimport java.io.IOException;\nimport java.lang.ref.WeakReference;\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport com.google.zxing.client.android.common.executor.AsyncTaskExecInterface;\nimport com.google.zxing.client.android.common.executor.AsyncTaskExecManager;\nimport com.google.zxing.client.android.history.HistoryManager;\nimport com.google.zxing.client.result.ISBNParsedResult;\nimport com.google.zxing.client.result.ParsedResult;\nimport com.google.zxing.client.result.ProductParsedResult;\nimport com.google.zxing.client.result.URIParsedResult;\n\npublic abstract class SupplementalInfoRetriever extends AsyncTask<Object,Object,Object> {\n\n  private static final String TAG = \"SupplementalInfo\";\n\n  public static void maybeInvokeRetrieval(TextView textView,\n                                          ParsedResult result,\n                                          HistoryManager historyManager,\n                                          Context context) {\n    AsyncTaskExecInterface taskExec = new AsyncTaskExecManager().build();\n    if (result instanceof URIParsedResult) {\n      taskExec.execute(new URIResultInfoRetriever(textView, (URIParsedResult) result, historyManager, context));\n      taskExec.execute(new TitleRetriever(textView, (URIParsedResult) result, historyManager));\n    } else if (result instanceof ProductParsedResult) {\n      String productID = ((ProductParsedResult) result).getProductID();\n      taskExec.execute(new ProductResultInfoRetriever(textView, productID, historyManager, context));\n    } else if (result instanceof ISBNParsedResult) {\n      String isbn = ((ISBNParsedResult) result).getISBN();\n      taskExec.execute(new ProductResultInfoRetriever(textView, isbn, historyManager, context));\n      taskExec.execute(new BookResultInfoRetriever(textView, isbn, historyManager, context));\n    }\n  }\n\n  private final WeakReference<TextView> textViewRef;\n  private final WeakReference<HistoryManager> historyManagerRef;\n  private final List<Spannable> newContents;\n  private final List<String[]> newHistories;\n\n  SupplementalInfoRetriever(TextView textView, HistoryManager historyManager) {\n    textViewRef = new WeakReference<TextView>(textView);\n    historyManagerRef = new WeakReference<HistoryManager>(historyManager);\n    newContents = new ArrayList<Spannable>();\n    newHistories = new ArrayList<String[]>();\n  }\n\n  @Override\n  public final Object doInBackground(Object... args) {\n    try {\n      retrieveSupplementalInfo();\n    } catch (IOException e) {\n      Log.w(TAG, e);\n    }\n    return null;\n  }\n\n  @Override\n  protected void onPostExecute(Object arg) {\n    TextView textView = textViewRef.get();\n    if (textView != null) {\n      for (Spannable content : newContents) {\n        textView.append(content);\n      }\n      textView.setMovementMethod(LinkMovementMethod.getInstance());\n    }\n    HistoryManager historyManager = historyManagerRef.get();\n    if (historyManager != null) {\n      for (String[] text : newHistories) {\n        historyManager.addHistoryItemDetails(text[0], text[1]);\n      }\n    }\n  }\n\n  abstract void retrieveSupplementalInfo() throws IOException;\n\n  final void append(String itemID, String source, String[] newTexts, String linkURL) {\n\n    StringBuilder newTextCombined = new StringBuilder();\n\n    if (source != null) {\n      newTextCombined.append(source).append(\" : \");\n    }\n\n    int linkStart = newTextCombined.length();\n\n    boolean first = true;\n    for (String newText : newTexts) {\n      if (first) {\n        newTextCombined.append(newText);\n        first = false;\n      } else {\n        newTextCombined.append(\" [\");\n        newTextCombined.append(newText);\n        newTextCombined.append(']');\n      }\n    }\n\n    int linkEnd = newTextCombined.length();\n\n    String newText = newTextCombined.toString();\n    Spannable content = new SpannableString(newText + \"\\n\\n\");\n    if (linkURL != null) {\n      // Strangely, some Android browsers don't seem to register to handle HTTP:// or HTTPS://.\n      // Lower-case these as it should always be OK to lower-case these schemes.\n      if (linkURL.startsWith(\"HTTP://\")) {\n        linkURL = \"http\" + linkURL.substring(4);\n      } else if (linkURL.startsWith(\"HTTPS://\")) {\n        linkURL = \"https\" + linkURL.substring(5);\n      }\n      content.setSpan(new URLSpan(linkURL), linkStart, linkEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);\n    }\n\n    newContents.add(content);\n    newHistories.add(new String[] {itemID, newText});\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/result/supplement/TitleRetriever.java",
    "content": "/*\n * Copyright 2012 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.result.supplement;\n\nimport android.widget.TextView;\nimport com.google.zxing.client.android.HttpHelper;\nimport com.google.zxing.client.android.history.HistoryManager;\nimport com.google.zxing.client.result.URIParsedResult;\n\nimport java.io.IOException;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\n/**\n * Retrieves the title of a web page as supplemental info.\n *\n * @author Sean Owen\n */\nfinal class TitleRetriever extends SupplementalInfoRetriever {\n\n  private static final Pattern TITLE_PATTERN = Pattern.compile(\"<title>([^<]+)\");\n  private static final int MAX_TITLE_LEN = 100;\n\n  private final String httpUrl;\n\n  TitleRetriever(TextView textView, URIParsedResult result, HistoryManager historyManager) {\n    super(textView, historyManager);\n    this.httpUrl = result.getURI();\n  }\n\n  @Override\n  void retrieveSupplementalInfo() {\n    CharSequence contents;\n    try {\n      contents = HttpHelper.downloadViaHttp(httpUrl, HttpHelper.ContentType.HTML, 4096);\n    } catch (IOException ioe) {\n      // ignore this\n      return;\n    }\n    if (contents != null && contents.length() > 0) {\n      Matcher m = TITLE_PATTERN.matcher(contents);\n      if (m.find()) {\n        String title = m.group(1);\n        if (title != null && title.length() > 0) {\n          if (title.length() > MAX_TITLE_LEN) {\n            title = title.substring(0, MAX_TITLE_LEN) + \"...\";\n          }\n          append(httpUrl, null, new String[] {title}, httpUrl);\n        }\n      }\n    }\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/result/supplement/URIResultInfoRetriever.java",
    "content": "/*\n * Copyright (C) 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.result.supplement;\n\nimport android.content.Context;\nimport android.widget.TextView;\nimport com.google.zxing.FakeR;\nimport com.google.zxing.client.android.HttpHelper;\nimport com.google.zxing.client.android.history.HistoryManager;\nimport com.google.zxing.client.android.R;\nimport com.google.zxing.client.result.URIParsedResult;\n\nimport java.io.IOException;\nimport java.net.URI;\nimport java.net.URISyntaxException;\n\nfinal class URIResultInfoRetriever extends SupplementalInfoRetriever {\n\n  private static final int MAX_REDIRECTS = 5;\n\n  private final URIParsedResult result;\n  private final String redirectString;\n\n  URIResultInfoRetriever(TextView textView, URIParsedResult result, HistoryManager historyManager, Context context) {\n    super(textView, historyManager);\n    redirectString = context.getString(FakeR.getId(context, \"string\", \"msg_redirect\"));\n    this.result = result;\n  }\n\n  @Override\n  void retrieveSupplementalInfo() throws IOException {\n    URI oldURI;\n    try {\n      oldURI = new URI(result.getURI());\n    } catch (URISyntaxException e) {\n      return;\n    }\n    URI newURI = HttpHelper.unredirect(oldURI);\n    int count = 0;\n    while (count++ < MAX_REDIRECTS && !oldURI.equals(newURI)) {\n      append(result.getDisplayResult(), \n             null, \n             new String[] { redirectString + \" : \" + newURI }, \n             newURI.toString());\n      oldURI = newURI;\n      newURI = HttpHelper.unredirect(newURI);\n    }\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/share/AppPickerActivity.java",
    "content": "/*\n * Copyright (C) 2009 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.share;\n\nimport android.app.ListActivity;\nimport android.content.Intent;\nimport android.provider.Browser;\nimport android.view.View;\nimport android.widget.ListView;\n\nimport com.google.zxing.client.android.common.executor.AsyncTaskExecInterface;\nimport com.google.zxing.client.android.common.executor.AsyncTaskExecManager;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic final class AppPickerActivity extends ListActivity {\n\n  private final List<String[]> labelsPackages;\n  private LoadPackagesAsyncTask backgroundTask;\n  private final AsyncTaskExecInterface taskExec;\n\n  public AppPickerActivity() {\n    labelsPackages = new ArrayList<String[]>();\n    taskExec = new AsyncTaskExecManager().build();\n  }\n\n  @Override\n  protected void onResume() {\n    super.onResume();\n    labelsPackages.clear();\n    backgroundTask = new LoadPackagesAsyncTask(this);\n    taskExec.execute(backgroundTask, labelsPackages);\n  }\n\n  @Override\n  protected void onPause() {\n    LoadPackagesAsyncTask task = backgroundTask;\n    if (task != null) {\n      task.cancel(true);\n      backgroundTask = null;\n    }\n    super.onPause();\n  }\n\n  @Override\n  protected void onListItemClick(ListView l, View view, int position, long id) {\n    if (position >= 0 && position < labelsPackages.size()) {\n      String url = \"market://details?id=\" + labelsPackages.get(position)[1];\n      Intent intent = new Intent();\n      intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);\n      intent.putExtra(Browser.BookmarkColumns.URL, url);\n      setResult(RESULT_OK, intent);\n    } else {\n      setResult(RESULT_CANCELED);\n    }\n    finish();\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/share/BookmarkAdapter.java",
    "content": "/*\n * Copyright (C) 2011 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.share;\n\nimport com.google.zxing.client.android.R;\n\nimport android.content.Context;\nimport android.database.Cursor;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.BaseAdapter;\nimport android.widget.LinearLayout;\nimport android.widget.TextView;\nimport com.google.zxing.FakeR;\n\n/**\n * A custom adapter designed to fetch bookmarks from a cursor. Before Honeycomb we used\n * SimpleCursorAdapter, but it assumes the existence of an _id column, and the bookmark schema was\n * rewritten for HC without one. This caused the app to crash, hence this new class, which is\n * forwards and backwards compatible.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n */\nfinal class BookmarkAdapter extends BaseAdapter {\n  private final Context context;\n  private final Cursor cursor;\n\n  private static FakeR fakeR;\n  BookmarkAdapter(Context context, Cursor cursor) {\n\tfakeR = new FakeR(context);\n    this.context = context;\n    this.cursor = cursor;\n  }\n\n  @Override\n  public int getCount() {\n    return cursor.getCount();\n  }\n\n  @Override\n  public Object getItem(int index) {\n    // Not used, so no point in retrieving it.\n    return null;\n  }\n\n  @Override\n  public long getItemId(int index) {\n    return index;\n  }\n\n  @Override\n  public View getView(int index, View view, ViewGroup viewGroup) {\n    LinearLayout layout;\n    if (view instanceof LinearLayout) {\n      layout = (LinearLayout) view;\n    } else {\n      LayoutInflater factory = LayoutInflater.from(context);\n      layout = (LinearLayout) factory.inflate(fakeR.getId(\"layout\", \"bookmark_picker_list_item\"), viewGroup, false);\n    }\n\n    if (!cursor.isClosed()) {\n      cursor.moveToPosition(index);\n      String title = cursor.getString(BookmarkPickerActivity.TITLE_COLUMN);\n      ((TextView) layout.findViewById(fakeR.getId(\"id\", \"bookmark_title\"))).setText(title);\n      String url = cursor.getString(BookmarkPickerActivity.URL_COLUMN);\n      ((TextView) layout.findViewById(fakeR.getId(\"id\", \"bookmark_url\"))).setText(url);\n    } // Otherwise... just don't update as the object is shutting down\n    return layout;\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/share/BookmarkPickerActivity.java",
    "content": "/*\n * Copyright (C) 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.share;\n\nimport android.app.ListActivity;\nimport android.content.Intent;\nimport android.database.Cursor;\nimport android.os.Bundle;\nimport android.provider.Browser;\nimport android.util.Log;\nimport android.view.View;\nimport android.widget.ListView;\n\n/**\n * This class is only needed because I can't successfully send an ACTION_PICK intent to\n * com.android.browser.BrowserBookmarksPage. It can go away if that starts working in the future.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n */\npublic final class BookmarkPickerActivity extends ListActivity {\n\n  private static final String TAG = BookmarkPickerActivity.class.getSimpleName();\n\n  private static final String[] BOOKMARK_PROJECTION = {\n      Browser.BookmarkColumns.TITLE,\n      Browser.BookmarkColumns.URL\n  };\n\n  static final int TITLE_COLUMN = 0;\n  static final int URL_COLUMN = 1;\n\n  // Without this selection, we'd get all the history entries too\n  private static final String BOOKMARK_SELECTION = \"bookmark = 1\";\n\n  private Cursor cursor = null;\n\n  @Override\n  protected void onCreate(Bundle icicle) {\n    super.onCreate(icicle);\n\n    cursor = getContentResolver().query(Browser.BOOKMARKS_URI, BOOKMARK_PROJECTION,\n        BOOKMARK_SELECTION, null, null);\n    if (cursor == null) {\n      Log.w(TAG, \"No cursor returned for bookmark query\");\n      finish();\n    } else {\n      startManagingCursor(cursor);\n      setListAdapter(new BookmarkAdapter(this, cursor));\n    }\n  }\n\n  @Override\n  protected void onListItemClick(ListView l, View view, int position, long id) {\n    if (!cursor.isClosed() && cursor.moveToPosition(position)) {\n      Intent intent = new Intent();\n      intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);\n      intent.putExtra(Browser.BookmarkColumns.TITLE, cursor.getString(TITLE_COLUMN));\n      intent.putExtra(Browser.BookmarkColumns.URL, cursor.getString(URL_COLUMN));\n      setResult(RESULT_OK, intent);\n    } else {\n      setResult(RESULT_CANCELED);\n    }\n    finish();\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/share/LoadPackagesAsyncTask.java",
    "content": "/*\n * Copyright (C) 2009 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.share;\n\nimport android.content.pm.ApplicationInfo;\nimport android.content.pm.PackageManager;\nimport android.os.AsyncTask;\nimport android.widget.ArrayAdapter;\nimport android.widget.ListAdapter;\n\nimport java.io.Serializable;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.List;\n\n/**\n * Loads a list of packages installed on the device asynchronously.\n *\n * @author Sean Owen\n */\nfinal class LoadPackagesAsyncTask extends AsyncTask<List<String[]>,Object,List<String[]>> {\n\n  private static final String[] PKG_PREFIX_WHITELIST = {\n      \"com.google.android.apps.\",\n  };\n  private static final String[] PKG_PREFIX_BLACKLIST = {\n      \"com.android.\",\n      \"android\",\n      \"com.google.android.\",\n      \"com.htc\",\n  };\n\n  private final AppPickerActivity activity;\n\n  LoadPackagesAsyncTask(AppPickerActivity activity) {\n    this.activity = activity;\n  }\n\n  @Override\n  protected List<String[]> doInBackground(List<String[]>... objects) {\n    List<String[]> labelsPackages = objects[0];\n    PackageManager packageManager = activity.getPackageManager();\n    List<ApplicationInfo> appInfos = packageManager.getInstalledApplications(0);\n    for (ApplicationInfo appInfo : appInfos) {\n      CharSequence label = appInfo.loadLabel(packageManager);\n      if (label != null) {\n        String packageName = appInfo.packageName;\n        if (!isHidden(packageName)) {\n          labelsPackages.add(new String[]{label.toString(), packageName});\n        }\n      }\n    }\n    Collections.sort(labelsPackages, new ByFirstStringComparator());\n    return labelsPackages;\n  }\n\n  private static boolean isHidden(String packageName) {\n    if (packageName == null) {\n      return true;\n    }\n    for (String prefix : PKG_PREFIX_WHITELIST) {\n      if (packageName.startsWith(prefix)) {\n        return false;\n      }\n    }\n    for (String prefix : PKG_PREFIX_BLACKLIST) {\n      if (packageName.startsWith(prefix)) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  @Override\n  protected synchronized void onPostExecute(List<String[]> results) {\n    List<String> labels = new ArrayList<String>(results.size());\n    for (String[] result : results) {\n      labels.add(result[0]);\n    }\n    ListAdapter listAdapter = new ArrayAdapter<String>(activity,\n        android.R.layout.simple_list_item_1, labels);\n    activity.setListAdapter(listAdapter);\n  }\n\n  private static class ByFirstStringComparator implements Comparator<String[]>, Serializable {\n    @Override\n    public int compare(String[] o1, String[] o2) {\n      return o1[0].compareTo(o2[0]);\n    }\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/share/ShareActivity.java",
    "content": "/*\n * Copyright (C) 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.share;\n\nimport android.provider.ContactsContract;\nimport com.google.zxing.BarcodeFormat;\nimport com.google.zxing.client.android.Contents;\nimport com.google.zxing.client.android.Intents;\nimport com.google.zxing.client.android.R;\n\nimport android.app.Activity;\nimport android.content.ContentResolver;\nimport android.content.Intent;\nimport android.database.Cursor;\nimport android.net.Uri;\nimport android.os.Bundle;\nimport android.provider.BaseColumns;\nimport android.provider.Browser;\nimport android.text.ClipboardManager;\nimport android.util.Log;\nimport android.view.KeyEvent;\nimport android.view.View;\nimport android.widget.Button;\nimport android.widget.TextView;\nimport com.google.zxing.FakeR;\n\n/**\n * Barcode Scanner can share data like contacts and bookmarks by displaying a QR Code on screen,\n * such that another user can scan the barcode with their phone.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n */\npublic final class ShareActivity extends Activity {\n\n  private static final String TAG = ShareActivity.class.getSimpleName();\n\n  private static final int PICK_BOOKMARK = 0;\n  private static final int PICK_CONTACT = 1;\n  private static final int PICK_APP = 2;\n\n  private Button clipboardButton;\n\n  private static FakeR fakeR;\n\n  private final Button.OnClickListener contactListener = new Button.OnClickListener() {\n    @Override\n    public void onClick(View v) {\n      Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);\n      intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);\n      startActivityForResult(intent, PICK_CONTACT);\n    }\n  };\n\n  private final Button.OnClickListener bookmarkListener = new Button.OnClickListener() {\n    @Override\n    public void onClick(View v) {\n      Intent intent = new Intent(Intent.ACTION_PICK);\n      intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);\n      intent.setClassName(ShareActivity.this, BookmarkPickerActivity.class.getName());\n      startActivityForResult(intent, PICK_BOOKMARK);\n    }\n  };\n\n  private final Button.OnClickListener appListener = new Button.OnClickListener() {\n    @Override\n    public void onClick(View v) {\n      Intent intent = new Intent(Intent.ACTION_PICK);\n      intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);\n      intent.setClassName(ShareActivity.this, AppPickerActivity.class.getName());\n      startActivityForResult(intent, PICK_APP);\n    }\n  };\n\n  private final Button.OnClickListener clipboardListener = new Button.OnClickListener() {\n    @Override\n    public void onClick(View v) {\n      ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);\n      // Should always be true, because we grey out the clipboard button in onResume() if it's empty\n      if (clipboard.hasText()) {\n        launchSearch(clipboard.getText().toString());\n      }\n    }\n  };\n\n  private final View.OnKeyListener textListener = new View.OnKeyListener() {\n    @Override\n    public boolean onKey(View view, int keyCode, KeyEvent event) {\n      if (keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_DOWN) {\n        String text = ((TextView) view).getText().toString();\n        if (text != null && text.length() > 0) {\n          launchSearch(text);\n        }\n        return true;\n      }\n      return false;\n    }\n  };\n\n  private void launchSearch(String text) {\n    Intent intent = new Intent(Intents.Encode.ACTION);\n    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);\n    intent.putExtra(Intents.Encode.TYPE, Contents.Type.TEXT);\n    intent.putExtra(Intents.Encode.DATA, text);\n    intent.putExtra(Intents.Encode.FORMAT, BarcodeFormat.QR_CODE.toString());\n    startActivity(intent);\n  }\n\n  @Override\n  public void onCreate(Bundle icicle) {\n    super.onCreate(icicle);\n\tfakeR = new FakeR(this);\n    setContentView(fakeR.getId(\"layout\", \"share\"));\n\n    findViewById(fakeR.getId(\"id\", \"share_contact_button\")).setOnClickListener(contactListener);\n    findViewById(fakeR.getId(\"id\", \"share_bookmark_button\")).setOnClickListener(bookmarkListener);\n    findViewById(fakeR.getId(\"id\", \"share_app_button\")).setOnClickListener(appListener);\n    clipboardButton = (Button) findViewById(fakeR.getId(\"id\", \"share_clipboard_button\"));\n    clipboardButton.setOnClickListener(clipboardListener);\n    findViewById(fakeR.getId(\"id\", \"share_text_view\")).setOnKeyListener(textListener);\n  }\n\n  @Override\n  protected void onResume() {\n    super.onResume();\n    ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);\n    clipboardButton.setEnabled(clipboard.hasText());\n  }\n\n  @Override\n  public void onActivityResult(int requestCode, int resultCode, Intent intent) {\n    if (resultCode == RESULT_OK) {\n      switch (requestCode) {\n        case PICK_BOOKMARK:\n        case PICK_APP:\n          showTextAsBarcode(intent.getStringExtra(Browser.BookmarkColumns.URL));\n          break;\n        case PICK_CONTACT:\n          // Data field is content://contacts/people/984\n          showContactAsBarcode(intent.getData());\n          break;\n      }\n    }\n  }\n\n  private void showTextAsBarcode(String text) {\n    Log.i(TAG, \"Showing text as barcode: \" + text);\n    if (text == null) {\n      return; // Show error?\n    }\n    Intent intent = new Intent(Intents.Encode.ACTION);\n    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);\n    intent.putExtra(Intents.Encode.TYPE, Contents.Type.TEXT);\n    intent.putExtra(Intents.Encode.DATA, text);\n    intent.putExtra(Intents.Encode.FORMAT, BarcodeFormat.QR_CODE.toString());\n    startActivity(intent);\n  }\n\n  /**\n   * Takes a contact Uri and does the necessary database lookups to retrieve that person's info,\n   * then sends an Encode intent to render it as a QR Code.\n   *\n   * @param contactUri A Uri of the form content://contacts/people/17\n   */\n  private void showContactAsBarcode(Uri contactUri) {\n    Log.i(TAG, \"Showing contact URI as barcode: \" + contactUri);\n    if (contactUri == null) {\n      return; // Show error?\n    }\n    ContentResolver resolver = getContentResolver();\n    Bundle bundle = new Bundle();\n\n    Cursor cursor;\n    try {\n      // We're seeing about six reports a week of this exception although I don't understand why.\n      cursor = resolver.query(contactUri, null, null, null, null);\n    } catch (IllegalArgumentException e) {\n      return;\n    }\n    if (cursor == null) {\n      return;\n    }\n\n    String id;\n    String name;\n    boolean hasPhone;\n    try {\n      if (!cursor.moveToFirst()) {\n        return;\n      }\n\n      id = cursor.getString(cursor.getColumnIndex(BaseColumns._ID));\n      name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));\n      hasPhone = cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)) > 0;\n\n\n    } finally {\n      cursor.close();\n    }\n\n    // Don't require a name to be present, this contact might be just a phone number.\n    if (name != null && name.length() > 0) {\n      bundle.putString(ContactsContract.Intents.Insert.NAME, massageContactData(name));\n    }\n\n    if (hasPhone) {\n      Cursor phonesCursor = resolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,\n                                           null,\n                                           ContactsContract.CommonDataKinds.Phone.CONTACT_ID + '=' + id,\n                                           null,\n                                           null);\n      if (phonesCursor != null) {\n        try {\n          int foundPhone = 0;\n          int phonesNumberColumn = phonesCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);\n          while (phonesCursor.moveToNext() && foundPhone < Contents.PHONE_KEYS.length) {\n            String number = phonesCursor.getString(phonesNumberColumn);\n            if (number != null && number.length() > 0) {\n              bundle.putString(Contents.PHONE_KEYS[foundPhone], massageContactData(number));\n            }\n            foundPhone++;\n          }\n        } finally {\n          phonesCursor.close();\n        }\n      }\n    }\n\n    Cursor methodsCursor = resolver.query(ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_URI,\n                                          null,\n                                          ContactsContract.CommonDataKinds.StructuredPostal.CONTACT_ID + '=' + id,\n                                          null,\n                                          null);\n    if (methodsCursor != null) {\n      try {\n        if (methodsCursor.moveToNext()) {\n          String data = methodsCursor.getString(\n              methodsCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.FORMATTED_ADDRESS));\n          if (data != null && data.length() > 0) {\n            bundle.putString(ContactsContract.Intents.Insert.POSTAL, massageContactData(data));\n          }\n        }\n      } finally {\n        methodsCursor.close();\n      }\n    }\n\n    Cursor emailCursor = resolver.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI,\n                                        null,\n                                        ContactsContract.CommonDataKinds.Email.CONTACT_ID + '=' + id,\n                                        null,\n                                        null);\n    if (emailCursor != null) {\n      try {\n        int foundEmail = 0;\n        int emailColumn = emailCursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA);\n        while (emailCursor.moveToNext() && foundEmail < Contents.EMAIL_KEYS.length) {\n          String email = emailCursor.getString(emailColumn);\n          if (email != null && email.length() > 0) {\n            bundle.putString(Contents.EMAIL_KEYS[foundEmail], massageContactData(email));\n          }\n          foundEmail++;\n        }\n      } finally {\n        emailCursor.close();\n      }\n    }\n\n    Intent intent = new Intent(Intents.Encode.ACTION);\n    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);\n    intent.putExtra(Intents.Encode.TYPE, Contents.Type.CONTACT);\n    intent.putExtra(Intents.Encode.DATA, bundle);\n    intent.putExtra(Intents.Encode.FORMAT, BarcodeFormat.QR_CODE.toString());\n\n    Log.i(TAG, \"Sending bundle for encoding: \" + bundle);\n    startActivity(intent);\n  }\n\n  private static String massageContactData(String data) {\n    // For now -- make sure we don't put newlines in shared contact data. It messes up\n    // any known encoding of contact data. Replace with space.\n    if (data.indexOf('\\n') >= 0) {\n      data = data.replace(\"\\n\", \" \");\n    }\n    if (data.indexOf('\\r') >= 0) {\n      data = data.replace(\"\\r\", \" \");\n    }\n    return data;\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/wifi/NetworkType.java",
    "content": "/*\n * Copyright (C) 2011 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.wifi;\n\nenum NetworkType {\n\n  WEP,\n  WPA,\n  NO_PASSWORD;\n\n  static NetworkType forIntentValue(String networkTypeString) {\n    if (networkTypeString == null) {\n      return NO_PASSWORD;\n    }\n    if (\"WPA\".equals(networkTypeString)) {\n      return WPA;\n    }\n    if (\"WEP\".equals(networkTypeString)) {\n      return WEP;\n    }\n    if (\"nopass\".equals(networkTypeString)) {\n      return NO_PASSWORD;\n    }\n    throw new IllegalArgumentException(networkTypeString);\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/android/wifi/WifiConfigManager.java",
    "content": "/*\n * Copyright (C) 2011 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.android.wifi;\n\nimport android.net.wifi.WifiConfiguration;\nimport android.net.wifi.WifiManager;\nimport android.os.AsyncTask;\nimport android.util.Log;\n\nimport java.util.List;\nimport java.util.regex.Pattern;\n\nimport com.google.zxing.client.result.WifiParsedResult;\n\n/**\n * @author Vikram Aggarwal\n * @author Sean Owen\n */\npublic final class WifiConfigManager extends AsyncTask<WifiParsedResult,Object,Object> {\n\n  private static final String TAG = WifiConfigManager.class.getSimpleName();\n\n  private static final Pattern HEX_DIGITS = Pattern.compile(\"[0-9A-Fa-f]+\");\n\n  private final WifiManager wifiManager;\n\n  public WifiConfigManager(WifiManager wifiManager) {\n    this.wifiManager = wifiManager;\n  }\n\n  @Override\n  protected Object doInBackground(WifiParsedResult... args) {\n    WifiParsedResult theWifiResult = args[0];\n    // Start WiFi, otherwise nothing will work\n    if (!wifiManager.isWifiEnabled()) {\n      Log.i(TAG, \"Enabling wi-fi...\");\n      if (wifiManager.setWifiEnabled(true)) {\n        Log.i(TAG, \"Wi-fi enabled\");\n      } else {\n        Log.w(TAG, \"Wi-fi could not be enabled!\");\n        return null;\n      }\n      // This happens very quickly, but need to wait for it to enable. A little busy wait?\n      int count = 0;\n      while (!wifiManager.isWifiEnabled()) {\n        if (count >= 10) {\n          Log.i(TAG, \"Took too long to enable wi-fi, quitting\");\n          return null;\n        }\n        Log.i(TAG, \"Still waiting for wi-fi to enable...\");\n        try {\n          Thread.sleep(1000L);\n        } catch (InterruptedException ie) {\n          // continue\n        }\n        count++;\n      }\n    }\n    String networkTypeString = theWifiResult.getNetworkEncryption();\n    NetworkType networkType;\n    try {\n      networkType = NetworkType.forIntentValue(networkTypeString);\n    } catch (IllegalArgumentException iae) {\n      Log.w(TAG, \"Bad network type; see NetworkType values: \" + networkTypeString);\n      return null;\n    }\n    if (networkType == NetworkType.NO_PASSWORD) {\n      changeNetworkUnEncrypted(wifiManager, theWifiResult);\n    } else {\n      String password = theWifiResult.getPassword();\n      if (password != null && password.length() != 0) {\n        if (networkType == NetworkType.WEP) {\n          changeNetworkWEP(wifiManager, theWifiResult);\n        } else if (networkType == NetworkType.WPA) {\n          changeNetworkWPA(wifiManager, theWifiResult);\n        }\n      }\n    }\n    return null;\n  }\n\n  /**\n   * Update the network: either create a new network or modify an existing network\n   * @param config the new network configuration\n   * @return network ID of the connected network.\n   */\n  private static void updateNetwork(WifiManager wifiManager, WifiConfiguration config) {\n    Integer foundNetworkID = findNetworkInExistingConfig(wifiManager, config.SSID);\n    if (foundNetworkID != null) {\n      Log.i(TAG, \"Removing old configuration for network \" + config.SSID);\n      wifiManager.removeNetwork(foundNetworkID);\n      wifiManager.saveConfiguration();\n    }\n    int networkId = wifiManager.addNetwork(config);\n    if (networkId >= 0) {\n      // Try to disable the current network and start a new one.\n      if (wifiManager.enableNetwork(networkId, true)) {\n        Log.i(TAG, \"Associating to network \" + config.SSID);\n        wifiManager.saveConfiguration();\n      } else {\n        Log.w(TAG, \"Failed to enable network \" + config.SSID);\n      }\n    } else {\n      Log.w(TAG, \"Unable to add network \" + config.SSID);\n    }\n  }\n\n  private static WifiConfiguration changeNetworkCommon(WifiParsedResult wifiResult) {\n    WifiConfiguration config = new WifiConfiguration();\n    config.allowedAuthAlgorithms.clear();\n    config.allowedGroupCiphers.clear();\n    config.allowedKeyManagement.clear();\n    config.allowedPairwiseCiphers.clear();\n    config.allowedProtocols.clear();\n    // Android API insists that an ascii SSID must be quoted to be correctly handled.\n    config.SSID = quoteNonHex(wifiResult.getSsid());\n    config.hiddenSSID = wifiResult.isHidden();\n    return config;\n  }\n\n  // Adding a WEP network\n  private static void changeNetworkWEP(WifiManager wifiManager, WifiParsedResult wifiResult) {\n    WifiConfiguration config = changeNetworkCommon(wifiResult);\n    config.wepKeys[0] = quoteNonHex(wifiResult.getPassword(), 10, 26, 58);\n    config.wepTxKeyIndex = 0;\n    config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);\n    config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);\n    config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);\n    config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);\n    config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);\n    config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);\n    updateNetwork(wifiManager, config);\n  }\n\n  // Adding a WPA or WPA2 network\n  private static void changeNetworkWPA(WifiManager wifiManager, WifiParsedResult wifiResult) {\n    WifiConfiguration config = changeNetworkCommon(wifiResult);\n    // Hex passwords that are 64 bits long are not to be quoted.\n    config.preSharedKey = quoteNonHex(wifiResult.getPassword(), 64);\n    config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);\n    config.allowedProtocols.set(WifiConfiguration.Protocol.WPA); // For WPA\n    config.allowedProtocols.set(WifiConfiguration.Protocol.RSN); // For WPA2\n    config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);\n    config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);\n    config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);\n    config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);\n    config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);\n    config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);\n    updateNetwork(wifiManager, config);\n  }\n\n  // Adding an open, unsecured network\n  private static void changeNetworkUnEncrypted(WifiManager wifiManager, WifiParsedResult wifiResult) {\n    WifiConfiguration config = changeNetworkCommon(wifiResult);\n    config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);\n    updateNetwork(wifiManager, config);\n  }\n\n  private static Integer findNetworkInExistingConfig(WifiManager wifiManager, String ssid) {\n    List<WifiConfiguration> existingConfigs = wifiManager.getConfiguredNetworks();\n    for (WifiConfiguration existingConfig : existingConfigs) {\n      if (existingConfig.SSID.equals(ssid)) {\n        return existingConfig.networkId;\n      }\n    }\n    return null;\n  }\n\n  private static String quoteNonHex(String value, int... allowedLengths) {\n    return isHexOfLength(value, allowedLengths) ? value : convertToQuotedString(value);\n  }\n\n  /**\n   * Encloses the incoming string inside double quotes, if it isn't already quoted.\n   * @param string the input string\n   * @return a quoted string, of the form \"input\".  If the input string is null, it returns null\n   * as well.\n   */\n  private static String convertToQuotedString(String string) {\n    if (string == null || string.length() == 0) {\n      return null;\n    }\n    // If already quoted, return as-is\n    if (string.charAt(0) == '\"' && string.charAt(string.length() - 1) == '\"') {\n      return string;\n    }\n    return '\\\"' + string + '\\\"';\n  }\n\n  /**\n   * @param value input to check\n   * @param allowedLengths allowed lengths, if any\n   * @return true if value is a non-null, non-empty string of hex digits, and if allowed lengths are given, has\n   *  an allowed length\n   */\n  private static boolean isHexOfLength(CharSequence value, int... allowedLengths) {\n    if (value == null || !HEX_DIGITS.matcher(value).matches()) {\n      return false;\n    }\n    if (allowedLengths.length == 0) {\n      return true;\n    }\n    for (int length : allowedLengths) {\n      if (value.length() == length) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/result/AbstractDoCoMoResultParser.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.result;\n\n/**\n * <p>See\n * <a href=\"http://www.nttdocomo.co.jp/english/service/imode/make/content/barcode/about/s2.html\">\n * DoCoMo's documentation</a> about the result types represented by subclasses of this class.</p>\n *\n * <p>Thanks to Jeff Griffin for proposing rewrite of these classes that relies less\n * on exception-based mechanisms during parsing.</p>\n *\n * @author Sean Owen\n */\nabstract class AbstractDoCoMoResultParser extends ResultParser {\n\n  static String[] matchDoCoMoPrefixedField(String prefix, String rawText, boolean trim) {\n    return matchPrefixedField(prefix, rawText, ';', trim);\n  }\n\n  static String matchSingleDoCoMoPrefixedField(String prefix, String rawText, boolean trim) {\n    return matchSinglePrefixedField(prefix, rawText, ';', trim);\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/result/AddressBookAUResultParser.java",
    "content": "/*\n * Copyright 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.result;\n\nimport com.google.zxing.Result;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Implements KDDI AU's address book format. See\n * <a href=\"http://www.au.kddi.com/ezfactory/tec/two_dimensions/index.html\">\n * http://www.au.kddi.com/ezfactory/tec/two_dimensions/index.html</a>.\n * (Thanks to Yuzo for translating!)\n *\n * @author Sean Owen\n */\npublic final class AddressBookAUResultParser extends ResultParser {\n\n  @Override\n  public AddressBookParsedResult parse(Result result) {\n    String rawText = getMassagedText(result);\n    // MEMORY is mandatory; seems like a decent indicator, as does end-of-record separator CR/LF\n    if (!rawText.contains(\"MEMORY\") || !rawText.contains(\"\\r\\n\")) {\n      return null;\n    }\n\n    // NAME1 and NAME2 have specific uses, namely written name and pronunciation, respectively.\n    // Therefore we treat them specially instead of as an array of names.\n    String name = matchSinglePrefixedField(\"NAME1:\", rawText, '\\r', true);\n    String pronunciation = matchSinglePrefixedField(\"NAME2:\", rawText, '\\r', true);\n\n    String[] phoneNumbers = matchMultipleValuePrefix(\"TEL\", 3, rawText, true);\n    String[] emails = matchMultipleValuePrefix(\"MAIL\", 3, rawText, true);\n    String note = matchSinglePrefixedField(\"MEMORY:\", rawText, '\\r', false);\n    String address = matchSinglePrefixedField(\"ADD:\", rawText, '\\r', true);\n    String[] addresses = address == null ? null : new String[] {address};\n    return new AddressBookParsedResult(maybeWrap(name),\n                                       pronunciation,\n                                       phoneNumbers,\n                                       null,\n                                       emails,\n                                       null,\n                                       null,\n                                       note,\n                                       addresses,\n                                       null,\n                                       null,\n                                       null,\n                                       null,\n                                       null);\n  }\n\n  private static String[] matchMultipleValuePrefix(String prefix,\n                                                   int max,\n                                                   String rawText,\n                                                   boolean trim) {\n    List<String> values = null;\n    for (int i = 1; i <= max; i++) {\n      String value = matchSinglePrefixedField(prefix + i + ':', rawText, '\\r', trim);\n      if (value == null) {\n        break;\n      }\n      if (values == null) {\n        values = new ArrayList<String>(max); // lazy init\n      }\n      values.add(value);\n    }\n    if (values == null) {\n      return null;\n    }\n    return values.toArray(new String[values.size()]);\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/result/AddressBookDoCoMoResultParser.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.result;\n\nimport com.google.zxing.Result;\n\n/**\n * Implements the \"MECARD\" address book entry format.\n *\n * Supported keys: N, SOUND, TEL, EMAIL, NOTE, ADR, BDAY, URL, plus ORG\n * Unsupported keys: TEL-AV, NICKNAME\n *\n * Except for TEL, multiple values for keys are also not supported;\n * the first one found takes precedence.\n *\n * Our understanding of the MECARD format is based on this document:\n *\n * http://www.mobicode.org.tw/files/OMIA%20Mobile%20Bar%20Code%20Standard%20v3.2.1.doc \n *\n * @author Sean Owen\n */\npublic final class AddressBookDoCoMoResultParser extends AbstractDoCoMoResultParser {\n\n  @Override\n  public AddressBookParsedResult parse(Result result) {\n    String rawText = getMassagedText(result);\n    if (!rawText.startsWith(\"MECARD:\")) {\n      return null;\n    }\n    String[] rawName = matchDoCoMoPrefixedField(\"N:\", rawText, true);\n    if (rawName == null) {\n      return null;\n    }\n    String name = parseName(rawName[0]);\n    String pronunciation = matchSingleDoCoMoPrefixedField(\"SOUND:\", rawText, true);\n    String[] phoneNumbers = matchDoCoMoPrefixedField(\"TEL:\", rawText, true);\n    String[] emails = matchDoCoMoPrefixedField(\"EMAIL:\", rawText, true);\n    String note = matchSingleDoCoMoPrefixedField(\"NOTE:\", rawText, false);\n    String[] addresses = matchDoCoMoPrefixedField(\"ADR:\", rawText, true);\n    String birthday = matchSingleDoCoMoPrefixedField(\"BDAY:\", rawText, true);\n    if (birthday != null && !isStringOfDigits(birthday, 8)) {\n      // No reason to throw out the whole card because the birthday is formatted wrong.\n      birthday = null;\n    }\n    String url = matchSingleDoCoMoPrefixedField(\"URL:\", rawText, true);\n\n    // Although ORG may not be strictly legal in MECARD, it does exist in VCARD and we might as well\n    // honor it when found in the wild.\n    String org = matchSingleDoCoMoPrefixedField(\"ORG:\", rawText, true);\n\n    return new AddressBookParsedResult(maybeWrap(name),\n                                       pronunciation,\n                                       phoneNumbers,\n                                       null,\n                                       emails,\n                                       null,\n                                       null,\n                                       note,\n                                       addresses,\n                                       null,\n                                       org,\n                                       birthday,\n                                       null,\n                                       url);\n  }\n\n  private static String parseName(String name) {\n    int comma = name.indexOf((int) ',');\n    if (comma >= 0) {\n      // Format may be last,first; switch it around\n      return name.substring(comma + 1) + ' ' + name.substring(0, comma);\n    }\n    return name;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/result/AddressBookParsedResult.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.result;\n\n/**\n * @author Sean Owen\n */\npublic final class AddressBookParsedResult extends ParsedResult {\n\n  private final String[] names;\n  private final String pronunciation;\n  private final String[] phoneNumbers;\n  private final String[] phoneTypes;\n  private final String[] emails;\n  private final String[] emailTypes;\n  private final String instantMessenger;\n  private final String note;\n  private final String[] addresses;\n  private final String[] addressTypes;\n  private final String org;\n  private final String birthday;\n  private final String title;\n  private final String url;\n\n  public AddressBookParsedResult(String[] names,\n                                 String pronunciation,\n                                 String[] phoneNumbers,\n                                 String[] phoneTypes,\n                                 String[] emails,\n                                 String[] emailTypes,\n                                 String instantMessenger,\n                                 String note,\n                                 String[] addresses,\n                                 String[] addressTypes,\n                                 String org,\n                                 String birthday,\n                                 String title,\n                                 String url) {\n    super(ParsedResultType.ADDRESSBOOK);\n    this.names = names;\n    this.pronunciation = pronunciation;\n    this.phoneNumbers = phoneNumbers;\n    this.phoneTypes = phoneTypes;\n    this.emails = emails;\n    this.emailTypes = emailTypes;\n    this.instantMessenger = instantMessenger;\n    this.note = note;\n    this.addresses = addresses;\n    this.addressTypes = addressTypes;\n    this.org = org;\n    this.birthday = birthday;\n    this.title = title;\n    this.url = url;\n  }\n\n  public String[] getNames() {\n    return names;\n  }\n\n  /**\n   * In Japanese, the name is written in kanji, which can have multiple readings. Therefore a hint\n   * is often provided, called furigana, which spells the name phonetically.\n   *\n   * @return The pronunciation of the getNames() field, often in hiragana or katakana.\n   */\n  public String getPronunciation() {\n    return pronunciation;\n  }\n\n  public String[] getPhoneNumbers() {\n    return phoneNumbers;\n  }\n\n  /**\n   * @return optional descriptions of the type of each phone number. It could be like \"HOME\", but,\n   *  there is no guaranteed or standard format.\n   */\n  public String[] getPhoneTypes() {\n    return phoneTypes;\n  }\n\n  public String[] getEmails() {\n    return emails;\n  }\n\n  /**\n   * @return optional descriptions of the type of each e-mail. It could be like \"WORK\", but,\n   *  there is no guaranteed or standard format.\n   */\n  public String[] getEmailTypes() {\n    return emailTypes;\n  }\n  \n  public String getInstantMessenger() {\n    return instantMessenger;\n  }\n\n  public String getNote() {\n    return note;\n  }\n\n  public String[] getAddresses() {\n    return addresses;\n  }\n\n  /**\n   * @return optional descriptions of the type of each e-mail. It could be like \"WORK\", but,\n   *  there is no guaranteed or standard format.\n   */\n  public String[] getAddressTypes() {\n    return addressTypes;\n  }\n\n  public String getTitle() {\n    return title;\n  }\n\n  public String getOrg() {\n    return org;\n  }\n\n  public String getURL() {\n    return url;\n  }\n\n  /**\n   * @return birthday formatted as yyyyMMdd (e.g. 19780917)\n   */\n  public String getBirthday() {\n    return birthday;\n  }\n\n  @Override\n  public String getDisplayResult() {\n    StringBuilder result = new StringBuilder(100);\n    maybeAppend(names, result);\n    maybeAppend(pronunciation, result);\n    maybeAppend(title, result);\n    maybeAppend(org, result);\n    maybeAppend(addresses, result);\n    maybeAppend(phoneNumbers, result);\n    maybeAppend(emails, result);\n    maybeAppend(instantMessenger, result);\n    maybeAppend(url, result);\n    maybeAppend(birthday, result);\n    maybeAppend(note, result);\n    return result.toString();\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/result/BizcardResultParser.java",
    "content": "/*\n * Copyright 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.result;\n\nimport com.google.zxing.Result;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Implements the \"BIZCARD\" address book entry format, though this has been\n * largely reverse-engineered from examples observed in the wild -- still\n * looking for a definitive reference.\n *\n * @author Sean Owen\n */\npublic final class BizcardResultParser extends AbstractDoCoMoResultParser {\n\n  // Yes, we extend AbstractDoCoMoResultParser since the format is very much\n  // like the DoCoMo MECARD format, but this is not technically one of \n  // DoCoMo's proposed formats\n\n  @Override\n  public AddressBookParsedResult parse(Result result) {\n    String rawText = getMassagedText(result);\n    if (!rawText.startsWith(\"BIZCARD:\")) {\n      return null;\n    }\n    String firstName = matchSingleDoCoMoPrefixedField(\"N:\", rawText, true);\n    String lastName = matchSingleDoCoMoPrefixedField(\"X:\", rawText, true);\n    String fullName = buildName(firstName, lastName);\n    String title = matchSingleDoCoMoPrefixedField(\"T:\", rawText, true);\n    String org = matchSingleDoCoMoPrefixedField(\"C:\", rawText, true);\n    String[] addresses = matchDoCoMoPrefixedField(\"A:\", rawText, true);\n    String phoneNumber1 = matchSingleDoCoMoPrefixedField(\"B:\", rawText, true);\n    String phoneNumber2 = matchSingleDoCoMoPrefixedField(\"M:\", rawText, true);\n    String phoneNumber3 = matchSingleDoCoMoPrefixedField(\"F:\", rawText, true);\n    String email = matchSingleDoCoMoPrefixedField(\"E:\", rawText, true);\n\n    return new AddressBookParsedResult(maybeWrap(fullName),\n                                       null,\n                                       buildPhoneNumbers(phoneNumber1, phoneNumber2, phoneNumber3),\n                                       null,\n                                       maybeWrap(email),\n                                       null,\n                                       null,\n                                       null,\n                                       addresses,\n                                       null,\n                                       org,\n                                       null,\n                                       title,\n                                       null);\n  }\n\n  private static String[] buildPhoneNumbers(String number1,\n                                            String number2,\n                                            String number3) {\n    List<String> numbers = new ArrayList<String>(3);\n    if (number1 != null) {\n      numbers.add(number1);\n    }\n    if (number2 != null) {\n      numbers.add(number2);\n    }\n    if (number3 != null) {\n      numbers.add(number3);\n    }\n    int size = numbers.size();\n    if (size == 0) {\n      return null;\n    }\n    return numbers.toArray(new String[size]);\n  }\n\n  private static String buildName(String firstName, String lastName) {\n    if (firstName == null) {\n      return lastName;\n    } else {\n      return lastName == null ? firstName : firstName + ' ' + lastName;\n    }\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/result/BookmarkDoCoMoResultParser.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.result;\n\nimport com.google.zxing.Result;\n\n/**\n * @author Sean Owen\n */\npublic final class BookmarkDoCoMoResultParser extends AbstractDoCoMoResultParser {\n\n  @Override\n  public URIParsedResult parse(Result result) {\n    String rawText = result.getText();\n    if (!rawText.startsWith(\"MEBKM:\")) {\n      return null;\n    }\n    String title = matchSingleDoCoMoPrefixedField(\"TITLE:\", rawText, true);\n    String[] rawUri = matchDoCoMoPrefixedField(\"URL:\", rawText, true);\n    if (rawUri == null) {\n      return null;\n    }\n    String uri = rawUri[0];\n    return URIResultParser.isBasicallyValidURI(uri) ? new URIParsedResult(uri, title) : null;\n  }\n\n}"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/result/CalendarParsedResult.java",
    "content": "/*\n * Copyright 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.result;\n\nimport java.text.DateFormat;\nimport java.text.ParseException;\nimport java.text.SimpleDateFormat;\nimport java.util.Calendar;\nimport java.util.Date;\nimport java.util.GregorianCalendar;\nimport java.util.Locale;\nimport java.util.TimeZone;\nimport java.util.regex.Pattern;\n\n/**\n * @author Sean Owen\n */\npublic final class CalendarParsedResult extends ParsedResult {\n\n  private static final Pattern DATE_TIME = Pattern.compile(\"[0-9]{8}(T[0-9]{6}Z?)?\");\n\n  private static final DateFormat DATE_FORMAT = new SimpleDateFormat(\"yyyyMMdd\", Locale.ENGLISH);\n  static {\n    // For dates without a time, for purposes of interacting with Android, the resulting timestamp\n    // needs to be midnight of that day in GMT. See:\n    // http://code.google.com/p/android/issues/detail?id=8330\n    DATE_FORMAT.setTimeZone(TimeZone.getTimeZone(\"GMT\"));\n  }\n  private static final DateFormat DATE_TIME_FORMAT = new SimpleDateFormat(\"yyyyMMdd'T'HHmmss\", Locale.ENGLISH);\n\n  private final String summary;\n  private final Date start;\n  private final boolean startAllDay;\n  private final Date end;\n  private final boolean endAllDay;\n  private final String location;\n  private final String organizer;\n  private final String[] attendees;\n  private final String description;\n  private final double latitude;\n  private final double longitude;\n\n  public CalendarParsedResult(String summary,\n                              String startString,\n                              String endString,\n                              String location,\n                              String organizer,\n                              String[] attendees,\n                              String description,\n                              double latitude,\n                              double longitude) {\n    super(ParsedResultType.CALENDAR);\n    this.summary = summary;\n    try {\n      this.start = parseDate(startString);\n      this.end = endString == null ? null : parseDate(endString);\n    } catch (ParseException pe) {\n      throw new IllegalArgumentException(pe.toString());\n    }\n    this.startAllDay = startString.length() == 8;\n    this.endAllDay = endString != null && endString.length() == 8;\n    this.location = location;\n    this.organizer = organizer;\n    this.attendees = attendees;\n    this.description = description;\n    this.latitude = latitude;\n    this.longitude = longitude;\n  }\n\n  public String getSummary() {\n    return summary;\n  }\n\n  /**\n   * @return start time\n   */\n  public Date getStart() {\n    return start;\n  }\n\n  /**\n   * @return true if start time was specified as a whole day\n   */\n  public boolean isStartAllDay() {\n    return startAllDay;\n  }\n\n  /**\n   * May return null if the event has no duration.\n   * @see #getStart()\n   */\n  public Date getEnd() {\n    return end;\n  }\n\n  /**\n   * @return true if end time was specified as a whole day\n   */\n  public boolean isEndAllDay() {\n    return endAllDay;\n  }\n\n  public String getLocation() {\n    return location;\n  }\n\n  public String getOrganizer() {\n    return organizer;\n  }\n\n  public String[] getAttendees() {\n    return attendees;\n  }\n\n  public String getDescription() {\n    return description;\n  }\n\n  public double getLatitude() {\n    return latitude;\n  }\n\n  public double getLongitude() {\n    return longitude;\n  }\n\n  @Override\n  public String getDisplayResult() {\n    StringBuilder result = new StringBuilder(100);\n    maybeAppend(summary, result);\n    maybeAppend(format(startAllDay, start), result);\n    maybeAppend(format(endAllDay, end), result);\n    maybeAppend(location, result);\n    maybeAppend(organizer, result);\n    maybeAppend(attendees, result);\n    maybeAppend(description, result);\n    return result.toString();\n  }\n\n  /**\n   * Parses a string as a date. RFC 2445 allows the start and end fields to be of type DATE (e.g. 20081021)\n   * or DATE-TIME (e.g. 20081021T123000 for local time, or 20081021T123000Z for UTC).\n   *\n   * @param when The string to parse\n   * @throws ParseException if not able to parse as a date\n   */\n  private static Date parseDate(String when) throws ParseException {\n    if (!DATE_TIME.matcher(when).matches()) {\n      throw new ParseException(when, 0);\n    }\n    if (when.length() == 8) {\n      // Show only year/month/day\n      return DATE_FORMAT.parse(when);\n    } else {\n      // The when string can be local time, or UTC if it ends with a Z\n      Date date;\n      if (when.length() == 16 && when.charAt(15) == 'Z') {\n        date = DATE_TIME_FORMAT.parse(when.substring(0, 15));\n        Calendar calendar = new GregorianCalendar();\n        long milliseconds = date.getTime();\n        // Account for time zone difference\n        milliseconds += calendar.get(Calendar.ZONE_OFFSET);\n        // Might need to correct for daylight savings time, but use target time since\n        // now might be in DST but not then, or vice versa\n        calendar.setTime(new Date(milliseconds));\n        milliseconds += calendar.get(Calendar.DST_OFFSET);\n        date = new Date(milliseconds);\n      } else {\n        date = DATE_TIME_FORMAT.parse(when);\n      }\n      return date;\n    }\n  }\n\n  private static String format(boolean allDay, Date date) {\n    if (date == null) {\n      return null;\n    }\n    DateFormat format = allDay\n        ? DateFormat.getDateInstance(DateFormat.MEDIUM)\n        : DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);\n    return format.format(date);\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/result/EmailAddressParsedResult.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.result;\n\n/**\n * @author Sean Owen\n */\npublic final class EmailAddressParsedResult extends ParsedResult {\n\n  private final String emailAddress;\n  private final String subject;\n  private final String body;\n  private final String mailtoURI;\n\n  EmailAddressParsedResult(String emailAddress,\n                           String subject,\n                           String body,\n                           String mailtoURI) {\n    super(ParsedResultType.EMAIL_ADDRESS);\n    this.emailAddress = emailAddress;\n    this.subject = subject;\n    this.body = body;\n    this.mailtoURI = mailtoURI;\n  }\n\n  public String getEmailAddress() {\n    return emailAddress;\n  }\n\n  public String getSubject() {\n    return subject;\n  }\n\n  public String getBody() {\n    return body;\n  }\n\n  public String getMailtoURI() {\n    return mailtoURI;\n  }\n\n  @Override\n  public String getDisplayResult() {\n    StringBuilder result = new StringBuilder(30);\n    maybeAppend(emailAddress, result);\n    maybeAppend(subject, result);\n    maybeAppend(body, result);\n    return result.toString();\n  }\n\n}"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/result/EmailAddressResultParser.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.result;\n\nimport com.google.zxing.Result;\n\nimport java.util.Map;\n\n/**\n * Represents a result that encodes an e-mail address, either as a plain address\n * like \"joe@example.org\" or a mailto: URL like \"mailto:joe@example.org\".\n *\n * @author Sean Owen\n */\npublic final class EmailAddressResultParser extends ResultParser {\n\n  @Override\n  public EmailAddressParsedResult parse(Result result) {\n    String rawText = getMassagedText(result);\n    String emailAddress;\n    if (rawText.startsWith(\"mailto:\") || rawText.startsWith(\"MAILTO:\")) {\n      // If it starts with mailto:, assume it is definitely trying to be an email address\n      emailAddress = rawText.substring(7);\n      int queryStart = emailAddress.indexOf('?');\n      if (queryStart >= 0) {\n        emailAddress = emailAddress.substring(0, queryStart);\n      }\n      Map<String,String> nameValues = parseNameValuePairs(rawText);\n      String subject = null;\n      String body = null;\n      if (nameValues != null) {\n        if (emailAddress.length() == 0) {\n          emailAddress = nameValues.get(\"to\");\n        }\n        subject = nameValues.get(\"subject\");\n        body = nameValues.get(\"body\");\n      }\n      return new EmailAddressParsedResult(emailAddress, subject, body, rawText);\n    } else {\n      if (!EmailDoCoMoResultParser.isBasicallyValidEmailAddress(rawText)) {\n        return null;\n      }\n      emailAddress = rawText;\n      return new EmailAddressParsedResult(emailAddress, null, null, \"mailto:\" + emailAddress);\n    }\n  }\n\n}"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/result/EmailDoCoMoResultParser.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.result;\n\nimport com.google.zxing.Result;\n\nimport java.util.regex.Pattern;\n\n/**\n * Implements the \"MATMSG\" email message entry format.\n *\n * Supported keys: TO, SUB, BODY\n *\n * @author Sean Owen\n */\npublic final class EmailDoCoMoResultParser extends AbstractDoCoMoResultParser {\n\n  private static final Pattern ATEXT_ALPHANUMERIC = Pattern.compile(\"[a-zA-Z0-9@.!#$%&'*+\\\\-/=?^_`{|}~]+\");\n\n  @Override\n  public EmailAddressParsedResult parse(Result result) {\n    String rawText = getMassagedText(result);\n    if (!rawText.startsWith(\"MATMSG:\")) {\n      return null;\n    }\n    String[] rawTo = matchDoCoMoPrefixedField(\"TO:\", rawText, true);\n    if (rawTo == null) {\n      return null;\n    }\n    String to = rawTo[0];\n    if (!isBasicallyValidEmailAddress(to)) {\n      return null;\n    }\n    String subject = matchSingleDoCoMoPrefixedField(\"SUB:\", rawText, false);\n    String body = matchSingleDoCoMoPrefixedField(\"BODY:\", rawText, false);\n    return new EmailAddressParsedResult(to, subject, body, \"mailto:\" + to);\n  }\n\n  /**\n   * This implements only the most basic checking for an email address's validity -- that it contains\n   * an '@' and contains no characters disallowed by RFC 2822. This is an overly lenient definition of\n   * validity. We want to generally be lenient here since this class is only intended to encapsulate what's\n   * in a barcode, not \"judge\" it.\n   */\n  static boolean isBasicallyValidEmailAddress(String email) {\n    return email != null && ATEXT_ALPHANUMERIC.matcher(email).matches() && email.indexOf('@') >= 0;\n  }\n\n}"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/result/ExpandedProductParsedResult.java",
    "content": "/*\n * Copyright (C) 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * These authors would like to acknowledge the Spanish Ministry of Industry,\n * Tourism and Trade, for the support in the project TSI020301-2008-2\n * \"PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled\n * Mobile Dynamic Environments\", led by Treelogic\n * ( http://www.treelogic.com/ ):\n *\n *   http://www.piramidepse.com/\n */\n\npackage com.google.zxing.client.result;\n\nimport java.util.Map;\n\n/**\n * @author Antonio Manuel Benjumea Conde, Servinform, S.A.\n * @author Agustín Delgado, Servinform, S.A.\n */\npublic final class ExpandedProductParsedResult extends ParsedResult {\n\n  public static final String KILOGRAM = \"KG\";\n  public static final String POUND = \"LB\";\n\n  private final String productID;\n  private final String sscc;\n  private final String lotNumber;\n  private final String productionDate;\n  private final String packagingDate;\n  private final String bestBeforeDate;\n  private final String expirationDate;\n  private final String weight;\n  private final String weightType;\n  private final String weightIncrement;\n  private final String price;\n  private final String priceIncrement;\n  private final String priceCurrency;\n  // For AIS that not exist in this object\n  private final Map<String,String> uncommonAIs;\n\n  public ExpandedProductParsedResult(String productID,\n                                     String sscc,\n                                     String lotNumber,\n                                     String productionDate,\n                                     String packagingDate,\n                                     String bestBeforeDate,\n                                     String expirationDate,\n                                     String weight,\n                                     String weightType,\n                                     String weightIncrement,\n                                     String price,\n                                     String priceIncrement,\n                                     String priceCurrency,\n                                     Map<String,String> uncommonAIs) {\n    super(ParsedResultType.PRODUCT);\n    this.productID = productID;\n    this.sscc = sscc;\n    this.lotNumber = lotNumber;\n    this.productionDate = productionDate;\n    this.packagingDate = packagingDate;\n    this.bestBeforeDate = bestBeforeDate;\n    this.expirationDate = expirationDate;\n    this.weight = weight;\n    this.weightType = weightType;\n    this.weightIncrement = weightIncrement;\n    this.price = price;\n    this.priceIncrement = priceIncrement;\n    this.priceCurrency = priceCurrency;\n    this.uncommonAIs = uncommonAIs;\n  }\n\n  @Override\n  public boolean equals(Object o){\n    if (!(o instanceof ExpandedProductParsedResult)) {\n      return false;\n    }\n\n    ExpandedProductParsedResult other = (ExpandedProductParsedResult)o;\n\n    return equalsOrNull(productID, other.productID)\n        && equalsOrNull(sscc, other.sscc)\n        && equalsOrNull(lotNumber, other.lotNumber)\n        && equalsOrNull(productionDate, other.productionDate)\n        && equalsOrNull(bestBeforeDate, other.bestBeforeDate)\n        && equalsOrNull(expirationDate, other.expirationDate)\n        && equalsOrNull(weight, other.weight)\n        && equalsOrNull(weightType, other.weightType)\n        && equalsOrNull(weightIncrement, other.weightIncrement)\n        && equalsOrNull(price, other.price)\n        && equalsOrNull(priceIncrement, other.priceIncrement)\n        && equalsOrNull(priceCurrency, other.priceCurrency)\n        && equalsOrNull(uncommonAIs, other.uncommonAIs);\n  }\n\n  private static boolean equalsOrNull(Object o1, Object o2) {\n    return o1 == null ? o2 == null : o1.equals(o2);\n  }\n\n  @Override\n  public int hashCode(){\n    int hash = 0;\n    hash ^= hashNotNull(productID);\n    hash ^= hashNotNull(sscc);\n    hash ^= hashNotNull(lotNumber);\n    hash ^= hashNotNull(productionDate);\n    hash ^= hashNotNull(bestBeforeDate);\n    hash ^= hashNotNull(expirationDate);\n    hash ^= hashNotNull(weight);\n    hash ^= hashNotNull(weightType);\n    hash ^= hashNotNull(weightIncrement);\n    hash ^= hashNotNull(price);\n    hash ^= hashNotNull(priceIncrement);\n    hash ^= hashNotNull(priceCurrency);\n    hash ^= hashNotNull(uncommonAIs);\n    return hash;\n  }\n\n  private static int hashNotNull(Object o) {\n    return o == null ? 0 : o.hashCode();\n  }\n\n  public String getProductID() {\n    return productID;\n  }\n\n  public String getSscc() {\n    return sscc;\n  }\n\n  public String getLotNumber() {\n    return lotNumber;\n  }\n\n  public String getProductionDate() {\n    return productionDate;\n  }\n\n  public String getPackagingDate() {\n    return packagingDate;\n  }\n\n  public String getBestBeforeDate() {\n    return bestBeforeDate;\n  }\n\n  public String getExpirationDate() {\n    return expirationDate;\n  }\n\n  public String getWeight() {\n    return weight;\n  }\n\n  public String getWeightType() {\n    return weightType;\n  }\n\n  public String getWeightIncrement() {\n    return weightIncrement;\n  }\n\n  public String getPrice() {\n    return price;\n  }\n\n  public String getPriceIncrement() {\n    return priceIncrement;\n  }\n\n  public String getPriceCurrency() {\n    return priceCurrency;\n  }\n\n  public Map<String,String> getUncommonAIs() {\n    return uncommonAIs;\n  }\n\n  @Override\n  public String getDisplayResult() {\n    return String.valueOf(productID);\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/result/ExpandedProductResultParser.java",
    "content": "/*\n * Copyright (C) 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * These authors would like to acknowledge the Spanish Ministry of Industry,\n * Tourism and Trade, for the support in the project TSI020301-2008-2\n * \"PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled\n * Mobile Dynamic Environments\", led by Treelogic\n * ( http://www.treelogic.com/ ):\n *\n *   http://www.piramidepse.com/\n */\n\npackage com.google.zxing.client.result;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport com.google.zxing.BarcodeFormat;\nimport com.google.zxing.Result;\n\n/**\n * Parses strings of digits that represent a RSS Extended code.\n * \n * @author Antonio Manuel Benjumea Conde, Servinform, S.A.\n * @author Agustín Delgado, Servinform, S.A.\n */\npublic final class ExpandedProductResultParser extends ResultParser {\n\n  @Override\n  public ExpandedProductParsedResult parse(Result result) {\n    BarcodeFormat format = result.getBarcodeFormat();\n    if (format != BarcodeFormat.RSS_EXPANDED) {\n      // ExtendedProductParsedResult NOT created. Not a RSS Expanded barcode\n      return null;\n    }\n    // Really neither of these should happen:\n    String rawText = getMassagedText(result);\n    if (rawText == null) {\n      // ExtendedProductParsedResult NOT created. Input text is NULL\n      return null;\n    }\n\n    String productID = null;\n    String sscc = null;\n    String lotNumber = null;\n    String productionDate = null;\n    String packagingDate = null;\n    String bestBeforeDate = null;\n    String expirationDate = null;\n    String weight = null;\n    String weightType = null;\n    String weightIncrement = null;\n    String price = null;\n    String priceIncrement = null;\n    String priceCurrency = null;\n    Map<String,String> uncommonAIs = new HashMap<String,String>();\n\n    int i = 0;\n\n    while (i < rawText.length()) {\n      String ai = findAIvalue(i, rawText);\n      if (ai == null) {\n        // Error. Code doesn't match with RSS expanded pattern\n        // ExtendedProductParsedResult NOT created. Not match with RSS Expanded pattern\n        return null;\n      }\n      i += ai.length() + 2;\n      String value = findValue(i, rawText);\n      i += value.length();\n\n      if (\"00\".equals(ai)) {\n        sscc = value;\n      } else if (\"01\".equals(ai)) {\n        productID = value;\n      } else if (\"10\".equals(ai)) {\n        lotNumber = value;\n      } else if (\"11\".equals(ai)) {\n        productionDate = value;\n      } else if (\"13\".equals(ai)) {\n        packagingDate = value;\n      } else if (\"15\".equals(ai)) {\n        bestBeforeDate = value;\n      } else if (\"17\".equals(ai)) {\n        expirationDate = value;\n      } else if (\"3100\".equals(ai) || \"3101\".equals(ai)\n          || \"3102\".equals(ai) || \"3103\".equals(ai)\n          || \"3104\".equals(ai) || \"3105\".equals(ai)\n          || \"3106\".equals(ai) || \"3107\".equals(ai)\n          || \"3108\".equals(ai) || \"3109\".equals(ai)) {\n        weight = value;\n        weightType = ExpandedProductParsedResult.KILOGRAM;\n        weightIncrement = ai.substring(3);\n      } else if (\"3200\".equals(ai) || \"3201\".equals(ai)\n          || \"3202\".equals(ai) || \"3203\".equals(ai)\n          || \"3204\".equals(ai) || \"3205\".equals(ai)\n          || \"3206\".equals(ai) || \"3207\".equals(ai)\n          || \"3208\".equals(ai) || \"3209\".equals(ai)) {\n        weight = value;\n        weightType = ExpandedProductParsedResult.POUND;\n        weightIncrement = ai.substring(3);\n      } else if (\"3920\".equals(ai) || \"3921\".equals(ai)\n          || \"3922\".equals(ai) || \"3923\".equals(ai)) {\n        price = value;\n        priceIncrement = ai.substring(3);\n      } else if (\"3930\".equals(ai) || \"3931\".equals(ai)\n          || \"3932\".equals(ai) || \"3933\".equals(ai)) {\n        if (value.length() < 4) {\n          // The value must have more of 3 symbols (3 for currency and\n          // 1 at least for the price)\n          // ExtendedProductParsedResult NOT created. Not match with RSS Expanded pattern\n          return null;\n        }\n        price = value.substring(3);\n        priceCurrency = value.substring(0, 3);\n        priceIncrement = ai.substring(3);\n      } else {\n        // No match with common AIs\n        uncommonAIs.put(ai, value);\n      }\n    }\n\n    return new ExpandedProductParsedResult(productID,\n                                           sscc,\n                                           lotNumber,\n                                           productionDate,\n                                           packagingDate,\n                                           bestBeforeDate,\n                                           expirationDate,\n                                           weight,\n                                           weightType,\n                                           weightIncrement,\n                                           price,\n                                           priceIncrement,\n                                           priceCurrency,\n                                           uncommonAIs);\n  }\n\n  private static String findAIvalue(int i, String rawText) {\n    StringBuilder buf = new StringBuilder();\n    char c = rawText.charAt(i);\n    // First character must be a open parenthesis.If not, ERROR\n    if (c != '(') {\n      return null;\n    }\n\n    String rawTextAux = rawText.substring(i + 1);\n\n    for (int index = 0; index < rawTextAux.length(); index++) {\n      char currentChar = rawTextAux.charAt(index);\n      if (currentChar == ')') {\n        return buf.toString();\n      } else if (currentChar >= '0' && currentChar <= '9') {\n        buf.append(currentChar);\n      } else {\n        return null;\n      }\n    }\n    return buf.toString();\n  }\n\n  private static String findValue(int i, String rawText) {\n    StringBuilder buf = new StringBuilder();\n    String rawTextAux = rawText.substring(i);\n\n    for (int index = 0; index < rawTextAux.length(); index++) {\n      char c = rawTextAux.charAt(index);\n      if (c == '(') {\n        // We look for a new AI. If it doesn't exist (ERROR), we coninue\n        // with the iteration\n        if (findAIvalue(index, rawTextAux) == null) {\n          buf.append('(');\n        } else {\n          break;\n        }\n      } else {\n        buf.append(c);\n      }\n    }\n    return buf.toString();\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/result/GeoParsedResult.java",
    "content": "/*\n * Copyright 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.result;\n\n/**\n * @author Sean Owen\n */\npublic final class GeoParsedResult extends ParsedResult {\n\n  private final double latitude;\n  private final double longitude;\n  private final double altitude;\n  private final String query;\n\n  GeoParsedResult(double latitude, double longitude, double altitude, String query) {\n    super(ParsedResultType.GEO);\n    this.latitude = latitude;\n    this.longitude = longitude;\n    this.altitude = altitude;\n    this.query = query;\n  }\n\n  public String getGeoURI() {\n    StringBuilder result = new StringBuilder();\n    result.append(\"geo:\");\n    result.append(latitude);\n    result.append(',');\n    result.append(longitude);\n    if (altitude > 0) {\n      result.append(',');\n      result.append(altitude);\n    }\n    if (query != null) {\n      result.append('?');\n      result.append(query);\n    }\n    return result.toString();\n  }\n\n  /**\n   * @return latitude in degrees\n   */\n  public double getLatitude() {\n    return latitude;\n  }\n\n  /**\n   * @return longitude in degrees\n   */\n  public double getLongitude() {\n    return longitude;\n  }\n\n  /**\n   * @return altitude in meters. If not specified, in the geo URI, returns 0.0\n   */\n  public double getAltitude() {\n    return altitude;\n  }\n\n  /**\n   * @return query string associated with geo URI or null if none exists\n   */\n  public String getQuery() {\n    return query;\n  }\n\n  @Override\n  public String getDisplayResult() {\n    StringBuilder result = new StringBuilder(20);\n    result.append(latitude);\n    result.append(\", \");\n    result.append(longitude);\n    if (altitude > 0.0) {\n      result.append(\", \");\n      result.append(altitude);\n      result.append('m');\n    }\n    if (query != null) {\n      result.append(\" (\");\n      result.append(query);\n      result.append(')');\n    }\n    return result.toString();\n  }\n\n}"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/result/GeoResultParser.java",
    "content": "/*\n * Copyright 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.result;\n\nimport com.google.zxing.Result;\n\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\n/**\n * Parses a \"geo:\" URI result, which specifies a location on the surface of\n * the Earth as well as an optional altitude above the surface. See\n * <a href=\"http://tools.ietf.org/html/draft-mayrhofer-geo-uri-00\">\n * http://tools.ietf.org/html/draft-mayrhofer-geo-uri-00</a>.\n *\n * @author Sean Owen\n */\npublic final class GeoResultParser extends ResultParser {\n\n  private static final Pattern GEO_URL_PATTERN = \n      Pattern.compile(\"geo:([\\\\-0-9.]+),([\\\\-0-9.]+)(?:,([\\\\-0-9.]+))?(?:\\\\?(.*))?\", Pattern.CASE_INSENSITIVE);\n  \n  @Override\n  public GeoParsedResult parse(Result result) {\n    String rawText = getMassagedText(result);\n    Matcher matcher = GEO_URL_PATTERN.matcher(rawText);\n    if (!matcher.matches()) {\n      return null;\n    }\n\n    String query = matcher.group(4);\n\n    double latitude;\n    double longitude;\n    double altitude;\n    try {\n      latitude = Double.parseDouble(matcher.group(1));\n      if (latitude > 90.0 || latitude < -90.0) {\n        return null;\n      }\n      longitude = Double.parseDouble(matcher.group(2));\n      if (longitude > 180.0 || longitude < -180.0) {\n        return null;\n      }\n      if (matcher.group(3) == null) {\n        altitude = 0.0;\n      } else {\n        altitude = Double.parseDouble(matcher.group(3));\n        if (altitude < 0.0) {\n          return null;\n        }\n      }\n    } catch (NumberFormatException nfe) {\n      return null;\n    }\n    return new GeoParsedResult(latitude, longitude, altitude, query);\n  }\n\n}"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/result/ISBNParsedResult.java",
    "content": "/*\n * Copyright 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.result;\n\n/**\n * @author jbreiden@google.com (Jeff Breidenbach)\n */\npublic final class ISBNParsedResult extends ParsedResult {\n\n  private final String isbn;\n\n  ISBNParsedResult(String isbn) {\n    super(ParsedResultType.ISBN);\n    this.isbn = isbn;\n  }\n\n  public String getISBN() {\n    return isbn;\n  }\n\n  @Override\n  public String getDisplayResult() {\n    return isbn;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/result/ISBNResultParser.java",
    "content": "/*\n * Copyright 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.result;\n\nimport com.google.zxing.BarcodeFormat;\nimport com.google.zxing.Result;\n\n/**\n * Parses strings of digits that represent a ISBN.\n * \n * @author jbreiden@google.com (Jeff Breidenbach)\n */\npublic final class ISBNResultParser extends ResultParser {\n\n  /**\n   * See <a href=\"http://www.bisg.org/isbn-13/for.dummies.html\">ISBN-13 For Dummies</a>\n   */\n  @Override\n  public ISBNParsedResult parse(Result result) {\n    BarcodeFormat format = result.getBarcodeFormat();\n    if (format != BarcodeFormat.EAN_13) {\n      return null;\n    }\n    String rawText = getMassagedText(result);\n    int length = rawText.length();\n    if (length != 13) {\n      return null;\n    }\n    if (!rawText.startsWith(\"978\") && !rawText.startsWith(\"979\")) {\n      return null;\n    }\n   \n    return new ISBNParsedResult(rawText);\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/result/ParsedResult.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.result;\n\nimport com.google.zxing.Result;\n\n/**\n * <p>Abstract class representing the result of decoding a barcode, as more than\n * a String -- as some type of structured data. This might be a subclass which represents\n * a URL, or an e-mail address. {@link ResultParser#parseResult(Result)} will turn a raw\n * decoded string into the most appropriate type of structured representation.</p>\n *\n * <p>Thanks to Jeff Griffin for proposing rewrite of these classes that relies less\n * on exception-based mechanisms during parsing.</p>\n *\n * @author Sean Owen\n */\npublic abstract class ParsedResult {\n\n  private final ParsedResultType type;\n\n  protected ParsedResult(ParsedResultType type) {\n    this.type = type;\n  }\n\n  public final ParsedResultType getType() {\n    return type;\n  }\n\n  public abstract String getDisplayResult();\n\n  @Override\n  public final String toString() {\n    return getDisplayResult();\n  }\n\n  public static void maybeAppend(String value, StringBuilder result) {\n    if (value != null && value.length() > 0) {\n      // Don't add a newline before the first value\n      if (result.length() > 0) {\n        result.append('\\n');\n      }\n      result.append(value);\n    }\n  }\n\n  public static void maybeAppend(String[] value, StringBuilder result) {\n    if (value != null) {\n      for (String s : value) {\n        if (s != null && s.length() > 0) {\n          if (result.length() > 0) {\n            result.append('\\n');\n          }\n          result.append(s);\n        }\n      }\n    }\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/result/ParsedResultType.java",
    "content": "/*\n * Copyright 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.result;\n\n/**\n * Represents the type of data encoded by a barcode -- from plain text, to a\n * URI, to an e-mail address, etc.\n *\n * @author Sean Owen\n */\npublic enum ParsedResultType {\n\n  ADDRESSBOOK,\n  EMAIL_ADDRESS,\n  PRODUCT,\n  URI,\n  TEXT,\n  GEO,\n  TEL,\n  SMS,\n  CALENDAR,\n  WIFI,\n  ISBN,\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/result/ProductParsedResult.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.result;\n\n/**\n * @author dswitkin@google.com (Daniel Switkin)\n */\npublic final class ProductParsedResult extends ParsedResult {\n\n  private final String productID;\n  private final String normalizedProductID;\n\n  ProductParsedResult(String productID) {\n    this(productID, productID);\n  }\n\n  ProductParsedResult(String productID, String normalizedProductID) {\n    super(ParsedResultType.PRODUCT);\n    this.productID = productID;\n    this.normalizedProductID = normalizedProductID;\n  }\n\n  public String getProductID() {\n    return productID;\n  }\n\n  public String getNormalizedProductID() {\n    return normalizedProductID;\n  }\n\n  @Override\n  public String getDisplayResult() {\n    return productID;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/result/ProductResultParser.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.result;\n\nimport com.google.zxing.BarcodeFormat;\nimport com.google.zxing.Result;\nimport com.google.zxing.oned.UPCEReader;\n\n/**\n * Parses strings of digits that represent a UPC code.\n * \n * @author dswitkin@google.com (Daniel Switkin)\n */\npublic final class ProductResultParser extends ResultParser {\n\n  // Treat all UPC and EAN variants as UPCs, in the sense that they are all product barcodes.\n  @Override\n  public ProductParsedResult parse(Result result) {\n    BarcodeFormat format = result.getBarcodeFormat();\n    if (!(format == BarcodeFormat.UPC_A || format == BarcodeFormat.UPC_E ||\n          format == BarcodeFormat.EAN_8 || format == BarcodeFormat.EAN_13)) {\n      return null;\n    }\n    String rawText = getMassagedText(result);\n    int length = rawText.length();\n    for (int x = 0; x < length; x++) {\n      char c = rawText.charAt(x);\n      if (c < '0' || c > '9') {\n        return null;\n      }\n    }\n    // Not actually checking the checksum again here    \n\n    String normalizedProductID;\n    // Expand UPC-E for purposes of searching\n    if (format == BarcodeFormat.UPC_E) {\n      normalizedProductID = UPCEReader.convertUPCEtoUPCA(rawText);\n    } else {\n      normalizedProductID = rawText;\n    }\n\n    return new ProductParsedResult(rawText, normalizedProductID);\n  }\n\n}"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/result/ResultParser.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.result;\n\nimport com.google.zxing.Result;\n\nimport java.io.UnsupportedEncodingException;\nimport java.net.URLDecoder;\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.regex.Pattern;\n\n/**\n * <p>Abstract class representing the result of decoding a barcode, as more than\n * a String -- as some type of structured data. This might be a subclass which represents\n * a URL, or an e-mail address. {@link #parseResult(Result)} will turn a raw\n * decoded string into the most appropriate type of structured representation.</p>\n *\n * <p>Thanks to Jeff Griffin for proposing rewrite of these classes that relies less\n * on exception-based mechanisms during parsing.</p>\n *\n * @author Sean Owen\n */\npublic abstract class ResultParser {\n\n  private static final ResultParser[] PARSERS = {\n      new BookmarkDoCoMoResultParser(),\n      new AddressBookDoCoMoResultParser(),\n      new EmailDoCoMoResultParser(),\n      new AddressBookAUResultParser(),\n      new VCardResultParser(),\n      new BizcardResultParser(),\n      new VEventResultParser(),\n      new EmailAddressResultParser(),\n      new SMTPResultParser(),\n      new TelResultParser(),\n      new SMSMMSResultParser(),\n      new SMSTOMMSTOResultParser(),\n      new GeoResultParser(),\n      new WifiResultParser(),\n      new URLTOResultParser(),\n      new URIResultParser(),\n      new ISBNResultParser(),\n      new ProductResultParser(),\n      new ExpandedProductResultParser(),\n  };\n\n  private static final Pattern DIGITS = Pattern.compile(\"\\\\d*\");\n  private static final Pattern ALPHANUM = Pattern.compile(\"[a-zA-Z0-9]*\");\n  private static final Pattern AMPERSAND = Pattern.compile(\"&\");\n  private static final Pattern EQUALS = Pattern.compile(\"=\");\n  private static final String BYTE_ORDER_MARK = \"\\ufeff\";\n\n  /**\n   * Attempts to parse the raw {@link Result}'s contents as a particular type\n   * of information (email, URL, etc.) and return a {@link ParsedResult} encapsulating\n   * the result of parsing.\n   */\n  public abstract ParsedResult parse(Result theResult);\n\n  protected static String getMassagedText(Result result) {\n    String text = result.getText();\n    if (text.startsWith(BYTE_ORDER_MARK)) {\n      text = text.substring(1);\n    }\n    return text;\n  }\n\n  public static ParsedResult parseResult(Result theResult) {\n    for (ResultParser parser : PARSERS) {\n      ParsedResult result = parser.parse(theResult);\n      if (result != null) {\n        return result;\n      }\n    }\n    return new TextParsedResult(theResult.getText(), null);\n  }\n\n  protected static void maybeAppend(String value, StringBuilder result) {\n    if (value != null) {\n      result.append('\\n');\n      result.append(value);\n    }\n  }\n\n  protected static void maybeAppend(String[] value, StringBuilder result) {\n    if (value != null) {\n      for (String s : value) {\n        result.append('\\n');\n        result.append(s);\n      }\n    }\n  }\n\n  protected static String[] maybeWrap(String value) {\n    return value == null ? null : new String[] { value };\n  }\n\n  protected static String unescapeBackslash(String escaped) {\n    int backslash = escaped.indexOf((int) '\\\\');\n    if (backslash < 0) {\n      return escaped;\n    }\n    int max = escaped.length();\n    StringBuilder unescaped = new StringBuilder(max - 1);\n    unescaped.append(escaped.toCharArray(), 0, backslash);\n    boolean nextIsEscaped = false;\n    for (int i = backslash; i < max; i++) {\n      char c = escaped.charAt(i);\n      if (nextIsEscaped || c != '\\\\') {\n        unescaped.append(c);\n        nextIsEscaped = false;\n      } else {\n        nextIsEscaped = true;\n      }\n    }\n    return unescaped.toString();\n  }\n\n  protected static int parseHexDigit(char c) {\n    if (c >= '0' && c <= '9') {\n      return c - '0';\n    }\n    if (c >= 'a' && c <= 'f') {\n      return 10 + (c - 'a');\n    }\n    if (c >= 'A' && c <= 'F') {\n      return 10 + (c - 'A');\n    }\n    return -1;\n  }\n\n  protected static boolean isStringOfDigits(CharSequence value, int length) {\n    return value != null && length == value.length() && DIGITS.matcher(value).matches();\n  }\n\n  protected static boolean isSubstringOfDigits(CharSequence value, int offset, int length) {\n    if (value == null) {\n      return false;\n    }\n    int max = offset + length;\n    return value.length() >= max && DIGITS.matcher(value.subSequence(offset, max)).matches();\n  }\n\n  protected static boolean isSubstringOfAlphaNumeric(CharSequence value, int offset, int length) {\n    if (value == null) {\n      return false;\n    }\n    int max = offset + length;\n    return value.length() >= max && ALPHANUM.matcher(value.subSequence(offset, max)).matches();\n  }\n\n  static Map<String,String> parseNameValuePairs(String uri) {\n    int paramStart = uri.indexOf('?');\n    if (paramStart < 0) {\n      return null;\n    }\n    Map<String,String> result = new HashMap<String,String>(3);\n    for (String keyValue : AMPERSAND.split(uri.substring(paramStart + 1))) {\n      appendKeyValue(keyValue, result);\n    }\n    return result;\n  }\n\n  private static void appendKeyValue(CharSequence keyValue, Map<String,String> result) {\n    String[] keyValueTokens = EQUALS.split(keyValue, 2);\n    if (keyValueTokens.length == 2) {\n      String key = keyValueTokens[0];\n      String value = keyValueTokens[1];\n      try {\n        value = URLDecoder.decode(value, \"UTF-8\");\n        result.put(key, value);\n      } catch (UnsupportedEncodingException uee) {\n        throw new IllegalStateException(uee); // can't happen\n      } catch (IllegalArgumentException iae) {\n        // continue; invalid data such as an escape like %0t\n      }\n    }\n  }\n\n  static String[] matchPrefixedField(String prefix, String rawText, char endChar, boolean trim) {\n    List<String> matches = null;\n    int i = 0;\n    int max = rawText.length();\n    while (i < max) {\n      i = rawText.indexOf(prefix, i);\n      if (i < 0) {\n        break;\n      }\n      i += prefix.length(); // Skip past this prefix we found to start\n      int start = i; // Found the start of a match here\n      boolean more = true;\n      while (more) {\n        i = rawText.indexOf((int) endChar, i);\n        if (i < 0) {\n          // No terminating end character? uh, done. Set i such that loop terminates and break\n          i = rawText.length();\n          more = false;\n        } else if (rawText.charAt(i - 1) == '\\\\') {\n          // semicolon was escaped so continue\n          i++;\n        } else {\n          // found a match\n          if (matches == null) {\n            matches = new ArrayList<String>(3); // lazy init\n          }\n          String element = unescapeBackslash(rawText.substring(start, i));\n          if (trim) {\n            element = element.trim();\n          }\n          matches.add(element);\n          i++;\n          more = false;\n        }\n      }\n    }\n    if (matches == null || matches.isEmpty()) {\n      return null;\n    }\n    return matches.toArray(new String[matches.size()]);\n  }\n\n  static String matchSinglePrefixedField(String prefix, String rawText, char endChar, boolean trim) {\n    String[] matches = matchPrefixedField(prefix, rawText, endChar, trim);\n    return matches == null ? null : matches[0];\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/result/SMSMMSResultParser.java",
    "content": "/*\n * Copyright 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.result;\n\nimport com.google.zxing.Result;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * <p>Parses an \"sms:\" URI result, which specifies a number to SMS.\n * See <a href=\"http://tools.ietf.org/html/rfc5724\"> RFC 5724</a> on this.</p>\n *\n * <p>This class supports \"via\" syntax for numbers, which is not part of the spec.\n * For example \"+12125551212;via=+12124440101\" may appear as a number.\n * It also supports a \"subject\" query parameter, which is not mentioned in the spec.\n * These are included since they were mentioned in earlier IETF drafts and might be\n * used.</p>\n *\n * <p>This actually also parses URIs starting with \"mms:\" and treats them all the same way,\n * and effectively converts them to an \"sms:\" URI for purposes of forwarding to the platform.</p>\n *\n * @author Sean Owen\n */\npublic final class SMSMMSResultParser extends ResultParser {\n\n  @Override\n  public SMSParsedResult parse(Result result) {\n    String rawText = getMassagedText(result);\n    if (!(rawText.startsWith(\"sms:\") || rawText.startsWith(\"SMS:\") ||\n          rawText.startsWith(\"mms:\") || rawText.startsWith(\"MMS:\"))) {\n      return null;\n    }\n\n    // Check up front if this is a URI syntax string with query arguments\n    Map<String,String> nameValuePairs = parseNameValuePairs(rawText);\n    String subject = null;\n    String body = null;\n    boolean querySyntax = false;\n    if (nameValuePairs != null && !nameValuePairs.isEmpty()) {\n      subject = nameValuePairs.get(\"subject\");\n      body = nameValuePairs.get(\"body\");\n      querySyntax = true;\n    }\n\n    // Drop sms, query portion\n    int queryStart = rawText.indexOf('?', 4);\n    String smsURIWithoutQuery;\n    // If it's not query syntax, the question mark is part of the subject or message\n    if (queryStart < 0 || !querySyntax) {\n      smsURIWithoutQuery = rawText.substring(4);\n    } else {\n      smsURIWithoutQuery = rawText.substring(4, queryStart);\n    }\n\n    int lastComma = -1;\n    int comma;\n    List<String> numbers = new ArrayList<String>(1);\n    List<String> vias = new ArrayList<String>(1);\n    while ((comma = smsURIWithoutQuery.indexOf(',', lastComma + 1)) > lastComma) {\n      String numberPart = smsURIWithoutQuery.substring(lastComma + 1, comma);\n      addNumberVia(numbers, vias, numberPart);\n      lastComma = comma;\n    }\n    addNumberVia(numbers, vias, smsURIWithoutQuery.substring(lastComma + 1));    \n\n    return new SMSParsedResult(numbers.toArray(new String[numbers.size()]),\n                               vias.toArray(new String[vias.size()]),\n                               subject,\n                               body);\n  }\n\n  private static void addNumberVia(Collection<String> numbers,\n                                   Collection<String> vias,\n                                   String numberPart) {\n    int numberEnd = numberPart.indexOf(';');\n    if (numberEnd < 0) {\n      numbers.add(numberPart);\n      vias.add(null);\n    } else {\n      numbers.add(numberPart.substring(0, numberEnd));\n      String maybeVia = numberPart.substring(numberEnd + 1);\n      String via;\n      if (maybeVia.startsWith(\"via=\")) {\n        via = maybeVia.substring(4);\n      } else {\n        via = null;\n      }\n      vias.add(via);\n    }\n  }\n\n}"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/result/SMSParsedResult.java",
    "content": "/*\n * Copyright 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.result;\n\n/**\n * @author Sean Owen\n */\npublic final class SMSParsedResult extends ParsedResult {\n\n  private final String[] numbers;\n  private final String[] vias;\n  private final String subject;\n  private final String body;\n\n  public SMSParsedResult(String number,\n                         String via,\n                         String subject,\n                         String body) {\n    super(ParsedResultType.SMS);\n    this.numbers = new String[] {number};\n    this.vias = new String[] {via};\n    this.subject = subject;\n    this.body = body;\n  }\n\n  public SMSParsedResult(String[] numbers,\n                         String[] vias,\n                         String subject,\n                         String body) {\n    super(ParsedResultType.SMS);\n    this.numbers = numbers;\n    this.vias = vias;\n    this.subject = subject;\n    this.body = body;\n  }\n\n  public String getSMSURI() {\n    StringBuilder result = new StringBuilder();\n    result.append(\"sms:\");\n    boolean first = true;\n    for (int i = 0; i < numbers.length; i++) {\n      if (first) {\n        first = false;\n      } else {\n        result.append(',');\n      }\n      result.append(numbers[i]);\n      if (vias != null && vias[i] != null) {\n        result.append(\";via=\");\n        result.append(vias[i]);\n      }\n    }\n    boolean hasBody = body != null;\n    boolean hasSubject = subject != null;\n    if (hasBody || hasSubject) {\n      result.append('?');\n      if (hasBody) {\n        result.append(\"body=\");\n        result.append(body);\n      }\n      if (hasSubject) {\n        if (hasBody) {\n          result.append('&');\n        }\n        result.append(\"subject=\");\n        result.append(subject);\n      }\n    }\n    return result.toString();\n  }\n\n  public String[] getNumbers() {\n    return numbers;\n  }\n\n  public String[] getVias() {\n    return vias;\n  }\n\n  public String getSubject() {\n    return subject;\n  }\n\n  public String getBody() {\n    return body;\n  }\n\n  @Override\n  public String getDisplayResult() {\n    StringBuilder result = new StringBuilder(100);\n    maybeAppend(numbers, result);\n    maybeAppend(subject, result);\n    maybeAppend(body, result);\n    return result.toString();\n  }\n\n}"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/result/SMSTOMMSTOResultParser.java",
    "content": "/*\n * Copyright 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.result;\n\nimport com.google.zxing.Result;\n\n/**\n * <p>Parses an \"smsto:\" URI result, whose format is not standardized but appears to be like:\n * {@code smsto:number(:body)}.</p>\n *\n * <p>This actually also parses URIs starting with \"smsto:\", \"mmsto:\", \"SMSTO:\", and\n * \"MMSTO:\", and treats them all the same way, and effectively converts them to an \"sms:\" URI\n * for purposes of forwarding to the platform.</p>\n *\n * @author Sean Owen\n */\npublic final class SMSTOMMSTOResultParser extends ResultParser {\n\n  @Override\n  public SMSParsedResult parse(Result result) {\n    String rawText = getMassagedText(result);\n    if (!(rawText.startsWith(\"smsto:\") || rawText.startsWith(\"SMSTO:\") ||\n          rawText.startsWith(\"mmsto:\") || rawText.startsWith(\"MMSTO:\"))) {\n      return null;\n    }\n    // Thanks to dominik.wild for suggesting this enhancement to support\n    // smsto:number:body URIs\n    String number = rawText.substring(6);\n    String body = null;\n    int bodyStart = number.indexOf(':');\n    if (bodyStart >= 0) {\n      body = number.substring(bodyStart + 1);\n      number = number.substring(0, bodyStart);\n    }\n    return new SMSParsedResult(number, null, null, body);\n  }\n\n}"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/result/SMTPResultParser.java",
    "content": "/*\n * Copyright 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.result;\n\nimport com.google.zxing.Result;\n\n/**\n * <p>Parses an \"smtp:\" URI result, whose format is not standardized but appears to be like:\n * {@code smtp(:subject(:body))}.</p>\n *\n * <p>See http://code.google.com/p/zxing/issues/detail?id=536</p>\n *\n * @author Sean Owen\n */\npublic final class SMTPResultParser extends ResultParser {\n\n  @Override\n  public EmailAddressParsedResult parse(Result result) {\n    String rawText = getMassagedText(result);\n    if (!(rawText.startsWith(\"smtp:\") || rawText.startsWith(\"SMTP:\"))) {\n      return null;\n    }\n    String emailAddress = rawText.substring(5);\n    String subject = null;\n    String body = null;\n    int colon = emailAddress.indexOf(':');\n    if (colon >= 0) {\n      subject = emailAddress.substring(colon + 1);\n      emailAddress = emailAddress.substring(0, colon);\n      colon = subject.indexOf(':');\n      if (colon >= 0) {\n        body = subject.substring(colon + 1);\n        subject = subject.substring(0, colon);\n      }\n    }\n    String mailtoURI = \"mailto:\" + emailAddress;\n    return new EmailAddressParsedResult(emailAddress, subject, body, mailtoURI);\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/result/TelParsedResult.java",
    "content": "/*\n * Copyright 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.result;\n\n/**\n * @author Sean Owen\n */\npublic final class TelParsedResult extends ParsedResult {\n\n  private final String number;\n  private final String telURI;\n  private final String title;\n\n  public TelParsedResult(String number, String telURI, String title) {\n    super(ParsedResultType.TEL);\n    this.number = number;\n    this.telURI = telURI;\n    this.title = title;\n  }\n\n  public String getNumber() {\n    return number;\n  }\n\n  public String getTelURI() {\n    return telURI;\n  }\n\n  public String getTitle() {\n    return title;\n  }\n\n  @Override\n  public String getDisplayResult() {\n    StringBuilder result = new StringBuilder(20);\n    maybeAppend(number, result);\n    maybeAppend(title, result);\n    return result.toString();\n  }\n\n}"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/result/TelResultParser.java",
    "content": "/*\n * Copyright 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.result;\n\nimport com.google.zxing.Result;\n\n/**\n * Parses a \"tel:\" URI result, which specifies a phone number.\n *\n * @author Sean Owen\n */\npublic final class TelResultParser extends ResultParser {\n\n  @Override\n  public TelParsedResult parse(Result result) {\n    String rawText = getMassagedText(result);\n    if (!rawText.startsWith(\"tel:\") && !rawText.startsWith(\"TEL:\")) {\n      return null;\n    }\n    // Normalize \"TEL:\" to \"tel:\"\n    String telURI = rawText.startsWith(\"TEL:\") ? \"tel:\" + rawText.substring(4) : rawText;\n    // Drop tel, query portion\n    int queryStart = rawText.indexOf('?', 4);\n    String number = queryStart < 0 ? rawText.substring(4) : rawText.substring(4, queryStart);\n    return new TelParsedResult(number, telURI, null);\n  }\n\n}"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/result/TextParsedResult.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.result;\n\n/**\n * A simple result type encapsulating a string that has no further\n * interpretation.\n * \n * @author Sean Owen\n */\npublic final class TextParsedResult extends ParsedResult {\n\n  private final String text;\n  private final String language;\n\n  public TextParsedResult(String text, String language) {\n    super(ParsedResultType.TEXT);\n    this.text = text;\n    this.language = language;\n  }\n\n  public String getText() {\n    return text;\n  }\n\n  public String getLanguage() {\n    return language;\n  }\n\n  @Override\n  public String getDisplayResult() {\n    return text;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/result/URIParsedResult.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.result;\n\nimport java.util.regex.Pattern;\n\n/**\n * @author Sean Owen\n */\npublic final class URIParsedResult extends ParsedResult {\n\n  private static final Pattern USER_IN_HOST = Pattern.compile(\":/*([^/@]+)@[^/]+\");\n\n  private final String uri;\n  private final String title;\n\n  public URIParsedResult(String uri, String title) {\n    super(ParsedResultType.URI);\n    this.uri = massageURI(uri);\n    this.title = title;\n  }\n\n  public String getURI() {\n    return uri;\n  }\n\n  public String getTitle() {\n    return title;\n  }\n\n  /**\n   * @return true if the URI contains suspicious patterns that may suggest it intends to\n   *  mislead the user about its true nature. At the moment this looks for the presence\n   *  of user/password syntax in the host/authority portion of a URI which may be used\n   *  in attempts to make the URI's host appear to be other than it is. Example:\n   *  http://yourbank.com@phisher.com  This URI connects to phisher.com but may appear\n   *  to connect to yourbank.com at first glance.\n   */\n  public boolean isPossiblyMaliciousURI() {\n    return USER_IN_HOST.matcher(uri).find();\n  }\n\n  @Override\n  public String getDisplayResult() {\n    StringBuilder result = new StringBuilder(30);\n    maybeAppend(title, result);\n    maybeAppend(uri, result);\n    return result.toString();\n  }\n\n  /**\n   * Transforms a string that represents a URI into something more proper, by adding or canonicalizing\n   * the protocol.\n   */\n  private static String massageURI(String uri) {\n    uri = uri.trim();\n    int protocolEnd = uri.indexOf(':');\n    if (protocolEnd < 0) {\n      // No protocol, assume http\n      uri = \"http://\" + uri;\n    } else if (isColonFollowedByPortNumber(uri, protocolEnd)) {\n      // Found a colon, but it looks like it is after the host, so the protocol is still missing\n      uri = \"http://\" + uri;\n    }\n    return uri;\n  }\n\n  private static boolean isColonFollowedByPortNumber(String uri, int protocolEnd) {\n    int nextSlash = uri.indexOf('/', protocolEnd + 1);\n    if (nextSlash < 0) {\n      nextSlash = uri.length();\n    }\n    if (nextSlash <= protocolEnd + 1) {\n      return false;\n    }\n    for (int x = protocolEnd + 1; x < nextSlash; x++) {\n      if (uri.charAt(x) < '0' || uri.charAt(x) > '9') {\n        return false;\n      }\n    }\n    return true;\n  }\n\n\n}"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/result/URIResultParser.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.result;\n\nimport com.google.zxing.Result;\n\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\n/**\n * Tries to parse results that are a URI of some kind.\n * \n * @author Sean Owen\n */\npublic final class URIResultParser extends ResultParser {\n\n  private static final String ALPHANUM_PART = \"[a-zA-Z0-9\\\\-]\";\n  private static final Pattern URL_WITH_PROTOCOL_PATTERN = Pattern.compile(\"[a-zA-Z0-9]{2,}:\");\n  private static final Pattern URL_WITHOUT_PROTOCOL_PATTERN = Pattern.compile(\n      '(' + ALPHANUM_PART + \"+\\\\.)+\" + ALPHANUM_PART + \"{2,}\" + // host name elements\n      \"(:\\\\d{1,5})?\" + // maybe port\n      \"(/|\\\\?|$)\"); // query, path or nothing\n\n  @Override\n  public URIParsedResult parse(Result result) {\n    String rawText = getMassagedText(result);\n    // We specifically handle the odd \"URL\" scheme here for simplicity and add \"URI\" for fun\n    // Assume anything starting this way really means to be a URI\n    if (rawText.startsWith(\"URL:\") || rawText.startsWith(\"URI:\")) {\n      return new URIParsedResult(rawText.substring(4).trim(), null);\n    }\n    rawText = rawText.trim();\n    return isBasicallyValidURI(rawText) ? new URIParsedResult(rawText, null) : null;\n  }\n\n  static boolean isBasicallyValidURI(CharSequence uri) {\n    Matcher m = URL_WITH_PROTOCOL_PATTERN.matcher(uri);\n    if (m.find() && m.start() == 0) { // match at start only\n      return true;\n    }\n    m = URL_WITHOUT_PROTOCOL_PATTERN.matcher(uri);\n    return m.find() && m.start() == 0;\n  }\n\n}"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/result/URLTOResultParser.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.result;\n\nimport com.google.zxing.Result;\n\n/**\n * Parses the \"URLTO\" result format, which is of the form \"URLTO:[title]:[url]\".\n * This seems to be used sometimes, but I am not able to find documentation\n * on its origin or official format?\n *\n * @author Sean Owen\n */\npublic final class URLTOResultParser extends ResultParser {\n\n  @Override\n  public URIParsedResult parse(Result result) {\n    String rawText = getMassagedText(result);\n    if (!rawText.startsWith(\"urlto:\") && !rawText.startsWith(\"URLTO:\")) {\n      return null;\n    }\n    int titleEnd = rawText.indexOf(':', 6);\n    if (titleEnd < 0) {\n      return null;\n    }\n    String title = titleEnd <= 6 ? null : rawText.substring(6, titleEnd);\n    String uri = rawText.substring(titleEnd + 1);\n    return new URIParsedResult(uri, title);\n  }\n\n}"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/result/VCardResultParser.java",
    "content": "/*\n * Copyright 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.result;\n\nimport com.google.zxing.Result;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.UnsupportedEncodingException;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\n/**\n * Parses contact information formatted according to the VCard (2.1) format. This is not a complete\n * implementation but should parse information as commonly encoded in 2D barcodes.\n *\n * @author Sean Owen\n */\npublic final class VCardResultParser extends ResultParser {\n\n  private static final Pattern BEGIN_VCARD = Pattern.compile(\"BEGIN:VCARD\", Pattern.CASE_INSENSITIVE);\n  private static final Pattern VCARD_LIKE_DATE = Pattern.compile(\"\\\\d{4}-?\\\\d{2}-?\\\\d{2}\");\n  private static final Pattern CR_LF_SPACE_TAB = Pattern.compile(\"\\r\\n[ \\t]\");\n  private static final Pattern NEWLINE_ESCAPE = Pattern.compile(\"\\\\\\\\[nN]\");\n  private static final Pattern VCARD_ESCAPES = Pattern.compile(\"\\\\\\\\([,;\\\\\\\\])\");\n  private static final Pattern EQUALS = Pattern.compile(\"=\");\n  private static final Pattern SEMICOLON = Pattern.compile(\";\");\n  private static final Pattern UNESCAPED_SEMICOLONS = Pattern.compile(\"(?<!\\\\\\\\);+\");\n\n  @Override\n  public AddressBookParsedResult parse(Result result) {\n    // Although we should insist on the raw text ending with \"END:VCARD\", there's no reason\n    // to throw out everything else we parsed just because this was omitted. In fact, Eclair\n    // is doing just that, and we can't parse its contacts without this leniency.\n    String rawText = getMassagedText(result);\n    Matcher m = BEGIN_VCARD.matcher(rawText);\n    if (!m.find() || m.start() != 0) {\n      return null;\n    }\n    List<List<String>> names = matchVCardPrefixedField(\"FN\", rawText, true, false);\n    if (names == null) {\n      // If no display names found, look for regular name fields and format them\n      names = matchVCardPrefixedField(\"N\", rawText, true, false);\n      formatNames(names);\n    }\n    List<List<String>> phoneNumbers = matchVCardPrefixedField(\"TEL\", rawText, true, false);\n    List<List<String>> emails = matchVCardPrefixedField(\"EMAIL\", rawText, true, false);\n    List<String> note = matchSingleVCardPrefixedField(\"NOTE\", rawText, false, false);\n    List<List<String>> addresses = matchVCardPrefixedField(\"ADR\", rawText, true, true);\n    List<String> org = matchSingleVCardPrefixedField(\"ORG\", rawText, true, true);\n    List<String> birthday = matchSingleVCardPrefixedField(\"BDAY\", rawText, true, false);\n    if (birthday != null && !isLikeVCardDate(birthday.get(0))) {\n      birthday = null;\n    }\n    List<String> title = matchSingleVCardPrefixedField(\"TITLE\", rawText, true, false);\n    List<String> url = matchSingleVCardPrefixedField(\"URL\", rawText, true, false);\n    List<String> instantMessenger = matchSingleVCardPrefixedField(\"IMPP\", rawText, true, false);\n    return new AddressBookParsedResult(toPrimaryValues(names), \n                                       null, \n                                       toPrimaryValues(phoneNumbers), \n                                       toTypes(phoneNumbers),\n                                       toPrimaryValues(emails),\n                                       toTypes(emails),\n                                       toPrimaryValue(instantMessenger),\n                                       toPrimaryValue(note),\n                                       toPrimaryValues(addresses),\n                                       toTypes(addresses),\n                                       toPrimaryValue(org),\n                                       toPrimaryValue(birthday),\n                                       toPrimaryValue(title),\n                                       toPrimaryValue(url));\n  }\n\n  static List<List<String>> matchVCardPrefixedField(CharSequence prefix,\n                                                    String rawText,\n                                                    boolean trim,\n                                                    boolean parseFieldDivider) {\n    List<List<String>> matches = null;\n    int i = 0;\n    int max = rawText.length();\n\n    while (i < max) {\n\n      // At start or after newline, match prefix, followed by optional metadata \n      // (led by ;) ultimately ending in colon\n      Matcher matcher = Pattern.compile(\"(?:^|\\n)\" + prefix + \"(?:;([^:]*))?:\",\n                                        Pattern.CASE_INSENSITIVE).matcher(rawText);\n      if (i > 0) {\n        i--; // Find from i-1 not i since looking at the preceding character\n      }\n      if (!matcher.find(i)) {\n        break;\n      }\n      i = matcher.end(0); // group 0 = whole pattern; end(0) is past final colon\n\n      String metadataString = matcher.group(1); // group 1 = metadata substring\n      List<String> metadata = null;\n      boolean quotedPrintable = false;\n      String quotedPrintableCharset = null;\n      if (metadataString != null) {\n        for (String metadatum : SEMICOLON.split(metadataString)) {\n          if (metadata == null) {\n            metadata = new ArrayList<String>(1);\n          }\n          metadata.add(metadatum);\n          String[] metadatumTokens = EQUALS.split(metadatum, 2);\n          if (metadatumTokens.length > 1) {\n            String key = metadatumTokens[0];\n            String value = metadatumTokens[1];\n            if (\"ENCODING\".equalsIgnoreCase(key) && \"QUOTED-PRINTABLE\".equalsIgnoreCase(value)) {\n              quotedPrintable = true;\n            } else if (\"CHARSET\".equalsIgnoreCase(key)) {\n              quotedPrintableCharset = value;\n            }\n          }\n        }\n      }\n\n      int matchStart = i; // Found the start of a match here\n\n      while ((i = rawText.indexOf((int) '\\n', i)) >= 0) { // Really, end in \\r\\n\n        if (i < rawText.length() - 1 &&           // But if followed by tab or space,\n            (rawText.charAt(i+1) == ' ' ||        // this is only a continuation\n             rawText.charAt(i+1) == '\\t')) {\n          i += 2; // Skip \\n and continutation whitespace\n        } else if (quotedPrintable &&             // If preceded by = in quoted printable\n                   ((i >= 1 && rawText.charAt(i-1) == '=') || // this is a continuation\n                    (i >= 2 && rawText.charAt(i-2) == '='))) {\n          i++; // Skip \\n\n        } else {\n          break;\n        }\n      }\n\n      if (i < 0) {\n        // No terminating end character? uh, done. Set i such that loop terminates and break\n        i = max;\n      } else if (i > matchStart) {\n        // found a match\n        if (matches == null) {\n          matches = new ArrayList<List<String>>(1); // lazy init\n        }\n        if (i >= 1 && rawText.charAt(i-1) == '\\r') {\n          i--; // Back up over \\r, which really should be there\n        }\n        String element = rawText.substring(matchStart, i);\n        if (trim) {\n          element = element.trim();\n        }\n        if (quotedPrintable) {\n          element = decodeQuotedPrintable(element, quotedPrintableCharset);\n          if (parseFieldDivider) {\n            element = UNESCAPED_SEMICOLONS.matcher(element).replaceAll(\"\\n\").trim();\n          }\n        } else {\n          if (parseFieldDivider) {\n            element = UNESCAPED_SEMICOLONS.matcher(element).replaceAll(\"\\n\").trim();\n          }\n          element = CR_LF_SPACE_TAB.matcher(element).replaceAll(\"\");\n          element = NEWLINE_ESCAPE.matcher(element).replaceAll(\"\\n\");\n          element = VCARD_ESCAPES.matcher(element).replaceAll(\"$1\");\n        }\n        if (metadata == null) {\n          List<String> match = new ArrayList<String>(1);\n          match.add(element);\n          matches.add(match);\n        } else {\n          metadata.add(0, element);\n          matches.add(metadata);\n        }\n        i++;\n      } else {\n        i++;\n      }\n\n    }\n\n    return matches;\n  }\n\n  private static String decodeQuotedPrintable(CharSequence value, String charset) {\n    int length = value.length();\n    StringBuilder result = new StringBuilder(length);\n    ByteArrayOutputStream fragmentBuffer = new ByteArrayOutputStream();\n    for (int i = 0; i < length; i++) {\n      char c = value.charAt(i);\n      switch (c) {\n        case '\\r':\n        case '\\n':\n          break;\n        case '=':\n          if (i < length - 2) {\n            char nextChar = value.charAt(i+1);\n            if (nextChar != '\\r' && nextChar != '\\n') {\n              char nextNextChar = value.charAt(i+2);\n              int firstDigit = parseHexDigit(nextChar);\n              int secondDigit = parseHexDigit(nextNextChar);\n              if (firstDigit >= 0 && secondDigit >= 0) {\n                fragmentBuffer.write((firstDigit << 4) + secondDigit);\n              } // else ignore it, assume it was incorrectly encoded\n              i += 2;\n            }\n          }\n          break;\n        default:\n          maybeAppendFragment(fragmentBuffer, charset, result);\n          result.append(c);\n      }\n    }\n    maybeAppendFragment(fragmentBuffer, charset, result);\n    return result.toString();\n  }\n\n  private static void maybeAppendFragment(ByteArrayOutputStream fragmentBuffer,\n                                          String charset,\n                                          StringBuilder result) {\n    if (fragmentBuffer.size() > 0) {\n      byte[] fragmentBytes = fragmentBuffer.toByteArray();\n      String fragment;\n      if (charset == null) {\n        fragment = new String(fragmentBytes);\n      } else {\n        try {\n          fragment = new String(fragmentBytes, charset);\n        } catch (UnsupportedEncodingException e) {\n          // Yikes, well try anyway:\n          fragment = new String(fragmentBytes);\n        }\n      }\n      fragmentBuffer.reset();\n      result.append(fragment);\n    }\n  }\n\n  static List<String> matchSingleVCardPrefixedField(CharSequence prefix,\n                                                    String rawText,\n                                                    boolean trim,\n                                                    boolean parseFieldDivider) {\n    List<List<String>> values = matchVCardPrefixedField(prefix, rawText, trim, parseFieldDivider);\n    return values == null || values.isEmpty() ? null : values.get(0);\n  }\n  \n  private static String toPrimaryValue(List<String> list) {\n    return list == null || list.isEmpty() ? null : list.get(0);\n  }\n  \n  private static String[] toPrimaryValues(Collection<List<String>> lists) {\n    if (lists == null || lists.isEmpty()) {\n      return null;\n    }\n    List<String> result = new ArrayList<String>(lists.size());\n    for (List<String> list : lists) {\n      result.add(list.get(0));\n    }\n    return result.toArray(new String[lists.size()]);\n  }\n  \n  private static String[] toTypes(Collection<List<String>> lists) {\n    if (lists == null || lists.isEmpty()) {\n      return null;\n    }\n    List<String> result = new ArrayList<String>(lists.size());\n    for (List<String> list : lists) {\n      String type = null;\n      for (int i = 1; i < list.size(); i++) {\n        String metadatum = list.get(i);\n        int equals = metadatum.indexOf('=');\n        if (equals < 0) {\n          // take the whole thing as a usable label\n          type = metadatum;\n          break;\n        }\n        if (\"TYPE\".equalsIgnoreCase(metadatum.substring(0, equals))) {\n          type = metadatum.substring(equals + 1);\n          break;\n        }\n      }\n      result.add(type);\n    }\n    return result.toArray(new String[lists.size()]);\n  }\n\n  private static boolean isLikeVCardDate(CharSequence value) {\n    return value == null || VCARD_LIKE_DATE.matcher(value).matches();\n  }\n\n  /**\n   * Formats name fields of the form \"Public;John;Q.;Reverend;III\" into a form like\n   * \"Reverend John Q. Public III\".\n   *\n   * @param names name values to format, in place\n   */\n  private static void formatNames(Iterable<List<String>> names) {\n    if (names != null) {\n      for (List<String> list : names) {\n        String name = list.get(0);\n        String[] components = new String[5];\n        int start = 0;\n        int end;\n        int componentIndex = 0;\n        while (componentIndex < components.length - 1 && (end = name.indexOf(';', start)) > 0) {\n          components[componentIndex] = name.substring(start, end);\n          componentIndex++;\n          start = end + 1;\n        }\n        components[componentIndex] = name.substring(start);\n        StringBuilder newName = new StringBuilder(100);\n        maybeAppendComponent(components, 3, newName);\n        maybeAppendComponent(components, 1, newName);\n        maybeAppendComponent(components, 2, newName);\n        maybeAppendComponent(components, 0, newName);\n        maybeAppendComponent(components, 4, newName);\n        list.set(0, newName.toString().trim());\n      }\n    }\n  }\n\n  private static void maybeAppendComponent(String[] components, int i, StringBuilder newName) {\n    if (components[i] != null) {\n      newName.append(' ');\n      newName.append(components[i]);\n    }\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/result/VEventResultParser.java",
    "content": "/*\n * Copyright 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.result;\n\nimport com.google.zxing.Result;\n\nimport java.util.List;\n\n/**\n * Partially implements the iCalendar format's \"VEVENT\" format for specifying a\n * calendar event. See RFC 2445. This supports SUMMARY, LOCATION, GEO, DTSTART and DTEND fields.\n *\n * @author Sean Owen\n */\npublic final class VEventResultParser extends ResultParser {\n\n  @Override\n  public CalendarParsedResult parse(Result result) {\n    String rawText = getMassagedText(result);\n    int vEventStart = rawText.indexOf(\"BEGIN:VEVENT\");\n    if (vEventStart < 0) {\n      return null;\n    }\n\n    String summary = matchSingleVCardPrefixedField(\"SUMMARY\", rawText, true);\n    String start = matchSingleVCardPrefixedField(\"DTSTART\", rawText, true);\n    if (start == null) {\n      return null;\n    }\n    String end = matchSingleVCardPrefixedField(\"DTEND\", rawText, true);\n    String location = matchSingleVCardPrefixedField(\"LOCATION\", rawText, true);\n    String organizer = stripMailto(matchSingleVCardPrefixedField(\"ORGANIZER\", rawText, true));\n\n    String[] attendees = matchVCardPrefixedField(\"ATTENDEE\", rawText, true);\n    if (attendees != null) {\n      for (int i = 0; i < attendees.length; i++) {\n        attendees[i] = stripMailto(attendees[i]);\n      }\n    }\n    String description = matchSingleVCardPrefixedField(\"DESCRIPTION\", rawText, true);\n\n    String geoString = matchSingleVCardPrefixedField(\"GEO\", rawText, true);\n    double latitude;\n    double longitude;\n    if (geoString == null) {\n      latitude = Double.NaN;\n      longitude = Double.NaN;\n    } else {\n      int semicolon = geoString.indexOf(';');\n      try {\n        latitude = Double.parseDouble(geoString.substring(0, semicolon));\n        longitude = Double.parseDouble(geoString.substring(semicolon + 1));\n      } catch (NumberFormatException nfe) {\n        return null;\n      }\n    }\n\n    try {\n      return new CalendarParsedResult(summary,\n                                      start,\n                                      end,\n                                      location,\n                                      organizer,\n                                      attendees,\n                                      description,\n                                      latitude,\n                                      longitude);\n    } catch (IllegalArgumentException iae) {\n      return null;\n    }\n  }\n\n  private static String matchSingleVCardPrefixedField(CharSequence prefix,\n                                                      String rawText,\n                                                      boolean trim) {\n    List<String> values = VCardResultParser.matchSingleVCardPrefixedField(prefix, rawText, trim, false);\n    return values == null || values.isEmpty() ? null : values.get(0);\n  }\n\n  private static String[] matchVCardPrefixedField(CharSequence prefix, String rawText, boolean trim) {\n    List<List<String>> values = VCardResultParser.matchVCardPrefixedField(prefix, rawText, trim, false);\n    if (values == null || values.isEmpty()) {\n      return null;\n    }\n    int size = values.size();\n    String[] result = new String[size];\n    for (int i = 0; i < size; i++) {\n      result[i] = values.get(i).get(0);\n    }\n    return result;\n  }\n\n  private static String stripMailto(String s) {\n    if (s != null && (s.startsWith(\"mailto:\") || s.startsWith(\"MAILTO:\"))) {\n      s = s.substring(7);\n    }\n    return s;\n  }\n\n}"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/result/WifiParsedResult.java",
    "content": "/*\n * Copyright 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.result;\n\n/**\n * @author Vikram Aggarwal\n */\npublic final class WifiParsedResult extends ParsedResult {\n\n  private final String ssid;\n  private final String networkEncryption;\n  private final String password;\n  private final boolean hidden;\n\n  public WifiParsedResult(String networkEncryption, String ssid, String password) {\n    this(networkEncryption, ssid, password, false);\n  }\n\n  public WifiParsedResult(String networkEncryption, String ssid, String password, boolean hidden) {\n    super(ParsedResultType.WIFI);\n    this.ssid = ssid;\n    this.networkEncryption = networkEncryption;\n    this.password = password;\n    this.hidden = hidden;\n  }\n\n  public String getSsid() {\n    return ssid;\n  }\n\n  public String getNetworkEncryption() {\n    return networkEncryption;\n  }\n\n  public String getPassword() {\n    return password;\n  }\n\n  public boolean isHidden() {\n    return hidden;\n  }\n\n  @Override\n  public String getDisplayResult() {\n    StringBuilder result = new StringBuilder(80);\n    maybeAppend(ssid, result);\n    maybeAppend(networkEncryption, result);\n    maybeAppend(password, result);\n    maybeAppend(Boolean.toString(hidden), result);\n    return result.toString();\n  }\n\n}"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/client/result/WifiResultParser.java",
    "content": "/*\n * Copyright 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.client.result;\n\nimport com.google.zxing.Result;\n\n/**\n * <p>Parses a WIFI configuration string. Strings will be of the form:</p>\n *\n * <p>{@code WIFI:T:[network type];S:[network SSID];P:[network password];H:[hidden?];;}</p>\n *\n * <p>The fields can appear in any order. Only \"S:\" is required.</p>\n *\n * @author Vikram Aggarwal\n * @author Sean Owen\n */\npublic final class WifiResultParser extends ResultParser {\n\n  @Override\n  public WifiParsedResult parse(Result result) {\n    String rawText = getMassagedText(result);\n    if (!rawText.startsWith(\"WIFI:\")) {\n      return null;\n    }\n    String ssid = matchSinglePrefixedField(\"S:\", rawText, ';', false);\n    if (ssid == null || ssid.length() == 0) {\n      return null;\n    }\n    String pass = matchSinglePrefixedField(\"P:\", rawText, ';', false);\n    String type = matchSinglePrefixedField(\"T:\", rawText, ';', false);\n    if (type == null) {\n      type = \"nopass\";\n    }\n    boolean hidden = Boolean.parseBoolean(matchSinglePrefixedField(\"B:\", rawText, ';', false));\n    return new WifiParsedResult(type, ssid, pass, hidden);\n  }\n}"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/common/BitArray.java",
    "content": "/*\r\n * Copyright 2007 ZXing authors\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage com.google.zxing.common;\r\n\r\n/**\r\n * <p>A simple, fast array of bits, represented compactly by an array of ints internally.</p>\r\n *\r\n * @author Sean Owen\r\n */\r\npublic final class BitArray {\r\n\r\n  private int[] bits;\r\n  private int size;\r\n\r\n  public BitArray() {\r\n    this.size = 0;\r\n    this.bits = new int[1];\r\n  }\r\n\r\n  public BitArray(int size) {\r\n    this.size = size;\r\n    this.bits = makeArray(size);\r\n  }\r\n\r\n  public int getSize() {\r\n    return size;\r\n  }\r\n\r\n  public int getSizeInBytes() {\r\n    return (size + 7) >> 3;\r\n  }\r\n\r\n  private void ensureCapacity(int size) {\r\n    if (size > bits.length << 5) {\r\n      int[] newBits = makeArray(size);\r\n      System.arraycopy(bits, 0, newBits, 0, bits.length);\r\n      this.bits = newBits;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * @param i bit to get\r\n   * @return true iff bit i is set\r\n   */\r\n  public boolean get(int i) {\r\n    return (bits[i >> 5] & (1 << (i & 0x1F))) != 0;\r\n  }\r\n\r\n  /**\r\n   * Sets bit i.\r\n   *\r\n   * @param i bit to set\r\n   */\r\n  public void set(int i) {\r\n    bits[i >> 5] |= 1 << (i & 0x1F);\r\n  }\r\n\r\n  /**\r\n   * Flips bit i.\r\n   *\r\n   * @param i bit to set\r\n   */\r\n  public void flip(int i) {\r\n    bits[i >> 5] ^= 1 << (i & 0x1F);\r\n  }\r\n\r\n  /**\r\n   * @param from first bit to check\r\n   * @return index of first bit that is set, starting from the given index, or size if none are set\r\n   *  at or beyond this given index\r\n   * @see #getNextUnset(int)\r\n   */\r\n  public int getNextSet(int from) {\r\n    if (from >= size) {\r\n      return size;\r\n    }\r\n    int bitsOffset = from >> 5;\r\n    int currentBits = bits[bitsOffset];\r\n    // mask off lesser bits first\r\n    currentBits &= ~((1 << (from & 0x1F)) - 1);\r\n    while (currentBits == 0) {\r\n      if (++bitsOffset == bits.length) {\r\n        return size;\r\n      }\r\n      currentBits = bits[bitsOffset];\r\n    }\r\n    int result = (bitsOffset << 5) + Integer.numberOfTrailingZeros(currentBits);\r\n    return result > size ? size : result;\r\n  }\r\n\r\n  /**\r\n   * @see #getNextSet(int)\r\n   */\r\n  public int getNextUnset(int from) {\r\n    if (from >= size) {\r\n      return size;\r\n    }\r\n    int bitsOffset = from >> 5;\r\n    int currentBits = ~bits[bitsOffset];\r\n    // mask off lesser bits first\r\n    currentBits &= ~((1 << (from & 0x1F)) - 1);\r\n    while (currentBits == 0) {\r\n      if (++bitsOffset == bits.length) {\r\n        return size;\r\n      }\r\n      currentBits = ~bits[bitsOffset];\r\n    }\r\n    int result = (bitsOffset << 5) + Integer.numberOfTrailingZeros(currentBits);\r\n    return result > size ? size : result;\r\n  }\r\n\r\n  /**\r\n   * Sets a block of 32 bits, starting at bit i.\r\n   *\r\n   * @param i first bit to set\r\n   * @param newBits the new value of the next 32 bits. Note again that the least-significant bit\r\n   * corresponds to bit i, the next-least-significant to i+1, and so on.\r\n   */\r\n  public void setBulk(int i, int newBits) {\r\n    bits[i >> 5] = newBits;\r\n  }\r\n\r\n  /**\r\n   * Sets a range of bits.\r\n   *\r\n   * @param start start of range, inclusive.\r\n   * @param end end of range, exclusive\r\n   */\r\n  public void setRange(int start, int end) {\r\n    if (end < start) {\r\n      throw new IllegalArgumentException();\r\n    }\r\n    if (end == start) {\r\n      return;\r\n    }\r\n    end--; // will be easier to treat this as the last actually set bit -- inclusive\r\n    int firstInt = start >> 5;\r\n    int lastInt = end >> 5;\r\n    for (int i = firstInt; i <= lastInt; i++) {\r\n      int firstBit = i > firstInt ? 0 : start & 0x1F;\r\n      int lastBit = i < lastInt ? 31 : end & 0x1F;\r\n      int mask;\r\n      if (firstBit == 0 && lastBit == 31) {\r\n        mask = -1;\r\n      } else {\r\n        mask = 0;\r\n        for (int j = firstBit; j <= lastBit; j++) {\r\n          mask |= 1 << j;\r\n        }\r\n      }\r\n      bits[i] |= mask;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Clears all bits (sets to false).\r\n   */\r\n  public void clear() {\r\n    int max = bits.length;\r\n    for (int i = 0; i < max; i++) {\r\n      bits[i] = 0;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Efficient method to check if a range of bits is set, or not set.\r\n   *\r\n   * @param start start of range, inclusive.\r\n   * @param end end of range, exclusive\r\n   * @param value if true, checks that bits in range are set, otherwise checks that they are not set\r\n   * @return true iff all bits are set or not set in range, according to value argument\r\n   * @throws IllegalArgumentException if end is less than or equal to start\r\n   */\r\n  public boolean isRange(int start, int end, boolean value) {\r\n    if (end < start) {\r\n      throw new IllegalArgumentException();\r\n    }\r\n    if (end == start) {\r\n      return true; // empty range matches\r\n    }\r\n    end--; // will be easier to treat this as the last actually set bit -- inclusive\r\n    int firstInt = start >> 5;\r\n    int lastInt = end >> 5;\r\n    for (int i = firstInt; i <= lastInt; i++) {\r\n      int firstBit = i > firstInt ? 0 : start & 0x1F;\r\n      int lastBit = i < lastInt ? 31 : end & 0x1F;\r\n      int mask;\r\n      if (firstBit == 0 && lastBit == 31) {\r\n        mask = -1;\r\n      } else {\r\n        mask = 0;\r\n        for (int j = firstBit; j <= lastBit; j++) {\r\n          mask |= 1 << j;\r\n        }\r\n      }\r\n\r\n      // Return false if we're looking for 1s and the masked bits[i] isn't all 1s (that is,\r\n      // equals the mask, or we're looking for 0s and the masked portion is not all 0s\r\n      if ((bits[i] & mask) != (value ? mask : 0)) {\r\n        return false;\r\n      }\r\n    }\r\n    return true;\r\n  }\r\n\r\n  public void appendBit(boolean bit) {\r\n    ensureCapacity(size + 1);\r\n    if (bit) {\r\n      bits[size >> 5] |= 1 << (size & 0x1F);\r\n    }\r\n    size++;\r\n  }\r\n\r\n  /**\r\n   * Appends the least-significant bits, from value, in order from most-significant to\r\n   * least-significant. For example, appending 6 bits from 0x000001E will append the bits\r\n   * 0, 1, 1, 1, 1, 0 in that order.\r\n   */\r\n  public void appendBits(int value, int numBits) {\r\n    if (numBits < 0 || numBits > 32) {\r\n      throw new IllegalArgumentException(\"Num bits must be between 0 and 32\");\r\n    }\r\n    ensureCapacity(size + numBits);\r\n    for (int numBitsLeft = numBits; numBitsLeft > 0; numBitsLeft--) {\r\n      appendBit(((value >> (numBitsLeft - 1)) & 0x01) == 1);\r\n    }\r\n  }\r\n\r\n  public void appendBitArray(BitArray other) {\r\n    int otherSize = other.size;\r\n    ensureCapacity(size + otherSize);\r\n    for (int i = 0; i < otherSize; i++) {\r\n      appendBit(other.get(i));\r\n    }\r\n  }\r\n\r\n  public void xor(BitArray other) {\r\n    if (bits.length != other.bits.length) {\r\n      throw new IllegalArgumentException(\"Sizes don't match\");\r\n    }\r\n    for (int i = 0; i < bits.length; i++) {\r\n      // The last byte could be incomplete (i.e. not have 8 bits in\r\n      // it) but there is no problem since 0 XOR 0 == 0.\r\n      bits[i] ^= other.bits[i];\r\n    }\r\n  }\r\n\r\n  /**\r\n   *\r\n   * @param bitOffset first bit to start writing\r\n   * @param array array to write into. Bytes are written most-significant byte first. This is the opposite\r\n   *  of the internal representation, which is exposed by {@link #getBitArray()}\r\n   * @param offset position in array to start writing\r\n   * @param numBytes how many bytes to write\r\n   */\r\n  public void toBytes(int bitOffset, byte[] array, int offset, int numBytes) {\r\n    for (int i = 0; i < numBytes; i++) {\r\n      int theByte = 0;\r\n      for (int j = 0; j < 8; j++) {\r\n        if (get(bitOffset)) {\r\n          theByte |= 1 << (7 - j);\r\n        }\r\n        bitOffset++;\r\n      }\r\n      array[offset + i] = (byte) theByte;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * @return underlying array of ints. The first element holds the first 32 bits, and the least\r\n   *         significant bit is bit 0.\r\n   */\r\n  public int[] getBitArray() {\r\n    return bits;\r\n  }\r\n\r\n  /**\r\n   * Reverses all bits in the array.\r\n   */\r\n  public void reverse() {\r\n    int[] newBits = new int[bits.length];\r\n    int size = this.size;\r\n    for (int i = 0; i < size; i++) {\r\n      if (get(size - i - 1)) {\r\n        newBits[i >> 5] |= 1 << (i & 0x1F);\r\n      }\r\n    }\r\n    bits = newBits;\r\n  }\r\n\r\n  private static int[] makeArray(int size) {\r\n    return new int[(size + 31) >> 5];\r\n  }\r\n\r\n  @Override\r\n  public String toString() {\r\n    StringBuilder result = new StringBuilder(size);\r\n    for (int i = 0; i < size; i++) {\r\n      if ((i & 0x07) == 0) {\r\n        result.append(' ');\r\n      }\r\n      result.append(get(i) ? 'X' : '.');\r\n    }\r\n    return result.toString();\r\n  }\r\n\r\n}"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/common/BitMatrix.java",
    "content": "/*\r\n * Copyright 2007 ZXing authors\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage com.google.zxing.common;\r\n\r\n/**\r\n * <p>Represents a 2D matrix of bits. In function arguments below, and throughout the common\r\n * module, x is the column position, and y is the row position. The ordering is always x, y.\r\n * The origin is at the top-left.</p>\r\n *\r\n * <p>Internally the bits are represented in a 1-D array of 32-bit ints. However, each row begins\r\n * with a new int. This is done intentionally so that we can copy out a row into a BitArray very\r\n * efficiently.</p>\r\n *\r\n * <p>The ordering of bits is row-major. Within each int, the least significant bits are used first,\r\n * meaning they represent lower x values. This is compatible with BitArray's implementation.</p>\r\n *\r\n * @author Sean Owen\r\n * @author dswitkin@google.com (Daniel Switkin)\r\n */\r\npublic final class BitMatrix {\r\n\r\n  private final int width;\r\n  private final int height;\r\n  private final int rowSize;\r\n  private final int[] bits;\r\n\r\n  // A helper to construct a square matrix.\r\n  public BitMatrix(int dimension) {\r\n    this(dimension, dimension);\r\n  }\r\n\r\n  public BitMatrix(int width, int height) {\r\n    if (width < 1 || height < 1) {\r\n      throw new IllegalArgumentException(\"Both dimensions must be greater than 0\");\r\n    }\r\n    this.width = width;\r\n    this.height = height;\r\n    this.rowSize = (width + 31) >> 5;\r\n    bits = new int[rowSize * height];\r\n  }\r\n\r\n  /**\r\n   * <p>Gets the requested bit, where true means black.</p>\r\n   *\r\n   * @param x The horizontal component (i.e. which column)\r\n   * @param y The vertical component (i.e. which row)\r\n   * @return value of given bit in matrix\r\n   */\r\n  public boolean get(int x, int y) {\r\n    int offset = y * rowSize + (x >> 5);\r\n    return ((bits[offset] >>> (x & 0x1f)) & 1) != 0;\r\n  }\r\n\r\n  /**\r\n   * <p>Sets the given bit to true.</p>\r\n   *\r\n   * @param x The horizontal component (i.e. which column)\r\n   * @param y The vertical component (i.e. which row)\r\n   */\r\n  public void set(int x, int y) {\r\n    int offset = y * rowSize + (x >> 5);\r\n    bits[offset] |= 1 << (x & 0x1f);\r\n  }\r\n\r\n  /**\r\n   * <p>Flips the given bit.</p>\r\n   *\r\n   * @param x The horizontal component (i.e. which column)\r\n   * @param y The vertical component (i.e. which row)\r\n   */\r\n  public void flip(int x, int y) {\r\n    int offset = y * rowSize + (x >> 5);\r\n    bits[offset] ^= 1 << (x & 0x1f);\r\n  }\r\n\r\n  /**\r\n   * Clears all bits (sets to false).\r\n   */\r\n  public void clear() {\r\n    int max = bits.length;\r\n    for (int i = 0; i < max; i++) {\r\n      bits[i] = 0;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * <p>Sets a square region of the bit matrix to true.</p>\r\n   *\r\n   * @param left The horizontal position to begin at (inclusive)\r\n   * @param top The vertical position to begin at (inclusive)\r\n   * @param width The width of the region\r\n   * @param height The height of the region\r\n   */\r\n  public void setRegion(int left, int top, int width, int height) {\r\n    if (top < 0 || left < 0) {\r\n      throw new IllegalArgumentException(\"Left and top must be nonnegative\");\r\n    }\r\n    if (height < 1 || width < 1) {\r\n      throw new IllegalArgumentException(\"Height and width must be at least 1\");\r\n    }\r\n    int right = left + width;\r\n    int bottom = top + height;\r\n    if (bottom > this.height || right > this.width) {\r\n      throw new IllegalArgumentException(\"The region must fit inside the matrix\");\r\n    }\r\n    for (int y = top; y < bottom; y++) {\r\n      int offset = y * rowSize;\r\n      for (int x = left; x < right; x++) {\r\n        bits[offset + (x >> 5)] |= 1 << (x & 0x1f);\r\n      }\r\n    }\r\n  }\r\n\r\n  /**\r\n   * A fast method to retrieve one row of data from the matrix as a BitArray.\r\n   *\r\n   * @param y The row to retrieve\r\n   * @param row An optional caller-allocated BitArray, will be allocated if null or too small\r\n   * @return The resulting BitArray - this reference should always be used even when passing\r\n   *         your own row\r\n   */\r\n  public BitArray getRow(int y, BitArray row) {\r\n    if (row == null || row.getSize() < width) {\r\n      row = new BitArray(width);\r\n    }\r\n    int offset = y * rowSize;\r\n    for (int x = 0; x < rowSize; x++) {\r\n      row.setBulk(x << 5, bits[offset + x]);\r\n    }\r\n    return row;\r\n  }\r\n\r\n  /**\r\n   * @param y row to set\r\n   * @param row {@link BitArray} to copy from\r\n   */\r\n  public void setRow(int y, BitArray row) {\r\n    System.arraycopy(row.getBitArray(), 0, bits, y * rowSize, rowSize);\r\n  }\r\n\r\n  /**\r\n   * This is useful in detecting the enclosing rectangle of a 'pure' barcode.\r\n   *\r\n   * @return {left,top,width,height} enclosing rectangle of all 1 bits, or null if it is all white\r\n   */\r\n  public int[] getEnclosingRectangle() {\r\n    int left = width;\r\n    int top = height;\r\n    int right = -1;\r\n    int bottom = -1;\r\n\r\n    for (int y = 0; y < height; y++) {\r\n      for (int x32 = 0; x32 < rowSize; x32++) {\r\n        int theBits = bits[y * rowSize + x32];\r\n        if (theBits != 0) {\r\n          if (y < top) {\r\n            top = y;\r\n          }\r\n          if (y > bottom) {\r\n            bottom = y;\r\n          }\r\n          if (x32 * 32 < left) {\r\n            int bit = 0;\r\n            while ((theBits << (31 - bit)) == 0) {\r\n              bit++;\r\n            }\r\n            if ((x32 * 32 + bit) < left) {\r\n              left = x32 * 32 + bit;\r\n            }\r\n          }\r\n          if (x32 * 32 + 31 > right) {\r\n            int bit = 31;\r\n            while ((theBits >>> bit) == 0) {\r\n              bit--;\r\n            }\r\n            if ((x32 * 32 + bit) > right) {\r\n              right = x32 * 32 + bit;\r\n            }\r\n          }\r\n        }\r\n      }\r\n    }\r\n\r\n    int width = right - left;\r\n    int height = bottom - top;\r\n\r\n    if (width < 0 || height < 0) {\r\n      return null;\r\n    }\r\n\r\n    return new int[] {left, top, width, height};\r\n  }\r\n\r\n  /**\r\n   * This is useful in detecting a corner of a 'pure' barcode.\r\n   *\r\n   * @return {x,y} coordinate of top-left-most 1 bit, or null if it is all white\r\n   */\r\n  public int[] getTopLeftOnBit() {\r\n    int bitsOffset = 0;\r\n    while (bitsOffset < bits.length && bits[bitsOffset] == 0) {\r\n      bitsOffset++;\r\n    }\r\n    if (bitsOffset == bits.length) {\r\n      return null;\r\n    }\r\n    int y = bitsOffset / rowSize;\r\n    int x = (bitsOffset % rowSize) << 5;\r\n\r\n    int theBits = bits[bitsOffset];\r\n    int bit = 0;\r\n    while ((theBits << (31-bit)) == 0) {\r\n      bit++;\r\n    }\r\n    x += bit;\r\n    return new int[] {x, y};\r\n  }\r\n\r\n  public int[] getBottomRightOnBit() {\r\n    int bitsOffset = bits.length - 1;\r\n    while (bitsOffset >= 0 && bits[bitsOffset] == 0) {\r\n      bitsOffset--;\r\n    }\r\n    if (bitsOffset < 0) {\r\n      return null;\r\n    }\r\n\r\n    int y = bitsOffset / rowSize;\r\n    int x = (bitsOffset % rowSize) << 5;\r\n\r\n    int theBits = bits[bitsOffset];\r\n    int bit = 31;\r\n    while ((theBits >>> bit) == 0) {\r\n      bit--;\r\n    }\r\n    x += bit;\r\n\r\n    return new int[] {x, y};\r\n  }\r\n\r\n  /**\r\n   * @return The width of the matrix\r\n   */\r\n  public int getWidth() {\r\n    return width;\r\n  }\r\n\r\n  /**\r\n   * @return The height of the matrix\r\n   */\r\n  public int getHeight() {\r\n    return height;\r\n  }\r\n\r\n  @Override\r\n  public boolean equals(Object o) {\r\n    if (!(o instanceof BitMatrix)) {\r\n      return false;\r\n    }\r\n    BitMatrix other = (BitMatrix) o;\r\n    if (width != other.width || height != other.height ||\r\n        rowSize != other.rowSize || bits.length != other.bits.length) {\r\n      return false;\r\n    }\r\n    for (int i = 0; i < bits.length; i++) {\r\n      if (bits[i] != other.bits[i]) {\r\n        return false;\r\n      }\r\n    }\r\n    return true;\r\n  }\r\n\r\n  @Override\r\n  public int hashCode() {\r\n    int hash = width;\r\n    hash = 31 * hash + width;\r\n    hash = 31 * hash + height;\r\n    hash = 31 * hash + rowSize;\r\n    for (int bit : bits) {\r\n      hash = 31 * hash + bit;\r\n    }\r\n    return hash;\r\n  }\r\n\r\n  @Override\r\n  public String toString() {\r\n    StringBuilder result = new StringBuilder(height * (width + 1));\r\n    for (int y = 0; y < height; y++) {\r\n      for (int x = 0; x < width; x++) {\r\n        result.append(get(x, y) ? \"X \" : \"  \");\r\n      }\r\n      result.append('\\n');\r\n    }\r\n    return result.toString();\r\n  }\r\n\r\n}\r\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/common/BitSource.java",
    "content": "/*\r\n * Copyright 2007 ZXing authors\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage com.google.zxing.common;\r\n\r\n/**\r\n * <p>This provides an easy abstraction to read bits at a time from a sequence of bytes, where the\r\n * number of bits read is not often a multiple of 8.</p>\r\n *\r\n * <p>This class is thread-safe but not reentrant -- unless the caller modifies the bytes array\r\n * it passed in, in which case all bets are off.</p>\r\n *\r\n * @author Sean Owen\r\n */\r\npublic final class BitSource {\r\n\r\n  private final byte[] bytes;\r\n  private int byteOffset;\r\n  private int bitOffset;\r\n\r\n  /**\r\n   * @param bytes bytes from which this will read bits. Bits will be read from the first byte first.\r\n   * Bits are read within a byte from most-significant to least-significant bit.\r\n   */\r\n  public BitSource(byte[] bytes) {\r\n    this.bytes = bytes;\r\n  }\r\n\r\n  /**\r\n   * @return index of next bit in current byte which would be read by the next call to {@link #readBits(int)}.\r\n   */\r\n  public int getBitOffset() {\r\n    return bitOffset;\r\n  }\r\n\r\n  /**\r\n   * @return index of next byte in input byte array which would be read by the next call to {@link #readBits(int)}.\r\n   */\r\n  public int getByteOffset() {\r\n    return byteOffset;\r\n  }\r\n\r\n  /**\r\n   * @param numBits number of bits to read\r\n   * @return int representing the bits read. The bits will appear as the least-significant\r\n   *         bits of the int\r\n   * @throws IllegalArgumentException if numBits isn't in [1,32] or more than is available\r\n   */\r\n  public int readBits(int numBits) {\r\n    if (numBits < 1 || numBits > 32 || numBits > available()) {\r\n      throw new IllegalArgumentException(String.valueOf(numBits));\r\n    }\r\n\r\n    int result = 0;\r\n\r\n    // First, read remainder from current byte\r\n    if (bitOffset > 0) {\r\n      int bitsLeft = 8 - bitOffset;\r\n      int toRead = numBits < bitsLeft ? numBits : bitsLeft;\r\n      int bitsToNotRead = bitsLeft - toRead;\r\n      int mask = (0xFF >> (8 - toRead)) << bitsToNotRead;\r\n      result = (bytes[byteOffset] & mask) >> bitsToNotRead;\r\n      numBits -= toRead;\r\n      bitOffset += toRead;\r\n      if (bitOffset == 8) {\r\n        bitOffset = 0;\r\n        byteOffset++;\r\n      }\r\n    }\r\n\r\n    // Next read whole bytes\r\n    if (numBits > 0) {\r\n      while (numBits >= 8) {\r\n        result = (result << 8) | (bytes[byteOffset] & 0xFF);\r\n        byteOffset++;\r\n        numBits -= 8;\r\n      }\r\n\r\n      // Finally read a partial byte\r\n      if (numBits > 0) {\r\n        int bitsToNotRead = 8 - numBits;\r\n        int mask = (0xFF >> bitsToNotRead) << bitsToNotRead;\r\n        result = (result << numBits) | ((bytes[byteOffset] & mask) >> bitsToNotRead);\r\n        bitOffset += numBits;\r\n      }\r\n    }\r\n\r\n    return result;\r\n  }\r\n\r\n  /**\r\n   * @return number of bits that can be read successfully\r\n   */\r\n  public int available() {\r\n    return 8 * (bytes.length - byteOffset) - bitOffset;\r\n  }\r\n\r\n}\r\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/common/CharacterSetECI.java",
    "content": "/*\n * Copyright 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.common;\n\nimport com.google.zxing.FormatException;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * Encapsulates a Character Set ECI, according to \"Extended Channel Interpretations\" 5.3.1.1\n * of ISO 18004.\n *\n * @author Sean Owen\n */\npublic enum CharacterSetECI {\n\n  // Enum name is a Java encoding valid for java.lang and java.io\n  Cp437(new int[]{0,2}),\n  ISO8859_1(new int[]{1,3}, \"ISO-8859-1\"),\n  ISO8859_2(4, \"ISO-8859-2\"),\n  ISO8859_3(5, \"ISO-8859-3\"),\n  ISO8859_4(6, \"ISO-8859-4\"),\n  ISO8859_5(7, \"ISO-8859-5\"),\n  ISO8859_6(8, \"ISO-8859-6\"),\n  ISO8859_7(9, \"ISO-8859-7\"),\n  ISO8859_8(10, \"ISO-8859-8\"),\n  ISO8859_9(11, \"ISO-8859-9\"),\n  ISO8859_10(12, \"ISO-8859-10\"),\n  ISO8859_11(13, \"ISO-8859-11\"),\n  ISO8859_13(15, \"ISO-8859-13\"),\n  ISO8859_14(16, \"ISO-8859-14\"),\n  ISO8859_15(17, \"ISO-8859-15\"),\n  ISO8859_16(18, \"ISO-8859-16\"),\n  SJIS(20, \"Shift_JIS\"),\n  Cp1250(21, \"windows-1250\"),\n  Cp1251(22, \"windows-1251\"),\n  Cp1252(23, \"windows-1252\"),\n  Cp1256(24, \"windows-1256\"),\n  UnicodeBigUnmarked(25, \"UTF-16BE\", \"UnicodeBig\"),\n  UTF8(26, \"UTF-8\"),\n  ASCII(new int[] {27, 170}, \"US-ASCII\"),\n  Big5(28),\n  GB18030(29, \"GB2312\", \"EUC_CN\", \"GBK\"),\n  EUC_KR(30, \"EUC-KR\");\n\n  private static final Map<Integer,CharacterSetECI> VALUE_TO_ECI = new HashMap<Integer,CharacterSetECI>();\n  private static final Map<String,CharacterSetECI> NAME_TO_ECI = new HashMap<String,CharacterSetECI>();\n  static {\n    for (CharacterSetECI eci : values()) {\n      for (int value : eci.values) {\n        VALUE_TO_ECI.put(value, eci);\n      }\n      NAME_TO_ECI.put(eci.name(), eci);\n      for (String name : eci.otherEncodingNames) {\n        NAME_TO_ECI.put(name, eci);\n      }\n    }\n  }\n\n  private final int[] values;\n  private final String[] otherEncodingNames;\n\n  CharacterSetECI(int value) {\n    this(new int[] {value});\n  }\n  \n  CharacterSetECI(int value, String... otherEncodingNames) {\n    this.values = new int[] {value};\n    this.otherEncodingNames = otherEncodingNames;\n  }\n\n  CharacterSetECI(int[] values, String... otherEncodingNames) {\n    this.values = values;\n    this.otherEncodingNames = otherEncodingNames;\n  }\n\n  public int getValue() {\n    return values[0];\n  }\n\n  /**\n   * @param value character set ECI value\n   * @return CharacterSetECI representing ECI of given value, or null if it is legal but\n   *   unsupported\n   * @throws IllegalArgumentException if ECI value is invalid\n   */\n  public static CharacterSetECI getCharacterSetECIByValue(int value) throws FormatException {\n    if (value < 0 || value >= 900) {\n      throw FormatException.getFormatInstance();\n    }\n    return VALUE_TO_ECI.get(value);\n  }\n\n  /**\n   * @param name character set ECI encoding name\n   * @return CharacterSetECI representing ECI for character encoding, or null if it is legal\n   *   but unsupported\n   */\n  public static CharacterSetECI getCharacterSetECIByName(String name) {\n    return NAME_TO_ECI.get(name);\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/common/DecoderResult.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.common;\n\nimport java.util.List;\n\n/**\n * <p>Encapsulates the result of decoding a matrix of bits. This typically\n * applies to 2D barcode formats. For now it contains the raw bytes obtained,\n * as well as a String interpretation of those bytes, if applicable.</p>\n *\n * @author Sean Owen\n */\npublic final class DecoderResult {\n\n  private final byte[] rawBytes;\n  private final String text;\n  private final List<byte[]> byteSegments;\n  private final String ecLevel;\n\n  public DecoderResult(byte[] rawBytes,\n                       String text,\n                       List<byte[]> byteSegments,\n                       String ecLevel) {\n    this.rawBytes = rawBytes;\n    this.text = text;\n    this.byteSegments = byteSegments;\n    this.ecLevel = ecLevel;\n  }\n\n  public byte[] getRawBytes() {\n    return rawBytes;\n  }\n\n  public String getText() {\n    return text;\n  }\n\n  public List<byte[]> getByteSegments() {\n    return byteSegments;\n  }\n\n  public String getECLevel() {\n    return ecLevel;\n  }\n\n}"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/common/DefaultGridSampler.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.common;\n\nimport com.google.zxing.NotFoundException;\n\n/**\n * @author Sean Owen\n */\npublic final class DefaultGridSampler extends GridSampler {\n\n  @Override\n  public BitMatrix sampleGrid(BitMatrix image,\n                              int dimensionX,\n                              int dimensionY,\n                              float p1ToX, float p1ToY,\n                              float p2ToX, float p2ToY,\n                              float p3ToX, float p3ToY,\n                              float p4ToX, float p4ToY,\n                              float p1FromX, float p1FromY,\n                              float p2FromX, float p2FromY,\n                              float p3FromX, float p3FromY,\n                              float p4FromX, float p4FromY) throws NotFoundException {\n\n    PerspectiveTransform transform = PerspectiveTransform.quadrilateralToQuadrilateral(\n        p1ToX, p1ToY, p2ToX, p2ToY, p3ToX, p3ToY, p4ToX, p4ToY,\n        p1FromX, p1FromY, p2FromX, p2FromY, p3FromX, p3FromY, p4FromX, p4FromY);\n\n    return sampleGrid(image, dimensionX, dimensionY, transform);\n  }\n\n  @Override\n  public BitMatrix sampleGrid(BitMatrix image,\n                              int dimensionX,\n                              int dimensionY,\n                              PerspectiveTransform transform) throws NotFoundException {\n    if (dimensionX <= 0 || dimensionY <= 0) {\n      throw NotFoundException.getNotFoundInstance();      \n    }\n    BitMatrix bits = new BitMatrix(dimensionX, dimensionY);\n    float[] points = new float[dimensionX << 1];\n    for (int y = 0; y < dimensionY; y++) {\n      int max = points.length;\n      float iValue = (float) y + 0.5f;\n      for (int x = 0; x < max; x += 2) {\n        points[x] = (float) (x >> 1) + 0.5f;\n        points[x + 1] = iValue;\n      }\n      transform.transformPoints(points);\n      // Quick check to see if points transformed to something inside the image;\n      // sufficient to check the endpoints\n      checkAndNudgePoints(image, points);\n      try {\n        for (int x = 0; x < max; x += 2) {\n          if (image.get((int) points[x], (int) points[x + 1])) {\n            // Black(-ish) pixel\n            bits.set(x >> 1, y);\n          }\n        }\n      } catch (ArrayIndexOutOfBoundsException aioobe) {\n        // This feels wrong, but, sometimes if the finder patterns are misidentified, the resulting\n        // transform gets \"twisted\" such that it maps a straight line of points to a set of points\n        // whose endpoints are in bounds, but others are not. There is probably some mathematical\n        // way to detect this about the transformation that I don't know yet.\n        // This results in an ugly runtime exception despite our clever checks above -- can't have\n        // that. We could check each point's coordinates but that feels duplicative. We settle for\n        // catching and wrapping ArrayIndexOutOfBoundsException.\n        throw NotFoundException.getNotFoundInstance();\n      }\n    }\n    return bits;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/common/DetectorResult.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.common;\n\nimport com.google.zxing.ResultPoint;\n\n/**\n * <p>Encapsulates the result of detecting a barcode in an image. This includes the raw\n * matrix of black/white pixels corresponding to the barcode, and possibly points of interest\n * in the image, like the location of finder patterns or corners of the barcode in the image.</p>\n *\n * @author Sean Owen\n */\npublic class DetectorResult {\n\n  private final BitMatrix bits;\n  private final ResultPoint[] points;\n\n  public DetectorResult(BitMatrix bits, ResultPoint[] points) {\n    this.bits = bits;\n    this.points = points;\n  }\n\n  public final BitMatrix getBits() {\n    return bits;\n  }\n\n  public final ResultPoint[] getPoints() {\n    return points;\n  }\n\n}"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/common/GlobalHistogramBinarizer.java",
    "content": "/*\n * Copyright 2009 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.common;\n\nimport com.google.zxing.Binarizer;\nimport com.google.zxing.LuminanceSource;\nimport com.google.zxing.NotFoundException;\n\n/**\n * This Binarizer implementation uses the old ZXing global histogram approach. It is suitable\n * for low-end mobile devices which don't have enough CPU or memory to use a local thresholding\n * algorithm. However, because it picks a global black point, it cannot handle difficult shadows\n * and gradients.\n *\n * Faster mobile devices and all desktop applications should probably use HybridBinarizer instead.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n * @author Sean Owen\n */\npublic class GlobalHistogramBinarizer extends Binarizer {\n\n  private static final int LUMINANCE_BITS = 5;\n  private static final int LUMINANCE_SHIFT = 8 - LUMINANCE_BITS;\n  private static final int LUMINANCE_BUCKETS = 1 << LUMINANCE_BITS;\n  private static final byte[] EMPTY = new byte[0];\n\n  private byte[] luminances;\n  private final int[] buckets;\n\n  public GlobalHistogramBinarizer(LuminanceSource source) {\n    super(source);\n    luminances = EMPTY;\n    buckets = new int[LUMINANCE_BUCKETS];\n  }\n\n  // Applies simple sharpening to the row data to improve performance of the 1D Readers.\n  @Override\n  public BitArray getBlackRow(int y, BitArray row) throws NotFoundException {\n    LuminanceSource source = getLuminanceSource();\n    int width = source.getWidth();\n    if (row == null || row.getSize() < width) {\n      row = new BitArray(width);\n    } else {\n      row.clear();\n    }\n\n    initArrays(width);\n    byte[] localLuminances = source.getRow(y, luminances);\n    int[] localBuckets = buckets;\n    for (int x = 0; x < width; x++) {\n      int pixel = localLuminances[x] & 0xff;\n      localBuckets[pixel >> LUMINANCE_SHIFT]++;\n    }\n    int blackPoint = estimateBlackPoint(localBuckets);\n\n    int left = localLuminances[0] & 0xff;\n    int center = localLuminances[1] & 0xff;\n    for (int x = 1; x < width - 1; x++) {\n      int right = localLuminances[x + 1] & 0xff;\n      // A simple -1 4 -1 box filter with a weight of 2.\n      int luminance = ((center << 2) - left - right) >> 1;\n      if (luminance < blackPoint) {\n        row.set(x);\n      }\n      left = center;\n      center = right;\n    }\n    return row;\n  }\n\n  // Does not sharpen the data, as this call is intended to only be used by 2D Readers.\n  @Override\n  public BitMatrix getBlackMatrix() throws NotFoundException {\n    LuminanceSource source = getLuminanceSource();\n    int width = source.getWidth();\n    int height = source.getHeight();\n    BitMatrix matrix = new BitMatrix(width, height);\n\n    // Quickly calculates the histogram by sampling four rows from the image. This proved to be\n    // more robust on the blackbox tests than sampling a diagonal as we used to do.\n    initArrays(width);\n    int[] localBuckets = buckets;\n    for (int y = 1; y < 5; y++) {\n      int row = height * y / 5;\n      byte[] localLuminances = source.getRow(row, luminances);\n      int right = (width << 2) / 5;\n      for (int x = width / 5; x < right; x++) {\n        int pixel = localLuminances[x] & 0xff;\n        localBuckets[pixel >> LUMINANCE_SHIFT]++;\n      }\n    }\n    int blackPoint = estimateBlackPoint(localBuckets);\n\n    // We delay reading the entire image luminance until the black point estimation succeeds.\n    // Although we end up reading four rows twice, it is consistent with our motto of\n    // \"fail quickly\" which is necessary for continuous scanning.\n    byte[] localLuminances = source.getMatrix();\n    for (int y = 0; y < height; y++) {\n      int offset = y * width;\n      for (int x = 0; x< width; x++) {\n        int pixel = localLuminances[offset + x] & 0xff;\n        if (pixel < blackPoint) {\n          matrix.set(x, y);\n        }\n      }\n    }\n\n    return matrix;\n  }\n\n  @Override\n  public Binarizer createBinarizer(LuminanceSource source) {\n    return new GlobalHistogramBinarizer(source);\n  }\n\n  private void initArrays(int luminanceSize) {\n    if (luminances.length < luminanceSize) {\n      luminances = new byte[luminanceSize];\n    }\n    for (int x = 0; x < LUMINANCE_BUCKETS; x++) {\n      buckets[x] = 0;\n    }\n  }\n\n  private static int estimateBlackPoint(int[] buckets) throws NotFoundException {\n    // Find the tallest peak in the histogram.\n    int numBuckets = buckets.length;\n    int maxBucketCount = 0;\n    int firstPeak = 0;\n    int firstPeakSize = 0;\n    for (int x = 0; x < numBuckets; x++) {\n      if (buckets[x] > firstPeakSize) {\n        firstPeak = x;\n        firstPeakSize = buckets[x];\n      }\n      if (buckets[x] > maxBucketCount) {\n        maxBucketCount = buckets[x];\n      }\n    }\n\n    // Find the second-tallest peak which is somewhat far from the tallest peak.\n    int secondPeak = 0;\n    int secondPeakScore = 0;\n    for (int x = 0; x < numBuckets; x++) {\n      int distanceToBiggest = x - firstPeak;\n      // Encourage more distant second peaks by multiplying by square of distance.\n      int score = buckets[x] * distanceToBiggest * distanceToBiggest;\n      if (score > secondPeakScore) {\n        secondPeak = x;\n        secondPeakScore = score;\n      }\n    }\n\n    // Make sure firstPeak corresponds to the black peak.\n    if (firstPeak > secondPeak) {\n      int temp = firstPeak;\n      firstPeak = secondPeak;\n      secondPeak = temp;\n    }\n\n    // If there is too little contrast in the image to pick a meaningful black point, throw rather\n    // than waste time trying to decode the image, and risk false positives.\n    if (secondPeak - firstPeak <= numBuckets >> 4) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n\n    // Find a valley between them that is low and closer to the white peak.\n    int bestValley = secondPeak - 1;\n    int bestValleyScore = -1;\n    for (int x = secondPeak - 1; x > firstPeak; x--) {\n      int fromFirst = x - firstPeak;\n      int score = fromFirst * fromFirst * (secondPeak - x) * (maxBucketCount - buckets[x]);\n      if (score > bestValleyScore) {\n        bestValley = x;\n        bestValleyScore = score;\n      }\n    }\n\n    return bestValley << LUMINANCE_SHIFT;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/common/GridSampler.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.common;\n\nimport com.google.zxing.NotFoundException;\n\n/**\n * Implementations of this class can, given locations of finder patterns for a QR code in an\n * image, sample the right points in the image to reconstruct the QR code, accounting for\n * perspective distortion. It is abstracted since it is relatively expensive and should be allowed\n * to take advantage of platform-specific optimized implementations, like Sun's Java Advanced\n * Imaging library, but which may not be available in other environments such as J2ME, and vice\n * versa.\n *\n * The implementation used can be controlled by calling {@link #setGridSampler(GridSampler)}\n * with an instance of a class which implements this interface.\n *\n * @author Sean Owen\n */\npublic abstract class GridSampler {\n\n  private static GridSampler gridSampler = new DefaultGridSampler();\n\n  /**\n   * Sets the implementation of GridSampler used by the library. One global\n   * instance is stored, which may sound problematic. But, the implementation provided\n   * ought to be appropriate for the entire platform, and all uses of this library\n   * in the whole lifetime of the JVM. For instance, an Android activity can swap in\n   * an implementation that takes advantage of native platform libraries.\n   * \n   * @param newGridSampler The platform-specific object to install.\n   */\n  public static void setGridSampler(GridSampler newGridSampler) {\n    gridSampler = newGridSampler;\n  }\n\n  /**\n   * @return the current implementation of GridSampler\n   */\n  public static GridSampler getInstance() {\n    return gridSampler;\n  }\n\n  /**\n   * Samples an image for a rectangular matrix of bits of the given dimension.\n   * @param image image to sample\n   * @param dimensionX width of {@link BitMatrix} to sample from image\n   * @param dimensionY height of {@link BitMatrix} to sample from image\n   * @return {@link BitMatrix} representing a grid of points sampled from the image within a region\n   *   defined by the \"from\" parameters\n   * @throws NotFoundException if image can't be sampled, for example, if the transformation defined\n   *   by the given points is invalid or results in sampling outside the image boundaries\n   */\n  public abstract BitMatrix sampleGrid(BitMatrix image,\n                                       int dimensionX,\n                                       int dimensionY,\n                                       float p1ToX, float p1ToY,\n                                       float p2ToX, float p2ToY,\n                                       float p3ToX, float p3ToY,\n                                       float p4ToX, float p4ToY,\n                                       float p1FromX, float p1FromY,\n                                       float p2FromX, float p2FromY,\n                                       float p3FromX, float p3FromY,\n                                       float p4FromX, float p4FromY) throws NotFoundException;\n  \n  public abstract BitMatrix sampleGrid(BitMatrix image,\n                                       int dimensionX,\n                                       int dimensionY,\n                                       PerspectiveTransform transform) throws NotFoundException;\n\n  /**\n   * <p>Checks a set of points that have been transformed to sample points on an image against\n   * the image's dimensions to see if the point are even within the image.</p>\n   *\n   * <p>This method will actually \"nudge\" the endpoints back onto the image if they are found to be\n   * barely (less than 1 pixel) off the image. This accounts for imperfect detection of finder\n   * patterns in an image where the QR Code runs all the way to the image border.</p>\n   *\n   * <p>For efficiency, the method will check points from either end of the line until one is found\n   * to be within the image. Because the set of points are assumed to be linear, this is valid.</p>\n   *\n   * @param image image into which the points should map\n   * @param points actual points in x1,y1,...,xn,yn form\n   * @throws NotFoundException if an endpoint is lies outside the image boundaries\n   */\n  protected static void checkAndNudgePoints(BitMatrix image,\n                                            float[] points) throws NotFoundException {\n    int width = image.getWidth();\n    int height = image.getHeight();\n    // Check and nudge points from start until we see some that are OK:\n    boolean nudged = true;\n    for (int offset = 0; offset < points.length && nudged; offset += 2) {\n      int x = (int) points[offset];\n      int y = (int) points[offset + 1];\n      if (x < -1 || x > width || y < -1 || y > height) {\n        throw NotFoundException.getNotFoundInstance();\n      }\n      nudged = false;\n      if (x == -1) {\n        points[offset] = 0.0f;\n        nudged = true;\n      } else if (x == width) {\n        points[offset] = width - 1;\n        nudged = true;\n      }\n      if (y == -1) {\n        points[offset + 1] = 0.0f;\n        nudged = true;\n      } else if (y == height) {\n        points[offset + 1] = height - 1;\n        nudged = true;\n      }\n    }\n    // Check and nudge points from end:\n    nudged = true;\n    for (int offset = points.length - 2; offset >= 0 && nudged; offset -= 2) {\n      int x = (int) points[offset];\n      int y = (int) points[offset + 1];\n      if (x < -1 || x > width || y < -1 || y > height) {\n        throw NotFoundException.getNotFoundInstance();\n      }\n      nudged = false;\n      if (x == -1) {\n        points[offset] = 0.0f;\n        nudged = true;\n      } else if (x == width) {\n        points[offset] = width - 1;\n        nudged = true;\n      }\n      if (y == -1) {\n        points[offset + 1] = 0.0f;\n        nudged = true;\n      } else if (y == height) {\n        points[offset + 1] = height - 1;\n        nudged = true;\n      }\n    }\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/common/HybridBinarizer.java",
    "content": "/*\n * Copyright 2009 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.common;\n\nimport com.google.zxing.Binarizer;\nimport com.google.zxing.LuminanceSource;\nimport com.google.zxing.NotFoundException;\n\n/**\n * This class implements a local thresholding algorithm, which while slower than the\n * GlobalHistogramBinarizer, is fairly efficient for what it does. It is designed for\n * high frequency images of barcodes with black data on white backgrounds. For this application,\n * it does a much better job than a global blackpoint with severe shadows and gradients.\n * However it tends to produce artifacts on lower frequency images and is therefore not\n * a good general purpose binarizer for uses outside ZXing.\n *\n * This class extends GlobalHistogramBinarizer, using the older histogram approach for 1D readers,\n * and the newer local approach for 2D readers. 1D decoding using a per-row histogram is already\n * inherently local, and only fails for horizontal gradients. We can revisit that problem later,\n * but for now it was not a win to use local blocks for 1D.\n *\n * This Binarizer is the default for the unit tests and the recommended class for library users.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n */\npublic final class HybridBinarizer extends GlobalHistogramBinarizer {\n\n  // This class uses 5x5 blocks to compute local luminance, where each block is 8x8 pixels.\n  // So this is the smallest dimension in each axis we can accept.\n  private static final int BLOCK_SIZE_POWER = 3;\n  private static final int BLOCK_SIZE = 1 << BLOCK_SIZE_POWER; // ...0100...00\n  private static final int BLOCK_SIZE_MASK = BLOCK_SIZE - 1;   // ...0011...11\n  private static final int MINIMUM_DIMENSION = BLOCK_SIZE * 5;\n  private static final int MIN_DYNAMIC_RANGE = 24;\n\n  private BitMatrix matrix;\n\n  public HybridBinarizer(LuminanceSource source) {\n    super(source);\n  }\n\n  /**\n   * Calculates the final BitMatrix once for all requests. This could be called once from the\n   * constructor instead, but there are some advantages to doing it lazily, such as making\n   * profiling easier, and not doing heavy lifting when callers don't expect it.\n   */\n  @Override\n  public BitMatrix getBlackMatrix() throws NotFoundException {\n    if (matrix != null) {\n      return matrix;\n    }\n    LuminanceSource source = getLuminanceSource();\n    int width = source.getWidth();\n    int height = source.getHeight();\n    if (width >= MINIMUM_DIMENSION && height >= MINIMUM_DIMENSION) {\n      byte[] luminances = source.getMatrix();\n      int subWidth = width >> BLOCK_SIZE_POWER;\n      if ((width & BLOCK_SIZE_MASK) != 0) {\n        subWidth++;\n      }\n      int subHeight = height >> BLOCK_SIZE_POWER;\n      if ((height & BLOCK_SIZE_MASK) != 0) {\n        subHeight++;\n      }\n      int[][] blackPoints = calculateBlackPoints(luminances, subWidth, subHeight, width, height);\n\n      BitMatrix newMatrix = new BitMatrix(width, height);\n      calculateThresholdForBlock(luminances, subWidth, subHeight, width, height, blackPoints, newMatrix);\n      matrix = newMatrix;\n    } else {\n      // If the image is too small, fall back to the global histogram approach.\n      matrix = super.getBlackMatrix();\n    }\n    return matrix;\n  }\n\n  @Override\n  public Binarizer createBinarizer(LuminanceSource source) {\n    return new HybridBinarizer(source);\n  }\n\n  /**\n   * For each block in the image, calculate the average black point using a 5x5 grid\n   * of the blocks around it. Also handles the corner cases (fractional blocks are computed based\n   * on the last pixels in the row/column which are also used in the previous block).\n   */\n  private static void calculateThresholdForBlock(byte[] luminances,\n                                                 int subWidth,\n                                                 int subHeight,\n                                                 int width,\n                                                 int height,\n                                                 int[][] blackPoints,\n                                                 BitMatrix matrix) {\n    for (int y = 0; y < subHeight; y++) {\n      int yoffset = y << BLOCK_SIZE_POWER;\n      int maxYOffset = height - BLOCK_SIZE;\n      if (yoffset > maxYOffset) {\n        yoffset = maxYOffset;\n      }\n      for (int x = 0; x < subWidth; x++) {\n        int xoffset = x << BLOCK_SIZE_POWER;\n        int maxXOffset = width - BLOCK_SIZE;\n        if (xoffset > maxXOffset) {\n          xoffset = maxXOffset;\n        }\n        int left = cap(x, 2, subWidth - 3);\n        int top = cap(y, 2, subHeight - 3);\n        int sum = 0;\n        for (int z = -2; z <= 2; z++) {\n          int[] blackRow = blackPoints[top + z];\n          sum += blackRow[left - 2] + blackRow[left - 1] + blackRow[left] + blackRow[left + 1] + blackRow[left + 2];\n        }\n        int average = sum / 25;\n        thresholdBlock(luminances, xoffset, yoffset, average, width, matrix);\n      }\n    }\n  }\n\n  private static int cap(int value, int min, int max) {\n    return value < min ? min : value > max ? max : value;\n  }\n\n  /**\n   * Applies a single threshold to a block of pixels.\n   */\n  private static void thresholdBlock(byte[] luminances,\n                                     int xoffset,\n                                     int yoffset,\n                                     int threshold,\n                                     int stride,\n                                     BitMatrix matrix) {\n    for (int y = 0, offset = yoffset * stride + xoffset; y < BLOCK_SIZE; y++, offset += stride) {\n      for (int x = 0; x < BLOCK_SIZE; x++) {\n        // Comparison needs to be <= so that black == 0 pixels are black even if the threshold is 0.\n        if ((luminances[offset + x] & 0xFF) <= threshold) {\n          matrix.set(xoffset + x, yoffset + y);\n        }\n      }\n    }\n  }\n\n  /**\n   * Calculates a single black point for each block of pixels and saves it away.\n   * See the following thread for a discussion of this algorithm:\n   *  http://groups.google.com/group/zxing/browse_thread/thread/d06efa2c35a7ddc0\n   */\n  private static int[][] calculateBlackPoints(byte[] luminances,\n                                              int subWidth,\n                                              int subHeight,\n                                              int width,\n                                              int height) {\n    int[][] blackPoints = new int[subHeight][subWidth];\n    for (int y = 0; y < subHeight; y++) {\n      int yoffset = y << BLOCK_SIZE_POWER;\n      int maxYOffset = height - BLOCK_SIZE;\n      if (yoffset > maxYOffset) {\n        yoffset = maxYOffset;\n      }\n      for (int x = 0; x < subWidth; x++) {\n        int xoffset = x << BLOCK_SIZE_POWER;\n        int maxXOffset = width - BLOCK_SIZE;\n        if (xoffset > maxXOffset) {\n          xoffset = maxXOffset;\n        }\n        int sum = 0;\n        int min = 0xFF;\n        int max = 0;\n        for (int yy = 0, offset = yoffset * width + xoffset; yy < BLOCK_SIZE; yy++, offset += width) {\n          for (int xx = 0; xx < BLOCK_SIZE; xx++) {\n            int pixel = luminances[offset + xx] & 0xFF;\n            sum += pixel;\n            // still looking for good contrast\n            if (pixel < min) {\n              min = pixel;\n            }\n            if (pixel > max) {\n              max = pixel;\n            }\n          }\n          // short-circuit min/max tests once dynamic range is met\n          if (max - min > MIN_DYNAMIC_RANGE) {\n            // finish the rest of the rows quickly\n            for (yy++, offset += width; yy < BLOCK_SIZE; yy++, offset += width) {\n              for (int xx = 0; xx < BLOCK_SIZE; xx++) {\n                sum += luminances[offset + xx] & 0xFF;\n              }\n            }\n          }\n        }\n\n        // The default estimate is the average of the values in the block.\n        int average = sum >> (BLOCK_SIZE_POWER * 2);\n        if (max - min <= MIN_DYNAMIC_RANGE) {\n          // If variation within the block is low, assume this is a block with only light or only\n          // dark pixels. In that case we do not want to use the average, as it would divide this\n          // low contrast area into black and white pixels, essentially creating data out of noise.\n          //\n          // The default assumption is that the block is light/background. Since no estimate for\n          // the level of dark pixels exists locally, use half the min for the block.\n          average = min >> 1;\n\n          if (y > 0 && x > 0) {\n            // Correct the \"white background\" assumption for blocks that have neighbors by comparing\n            // the pixels in this block to the previously calculated black points. This is based on\n            // the fact that dark barcode symbology is always surrounded by some amount of light\n            // background for which reasonable black point estimates were made. The bp estimated at\n            // the boundaries is used for the interior.\n\n            // The (min < bp) is arbitrary but works better than other heuristics that were tried.\n            int averageNeighborBlackPoint = (blackPoints[y - 1][x] + (2 * blackPoints[y][x - 1]) +\n                blackPoints[y - 1][x - 1]) >> 2;\n            if (min < averageNeighborBlackPoint) {\n              average = averageNeighborBlackPoint;\n            }\n          }\n        }\n        blackPoints[y][x] = average;\n      }\n    }\n    return blackPoints;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/common/PerspectiveTransform.java",
    "content": "/*\r\n * Copyright 2007 ZXing authors\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage com.google.zxing.common;\r\n\r\n/**\r\n * <p>This class implements a perspective transform in two dimensions. Given four source and four\r\n * destination points, it will compute the transformation implied between them. The code is based\r\n * directly upon section 3.4.2 of George Wolberg's \"Digital Image Warping\"; see pages 54-56.</p>\r\n *\r\n * @author Sean Owen\r\n */\r\npublic final class PerspectiveTransform {\r\n\r\n  private final float a11;\r\n  private final float a12;\r\n  private final float a13;\r\n  private final float a21;\r\n  private final float a22;\r\n  private final float a23;\r\n  private final float a31;\r\n  private final float a32;\r\n  private final float a33;\r\n\r\n  private PerspectiveTransform(float a11, float a21, float a31,\r\n                               float a12, float a22, float a32,\r\n                               float a13, float a23, float a33) {\r\n    this.a11 = a11;\r\n    this.a12 = a12;\r\n    this.a13 = a13;\r\n    this.a21 = a21;\r\n    this.a22 = a22;\r\n    this.a23 = a23;\r\n    this.a31 = a31;\r\n    this.a32 = a32;\r\n    this.a33 = a33;\r\n  }\r\n\r\n  public static PerspectiveTransform quadrilateralToQuadrilateral(float x0, float y0,\r\n                                                                  float x1, float y1,\r\n                                                                  float x2, float y2,\r\n                                                                  float x3, float y3,\r\n                                                                  float x0p, float y0p,\r\n                                                                  float x1p, float y1p,\r\n                                                                  float x2p, float y2p,\r\n                                                                  float x3p, float y3p) {\r\n\r\n    PerspectiveTransform qToS = quadrilateralToSquare(x0, y0, x1, y1, x2, y2, x3, y3);\r\n    PerspectiveTransform sToQ = squareToQuadrilateral(x0p, y0p, x1p, y1p, x2p, y2p, x3p, y3p);\r\n    return sToQ.times(qToS);\r\n  }\r\n\r\n  public void transformPoints(float[] points) {\r\n    int max = points.length;\r\n    float a11 = this.a11;\r\n    float a12 = this.a12;\r\n    float a13 = this.a13;\r\n    float a21 = this.a21;\r\n    float a22 = this.a22;\r\n    float a23 = this.a23;\r\n    float a31 = this.a31;\r\n    float a32 = this.a32;\r\n    float a33 = this.a33;\r\n    for (int i = 0; i < max; i += 2) {\r\n      float x = points[i];\r\n      float y = points[i + 1];\r\n      float denominator = a13 * x + a23 * y + a33;\r\n      points[i] = (a11 * x + a21 * y + a31) / denominator;\r\n      points[i + 1] = (a12 * x + a22 * y + a32) / denominator;\r\n    }\r\n  }\r\n\r\n  /** Convenience method, not optimized for performance. */\r\n  public void transformPoints(float[] xValues, float[] yValues) {\r\n    int n = xValues.length;\r\n    for (int i = 0; i < n; i ++) {\r\n      float x = xValues[i];\r\n      float y = yValues[i];\r\n      float denominator = a13 * x + a23 * y + a33;\r\n      xValues[i] = (a11 * x + a21 * y + a31) / denominator;\r\n      yValues[i] = (a12 * x + a22 * y + a32) / denominator;\r\n    }\r\n  }\r\n\r\n  public static PerspectiveTransform squareToQuadrilateral(float x0, float y0,\r\n                                                           float x1, float y1,\r\n                                                           float x2, float y2,\r\n                                                           float x3, float y3) {\r\n    float dx3 = x0 - x1 + x2 - x3;\r\n    float dy3 = y0 - y1 + y2 - y3;\r\n    if (dx3 == 0.0f && dy3 == 0.0f) {\r\n      // Affine\r\n      return new PerspectiveTransform(x1 - x0, x2 - x1, x0,\r\n                                      y1 - y0, y2 - y1, y0,\r\n                                      0.0f,    0.0f,    1.0f);\r\n    } else {\r\n      float dx1 = x1 - x2;\r\n      float dx2 = x3 - x2;\r\n      float dy1 = y1 - y2;\r\n      float dy2 = y3 - y2;\r\n      float denominator = dx1 * dy2 - dx2 * dy1;\r\n      float a13 = (dx3 * dy2 - dx2 * dy3) / denominator;\r\n      float a23 = (dx1 * dy3 - dx3 * dy1) / denominator;\r\n      return new PerspectiveTransform(x1 - x0 + a13 * x1, x3 - x0 + a23 * x3, x0,\r\n                                      y1 - y0 + a13 * y1, y3 - y0 + a23 * y3, y0,\r\n                                      a13,                a23,                1.0f);\r\n    }\r\n  }\r\n\r\n  public static PerspectiveTransform quadrilateralToSquare(float x0, float y0,\r\n                                                           float x1, float y1,\r\n                                                           float x2, float y2,\r\n                                                           float x3, float y3) {\r\n    // Here, the adjoint serves as the inverse:\r\n    return squareToQuadrilateral(x0, y0, x1, y1, x2, y2, x3, y3).buildAdjoint();\r\n  }\r\n\r\n  PerspectiveTransform buildAdjoint() {\r\n    // Adjoint is the transpose of the cofactor matrix:\r\n    return new PerspectiveTransform(a22 * a33 - a23 * a32,\r\n        a23 * a31 - a21 * a33,\r\n        a21 * a32 - a22 * a31,\r\n        a13 * a32 - a12 * a33,\r\n        a11 * a33 - a13 * a31,\r\n        a12 * a31 - a11 * a32,\r\n        a12 * a23 - a13 * a22,\r\n        a13 * a21 - a11 * a23,\r\n        a11 * a22 - a12 * a21);\r\n  }\r\n\r\n  PerspectiveTransform times(PerspectiveTransform other) {\r\n    return new PerspectiveTransform(a11 * other.a11 + a21 * other.a12 + a31 * other.a13,\r\n        a11 * other.a21 + a21 * other.a22 + a31 * other.a23,\r\n        a11 * other.a31 + a21 * other.a32 + a31 * other.a33,\r\n        a12 * other.a11 + a22 * other.a12 + a32 * other.a13,\r\n        a12 * other.a21 + a22 * other.a22 + a32 * other.a23,\r\n        a12 * other.a31 + a22 * other.a32 + a32 * other.a33,\r\n        a13 * other.a11 + a23 * other.a12 + a33 * other.a13,\r\n        a13 * other.a21 + a23 * other.a22 + a33 * other.a23,\r\n        a13 * other.a31 + a23 * other.a32 + a33 * other.a33);\r\n\r\n  }\r\n\r\n}\r\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/common/StringUtils.java",
    "content": "/*\n * Copyright (C) 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.common;\n\nimport java.util.Map;\n\nimport com.google.zxing.DecodeHintType;\n\n/**\n * Common string-related functions.\n *\n * @author Sean Owen\n * @author Alex Dupre\n */\npublic final class StringUtils {\n\n  private static final String PLATFORM_DEFAULT_ENCODING =\n      System.getProperty(\"file.encoding\");\n  public static final String SHIFT_JIS = \"SJIS\";\n  public static final String GB2312 = \"GB2312\";\n  private static final String EUC_JP = \"EUC_JP\";\n  private static final String UTF8 = \"UTF8\";\n  private static final String ISO88591 = \"ISO8859_1\";\n  private static final boolean ASSUME_SHIFT_JIS =\n      SHIFT_JIS.equalsIgnoreCase(PLATFORM_DEFAULT_ENCODING) ||\n      EUC_JP.equalsIgnoreCase(PLATFORM_DEFAULT_ENCODING);\n\n  private StringUtils() {}\n\n  /**\n   * @param bytes bytes encoding a string, whose encoding should be guessed\n   * @param hints decode hints if applicable\n   * @return name of guessed encoding; at the moment will only guess one of:\n   *  {@link #SHIFT_JIS}, {@link #UTF8}, {@link #ISO88591}, or the platform\n   *  default encoding if none of these can possibly be correct\n   */\n  public static String guessEncoding(byte[] bytes, Map<DecodeHintType,?> hints) {\n    if (hints != null) {\n      String characterSet = (String) hints.get(DecodeHintType.CHARACTER_SET);\n      if (characterSet != null) {\n        return characterSet;\n      }\n    }\n    // For now, merely tries to distinguish ISO-8859-1, UTF-8 and Shift_JIS,\n    // which should be by far the most common encodings.\n    int length = bytes.length;\n    boolean canBeISO88591 = true;\n    boolean canBeShiftJIS = true;\n    boolean canBeUTF8 = true;\n    int utf8BytesLeft = 0;\n    //int utf8LowChars = 0;\n    int utf2BytesChars = 0;\n    int utf3BytesChars = 0;\n    int utf4BytesChars = 0;\n    int sjisBytesLeft = 0;\n    //int sjisLowChars = 0;\n    int sjisKatakanaChars = 0;\n    //int sjisDoubleBytesChars = 0;\n    int sjisCurKatakanaWordLength = 0;\n    int sjisCurDoubleBytesWordLength = 0;\n    int sjisMaxKatakanaWordLength = 0;\n    int sjisMaxDoubleBytesWordLength = 0;\n    //int isoLowChars = 0;\n    //int isoHighChars = 0;\n    int isoHighOther = 0;\n\n    boolean utf8bom = bytes.length > 3 &&\n        bytes[0] == (byte) 0xEF &&\n        bytes[1] == (byte) 0xBB &&\n        bytes[2] == (byte) 0xBF;\n\n    for (int i = 0;\n         i < length && (canBeISO88591 || canBeShiftJIS || canBeUTF8);\n         i++) {\n\n      int value = bytes[i] & 0xFF;\n\n      // UTF-8 stuff\n      if (canBeUTF8) {\n        if (utf8BytesLeft > 0) {\n          if ((value & 0x80) == 0) {\n            canBeUTF8 = false;\n          } else {\n            utf8BytesLeft--;\n          }\n        } else if ((value & 0x80) != 0) {\n          if ((value & 0x40) == 0) {\n            canBeUTF8 = false;\n          } else {\n            utf8BytesLeft++;\n            if ((value & 0x20) == 0) {\n              utf2BytesChars++;\n            } else {\n              utf8BytesLeft++;\n              if ((value & 0x10) == 0) {\n                utf3BytesChars++;\n              } else {\n                utf8BytesLeft++;\n                if ((value & 0x08) == 0) {\n                  utf4BytesChars++;\n                } else {\n                  canBeUTF8 = false;\n                }\n              }\n            }\n          }\n        } //else {\n          //utf8LowChars++;\n        //}\n      }\n\n      // ISO-8859-1 stuff\n      if (canBeISO88591) {\n        if (value > 0x7F && value < 0xA0) {\n          canBeISO88591 = false;\n        } else if (value > 0x9F) {\n          if (value < 0xC0 || value == 0xD7 || value == 0xF7) {\n            isoHighOther++;\n          } //else {\n            //isoHighChars++;\n          //}\n        } //else {\n          //isoLowChars++;\n        //}\n      }\n\n      // Shift_JIS stuff\n      if (canBeShiftJIS) {\n        if (sjisBytesLeft > 0) {\n          if (value < 0x40 || value == 0x7F || value > 0xFC) {\n            canBeShiftJIS = false;\n          } else {\n            sjisBytesLeft--;\n          }\n        } else if (value == 0x80 || value == 0xA0 || value > 0xEF) {\n          canBeShiftJIS = false;\n        } else if (value > 0xA0 && value < 0xE0) {\n          sjisKatakanaChars++;\n          sjisCurDoubleBytesWordLength = 0;\n          sjisCurKatakanaWordLength++;\n          if (sjisCurKatakanaWordLength > sjisMaxKatakanaWordLength) {\n            sjisMaxKatakanaWordLength = sjisCurKatakanaWordLength;\n          }\n        } else if (value > 0x7F) {\n          sjisBytesLeft++;\n          //sjisDoubleBytesChars++;\n          sjisCurKatakanaWordLength = 0;\n          sjisCurDoubleBytesWordLength++;\n          if (sjisCurDoubleBytesWordLength > sjisMaxDoubleBytesWordLength) {\n            sjisMaxDoubleBytesWordLength = sjisCurDoubleBytesWordLength;\n          }\n        } else {\n          //sjisLowChars++;\n          sjisCurKatakanaWordLength = 0;\n          sjisCurDoubleBytesWordLength = 0;\n        }\n      }\n    }\n\n    if (canBeUTF8 && utf8BytesLeft > 0) {\n      canBeUTF8 = false;\n    }\n    if (canBeShiftJIS && sjisBytesLeft > 0) {\n      canBeShiftJIS = false;\n    }\n\n    // Easy -- if there is BOM or at least 1 valid not-single byte character (and no evidence it can't be UTF-8), done\n    if (canBeUTF8 && (utf8bom || utf2BytesChars + utf3BytesChars + utf4BytesChars > 0)) {\n      return UTF8;\n    }\n    // Easy -- if assuming Shift_JIS or at least 3 valid consecutive not-ascii characters (and no evidence it can't be), done\n    if (canBeShiftJIS && (ASSUME_SHIFT_JIS || sjisMaxKatakanaWordLength >= 3 || sjisMaxDoubleBytesWordLength >= 3)) {\n      return SHIFT_JIS;\n    }\n    // Distinguishing Shift_JIS and ISO-8859-1 can be a little tough for short words. The crude heuristic is:\n    // - If we saw\n    //   - only two consecutive katakana chars in the whole text, or\n    //   - at least 10% of bytes that could be \"upper\" not-alphanumeric Latin1,\n    // - then we conclude Shift_JIS, else ISO-8859-1\n    if (canBeISO88591 && canBeShiftJIS) {\n      return (sjisMaxKatakanaWordLength == 2 && sjisKatakanaChars == 2) || isoHighOther * 10 >= length\n          ? SHIFT_JIS : ISO88591;\n    }\n\n    // Otherwise, try in order ISO-8859-1, Shift JIS, UTF-8 and fall back to default platform encoding\n    if (canBeISO88591) {\n      return ISO88591;\n    }\n    if (canBeShiftJIS) {\n      return SHIFT_JIS;\n    }\n    if (canBeUTF8) {\n      return UTF8;\n    }\n    // Otherwise, we take a wild guess with platform encoding\n    return PLATFORM_DEFAULT_ENCODING;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/common/detector/MathUtils.java",
    "content": "/*\n * Copyright 2012 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.common.detector;\n\npublic final class MathUtils {\n\n  private MathUtils() {\n  }\n\n  /**\n   * Ends up being a bit faster than {@link Math#round(float)}. This merely rounds its\n   * argument to the nearest int, where x.5 rounds up to x+1.\n   */\n  public static int round(float d) {\n    return (int) (d + 0.5f);\n  }\n\n  public static float distance(float aX, float aY, float bX, float bY) {\n    float xDiff = aX - bX;\n    float yDiff = aY - bY;\n    return (float) Math.sqrt(xDiff * xDiff + yDiff * yDiff);\n  }\n\n  public static float distance(int aX, int aY, int bX, int bY) {\n    int xDiff = aX - bX;\n    int yDiff = aY - bY;\n    return (float) Math.sqrt(xDiff * xDiff + yDiff * yDiff);\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/common/detector/MonochromeRectangleDetector.java",
    "content": "/*\n * Copyright 2009 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.common.detector;\n\nimport com.google.zxing.NotFoundException;\nimport com.google.zxing.ResultPoint;\nimport com.google.zxing.common.BitMatrix;\n\n/**\n * <p>A somewhat generic detector that looks for a barcode-like rectangular region within an image.\n * It looks within a mostly white region of an image for a region of black and white, but mostly\n * black. It returns the four corners of the region, as best it can determine.</p>\n *\n * @author Sean Owen\n */\npublic final class MonochromeRectangleDetector {\n\n  private static final int MAX_MODULES = 32;\n\n  private final BitMatrix image;\n\n  public MonochromeRectangleDetector(BitMatrix image) {\n    this.image = image;\n  }\n\n  /**\n   * <p>Detects a rectangular region of black and white -- mostly black -- with a region of mostly\n   * white, in an image.</p>\n   *\n   * @return {@link ResultPoint}[] describing the corners of the rectangular region. The first and\n   *  last points are opposed on the diagonal, as are the second and third. The first point will be\n   *  the topmost point and the last, the bottommost. The second point will be leftmost and the\n   *  third, the rightmost\n   * @throws NotFoundException if no Data Matrix Code can be found\n   */\n  public ResultPoint[] detect() throws NotFoundException {\n    int height = image.getHeight();\n    int width = image.getWidth();\n    int halfHeight = height >> 1;\n    int halfWidth = width >> 1;\n    int deltaY = Math.max(1, height / (MAX_MODULES << 3));\n    int deltaX = Math.max(1, width / (MAX_MODULES << 3));\n\n    int top = 0;\n    int bottom = height;\n    int left = 0;\n    int right = width;\n    ResultPoint pointA = findCornerFromCenter(halfWidth, 0, left, right,\n        halfHeight, -deltaY, top, bottom, halfWidth >> 1);\n    top = (int) pointA.getY() - 1;\n    ResultPoint pointB = findCornerFromCenter(halfWidth, -deltaX, left, right,\n        halfHeight, 0, top, bottom, halfHeight >> 1);\n    left = (int) pointB.getX() - 1;\n    ResultPoint pointC = findCornerFromCenter(halfWidth, deltaX, left, right,\n        halfHeight, 0, top, bottom, halfHeight >> 1);\n    right = (int) pointC.getX() + 1;\n    ResultPoint pointD = findCornerFromCenter(halfWidth, 0, left, right,\n        halfHeight, deltaY, top, bottom, halfWidth >> 1);\n    bottom = (int) pointD.getY() + 1;\n\n    // Go try to find point A again with better information -- might have been off at first.\n    pointA = findCornerFromCenter(halfWidth, 0, left, right,\n        halfHeight, -deltaY, top, bottom, halfWidth >> 2);\n\n    return new ResultPoint[] { pointA, pointB, pointC, pointD };\n  }\n\n  /**\n   * Attempts to locate a corner of the barcode by scanning up, down, left or right from a center\n   * point which should be within the barcode.\n   *\n   * @param centerX center's x component (horizontal)\n   * @param deltaX same as deltaY but change in x per step instead\n   * @param left minimum value of x\n   * @param right maximum value of x\n   * @param centerY center's y component (vertical)\n   * @param deltaY change in y per step. If scanning up this is negative; down, positive;\n   *  left or right, 0\n   * @param top minimum value of y to search through (meaningless when di == 0)\n   * @param bottom maximum value of y\n   * @param maxWhiteRun maximum run of white pixels that can still be considered to be within\n   *  the barcode\n   * @return a {@link com.google.zxing.ResultPoint} encapsulating the corner that was found\n   * @throws NotFoundException if such a point cannot be found\n   */\n  private ResultPoint findCornerFromCenter(int centerX,\n                                           int deltaX,\n                                           int left,\n                                           int right,\n                                           int centerY,\n                                           int deltaY,\n                                           int top,\n                                           int bottom,\n                                           int maxWhiteRun) throws NotFoundException {\n    int[] lastRange = null;\n    for (int y = centerY, x = centerX;\n         y < bottom && y >= top && x < right && x >= left;\n         y += deltaY, x += deltaX) {\n      int[] range;\n      if (deltaX == 0) {\n        // horizontal slices, up and down\n        range = blackWhiteRange(y, maxWhiteRun, left, right, true);\n      } else {\n        // vertical slices, left and right\n        range = blackWhiteRange(x, maxWhiteRun, top, bottom, false);\n      }\n      if (range == null) {\n        if (lastRange == null) {\n          throw NotFoundException.getNotFoundInstance();\n        }\n        // lastRange was found\n        if (deltaX == 0) {\n          int lastY = y - deltaY;\n          if (lastRange[0] < centerX) {\n            if (lastRange[1] > centerX) {\n              // straddle, choose one or the other based on direction\n              return new ResultPoint(deltaY > 0 ? lastRange[0] : lastRange[1], lastY);\n            }\n            return new ResultPoint(lastRange[0], lastY);\n          } else {\n            return new ResultPoint(lastRange[1], lastY);\n          }\n        } else {\n          int lastX = x - deltaX;\n          if (lastRange[0] < centerY) {\n            if (lastRange[1] > centerY) {\n              return new ResultPoint(lastX, deltaX < 0 ? lastRange[0] : lastRange[1]);\n            }\n            return new ResultPoint(lastX, lastRange[0]);\n          } else {\n            return new ResultPoint(lastX, lastRange[1]);\n          }\n        }\n      }\n      lastRange = range;\n    }\n    throw NotFoundException.getNotFoundInstance();\n  }\n\n  /**\n   * Computes the start and end of a region of pixels, either horizontally or vertically, that could\n   * be part of a Data Matrix barcode.\n   *\n   * @param fixedDimension if scanning horizontally, this is the row (the fixed vertical location)\n   *  where we are scanning. If scanning vertically it's the column, the fixed horizontal location\n   * @param maxWhiteRun largest run of white pixels that can still be considered part of the\n   *  barcode region\n   * @param minDim minimum pixel location, horizontally or vertically, to consider\n   * @param maxDim maximum pixel location, horizontally or vertically, to consider\n   * @param horizontal if true, we're scanning left-right, instead of up-down\n   * @return int[] with start and end of found range, or null if no such range is found\n   *  (e.g. only white was found)\n   */\n  private int[] blackWhiteRange(int fixedDimension, int maxWhiteRun, int minDim, int maxDim, boolean horizontal) {\n\n    int center = (minDim + maxDim) >> 1;\n\n    // Scan left/up first\n    int start = center;\n    while (start >= minDim) {\n      if (horizontal ? image.get(start, fixedDimension) : image.get(fixedDimension, start)) {\n        start--;\n      } else {\n        int whiteRunStart = start;\n        do {\n          start--;\n        } while (start >= minDim && !(horizontal ? image.get(start, fixedDimension) :\n            image.get(fixedDimension, start)));\n        int whiteRunSize = whiteRunStart - start;\n        if (start < minDim || whiteRunSize > maxWhiteRun) {\n          start = whiteRunStart;\n          break;\n        }\n      }\n    }\n    start++;\n\n    // Then try right/down\n    int end = center;\n    while (end < maxDim) {\n      if (horizontal ? image.get(end, fixedDimension) : image.get(fixedDimension, end)) {\n        end++;\n      } else {\n        int whiteRunStart = end;\n        do {\n          end++;\n        } while (end < maxDim && !(horizontal ? image.get(end, fixedDimension) :\n            image.get(fixedDimension, end)));\n        int whiteRunSize = end - whiteRunStart;\n        if (end >= maxDim || whiteRunSize > maxWhiteRun) {\n          end = whiteRunStart;\n          break;\n        }\n      }\n    }\n    end--;\n\n    return end > start ? new int[]{start, end} : null;\n  }\n\n}"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/common/detector/WhiteRectangleDetector.java",
    "content": "/*\n * Copyright 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.common.detector;\n\nimport com.google.zxing.NotFoundException;\nimport com.google.zxing.ResultPoint;\nimport com.google.zxing.common.BitMatrix;\n\n/**\n * <p>\n * Detects a candidate barcode-like rectangular region within an image. It\n * starts around the center of the image, increases the size of the candidate\n * region until it finds a white rectangular region. By keeping track of the\n * last black points it encountered, it determines the corners of the barcode.\n * </p>\n *\n * @author David Olivier\n */\npublic final class WhiteRectangleDetector {\n\n  private static final int INIT_SIZE = 30;\n  private static final int CORR = 1;\n\n  private final BitMatrix image;\n  private final int height;\n  private final int width;\n  private final int leftInit;\n  private final int rightInit;\n  private final int downInit;\n  private final int upInit;\n\n  /**\n   * @throws NotFoundException if image is too small\n   */\n  public WhiteRectangleDetector(BitMatrix image) throws NotFoundException {\n    this.image = image;\n    height = image.getHeight();\n    width = image.getWidth();\n    leftInit = (width - INIT_SIZE) >> 1;\n    rightInit = (width + INIT_SIZE) >> 1;\n    upInit = (height - INIT_SIZE) >> 1;\n    downInit = (height + INIT_SIZE) >> 1;\n    if (upInit < 0 || leftInit < 0 || downInit >= height || rightInit >= width) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n  }\n\n  /**\n   * @throws NotFoundException if image is too small\n   */\n  public WhiteRectangleDetector(BitMatrix image, int initSize, int x, int y) throws NotFoundException {\n    this.image = image;\n    height = image.getHeight();\n    width = image.getWidth();\n    int halfsize = initSize >> 1;\n    leftInit = x - halfsize;\n    rightInit = x + halfsize;\n    upInit = y - halfsize;\n    downInit = y + halfsize;\n    if (upInit < 0 || leftInit < 0 || downInit >= height || rightInit >= width) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n  }\n\n  /**\n   * <p>\n   * Detects a candidate barcode-like rectangular region within an image. It\n   * starts around the center of the image, increases the size of the candidate\n   * region until it finds a white rectangular region.\n   * </p>\n   *\n   * @return {@link ResultPoint}[] describing the corners of the rectangular\n   *         region. The first and last points are opposed on the diagonal, as\n   *         are the second and third. The first point will be the topmost\n   *         point and the last, the bottommost. The second point will be\n   *         leftmost and the third, the rightmost\n   * @throws NotFoundException if no Data Matrix Code can be found\n   */\n  public ResultPoint[] detect() throws NotFoundException {\n\n    int left = leftInit;\n    int right = rightInit;\n    int up = upInit;\n    int down = downInit;\n    boolean sizeExceeded = false;\n    boolean aBlackPointFoundOnBorder = true;\n    boolean atLeastOneBlackPointFoundOnBorder = false;\n\n    while (aBlackPointFoundOnBorder) {\n\n      aBlackPointFoundOnBorder = false;\n\n      // .....\n      // .   |\n      // .....\n      boolean rightBorderNotWhite = true;\n      while (rightBorderNotWhite && right < width) {\n        rightBorderNotWhite = containsBlackPoint(up, down, right, false);\n        if (rightBorderNotWhite) {\n          right++;\n          aBlackPointFoundOnBorder = true;\n        }\n      }\n\n      if (right >= width) {\n        sizeExceeded = true;\n        break;\n      }\n\n      // .....\n      // .   .\n      // .___.\n      boolean bottomBorderNotWhite = true;\n      while (bottomBorderNotWhite && down < height) {\n        bottomBorderNotWhite = containsBlackPoint(left, right, down, true);\n        if (bottomBorderNotWhite) {\n          down++;\n          aBlackPointFoundOnBorder = true;\n        }\n      }\n\n      if (down >= height) {\n        sizeExceeded = true;\n        break;\n      }\n\n      // .....\n      // |   .\n      // .....\n      boolean leftBorderNotWhite = true;\n      while (leftBorderNotWhite && left >= 0) {\n        leftBorderNotWhite = containsBlackPoint(up, down, left, false);\n        if (leftBorderNotWhite) {\n          left--;\n          aBlackPointFoundOnBorder = true;\n        }\n      }\n\n      if (left < 0) {\n        sizeExceeded = true;\n        break;\n      }\n\n      // .___.\n      // .   .\n      // .....\n      boolean topBorderNotWhite = true;\n      while (topBorderNotWhite && up >= 0) {\n        topBorderNotWhite = containsBlackPoint(left, right, up, true);\n        if (topBorderNotWhite) {\n          up--;\n          aBlackPointFoundOnBorder = true;\n        }\n      }\n\n      if (up < 0) {\n        sizeExceeded = true;\n        break;\n      }\n\n      if (aBlackPointFoundOnBorder) {\n        atLeastOneBlackPointFoundOnBorder = true;\n      }\n\n    }\n\n    if (!sizeExceeded && atLeastOneBlackPointFoundOnBorder) {\n\n      int maxSize = right - left;\n\n      ResultPoint z = null;\n      for (int i = 1; i < maxSize; i++) {\n        z = getBlackPointOnSegment(left, down - i, left + i, down);\n        if (z != null) {\n          break;\n        }\n      }\n\n      if (z == null) {\n        throw NotFoundException.getNotFoundInstance();\n      }\n\n      ResultPoint t = null;\n      //go down right\n      for (int i = 1; i < maxSize; i++) {\n        t = getBlackPointOnSegment(left, up + i, left + i, up);\n        if (t != null) {\n          break;\n        }\n      }\n\n      if (t == null) {\n        throw NotFoundException.getNotFoundInstance();\n      }\n\n      ResultPoint x = null;\n      //go down left\n      for (int i = 1; i < maxSize; i++) {\n        x = getBlackPointOnSegment(right, up + i, right - i, up);\n        if (x != null) {\n          break;\n        }\n      }\n\n      if (x == null) {\n        throw NotFoundException.getNotFoundInstance();\n      }\n\n      ResultPoint y = null;\n      //go up left\n      for (int i = 1; i < maxSize; i++) {\n        y = getBlackPointOnSegment(right, down - i, right - i, down);\n        if (y != null) {\n          break;\n        }\n      }\n\n      if (y == null) {\n        throw NotFoundException.getNotFoundInstance();\n      }\n\n      return centerEdges(y, z, x, t);\n\n    } else {\n      throw NotFoundException.getNotFoundInstance();\n    }\n  }\n\n  private ResultPoint getBlackPointOnSegment(float aX, float aY, float bX, float bY) {\n    int dist = MathUtils.round(MathUtils.distance(aX, aY, bX, bY));\n    float xStep = (bX - aX) / dist;\n    float yStep = (bY - aY) / dist;\n\n    for (int i = 0; i < dist; i++) {\n      int x = MathUtils.round(aX + i * xStep);\n      int y = MathUtils.round(aY + i * yStep);\n      if (image.get(x, y)) {\n        return new ResultPoint(x, y);\n      }\n    }\n    return null;\n  }\n\n  /**\n   * recenters the points of a constant distance towards the center\n   *\n   * @param y bottom most point\n   * @param z left most point\n   * @param x right most point\n   * @param t top most point\n   * @return {@link ResultPoint}[] describing the corners of the rectangular\n   *         region. The first and last points are opposed on the diagonal, as\n   *         are the second and third. The first point will be the topmost\n   *         point and the last, the bottommost. The second point will be\n   *         leftmost and the third, the rightmost\n   */\n  private ResultPoint[] centerEdges(ResultPoint y, ResultPoint z,\n                                    ResultPoint x, ResultPoint t) {\n\n    //\n    //       t            t\n    //  z                      x\n    //        x    OR    z\n    //   y                    y\n    //\n\n    float yi = y.getX();\n    float yj = y.getY();\n    float zi = z.getX();\n    float zj = z.getY();\n    float xi = x.getX();\n    float xj = x.getY();\n    float ti = t.getX();\n    float tj = t.getY();\n\n    if (yi < width / 2) {\n      return new ResultPoint[]{\n          new ResultPoint(ti - CORR, tj + CORR),\n          new ResultPoint(zi + CORR, zj + CORR),\n          new ResultPoint(xi - CORR, xj - CORR),\n          new ResultPoint(yi + CORR, yj - CORR)};\n    } else {\n      return new ResultPoint[]{\n          new ResultPoint(ti + CORR, tj + CORR),\n          new ResultPoint(zi + CORR, zj - CORR),\n          new ResultPoint(xi - CORR, xj + CORR),\n          new ResultPoint(yi - CORR, yj - CORR)};\n    }\n  }\n\n  /**\n   * Determines whether a segment contains a black point\n   *\n   * @param a          min value of the scanned coordinate\n   * @param b          max value of the scanned coordinate\n   * @param fixed      value of fixed coordinate\n   * @param horizontal set to true if scan must be horizontal, false if vertical\n   * @return true if a black point has been found, else false.\n   */\n  private boolean containsBlackPoint(int a, int b, int fixed, boolean horizontal) {\n\n    if (horizontal) {\n      for (int x = a; x <= b; x++) {\n        if (image.get(x, fixed)) {\n          return true;\n        }\n      }\n    } else {\n      for (int y = a; y <= b; y++) {\n        if (image.get(fixed, y)) {\n          return true;\n        }\n      }\n    }\n\n    return false;\n  }\n\n}"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/common/reedsolomon/GenericGF.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.common.reedsolomon;\n\n/**\n * <p>This class contains utility methods for performing mathematical operations over\n * the Galois Fields. Operations use a given primitive polynomial in calculations.</p>\n *\n * <p>Throughout this package, elements of the GF are represented as an {@code int}\n * for convenience and speed (but at the cost of memory).\n * </p>\n *\n * @author Sean Owen\n * @author David Olivier\n */\npublic final class GenericGF {\n\n  public static final GenericGF AZTEC_DATA_12 = new GenericGF(0x1069, 4096); // x^12 + x^6 + x^5 + x^3 + 1\n  public static final GenericGF AZTEC_DATA_10 = new GenericGF(0x409, 1024); // x^10 + x^3 + 1\n  public static final GenericGF AZTEC_DATA_6 = new GenericGF(0x43, 64); // x^6 + x + 1\n  public static final GenericGF AZTEC_PARAM = new GenericGF(0x13, 16); // x^4 + x + 1\n  public static final GenericGF QR_CODE_FIELD_256 = new GenericGF(0x011D, 256); // x^8 + x^4 + x^3 + x^2 + 1\n  public static final GenericGF DATA_MATRIX_FIELD_256 = new GenericGF(0x012D, 256); // x^8 + x^5 + x^3 + x^2 + 1\n  public static final GenericGF AZTEC_DATA_8 = DATA_MATRIX_FIELD_256;\n  public static final GenericGF MAXICODE_FIELD_64 = AZTEC_DATA_6;\n\n  private static final int INITIALIZATION_THRESHOLD = 0;\n\n  private int[] expTable;\n  private int[] logTable;\n  private GenericGFPoly zero;\n  private GenericGFPoly one;\n  private final int size;\n  private final int primitive;\n  private boolean initialized = false;\n\n  /**\n   * Create a representation of GF(size) using the given primitive polynomial.\n   *\n   * @param primitive irreducible polynomial whose coefficients are represented by\n   *  the bits of an int, where the least-significant bit represents the constant\n   *  coefficient\n   */\n  public GenericGF(int primitive, int size) {\n  \tthis.primitive = primitive;\n    this.size = size;\n    \n    if (size <= INITIALIZATION_THRESHOLD){\n    \tinitialize();\n    }\n  }\n\n  private void initialize(){\n    expTable = new int[size];\n    logTable = new int[size];\n    int x = 1;\n    for (int i = 0; i < size; i++) {\n      expTable[i] = x;\n      x <<= 1; // x = x * 2; we're assuming the generator alpha is 2\n      if (x >= size) {\n        x ^= primitive;\n        x &= size-1;\n      }\n    }\n    for (int i = 0; i < size-1; i++) {\n      logTable[expTable[i]] = i;\n    }\n    // logTable[0] == 0 but this should never be used\n    zero = new GenericGFPoly(this, new int[]{0});\n    one = new GenericGFPoly(this, new int[]{1});\n    initialized = true;\n  }\n  \n  private void checkInit(){\n  \tif (!initialized) {\n      initialize();\n    }\n  }\n  \n  GenericGFPoly getZero() {\n  \tcheckInit();\n  \t\n    return zero;\n  }\n\n  GenericGFPoly getOne() {\n  \tcheckInit();\n  \t\n    return one;\n  }\n\n  /**\n   * @return the monomial representing coefficient * x^degree\n   */\n  GenericGFPoly buildMonomial(int degree, int coefficient) {\n  \tcheckInit();\n  \t\n    if (degree < 0) {\n      throw new IllegalArgumentException();\n    }\n    if (coefficient == 0) {\n      return zero;\n    }\n    int[] coefficients = new int[degree + 1];\n    coefficients[0] = coefficient;\n    return new GenericGFPoly(this, coefficients);\n  }\n\n  /**\n   * Implements both addition and subtraction -- they are the same in GF(size).\n   *\n   * @return sum/difference of a and b\n   */\n  static int addOrSubtract(int a, int b) {\n    return a ^ b;\n  }\n\n  /**\n   * @return 2 to the power of a in GF(size)\n   */\n  int exp(int a) {\n  \tcheckInit();\n  \t\n    return expTable[a];\n  }\n\n  /**\n   * @return base 2 log of a in GF(size)\n   */\n  int log(int a) {\n  \tcheckInit();\n  \t\n    if (a == 0) {\n      throw new IllegalArgumentException();\n    }\n    return logTable[a];\n  }\n\n  /**\n   * @return multiplicative inverse of a\n   */\n  int inverse(int a) {\n  \tcheckInit();\n  \t\n    if (a == 0) {\n      throw new ArithmeticException();\n    }\n    return expTable[size - logTable[a] - 1];\n  }\n\n  /**\n   * @return product of a and b in GF(size)\n   */\n  int multiply(int a, int b) {\n  \tcheckInit();\n\n    if (a == 0 || b == 0) {\n      return 0;\n    }\n    return expTable[(logTable[a] + logTable[b]) % (size - 1)];\n  }\n\n  public int getSize() {\n  \treturn size;\n  }\n  \n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/common/reedsolomon/GenericGFPoly.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.common.reedsolomon;\n\n/**\n * <p>Represents a polynomial whose coefficients are elements of a GF.\n * Instances of this class are immutable.</p>\n *\n * <p>Much credit is due to William Rucklidge since portions of this code are an indirect\n * port of his C++ Reed-Solomon implementation.</p>\n *\n * @author Sean Owen\n */\nfinal class GenericGFPoly {\n\n  private final GenericGF field;\n  private final int[] coefficients;\n\n  /**\n   * @param field the {@link GenericGF} instance representing the field to use\n   * to perform computations\n   * @param coefficients coefficients as ints representing elements of GF(size), arranged\n   * from most significant (highest-power term) coefficient to least significant\n   * @throws IllegalArgumentException if argument is null or empty,\n   * or if leading coefficient is 0 and this is not a\n   * constant polynomial (that is, it is not the monomial \"0\")\n   */\n  GenericGFPoly(GenericGF field, int[] coefficients) {\n    if (coefficients.length == 0) {\n      throw new IllegalArgumentException();\n    }\n    this.field = field;\n    int coefficientsLength = coefficients.length;\n    if (coefficientsLength > 1 && coefficients[0] == 0) {\n      // Leading term must be non-zero for anything except the constant polynomial \"0\"\n      int firstNonZero = 1;\n      while (firstNonZero < coefficientsLength && coefficients[firstNonZero] == 0) {\n        firstNonZero++;\n      }\n      if (firstNonZero == coefficientsLength) {\n        this.coefficients = field.getZero().coefficients;\n      } else {\n        this.coefficients = new int[coefficientsLength - firstNonZero];\n        System.arraycopy(coefficients,\n            firstNonZero,\n            this.coefficients,\n            0,\n            this.coefficients.length);\n      }\n    } else {\n      this.coefficients = coefficients;\n    }\n  }\n\n  int[] getCoefficients() {\n    return coefficients;\n  }\n\n  /**\n   * @return degree of this polynomial\n   */\n  int getDegree() {\n    return coefficients.length - 1;\n  }\n\n  /**\n   * @return true iff this polynomial is the monomial \"0\"\n   */\n  boolean isZero() {\n    return coefficients[0] == 0;\n  }\n\n  /**\n   * @return coefficient of x^degree term in this polynomial\n   */\n  int getCoefficient(int degree) {\n    return coefficients[coefficients.length - 1 - degree];\n  }\n\n  /**\n   * @return evaluation of this polynomial at a given point\n   */\n  int evaluateAt(int a) {\n    if (a == 0) {\n      // Just return the x^0 coefficient\n      return getCoefficient(0);\n    }\n    int size = coefficients.length;\n    if (a == 1) {\n      // Just the sum of the coefficients\n      int result = 0;\n      for (int coefficient : coefficients) {\n        result = GenericGF.addOrSubtract(result, coefficient);\n      }\n      return result;\n    }\n    int result = coefficients[0];\n    for (int i = 1; i < size; i++) {\n      result = GenericGF.addOrSubtract(field.multiply(a, result), coefficients[i]);\n    }\n    return result;\n  }\n\n  GenericGFPoly addOrSubtract(GenericGFPoly other) {\n    if (!field.equals(other.field)) {\n      throw new IllegalArgumentException(\"GenericGFPolys do not have same GenericGF field\");\n    }\n    if (isZero()) {\n      return other;\n    }\n    if (other.isZero()) {\n      return this;\n    }\n\n    int[] smallerCoefficients = this.coefficients;\n    int[] largerCoefficients = other.coefficients;\n    if (smallerCoefficients.length > largerCoefficients.length) {\n      int[] temp = smallerCoefficients;\n      smallerCoefficients = largerCoefficients;\n      largerCoefficients = temp;\n    }\n    int[] sumDiff = new int[largerCoefficients.length];\n    int lengthDiff = largerCoefficients.length - smallerCoefficients.length;\n    // Copy high-order terms only found in higher-degree polynomial's coefficients\n    System.arraycopy(largerCoefficients, 0, sumDiff, 0, lengthDiff);\n\n    for (int i = lengthDiff; i < largerCoefficients.length; i++) {\n      sumDiff[i] = GenericGF.addOrSubtract(smallerCoefficients[i - lengthDiff], largerCoefficients[i]);\n    }\n\n    return new GenericGFPoly(field, sumDiff);\n  }\n\n  GenericGFPoly multiply(GenericGFPoly other) {\n    if (!field.equals(other.field)) {\n      throw new IllegalArgumentException(\"GenericGFPolys do not have same GenericGF field\");\n    }\n    if (isZero() || other.isZero()) {\n      return field.getZero();\n    }\n    int[] aCoefficients = this.coefficients;\n    int aLength = aCoefficients.length;\n    int[] bCoefficients = other.coefficients;\n    int bLength = bCoefficients.length;\n    int[] product = new int[aLength + bLength - 1];\n    for (int i = 0; i < aLength; i++) {\n      int aCoeff = aCoefficients[i];\n      for (int j = 0; j < bLength; j++) {\n        product[i + j] = GenericGF.addOrSubtract(product[i + j],\n            field.multiply(aCoeff, bCoefficients[j]));\n      }\n    }\n    return new GenericGFPoly(field, product);\n  }\n\n  GenericGFPoly multiply(int scalar) {\n    if (scalar == 0) {\n      return field.getZero();\n    }\n    if (scalar == 1) {\n      return this;\n    }\n    int size = coefficients.length;\n    int[] product = new int[size];\n    for (int i = 0; i < size; i++) {\n      product[i] = field.multiply(coefficients[i], scalar);\n    }\n    return new GenericGFPoly(field, product);\n  }\n\n  GenericGFPoly multiplyByMonomial(int degree, int coefficient) {\n    if (degree < 0) {\n      throw new IllegalArgumentException();\n    }\n    if (coefficient == 0) {\n      return field.getZero();\n    }\n    int size = coefficients.length;\n    int[] product = new int[size + degree];\n    for (int i = 0; i < size; i++) {\n      product[i] = field.multiply(coefficients[i], coefficient);\n    }\n    return new GenericGFPoly(field, product);\n  }\n\n  GenericGFPoly[] divide(GenericGFPoly other) {\n    if (!field.equals(other.field)) {\n      throw new IllegalArgumentException(\"GenericGFPolys do not have same GenericGF field\");\n    }\n    if (other.isZero()) {\n      throw new IllegalArgumentException(\"Divide by 0\");\n    }\n\n    GenericGFPoly quotient = field.getZero();\n    GenericGFPoly remainder = this;\n\n    int denominatorLeadingTerm = other.getCoefficient(other.getDegree());\n    int inverseDenominatorLeadingTerm = field.inverse(denominatorLeadingTerm);\n\n    while (remainder.getDegree() >= other.getDegree() && !remainder.isZero()) {\n      int degreeDifference = remainder.getDegree() - other.getDegree();\n      int scale = field.multiply(remainder.getCoefficient(remainder.getDegree()), inverseDenominatorLeadingTerm);\n      GenericGFPoly term = other.multiplyByMonomial(degreeDifference, scale);\n      GenericGFPoly iterationQuotient = field.buildMonomial(degreeDifference, scale);\n      quotient = quotient.addOrSubtract(iterationQuotient);\n      remainder = remainder.addOrSubtract(term);\n    }\n\n    return new GenericGFPoly[] { quotient, remainder };\n  }\n\n  @Override\n  public String toString() {\n    StringBuilder result = new StringBuilder(8 * getDegree());\n    for (int degree = getDegree(); degree >= 0; degree--) {\n      int coefficient = getCoefficient(degree);\n      if (coefficient != 0) {\n        if (coefficient < 0) {\n          result.append(\" - \");\n          coefficient = -coefficient;\n        } else {\n          if (result.length() > 0) {\n            result.append(\" + \");\n          }\n        }\n        if (degree == 0 || coefficient != 1) {\n          int alphaPower = field.log(coefficient);\n          if (alphaPower == 0) {\n            result.append('1');\n          } else if (alphaPower == 1) {\n            result.append('a');\n          } else {\n            result.append(\"a^\");\n            result.append(alphaPower);\n          }\n        }\n        if (degree != 0) {\n          if (degree == 1) {\n            result.append('x');\n          } else {\n            result.append(\"x^\");\n            result.append(degree);\n          }\n        }\n      }\n    }\n    return result.toString();\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/common/reedsolomon/ReedSolomonDecoder.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.common.reedsolomon;\n\n/**\n * <p>Implements Reed-Solomon decoding, as the name implies.</p>\n *\n * <p>The algorithm will not be explained here, but the following references were helpful\n * in creating this implementation:</p>\n *\n * <ul>\n * <li>Bruce Maggs.\n * <a href=\"http://www.cs.cmu.edu/afs/cs.cmu.edu/project/pscico-guyb/realworld/www/rs_decode.ps\">\n * \"Decoding Reed-Solomon Codes\"</a> (see discussion of Forney's Formula)</li>\n * <li>J.I. Hall. <a href=\"www.mth.msu.edu/~jhall/classes/codenotes/GRS.pdf\">\n * \"Chapter 5. Generalized Reed-Solomon Codes\"</a>\n * (see discussion of Euclidean algorithm)</li>\n * </ul>\n *\n * <p>Much credit is due to William Rucklidge since portions of this code are an indirect\n * port of his C++ Reed-Solomon implementation.</p>\n *\n * @author Sean Owen\n * @author William Rucklidge\n * @author sanfordsquires\n */\npublic final class ReedSolomonDecoder {\n\n  private final GenericGF field;\n\n  public ReedSolomonDecoder(GenericGF field) {\n    this.field = field;\n  }\n\n  /**\n   * <p>Decodes given set of received codewords, which include both data and error-correction\n   * codewords. Really, this means it uses Reed-Solomon to detect and correct errors, in-place,\n   * in the input.</p>\n   *\n   * @param received data and error-correction codewords\n   * @param twoS number of error-correction codewords available\n   * @throws ReedSolomonException if decoding fails for any reason\n   */\n  public void decode(int[] received, int twoS) throws ReedSolomonException {\n    GenericGFPoly poly = new GenericGFPoly(field, received);\n    int[] syndromeCoefficients = new int[twoS];\n    boolean dataMatrix = field.equals(GenericGF.DATA_MATRIX_FIELD_256);\n    boolean noError = true;\n    for (int i = 0; i < twoS; i++) {\n      // Thanks to sanfordsquires for this fix:\n      int eval = poly.evaluateAt(field.exp(dataMatrix ? i + 1 : i));\n      syndromeCoefficients[syndromeCoefficients.length - 1 - i] = eval;\n      if (eval != 0) {\n        noError = false;\n      }\n    }\n    if (noError) {\n      return;\n    }\n    GenericGFPoly syndrome = new GenericGFPoly(field, syndromeCoefficients);\n    GenericGFPoly[] sigmaOmega =\n        runEuclideanAlgorithm(field.buildMonomial(twoS, 1), syndrome, twoS);\n    GenericGFPoly sigma = sigmaOmega[0];\n    GenericGFPoly omega = sigmaOmega[1];\n    int[] errorLocations = findErrorLocations(sigma);\n    int[] errorMagnitudes = findErrorMagnitudes(omega, errorLocations, dataMatrix);\n    for (int i = 0; i < errorLocations.length; i++) {\n      int position = received.length - 1 - field.log(errorLocations[i]);\n      if (position < 0) {\n        throw new ReedSolomonException(\"Bad error location\");\n      }\n      received[position] = GenericGF.addOrSubtract(received[position], errorMagnitudes[i]);\n    }\n  }\n\n  private GenericGFPoly[] runEuclideanAlgorithm(GenericGFPoly a, GenericGFPoly b, int R)\n      throws ReedSolomonException {\n    // Assume a's degree is >= b's\n    if (a.getDegree() < b.getDegree()) {\n      GenericGFPoly temp = a;\n      a = b;\n      b = temp;\n    }\n\n    GenericGFPoly rLast = a;\n    GenericGFPoly r = b;\n    GenericGFPoly tLast = field.getZero();\n    GenericGFPoly t = field.getOne();\n\n    // Run Euclidean algorithm until r's degree is less than R/2\n    while (r.getDegree() >= R / 2) {\n      GenericGFPoly rLastLast = rLast;\n      GenericGFPoly tLastLast = tLast;\n      rLast = r;\n      tLast = t;\n\n      // Divide rLastLast by rLast, with quotient in q and remainder in r\n      if (rLast.isZero()) {\n        // Oops, Euclidean algorithm already terminated?\n        throw new ReedSolomonException(\"r_{i-1} was zero\");\n      }\n      r = rLastLast;\n      GenericGFPoly q = field.getZero();\n      int denominatorLeadingTerm = rLast.getCoefficient(rLast.getDegree());\n      int dltInverse = field.inverse(denominatorLeadingTerm);\n      while (r.getDegree() >= rLast.getDegree() && !r.isZero()) {\n        int degreeDiff = r.getDegree() - rLast.getDegree();\n        int scale = field.multiply(r.getCoefficient(r.getDegree()), dltInverse);\n        q = q.addOrSubtract(field.buildMonomial(degreeDiff, scale));\n        r = r.addOrSubtract(rLast.multiplyByMonomial(degreeDiff, scale));\n      }\n\n      t = q.multiply(tLast).addOrSubtract(tLastLast);\n    }\n\n    int sigmaTildeAtZero = t.getCoefficient(0);\n    if (sigmaTildeAtZero == 0) {\n      throw new ReedSolomonException(\"sigmaTilde(0) was zero\");\n    }\n\n    int inverse = field.inverse(sigmaTildeAtZero);\n    GenericGFPoly sigma = t.multiply(inverse);\n    GenericGFPoly omega = r.multiply(inverse);\n    return new GenericGFPoly[]{sigma, omega};\n  }\n\n  private int[] findErrorLocations(GenericGFPoly errorLocator) throws ReedSolomonException {\n    // This is a direct application of Chien's search\n    int numErrors = errorLocator.getDegree();\n    if (numErrors == 1) { // shortcut\n      return new int[] { errorLocator.getCoefficient(1) };\n    }\n    int[] result = new int[numErrors];\n    int e = 0;\n    for (int i = 1; i < field.getSize() && e < numErrors; i++) {\n      if (errorLocator.evaluateAt(i) == 0) {\n        result[e] = field.inverse(i);\n        e++;\n      }\n    }\n    if (e != numErrors) {\n      throw new ReedSolomonException(\"Error locator degree does not match number of roots\");\n    }\n    return result;\n  }\n\n  private int[] findErrorMagnitudes(GenericGFPoly errorEvaluator,\n                                    int[] errorLocations,\n                                    boolean dataMatrix) {\n    // This is directly applying Forney's Formula\n    int s = errorLocations.length;\n    int[] result = new int[s];\n    for (int i = 0; i < s; i++) {\n      int xiInverse = field.inverse(errorLocations[i]);\n      int denominator = 1;\n      for (int j = 0; j < s; j++) {\n        if (i != j) {\n          //denominator = field.multiply(denominator,\n          //    GenericGF.addOrSubtract(1, field.multiply(errorLocations[j], xiInverse)));\n          // Above should work but fails on some Apple and Linux JDKs due to a Hotspot bug.\n          // Below is a funny-looking workaround from Steven Parkes\n          int term = field.multiply(errorLocations[j], xiInverse);\n          int termPlus1 = (term & 0x1) == 0 ? term | 1 : term & ~1;\n          denominator = field.multiply(denominator, termPlus1);\n        }\n      }\n      result[i] = field.multiply(errorEvaluator.evaluateAt(xiInverse),\n          field.inverse(denominator));\n      // Thanks to sanfordsquires for this fix:\n      if (dataMatrix) {\n        result[i] = field.multiply(result[i], xiInverse);\n      }\n    }\n    return result;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/common/reedsolomon/ReedSolomonEncoder.java",
    "content": "/*\n * Copyright 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.common.reedsolomon;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * <p>Implements Reed-Solomon enbcoding, as the name implies.</p>\n *\n * @author Sean Owen\n * @author William Rucklidge\n */\npublic final class ReedSolomonEncoder {\n\n  private final GenericGF field;\n  private final List<GenericGFPoly> cachedGenerators;\n\n  public ReedSolomonEncoder(GenericGF field) {\n    if (!GenericGF.QR_CODE_FIELD_256.equals(field)) {\n      throw new IllegalArgumentException(\"Only QR Code is supported at this time\");\n    }\n    this.field = field;\n    this.cachedGenerators = new ArrayList<GenericGFPoly>();\n    cachedGenerators.add(new GenericGFPoly(field, new int[]{1}));\n  }\n\n  private GenericGFPoly buildGenerator(int degree) {\n    if (degree >= cachedGenerators.size()) {\n      GenericGFPoly lastGenerator = cachedGenerators.get(cachedGenerators.size() - 1);\n      for (int d = cachedGenerators.size(); d <= degree; d++) {\n        GenericGFPoly nextGenerator = lastGenerator.multiply(new GenericGFPoly(field, new int[] { 1, field.exp(d - 1) }));\n        cachedGenerators.add(nextGenerator);\n        lastGenerator = nextGenerator;\n      }\n    }\n    return cachedGenerators.get(degree);\n  }\n\n  public void encode(int[] toEncode, int ecBytes) {\n    if (ecBytes == 0) {\n      throw new IllegalArgumentException(\"No error correction bytes\");\n    }\n    int dataBytes = toEncode.length - ecBytes;\n    if (dataBytes <= 0) {\n      throw new IllegalArgumentException(\"No data bytes provided\");\n    }\n    GenericGFPoly generator = buildGenerator(ecBytes);\n    int[] infoCoefficients = new int[dataBytes];\n    System.arraycopy(toEncode, 0, infoCoefficients, 0, dataBytes);\n    GenericGFPoly info = new GenericGFPoly(field, infoCoefficients);\n    info = info.multiplyByMonomial(ecBytes, 1);\n    GenericGFPoly remainder = info.divide(generator)[1];\n    int[] coefficients = remainder.getCoefficients();\n    int numZeroCoefficients = ecBytes - coefficients.length;\n    for (int i = 0; i < numZeroCoefficients; i++) {\n      toEncode[dataBytes + i] = 0;\n    }\n    System.arraycopy(coefficients, 0, toEncode, dataBytes + numZeroCoefficients, coefficients.length);\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/common/reedsolomon/ReedSolomonException.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.common.reedsolomon;\n\n/**\n * <p>Thrown when an exception occurs during Reed-Solomon decoding, such as when\n * there are too many errors to correct.</p>\n *\n * @author Sean Owen\n */\npublic final class ReedSolomonException extends Exception {\n\n  public ReedSolomonException(String message) {\n    super(message);\n  }\n\n}"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/datamatrix/DataMatrixReader.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.datamatrix;\n\nimport com.google.zxing.BarcodeFormat;\nimport com.google.zxing.BinaryBitmap;\nimport com.google.zxing.ChecksumException;\nimport com.google.zxing.DecodeHintType;\nimport com.google.zxing.FormatException;\nimport com.google.zxing.NotFoundException;\nimport com.google.zxing.Reader;\nimport com.google.zxing.Result;\nimport com.google.zxing.ResultMetadataType;\nimport com.google.zxing.ResultPoint;\nimport com.google.zxing.common.BitMatrix;\nimport com.google.zxing.common.DecoderResult;\nimport com.google.zxing.common.DetectorResult;\nimport com.google.zxing.datamatrix.decoder.Decoder;\nimport com.google.zxing.datamatrix.detector.Detector;\n\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * This implementation can detect and decode Data Matrix codes in an image.\n *\n * @author bbrown@google.com (Brian Brown)\n */\npublic final class DataMatrixReader implements Reader {\n\n  private static final ResultPoint[] NO_POINTS = new ResultPoint[0];\n\n  private final Decoder decoder = new Decoder();\n\n  /**\n   * Locates and decodes a Data Matrix code in an image.\n   *\n   * @return a String representing the content encoded by the Data Matrix code\n   * @throws NotFoundException if a Data Matrix code cannot be found\n   * @throws FormatException if a Data Matrix code cannot be decoded\n   * @throws ChecksumException if error correction fails\n   */\n  @Override\n  public Result decode(BinaryBitmap image) throws NotFoundException, ChecksumException, FormatException {\n    return decode(image, null);\n  }\n\n  @Override\n  public Result decode(BinaryBitmap image, Map<DecodeHintType,?> hints)\n      throws NotFoundException, ChecksumException, FormatException {\n    DecoderResult decoderResult;\n    ResultPoint[] points;\n    if (hints != null && hints.containsKey(DecodeHintType.PURE_BARCODE)) {\n      BitMatrix bits = extractPureBits(image.getBlackMatrix());\n      decoderResult = decoder.decode(bits);\n      points = NO_POINTS;\n    } else {\n      DetectorResult detectorResult = new Detector(image.getBlackMatrix()).detect();\n      decoderResult = decoder.decode(detectorResult.getBits());\n      points = detectorResult.getPoints();\n    }\n    Result result = new Result(decoderResult.getText(), decoderResult.getRawBytes(), points,\n        BarcodeFormat.DATA_MATRIX);\n    List<byte[]> byteSegments = decoderResult.getByteSegments();\n    if (byteSegments != null) {\n      result.putMetadata(ResultMetadataType.BYTE_SEGMENTS, byteSegments);\n    }\n    String ecLevel = decoderResult.getECLevel();\n    if (ecLevel != null) {\n      result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, ecLevel);\n    }\n    return result;\n  }\n\n  @Override\n  public void reset() {\n    // do nothing\n  }\n\n  /**\n   * This method detects a code in a \"pure\" image -- that is, pure monochrome image\n   * which contains only an unrotated, unskewed, image of a code, with some white border\n   * around it. This is a specialized method that works exceptionally fast in this special\n   * case.\n   *\n   * @see com.google.zxing.pdf417.PDF417Reader#extractPureBits(BitMatrix)\n   * @see com.google.zxing.qrcode.QRCodeReader#extractPureBits(BitMatrix)\n   */\n  private static BitMatrix extractPureBits(BitMatrix image) throws NotFoundException {\n\n    int[] leftTopBlack = image.getTopLeftOnBit();\n    int[] rightBottomBlack = image.getBottomRightOnBit();\n    if (leftTopBlack == null || rightBottomBlack == null) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n\n    int moduleSize = moduleSize(leftTopBlack, image);\n\n    int top = leftTopBlack[1];\n    int bottom = rightBottomBlack[1];\n    int left = leftTopBlack[0];\n    int right = rightBottomBlack[0];\n\n    int matrixWidth = (right - left + 1) / moduleSize;\n    int matrixHeight = (bottom - top + 1) / moduleSize;\n    if (matrixWidth <= 0 || matrixHeight <= 0) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n\n    // Push in the \"border\" by half the module width so that we start\n    // sampling in the middle of the module. Just in case the image is a\n    // little off, this will help recover.\n    int nudge = moduleSize >> 1;\n    top += nudge;\n    left += nudge;\n\n    // Now just read off the bits\n    BitMatrix bits = new BitMatrix(matrixWidth, matrixHeight);\n    for (int y = 0; y < matrixHeight; y++) {\n      int iOffset = top + y * moduleSize;\n      for (int x = 0; x < matrixWidth; x++) {\n        if (image.get(left + x * moduleSize, iOffset)) {\n          bits.set(x, y);\n        }\n      }\n    }\n    return bits;\n  }\n\n  private static int moduleSize(int[] leftTopBlack, BitMatrix image) throws NotFoundException {\n    int width = image.getWidth();\n    int x = leftTopBlack[0];\n    int y = leftTopBlack[1];\n    while (x < width && image.get(x, y)) {\n      x++;\n    }\n    if (x == width) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n\n    int moduleSize = x - leftTopBlack[0];\n    if (moduleSize == 0) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n    return moduleSize;\n  }\n\n}"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/datamatrix/decoder/BitMatrixParser.java",
    "content": "/*\r\n * Copyright 2007 ZXing authors\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage com.google.zxing.datamatrix.decoder;\r\n\r\nimport com.google.zxing.FormatException;\r\nimport com.google.zxing.common.BitMatrix;\r\n\r\n/**\r\n * @author bbrown@google.com (Brian Brown)\r\n */\r\nfinal class BitMatrixParser {\r\n\r\n  private final BitMatrix mappingBitMatrix;\r\n  private final BitMatrix readMappingMatrix;\r\n  private final Version version;\r\n\r\n  /**\r\n   * @param bitMatrix {@link BitMatrix} to parse\r\n   * @throws FormatException if dimension is < 8 or > 144 or not 0 mod 2\r\n   */\r\n  BitMatrixParser(BitMatrix bitMatrix) throws FormatException {\r\n    int dimension = bitMatrix.getHeight();\r\n    if (dimension < 8 || dimension > 144 || (dimension & 0x01) != 0) {\r\n      throw FormatException.getFormatInstance();\r\n    }\r\n    \r\n    version = readVersion(bitMatrix);\r\n    this.mappingBitMatrix = extractDataRegion(bitMatrix);\r\n    this.readMappingMatrix = new BitMatrix(this.mappingBitMatrix.getWidth(), this.mappingBitMatrix.getHeight());\r\n  }\r\n\r\n  Version getVersion() {\r\n    return version;\r\n  }\r\n\r\n  /**\r\n   * <p>Creates the version object based on the dimension of the original bit matrix from \r\n   * the datamatrix code.</p>\r\n   *\r\n   * <p>See ISO 16022:2006 Table 7 - ECC 200 symbol attributes</p>\r\n   * \r\n   * @param bitMatrix Original {@link BitMatrix} including alignment patterns\r\n   * @return {@link Version} encapsulating the Data Matrix Code's \"version\"\r\n   * @throws FormatException if the dimensions of the mapping matrix are not valid\r\n   * Data Matrix dimensions.\r\n   */\r\n  private static Version readVersion(BitMatrix bitMatrix) throws FormatException {\r\n    int numRows = bitMatrix.getHeight();\r\n    int numColumns = bitMatrix.getWidth();\r\n    return Version.getVersionForDimensions(numRows, numColumns);\r\n  }\r\n\r\n  /**\r\n   * <p>Reads the bits in the {@link BitMatrix} representing the mapping matrix (No alignment patterns)\r\n   * in the correct order in order to reconstitute the codewords bytes contained within the\r\n   * Data Matrix Code.</p>\r\n   *\r\n   * @return bytes encoded within the Data Matrix Code\r\n   * @throws FormatException if the exact number of bytes expected is not read\r\n   */\r\n  byte[] readCodewords() throws FormatException {\r\n\r\n    byte[] result = new byte[version.getTotalCodewords()];\r\n    int resultOffset = 0;\r\n    \r\n    int row = 4;\r\n    int column = 0;\r\n\r\n    int numRows = mappingBitMatrix.getHeight();\r\n    int numColumns = mappingBitMatrix.getWidth();\r\n    \r\n    boolean corner1Read = false;\r\n    boolean corner2Read = false;\r\n    boolean corner3Read = false;\r\n    boolean corner4Read = false;\r\n    \r\n    // Read all of the codewords\r\n    do {\r\n      // Check the four corner cases\r\n      if ((row == numRows) && (column == 0) && !corner1Read) {\r\n        result[resultOffset++] = (byte) readCorner1(numRows, numColumns);\r\n        row -= 2;\r\n        column +=2;\r\n        corner1Read = true;\r\n      } else if ((row == numRows-2) && (column == 0) && ((numColumns & 0x03) != 0) && !corner2Read) {\r\n        result[resultOffset++] = (byte) readCorner2(numRows, numColumns);\r\n        row -= 2;\r\n        column +=2;\r\n        corner2Read = true;\r\n      } else if ((row == numRows+4) && (column == 2) && ((numColumns & 0x07) == 0) && !corner3Read) {\r\n        result[resultOffset++] = (byte) readCorner3(numRows, numColumns);\r\n        row -= 2;\r\n        column +=2;\r\n        corner3Read = true;\r\n      } else if ((row == numRows-2) && (column == 0) && ((numColumns & 0x07) == 4) && !corner4Read) {\r\n        result[resultOffset++] = (byte) readCorner4(numRows, numColumns);\r\n        row -= 2;\r\n        column +=2;\r\n        corner4Read = true;\r\n      } else {\r\n        // Sweep upward diagonally to the right\r\n        do {\r\n          if ((row < numRows) && (column >= 0) && !readMappingMatrix.get(column, row)) {\r\n            result[resultOffset++] = (byte) readUtah(row, column, numRows, numColumns);\r\n          }\r\n          row -= 2;\r\n          column +=2;\r\n        } while ((row >= 0) && (column < numColumns));\r\n        row += 1;\r\n        column +=3;\r\n        \r\n        // Sweep downward diagonally to the left\r\n        do {\r\n          if ((row >= 0) && (column < numColumns) && !readMappingMatrix.get(column, row)) {\r\n             result[resultOffset++] = (byte) readUtah(row, column, numRows, numColumns);\r\n          }\r\n          row += 2;\r\n          column -=2;\r\n        } while ((row < numRows) && (column >= 0));\r\n        row += 3;\r\n        column +=1;\r\n      }\r\n    } while ((row < numRows) || (column < numColumns));\r\n\r\n    if (resultOffset != version.getTotalCodewords()) {\r\n      throw FormatException.getFormatInstance();\r\n    }\r\n    return result;\r\n  }\r\n  \r\n  /**\r\n   * <p>Reads a bit of the mapping matrix accounting for boundary wrapping.</p>\r\n   * \r\n   * @param row Row to read in the mapping matrix\r\n   * @param column Column to read in the mapping matrix\r\n   * @param numRows Number of rows in the mapping matrix\r\n   * @param numColumns Number of columns in the mapping matrix\r\n   * @return value of the given bit in the mapping matrix\r\n   */\r\n  boolean readModule(int row, int column, int numRows, int numColumns) {\r\n    // Adjust the row and column indices based on boundary wrapping\r\n    if (row < 0) {\r\n      row += numRows;\r\n      column += 4 - ((numRows + 4) & 0x07);\r\n    }\r\n    if (column < 0) {\r\n      column += numColumns;\r\n      row += 4 - ((numColumns + 4) & 0x07);\r\n    }\r\n    readMappingMatrix.set(column, row);\r\n    return mappingBitMatrix.get(column, row);\r\n  }\r\n  \r\n  /**\r\n   * <p>Reads the 8 bits of the standard Utah-shaped pattern.</p>\r\n   * \r\n   * <p>See ISO 16022:2006, 5.8.1 Figure 6</p>\r\n   * \r\n   * @param row Current row in the mapping matrix, anchored at the 8th bit (LSB) of the pattern\r\n   * @param column Current column in the mapping matrix, anchored at the 8th bit (LSB) of the pattern\r\n   * @param numRows Number of rows in the mapping matrix\r\n   * @param numColumns Number of columns in the mapping matrix\r\n   * @return byte from the utah shape\r\n   */\r\n  int readUtah(int row, int column, int numRows, int numColumns) {\r\n    int currentByte = 0;\r\n    if (readModule(row - 2, column - 2, numRows, numColumns)) {\r\n      currentByte |= 1;\r\n    }\r\n    currentByte <<= 1;\r\n    if (readModule(row - 2, column - 1, numRows, numColumns)) {\r\n      currentByte |= 1;\r\n    }\r\n    currentByte <<= 1;\r\n    if (readModule(row - 1, column - 2, numRows, numColumns)) {\r\n      currentByte |= 1;\r\n    }\r\n    currentByte <<= 1;\r\n    if (readModule(row - 1, column - 1, numRows, numColumns)) {\r\n      currentByte |= 1;\r\n    }\r\n    currentByte <<= 1;\r\n    if (readModule(row - 1, column, numRows, numColumns)) {\r\n      currentByte |= 1;\r\n    }\r\n    currentByte <<= 1;\r\n    if (readModule(row, column - 2, numRows, numColumns)) {\r\n      currentByte |= 1;\r\n    }\r\n    currentByte <<= 1;\r\n    if (readModule(row, column - 1, numRows, numColumns)) {\r\n      currentByte |= 1;\r\n    }\r\n    currentByte <<= 1;\r\n    if (readModule(row, column, numRows, numColumns)) {\r\n      currentByte |= 1;\r\n    }\r\n    return currentByte;\r\n  }\r\n  \r\n  /**\r\n   * <p>Reads the 8 bits of the special corner condition 1.</p>\r\n   * \r\n   * <p>See ISO 16022:2006, Figure F.3</p>\r\n   * \r\n   * @param numRows Number of rows in the mapping matrix\r\n   * @param numColumns Number of columns in the mapping matrix\r\n   * @return byte from the Corner condition 1\r\n   */\r\n  int readCorner1(int numRows, int numColumns) {\r\n    int currentByte = 0;\r\n    if (readModule(numRows - 1, 0, numRows, numColumns)) {\r\n      currentByte |= 1;\r\n    }\r\n    currentByte <<= 1;\r\n    if (readModule(numRows - 1, 1, numRows, numColumns)) {\r\n      currentByte |= 1;\r\n    }\r\n    currentByte <<= 1;\r\n    if (readModule(numRows - 1, 2, numRows, numColumns)) {\r\n      currentByte |= 1;\r\n    }\r\n    currentByte <<= 1;\r\n    if (readModule(0, numColumns - 2, numRows, numColumns)) {\r\n      currentByte |= 1;\r\n    }\r\n    currentByte <<= 1;\r\n    if (readModule(0, numColumns - 1, numRows, numColumns)) {\r\n      currentByte |= 1;\r\n    }\r\n    currentByte <<= 1;\r\n    if (readModule(1, numColumns - 1, numRows, numColumns)) {\r\n      currentByte |= 1;\r\n    }\r\n    currentByte <<= 1;\r\n    if (readModule(2, numColumns - 1, numRows, numColumns)) {\r\n      currentByte |= 1;\r\n    }\r\n    currentByte <<= 1;\r\n    if (readModule(3, numColumns - 1, numRows, numColumns)) {\r\n      currentByte |= 1;\r\n    }\r\n    return currentByte;\r\n  }\r\n  \r\n  /**\r\n   * <p>Reads the 8 bits of the special corner condition 2.</p>\r\n   * \r\n   * <p>See ISO 16022:2006, Figure F.4</p>\r\n   * \r\n   * @param numRows Number of rows in the mapping matrix\r\n   * @param numColumns Number of columns in the mapping matrix\r\n   * @return byte from the Corner condition 2\r\n   */\r\n  int readCorner2(int numRows, int numColumns) {\r\n    int currentByte = 0;\r\n    if (readModule(numRows - 3, 0, numRows, numColumns)) {\r\n      currentByte |= 1;\r\n    }\r\n    currentByte <<= 1;\r\n    if (readModule(numRows - 2, 0, numRows, numColumns)) {\r\n      currentByte |= 1;\r\n    }\r\n    currentByte <<= 1;\r\n    if (readModule(numRows - 1, 0, numRows, numColumns)) {\r\n      currentByte |= 1;\r\n    }\r\n    currentByte <<= 1;\r\n    if (readModule(0, numColumns - 4, numRows, numColumns)) {\r\n      currentByte |= 1;\r\n    }\r\n    currentByte <<= 1;\r\n    if (readModule(0, numColumns - 3, numRows, numColumns)) {\r\n      currentByte |= 1;\r\n    }\r\n    currentByte <<= 1;\r\n    if (readModule(0, numColumns - 2, numRows, numColumns)) {\r\n      currentByte |= 1;\r\n    }\r\n    currentByte <<= 1;\r\n    if (readModule(0, numColumns - 1, numRows, numColumns)) {\r\n      currentByte |= 1;\r\n    }\r\n    currentByte <<= 1;\r\n    if (readModule(1, numColumns - 1, numRows, numColumns)) {\r\n      currentByte |= 1;\r\n    }\r\n    return currentByte;\r\n  }\r\n  \r\n  /**\r\n   * <p>Reads the 8 bits of the special corner condition 3.</p>\r\n   * \r\n   * <p>See ISO 16022:2006, Figure F.5</p>\r\n   * \r\n   * @param numRows Number of rows in the mapping matrix\r\n   * @param numColumns Number of columns in the mapping matrix\r\n   * @return byte from the Corner condition 3\r\n   */\r\n  int readCorner3(int numRows, int numColumns) {\r\n    int currentByte = 0;\r\n    if (readModule(numRows - 1, 0, numRows, numColumns)) {\r\n      currentByte |= 1;\r\n    }\r\n    currentByte <<= 1;\r\n    if (readModule(numRows - 1, numColumns - 1, numRows, numColumns)) {\r\n      currentByte |= 1;\r\n    }\r\n    currentByte <<= 1;\r\n    if (readModule(0, numColumns - 3, numRows, numColumns)) {\r\n      currentByte |= 1;\r\n    }\r\n    currentByte <<= 1;\r\n    if (readModule(0, numColumns - 2, numRows, numColumns)) {\r\n      currentByte |= 1;\r\n    }\r\n    currentByte <<= 1;\r\n    if (readModule(0, numColumns - 1, numRows, numColumns)) {\r\n      currentByte |= 1;\r\n    }\r\n    currentByte <<= 1;\r\n    if (readModule(1, numColumns - 3, numRows, numColumns)) {\r\n      currentByte |= 1;\r\n    }\r\n    currentByte <<= 1;\r\n    if (readModule(1, numColumns - 2, numRows, numColumns)) {\r\n      currentByte |= 1;\r\n    }\r\n    currentByte <<= 1;\r\n    if (readModule(1, numColumns - 1, numRows, numColumns)) {\r\n      currentByte |= 1;\r\n    }\r\n    return currentByte;\r\n  }\r\n  \r\n  /**\r\n   * <p>Reads the 8 bits of the special corner condition 4.</p>\r\n   * \r\n   * <p>See ISO 16022:2006, Figure F.6</p>\r\n   * \r\n   * @param numRows Number of rows in the mapping matrix\r\n   * @param numColumns Number of columns in the mapping matrix\r\n   * @return byte from the Corner condition 4\r\n   */\r\n  int readCorner4(int numRows, int numColumns) {\r\n    int currentByte = 0;\r\n    if (readModule(numRows - 3, 0, numRows, numColumns)) {\r\n      currentByte |= 1;\r\n    }\r\n    currentByte <<= 1;\r\n    if (readModule(numRows - 2, 0, numRows, numColumns)) {\r\n      currentByte |= 1;\r\n    }\r\n    currentByte <<= 1;\r\n    if (readModule(numRows - 1, 0, numRows, numColumns)) {\r\n      currentByte |= 1;\r\n    }\r\n    currentByte <<= 1;\r\n    if (readModule(0, numColumns - 2, numRows, numColumns)) {\r\n      currentByte |= 1;\r\n    }\r\n    currentByte <<= 1;\r\n    if (readModule(0, numColumns - 1, numRows, numColumns)) {\r\n      currentByte |= 1;\r\n    }\r\n    currentByte <<= 1;\r\n    if (readModule(1, numColumns - 1, numRows, numColumns)) {\r\n      currentByte |= 1;\r\n    }\r\n    currentByte <<= 1;\r\n    if (readModule(2, numColumns - 1, numRows, numColumns)) {\r\n      currentByte |= 1;\r\n    }\r\n    currentByte <<= 1;\r\n    if (readModule(3, numColumns - 1, numRows, numColumns)) {\r\n      currentByte |= 1;\r\n    }\r\n    return currentByte;\r\n  }\r\n  \r\n  /**\r\n   * <p>Extracts the data region from a {@link BitMatrix} that contains\r\n   * alignment patterns.</p>\r\n   * \r\n   * @param bitMatrix Original {@link BitMatrix} with alignment patterns\r\n   * @return BitMatrix that has the alignment patterns removed\r\n   */\r\n  BitMatrix extractDataRegion(BitMatrix bitMatrix) {\r\n    int symbolSizeRows = version.getSymbolSizeRows();\r\n    int symbolSizeColumns = version.getSymbolSizeColumns();\r\n    \r\n    if (bitMatrix.getHeight() != symbolSizeRows) {\r\n      throw new IllegalArgumentException(\"Dimension of bitMarix must match the version size\");\r\n    }\r\n    \r\n    int dataRegionSizeRows = version.getDataRegionSizeRows();\r\n    int dataRegionSizeColumns = version.getDataRegionSizeColumns();\r\n    \r\n    int numDataRegionsRow = symbolSizeRows / dataRegionSizeRows;\r\n    int numDataRegionsColumn = symbolSizeColumns / dataRegionSizeColumns;\r\n    \r\n    int sizeDataRegionRow = numDataRegionsRow * dataRegionSizeRows;\r\n    int sizeDataRegionColumn = numDataRegionsColumn * dataRegionSizeColumns;\r\n    \r\n    BitMatrix bitMatrixWithoutAlignment = new BitMatrix(sizeDataRegionColumn, sizeDataRegionRow);\r\n    for (int dataRegionRow = 0; dataRegionRow < numDataRegionsRow; ++dataRegionRow) {\r\n      int dataRegionRowOffset = dataRegionRow * dataRegionSizeRows;\r\n      for (int dataRegionColumn = 0; dataRegionColumn < numDataRegionsColumn; ++dataRegionColumn) {\r\n        int dataRegionColumnOffset = dataRegionColumn * dataRegionSizeColumns;\r\n        for (int i = 0; i < dataRegionSizeRows; ++i) {\r\n          int readRowOffset = dataRegionRow * (dataRegionSizeRows + 2) + 1 + i;\r\n          int writeRowOffset = dataRegionRowOffset + i;\r\n          for (int j = 0; j < dataRegionSizeColumns; ++j) {\r\n            int readColumnOffset = dataRegionColumn * (dataRegionSizeColumns + 2) + 1 + j;\r\n            if (bitMatrix.get(readColumnOffset, readRowOffset)) {\r\n              int writeColumnOffset = dataRegionColumnOffset + j;\r\n              bitMatrixWithoutAlignment.set(writeColumnOffset, writeRowOffset);\r\n            }\r\n          }\r\n        }\r\n      }\r\n    }\r\n    return bitMatrixWithoutAlignment;\r\n  }\r\n\r\n}"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/datamatrix/decoder/DataBlock.java",
    "content": "/*\r\n * Copyright 2008 ZXing authors\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage com.google.zxing.datamatrix.decoder;\r\n\r\n/**\r\n * <p>Encapsulates a block of data within a Data Matrix Code. Data Matrix Codes may split their data into\r\n * multiple blocks, each of which is a unit of data and error-correction codewords. Each\r\n * is represented by an instance of this class.</p>\r\n *\r\n * @author bbrown@google.com (Brian Brown)\r\n */\r\nfinal class DataBlock {\r\n\r\n  private final int numDataCodewords;\r\n  private final byte[] codewords;\r\n\r\n  private DataBlock(int numDataCodewords, byte[] codewords) {\r\n    this.numDataCodewords = numDataCodewords;\r\n    this.codewords = codewords;\r\n  }\r\n\r\n  /**\r\n   * <p>When Data Matrix Codes use multiple data blocks, they actually interleave the bytes of each of them.\r\n   * That is, the first byte of data block 1 to n is written, then the second bytes, and so on. This\r\n   * method will separate the data into original blocks.</p>\r\n   *\r\n   * @param rawCodewords bytes as read directly from the Data Matrix Code\r\n   * @param version version of the Data Matrix Code\r\n   * @return DataBlocks containing original bytes, \"de-interleaved\" from representation in the\r\n   *         Data Matrix Code\r\n   */\r\n  static DataBlock[] getDataBlocks(byte[] rawCodewords,\r\n                                   Version version) {\r\n    // Figure out the number and size of data blocks used by this version\r\n    Version.ECBlocks ecBlocks = version.getECBlocks();\r\n\r\n    // First count the total number of data blocks\r\n    int totalBlocks = 0;\r\n    Version.ECB[] ecBlockArray = ecBlocks.getECBlocks();\r\n    for (Version.ECB ecBlock : ecBlockArray) {\r\n       totalBlocks += ecBlock.getCount();\r\n    }\r\n\r\n    // Now establish DataBlocks of the appropriate size and number of data codewords\r\n    DataBlock[] result = new DataBlock[totalBlocks];\r\n    int numResultBlocks = 0;\r\n    for (Version.ECB ecBlock : ecBlockArray) {\r\n      for (int i = 0; i < ecBlock.getCount(); i++) {\r\n        int numDataCodewords = ecBlock.getDataCodewords();\r\n        int numBlockCodewords = ecBlocks.getECCodewords() + numDataCodewords;\r\n        result[numResultBlocks++] = new DataBlock(numDataCodewords, new byte[numBlockCodewords]);\r\n      }\r\n    }\r\n\r\n    // All blocks have the same amount of data, except that the last n\r\n    // (where n may be 0) have 1 less byte. Figure out where these start.\r\n    // TODO(bbrown): There is only one case where there is a difference for Data Matrix for size 144\r\n    int longerBlocksTotalCodewords = result[0].codewords.length;\r\n    //int shorterBlocksTotalCodewords = longerBlocksTotalCodewords - 1;\r\n\r\n    int longerBlocksNumDataCodewords = longerBlocksTotalCodewords - ecBlocks.getECCodewords();\r\n    int shorterBlocksNumDataCodewords = longerBlocksNumDataCodewords - 1;\r\n    // The last elements of result may be 1 element shorter for 144 matrix\r\n    // first fill out as many elements as all of them have minus 1\r\n    int rawCodewordsOffset = 0;\r\n    for (int i = 0; i < shorterBlocksNumDataCodewords; i++) {\r\n      for (int j = 0; j < numResultBlocks; j++) {\r\n        result[j].codewords[i] = rawCodewords[rawCodewordsOffset++];\r\n      }\r\n    }\r\n    \r\n    // Fill out the last data block in the longer ones\r\n    boolean specialVersion = version.getVersionNumber() == 24;\r\n    int numLongerBlocks = specialVersion ? 8 : numResultBlocks;\r\n    for (int j = 0; j < numLongerBlocks; j++) {\r\n      result[j].codewords[longerBlocksNumDataCodewords - 1] = rawCodewords[rawCodewordsOffset++];\r\n    }\r\n    \r\n    // Now add in error correction blocks\r\n    int max = result[0].codewords.length;\r\n    for (int i = longerBlocksNumDataCodewords; i < max; i++) {\r\n      for (int j = 0; j < numResultBlocks; j++) {\r\n        int iOffset = specialVersion && j > 7 ? i - 1 : i;\r\n        result[j].codewords[iOffset] = rawCodewords[rawCodewordsOffset++];\r\n      }\r\n    }\r\n\r\n    if (rawCodewordsOffset != rawCodewords.length) {\r\n      throw new IllegalArgumentException();\r\n    }\r\n\r\n    return result;\r\n  }\r\n\r\n  int getNumDataCodewords() {\r\n    return numDataCodewords;\r\n  }\r\n\r\n  byte[] getCodewords() {\r\n    return codewords;\r\n  }\r\n\r\n}\r\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/datamatrix/decoder/DecodedBitStreamParser.java",
    "content": "/*\n * Copyright 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.datamatrix.decoder;\n\nimport com.google.zxing.FormatException;\nimport com.google.zxing.common.BitSource;\nimport com.google.zxing.common.DecoderResult;\n\nimport java.io.UnsupportedEncodingException;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\n\n/**\n * <p>Data Matrix Codes can encode text as bits in one of several modes, and can use multiple modes\n * in one Data Matrix Code. This class decodes the bits back into text.</p>\n *\n * <p>See ISO 16022:2006, 5.2.1 - 5.2.9.2</p>\n *\n * @author bbrown@google.com (Brian Brown)\n * @author Sean Owen\n */\nfinal class DecodedBitStreamParser {\n\n  private enum Mode {\n    PAD_ENCODE, // Not really a mode\n    ASCII_ENCODE,\n    C40_ENCODE,\n    TEXT_ENCODE,\n    ANSIX12_ENCODE,\n    EDIFACT_ENCODE,\n    BASE256_ENCODE\n  }\n\n  /**\n   * See ISO 16022:2006, Annex C Table C.1\n   * The C40 Basic Character Set (*'s used for placeholders for the shift values)\n   */\n  private static final char[] C40_BASIC_SET_CHARS = {\n    '*', '*', '*', ' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',\n    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',\n    'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'\n  };\n\n  private static final char[] C40_SHIFT2_SET_CHARS = {\n    '!', '\"', '#', '$', '%', '&', '\\'', '(', ')', '*',  '+', ',', '-', '.',\n    '/', ':', ';', '<', '=', '>', '?',  '@', '[', '\\\\', ']', '^', '_'\n  };\n\n  /**\n   * See ISO 16022:2006, Annex C Table C.2\n   * The Text Basic Character Set (*'s used for placeholders for the shift values)\n   */\n  private static final char[] TEXT_BASIC_SET_CHARS = {\n    '*', '*', '*', ' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',\n    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',\n    'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'\n  };\n\n  private static final char[] TEXT_SHIFT3_SET_CHARS = {\n    '\\'', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',\n    'O',  'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '{', '|', '}', '~', (char) 127\n  };\n\n  private DecodedBitStreamParser() {\n  }\n\n  static DecoderResult decode(byte[] bytes) throws FormatException {\n    BitSource bits = new BitSource(bytes);\n    StringBuilder result = new StringBuilder(100);\n    StringBuilder resultTrailer = new StringBuilder(0);\n    List<byte[]> byteSegments = new ArrayList<byte[]>(1);\n    Mode mode = Mode.ASCII_ENCODE;\n    do {\n      if (mode == Mode.ASCII_ENCODE) {\n        mode = decodeAsciiSegment(bits, result, resultTrailer);\n      } else {\n        switch (mode) {\n          case C40_ENCODE:\n            decodeC40Segment(bits, result);\n            break;\n          case TEXT_ENCODE:\n            decodeTextSegment(bits, result);\n            break;\n          case ANSIX12_ENCODE:\n            decodeAnsiX12Segment(bits, result);\n            break;\n          case EDIFACT_ENCODE:\n            decodeEdifactSegment(bits, result);\n            break;\n          case BASE256_ENCODE:\n            decodeBase256Segment(bits, result, byteSegments);\n            break;\n          default:\n            throw FormatException.getFormatInstance();\n        }\n        mode = Mode.ASCII_ENCODE;\n      }\n    } while (mode != Mode.PAD_ENCODE && bits.available() > 0);\n    if (resultTrailer.length() > 0) {\n      result.append(resultTrailer.toString());\n    }\n    return new DecoderResult(bytes, result.toString(), byteSegments.isEmpty() ? null : byteSegments, null);\n  }\n\n  /**\n   * See ISO 16022:2006, 5.2.3 and Annex C, Table C.2\n   */\n  private static Mode decodeAsciiSegment(BitSource bits,\n                                         StringBuilder result,\n                                         StringBuilder resultTrailer) throws FormatException {\n    boolean upperShift = false;\n    do {\n      int oneByte = bits.readBits(8);\n      if (oneByte == 0) {\n        throw FormatException.getFormatInstance();\n      } else if (oneByte <= 128) {  // ASCII data (ASCII value + 1)\n        if (upperShift) {\n          oneByte += 128;\n          //upperShift = false;\n        }\n        result.append((char) (oneByte - 1));\n        return Mode.ASCII_ENCODE;\n      } else if (oneByte == 129) {  // Pad\n        return Mode.PAD_ENCODE;\n      } else if (oneByte <= 229) {  // 2-digit data 00-99 (Numeric Value + 130)\n        int value = oneByte - 130;\n        if (value < 10) { // padd with '0' for single digit values\n          result.append('0');\n        }\n        result.append(value);\n      } else if (oneByte == 230) {  // Latch to C40 encodation\n        return Mode.C40_ENCODE;\n      } else if (oneByte == 231) {  // Latch to Base 256 encodation\n        return Mode.BASE256_ENCODE;\n      } else if (oneByte == 232) {\n        // FNC1\n        result.append((char) 29); // translate as ASCII 29\n      } else if (oneByte == 233 || oneByte == 234) {\n        // Structured Append, Reader Programming\n        // Ignore these symbols for now\n        //throw ReaderException.getInstance();\n      } else if (oneByte == 235) {  // Upper Shift (shift to Extended ASCII)\n        upperShift = true;\n      } else if (oneByte == 236) {  // 05 Macro\n        result.append(\"[)>\\u001E05\\u001D\");\n        resultTrailer.insert(0, \"\\u001E\\u0004\");\n      } else if (oneByte == 237) {  // 06 Macro\n        result.append(\"[)>\\u001E06\\u001D\");\n        resultTrailer.insert(0, \"\\u001E\\u0004\");\n      } else if (oneByte == 238) {  // Latch to ANSI X12 encodation\n        return Mode.ANSIX12_ENCODE;\n      } else if (oneByte == 239) {  // Latch to Text encodation\n        return Mode.TEXT_ENCODE;\n      } else if (oneByte == 240) {  // Latch to EDIFACT encodation\n        return Mode.EDIFACT_ENCODE;\n      } else if (oneByte == 241) {  // ECI Character\n        // TODO(bbrown): I think we need to support ECI\n        //throw ReaderException.getInstance();\n        // Ignore this symbol for now\n      } else if (oneByte >= 242) {  // Not to be used in ASCII encodation\n        // ... but work around encoders that end with 254, latch back to ASCII\n        if (oneByte != 254 || bits.available() != 0) {\n          throw FormatException.getFormatInstance();\n        }\n      }\n    } while (bits.available() > 0);\n    return Mode.ASCII_ENCODE;\n  }\n\n  /**\n   * See ISO 16022:2006, 5.2.5 and Annex C, Table C.1\n   */\n  private static void decodeC40Segment(BitSource bits, StringBuilder result) throws FormatException {\n    // Three C40 values are encoded in a 16-bit value as\n    // (1600 * C1) + (40 * C2) + C3 + 1\n    // TODO(bbrown): The Upper Shift with C40 doesn't work in the 4 value scenario all the time\n    boolean upperShift = false;\n\n    int[] cValues = new int[3];\n    int shift = 0;\n\n    do {\n      // If there is only one byte left then it will be encoded as ASCII\n      if (bits.available() == 8) {\n        return;\n      }\n      int firstByte = bits.readBits(8);\n      if (firstByte == 254) {  // Unlatch codeword\n        return;\n      }\n\n      parseTwoBytes(firstByte, bits.readBits(8), cValues);\n\n      for (int i = 0; i < 3; i++) {\n        int cValue = cValues[i];\n        switch (shift) {\n          case 0:\n            if (cValue < 3) {\n              shift = cValue + 1;\n            } else if (cValue < C40_BASIC_SET_CHARS.length) {\n              char c40char = C40_BASIC_SET_CHARS[cValue];\n              if (upperShift) {\n                result.append((char) (c40char + 128));\n                upperShift = false;\n              } else {\n                result.append(c40char);\n              }\n            } else {\n              throw FormatException.getFormatInstance();\n            }\n            break;\n          case 1:\n            if (upperShift) {\n              result.append((char) (cValue + 128));\n              upperShift = false;\n            } else {\n              result.append((char) cValue);\n            }\n            shift = 0;\n            break;\n          case 2:\n            if (cValue < C40_SHIFT2_SET_CHARS.length) {\n              char c40char = C40_SHIFT2_SET_CHARS[cValue];\n              if (upperShift) {\n                result.append((char) (c40char + 128));\n                upperShift = false;\n              } else {\n                result.append(c40char);\n              }\n            } else if (cValue == 27) {  // FNC1\n              result.append((char) 29); // translate as ASCII 29\n            } else if (cValue == 30) {  // Upper Shift\n              upperShift = true;\n            } else {\n              throw FormatException.getFormatInstance();\n            }\n            shift = 0;\n            break;\n          case 3:\n            if (upperShift) {\n              result.append((char) (cValue + 224));\n              upperShift = false;\n            } else {\n              result.append((char) (cValue + 96));\n            }\n            shift = 0;\n            break;\n          default:\n            throw FormatException.getFormatInstance();\n        }\n      }\n    } while (bits.available() > 0);\n  }\n\n  /**\n   * See ISO 16022:2006, 5.2.6 and Annex C, Table C.2\n   */\n  private static void decodeTextSegment(BitSource bits, StringBuilder result) throws FormatException {\n    // Three Text values are encoded in a 16-bit value as\n    // (1600 * C1) + (40 * C2) + C3 + 1\n    // TODO(bbrown): The Upper Shift with Text doesn't work in the 4 value scenario all the time\n    boolean upperShift = false;\n\n    int[] cValues = new int[3];\n    int shift = 0;\n    do {\n      // If there is only one byte left then it will be encoded as ASCII\n      if (bits.available() == 8) {\n        return;\n      }\n      int firstByte = bits.readBits(8);\n      if (firstByte == 254) {  // Unlatch codeword\n        return;\n      }\n\n      parseTwoBytes(firstByte, bits.readBits(8), cValues);\n\n      for (int i = 0; i < 3; i++) {\n        int cValue = cValues[i];\n        switch (shift) {\n          case 0:\n            if (cValue < 3) {\n              shift = cValue + 1;\n            } else if (cValue < TEXT_BASIC_SET_CHARS.length) {\n              char textChar = TEXT_BASIC_SET_CHARS[cValue];\n              if (upperShift) {\n                result.append((char) (textChar + 128));\n                upperShift = false;\n              } else {\n                result.append(textChar);\n              }\n            } else {\n              throw FormatException.getFormatInstance();\n            }\n            break;\n          case 1:\n            if (upperShift) {\n              result.append((char) (cValue + 128));\n              upperShift = false;\n            } else {\n              result.append((char) cValue);\n            }\n            shift = 0;\n            break;\n          case 2:\n            // Shift 2 for Text is the same encoding as C40\n            if (cValue < C40_SHIFT2_SET_CHARS.length) {\n              char c40char = C40_SHIFT2_SET_CHARS[cValue];\n              if (upperShift) {\n                result.append((char) (c40char + 128));\n                upperShift = false;\n              } else {\n                result.append(c40char);\n              }\n            } else if (cValue == 27) {  // FNC1\n              result.append((char) 29); // translate as ASCII 29\n            } else if (cValue == 30) {  // Upper Shift\n              upperShift = true;\n            } else {\n              throw FormatException.getFormatInstance();\n            }\n            shift = 0;\n            break;\n          case 3:\n            if (cValue < TEXT_SHIFT3_SET_CHARS.length) {\n              char textChar = TEXT_SHIFT3_SET_CHARS[cValue];\n              if (upperShift) {\n                result.append((char) (textChar + 128));\n                upperShift = false;\n              } else {\n                result.append(textChar);\n              }\n              shift = 0;\n            } else {\n              throw FormatException.getFormatInstance();\n            }\n            break;\n          default:\n            throw FormatException.getFormatInstance();\n        }\n      }\n    } while (bits.available() > 0);\n  }\n\n  /**\n   * See ISO 16022:2006, 5.2.7\n   */\n  private static void decodeAnsiX12Segment(BitSource bits,\n                                           StringBuilder result) throws FormatException {\n    // Three ANSI X12 values are encoded in a 16-bit value as\n    // (1600 * C1) + (40 * C2) + C3 + 1\n\n    int[] cValues = new int[3];\n    do {\n      // If there is only one byte left then it will be encoded as ASCII\n      if (bits.available() == 8) {\n        return;\n      }\n      int firstByte = bits.readBits(8);\n      if (firstByte == 254) {  // Unlatch codeword\n        return;\n      }\n\n      parseTwoBytes(firstByte, bits.readBits(8), cValues);\n\n      for (int i = 0; i < 3; i++) {\n        int cValue = cValues[i];\n        if (cValue == 0) {  // X12 segment terminator <CR>\n          result.append('\\r');\n        } else if (cValue == 1) {  // X12 segment separator *\n          result.append('*');\n        } else if (cValue == 2) {  // X12 sub-element separator >\n          result.append('>');\n        } else if (cValue == 3) {  // space\n          result.append(' ');\n        } else if (cValue < 14) {  // 0 - 9\n          result.append((char) (cValue + 44));\n        } else if (cValue < 40) {  // A - Z\n          result.append((char) (cValue + 51));\n        } else {\n          throw FormatException.getFormatInstance();\n        }\n      }\n    } while (bits.available() > 0);\n  }\n\n  private static void parseTwoBytes(int firstByte, int secondByte, int[] result) {\n    int fullBitValue = (firstByte << 8) + secondByte - 1;\n    int temp = fullBitValue / 1600;\n    result[0] = temp;\n    fullBitValue -= temp * 1600;\n    temp = fullBitValue / 40;\n    result[1] = temp;\n    result[2] = fullBitValue - temp * 40;\n  }\n\n  /**\n   * See ISO 16022:2006, 5.2.8 and Annex C Table C.3\n   */\n  private static void decodeEdifactSegment(BitSource bits, StringBuilder result) {\n    do {\n      // If there is only two or less bytes left then it will be encoded as ASCII\n      if (bits.available() <= 16) {\n        return;\n      }\n\n      for (int i = 0; i < 4; i++) {\n        int edifactValue = bits.readBits(6);\n\n        // Check for the unlatch character\n        if (edifactValue == 0x1F) {  // 011111\n          // Read rest of byte, which should be 0, and stop\n          int bitsLeft = 8 - bits.getBitOffset();\n          if (bitsLeft != 8) {\n            bits.readBits(bitsLeft);\n          }\n          return;\n        }\n\n        if ((edifactValue & 0x20) == 0) {  // no 1 in the leading (6th) bit\n          edifactValue |= 0x40;  // Add a leading 01 to the 6 bit binary value\n        }\n        result.append((char) edifactValue);\n      }\n    } while (bits.available() > 0);\n  }\n\n  /**\n   * See ISO 16022:2006, 5.2.9 and Annex B, B.2\n   */\n  private static void decodeBase256Segment(BitSource bits,\n                                           StringBuilder result,\n                                           Collection<byte[]> byteSegments)\n      throws FormatException {\n    // Figure out how long the Base 256 Segment is.\n    int codewordPosition = 1 + bits.getByteOffset(); // position is 1-indexed\n    int d1 = unrandomize255State(bits.readBits(8), codewordPosition++);\n    int count;\n    if (d1 == 0) {  // Read the remainder of the symbol\n      count = bits.available() / 8;\n    } else if (d1 < 250) {\n      count = d1;\n    } else {\n      count = 250 * (d1 - 249) + unrandomize255State(bits.readBits(8), codewordPosition++);\n    }\n\n    // We're seeing NegativeArraySizeException errors from users.\n    if (count < 0) {\n      throw FormatException.getFormatInstance();\n    }\n\n    byte[] bytes = new byte[count];\n    for (int i = 0; i < count; i++) {\n      // Have seen this particular error in the wild, such as at\n      // http://www.bcgen.com/demo/IDAutomationStreamingDataMatrix.aspx?MODE=3&D=Fred&PFMT=3&PT=F&X=0.3&O=0&LM=0.2\n      if (bits.available() < 8) {\n        throw FormatException.getFormatInstance();\n      }\n      bytes[i] = (byte) unrandomize255State(bits.readBits(8), codewordPosition++);\n    }\n    byteSegments.add(bytes);\n    try {\n      result.append(new String(bytes, \"ISO8859_1\"));\n    } catch (UnsupportedEncodingException uee) {\n      throw new IllegalStateException(\"Platform does not support required encoding: \" + uee);\n    }\n  }\n\n  /**\n   * See ISO 16022:2006, Annex B, B.2\n   */\n  private static int unrandomize255State(int randomizedBase256Codeword,\n                                          int base256CodewordPosition) {\n    int pseudoRandomNumber = ((149 * base256CodewordPosition) % 255) + 1;\n    int tempVariable = randomizedBase256Codeword - pseudoRandomNumber;\n    return tempVariable >= 0 ? tempVariable : tempVariable + 256;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/datamatrix/decoder/Decoder.java",
    "content": "/*\r\n * Copyright 2007 ZXing authors\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage com.google.zxing.datamatrix.decoder;\r\n\r\nimport com.google.zxing.ChecksumException;\r\nimport com.google.zxing.FormatException;\r\nimport com.google.zxing.common.BitMatrix;\r\nimport com.google.zxing.common.DecoderResult;\r\nimport com.google.zxing.common.reedsolomon.GenericGF;\r\nimport com.google.zxing.common.reedsolomon.ReedSolomonDecoder;\r\nimport com.google.zxing.common.reedsolomon.ReedSolomonException;\r\n\r\n/**\r\n * <p>The main class which implements Data Matrix Code decoding -- as opposed to locating and extracting\r\n * the Data Matrix Code from an image.</p>\r\n *\r\n * @author bbrown@google.com (Brian Brown)\r\n */\r\npublic final class Decoder {\r\n\r\n  private final ReedSolomonDecoder rsDecoder;\r\n\r\n  public Decoder() {\r\n    rsDecoder = new ReedSolomonDecoder(GenericGF.DATA_MATRIX_FIELD_256);\r\n  }\r\n\r\n  /**\r\n   * <p>Convenience method that can decode a Data Matrix Code represented as a 2D array of booleans.\r\n   * \"true\" is taken to mean a black module.</p>\r\n   *\r\n   * @param image booleans representing white/black Data Matrix Code modules\r\n   * @return text and bytes encoded within the Data Matrix Code\r\n   * @throws FormatException if the Data Matrix Code cannot be decoded\r\n   * @throws ChecksumException if error correction fails\r\n   */\r\n  public DecoderResult decode(boolean[][] image) throws FormatException, ChecksumException {\r\n    int dimension = image.length;\r\n    BitMatrix bits = new BitMatrix(dimension);\r\n    for (int i = 0; i < dimension; i++) {\r\n      for (int j = 0; j < dimension; j++) {\r\n        if (image[i][j]) {\r\n          bits.set(j, i);\r\n        }\r\n      }\r\n    }\r\n    return decode(bits);\r\n  }\r\n\r\n  /**\r\n   * <p>Decodes a Data Matrix Code represented as a {@link BitMatrix}. A 1 or \"true\" is taken\r\n   * to mean a black module.</p>\r\n   *\r\n   * @param bits booleans representing white/black Data Matrix Code modules\r\n   * @return text and bytes encoded within the Data Matrix Code\r\n   * @throws FormatException if the Data Matrix Code cannot be decoded\r\n   * @throws ChecksumException if error correction fails\r\n   */\r\n  public DecoderResult decode(BitMatrix bits) throws FormatException, ChecksumException {\r\n\r\n    // Construct a parser and read version, error-correction level\r\n    BitMatrixParser parser = new BitMatrixParser(bits);\r\n    Version version = parser.getVersion();\r\n\r\n    // Read codewords\r\n    byte[] codewords = parser.readCodewords();\r\n    // Separate into data blocks\r\n    DataBlock[] dataBlocks = DataBlock.getDataBlocks(codewords, version);\r\n\r\n    int dataBlocksCount = dataBlocks.length;\r\n\r\n    // Count total number of data bytes\r\n    int totalBytes = 0;\r\n    for (DataBlock db : dataBlocks) {\r\n      totalBytes += db.getNumDataCodewords();\r\n    }\r\n    byte[] resultBytes = new byte[totalBytes];\r\n\r\n    // Error-correct and copy data blocks together into a stream of bytes\r\n    for (int j = 0; j < dataBlocksCount; j++) {\r\n      DataBlock dataBlock = dataBlocks[j];\r\n      byte[] codewordBytes = dataBlock.getCodewords();\r\n      int numDataCodewords = dataBlock.getNumDataCodewords();\r\n      correctErrors(codewordBytes, numDataCodewords);\r\n      for (int i = 0; i < numDataCodewords; i++) {\r\n        // De-interlace data blocks.\r\n        resultBytes[i * dataBlocksCount + j] = codewordBytes[i];\r\n      }\r\n    }\r\n\r\n    // Decode the contents of that stream of bytes\r\n    return DecodedBitStreamParser.decode(resultBytes);\r\n  }\r\n\r\n  /**\r\n   * <p>Given data and error-correction codewords received, possibly corrupted by errors, attempts to\r\n   * correct the errors in-place using Reed-Solomon error correction.</p>\r\n   *\r\n   * @param codewordBytes data and error correction codewords\r\n   * @param numDataCodewords number of codewords that are data bytes\r\n   * @throws ChecksumException if error correction fails\r\n   */\r\n  private void correctErrors(byte[] codewordBytes, int numDataCodewords) throws ChecksumException {\r\n    int numCodewords = codewordBytes.length;\r\n    // First read into an array of ints\r\n    int[] codewordsInts = new int[numCodewords];\r\n    for (int i = 0; i < numCodewords; i++) {\r\n      codewordsInts[i] = codewordBytes[i] & 0xFF;\r\n    }\r\n    int numECCodewords = codewordBytes.length - numDataCodewords;\r\n    try {\r\n      rsDecoder.decode(codewordsInts, numECCodewords);\r\n    } catch (ReedSolomonException rse) {\r\n      throw ChecksumException.getChecksumInstance();\r\n    }\r\n    // Copy back into array of bytes -- only need to worry about the bytes that were data\r\n    // We don't care about errors in the error-correction codewords\r\n    for (int i = 0; i < numDataCodewords; i++) {\r\n      codewordBytes[i] = (byte) codewordsInts[i];\r\n    }\r\n  }\r\n\r\n}\r\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/datamatrix/decoder/Version.java",
    "content": "/*\r\n * Copyright 2007 ZXing authors\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage com.google.zxing.datamatrix.decoder;\r\n\r\nimport com.google.zxing.FormatException;\r\n\r\n/**\r\n * The Version object encapsulates attributes about a particular\r\n * size Data Matrix Code.\r\n *\r\n * @author bbrown@google.com (Brian Brown)\r\n */\r\npublic final class Version {\r\n\r\n  private static final Version[] VERSIONS = buildVersions();\r\n\r\n  private final int versionNumber;\r\n  private final int symbolSizeRows;\r\n  private final int symbolSizeColumns;\r\n  private final int dataRegionSizeRows;\r\n  private final int dataRegionSizeColumns;\r\n  private final ECBlocks ecBlocks;\r\n  private final int totalCodewords;\r\n\r\n  private Version(int versionNumber,\r\n                  int symbolSizeRows,\r\n                  int symbolSizeColumns,\r\n                  int dataRegionSizeRows,\r\n                  int dataRegionSizeColumns,\r\n                  ECBlocks ecBlocks) {\r\n    this.versionNumber = versionNumber;\r\n    this.symbolSizeRows = symbolSizeRows;\r\n    this.symbolSizeColumns = symbolSizeColumns;\r\n    this.dataRegionSizeRows = dataRegionSizeRows;\r\n    this.dataRegionSizeColumns = dataRegionSizeColumns;\r\n    this.ecBlocks = ecBlocks;\r\n    \r\n    // Calculate the total number of codewords\r\n    int total = 0;\r\n    int ecCodewords = ecBlocks.getECCodewords();\r\n    ECB[] ecbArray = ecBlocks.getECBlocks();\r\n    for (ECB ecBlock : ecbArray) {\r\n      total += ecBlock.getCount() * (ecBlock.getDataCodewords() + ecCodewords);\r\n    }\r\n    this.totalCodewords = total;\r\n  }\r\n\r\n  public int getVersionNumber() {\r\n    return versionNumber;\r\n  }\r\n\r\n  public int getSymbolSizeRows() {\r\n    return symbolSizeRows;\r\n  }\r\n  \r\n  public int getSymbolSizeColumns() {\r\n    return symbolSizeColumns;\r\n  }\r\n  \r\n  public int getDataRegionSizeRows() {\r\n    return dataRegionSizeRows;\r\n  }\r\n  \r\n  public int getDataRegionSizeColumns() {\r\n    return dataRegionSizeColumns;\r\n  }\r\n  \r\n  public int getTotalCodewords() {\r\n    return totalCodewords;\r\n  }\r\n  \r\n  ECBlocks getECBlocks() {\r\n    return ecBlocks;\r\n  }\r\n\r\n  /**\r\n   * <p>Deduces version information from Data Matrix dimensions.</p>\r\n   *\r\n   * @param numRows Number of rows in modules\r\n   * @param numColumns Number of columns in modules\r\n   * @return Version for a Data Matrix Code of those dimensions\r\n   * @throws FormatException if dimensions do correspond to a valid Data Matrix size\r\n   */\r\n  public static Version getVersionForDimensions(int numRows, int numColumns) throws FormatException {\r\n    if ((numRows & 0x01) != 0 || (numColumns & 0x01) != 0) {\r\n      throw FormatException.getFormatInstance();\r\n    }\r\n\r\n    for (Version version : VERSIONS) {\r\n      if (version.symbolSizeRows == numRows && version.symbolSizeColumns == numColumns) {\r\n        return version;\r\n      }\r\n    }\r\n    \r\n    throw FormatException.getFormatInstance();\r\n  }\r\n\r\n  /**\r\n   * <p>Encapsulates a set of error-correction blocks in one symbol version. Most versions will\r\n   * use blocks of differing sizes within one version, so, this encapsulates the parameters for\r\n   * each set of blocks. It also holds the number of error-correction codewords per block since it\r\n   * will be the same across all blocks within one version.</p>\r\n   */\r\n  static final class ECBlocks {\r\n    private final int ecCodewords;\r\n    private final ECB[] ecBlocks;\r\n\r\n    private ECBlocks(int ecCodewords, ECB ecBlocks) {\r\n      this.ecCodewords = ecCodewords;\r\n      this.ecBlocks = new ECB[] { ecBlocks };\r\n    }\r\n\r\n    private ECBlocks(int ecCodewords, ECB ecBlocks1, ECB ecBlocks2) {\r\n      this.ecCodewords = ecCodewords;\r\n      this.ecBlocks = new ECB[] { ecBlocks1, ecBlocks2 };\r\n    }\r\n\r\n    int getECCodewords() {\r\n      return ecCodewords;\r\n    }\r\n\r\n    ECB[] getECBlocks() {\r\n      return ecBlocks;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * <p>Encapsualtes the parameters for one error-correction block in one symbol version.\r\n   * This includes the number of data codewords, and the number of times a block with these\r\n   * parameters is used consecutively in the Data Matrix code version's format.</p>\r\n   */\r\n  static final class ECB {\r\n    private final int count;\r\n    private final int dataCodewords;\r\n\r\n    private ECB(int count, int dataCodewords) {\r\n      this.count = count;\r\n      this.dataCodewords = dataCodewords;\r\n    }\r\n\r\n    int getCount() {\r\n      return count;\r\n    }\r\n\r\n    int getDataCodewords() {\r\n      return dataCodewords;\r\n    }\r\n  }\r\n\r\n  @Override\r\n  public String toString() {\r\n    return String.valueOf(versionNumber);\r\n  }\r\n\r\n  /**\r\n   * See ISO 16022:2006 5.5.1 Table 7\r\n   */\r\n  private static Version[] buildVersions() {\r\n    return new Version[]{\r\n        new Version(1, 10, 10, 8, 8,\r\n            new ECBlocks(5, new ECB(1, 3))),\r\n        new Version(2, 12, 12, 10, 10,\r\n            new ECBlocks(7, new ECB(1, 5))),\r\n        new Version(3, 14, 14, 12, 12,\r\n            new ECBlocks(10, new ECB(1, 8))),\r\n        new Version(4, 16, 16, 14, 14,\r\n            new ECBlocks(12, new ECB(1, 12))),\r\n        new Version(5, 18, 18, 16, 16,\r\n            new ECBlocks(14, new ECB(1, 18))),\r\n        new Version(6, 20, 20, 18, 18,\r\n            new ECBlocks(18, new ECB(1, 22))),\r\n        new Version(7, 22, 22, 20, 20,\r\n            new ECBlocks(20, new ECB(1, 30))),\r\n        new Version(8, 24, 24, 22, 22,\r\n            new ECBlocks(24, new ECB(1, 36))),\r\n        new Version(9, 26, 26, 24, 24,\r\n            new ECBlocks(28, new ECB(1, 44))),\r\n        new Version(10, 32, 32, 14, 14,\r\n            new ECBlocks(36, new ECB(1, 62))),\r\n        new Version(11, 36, 36, 16, 16,\r\n            new ECBlocks(42, new ECB(1, 86))),\r\n        new Version(12, 40, 40, 18, 18,\r\n            new ECBlocks(48, new ECB(1, 114))),\r\n        new Version(13, 44, 44, 20, 20,\r\n            new ECBlocks(56, new ECB(1, 144))),\r\n        new Version(14, 48, 48, 22, 22,\r\n            new ECBlocks(68, new ECB(1, 174))),\r\n        new Version(15, 52, 52, 24, 24,\r\n            new ECBlocks(42, new ECB(2, 102))),\r\n        new Version(16, 64, 64, 14, 14,\r\n            new ECBlocks(56, new ECB(2, 140))),\r\n        new Version(17, 72, 72, 16, 16,\r\n            new ECBlocks(36, new ECB(4, 92))),\r\n        new Version(18, 80, 80, 18, 18,\r\n            new ECBlocks(48, new ECB(4, 114))),\r\n        new Version(19, 88, 88, 20, 20,\r\n            new ECBlocks(56, new ECB(4, 144))),\r\n        new Version(20, 96, 96, 22, 22,\r\n            new ECBlocks(68, new ECB(4, 174))),\r\n        new Version(21, 104, 104, 24, 24,\r\n            new ECBlocks(56, new ECB(6, 136))),\r\n        new Version(22, 120, 120, 18, 18,\r\n            new ECBlocks(68, new ECB(6, 175))),\r\n        new Version(23, 132, 132, 20, 20,\r\n            new ECBlocks(62, new ECB(8, 163))),\r\n        new Version(24, 144, 144, 22, 22,\r\n            new ECBlocks(62, new ECB(8, 156), new ECB(2, 155))),\r\n        new Version(25, 8, 18, 6, 16,\r\n            new ECBlocks(7, new ECB(1, 5))),\r\n        new Version(26, 8, 32, 6, 14,\r\n            new ECBlocks(11, new ECB(1, 10))),\r\n        new Version(27, 12, 26, 10, 24,\r\n            new ECBlocks(14, new ECB(1, 16))),\r\n        new Version(28, 12, 36, 10, 16,\r\n            new ECBlocks(18, new ECB(1, 22))),\r\n        new Version(29, 16, 36, 14, 16,\r\n            new ECBlocks(24, new ECB(1, 32))),\r\n        new Version(30, 16, 48, 14, 22,\r\n            new ECBlocks(28, new ECB(1, 49)))\r\n    };\r\n  }\r\n\r\n}\r\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/datamatrix/detector/Detector.java",
    "content": "/*\n * Copyright 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.datamatrix.detector;\n\nimport com.google.zxing.NotFoundException;\nimport com.google.zxing.ResultPoint;\nimport com.google.zxing.common.BitMatrix;\nimport com.google.zxing.common.DetectorResult;\nimport com.google.zxing.common.GridSampler;\nimport com.google.zxing.common.detector.MathUtils;\nimport com.google.zxing.common.detector.WhiteRectangleDetector;\n\nimport java.io.Serializable;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Comparator;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * <p>Encapsulates logic that can detect a Data Matrix Code in an image, even if the Data Matrix Code\n * is rotated or skewed, or partially obscured.</p>\n *\n * @author Sean Owen\n */\npublic final class Detector {\n\n  private final BitMatrix image;\n  private final WhiteRectangleDetector rectangleDetector;\n\n  public Detector(BitMatrix image) throws NotFoundException {\n    this.image = image;\n    rectangleDetector = new WhiteRectangleDetector(image);\n  }\n\n  /**\n   * <p>Detects a Data Matrix Code in an image.</p>\n   *\n   * @return {@link DetectorResult} encapsulating results of detecting a Data Matrix Code\n   * @throws NotFoundException if no Data Matrix Code can be found\n   */\n  public DetectorResult detect() throws NotFoundException {\n\n    ResultPoint[] cornerPoints = rectangleDetector.detect();\n    ResultPoint pointA = cornerPoints[0];\n    ResultPoint pointB = cornerPoints[1];\n    ResultPoint pointC = cornerPoints[2];\n    ResultPoint pointD = cornerPoints[3];\n\n    // Point A and D are across the diagonal from one another,\n    // as are B and C. Figure out which are the solid black lines\n    // by counting transitions\n    List<ResultPointsAndTransitions> transitions = new ArrayList<ResultPointsAndTransitions>(4);\n    transitions.add(transitionsBetween(pointA, pointB));\n    transitions.add(transitionsBetween(pointA, pointC));\n    transitions.add(transitionsBetween(pointB, pointD));\n    transitions.add(transitionsBetween(pointC, pointD));\n    Collections.sort(transitions, new ResultPointsAndTransitionsComparator());\n\n    // Sort by number of transitions. First two will be the two solid sides; last two\n    // will be the two alternating black/white sides\n    ResultPointsAndTransitions lSideOne = transitions.get(0);\n    ResultPointsAndTransitions lSideTwo = transitions.get(1);\n\n    // Figure out which point is their intersection by tallying up the number of times we see the\n    // endpoints in the four endpoints. One will show up twice.\n    Map<ResultPoint,Integer> pointCount = new HashMap<ResultPoint,Integer>();\n    increment(pointCount, lSideOne.getFrom());\n    increment(pointCount, lSideOne.getTo());\n    increment(pointCount, lSideTwo.getFrom());\n    increment(pointCount, lSideTwo.getTo());\n\n    ResultPoint maybeTopLeft = null;\n    ResultPoint bottomLeft = null;\n    ResultPoint maybeBottomRight = null;\n    for (Map.Entry<ResultPoint,Integer> entry : pointCount.entrySet()) {\n      ResultPoint point = entry.getKey();\n      Integer value = entry.getValue();\n      if (value == 2) {\n        bottomLeft = point; // this is definitely the bottom left, then -- end of two L sides\n      } else {\n        // Otherwise it's either top left or bottom right -- just assign the two arbitrarily now\n        if (maybeTopLeft == null) {\n          maybeTopLeft = point;\n        } else {\n          maybeBottomRight = point;\n        }\n      }\n    }\n\n    if (maybeTopLeft == null || bottomLeft == null || maybeBottomRight == null) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n\n    // Bottom left is correct but top left and bottom right might be switched\n    ResultPoint[] corners = { maybeTopLeft, bottomLeft, maybeBottomRight };\n    // Use the dot product trick to sort them out\n    ResultPoint.orderBestPatterns(corners);\n\n    // Now we know which is which:\n    ResultPoint bottomRight = corners[0];\n    bottomLeft = corners[1];\n    ResultPoint topLeft = corners[2];\n\n    // Which point didn't we find in relation to the \"L\" sides? that's the top right corner\n    ResultPoint topRight;\n    if (!pointCount.containsKey(pointA)) {\n      topRight = pointA;\n    } else if (!pointCount.containsKey(pointB)) {\n      topRight = pointB;\n    } else if (!pointCount.containsKey(pointC)) {\n      topRight = pointC;\n    } else {\n      topRight = pointD;\n    }\n\n    // Next determine the dimension by tracing along the top or right side and counting black/white\n    // transitions. Since we start inside a black module, we should see a number of transitions\n    // equal to 1 less than the code dimension. Well, actually 2 less, because we are going to\n    // end on a black module:\n\n    // The top right point is actually the corner of a module, which is one of the two black modules\n    // adjacent to the white module at the top right. Tracing to that corner from either the top left\n    // or bottom right should work here.\n    \n    int dimensionTop = transitionsBetween(topLeft, topRight).getTransitions();\n    int dimensionRight = transitionsBetween(bottomRight, topRight).getTransitions();\n    \n    if ((dimensionTop & 0x01) == 1) {\n      // it can't be odd, so, round... up?\n      dimensionTop++;\n    }\n    dimensionTop += 2;\n    \n    if ((dimensionRight & 0x01) == 1) {\n      // it can't be odd, so, round... up?\n      dimensionRight++;\n    }\n    dimensionRight += 2;\n\n    BitMatrix bits;\n    ResultPoint correctedTopRight;\n\n    // Rectanguar symbols are 6x16, 6x28, 10x24, 10x32, 14x32, or 14x44. If one dimension is more\n    // than twice the other, it's certainly rectangular, but to cut a bit more slack we accept it as\n    // rectangular if the bigger side is at least 7/4 times the other:\n    if (4 * dimensionTop >= 7 * dimensionRight || 4 * dimensionRight >= 7 * dimensionTop) {\n      // The matrix is rectangular\n\n      correctedTopRight =\n          correctTopRightRectangular(bottomLeft, bottomRight, topLeft, topRight, dimensionTop, dimensionRight);\n      if (correctedTopRight == null){\n        correctedTopRight = topRight;\n      }\n\n      dimensionTop = transitionsBetween(topLeft, correctedTopRight).getTransitions();\n      dimensionRight = transitionsBetween(bottomRight, correctedTopRight).getTransitions();\n\n      if ((dimensionTop & 0x01) == 1) {\n        // it can't be odd, so, round... up?\n        dimensionTop++;\n      }\n\n      if ((dimensionRight & 0x01) == 1) {\n        // it can't be odd, so, round... up?\n        dimensionRight++;\n      }\n\n      bits = sampleGrid(image, topLeft, bottomLeft, bottomRight, correctedTopRight, dimensionTop, dimensionRight);\n          \n    } else {\n      // The matrix is square\n        \n      int dimension = Math.min(dimensionRight, dimensionTop);\n      // correct top right point to match the white module\n      correctedTopRight = correctTopRight(bottomLeft, bottomRight, topLeft, topRight, dimension);\n      if (correctedTopRight == null){\n        correctedTopRight = topRight;\n      }\n\n      // Redetermine the dimension using the corrected top right point\n      int dimensionCorrected = Math.max(transitionsBetween(topLeft, correctedTopRight).getTransitions(),\n                                transitionsBetween(bottomRight, correctedTopRight).getTransitions());\n      dimensionCorrected++;\n      if ((dimensionCorrected & 0x01) == 1) {\n        dimensionCorrected++;\n      }\n\n      bits = sampleGrid(image,\n                        topLeft,\n                        bottomLeft,\n                        bottomRight,\n                        correctedTopRight,\n                        dimensionCorrected,\n                        dimensionCorrected);\n    }\n\n    return new DetectorResult(bits, new ResultPoint[]{topLeft, bottomLeft, bottomRight, correctedTopRight});\n  }\n\n  /**\n   * Calculates the position of the white top right module using the output of the rectangle detector\n   * for a rectangular matrix\n   */\n  private ResultPoint correctTopRightRectangular(ResultPoint bottomLeft,\n                                                 ResultPoint bottomRight,\n                                                 ResultPoint topLeft,\n                                                 ResultPoint topRight,\n                                                 int dimensionTop,\n                                                 int dimensionRight) {\n\n    float corr = distance(bottomLeft, bottomRight) / (float)dimensionTop;\n    int norm = distance(topLeft, topRight);\n    float cos = (topRight.getX() - topLeft.getX()) / norm;\n    float sin = (topRight.getY() - topLeft.getY()) / norm;\n\n    ResultPoint c1 = new ResultPoint(topRight.getX()+corr*cos, topRight.getY()+corr*sin);\n\n    corr = distance(bottomLeft, topLeft) / (float)dimensionRight;\n    norm = distance(bottomRight, topRight);\n    cos = (topRight.getX() - bottomRight.getX()) / norm;\n    sin = (topRight.getY() - bottomRight.getY()) / norm;\n\n    ResultPoint c2 = new ResultPoint(topRight.getX()+corr*cos, topRight.getY()+corr*sin);\n\n    if (!isValid(c1)) {\n      if (isValid(c2)) {\n        return c2;\n      }\n      return null;\n    }\n    if (!isValid(c2)){\n      return c1;\n    }\n\n    int l1 = Math.abs(dimensionTop - transitionsBetween(topLeft, c1).getTransitions()) +\n          Math.abs(dimensionRight - transitionsBetween(bottomRight, c1).getTransitions());\n    int l2 = Math.abs(dimensionTop - transitionsBetween(topLeft, c2).getTransitions()) +\n    Math.abs(dimensionRight - transitionsBetween(bottomRight, c2).getTransitions());\n\n    if (l1 <= l2){\n      return c1;\n    }\n\n    return c2;\n  }\n\n  /**\n   * Calculates the position of the white top right module using the output of the rectangle detector\n   * for a square matrix\n   */\n  private ResultPoint correctTopRight(ResultPoint bottomLeft,\n                                      ResultPoint bottomRight,\n                                      ResultPoint topLeft,\n                                      ResultPoint topRight,\n                                      int dimension) {\n\n    float corr = distance(bottomLeft, bottomRight) / (float) dimension;\n    int norm = distance(topLeft, topRight);\n    float cos = (topRight.getX() - topLeft.getX()) / norm;\n    float sin = (topRight.getY() - topLeft.getY()) / norm;\n\n    ResultPoint c1 = new ResultPoint(topRight.getX() + corr * cos, topRight.getY() + corr * sin);\n\n    corr = distance(bottomLeft, topLeft) / (float) dimension;\n    norm = distance(bottomRight, topRight);\n    cos = (topRight.getX() - bottomRight.getX()) / norm;\n    sin = (topRight.getY() - bottomRight.getY()) / norm;\n\n    ResultPoint c2 = new ResultPoint(topRight.getX() + corr * cos, topRight.getY() + corr * sin);\n\n    if (!isValid(c1)) {\n      if (isValid(c2)) {\n        return c2;\n      }\n      return null;\n    }\n    if (!isValid(c2)) {\n      return c1;\n    }\n\n    int l1 = Math.abs(transitionsBetween(topLeft, c1).getTransitions() -\n                      transitionsBetween(bottomRight, c1).getTransitions());\n    int l2 = Math.abs(transitionsBetween(topLeft, c2).getTransitions() -\n                      transitionsBetween(bottomRight, c2).getTransitions());\n\n    return l1 <= l2 ? c1 : c2;\n  }\n\n  private boolean isValid(ResultPoint p) {\n    return p.getX() >= 0 && p.getX() < image.getWidth() && p.getY() > 0 && p.getY() < image.getHeight();\n  }\n\n  private static int distance(ResultPoint a, ResultPoint b) {\n    return MathUtils.round(ResultPoint.distance(a, b));\n  }\n\n  /**\n   * Increments the Integer associated with a key by one.\n   */\n  private static void increment(Map<ResultPoint,Integer> table, ResultPoint key) {\n    Integer value = table.get(key);\n    table.put(key, value == null ? 1 : value + 1);\n  }\n\n  private static BitMatrix sampleGrid(BitMatrix image,\n                                      ResultPoint topLeft,\n                                      ResultPoint bottomLeft,\n                                      ResultPoint bottomRight,\n                                      ResultPoint topRight,\n                                      int dimensionX,\n                                      int dimensionY) throws NotFoundException {\n\n    GridSampler sampler = GridSampler.getInstance();\n\n    return sampler.sampleGrid(image,\n                              dimensionX,\n                              dimensionY,\n                              0.5f,\n                              0.5f,\n                              dimensionX - 0.5f,\n                              0.5f,\n                              dimensionX - 0.5f,\n                              dimensionY - 0.5f,\n                              0.5f,\n                              dimensionY - 0.5f,\n                              topLeft.getX(),\n                              topLeft.getY(),\n                              topRight.getX(),\n                              topRight.getY(),\n                              bottomRight.getX(),\n                              bottomRight.getY(),\n                              bottomLeft.getX(),\n                              bottomLeft.getY());\n  }\n\n  /**\n   * Counts the number of black/white transitions between two points, using something like Bresenham's algorithm.\n   */\n  private ResultPointsAndTransitions transitionsBetween(ResultPoint from, ResultPoint to) {\n    // See QR Code Detector, sizeOfBlackWhiteBlackRun()\n    int fromX = (int) from.getX();\n    int fromY = (int) from.getY();\n    int toX = (int) to.getX();\n    int toY = (int) to.getY();\n    boolean steep = Math.abs(toY - fromY) > Math.abs(toX - fromX);\n    if (steep) {\n      int temp = fromX;\n      fromX = fromY;\n      fromY = temp;\n      temp = toX;\n      toX = toY;\n      toY = temp;\n    }\n\n    int dx = Math.abs(toX - fromX);\n    int dy = Math.abs(toY - fromY);\n    int error = -dx >> 1;\n    int ystep = fromY < toY ? 1 : -1;\n    int xstep = fromX < toX ? 1 : -1;\n    int transitions = 0;\n    boolean inBlack = image.get(steep ? fromY : fromX, steep ? fromX : fromY);\n    for (int x = fromX, y = fromY; x != toX; x += xstep) {\n      boolean isBlack = image.get(steep ? y : x, steep ? x : y);\n      if (isBlack != inBlack) {\n        transitions++;\n        inBlack = isBlack;\n      }\n      error += dy;\n      if (error > 0) {\n        if (y == toY) {\n          break;\n        }\n        y += ystep;\n        error -= dx;\n      }\n    }\n    return new ResultPointsAndTransitions(from, to, transitions);\n  }\n\n  /**\n   * Simply encapsulates two points and a number of transitions between them.\n   */\n  private static final class ResultPointsAndTransitions {\n\n    private final ResultPoint from;\n    private final ResultPoint to;\n    private final int transitions;\n\n    private ResultPointsAndTransitions(ResultPoint from, ResultPoint to, int transitions) {\n      this.from = from;\n      this.to = to;\n      this.transitions = transitions;\n    }\n\n    ResultPoint getFrom() {\n      return from;\n    }\n\n    ResultPoint getTo() {\n      return to;\n    }\n\n    public int getTransitions() {\n      return transitions;\n    }\n    \n    @Override\n    public String toString() {\n      return from + \"/\" + to + '/' + transitions;\n    }\n  }\n\n  /**\n   * Orders ResultPointsAndTransitions by number of transitions, ascending.\n   */\n  private static final class ResultPointsAndTransitionsComparator\n      implements Comparator<ResultPointsAndTransitions>, Serializable {\n    @Override\n    public int compare(ResultPointsAndTransitions o1, ResultPointsAndTransitions o2) {\n      return o1.getTransitions() - o2.getTransitions();\n    }\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/maxicode/MaxiCodeReader.java",
    "content": "/*\n * Copyright 2011 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.maxicode;\n\nimport com.google.zxing.BarcodeFormat;\nimport com.google.zxing.BinaryBitmap;\nimport com.google.zxing.ChecksumException;\nimport com.google.zxing.DecodeHintType;\nimport com.google.zxing.FormatException;\nimport com.google.zxing.NotFoundException;\nimport com.google.zxing.Reader;\nimport com.google.zxing.Result;\nimport com.google.zxing.ResultMetadataType;\nimport com.google.zxing.ResultPoint;\nimport com.google.zxing.common.BitMatrix;\nimport com.google.zxing.common.DecoderResult;\nimport com.google.zxing.maxicode.decoder.Decoder;\n\nimport java.util.Map;\n\n/**\n * This implementation can detect and decode a MaxiCode in an image.\n */\npublic final class MaxiCodeReader implements Reader {\n\n  private static final ResultPoint[] NO_POINTS = new ResultPoint[0];\n  private static final int MATRIX_WIDTH = 30;\n  private static final int MATRIX_HEIGHT = 33;\n\n  private final Decoder decoder = new Decoder();\n\n  Decoder getDecoder() {\n    return decoder;\n  }\n\n  /**\n   * Locates and decodes a MaxiCode in an image.\n   *\n   * @return a String representing the content encoded by the MaxiCode\n   * @throws NotFoundException if a MaxiCode cannot be found\n   * @throws FormatException if a MaxiCode cannot be decoded\n   * @throws ChecksumException if error correction fails\n   */\n  @Override\n  public Result decode(BinaryBitmap image) throws NotFoundException, ChecksumException, FormatException {\n    return decode(image, null);\n  }\n\n  @Override\n  public Result decode(BinaryBitmap image, Map<DecodeHintType,?> hints)\n      throws NotFoundException, ChecksumException, FormatException {\n    DecoderResult decoderResult;\n    if (hints != null && hints.containsKey(DecodeHintType.PURE_BARCODE)) {\n      BitMatrix bits = extractPureBits(image.getBlackMatrix());\n      decoderResult = decoder.decode(bits, hints);\n    } else {\n      throw NotFoundException.getNotFoundInstance();\n    }\n\n    ResultPoint[] points = NO_POINTS;\n    Result result = new Result(decoderResult.getText(), decoderResult.getRawBytes(), points, BarcodeFormat.MAXICODE);\n\n    String ecLevel = decoderResult.getECLevel();\n    if (ecLevel != null) {\n      result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, ecLevel);\n    }\n    return result;\n  }\n\n  @Override\n  public void reset() {\n    // do nothing\n  }\n\n  /**\n   * This method detects a code in a \"pure\" image -- that is, pure monochrome image\n   * which contains only an unrotated, unskewed, image of a code, with some white border\n   * around it. This is a specialized method that works exceptionally fast in this special\n   * case.\n   *\n   * @see com.google.zxing.pdf417.PDF417Reader#extractPureBits(BitMatrix)\n   * @see com.google.zxing.datamatrix.DataMatrixReader#extractPureBits(BitMatrix)\n   * @see com.google.zxing.qrcode.QRCodeReader#extractPureBits(BitMatrix)\n   */\n  private static BitMatrix extractPureBits(BitMatrix image) throws NotFoundException {\n    \n    int[] enclosingRectangle = image.getEnclosingRectangle();\n    if (enclosingRectangle == null) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n    \n    int left = enclosingRectangle[0];\n    int top = enclosingRectangle[1];\n    int width = enclosingRectangle[2];\n    int height = enclosingRectangle[3];\n\n    // Now just read off the bits\n    BitMatrix bits = new BitMatrix(MATRIX_WIDTH, MATRIX_HEIGHT);\n    for (int y = 0; y < MATRIX_HEIGHT; y++) {\n      int iy = top + (y * height + height / 2) / MATRIX_HEIGHT;\n      for (int x = 0; x < MATRIX_WIDTH; x++) {\n        int ix = left + (x * width + width / 2 + (y & 0x01) *  width / 2) / MATRIX_WIDTH;\n        if (image.get(ix, iy)) {\n          bits.set(x, y);\n        }\n      }\n    }\n    return bits;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/maxicode/decoder/BitMatrixParser.java",
    "content": "/*\n * Copyright 2011 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.maxicode.decoder;\n\nimport com.google.zxing.common.BitMatrix;\n\n/**\n * @author mike32767\n * @author Manuel Kasten\n */\nfinal class BitMatrixParser {\n\n  private static final int[][] BITNR = {\n    {121,120,127,126,133,132,139,138,145,144,151,150,157,156,163,162,169,168,175,174,181,180,187,186,193,192,199,198, -2, -2},\n    {123,122,129,128,135,134,141,140,147,146,153,152,159,158,165,164,171,170,177,176,183,182,189,188,195,194,201,200,816, -3},\n    {125,124,131,130,137,136,143,142,149,148,155,154,161,160,167,166,173,172,179,178,185,184,191,190,197,196,203,202,818,817},\n    {283,282,277,276,271,270,265,264,259,258,253,252,247,246,241,240,235,234,229,228,223,222,217,216,211,210,205,204,819, -3},\n    {285,284,279,278,273,272,267,266,261,260,255,254,249,248,243,242,237,236,231,230,225,224,219,218,213,212,207,206,821,820},\n    {287,286,281,280,275,274,269,268,263,262,257,256,251,250,245,244,239,238,233,232,227,226,221,220,215,214,209,208,822, -3},\n    {289,288,295,294,301,300,307,306,313,312,319,318,325,324,331,330,337,336,343,342,349,348,355,354,361,360,367,366,824,823},\n    {291,290,297,296,303,302,309,308,315,314,321,320,327,326,333,332,339,338,345,344,351,350,357,356,363,362,369,368,825, -3},\n    {293,292,299,298,305,304,311,310,317,316,323,322,329,328,335,334,341,340,347,346,353,352,359,358,365,364,371,370,827,826},\n    {409,408,403,402,397,396,391,390, 79, 78, -2, -2, 13, 12, 37, 36,  2, -1, 44, 43,109,108,385,384,379,378,373,372,828, -3},\n    {411,410,405,404,399,398,393,392, 81, 80, 40, -2, 15, 14, 39, 38,  3, -1, -1, 45,111,110,387,386,381,380,375,374,830,829},\n    {413,412,407,406,401,400,395,394, 83, 82, 41, -3, -3, -3, -3, -3,  5,  4, 47, 46,113,112,389,388,383,382,377,376,831, -3},\n    {415,414,421,420,427,426,103,102, 55, 54, 16, -3, -3, -3, -3, -3, -3, -3, 20, 19, 85, 84,433,432,439,438,445,444,833,832},\n    {417,416,423,422,429,428,105,104, 57, 56, -3, -3, -3, -3, -3, -3, -3, -3, 22, 21, 87, 86,435,434,441,440,447,446,834, -3},\n    {419,418,425,424,431,430,107,106, 59, 58, -3, -3, -3, -3, -3, -3, -3, -3, -3, 23, 89, 88,437,436,443,442,449,448,836,835},\n    {481,480,475,474,469,468, 48, -2, 30, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,  0, 53, 52,463,462,457,456,451,450,837, -3},\n    {483,482,477,476,471,470, 49, -1, -2, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -2, -1,465,464,459,458,453,452,839,838},\n    {485,484,479,478,473,472, 51, 50, 31, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,  1, -2, 42,467,466,461,460,455,454,840, -3},\n    {487,486,493,492,499,498, 97, 96, 61, 60, -3, -3, -3, -3, -3, -3, -3, -3, -3, 26, 91, 90,505,504,511,510,517,516,842,841},\n    {489,488,495,494,501,500, 99, 98, 63, 62, -3, -3, -3, -3, -3, -3, -3, -3, 28, 27, 93, 92,507,506,513,512,519,518,843, -3},\n    {491,490,497,496,503,502,101,100, 65, 64, 17, -3, -3, -3, -3, -3, -3, -3, 18, 29, 95, 94,509,508,515,514,521,520,845,844},\n    {559,558,553,552,547,546,541,540, 73, 72, 32, -3, -3, -3, -3, -3, -3, 10, 67, 66,115,114,535,534,529,528,523,522,846, -3},\n    {561,560,555,554,549,548,543,542, 75, 74, -2, -1,  7,  6, 35, 34, 11, -2, 69, 68,117,116,537,536,531,530,525,524,848,847},\n    {563,562,557,556,551,550,545,544, 77, 76, -2, 33,  9,  8, 25, 24, -1, -2, 71, 70,119,118,539,538,533,532,527,526,849, -3},\n    {565,564,571,570,577,576,583,582,589,588,595,594,601,600,607,606,613,612,619,618,625,624,631,630,637,636,643,642,851,850},\n    {567,566,573,572,579,578,585,584,591,590,597,596,603,602,609,608,615,614,621,620,627,626,633,632,639,638,645,644,852, -3},\n    {569,568,575,574,581,580,587,586,593,592,599,598,605,604,611,610,617,616,623,622,629,628,635,634,641,640,647,646,854,853},\n    {727,726,721,720,715,714,709,708,703,702,697,696,691,690,685,684,679,678,673,672,667,666,661,660,655,654,649,648,855, -3},\n    {729,728,723,722,717,716,711,710,705,704,699,698,693,692,687,686,681,680,675,674,669,668,663,662,657,656,651,650,857,856},\n    {731,730,725,724,719,718,713,712,707,706,701,700,695,694,689,688,683,682,677,676,671,670,665,664,659,658,653,652,858, -3},\n    {733,732,739,738,745,744,751,750,757,756,763,762,769,768,775,774,781,780,787,786,793,792,799,798,805,804,811,810,860,859},\n    {735,734,741,740,747,746,753,752,759,758,765,764,771,770,777,776,783,782,789,788,795,794,801,800,807,806,813,812,861, -3},\n    {737,736,743,742,749,748,755,754,761,760,767,766,773,772,779,778,785,784,791,790,797,796,803,802,809,808,815,814,863,862}\n  };\n\n  private final BitMatrix bitMatrix;\n\n  /**\n   * @param bitMatrix {@link BitMatrix} to parse\n   */\n  BitMatrixParser(BitMatrix bitMatrix) {\n    this.bitMatrix = bitMatrix;\n  }\n\n  byte[] readCodewords() {\n    byte[] result = new byte[144];\n    int height = bitMatrix.getHeight();\n    int width = bitMatrix.getWidth();\n    for (int y = 0; y < height; y++) {\n      int[] bitnrRow = BITNR[y];\n      for (int x = 0; x < width; x++) {\n        int bit = bitnrRow[x];\n        if (bit >= 0 && bitMatrix.get(x, y)) {\n          result[bit / 6] |= (byte) (1 << (5 - (bit % 6)));\n        }\n      }\n    }\n    return result;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/maxicode/decoder/DecodedBitStreamParser.java",
    "content": "/*\n * Copyright 2011 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.maxicode.decoder;\n\nimport com.google.zxing.common.DecoderResult;\nimport java.text.DecimalFormat;\nimport java.text.NumberFormat;\n\n/**\n * <p>MaxiCodes can encode text or structured information as bits in one of several modes,\n * with multiple character sets in one code. This class decodes the bits back into text.</p>\n *\n * @author mike32767\n * @author Manuel Kasten\n */\nfinal class DecodedBitStreamParser {\n\n  private static final char SHIFTA = '\\uFFF0';\n  private static final char SHIFTB = '\\uFFF1';\n  private static final char SHIFTC = '\\uFFF2';\n  private static final char SHIFTD = '\\uFFF3';\n  private static final char SHIFTE = '\\uFFF4';\n  private static final char TWOSHIFTA = '\\uFFF5';\n  private static final char THREESHIFTA = '\\uFFF6';\n  private static final char LATCHA = '\\uFFF7';\n  private static final char LATCHB = '\\uFFF8';\n  private static final char LOCK = '\\uFFF9';\n  private static final char ECI = '\\uFFFA';\n  private static final char NS = '\\uFFFB';\n  private static final char PAD = '\\uFFFC';\n  private static final char FS = '\\u001C';\n  private static final char GS = '\\u001D';\n  private static final char RS = '\\u001E';\n  private static final NumberFormat NINE_DIGITS = new DecimalFormat(\"000000000\");\n  private static final NumberFormat THREE_DIGITS = new DecimalFormat(\"000\");\n\n  private static final String[] SETS = {\n    \"\\nABCDEFGHIJKLMNOPQRSTUVWXYZ\"+ECI+FS+GS+RS+NS+' '+PAD+\"\\\"#$%&'()*+,-./0123456789:\"+SHIFTB+SHIFTC+SHIFTD+SHIFTE+LATCHB,\n    \"`abcdefghijklmnopqrstuvwxyz\"+ECI+FS+GS+RS+NS+'{'+PAD+\"}~\\u007F;<=>?[\\\\]^_ ,./:@!|\"+PAD+TWOSHIFTA+THREESHIFTA+PAD+SHIFTA+SHIFTC+SHIFTD+SHIFTE+LATCHA,\n    \"\\u00C0\\u00C1\\u00C2\\u00C3\\u00C4\\u00C5\\u00C6\\u00C7\\u00C8\\u00C9\\u00CA\\u00CB\\u00CC\\u00CD\\u00CE\\u00CF\\u00D0\\u00D1\\u00D2\\u00D3\\u00D4\\u00D5\\u00D6\\u00D7\\u00D8\\u00D9\\u00DA\"+ECI+FS+GS+RS+\"\\u00DB\\u00DC\\u00DD\\u00DE\\u00DF\\u00AA\\u00AC\\u00B1\\u00B2\\u00B3\\u00B5\\u00B9\\u00BA\\u00BC\\u00BD\\u00BE\\u0080\\u0081\\u0082\\u0083\\u0084\\u0085\\u0086\\u0087\\u0088\\u0089\"+LATCHA+' '+LOCK+SHIFTD+SHIFTE+LATCHB,\n    \"\\u00E0\\u00E1\\u00E2\\u00E3\\u00E4\\u00E5\\u00E6\\u00E7\\u00E8\\u00E9\\u00EA\\u00EB\\u00EC\\u00ED\\u00EE\\u00EF\\u00F0\\u00F1\\u00F2\\u00F3\\u00F4\\u00F5\\u00F6\\u00F7\\u00F8\\u00F9\\u00FA\"+ECI+FS+GS+RS+NS+\"\\u00FB\\u00FC\\u00FD\\u00FE\\u00FF\\u00A1\\u00A8\\u00AB\\u00AF\\u00B0\\u00B4\\u00B7\\u00B8\\u00BB\\u00BF\\u008A\\u008B\\u008C\\u008D\\u008E\\u008F\\u0090\\u0091\\u0092\\u0093\\u0094\"+LATCHA+' '+SHIFTC+LOCK+SHIFTE+LATCHB,\n    \"\\u0000\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007\\u0008\\u0009\\n\\u000B\\u000C\\r\\u000E\\u000F\\u0010\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017\\u0018\\u0019\\u001A\"+ECI+PAD+PAD+'\\u001B'+NS+FS+GS+RS+\"\\u001F\\u009F\\u00A0\\u00A2\\u00A3\\u00A4\\u00A5\\u00A6\\u00A7\\u00A9\\u00AD\\u00AE\\u00B6\\u0095\\u0096\\u0097\\u0098\\u0099\\u009A\\u009B\\u009C\\u009D\\u009E\"+LATCHA+' '+SHIFTC+SHIFTD+LOCK+LATCHB,\n    \"\\u0000\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007\\u0008\\u0009\\n\\u000B\\u000C\\r\\u000E\\u000F\\u0010\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017\\u0018\\u0019\\u001A\\u001B\\u001C\\u001D\\u001E\\u001F\\u0020\\u0021\\\"\\u0023\\u0024\\u0025\\u0026\\u0027\\u0028\\u0029\\u002A\\u002B\\u002C\\u002D\\u002E\\u002F\\u0030\\u0031\\u0032\\u0033\\u0034\\u0035\\u0036\\u0037\\u0038\\u0039\\u003A\\u003B\\u003C\\u003D\\u003E\\u003F\"\n  };\n\n  private DecodedBitStreamParser() {\n  }\n\n  static DecoderResult decode(byte[] bytes, int mode) {\n    StringBuilder result = new StringBuilder(144);\n    switch (mode) {\n      case 2:\n      case 3:\n        String postcode;\n        if (mode == 2) {\n          int pc = getPostCode2(bytes);\n          NumberFormat df = new DecimalFormat(\"0000000000\".substring(0, getPostCode2Length(bytes)));\n          postcode = df.format(pc);\n        } else {\n          postcode = getPostCode3(bytes);\n        }\n        String country = THREE_DIGITS.format(getCountry(bytes));\n        String service = THREE_DIGITS.format(getServiceClass(bytes));\n        result.append(getMessage(bytes, 10, 84));\n        if (result.toString().startsWith(\"[)>\"+RS+\"01\"+GS)) {\n          result.insert(9, postcode + GS + country + GS + service + GS);\n        } else {\n          result.insert(0, postcode + GS + country + GS + service + GS);\n        }\n        break;\n      case 4:\n        result.append(getMessage(bytes, 1, 93));\n        break;\n      case 5:\n        result.append(getMessage(bytes, 1, 77));\n        break;\n    }\n    return new DecoderResult(bytes, result.toString(), null, String.valueOf(mode));\n  }\n\n  private static int getBit(int bit, byte[] bytes) {\n    bit--;\n    return (bytes[bit / 6] & (1 << (5 - (bit % 6)))) == 0 ? 0 : 1;\n  }\n\n  private static int getInt(byte[] bytes, byte[] x) {\n    int val = 0;\n    for (int i = 0; i < x.length; i++) {\n      val += getBit(x[i], bytes) << (x.length - i - 1);\n    }\n    return val;\n  }\n\n  private static int getCountry(byte[] bytes) {\n    return getInt(bytes, new byte[] {53, 54, 43, 44, 45, 46, 47, 48, 37, 38});\n  }\n\n  private static int getServiceClass(byte[] bytes) {\n    return getInt(bytes, new byte[] {55, 56, 57, 58, 59, 60, 49, 50, 51, 52});\n  }\n\n  private static int getPostCode2Length(byte[] bytes) {\n    return getInt(bytes, new byte[] {39, 40, 41, 42, 31, 32});\n  }\n\n  private static int getPostCode2(byte[] bytes) {\n    return getInt(bytes, new byte[] {33, 34, 35, 36, 25, 26, 27, 28, 29, 30, 19,\n        20, 21, 22, 23, 24, 13, 14, 15, 16, 17, 18, 7, 8, 9, 10, 11, 12, 1, 2});\n  }\n\n  private static String getPostCode3(byte[] bytes) {\n    return String.valueOf(\n       new char[] {\n         SETS[0].charAt(getInt(bytes, new byte[] {39, 40, 41, 42, 31, 32})),\n         SETS[0].charAt(getInt(bytes, new byte[] {33, 34, 35, 36, 25, 26})),\n         SETS[0].charAt(getInt(bytes, new byte[] {27, 28, 29, 30, 19, 20})),\n         SETS[0].charAt(getInt(bytes, new byte[] {21, 22, 23, 24, 13, 14})),\n         SETS[0].charAt(getInt(bytes, new byte[] {15, 16, 17, 18,  7,  8})),\n         SETS[0].charAt(getInt(bytes, new byte[] { 9, 10, 11, 12,  1,  2})),\n       }\n    );\n  }\n\n  private static String getMessage(byte[] bytes, int start, int len) {\n    StringBuilder sb = new StringBuilder();\n    int shift = -1;\n    int set = 0;\n    int lastset = 0;\n    for (int i = start; i < start + len; i++) {\n      char c = SETS[set].charAt(bytes[i]);\n      switch (c) {\n        case LATCHA:\n          set = 0;\n          shift = -1;\n          break;\n        case LATCHB:\n          set = 1;\n          shift = -1;\n          break;\n        case SHIFTA:\n        case SHIFTB:\n        case SHIFTC:\n        case SHIFTD:\n        case SHIFTE:\n          lastset = set;\n          set = c - SHIFTA;\n          shift = 1;\n          break;\n        case TWOSHIFTA:\n          lastset = set;\n          set = 0;\n          shift = 2;\n          break;\n        case THREESHIFTA:\n          lastset = set;\n          set = 0;\n          shift = 3;\n          break;\n        case NS:\n          int nsval = (bytes[++i] << 24) + (bytes[++i] << 18) + (bytes[++i] << 12) + (bytes[++i] << 6) + bytes[++i];\n          sb.append(NINE_DIGITS.format(nsval));\n          break;\n        case LOCK:\n          shift = -1;\n          break;\n        default:\n          sb.append(c);\n      }\n      if (shift-- == 0) {\n        set = lastset;\n      }\n    }\n    while (sb.length() > 0 && sb.charAt(sb.length() - 1) == PAD) {\n      sb.setLength(sb.length() - 1);\n    }\n    return sb.toString();\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/maxicode/decoder/Decoder.java",
    "content": "/*\n * Copyright 2011 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.maxicode.decoder;\n\nimport com.google.zxing.ChecksumException;\nimport com.google.zxing.DecodeHintType;\nimport com.google.zxing.FormatException;\nimport com.google.zxing.common.BitMatrix;\nimport com.google.zxing.common.DecoderResult;\nimport com.google.zxing.common.reedsolomon.GenericGF;\nimport com.google.zxing.common.reedsolomon.ReedSolomonDecoder;\nimport com.google.zxing.common.reedsolomon.ReedSolomonException;\n\nimport java.util.Map;\n\n/**\n * <p>The main class which implements MaxiCode decoding -- as opposed to locating and extracting\n * the MaxiCode from an image.</p>\n *\n * @author Manuel Kasten\n */\npublic final class Decoder {\n\n  private static final int ALL = 0;\n  private static final int EVEN = 1;\n  private static final int ODD = 2;\n\n  private final ReedSolomonDecoder rsDecoder;\n\n  public Decoder() {\n    rsDecoder = new ReedSolomonDecoder(GenericGF.MAXICODE_FIELD_64);\n  }\n\n  public DecoderResult decode(BitMatrix bits) throws ChecksumException, FormatException {\n    return decode(bits, null);\n  }\n\n  public DecoderResult decode(BitMatrix bits,\n                              Map<DecodeHintType,?> hints) throws FormatException, ChecksumException {\n    BitMatrixParser parser = new BitMatrixParser(bits);\n    byte[] codewords = parser.readCodewords();\n\n    correctErrors(codewords, 0, 10, 10, ALL);\n    int mode = codewords[0] & 0x0F;\n    byte[] datawords;\n    switch (mode) {\n      case 2:\n      case 3:\n      case 4:\n        correctErrors(codewords, 20, 84, 40, EVEN);\n        correctErrors(codewords, 20, 84, 40, ODD);\n        datawords = new byte[94];\n        break;\n      case 5:\n        correctErrors(codewords, 20, 68, 56, EVEN);\n        correctErrors(codewords, 20, 68, 56, ODD);\n        datawords = new byte[78];\n        break;\n      default:\n        throw FormatException.getFormatInstance();\n    }\n\n    System.arraycopy(codewords, 0, datawords, 0, 10);\n    System.arraycopy(codewords, 20, datawords, 10, datawords.length - 10);\n\n    return DecodedBitStreamParser.decode(datawords, mode);\n  }\n\n  private void correctErrors(byte[] codewordBytes,\n                             int start,\n                             int dataCodewords,\n                             int ecCodewords,\n                             int mode) throws ChecksumException {\n    int codewords = dataCodewords + ecCodewords;\n\n    // in EVEN or ODD mode only half the codewords\n    int divisor = mode == ALL ? 1 : 2;\n\n    // First read into an array of ints\n    int[] codewordsInts = new int[codewords / divisor];\n    for (int i = 0; i < codewords; i++) {\n      if ((mode == ALL) || (i % 2 == (mode - 1))) {\n        codewordsInts[i / divisor] = codewordBytes[i + start] & 0xFF;\n      }\n    }\n    try {\n      rsDecoder.decode(codewordsInts, ecCodewords / divisor);\n    } catch (ReedSolomonException rse) {\n      throw ChecksumException.getChecksumInstance();\n    }\n    // Copy back into array of bytes -- only need to worry about the bytes that were data\n    // We don't care about errors in the error-correction codewords\n    for (int i = 0; i < dataCodewords; i++) {\n      if ((mode == ALL) || (i % 2 == (mode - 1))) {\n        codewordBytes[i + start] = (byte) codewordsInts[i / divisor];\n      }\n    }\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/multi/ByQuadrantReader.java",
    "content": "/*\n * Copyright 2009 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.multi;\n\nimport com.google.zxing.BinaryBitmap;\nimport com.google.zxing.ChecksumException;\nimport com.google.zxing.DecodeHintType;\nimport com.google.zxing.FormatException;\nimport com.google.zxing.NotFoundException;\nimport com.google.zxing.Reader;\nimport com.google.zxing.Result;\n\nimport java.util.Map;\n\n/**\n * This class attempts to decode a barcode from an image, not by scanning the whole image,\n * but by scanning subsets of the image. This is important when there may be multiple barcodes in\n * an image, and detecting a barcode may find parts of multiple barcode and fail to decode\n * (e.g. QR Codes). Instead this scans the four quadrants of the image -- and also the center\n * 'quadrant' to cover the case where a barcode is found in the center.\n *\n * @see GenericMultipleBarcodeReader\n */\npublic final class ByQuadrantReader implements Reader {\n\n  private final Reader delegate;\n\n  public ByQuadrantReader(Reader delegate) {\n    this.delegate = delegate;\n  }\n\n  @Override\n  public Result decode(BinaryBitmap image)\n      throws NotFoundException, ChecksumException, FormatException {\n    return decode(image, null);\n  }\n\n  @Override\n  public Result decode(BinaryBitmap image, Map<DecodeHintType,?> hints)\n      throws NotFoundException, ChecksumException, FormatException {\n\n    int width = image.getWidth();\n    int height = image.getHeight();\n    int halfWidth = width / 2;\n    int halfHeight = height / 2;\n\n    BinaryBitmap topLeft = image.crop(0, 0, halfWidth, halfHeight);\n    try {\n      return delegate.decode(topLeft, hints);\n    } catch (NotFoundException re) {\n      // continue\n    }\n\n    BinaryBitmap topRight = image.crop(halfWidth, 0, halfWidth, halfHeight);\n    try {\n      return delegate.decode(topRight, hints);\n    } catch (NotFoundException re) {\n      // continue\n    }\n\n    BinaryBitmap bottomLeft = image.crop(0, halfHeight, halfWidth, halfHeight);\n    try {\n      return delegate.decode(bottomLeft, hints);\n    } catch (NotFoundException re) {\n      // continue\n    }\n\n    BinaryBitmap bottomRight = image.crop(halfWidth, halfHeight, halfWidth, halfHeight);\n    try {\n      return delegate.decode(bottomRight, hints);\n    } catch (NotFoundException re) {\n      // continue\n    }\n\n    int quarterWidth = halfWidth / 2;\n    int quarterHeight = halfHeight / 2;\n    BinaryBitmap center = image.crop(quarterWidth, quarterHeight, halfWidth, halfHeight);\n    return delegate.decode(center, hints);\n  }\n\n  @Override\n  public void reset() {\n    delegate.reset();\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/multi/GenericMultipleBarcodeReader.java",
    "content": "/*\n * Copyright 2009 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.multi;\n\nimport com.google.zxing.BinaryBitmap;\nimport com.google.zxing.DecodeHintType;\nimport com.google.zxing.NotFoundException;\nimport com.google.zxing.Reader;\nimport com.google.zxing.ReaderException;\nimport com.google.zxing.Result;\nimport com.google.zxing.ResultPoint;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * <p>Attempts to locate multiple barcodes in an image by repeatedly decoding portion of the image.\n * After one barcode is found, the areas left, above, right and below the barcode's\n * {@link ResultPoint}s are scanned, recursively.</p>\n *\n * <p>A caller may want to also employ {@link ByQuadrantReader} when attempting to find multiple\n * 2D barcodes, like QR Codes, in an image, where the presence of multiple barcodes might prevent\n * detecting any one of them.</p>\n *\n * <p>That is, instead of passing a {@link Reader} a caller might pass\n * {@code new ByQuadrantReader(reader)}.</p>\n *\n * @author Sean Owen\n */\npublic final class GenericMultipleBarcodeReader implements MultipleBarcodeReader {\n\n  private static final int MIN_DIMENSION_TO_RECUR = 100;\n\n  private final Reader delegate;\n\n  public GenericMultipleBarcodeReader(Reader delegate) {\n    this.delegate = delegate;\n  }\n\n  @Override\n  public Result[] decodeMultiple(BinaryBitmap image) throws NotFoundException {\n    return decodeMultiple(image, null);\n  }\n\n  @Override\n  public Result[] decodeMultiple(BinaryBitmap image, Map<DecodeHintType,?> hints)\n      throws NotFoundException {\n    List<Result> results = new ArrayList<Result>();\n    doDecodeMultiple(image, hints, results, 0, 0);\n    if (results.isEmpty()) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n    return results.toArray(new Result[results.size()]);\n  }\n\n  private void doDecodeMultiple(BinaryBitmap image,\n                                Map<DecodeHintType,?> hints,\n                                List<Result> results,\n                                int xOffset,\n                                int yOffset) {\n    Result result;\n    try {\n      result = delegate.decode(image, hints);\n    } catch (ReaderException re) {\n      return;\n    }\n    boolean alreadyFound = false;\n    for (Result existingResult : results) {\n      if (existingResult.getText().equals(result.getText())) {\n        alreadyFound = true;\n        break;\n      }\n    }\n    if (alreadyFound) {\n      return;\n    }\n    results.add(translateResultPoints(result, xOffset, yOffset));\n    ResultPoint[] resultPoints = result.getResultPoints();\n    if (resultPoints == null || resultPoints.length == 0) {\n      return;\n    }\n    int width = image.getWidth();\n    int height = image.getHeight();\n    float minX = width;\n    float minY = height;\n    float maxX = 0.0f;\n    float maxY = 0.0f;\n    for (ResultPoint point : resultPoints) {\n      float x = point.getX();\n      float y = point.getY();\n      if (x < minX) {\n        minX = x;\n      }\n      if (y < minY) {\n        minY = y;\n      }\n      if (x > maxX) {\n        maxX = x;\n      }\n      if (y > maxY) {\n        maxY = y;\n      }\n    }\n\n    // Decode left of barcode\n    if (minX > MIN_DIMENSION_TO_RECUR) {\n      doDecodeMultiple(image.crop(0, 0, (int) minX, height),\n                       hints, results, xOffset, yOffset);\n    }\n    // Decode above barcode\n    if (minY > MIN_DIMENSION_TO_RECUR) {\n      doDecodeMultiple(image.crop(0, 0, width, (int) minY),\n                       hints, results, xOffset, yOffset);\n    }\n    // Decode right of barcode\n    if (maxX < width - MIN_DIMENSION_TO_RECUR) {\n      doDecodeMultiple(image.crop((int) maxX, 0, width - (int) maxX, height),\n                       hints, results, xOffset + (int) maxX, yOffset);\n    }\n    // Decode below barcode\n    if (maxY < height - MIN_DIMENSION_TO_RECUR) {\n      doDecodeMultiple(image.crop(0, (int) maxY, width, height - (int) maxY),\n                       hints, results, xOffset, yOffset + (int) maxY);\n    }\n  }\n\n  private static Result translateResultPoints(Result result, int xOffset, int yOffset) {\n    ResultPoint[] oldResultPoints = result.getResultPoints();\n    if (oldResultPoints == null) {\n      return result;\n    }\n    ResultPoint[] newResultPoints = new ResultPoint[oldResultPoints.length];\n    for (int i = 0; i < oldResultPoints.length; i++) {\n      ResultPoint oldPoint = oldResultPoints[i];\n      newResultPoints[i] = new ResultPoint(oldPoint.getX() + xOffset, oldPoint.getY() + yOffset);\n    }\n    return new Result(result.getText(), result.getRawBytes(), newResultPoints,\n        result.getBarcodeFormat());\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/multi/MultipleBarcodeReader.java",
    "content": "/*\n * Copyright 2009 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.multi;\n\nimport com.google.zxing.BinaryBitmap;\nimport com.google.zxing.DecodeHintType;\nimport com.google.zxing.NotFoundException;\nimport com.google.zxing.Result;\n\nimport java.util.Map;\n\n/**\n * Implementation of this interface attempt to read several barcodes from one image.\n *\n * @see com.google.zxing.Reader\n * @author Sean Owen\n */\npublic interface MultipleBarcodeReader {\n\n  Result[] decodeMultiple(BinaryBitmap image) throws NotFoundException;\n\n  Result[] decodeMultiple(BinaryBitmap image,\n                          Map<DecodeHintType,?> hints) throws NotFoundException;\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/multi/qrcode/QRCodeMultiReader.java",
    "content": "/*\n * Copyright 2009 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.multi.qrcode;\n\nimport com.google.zxing.BarcodeFormat;\nimport com.google.zxing.BinaryBitmap;\nimport com.google.zxing.DecodeHintType;\nimport com.google.zxing.NotFoundException;\nimport com.google.zxing.ReaderException;\nimport com.google.zxing.Result;\nimport com.google.zxing.ResultMetadataType;\nimport com.google.zxing.ResultPoint;\nimport com.google.zxing.common.DecoderResult;\nimport com.google.zxing.common.DetectorResult;\nimport com.google.zxing.multi.MultipleBarcodeReader;\nimport com.google.zxing.multi.qrcode.detector.MultiDetector;\nimport com.google.zxing.qrcode.QRCodeReader;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * This implementation can detect and decode multiple QR Codes in an image.\n *\n * @author Sean Owen\n * @author Hannes Erven\n */\npublic final class QRCodeMultiReader extends QRCodeReader implements MultipleBarcodeReader {\n\n  private static final Result[] EMPTY_RESULT_ARRAY = new Result[0];\n\n  @Override\n  public Result[] decodeMultiple(BinaryBitmap image) throws NotFoundException {\n    return decodeMultiple(image, null);\n  }\n\n  @Override\n  public Result[] decodeMultiple(BinaryBitmap image, Map<DecodeHintType,?> hints) throws NotFoundException {\n    List<Result> results = new ArrayList<Result>();\n    DetectorResult[] detectorResults = new MultiDetector(image.getBlackMatrix()).detectMulti(hints);\n    for (DetectorResult detectorResult : detectorResults) {\n      try {\n        DecoderResult decoderResult = getDecoder().decode(detectorResult.getBits(), hints);\n        ResultPoint[] points = detectorResult.getPoints();\n        Result result = new Result(decoderResult.getText(), decoderResult.getRawBytes(), points,\n                                   BarcodeFormat.QR_CODE);\n        List<byte[]> byteSegments = decoderResult.getByteSegments();\n        if (byteSegments != null) {\n          result.putMetadata(ResultMetadataType.BYTE_SEGMENTS, byteSegments);\n        }\n        String ecLevel = decoderResult.getECLevel();\n        if (ecLevel != null) {\n          result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, ecLevel);\n        }\n        results.add(result);\n      } catch (ReaderException re) {\n        // ignore and continue \n      }\n    }\n    if (results.isEmpty()) {\n      return EMPTY_RESULT_ARRAY;\n    } else {\n      return results.toArray(new Result[results.size()]);\n    }\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/multi/qrcode/detector/MultiDetector.java",
    "content": "/*\n * Copyright 2009 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.multi.qrcode.detector;\n\nimport com.google.zxing.DecodeHintType;\nimport com.google.zxing.NotFoundException;\nimport com.google.zxing.ReaderException;\nimport com.google.zxing.ResultPointCallback;\nimport com.google.zxing.common.BitMatrix;\nimport com.google.zxing.common.DetectorResult;\nimport com.google.zxing.qrcode.detector.Detector;\nimport com.google.zxing.qrcode.detector.FinderPatternInfo;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * <p>Encapsulates logic that can detect one or more QR Codes in an image, even if the QR Code\n * is rotated or skewed, or partially obscured.</p>\n *\n * @author Sean Owen\n * @author Hannes Erven\n */\npublic final class MultiDetector extends Detector {\n\n  private static final DetectorResult[] EMPTY_DETECTOR_RESULTS = new DetectorResult[0];\n\n  public MultiDetector(BitMatrix image) {\n    super(image);\n  }\n\n  public DetectorResult[] detectMulti(Map<DecodeHintType,?> hints) throws NotFoundException {\n    BitMatrix image = getImage();\n    ResultPointCallback resultPointCallback =\n        hints == null ? null : (ResultPointCallback) hints.get(DecodeHintType.NEED_RESULT_POINT_CALLBACK);\n    MultiFinderPatternFinder finder = new MultiFinderPatternFinder(image, resultPointCallback);\n    FinderPatternInfo[] infos = finder.findMulti(hints);\n\n    if (infos.length == 0) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n\n    List<DetectorResult> result = new ArrayList<DetectorResult>();\n    for (FinderPatternInfo info : infos) {\n      try {\n        result.add(processFinderPatternInfo(info));\n      } catch (ReaderException e) {\n        // ignore\n      }\n    }\n    if (result.isEmpty()) {\n      return EMPTY_DETECTOR_RESULTS;\n    } else {\n      return result.toArray(new DetectorResult[result.size()]);\n    }\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/multi/qrcode/detector/MultiFinderPatternFinder.java",
    "content": "/*\r\n * Copyright 2009 ZXing authors\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage com.google.zxing.multi.qrcode.detector;\r\n\r\nimport com.google.zxing.DecodeHintType;\r\nimport com.google.zxing.NotFoundException;\r\nimport com.google.zxing.ResultPoint;\r\nimport com.google.zxing.ResultPointCallback;\r\nimport com.google.zxing.common.BitMatrix;\r\nimport com.google.zxing.qrcode.detector.FinderPattern;\r\nimport com.google.zxing.qrcode.detector.FinderPatternFinder;\r\nimport com.google.zxing.qrcode.detector.FinderPatternInfo;\r\n\r\nimport java.io.Serializable;\r\nimport java.util.ArrayList;\r\nimport java.util.Collections;\r\nimport java.util.Comparator;\r\nimport java.util.List;\r\nimport java.util.Map;\r\n\r\n/**\r\n * <p>This class attempts to find finder patterns in a QR Code. Finder patterns are the square\r\n * markers at three corners of a QR Code.</p>\r\n *\r\n * <p>This class is thread-safe but not reentrant. Each thread must allocate its own object.\r\n *\r\n * <p>In contrast to {@link FinderPatternFinder}, this class will return an array of all possible\r\n * QR code locations in the image.</p>\r\n *\r\n * <p>Use the TRY_HARDER hint to ask for a more thorough detection.</p>\r\n *\r\n * @author Sean Owen\r\n * @author Hannes Erven\r\n */\r\nfinal class MultiFinderPatternFinder extends FinderPatternFinder {\r\n\r\n  private static final FinderPatternInfo[] EMPTY_RESULT_ARRAY = new FinderPatternInfo[0];\r\n\r\n  // TODO MIN_MODULE_COUNT and MAX_MODULE_COUNT would be great hints to ask the user for\r\n  // since it limits the number of regions to decode\r\n\r\n  // max. legal count of modules per QR code edge (177)\r\n  private static final float MAX_MODULE_COUNT_PER_EDGE = 180;\r\n  // min. legal count per modules per QR code edge (11)\r\n  private static final float MIN_MODULE_COUNT_PER_EDGE = 9;\r\n\r\n  /**\r\n   * More or less arbitrary cutoff point for determining if two finder patterns might belong\r\n   * to the same code if they differ less than DIFF_MODSIZE_CUTOFF_PERCENT percent in their\r\n   * estimated modules sizes.\r\n   */\r\n  private static final float DIFF_MODSIZE_CUTOFF_PERCENT = 0.05f;\r\n\r\n  /**\r\n   * More or less arbitrary cutoff point for determining if two finder patterns might belong\r\n   * to the same code if they differ less than DIFF_MODSIZE_CUTOFF pixels/module in their\r\n   * estimated modules sizes.\r\n   */\r\n  private static final float DIFF_MODSIZE_CUTOFF = 0.5f;\r\n\r\n\r\n  /**\r\n   * A comparator that orders FinderPatterns by their estimated module size.\r\n   */\r\n  private static final class ModuleSizeComparator implements Comparator<FinderPattern>, Serializable {\r\n    @Override\r\n    public int compare(FinderPattern center1, FinderPattern center2) {\r\n      float value = center2.getEstimatedModuleSize() - center1.getEstimatedModuleSize();\r\n      return value < 0.0 ? -1 : value > 0.0 ? 1 : 0;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * <p>Creates a finder that will search the image for three finder patterns.</p>\r\n   *\r\n   * @param image image to search\r\n   */\r\n  MultiFinderPatternFinder(BitMatrix image) {\r\n    super(image);\r\n  }\r\n\r\n  MultiFinderPatternFinder(BitMatrix image, ResultPointCallback resultPointCallback) {\r\n    super(image, resultPointCallback);\r\n  }\r\n\r\n  /**\r\n   * @return the 3 best {@link FinderPattern}s from our list of candidates. The \"best\" are\r\n   *         those that have been detected at least {@link #CENTER_QUORUM} times, and whose module\r\n   *         size differs from the average among those patterns the least\r\n   * @throws NotFoundException if 3 such finder patterns do not exist\r\n   */\r\n  private FinderPattern[][] selectMutipleBestPatterns() throws NotFoundException {\r\n    List<FinderPattern> possibleCenters = getPossibleCenters();\r\n    int size = possibleCenters.size();\r\n\r\n    if (size < 3) {\r\n      // Couldn't find enough finder patterns\r\n      throw NotFoundException.getNotFoundInstance();\r\n    }\r\n\r\n    /*\r\n     * Begin HE modifications to safely detect multiple codes of equal size\r\n     */\r\n    if (size == 3) {\r\n      return new FinderPattern[][]{\r\n          new FinderPattern[]{\r\n              possibleCenters.get(0),\r\n              possibleCenters.get(1),\r\n              possibleCenters.get(2)\r\n          }\r\n      };\r\n    }\r\n\r\n    // Sort by estimated module size to speed up the upcoming checks\r\n    Collections.sort(possibleCenters, new ModuleSizeComparator());\r\n\r\n    /*\r\n     * Now lets start: build a list of tuples of three finder locations that\r\n     *  - feature similar module sizes\r\n     *  - are placed in a distance so the estimated module count is within the QR specification\r\n     *  - have similar distance between upper left/right and left top/bottom finder patterns\r\n     *  - form a triangle with 90° angle (checked by comparing top right/bottom left distance\r\n     *    with pythagoras)\r\n     *\r\n     * Note: we allow each point to be used for more than one code region: this might seem\r\n     * counterintuitive at first, but the performance penalty is not that big. At this point,\r\n     * we cannot make a good quality decision whether the three finders actually represent\r\n     * a QR code, or are just by chance layouted so it looks like there might be a QR code there.\r\n     * So, if the layout seems right, lets have the decoder try to decode.     \r\n     */\r\n\r\n     List<FinderPattern[]> results = new ArrayList<FinderPattern[]>(); // holder for the results\r\n\r\n    for (int i1 = 0; i1 < (size - 2); i1++) {\r\n      FinderPattern p1 = possibleCenters.get(i1);\r\n      if (p1 == null) {\r\n        continue;\r\n      }\r\n\r\n      for (int i2 = i1 + 1; i2 < (size - 1); i2++) {\r\n        FinderPattern p2 = possibleCenters.get(i2);\r\n        if (p2 == null) {\r\n          continue;\r\n        }\r\n\r\n        // Compare the expected module sizes; if they are really off, skip\r\n        float vModSize12 = (p1.getEstimatedModuleSize() - p2.getEstimatedModuleSize()) /\r\n            Math.min(p1.getEstimatedModuleSize(), p2.getEstimatedModuleSize());\r\n        float vModSize12A = Math.abs(p1.getEstimatedModuleSize() - p2.getEstimatedModuleSize());\r\n        if (vModSize12A > DIFF_MODSIZE_CUTOFF && vModSize12 >= DIFF_MODSIZE_CUTOFF_PERCENT) {\r\n          // break, since elements are ordered by the module size deviation there cannot be\r\n          // any more interesting elements for the given p1.\r\n          break;\r\n        }\r\n\r\n        for (int i3 = i2 + 1; i3 < size; i3++) {\r\n          FinderPattern p3 = possibleCenters.get(i3);\r\n          if (p3 == null) {\r\n            continue;\r\n          }\r\n\r\n          // Compare the expected module sizes; if they are really off, skip\r\n          float vModSize23 = (p2.getEstimatedModuleSize() - p3.getEstimatedModuleSize()) /\r\n              Math.min(p2.getEstimatedModuleSize(), p3.getEstimatedModuleSize());\r\n          float vModSize23A = Math.abs(p2.getEstimatedModuleSize() - p3.getEstimatedModuleSize());\r\n          if (vModSize23A > DIFF_MODSIZE_CUTOFF && vModSize23 >= DIFF_MODSIZE_CUTOFF_PERCENT) {\r\n            // break, since elements are ordered by the module size deviation there cannot be\r\n            // any more interesting elements for the given p1.\r\n            break;\r\n          }\r\n\r\n          FinderPattern[] test = {p1, p2, p3};\r\n          ResultPoint.orderBestPatterns(test);\r\n\r\n          // Calculate the distances: a = topleft-bottomleft, b=topleft-topright, c = diagonal\r\n          FinderPatternInfo info = new FinderPatternInfo(test);\r\n          float dA = ResultPoint.distance(info.getTopLeft(), info.getBottomLeft());\r\n          float dC = ResultPoint.distance(info.getTopRight(), info.getBottomLeft());\r\n          float dB = ResultPoint.distance(info.getTopLeft(), info.getTopRight());\r\n\r\n          // Check the sizes\r\n          float estimatedModuleCount = (dA + dB) / (p1.getEstimatedModuleSize() * 2.0f);\r\n          if (estimatedModuleCount > MAX_MODULE_COUNT_PER_EDGE ||\r\n              estimatedModuleCount < MIN_MODULE_COUNT_PER_EDGE) {\r\n            continue;\r\n          }\r\n\r\n          // Calculate the difference of the edge lengths in percent\r\n          float vABBC = Math.abs((dA - dB) / Math.min(dA, dB));\r\n          if (vABBC >= 0.1f) {\r\n            continue;\r\n          }\r\n\r\n          // Calculate the diagonal length by assuming a 90° angle at topleft\r\n          float dCpy = (float) Math.sqrt(dA * dA + dB * dB);\r\n          // Compare to the real distance in %\r\n          float vPyC = Math.abs((dC - dCpy) / Math.min(dC, dCpy));\r\n\r\n          if (vPyC >= 0.1f) {\r\n            continue;\r\n          }\r\n\r\n          // All tests passed!\r\n          results.add(test);\r\n        } // end iterate p3\r\n      } // end iterate p2\r\n    } // end iterate p1\r\n\r\n    if (!results.isEmpty()) {\r\n      return results.toArray(new FinderPattern[results.size()][]);\r\n    }\r\n\r\n    // Nothing found!\r\n    throw NotFoundException.getNotFoundInstance();\r\n  }\r\n\r\n  public FinderPatternInfo[] findMulti(Map<DecodeHintType,?> hints) throws NotFoundException {\r\n    boolean tryHarder = hints != null && hints.containsKey(DecodeHintType.TRY_HARDER);\r\n    BitMatrix image = getImage();\r\n    int maxI = image.getHeight();\r\n    int maxJ = image.getWidth();\r\n    // We are looking for black/white/black/white/black modules in\r\n    // 1:1:3:1:1 ratio; this tracks the number of such modules seen so far\r\n\r\n    // Let's assume that the maximum version QR Code we support takes up 1/4 the height of the\r\n    // image, and then account for the center being 3 modules in size. This gives the smallest\r\n    // number of pixels the center could be, so skip this often. When trying harder, look for all\r\n    // QR versions regardless of how dense they are.\r\n    int iSkip = (int) (maxI / (MAX_MODULES * 4.0f) * 3);\r\n    if (iSkip < MIN_SKIP || tryHarder) {\r\n      iSkip = MIN_SKIP;\r\n    }\r\n\r\n    int[] stateCount = new int[5];\r\n    for (int i = iSkip - 1; i < maxI; i += iSkip) {\r\n      // Get a row of black/white values\r\n      stateCount[0] = 0;\r\n      stateCount[1] = 0;\r\n      stateCount[2] = 0;\r\n      stateCount[3] = 0;\r\n      stateCount[4] = 0;\r\n      int currentState = 0;\r\n      for (int j = 0; j < maxJ; j++) {\r\n        if (image.get(j, i)) {\r\n          // Black pixel\r\n          if ((currentState & 1) == 1) { // Counting white pixels\r\n            currentState++;\r\n          }\r\n          stateCount[currentState]++;\r\n        } else { // White pixel\r\n          if ((currentState & 1) == 0) { // Counting black pixels\r\n            if (currentState == 4) { // A winner?\r\n              if (foundPatternCross(stateCount)) { // Yes\r\n                boolean confirmed = handlePossibleCenter(stateCount, i, j);\r\n                if (!confirmed) {\r\n                  do { // Advance to next black pixel\r\n                    j++;\r\n                  } while (j < maxJ && !image.get(j, i));\r\n                  j--; // back up to that last white pixel\r\n                }\r\n                // Clear state to start looking again\r\n                currentState = 0;\r\n                stateCount[0] = 0;\r\n                stateCount[1] = 0;\r\n                stateCount[2] = 0;\r\n                stateCount[3] = 0;\r\n                stateCount[4] = 0;\r\n              } else { // No, shift counts back by two\r\n                stateCount[0] = stateCount[2];\r\n                stateCount[1] = stateCount[3];\r\n                stateCount[2] = stateCount[4];\r\n                stateCount[3] = 1;\r\n                stateCount[4] = 0;\r\n                currentState = 3;\r\n              }\r\n            } else {\r\n              stateCount[++currentState]++;\r\n            }\r\n          } else { // Counting white pixels\r\n            stateCount[currentState]++;\r\n          }\r\n        }\r\n      } // for j=...\r\n\r\n      if (foundPatternCross(stateCount)) {\r\n        handlePossibleCenter(stateCount, i, maxJ);\r\n      } // end if foundPatternCross\r\n    } // for i=iSkip-1 ...\r\n    FinderPattern[][] patternInfo = selectMutipleBestPatterns();\r\n    List<FinderPatternInfo> result = new ArrayList<FinderPatternInfo>();\r\n    for (FinderPattern[] pattern : patternInfo) {\r\n      ResultPoint.orderBestPatterns(pattern);\r\n      result.add(new FinderPatternInfo(pattern));\r\n    }\r\n\r\n    if (result.isEmpty()) {\r\n      return EMPTY_RESULT_ARRAY;\r\n    } else {\r\n      return result.toArray(new FinderPatternInfo[result.size()]);\r\n    }\r\n  }\r\n\r\n}\r\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/CodaBarReader.java",
    "content": "/*\r\n * Copyright 2008 ZXing authors\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage com.google.zxing.oned;\r\n\r\nimport com.google.zxing.BarcodeFormat;\r\nimport com.google.zxing.DecodeHintType;\r\nimport com.google.zxing.NotFoundException;\r\nimport com.google.zxing.Result;\r\nimport com.google.zxing.ResultPoint;\r\nimport com.google.zxing.common.BitArray;\r\n\r\nimport java.util.Map;\r\n\r\n/**\r\n * <p>Decodes Codabar barcodes.</p>\r\n *\r\n * @author Bas Vijfwinkel\r\n * @author David Walker\r\n */\r\npublic final class CodaBarReader extends OneDReader {\r\n\r\n  // These values are critical for determining how permissive the decoding\r\n  // will be. All stripe sizes must be within the window these define, as\r\n  // compared to the average stripe size.\r\n  private static final int MAX_ACCEPTABLE = (int) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 2.0f);\r\n  private static final int PADDING = (int) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 1.5f);\r\n\r\n  private static final String ALPHABET_STRING = \"0123456789-$:/.+ABCD\";\r\n  static final char[] ALPHABET = ALPHABET_STRING.toCharArray();\r\n\r\n  /**\r\n   * These represent the encodings of characters, as patterns of wide and narrow bars. The 7 least-significant bits of\r\n   * each int correspond to the pattern of wide and narrow, with 1s representing \"wide\" and 0s representing narrow.\r\n   */\r\n  static final int[] CHARACTER_ENCODINGS = {\r\n      0x003, 0x006, 0x009, 0x060, 0x012, 0x042, 0x021, 0x024, 0x030, 0x048, // 0-9\r\n      0x00c, 0x018, 0x045, 0x051, 0x054, 0x015, 0x01A, 0x029, 0x00B, 0x00E, // -$:/.+ABCD\r\n  };\r\n\r\n  // minimal number of characters that should be present (inclusing start and stop characters)\r\n  // under normal circumstances this should be set to 3, but can be set higher\r\n  // as a last-ditch attempt to reduce false positives.\r\n  private static final int MIN_CHARACTER_LENGTH = 3;\r\n\r\n  // official start and end patterns\r\n  private static final char[] STARTEND_ENCODING = {'A', 'B', 'C', 'D'};\r\n  // some codabar generator allow the codabar string to be closed by every\r\n  // character. This will cause lots of false positives!\r\n\r\n  // some industries use a checksum standard but this is not part of the original codabar standard\r\n  // for more information see : http://www.mecsw.com/specs/codabar.html\r\n\r\n  // Keep some instance variables to avoid reallocations\r\n  private final StringBuilder decodeRowResult;\r\n  private int[] counters;\r\n  private int counterLength;\r\n\r\n  public CodaBarReader() {\r\n    decodeRowResult = new StringBuilder(20);\r\n    counters = new int[80];\r\n    counterLength = 0;\r\n  }\r\n\r\n  @Override\r\n  public Result decodeRow(int rowNumber, BitArray row, Map<DecodeHintType,?> hints) throws NotFoundException {\r\n\r\n    setCounters(row);\r\n    int startOffset = findStartPattern();\r\n    int nextStart = startOffset;\r\n\r\n    decodeRowResult.setLength(0);\r\n    do {\r\n      int charOffset = toNarrowWidePattern(nextStart);\r\n      if (charOffset == -1) {\r\n        throw NotFoundException.getNotFoundInstance();\r\n      }\r\n      // Hack: We store the position in the alphabet table into a\r\n      // StringBuilder, so that we can access the decoded patterns in\r\n      // validatePattern. We'll translate to the actual characters later.\r\n      decodeRowResult.append((char)charOffset);\r\n      nextStart += 8;\r\n      // Stop as soon as we see the end character.\r\n      if (decodeRowResult.length() > 1 &&\r\n          arrayContains(STARTEND_ENCODING, ALPHABET[charOffset])) {\r\n        break;\r\n      }\r\n    } while (nextStart < counterLength); // no fixed end pattern so keep on reading while data is available\r\n\r\n    // Look for whitespace after pattern:\r\n    int trailingWhitespace = counters[nextStart - 1];\r\n    int lastPatternSize = 0;\r\n    for (int i = -8; i < -1; i++) {\r\n      lastPatternSize += counters[nextStart + i];\r\n    }\r\n\r\n    // We need to see whitespace equal to 50% of the last pattern size,\r\n    // otherwise this is probably a false positive. The exception is if we are\r\n    // at the end of the row. (I.e. the barcode barely fits.)\r\n    if (nextStart < counterLength && trailingWhitespace < lastPatternSize / 2) {\r\n      throw NotFoundException.getNotFoundInstance();\r\n    }\r\n\r\n    validatePattern(startOffset);\r\n\r\n    // Translate character table offsets to actual characters.\r\n    for (int i = 0; i < decodeRowResult.length(); i++) {\r\n      decodeRowResult.setCharAt(i, ALPHABET[decodeRowResult.charAt(i)]);\r\n    }\r\n    // Ensure a valid start and end character\r\n    char startchar = decodeRowResult.charAt(0);\r\n    if (!arrayContains(STARTEND_ENCODING, startchar)) {\r\n      throw NotFoundException.getNotFoundInstance();\r\n    }\r\n    char endchar = decodeRowResult.charAt(decodeRowResult.length() - 1);\r\n    if (!arrayContains(STARTEND_ENCODING, endchar)) {\r\n      throw NotFoundException.getNotFoundInstance();\r\n    }\r\n\r\n    // remove stop/start characters character and check if a long enough string is contained\r\n    if (decodeRowResult.length() <= MIN_CHARACTER_LENGTH) {\r\n      // Almost surely a false positive ( start + stop + at least 1 character)\r\n      throw NotFoundException.getNotFoundInstance();\r\n    }\r\n\r\n    decodeRowResult.deleteCharAt(decodeRowResult.length() - 1);\r\n    decodeRowResult.deleteCharAt(0);\r\n\r\n    int runningCount = 0;\r\n    for (int i = 0; i < startOffset; i++) {\r\n      runningCount += counters[i];\r\n    }\r\n    float left = (float) runningCount;\r\n    for (int i = startOffset; i < nextStart - 1; i++) {\r\n      runningCount += counters[i];\r\n    }\r\n    float right = (float) runningCount;\r\n    return new Result(\r\n        decodeRowResult.toString(),\r\n        null,\r\n        new ResultPoint[]{\r\n            new ResultPoint(left, (float) rowNumber),\r\n            new ResultPoint(right, (float) rowNumber)},\r\n        BarcodeFormat.CODABAR);\r\n  }\r\n\r\n  void validatePattern(int start) throws NotFoundException {\r\n    // First, sum up the total size of our four categories of stripe sizes;\r\n    int[] sizes = {0, 0, 0, 0};\r\n    int[] counts = {0, 0, 0, 0};\r\n    int end = decodeRowResult.length() - 1;\r\n\r\n    // We break out of this loop in the middle, in order to handle\r\n    // inter-character spaces properly.\r\n    int pos = start;\r\n    for (int i = 0; true; i++) {\r\n      int pattern = CHARACTER_ENCODINGS[decodeRowResult.charAt(i)];\r\n      for (int j = 6; j >= 0; j--) {\r\n        // Even j = bars, while odd j = spaces. Categories 2 and 3 are for\r\n        // long stripes, while 0 and 1 are for short stripes.\r\n        int category = (j & 1) + (pattern & 1) * 2;\r\n        sizes[category] += counters[pos + j];\r\n        counts[category]++;\r\n        pattern >>= 1;\r\n      }\r\n      if (i >= end) {\r\n        break;\r\n      }\r\n      // We ignore the inter-character space - it could be of any size.\r\n      pos += 8;\r\n    }\r\n\r\n    // Calculate our allowable size thresholds using fixed-point math.\r\n    int[] maxes = new int[4];\r\n    int[] mins = new int[4];\r\n    // Define the threshold of acceptability to be the midpoint between the\r\n    // average small stripe and the average large stripe. No stripe lengths\r\n    // should be on the \"wrong\" side of that line.\r\n    for (int i = 0; i < 2; i++) {\r\n      mins[i] = 0;  // Accept arbitrarily small \"short\" stripes.\r\n      mins[i + 2] = ((sizes[i] << INTEGER_MATH_SHIFT) / counts[i] +\r\n                     (sizes[i + 2] << INTEGER_MATH_SHIFT) / counts[i + 2]) >> 1;\r\n      maxes[i] = mins[i + 2];\r\n      maxes[i + 2] = (sizes[i + 2] * MAX_ACCEPTABLE + PADDING) / counts[i + 2];\r\n    }\r\n\r\n    // Now verify that all of the stripes are within the thresholds.\r\n    pos = start;\r\n    for (int i = 0; true; i++) {\r\n      int pattern = CHARACTER_ENCODINGS[decodeRowResult.charAt(i)];\r\n      for (int j = 6; j >= 0; j--) {\r\n        // Even j = bars, while odd j = spaces. Categories 2 and 3 are for\r\n        // long stripes, while 0 and 1 are for short stripes.\r\n        int category = (j & 1) + (pattern & 1) * 2;\r\n        int size = counters[pos + j] << INTEGER_MATH_SHIFT;\r\n        if (size < mins[category] || size > maxes[category]) {\r\n          throw NotFoundException.getNotFoundInstance();\r\n        }\r\n        pattern >>= 1;\r\n      }\r\n      if (i >= end) {\r\n        break;\r\n      }\r\n      pos += 8;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Records the size of all runs of white and black pixels, starting with white.\r\n   * This is just like recordPattern, except it records all the counters, and\r\n   * uses our builtin \"counters\" member for storage.\r\n   * @param row row to count from\r\n   */\r\n  private void setCounters(BitArray row) throws NotFoundException {\r\n    counterLength = 0;\r\n    // Start from the first white bit.\r\n    int i = row.getNextUnset(0);\r\n    int end = row.getSize();\r\n    if (i >= end) {\r\n      throw NotFoundException.getNotFoundInstance();\r\n    }\r\n    boolean isWhite = true;\r\n    int count = 0;\r\n    for (; i < end; i++) {\r\n      if (row.get(i) ^ isWhite) { // that is, exactly one is true\r\n        count++;\r\n      } else {\r\n        counterAppend(count);\r\n        count = 1;\r\n        isWhite = !isWhite;\r\n      }\r\n    }\r\n    counterAppend(count);\r\n  }\r\n\r\n  private void counterAppend(int e) {\r\n    counters[counterLength] = e;\r\n    counterLength++;\r\n    if (counterLength >= counters.length) {\r\n      int[] temp = new int[counterLength * 2];\r\n      System.arraycopy(counters, 0, temp, 0, counterLength);\r\n      counters = temp;\r\n    }\r\n  }\r\n\r\n  private int findStartPattern() throws NotFoundException {\r\n    for (int i = 1; i < counterLength; i += 2) {\r\n      int charOffset = toNarrowWidePattern(i);\r\n      if (charOffset != -1 && arrayContains(STARTEND_ENCODING, ALPHABET[charOffset])) {\r\n        // Look for whitespace before start pattern, >= 50% of width of start pattern\r\n        // We make an exception if the whitespace is the first element.\r\n        int patternSize = 0;\r\n        for (int j = i; j < i + 7; j++) {\r\n          patternSize += counters[j];\r\n        }\r\n        if (i == 1 || counters[i-1] >= patternSize / 2) {\r\n          return i;\r\n        }\r\n      }\r\n    }\r\n    throw NotFoundException.getNotFoundInstance();\r\n  }\r\n\r\n  static boolean arrayContains(char[] array, char key) {\r\n    if (array != null) {\r\n      for (char c : array) {\r\n        if (c == key) {\r\n          return true;\r\n        }\r\n      }\r\n    }\r\n    return false;\r\n  }\r\n\r\n  // Assumes that counters[position] is a bar.\r\n  private int toNarrowWidePattern(int position) {\r\n    int end = position + 7;\r\n    if (end >= counterLength) {\r\n      return -1;\r\n    }\r\n    // First element is for bars, second is for spaces.\r\n    int[] maxes = {0, 0};\r\n    int[] mins = {Integer.MAX_VALUE, Integer.MAX_VALUE};\r\n    int[] thresholds = {0, 0};\r\n\r\n    for (int i = 0; i < 2; i++) {\r\n      for (int j = position + i; j < end; j += 2) {\r\n        if (counters[j] < mins[i]) {\r\n          mins[i] = counters[j];\r\n        }\r\n        if (counters[j] > maxes[i]) {\r\n          maxes[i] = counters[j];\r\n        }\r\n      }\r\n      thresholds[i] = (mins[i] + maxes[i]) / 2;\r\n    }\r\n\r\n    int bitmask = 1 << 7;\r\n    int pattern = 0;\r\n    for (int i = 0; i < 7; i++) {\r\n      int barOrSpace = i & 1;\r\n      bitmask >>= 1;\r\n      if (counters[position + i] > thresholds[barOrSpace]) {\r\n        pattern |= bitmask;\r\n      }\r\n    }\r\n\r\n    for (int i = 0; i < CHARACTER_ENCODINGS.length; i++) {\r\n      if (CHARACTER_ENCODINGS[i] == pattern) {\r\n        return i;\r\n      }\r\n    }\r\n    return -1;\r\n  }\r\n\r\n}\r\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/CodaBarWriter.java",
    "content": "/*\n * Copyright 2011 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.oned;\n\nimport com.google.zxing.common.BitMatrix;\n\nimport java.util.Arrays;\n\n/**\n * This class renders CodaBar as {@link BitMatrix}.\n *\n * @author dsbnatut@gmail.com (Kazuki Nishiura)\n */\npublic final class CodaBarWriter extends OneDimensionalCodeWriter {\n\n  private static final char[] START_CHARS = {'A', 'B', 'C', 'D'};\n  private static final char[] END_CHARS = {'T', 'N', '*', 'E'};\n\n  /*\n   * @see OneDimensionalCodeWriter#encode(String)\n   */\n  @Override\n  public boolean[] encode(String contents) {\n\n    // Verify input and calculate decoded length.\n    if (!CodaBarReader.arrayContains(START_CHARS, Character.toUpperCase(contents.charAt(0)))) {\n      throw new IllegalArgumentException(\n          \"Codabar should start with one of the following: \" + Arrays.toString(START_CHARS));\n    }\n    if (!CodaBarReader.arrayContains(END_CHARS, Character.toUpperCase(contents.charAt(contents.length() - 1)))) {\n      throw new IllegalArgumentException(\n          \"Codabar should end with one of the following: \" + Arrays.toString(END_CHARS));\n    }\n    // The start character and the end character are decoded to 10 length each.\n    int resultLength = 20;\n    char[] charsWhichAreTenLengthEachAfterDecoded = {'/', ':', '+', '.'};\n    for (int i = 1; i < contents.length() - 1; i++) {\n      if (Character.isDigit(contents.charAt(i)) || contents.charAt(i) == '-'\n          || contents.charAt(i) == '$') {\n        resultLength += 9;\n      } else if (CodaBarReader.arrayContains(\n          charsWhichAreTenLengthEachAfterDecoded, contents.charAt(i))) {\n        resultLength += 10;\n      } else {\n        throw new IllegalArgumentException(\"Cannot encode : '\" + contents.charAt(i) + '\\'');\n      }\n    }\n    // A blank is placed between each character.\n    resultLength += contents.length() - 1;\n\n    boolean[] result = new boolean[resultLength];\n    int position = 0;\n    for (int index = 0; index < contents.length(); index++) {\n      char c = Character.toUpperCase(contents.charAt(index));\n      if (index == contents.length() - 1) {\n        // The end chars are not in the CodaBarReader.ALPHABET.\n        switch (c) {\n          case 'T':\n            c = 'A';\n            break;\n          case 'N':\n            c = 'B';\n            break;\n          case '*':\n            c = 'C';\n            break;\n          case 'E':\n            c = 'D';\n            break;\n        }\n      }\n      int code = 0;\n      for (int i = 0; i < CodaBarReader.ALPHABET.length; i++) {\n        // Found any, because I checked above.\n        if (c == CodaBarReader.ALPHABET[i]) {\n          code = CodaBarReader.CHARACTER_ENCODINGS[i];\n          break;\n        }\n      }\n      boolean color = true;\n      int counter = 0;\n      int bit = 0;\n      while (bit < 7) { // A character consists of 7 digit.\n        result[position] = color;\n        position++;\n        if (((code >> (6 - bit)) & 1) == 0 || counter == 1) {\n          color = !color; // Flip the color.\n          bit++;\n          counter = 0;\n        } else {\n          counter++;\n        }\n      }\n      if (index < contents.length() - 1) {\n        result[position] = false;\n        position++;\n      }\n    }\n    return result;\n  }\n}\n\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/Code128Reader.java",
    "content": "/*\n * Copyright 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.oned;\n\nimport com.google.zxing.BarcodeFormat;\nimport com.google.zxing.ChecksumException;\nimport com.google.zxing.DecodeHintType;\nimport com.google.zxing.FormatException;\nimport com.google.zxing.NotFoundException;\nimport com.google.zxing.Result;\nimport com.google.zxing.ResultPoint;\nimport com.google.zxing.common.BitArray;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * <p>Decodes Code 128 barcodes.</p>\n *\n * @author Sean Owen\n */\npublic final class Code128Reader extends OneDReader {\n\n  static final int[][] CODE_PATTERNS = {\n      {2, 1, 2, 2, 2, 2}, // 0\n      {2, 2, 2, 1, 2, 2},\n      {2, 2, 2, 2, 2, 1},\n      {1, 2, 1, 2, 2, 3},\n      {1, 2, 1, 3, 2, 2},\n      {1, 3, 1, 2, 2, 2}, // 5\n      {1, 2, 2, 2, 1, 3},\n      {1, 2, 2, 3, 1, 2},\n      {1, 3, 2, 2, 1, 2},\n      {2, 2, 1, 2, 1, 3},\n      {2, 2, 1, 3, 1, 2}, // 10\n      {2, 3, 1, 2, 1, 2},\n      {1, 1, 2, 2, 3, 2},\n      {1, 2, 2, 1, 3, 2},\n      {1, 2, 2, 2, 3, 1},\n      {1, 1, 3, 2, 2, 2}, // 15\n      {1, 2, 3, 1, 2, 2},\n      {1, 2, 3, 2, 2, 1},\n      {2, 2, 3, 2, 1, 1},\n      {2, 2, 1, 1, 3, 2},\n      {2, 2, 1, 2, 3, 1}, // 20\n      {2, 1, 3, 2, 1, 2},\n      {2, 2, 3, 1, 1, 2},\n      {3, 1, 2, 1, 3, 1},\n      {3, 1, 1, 2, 2, 2},\n      {3, 2, 1, 1, 2, 2}, // 25\n      {3, 2, 1, 2, 2, 1},\n      {3, 1, 2, 2, 1, 2},\n      {3, 2, 2, 1, 1, 2},\n      {3, 2, 2, 2, 1, 1},\n      {2, 1, 2, 1, 2, 3}, // 30\n      {2, 1, 2, 3, 2, 1},\n      {2, 3, 2, 1, 2, 1},\n      {1, 1, 1, 3, 2, 3},\n      {1, 3, 1, 1, 2, 3},\n      {1, 3, 1, 3, 2, 1}, // 35\n      {1, 1, 2, 3, 1, 3},\n      {1, 3, 2, 1, 1, 3},\n      {1, 3, 2, 3, 1, 1},\n      {2, 1, 1, 3, 1, 3},\n      {2, 3, 1, 1, 1, 3}, // 40\n      {2, 3, 1, 3, 1, 1},\n      {1, 1, 2, 1, 3, 3},\n      {1, 1, 2, 3, 3, 1},\n      {1, 3, 2, 1, 3, 1},\n      {1, 1, 3, 1, 2, 3}, // 45\n      {1, 1, 3, 3, 2, 1},\n      {1, 3, 3, 1, 2, 1},\n      {3, 1, 3, 1, 2, 1},\n      {2, 1, 1, 3, 3, 1},\n      {2, 3, 1, 1, 3, 1}, // 50\n      {2, 1, 3, 1, 1, 3},\n      {2, 1, 3, 3, 1, 1},\n      {2, 1, 3, 1, 3, 1},\n      {3, 1, 1, 1, 2, 3},\n      {3, 1, 1, 3, 2, 1}, // 55\n      {3, 3, 1, 1, 2, 1},\n      {3, 1, 2, 1, 1, 3},\n      {3, 1, 2, 3, 1, 1},\n      {3, 3, 2, 1, 1, 1},\n      {3, 1, 4, 1, 1, 1}, // 60\n      {2, 2, 1, 4, 1, 1},\n      {4, 3, 1, 1, 1, 1},\n      {1, 1, 1, 2, 2, 4},\n      {1, 1, 1, 4, 2, 2},\n      {1, 2, 1, 1, 2, 4}, // 65\n      {1, 2, 1, 4, 2, 1},\n      {1, 4, 1, 1, 2, 2},\n      {1, 4, 1, 2, 2, 1},\n      {1, 1, 2, 2, 1, 4},\n      {1, 1, 2, 4, 1, 2}, // 70\n      {1, 2, 2, 1, 1, 4},\n      {1, 2, 2, 4, 1, 1},\n      {1, 4, 2, 1, 1, 2},\n      {1, 4, 2, 2, 1, 1},\n      {2, 4, 1, 2, 1, 1}, // 75\n      {2, 2, 1, 1, 1, 4},\n      {4, 1, 3, 1, 1, 1},\n      {2, 4, 1, 1, 1, 2},\n      {1, 3, 4, 1, 1, 1},\n      {1, 1, 1, 2, 4, 2}, // 80\n      {1, 2, 1, 1, 4, 2},\n      {1, 2, 1, 2, 4, 1},\n      {1, 1, 4, 2, 1, 2},\n      {1, 2, 4, 1, 1, 2},\n      {1, 2, 4, 2, 1, 1}, // 85\n      {4, 1, 1, 2, 1, 2},\n      {4, 2, 1, 1, 1, 2},\n      {4, 2, 1, 2, 1, 1},\n      {2, 1, 2, 1, 4, 1},\n      {2, 1, 4, 1, 2, 1}, // 90\n      {4, 1, 2, 1, 2, 1},\n      {1, 1, 1, 1, 4, 3},\n      {1, 1, 1, 3, 4, 1},\n      {1, 3, 1, 1, 4, 1},\n      {1, 1, 4, 1, 1, 3}, // 95\n      {1, 1, 4, 3, 1, 1},\n      {4, 1, 1, 1, 1, 3},\n      {4, 1, 1, 3, 1, 1},\n      {1, 1, 3, 1, 4, 1},\n      {1, 1, 4, 1, 3, 1}, // 100\n      {3, 1, 1, 1, 4, 1},\n      {4, 1, 1, 1, 3, 1},\n      {2, 1, 1, 4, 1, 2},\n      {2, 1, 1, 2, 1, 4},\n      {2, 1, 1, 2, 3, 2}, // 105\n      {2, 3, 3, 1, 1, 1, 2}\n  };\n\n  private static final int MAX_AVG_VARIANCE = (int) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.25f);\n  private static final int MAX_INDIVIDUAL_VARIANCE = (int) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.7f);\n\n  private static final int CODE_SHIFT = 98;\n\n  private static final int CODE_CODE_C = 99;\n  private static final int CODE_CODE_B = 100;\n  private static final int CODE_CODE_A = 101;\n\n  private static final int CODE_FNC_1 = 102;\n  private static final int CODE_FNC_2 = 97;\n  private static final int CODE_FNC_3 = 96;\n  private static final int CODE_FNC_4_A = 101;\n  private static final int CODE_FNC_4_B = 100;\n\n  private static final int CODE_START_A = 103;\n  private static final int CODE_START_B = 104;\n  private static final int CODE_START_C = 105;\n  private static final int CODE_STOP = 106;\n\n  private static int[] findStartPattern(BitArray row) throws NotFoundException {\n    int width = row.getSize();\n    int rowOffset = row.getNextSet(0);\n\n    int counterPosition = 0;\n    int[] counters = new int[6];\n    int patternStart = rowOffset;\n    boolean isWhite = false;\n    int patternLength = counters.length;\n\n    for (int i = rowOffset; i < width; i++) {\n      if (row.get(i) ^ isWhite) {\n        counters[counterPosition]++;\n      } else {\n        if (counterPosition == patternLength - 1) {\n          int bestVariance = MAX_AVG_VARIANCE;\n          int bestMatch = -1;\n          for (int startCode = CODE_START_A; startCode <= CODE_START_C; startCode++) {\n            int variance = patternMatchVariance(counters, CODE_PATTERNS[startCode],\n                MAX_INDIVIDUAL_VARIANCE);\n            if (variance < bestVariance) {\n              bestVariance = variance;\n              bestMatch = startCode;\n            }\n          }\n          // Look for whitespace before start pattern, >= 50% of width of start pattern\n          if (bestMatch >= 0 &&\n              row.isRange(Math.max(0, patternStart - (i - patternStart) / 2), patternStart, false)) {\n            return new int[]{patternStart, i, bestMatch};\n          }\n          patternStart += counters[0] + counters[1];\n          System.arraycopy(counters, 2, counters, 0, patternLength - 2);\n          counters[patternLength - 2] = 0;\n          counters[patternLength - 1] = 0;\n          counterPosition--;\n        } else {\n          counterPosition++;\n        }\n        counters[counterPosition] = 1;\n        isWhite = !isWhite;\n      }\n    }\n    throw NotFoundException.getNotFoundInstance();\n  }\n\n  private static int decodeCode(BitArray row, int[] counters, int rowOffset)\n      throws NotFoundException {\n    recordPattern(row, rowOffset, counters);\n    int bestVariance = MAX_AVG_VARIANCE; // worst variance we'll accept\n    int bestMatch = -1;\n    for (int d = 0; d < CODE_PATTERNS.length; d++) {\n      int[] pattern = CODE_PATTERNS[d];\n      int variance = patternMatchVariance(counters, pattern, MAX_INDIVIDUAL_VARIANCE);\n      if (variance < bestVariance) {\n        bestVariance = variance;\n        bestMatch = d;\n      }\n    }\n    // TODO We're overlooking the fact that the STOP pattern has 7 values, not 6.\n    if (bestMatch >= 0) {\n      return bestMatch;\n    } else {\n      throw NotFoundException.getNotFoundInstance();\n    }\n  }\n\n  @Override\n  public Result decodeRow(int rowNumber, BitArray row, Map<DecodeHintType,?> hints)\n      throws NotFoundException, FormatException, ChecksumException {\n\n    int[] startPatternInfo = findStartPattern(row);\n    int startCode = startPatternInfo[2];\n    int codeSet;\n    switch (startCode) {\n      case CODE_START_A:\n        codeSet = CODE_CODE_A;\n        break;\n      case CODE_START_B:\n        codeSet = CODE_CODE_B;\n        break;\n      case CODE_START_C:\n        codeSet = CODE_CODE_C;\n        break;\n      default:\n        throw FormatException.getFormatInstance();\n    }\n\n    boolean done = false;\n    boolean isNextShifted = false;\n\n    StringBuilder result = new StringBuilder(20);\n    List<Byte> rawCodes = new ArrayList<Byte>(20);\n\n    int lastStart = startPatternInfo[0];\n    int nextStart = startPatternInfo[1];\n    int[] counters = new int[6];\n\n    int lastCode = 0;\n    int code = 0;\n    int checksumTotal = startCode;\n    int multiplier = 0;\n    boolean lastCharacterWasPrintable = true;\n\n    while (!done) {\n\n      boolean unshift = isNextShifted;\n      isNextShifted = false;\n\n      // Save off last code\n      lastCode = code;\n\n      // Decode another code from image\n      code = decodeCode(row, counters, nextStart);\n\n      rawCodes.add((byte) code);\n\n      // Remember whether the last code was printable or not (excluding CODE_STOP)\n      if (code != CODE_STOP) {\n        lastCharacterWasPrintable = true;\n      }\n\n      // Add to checksum computation (if not CODE_STOP of course)\n      if (code != CODE_STOP) {\n        multiplier++;\n        checksumTotal += multiplier * code;\n      }\n\n      // Advance to where the next code will to start\n      lastStart = nextStart;\n      for (int counter : counters) {\n        nextStart += counter;\n      }\n\n      // Take care of illegal start codes\n      switch (code) {\n        case CODE_START_A:\n        case CODE_START_B:\n        case CODE_START_C:\n          throw FormatException.getFormatInstance();\n      }\n\n      switch (codeSet) {\n\n        case CODE_CODE_A:\n          if (code < 64) {\n            result.append((char) (' ' + code));\n          } else if (code < 96) {\n            result.append((char) (code - 64));\n          } else {\n            // Don't let CODE_STOP, which always appears, affect whether whether we think the last\n            // code was printable or not.\n            if (code != CODE_STOP) {\n              lastCharacterWasPrintable = false;\n            }\n            switch (code) {\n              case CODE_FNC_1:\n              case CODE_FNC_2:\n              case CODE_FNC_3:\n              case CODE_FNC_4_A:\n                // do nothing?\n                break;\n              case CODE_SHIFT:\n                isNextShifted = true;\n                codeSet = CODE_CODE_B;\n                break;\n              case CODE_CODE_B:\n                codeSet = CODE_CODE_B;\n                break;\n              case CODE_CODE_C:\n                codeSet = CODE_CODE_C;\n                break;\n              case CODE_STOP:\n                done = true;\n                break;\n            }\n          }\n          break;\n        case CODE_CODE_B:\n          if (code < 96) {\n            result.append((char) (' ' + code));\n          } else {\n            if (code != CODE_STOP) {\n              lastCharacterWasPrintable = false;\n            }\n            switch (code) {\n              case CODE_FNC_1:\n              case CODE_FNC_2:\n              case CODE_FNC_3:\n              case CODE_FNC_4_B:\n                // do nothing?\n                break;\n              case CODE_SHIFT:\n                isNextShifted = true;\n                codeSet = CODE_CODE_A;\n                break;\n              case CODE_CODE_A:\n                codeSet = CODE_CODE_A;\n                break;\n              case CODE_CODE_C:\n                codeSet = CODE_CODE_C;\n                break;\n              case CODE_STOP:\n                done = true;\n                break;\n            }\n          }\n          break;\n        case CODE_CODE_C:\n          if (code < 100) {\n            if (code < 10) {\n              result.append('0');\n            }\n            result.append(code);\n          } else {\n            if (code != CODE_STOP) {\n              lastCharacterWasPrintable = false;\n            }\n            switch (code) {\n              case CODE_FNC_1:\n                // do nothing?\n                break;\n              case CODE_CODE_A:\n                codeSet = CODE_CODE_A;\n                break;\n              case CODE_CODE_B:\n                codeSet = CODE_CODE_B;\n                break;\n              case CODE_STOP:\n                done = true;\n                break;\n            }\n          }\n          break;\n      }\n\n      // Unshift back to another code set if we were shifted\n      if (unshift) {\n        codeSet = codeSet == CODE_CODE_A ? CODE_CODE_B : CODE_CODE_A;\n      }\n\n    }\n\n    // Check for ample whitespace following pattern, but, to do this we first need to remember that\n    // we fudged decoding CODE_STOP since it actually has 7 bars, not 6. There is a black bar left\n    // to read off. Would be slightly better to properly read. Here we just skip it:\n    nextStart = row.getNextUnset(nextStart);\n    if (!row.isRange(nextStart,\n                     Math.min(row.getSize(), nextStart + (nextStart - lastStart) / 2),\n                     false)) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n\n    // Pull out from sum the value of the penultimate check code\n    checksumTotal -= multiplier * lastCode;\n    // lastCode is the checksum then:\n    if (checksumTotal % 103 != lastCode) {\n      throw ChecksumException.getChecksumInstance();\n    }\n\n    // Need to pull out the check digits from string\n    int resultLength = result.length();\n    if (resultLength == 0) {\n      // false positive\n      throw NotFoundException.getNotFoundInstance();\n    }\n\n    // Only bother if the result had at least one character, and if the checksum digit happened to\n    // be a printable character. If it was just interpreted as a control code, nothing to remove.\n    if (resultLength > 0 && lastCharacterWasPrintable) {\n      if (codeSet == CODE_CODE_C) {\n        result.delete(resultLength - 2, resultLength);\n      } else {\n        result.delete(resultLength - 1, resultLength);\n      }\n    }\n\n    float left = (float) (startPatternInfo[1] + startPatternInfo[0]) / 2.0f;\n    float right = (float) (nextStart + lastStart) / 2.0f;\n\n    int rawCodesSize = rawCodes.size();\n    byte[] rawBytes = new byte[rawCodesSize];\n    for (int i = 0; i < rawCodesSize; i++) {\n      rawBytes[i] = rawCodes.get(i);\n    }\n\n    return new Result(\n        result.toString(),\n        rawBytes,\n        new ResultPoint[]{\n            new ResultPoint(left, (float) rowNumber),\n            new ResultPoint(right, (float) rowNumber)},\n        BarcodeFormat.CODE_128);\n\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/Code128Writer.java",
    "content": "/*\n * Copyright 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.oned;\n\nimport com.google.zxing.BarcodeFormat;\nimport com.google.zxing.EncodeHintType;\nimport com.google.zxing.WriterException;\nimport com.google.zxing.common.BitMatrix;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Map;\n\n/**\n * This object renders a CODE128 code as a {@link BitMatrix}.\n * \n * @author erik.barbara@gmail.com (Erik Barbara)\n */\npublic final class Code128Writer extends OneDimensionalCodeWriter {\n\n  private static final int CODE_START_B = 104;\n  private static final int CODE_START_C = 105;\n  private static final int CODE_CODE_B = 100;\n  private static final int CODE_CODE_C = 99;\n  private static final int CODE_STOP = 106;\n\n  // Dummy characters used to specify control characters in input\n  private static final char ESCAPE_FNC_1 = '\\u00f1';\n  private static final char ESCAPE_FNC_2 = '\\u00f2';\n  private static final char ESCAPE_FNC_3 = '\\u00f3';\n  private static final char ESCAPE_FNC_4 = '\\u00f4';\n\n  private static final int CODE_FNC_1 = 102;   // Code A, Code B, Code C\n  private static final int CODE_FNC_2 = 97;    // Code A, Code B\n  private static final int CODE_FNC_3 = 96;    // Code A, Code B\n  private static final int CODE_FNC_4_B = 100; // Code B\n\n  @Override\n  public BitMatrix encode(String contents,\n                          BarcodeFormat format,\n                          int width,\n                          int height,\n                          Map<EncodeHintType,?> hints) throws WriterException {\n    if (format != BarcodeFormat.CODE_128) {\n      throw new IllegalArgumentException(\"Can only encode CODE_128, but got \" + format);\n    }\n    return super.encode(contents, format, width, height, hints);\n  }\n\n  @Override\n  public boolean[] encode(String contents) {\n    int length = contents.length();\n    // Check length\n    if (length < 1 || length > 80) {\n      throw new IllegalArgumentException(\n          \"Contents length should be between 1 and 80 characters, but got \" + length);\n    }\n    // Check content\n    for (int i = 0; i < length; i++) {\n      char c = contents.charAt(i);\n      if (c < ' ' || c > '~') {\n        switch (c) {\n          case ESCAPE_FNC_1:\n          case ESCAPE_FNC_2:\n          case ESCAPE_FNC_3:\n          case ESCAPE_FNC_4:\n            break;\n          default:\n            throw new IllegalArgumentException(\"Bad character in input: \" + c);\n        }\n      }\n    }\n    \n    Collection<int[]> patterns = new ArrayList<int[]>(); // temporary storage for patterns\n    int checkSum = 0;\n    int checkWeight = 1;\n    int codeSet = 0; // selected code (CODE_CODE_B or CODE_CODE_C)\n    int position = 0; // position in contents\n    \n    while (position < length) {\n      //Select code to use\n      int requiredDigitCount = codeSet == CODE_CODE_C ? 2 : 4;\n      int newCodeSet;\n      if (isDigits(contents, position, requiredDigitCount)) {\n        newCodeSet = CODE_CODE_C;\n      } else {\n        newCodeSet = CODE_CODE_B;\n      }\n      \n      //Get the pattern index\n      int patternIndex;\n      if (newCodeSet == codeSet) {\n        // Encode the current character\n        if (codeSet == CODE_CODE_B) {\n          patternIndex = contents.charAt(position) - ' ';\n          position += 1;\n        } else { // CODE_CODE_C\n          switch (contents.charAt(position)) {\n            case ESCAPE_FNC_1:\n              patternIndex = CODE_FNC_1;\n              position++;\n              break;\n            case ESCAPE_FNC_2:\n              patternIndex = CODE_FNC_2;\n              position++;\n              break;\n            case ESCAPE_FNC_3:\n              patternIndex = CODE_FNC_3;\n              position++;\n              break;\n            case ESCAPE_FNC_4:\n              patternIndex = CODE_FNC_4_B; // FIXME if this ever outputs Code A\n              position++;\n              break;\n            default:\n              patternIndex = Integer.parseInt(contents.substring(position, position + 2));\n              position += 2;\n              break;\n          }\n        }\n      } else {\n        // Should we change the current code?\n        // Do we have a code set?\n        if (codeSet == 0) {\n          // No, we don't have a code set\n          if (newCodeSet == CODE_CODE_B) {\n            patternIndex = CODE_START_B;\n          } else {\n            // CODE_CODE_C\n            patternIndex = CODE_START_C;\n          }\n        } else {\n          // Yes, we have a code set\n          patternIndex = newCodeSet;\n        }\n        codeSet = newCodeSet;\n      }\n      \n      // Get the pattern\n      patterns.add(Code128Reader.CODE_PATTERNS[patternIndex]);\n      \n      // Compute checksum\n      checkSum += patternIndex * checkWeight;\n      if (position != 0) {\n        checkWeight++;\n      }\n    }\n    \n    // Compute and append checksum\n    checkSum %= 103;\n    patterns.add(Code128Reader.CODE_PATTERNS[checkSum]);\n    \n    // Append stop code\n    patterns.add(Code128Reader.CODE_PATTERNS[CODE_STOP]);\n    \n    // Compute code width\n    int codeWidth = 0;\n    for (int[] pattern : patterns) {\n      for (int width : pattern) {\n        codeWidth += width;\n      }\n    }\n    \n    // Compute result\n    boolean[] result = new boolean[codeWidth];\n    int pos = 0;\n    for (int[] pattern : patterns) {\n      pos += appendPattern(result, pos, pattern, true);\n    }\n    \n    return result;\n  }\n\n  private static boolean isDigits(CharSequence value, int start, int length) {\n    int end = start + length;\n    int last = value.length();\n    for (int i = start; i < end && i < last; i++) {\n      char c = value.charAt(i);\n      if (c < '0' || c > '9') {\n        if (c != ESCAPE_FNC_1) {\n          return false;\n        }\n        end++; // ignore FNC_1\n      }\n    }\n    return end <= last; // end > last if we've run out of string\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/Code39Reader.java",
    "content": "/*\n * Copyright 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.oned;\n\nimport com.google.zxing.BarcodeFormat;\nimport com.google.zxing.ChecksumException;\nimport com.google.zxing.DecodeHintType;\nimport com.google.zxing.FormatException;\nimport com.google.zxing.NotFoundException;\nimport com.google.zxing.Result;\nimport com.google.zxing.ResultPoint;\nimport com.google.zxing.common.BitArray;\n\nimport java.util.Map;\n\n/**\n * <p>Decodes Code 39 barcodes. This does not support \"Full ASCII Code 39\" yet.</p>\n *\n * @author Sean Owen\n * @see Code93Reader\n */\npublic final class Code39Reader extends OneDReader {\n\n  static final String ALPHABET_STRING = \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. *$/+%\";\n  private static final char[] ALPHABET = ALPHABET_STRING.toCharArray();\n\n  /**\n   * These represent the encodings of characters, as patterns of wide and narrow bars.\n   * The 9 least-significant bits of each int correspond to the pattern of wide and narrow,\n   * with 1s representing \"wide\" and 0s representing narrow.\n   */\n  static final int[] CHARACTER_ENCODINGS = {\n      0x034, 0x121, 0x061, 0x160, 0x031, 0x130, 0x070, 0x025, 0x124, 0x064, // 0-9\n      0x109, 0x049, 0x148, 0x019, 0x118, 0x058, 0x00D, 0x10C, 0x04C, 0x01C, // A-J\n      0x103, 0x043, 0x142, 0x013, 0x112, 0x052, 0x007, 0x106, 0x046, 0x016, // K-T\n      0x181, 0x0C1, 0x1C0, 0x091, 0x190, 0x0D0, 0x085, 0x184, 0x0C4, 0x094, // U-*\n      0x0A8, 0x0A2, 0x08A, 0x02A // $-%\n  };\n\n  private static final int ASTERISK_ENCODING = CHARACTER_ENCODINGS[39];\n\n  private final boolean usingCheckDigit;\n  private final boolean extendedMode;\n\n  /**\n   * Creates a reader that assumes all encoded data is data, and does not treat the final\n   * character as a check digit. It will not decoded \"extended Code 39\" sequences.\n   */\n  public Code39Reader() {\n    usingCheckDigit = false;\n    extendedMode = false;\n  }\n\n  /**\n   * Creates a reader that can be configured to check the last character as a check digit.\n   * It will not decoded \"extended Code 39\" sequences.\n   *\n   * @param usingCheckDigit if true, treat the last data character as a check digit, not\n   * data, and verify that the checksum passes.\n   */\n  public Code39Reader(boolean usingCheckDigit) {\n    this.usingCheckDigit = usingCheckDigit;\n    this.extendedMode = false;\n  }\n\n  /**\n   * Creates a reader that can be configured to check the last character as a check digit,\n   * or optionally attempt to decode \"extended Code 39\" sequences that are used to encode\n   * the full ASCII character set.\n   *\n   * @param usingCheckDigit if true, treat the last data character as a check digit, not\n   * data, and verify that the checksum passes.\n   * @param extendedMode if true, will attempt to decode extended Code 39 sequences in the\n   * text.\n   */\n  public Code39Reader(boolean usingCheckDigit, boolean extendedMode) {\n    this.usingCheckDigit = usingCheckDigit;\n    this.extendedMode = extendedMode;\n  }\n\n  @Override\n  public Result decodeRow(int rowNumber, BitArray row, Map<DecodeHintType,?> hints)\n      throws NotFoundException, ChecksumException, FormatException {\n\n    int[] counters = new int[9];\n    int[] start = findAsteriskPattern(row, counters);\n    // Read off white space    \n    int nextStart = row.getNextSet(start[1]);\n    int end = row.getSize();\n\n    StringBuilder result = new StringBuilder(20);\n    char decodedChar;\n    int lastStart;\n    do {\n      recordPattern(row, nextStart, counters);\n      int pattern = toNarrowWidePattern(counters);\n      if (pattern < 0) {\n        throw NotFoundException.getNotFoundInstance();\n      }\n      decodedChar = patternToChar(pattern);\n      result.append(decodedChar);\n      lastStart = nextStart;\n      for (int counter : counters) {\n        nextStart += counter;\n      }\n      // Read off white space\n      nextStart = row.getNextSet(nextStart);\n    } while (decodedChar != '*');\n    result.setLength(result.length() - 1); // remove asterisk\n\n    // Look for whitespace after pattern:\n    int lastPatternSize = 0;\n    for (int counter : counters) {\n      lastPatternSize += counter;\n    }\n    int whiteSpaceAfterEnd = nextStart - lastStart - lastPatternSize;\n    // If 50% of last pattern size, following last pattern, is not whitespace, fail\n    // (but if it's whitespace to the very end of the image, that's OK)\n    if (nextStart != end && (whiteSpaceAfterEnd >> 1) < lastPatternSize) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n\n    if (usingCheckDigit) {\n      int max = result.length() - 1;\n      int total = 0;\n      for (int i = 0; i < max; i++) {\n        total += ALPHABET_STRING.indexOf(result.charAt(i));\n      }\n      if (result.charAt(max) != ALPHABET[total % 43]) {\n        throw ChecksumException.getChecksumInstance();\n      }\n      result.setLength(max);\n    }\n\n    if (result.length() == 0) {\n      // false positive\n      throw NotFoundException.getNotFoundInstance();\n    }\n\n    String resultString;\n    if (extendedMode) {\n      resultString = decodeExtended(result);\n    } else {\n      resultString = result.toString();\n    }\n\n    float left = (float) (start[1] + start[0]) / 2.0f;\n    float right = (float) (nextStart + lastStart) / 2.0f;\n    return new Result(\n        resultString,\n        null,\n        new ResultPoint[]{\n            new ResultPoint(left, (float) rowNumber),\n            new ResultPoint(right, (float) rowNumber)},\n        BarcodeFormat.CODE_39);\n\n  }\n\n  private static int[] findAsteriskPattern(BitArray row, int[] counters) throws NotFoundException {\n    int width = row.getSize();\n    int rowOffset = row.getNextSet(0);\n\n    int counterPosition = 0;\n    int patternStart = rowOffset;\n    boolean isWhite = false;\n    int patternLength = counters.length;\n\n    for (int i = rowOffset; i < width; i++) {\n      if (row.get(i) ^ isWhite) {\n        counters[counterPosition]++;\n      } else {\n        if (counterPosition == patternLength - 1) {\n          // Look for whitespace before start pattern, >= 50% of width of start pattern\n          if (toNarrowWidePattern(counters) == ASTERISK_ENCODING &&\n              row.isRange(Math.max(0, patternStart - ((i - patternStart) >> 1)), patternStart, false)) {\n            return new int[]{patternStart, i};\n          }\n          patternStart += counters[0] + counters[1];\n          System.arraycopy(counters, 2, counters, 0, patternLength - 2);\n          counters[patternLength - 2] = 0;\n          counters[patternLength - 1] = 0;\n          counterPosition--;\n        } else {\n          counterPosition++;\n        }\n        counters[counterPosition] = 1;\n        isWhite = !isWhite;\n      }\n    }\n    throw NotFoundException.getNotFoundInstance();\n  }\n\n  // For efficiency, returns -1 on failure. Not throwing here saved as many as 700 exceptions\n  // per image when using some of our blackbox images.\n  private static int toNarrowWidePattern(int[] counters) {\n    int numCounters = counters.length;\n    int maxNarrowCounter = 0;\n    int wideCounters;\n    do {\n      int minCounter = Integer.MAX_VALUE;\n      for (int counter : counters) {\n        if (counter < minCounter && counter > maxNarrowCounter) {\n          minCounter = counter;\n        }\n      }\n      maxNarrowCounter = minCounter;\n      wideCounters = 0;\n      int totalWideCountersWidth = 0;\n      int pattern = 0;\n      for (int i = 0; i < numCounters; i++) {\n        int counter = counters[i];\n        if (counters[i] > maxNarrowCounter) {\n          pattern |= 1 << (numCounters - 1 - i);\n          wideCounters++;\n          totalWideCountersWidth += counter;\n        }\n      }\n      if (wideCounters == 3) {\n        // Found 3 wide counters, but are they close enough in width?\n        // We can perform a cheap, conservative check to see if any individual\n        // counter is more than 1.5 times the average:\n        for (int i = 0; i < numCounters && wideCounters > 0; i++) {\n          int counter = counters[i];\n          if (counters[i] > maxNarrowCounter) {\n            wideCounters--;\n            // totalWideCountersWidth = 3 * average, so this checks if counter >= 3/2 * average\n            if ((counter << 1) >= totalWideCountersWidth) {\n              return -1;\n            }\n          }\n        }\n        return pattern;\n      }\n    } while (wideCounters > 3);\n    return -1;\n  }\n\n  private static char patternToChar(int pattern) throws NotFoundException {\n    for (int i = 0; i < CHARACTER_ENCODINGS.length; i++) {\n      if (CHARACTER_ENCODINGS[i] == pattern) {\n        return ALPHABET[i];\n      }\n    }\n    throw NotFoundException.getNotFoundInstance();\n  }\n\n  private static String decodeExtended(CharSequence encoded) throws FormatException {\n    int length = encoded.length();\n    StringBuilder decoded = new StringBuilder(length);\n    for (int i = 0; i < length; i++) {\n      char c = encoded.charAt(i);\n      if (c == '+' || c == '$' || c == '%' || c == '/') {\n        char next = encoded.charAt(i + 1);\n        char decodedChar = '\\0';\n        switch (c) {\n          case '+':\n            // +A to +Z map to a to z\n            if (next >= 'A' && next <= 'Z') {\n              decodedChar = (char) (next + 32);\n            } else {\n              throw FormatException.getFormatInstance();\n            }\n            break;\n          case '$':\n            // $A to $Z map to control codes SH to SB\n            if (next >= 'A' && next <= 'Z') {\n              decodedChar = (char) (next - 64);\n            } else {\n              throw FormatException.getFormatInstance();\n            }\n            break;\n          case '%':\n            // %A to %E map to control codes ESC to US\n            if (next >= 'A' && next <= 'E') {\n              decodedChar = (char) (next - 38);\n            } else if (next >= 'F' && next <= 'W') {\n              decodedChar = (char) (next - 11);\n            } else {\n              throw FormatException.getFormatInstance();\n            }\n            break;\n          case '/':\n            // /A to /O map to ! to , and /Z maps to :\n            if (next >= 'A' && next <= 'O') {\n              decodedChar = (char) (next - 32);\n            } else if (next == 'Z') {\n              decodedChar = ':';\n            } else {\n              throw FormatException.getFormatInstance();\n            }\n            break;\n        }\n        decoded.append(decodedChar);\n        // bump up i again since we read two characters\n        i++;\n      } else {\n        decoded.append(c);\n      }\n    }\n    return decoded.toString();\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/Code39Writer.java",
    "content": "/*\n * Copyright 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.oned;\n\nimport com.google.zxing.BarcodeFormat;\nimport com.google.zxing.EncodeHintType;\nimport com.google.zxing.WriterException;\nimport com.google.zxing.common.BitMatrix;\n\nimport java.util.Map;\n\n/**\n * This object renders a CODE39 code as a {@link BitMatrix}.\n * \n * @author erik.barbara@gmail.com (Erik Barbara)\n */\npublic final class Code39Writer extends OneDimensionalCodeWriter {\n\n  @Override\n  public BitMatrix encode(String contents,\n                          BarcodeFormat format,\n                          int width,\n                          int height,\n                          Map<EncodeHintType,?> hints) throws WriterException {\n    if (format != BarcodeFormat.CODE_39) {\n      throw new IllegalArgumentException(\"Can only encode CODE_39, but got \" + format);\n    }\n    return super.encode(contents, format, width, height, hints);\n  }\n\n  @Override\n  public boolean[] encode(String contents) {\n    int length = contents.length();\n    if (length > 80) {\n      throw new IllegalArgumentException(\n          \"Requested contents should be less than 80 digits long, but got \" + length);\n    }\n\n    int[] widths = new int[9];\n    int codeWidth = 24 + 1 + length;\n    for (int i = 0; i < length; i++) {\n      int indexInString = Code39Reader.ALPHABET_STRING.indexOf(contents.charAt(i));\n      toIntArray(Code39Reader.CHARACTER_ENCODINGS[indexInString], widths);\n      for (int width : widths) {\n        codeWidth += width;\n      }\n    }\n    boolean[] result = new boolean[codeWidth];\n    toIntArray(Code39Reader.CHARACTER_ENCODINGS[39], widths);\n    int pos = appendPattern(result, 0, widths, true);\n    int[] narrowWhite = {1};\n    pos += appendPattern(result, pos, narrowWhite, false);\n    //append next character to bytematrix\n    for(int i = length-1; i >= 0; i--) {\n      int indexInString = Code39Reader.ALPHABET_STRING.indexOf(contents.charAt(i));\n      toIntArray(Code39Reader.CHARACTER_ENCODINGS[indexInString], widths);\n      pos += appendPattern(result, pos, widths, true);\n      pos += appendPattern(result, pos, narrowWhite, false);\n    }\n    toIntArray(Code39Reader.CHARACTER_ENCODINGS[39], widths);\n    pos += appendPattern(result, pos, widths, true);\n    return result;\n  }\n\n  private static void toIntArray(int a, int[] toReturn) {\n    for (int i = 0; i < 9; i++) {\n      int temp = a & (1 << i);\n      toReturn[i] = temp == 0 ? 1 : 2;\n    }\n  }\n\n}"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/Code93Reader.java",
    "content": "/*\n * Copyright 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.oned;\n\nimport com.google.zxing.BarcodeFormat;\nimport com.google.zxing.ChecksumException;\nimport com.google.zxing.DecodeHintType;\nimport com.google.zxing.FormatException;\nimport com.google.zxing.NotFoundException;\nimport com.google.zxing.Result;\nimport com.google.zxing.ResultPoint;\nimport com.google.zxing.common.BitArray;\n\nimport java.util.Map;\n\n/**\n * <p>Decodes Code 93 barcodes.</p>\n *\n * @author Sean Owen\n * @see Code39Reader\n */\npublic final class Code93Reader extends OneDReader {\n\n  // Note that 'abcd' are dummy characters in place of control characters.\n  private static final String ALPHABET_STRING = \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%abcd*\";\n  private static final char[] ALPHABET = ALPHABET_STRING.toCharArray();\n\n  /**\n   * These represent the encodings of characters, as patterns of wide and narrow bars.\n   * The 9 least-significant bits of each int correspond to the pattern of wide and narrow.\n   */\n  private static final int[] CHARACTER_ENCODINGS = {\n      0x114, 0x148, 0x144, 0x142, 0x128, 0x124, 0x122, 0x150, 0x112, 0x10A, // 0-9\n      0x1A8, 0x1A4, 0x1A2, 0x194, 0x192, 0x18A, 0x168, 0x164, 0x162, 0x134, // A-J\n      0x11A, 0x158, 0x14C, 0x146, 0x12C, 0x116, 0x1B4, 0x1B2, 0x1AC, 0x1A6, // K-T\n      0x196, 0x19A, 0x16C, 0x166, 0x136, 0x13A, // U-Z\n      0x12E, 0x1D4, 0x1D2, 0x1CA, 0x16E, 0x176, 0x1AE, // - - %\n      0x126, 0x1DA, 0x1D6, 0x132, 0x15E, // Control chars? $-*\n  };\n  private static final int ASTERISK_ENCODING = CHARACTER_ENCODINGS[47];\n\n  @Override\n  public Result decodeRow(int rowNumber, BitArray row, Map<DecodeHintType,?> hints)\n      throws NotFoundException, ChecksumException, FormatException {\n\n    int[] start = findAsteriskPattern(row);\n    // Read off white space    \n    int nextStart = row.getNextSet(start[1]);\n    int end = row.getSize();\n\n    StringBuilder result = new StringBuilder(20);\n    int[] counters = new int[6];\n    char decodedChar;\n    int lastStart;\n    do {\n      recordPattern(row, nextStart, counters);\n      int pattern = toPattern(counters);\n      if (pattern < 0) {\n        throw NotFoundException.getNotFoundInstance();\n      }\n      decodedChar = patternToChar(pattern);\n      result.append(decodedChar);\n      lastStart = nextStart;\n      for (int counter : counters) {\n        nextStart += counter;\n      }\n      // Read off white space\n      nextStart = row.getNextSet(nextStart);\n    } while (decodedChar != '*');\n    result.deleteCharAt(result.length() - 1); // remove asterisk\n\n    // Should be at least one more black module\n    if (nextStart == end || !row.get(nextStart)) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n\n    if (result.length() < 2) {\n      // false positive -- need at least 2 checksum digits\n      throw NotFoundException.getNotFoundInstance();\n    }\n\n    checkChecksums(result);\n    // Remove checksum digits\n    result.setLength(result.length() - 2);\n\n    String resultString = decodeExtended(result);\n\n    float left = (float) (start[1] + start[0]) / 2.0f;\n    float right = (float) (nextStart + lastStart) / 2.0f;\n    return new Result(\n        resultString,\n        null,\n        new ResultPoint[]{\n            new ResultPoint(left, (float) rowNumber),\n            new ResultPoint(right, (float) rowNumber)},\n        BarcodeFormat.CODE_93);\n\n  }\n\n  private static int[] findAsteriskPattern(BitArray row) throws NotFoundException {\n    int width = row.getSize();\n    int rowOffset = row.getNextSet(0);\n\n    int counterPosition = 0;\n    int[] counters = new int[6];\n    int patternStart = rowOffset;\n    boolean isWhite = false;\n    int patternLength = counters.length;\n\n    for (int i = rowOffset; i < width; i++) {\n      if (row.get(i) ^ isWhite) {\n        counters[counterPosition]++;\n      } else {\n        if (counterPosition == patternLength - 1) {\n          if (toPattern(counters) == ASTERISK_ENCODING) {\n            return new int[]{patternStart, i};\n          }\n          patternStart += counters[0] + counters[1];\n          System.arraycopy(counters, 2, counters, 0, patternLength - 2);\n          counters[patternLength - 2] = 0;\n          counters[patternLength - 1] = 0;\n          counterPosition--;\n        } else {\n          counterPosition++;\n        }\n        counters[counterPosition] = 1;\n        isWhite = !isWhite;\n      }\n    }\n    throw NotFoundException.getNotFoundInstance();\n  }\n\n  private static int toPattern(int[] counters) {\n    int max = counters.length;\n    int sum = 0;\n    for (int counter : counters) {\n      sum += counter;\n    }\n    int pattern = 0;\n    for (int i = 0; i < max; i++) {\n      int scaledShifted = (counters[i] << INTEGER_MATH_SHIFT) * 9 / sum;\n      int scaledUnshifted = scaledShifted >> INTEGER_MATH_SHIFT;\n      if ((scaledShifted & 0xFF) > 0x7F) {\n        scaledUnshifted++;\n      }\n      if (scaledUnshifted < 1 || scaledUnshifted > 4) {\n        return -1;\n      }\n      if ((i & 0x01) == 0) {\n        for (int j = 0; j < scaledUnshifted; j++) {\n          pattern = (pattern << 1) | 0x01;\n        }\n      } else {\n        pattern <<= scaledUnshifted;\n      }\n    }\n    return pattern;\n  }\n\n  private static char patternToChar(int pattern) throws NotFoundException {\n    for (int i = 0; i < CHARACTER_ENCODINGS.length; i++) {\n      if (CHARACTER_ENCODINGS[i] == pattern) {\n        return ALPHABET[i];\n      }\n    }\n    throw NotFoundException.getNotFoundInstance();\n  }\n\n  private static String decodeExtended(CharSequence encoded) throws FormatException {\n    int length = encoded.length();\n    StringBuilder decoded = new StringBuilder(length);\n    for (int i = 0; i < length; i++) {\n      char c = encoded.charAt(i);\n      if (c >= 'a' && c <= 'd') {\n        if (i >= length - 1) {\n          throw FormatException.getFormatInstance();\n        }\n        char next = encoded.charAt(i + 1);\n        char decodedChar = '\\0';\n        switch (c) {\n          case 'd':\n            // +A to +Z map to a to z\n            if (next >= 'A' && next <= 'Z') {\n              decodedChar = (char) (next + 32);\n            } else {\n              throw FormatException.getFormatInstance();\n            }\n            break;\n          case 'a':\n            // $A to $Z map to control codes SH to SB\n            if (next >= 'A' && next <= 'Z') {\n              decodedChar = (char) (next - 64);\n            } else {\n              throw FormatException.getFormatInstance();\n            }\n            break;\n          case 'b':\n            // %A to %E map to control codes ESC to US\n            if (next >= 'A' && next <= 'E') {\n              decodedChar = (char) (next - 38);\n            } else if (next >= 'F' && next <= 'W') {\n              decodedChar = (char) (next - 11);\n            } else {\n              throw FormatException.getFormatInstance();\n            }\n            break;\n          case 'c':\n            // /A to /O map to ! to , and /Z maps to :\n            if (next >= 'A' && next <= 'O') {\n              decodedChar = (char) (next - 32);\n            } else if (next == 'Z') {\n              decodedChar = ':';\n            } else {\n              throw FormatException.getFormatInstance();\n            }\n            break;\n        }\n        decoded.append(decodedChar);\n        // bump up i again since we read two characters\n        i++;\n      } else {\n        decoded.append(c);\n      }\n    }\n    return decoded.toString();\n  }\n\n  private static void checkChecksums(CharSequence result) throws ChecksumException {\n    int length = result.length();\n    checkOneChecksum(result, length - 2, 20);\n    checkOneChecksum(result, length - 1, 15);\n  }\n\n  private static void checkOneChecksum(CharSequence result, int checkPosition, int weightMax)\n      throws ChecksumException {\n    int weight = 1;\n    int total = 0;\n    for (int i = checkPosition - 1; i >= 0; i--) {\n      total += weight * ALPHABET_STRING.indexOf(result.charAt(i));\n      if (++weight > weightMax) {\n        weight = 1;\n      }\n    }\n    if (result.charAt(checkPosition) != ALPHABET[total % 47]) {\n      throw ChecksumException.getChecksumInstance();\n    }\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/EAN13Reader.java",
    "content": "/*\n * Copyright 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.oned;\n\nimport com.google.zxing.BarcodeFormat;\nimport com.google.zxing.NotFoundException;\nimport com.google.zxing.common.BitArray;\n\n/**\n * <p>Implements decoding of the EAN-13 format.</p>\n *\n * @author dswitkin@google.com (Daniel Switkin)\n * @author Sean Owen\n * @author alasdair@google.com (Alasdair Mackintosh)\n */\npublic final class EAN13Reader extends UPCEANReader {\n\n  // For an EAN-13 barcode, the first digit is represented by the parities used\n  // to encode the next six digits, according to the table below. For example,\n  // if the barcode is 5 123456 789012 then the value of the first digit is\n  // signified by using odd for '1', even for '2', even for '3', odd for '4',\n  // odd for '5', and even for '6'. See http://en.wikipedia.org/wiki/EAN-13\n  //\n  //                Parity of next 6 digits\n  //    Digit   0     1     2     3     4     5\n  //       0    Odd   Odd   Odd   Odd   Odd   Odd\n  //       1    Odd   Odd   Even  Odd   Even  Even\n  //       2    Odd   Odd   Even  Even  Odd   Even\n  //       3    Odd   Odd   Even  Even  Even  Odd\n  //       4    Odd   Even  Odd   Odd   Even  Even\n  //       5    Odd   Even  Even  Odd   Odd   Even\n  //       6    Odd   Even  Even  Even  Odd   Odd\n  //       7    Odd   Even  Odd   Even  Odd   Even\n  //       8    Odd   Even  Odd   Even  Even  Odd\n  //       9    Odd   Even  Even  Odd   Even  Odd\n  //\n  // Note that the encoding for '0' uses the same parity as a UPC barcode. Hence\n  // a UPC barcode can be converted to an EAN-13 barcode by prepending a 0.\n  //\n  // The encoding is represented by the following array, which is a bit pattern\n  // using Odd = 0 and Even = 1. For example, 5 is represented by:\n  //\n  //              Odd Even Even Odd Odd Even\n  // in binary:\n  //                0    1    1   0   0    1   == 0x19\n  //\n  static final int[] FIRST_DIGIT_ENCODINGS = {\n      0x00, 0x0B, 0x0D, 0xE, 0x13, 0x19, 0x1C, 0x15, 0x16, 0x1A\n  };\n\n  private final int[] decodeMiddleCounters;\n\n  public EAN13Reader() {\n    decodeMiddleCounters = new int[4];\n  }\n\n  @Override\n  protected int decodeMiddle(BitArray row,\n                             int[] startRange,\n                             StringBuilder resultString) throws NotFoundException {\n    int[] counters = decodeMiddleCounters;\n    counters[0] = 0;\n    counters[1] = 0;\n    counters[2] = 0;\n    counters[3] = 0;\n    int end = row.getSize();\n    int rowOffset = startRange[1];\n\n    int lgPatternFound = 0;\n\n    for (int x = 0; x < 6 && rowOffset < end; x++) {\n      int bestMatch = decodeDigit(row, counters, rowOffset, L_AND_G_PATTERNS);\n      resultString.append((char) ('0' + bestMatch % 10));\n      for (int counter : counters) {\n        rowOffset += counter;\n      }\n      if (bestMatch >= 10) {\n        lgPatternFound |= 1 << (5 - x);\n      }\n    }\n\n    determineFirstDigit(resultString, lgPatternFound);\n\n    int[] middleRange = findGuardPattern(row, rowOffset, true, MIDDLE_PATTERN);\n    rowOffset = middleRange[1];\n\n    for (int x = 0; x < 6 && rowOffset < end; x++) {\n      int bestMatch = decodeDigit(row, counters, rowOffset, L_PATTERNS);\n      resultString.append((char) ('0' + bestMatch));\n      for (int counter : counters) {\n        rowOffset += counter;\n      }\n    }\n\n    return rowOffset;\n  }\n\n  @Override\n  BarcodeFormat getBarcodeFormat() {\n    return BarcodeFormat.EAN_13;\n  }\n\n  /**\n   * Based on pattern of odd-even ('L' and 'G') patterns used to encoded the explicitly-encoded\n   * digits in a barcode, determines the implicitly encoded first digit and adds it to the\n   * result string.\n   *\n   * @param resultString string to insert decoded first digit into\n   * @param lgPatternFound int whose bits indicates the pattern of odd/even L/G patterns used to\n   *  encode digits\n   * @throws NotFoundException if first digit cannot be determined\n   */\n  private static void determineFirstDigit(StringBuilder resultString, int lgPatternFound)\n      throws NotFoundException {\n    for (int d = 0; d < 10; d++) {\n      if (lgPatternFound == FIRST_DIGIT_ENCODINGS[d]) {\n        resultString.insert(0, (char) ('0' + d));\n        return;\n      }\n    }\n    throw NotFoundException.getNotFoundInstance();\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/EAN13Writer.java",
    "content": "/*\n * Copyright 2009 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.oned;\n\nimport com.google.zxing.BarcodeFormat;\nimport com.google.zxing.EncodeHintType;\nimport com.google.zxing.FormatException;\nimport com.google.zxing.WriterException;\nimport com.google.zxing.common.BitMatrix;\n\nimport java.util.Map;\n\n/**\n * This object renders an EAN13 code as a {@link BitMatrix}.\n *\n * @author aripollak@gmail.com (Ari Pollak)\n */\npublic final class EAN13Writer extends UPCEANWriter {\n\n  private static final int CODE_WIDTH = 3 + // start guard\n      (7 * 6) + // left bars\n      5 + // middle guard\n      (7 * 6) + // right bars\n      3; // end guard\n\n  @Override\n  public BitMatrix encode(String contents,\n                          BarcodeFormat format,\n                          int width,\n                          int height,\n                          Map<EncodeHintType,?> hints) throws WriterException {\n    if (format != BarcodeFormat.EAN_13) {\n      throw new IllegalArgumentException(\"Can only encode EAN_13, but got \" + format);\n    }\n\n    return super.encode(contents, format, width, height, hints);\n  }\n\n  @Override\n  public boolean[] encode(String contents) {\n    if (contents.length() != 13) {\n      throw new IllegalArgumentException(\n          \"Requested contents should be 13 digits long, but got \" + contents.length());\n    }\n    try {\n      if (!UPCEANReader.checkStandardUPCEANChecksum(contents)) {\n        throw new IllegalArgumentException(\"Contents do not pass checksum\");\n      }\n    } catch (FormatException fe) {\n      throw new IllegalArgumentException(\"Illegal contents\");\n    }\n\n    int firstDigit = Integer.parseInt(contents.substring(0, 1));\n    int parities = EAN13Reader.FIRST_DIGIT_ENCODINGS[firstDigit];\n    boolean[] result = new boolean[CODE_WIDTH];\n    int pos = 0;\n\n    pos += appendPattern(result, pos, UPCEANReader.START_END_PATTERN, true);\n\n    // See {@link #EAN13Reader} for a description of how the first digit & left bars are encoded\n    for (int i = 1; i <= 6; i++) {\n      int digit = Integer.parseInt(contents.substring(i, i + 1));\n      if ((parities >> (6 - i) & 1) == 1) {\n        digit += 10;\n      }\n      pos += appendPattern(result, pos, UPCEANReader.L_AND_G_PATTERNS[digit], false);\n    }\n\n    pos += appendPattern(result, pos, UPCEANReader.MIDDLE_PATTERN, false);\n\n    for (int i = 7; i <= 12; i++) {\n      int digit = Integer.parseInt(contents.substring(i, i + 1));\n      pos += appendPattern(result, pos, UPCEANReader.L_PATTERNS[digit], true);\n    }\n    pos += appendPattern(result, pos, UPCEANReader.START_END_PATTERN, true);\n\n    return result;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/EAN8Reader.java",
    "content": "/*\n * Copyright 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.oned;\n\nimport com.google.zxing.BarcodeFormat;\nimport com.google.zxing.NotFoundException;\nimport com.google.zxing.common.BitArray;\n\n/**\n * <p>Implements decoding of the EAN-8 format.</p>\n *\n * @author Sean Owen\n */\npublic final class EAN8Reader extends UPCEANReader {\n\n  private final int[] decodeMiddleCounters;\n\n  public EAN8Reader() {\n    decodeMiddleCounters = new int[4];\n  }\n\n  @Override\n  protected int decodeMiddle(BitArray row,\n                             int[] startRange,\n                             StringBuilder result) throws NotFoundException {\n    int[] counters = decodeMiddleCounters;\n    counters[0] = 0;\n    counters[1] = 0;\n    counters[2] = 0;\n    counters[3] = 0;\n    int end = row.getSize();\n    int rowOffset = startRange[1];\n\n    for (int x = 0; x < 4 && rowOffset < end; x++) {\n      int bestMatch = decodeDigit(row, counters, rowOffset, L_PATTERNS);\n      result.append((char) ('0' + bestMatch));\n      for (int counter : counters) {\n        rowOffset += counter;\n      }\n    }\n\n    int[] middleRange = findGuardPattern(row, rowOffset, true, MIDDLE_PATTERN);\n    rowOffset = middleRange[1];\n\n    for (int x = 0; x < 4 && rowOffset < end; x++) {\n      int bestMatch = decodeDigit(row, counters, rowOffset, L_PATTERNS);\n      result.append((char) ('0' + bestMatch));\n      for (int counter : counters) {\n        rowOffset += counter;\n      }\n    }\n\n    return rowOffset;\n  }\n\n  @Override\n  BarcodeFormat getBarcodeFormat() {\n    return BarcodeFormat.EAN_8;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/EAN8Writer.java",
    "content": "/*\n * Copyright 2009 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.oned;\n\nimport com.google.zxing.BarcodeFormat;\nimport com.google.zxing.EncodeHintType;\nimport com.google.zxing.WriterException;\nimport com.google.zxing.common.BitMatrix;\n\nimport java.util.Map;\n\n/**\n * This object renders an EAN8 code as a {@link BitMatrix}.\n *\n * @author aripollak@gmail.com (Ari Pollak)\n */\npublic final class EAN8Writer extends UPCEANWriter {\n\n  private static final int CODE_WIDTH = 3 + // start guard\n      (7 * 4) + // left bars\n      5 + // middle guard\n      (7 * 4) + // right bars\n      3; // end guard\n\n  @Override\n  public BitMatrix encode(String contents,\n                          BarcodeFormat format,\n                          int width,\n                          int height,\n                          Map<EncodeHintType,?> hints) throws WriterException {\n    if (format != BarcodeFormat.EAN_8) {\n      throw new IllegalArgumentException(\"Can only encode EAN_8, but got \"\n          + format);\n    }\n\n    return super.encode(contents, format, width, height, hints);\n  }\n\n  /**\n   * @return a byte array of horizontal pixels (false = white, true = black)\n   */\n  @Override\n  public boolean[] encode(String contents) {\n    if (contents.length() != 8) {\n      throw new IllegalArgumentException(\n          \"Requested contents should be 8 digits long, but got \" + contents.length());\n    }\n\n    boolean[] result = new boolean[CODE_WIDTH];\n    int pos = 0;\n\n    pos += appendPattern(result, pos, UPCEANReader.START_END_PATTERN, true);\n\n    for (int i = 0; i <= 3; i++) {\n      int digit = Integer.parseInt(contents.substring(i, i + 1));\n      pos += appendPattern(result, pos, UPCEANReader.L_PATTERNS[digit], false);\n    }\n\n    pos += appendPattern(result, pos, UPCEANReader.MIDDLE_PATTERN, false);\n\n    for (int i = 4; i <= 7; i++) {\n      int digit = Integer.parseInt(contents.substring(i, i + 1));\n      pos += appendPattern(result, pos, UPCEANReader.L_PATTERNS[digit], true);\n    }\n    pos += appendPattern(result, pos, UPCEANReader.START_END_PATTERN, true);\n\n    return result;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/EANManufacturerOrgSupport.java",
    "content": "/*\n * Copyright (C) 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.oned;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Records EAN prefix to GS1 Member Organization, where the member organization\n * correlates strongly with a country. This is an imperfect means of identifying\n * a country of origin by EAN-13 barcode value. See\n * <a href=\"http://en.wikipedia.org/wiki/List_of_GS1_country_codes\">\n * http://en.wikipedia.org/wiki/List_of_GS1_country_codes</a>.\n *\n * @author Sean Owen\n */\nfinal class EANManufacturerOrgSupport {\n\n  private final List<int[]> ranges = new ArrayList<int[]>();\n  private final List<String> countryIdentifiers = new ArrayList<String>();\n\n  String lookupCountryIdentifier(String productCode) {\n    initIfNeeded();\n    int prefix = Integer.parseInt(productCode.substring(0, 3));\n    int max = ranges.size();\n    for (int i = 0; i < max; i++) {\n      int[] range = ranges.get(i);\n      int start = range[0];\n      if (prefix < start) {\n        return null;\n      }\n      int end = range.length == 1 ? start : range[1];\n      if (prefix <= end) {\n        return countryIdentifiers.get(i);\n      }\n    }\n    return null;\n  }\n  \n  private void add(int[] range, String id) {\n    ranges.add(range);\n    countryIdentifiers.add(id);\n  }\n  \n  private synchronized void initIfNeeded() {\n    if (!ranges.isEmpty()) {\n      return;\n    }\n    add(new int[] {0,19},    \"US/CA\");\n    add(new int[] {30,39},   \"US\");\n    add(new int[] {60,139},  \"US/CA\");\n    add(new int[] {300,379}, \"FR\");\n    add(new int[] {380},     \"BG\");\n    add(new int[] {383},     \"SI\");\n    add(new int[] {385},     \"HR\");\n    add(new int[] {387},     \"BA\");\n    add(new int[] {400,440}, \"DE\");\n    add(new int[] {450,459}, \"JP\");\n    add(new int[] {460,469}, \"RU\");\n    add(new int[] {471},     \"TW\");\n    add(new int[] {474},     \"EE\");\n    add(new int[] {475},     \"LV\");\n    add(new int[] {476},     \"AZ\");\n    add(new int[] {477},     \"LT\");\n    add(new int[] {478},     \"UZ\");\n    add(new int[] {479},     \"LK\");\n    add(new int[] {480},     \"PH\");\n    add(new int[] {481},     \"BY\");\n    add(new int[] {482},     \"UA\");\n    add(new int[] {484},     \"MD\");\n    add(new int[] {485},     \"AM\");\n    add(new int[] {486},     \"GE\");\n    add(new int[] {487},     \"KZ\");\n    add(new int[] {489},     \"HK\");\n    add(new int[] {490,499}, \"JP\");    \n    add(new int[] {500,509}, \"GB\");    \n    add(new int[] {520},     \"GR\");\n    add(new int[] {528},     \"LB\");\n    add(new int[] {529},     \"CY\");\n    add(new int[] {531},     \"MK\");\n    add(new int[] {535},     \"MT\");\n    add(new int[] {539},     \"IE\");\n    add(new int[] {540,549}, \"BE/LU\");    \n    add(new int[] {560},     \"PT\");\n    add(new int[] {569},     \"IS\");\n    add(new int[] {570,579}, \"DK\");\n    add(new int[] {590},     \"PL\");\n    add(new int[] {594},     \"RO\");\n    add(new int[] {599},     \"HU\");\n    add(new int[] {600,601}, \"ZA\");\n    add(new int[] {603},     \"GH\");    \n    add(new int[] {608},     \"BH\");\n    add(new int[] {609},     \"MU\");\n    add(new int[] {611},     \"MA\");\n    add(new int[] {613},     \"DZ\");\n    add(new int[] {616},     \"KE\");\n    add(new int[] {618},     \"CI\");    \n    add(new int[] {619},     \"TN\");\n    add(new int[] {621},     \"SY\");\n    add(new int[] {622},     \"EG\");\n    add(new int[] {624},     \"LY\");\n    add(new int[] {625},     \"JO\");\n    add(new int[] {626},     \"IR\");\n    add(new int[] {627},     \"KW\");\n    add(new int[] {628},     \"SA\");\n    add(new int[] {629},     \"AE\");\n    add(new int[] {640,649}, \"FI\");\n    add(new int[] {690,695}, \"CN\");\n    add(new int[] {700,709}, \"NO\");\n    add(new int[] {729},     \"IL\");\n    add(new int[] {730,739}, \"SE\");\n    add(new int[] {740},     \"GT\");\n    add(new int[] {741},     \"SV\");\n    add(new int[] {742},     \"HN\");\n    add(new int[] {743},     \"NI\");\n    add(new int[] {744},     \"CR\");\n    add(new int[] {745},     \"PA\");\n    add(new int[] {746},     \"DO\");\n    add(new int[] {750},     \"MX\");\n    add(new int[] {754,755}, \"CA\");\n    add(new int[] {759},     \"VE\");\n    add(new int[] {760,769}, \"CH\");\n    add(new int[] {770},     \"CO\");\n    add(new int[] {773},     \"UY\");\n    add(new int[] {775},     \"PE\");\n    add(new int[] {777},     \"BO\");\n    add(new int[] {779},     \"AR\");\n    add(new int[] {780},     \"CL\");\n    add(new int[] {784},     \"PY\");\n    add(new int[] {785},     \"PE\");  \n    add(new int[] {786},     \"EC\");\n    add(new int[] {789,790}, \"BR\");\n    add(new int[] {800,839}, \"IT\");\n    add(new int[] {840,849}, \"ES\");\n    add(new int[] {850},     \"CU\");\n    add(new int[] {858},     \"SK\");\n    add(new int[] {859},     \"CZ\");\n    add(new int[] {860},     \"YU\");\n    add(new int[] {865},     \"MN\");    \n    add(new int[] {867},     \"KP\");\n    add(new int[] {868,869}, \"TR\");\n    add(new int[] {870,879}, \"NL\");\n    add(new int[] {880},     \"KR\");\n    add(new int[] {885},     \"TH\");\n    add(new int[] {888},     \"SG\");\n    add(new int[] {890},     \"IN\");\n    add(new int[] {893},     \"VN\");\n    add(new int[] {896},     \"PK\");    \n    add(new int[] {899},     \"ID\");\n    add(new int[] {900,919}, \"AT\");\n    add(new int[] {930,939}, \"AU\");\n    add(new int[] {940,949}, \"AZ\");\n    add(new int[] {955},     \"MY\");\n    add(new int[] {958},     \"MO\");\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/ITFReader.java",
    "content": "/*\r\n * Copyright 2008 ZXing authors\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage com.google.zxing.oned;\r\n\r\nimport com.google.zxing.BarcodeFormat;\r\nimport com.google.zxing.DecodeHintType;\r\nimport com.google.zxing.FormatException;\r\nimport com.google.zxing.NotFoundException;\r\nimport com.google.zxing.Result;\r\nimport com.google.zxing.ResultPoint;\r\nimport com.google.zxing.common.BitArray;\r\n\r\nimport java.util.Map;\r\n\r\n/**\r\n * <p>Implements decoding of the ITF format, or Interleaved Two of Five.</p>\r\n *\r\n * <p>This Reader will scan ITF barcodes of certain lengths only.\r\n * At the moment it reads length 6, 10, 12, 14, 16, 24, and 44 as these have appeared \"in the wild\". Not all\r\n * lengths are scanned, especially shorter ones, to avoid false positives. This in turn is due to a lack of\r\n * required checksum function.</p>\r\n *\r\n * <p>The checksum is optional and is not applied by this Reader. The consumer of the decoded\r\n * value will have to apply a checksum if required.</p>\r\n *\r\n * <p><a href=\"http://en.wikipedia.org/wiki/Interleaved_2_of_5\">http://en.wikipedia.org/wiki/Interleaved_2_of_5</a>\r\n * is a great reference for Interleaved 2 of 5 information.</p>\r\n *\r\n * @author kevin.osullivan@sita.aero, SITA Lab.\r\n */\r\npublic final class ITFReader extends OneDReader {\r\n\r\n  private static final int MAX_AVG_VARIANCE = (int) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.42f);\r\n  private static final int MAX_INDIVIDUAL_VARIANCE = (int) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.8f);\r\n\r\n  private static final int W = 3; // Pixel width of a wide line\r\n  private static final int N = 1; // Pixed width of a narrow line\r\n\r\n  private static final int[] DEFAULT_ALLOWED_LENGTHS = { 44, 24, 20, 18, 16, 14, 12, 10, 8, 6 };\r\n\r\n  // Stores the actual narrow line width of the image being decoded.\r\n  private int narrowLineWidth = -1;\r\n\r\n  /**\r\n   * Start/end guard pattern.\r\n   *\r\n   * Note: The end pattern is reversed because the row is reversed before\r\n   * searching for the END_PATTERN\r\n   */\r\n  private static final int[] START_PATTERN = {N, N, N, N};\r\n  private static final int[] END_PATTERN_REVERSED = {N, N, W};\r\n\r\n  /**\r\n   * Patterns of Wide / Narrow lines to indicate each digit\r\n   */\r\n  static final int[][] PATTERNS = {\r\n      {N, N, W, W, N}, // 0\r\n      {W, N, N, N, W}, // 1\r\n      {N, W, N, N, W}, // 2\r\n      {W, W, N, N, N}, // 3\r\n      {N, N, W, N, W}, // 4\r\n      {W, N, W, N, N}, // 5\r\n      {N, W, W, N, N}, // 6\r\n      {N, N, N, W, W}, // 7\r\n      {W, N, N, W, N}, // 8\r\n      {N, W, N, W, N}  // 9\r\n  };\r\n\r\n  @Override\r\n  public Result decodeRow(int rowNumber, BitArray row, Map<DecodeHintType,?> hints)\r\n      throws FormatException, NotFoundException {\r\n\r\n    // Find out where the Middle section (payload) starts & ends\r\n    int[] startRange = decodeStart(row);\r\n    int[] endRange = decodeEnd(row);\r\n\r\n    StringBuilder result = new StringBuilder(20);\r\n    decodeMiddle(row, startRange[1], endRange[0], result);\r\n    String resultString = result.toString();\r\n\r\n    int[] allowedLengths = null;\r\n    if (hints != null) {\r\n      allowedLengths = (int[]) hints.get(DecodeHintType.ALLOWED_LENGTHS);\r\n\r\n    }\r\n    if (allowedLengths == null) {\r\n      allowedLengths = DEFAULT_ALLOWED_LENGTHS;\r\n    }\r\n\r\n    // To avoid false positives with 2D barcodes (and other patterns), make\r\n    // an assumption that the decoded string must be 6, 10 or 14 digits.\r\n    int length = resultString.length();\r\n    boolean lengthOK = false;\r\n    for (int allowedLength : allowedLengths) {\r\n      if (length == allowedLength) {\r\n        lengthOK = true;\r\n        break;\r\n      }\r\n    }\r\n    if (!lengthOK) {\r\n      throw FormatException.getFormatInstance();\r\n    }\r\n\r\n    return new Result(\r\n        resultString,\r\n        null, // no natural byte representation for these barcodes\r\n        new ResultPoint[] { new ResultPoint(startRange[1], (float) rowNumber),\r\n                            new ResultPoint(endRange[0], (float) rowNumber)},\r\n        BarcodeFormat.ITF);\r\n  }\r\n\r\n  /**\r\n   * @param row          row of black/white values to search\r\n   * @param payloadStart offset of start pattern\r\n   * @param resultString {@link StringBuilder} to append decoded chars to\r\n   * @throws NotFoundException if decoding could not complete successfully\r\n   */\r\n  private static void decodeMiddle(BitArray row,\r\n                                   int payloadStart,\r\n                                   int payloadEnd,\r\n                                   StringBuilder resultString) throws NotFoundException {\r\n\r\n    // Digits are interleaved in pairs - 5 black lines for one digit, and the\r\n    // 5\r\n    // interleaved white lines for the second digit.\r\n    // Therefore, need to scan 10 lines and then\r\n    // split these into two arrays\r\n    int[] counterDigitPair = new int[10];\r\n    int[] counterBlack = new int[5];\r\n    int[] counterWhite = new int[5];\r\n\r\n    while (payloadStart < payloadEnd) {\r\n\r\n      // Get 10 runs of black/white.\r\n      recordPattern(row, payloadStart, counterDigitPair);\r\n      // Split them into each array\r\n      for (int k = 0; k < 5; k++) {\r\n        int twoK = k << 1;\r\n        counterBlack[k] = counterDigitPair[twoK];\r\n        counterWhite[k] = counterDigitPair[twoK + 1];\r\n      }\r\n\r\n      int bestMatch = decodeDigit(counterBlack);\r\n      resultString.append((char) ('0' + bestMatch));\r\n      bestMatch = decodeDigit(counterWhite);\r\n      resultString.append((char) ('0' + bestMatch));\r\n\r\n      for (int counterDigit : counterDigitPair) {\r\n        payloadStart += counterDigit;\r\n      }\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Identify where the start of the middle / payload section starts.\r\n   *\r\n   * @param row row of black/white values to search\r\n   * @return Array, containing index of start of 'start block' and end of\r\n   *         'start block'\r\n   * @throws NotFoundException\r\n   */\r\n  int[] decodeStart(BitArray row) throws NotFoundException {\r\n    int endStart = skipWhiteSpace(row);\r\n    int[] startPattern = findGuardPattern(row, endStart, START_PATTERN);\r\n\r\n    // Determine the width of a narrow line in pixels. We can do this by\r\n    // getting the width of the start pattern and dividing by 4 because its\r\n    // made up of 4 narrow lines.\r\n    this.narrowLineWidth = (startPattern[1] - startPattern[0]) >> 2;\r\n\r\n    validateQuietZone(row, startPattern[0]);\r\n\r\n    return startPattern;\r\n  }\r\n\r\n  /**\r\n   * The start & end patterns must be pre/post fixed by a quiet zone. This\r\n   * zone must be at least 10 times the width of a narrow line.  Scan back until\r\n   * we either get to the start of the barcode or match the necessary number of\r\n   * quiet zone pixels.\r\n   *\r\n   * Note: Its assumed the row is reversed when using this method to find\r\n   * quiet zone after the end pattern.\r\n   *\r\n   * ref: http://www.barcode-1.net/i25code.html\r\n   *\r\n   * @param row bit array representing the scanned barcode.\r\n   * @param startPattern index into row of the start or end pattern.\r\n   * @throws NotFoundException if the quiet zone cannot be found, a ReaderException is thrown.\r\n   */\r\n  private void validateQuietZone(BitArray row, int startPattern) throws NotFoundException {\r\n\r\n    int quietCount = this.narrowLineWidth * 10;  // expect to find this many pixels of quiet zone\r\n\r\n    for (int i = startPattern - 1; quietCount > 0 && i >= 0; i--) {\r\n      if (row.get(i)) {\r\n        break;\r\n      }\r\n      quietCount--;\r\n    }\r\n    if (quietCount != 0) {\r\n      // Unable to find the necessary number of quiet zone pixels.\r\n      throw NotFoundException.getNotFoundInstance();\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Skip all whitespace until we get to the first black line.\r\n   *\r\n   * @param row row of black/white values to search\r\n   * @return index of the first black line.\r\n   * @throws NotFoundException Throws exception if no black lines are found in the row\r\n   */\r\n  private static int skipWhiteSpace(BitArray row) throws NotFoundException {\r\n    int width = row.getSize();\r\n    int endStart = row.getNextSet(0);\r\n    if (endStart == width) {\r\n      throw NotFoundException.getNotFoundInstance();\r\n    }\r\n\r\n    return endStart;\r\n  }\r\n\r\n  /**\r\n   * Identify where the end of the middle / payload section ends.\r\n   *\r\n   * @param row row of black/white values to search\r\n   * @return Array, containing index of start of 'end block' and end of 'end\r\n   *         block'\r\n   * @throws NotFoundException\r\n   */\r\n  int[] decodeEnd(BitArray row) throws NotFoundException {\r\n\r\n    // For convenience, reverse the row and then\r\n    // search from 'the start' for the end block\r\n    row.reverse();\r\n    try {\r\n      int endStart = skipWhiteSpace(row);\r\n      int[] endPattern = findGuardPattern(row, endStart, END_PATTERN_REVERSED);\r\n\r\n      // The start & end patterns must be pre/post fixed by a quiet zone. This\r\n      // zone must be at least 10 times the width of a narrow line.\r\n      // ref: http://www.barcode-1.net/i25code.html\r\n      validateQuietZone(row, endPattern[0]);\r\n\r\n      // Now recalculate the indices of where the 'endblock' starts & stops to\r\n      // accommodate\r\n      // the reversed nature of the search\r\n      int temp = endPattern[0];\r\n      endPattern[0] = row.getSize() - endPattern[1];\r\n      endPattern[1] = row.getSize() - temp;\r\n\r\n      return endPattern;\r\n    } finally {\r\n      // Put the row back the right way.\r\n      row.reverse();\r\n    }\r\n  }\r\n\r\n  /**\r\n   * @param row       row of black/white values to search\r\n   * @param rowOffset position to start search\r\n   * @param pattern   pattern of counts of number of black and white pixels that are\r\n   *                  being searched for as a pattern\r\n   * @return start/end horizontal offset of guard pattern, as an array of two\r\n   *         ints\r\n   * @throws NotFoundException if pattern is not found\r\n   */\r\n  private static int[] findGuardPattern(BitArray row,\r\n                                        int rowOffset,\r\n                                        int[] pattern) throws NotFoundException {\r\n\r\n    // TODO: This is very similar to implementation in UPCEANReader. Consider if they can be\r\n    // merged to a single method.\r\n    int patternLength = pattern.length;\r\n    int[] counters = new int[patternLength];\r\n    int width = row.getSize();\r\n    boolean isWhite = false;\r\n\r\n    int counterPosition = 0;\r\n    int patternStart = rowOffset;\r\n    for (int x = rowOffset; x < width; x++) {\r\n      if (row.get(x) ^ isWhite) {\r\n        counters[counterPosition]++;\r\n      } else {\r\n        if (counterPosition == patternLength - 1) {\r\n          if (patternMatchVariance(counters, pattern, MAX_INDIVIDUAL_VARIANCE) < MAX_AVG_VARIANCE) {\r\n            return new int[]{patternStart, x};\r\n          }\r\n          patternStart += counters[0] + counters[1];\r\n          System.arraycopy(counters, 2, counters, 0, patternLength - 2);\r\n          counters[patternLength - 2] = 0;\r\n          counters[patternLength - 1] = 0;\r\n          counterPosition--;\r\n        } else {\r\n          counterPosition++;\r\n        }\r\n        counters[counterPosition] = 1;\r\n        isWhite = !isWhite;\r\n      }\r\n    }\r\n    throw NotFoundException.getNotFoundInstance();\r\n  }\r\n\r\n  /**\r\n   * Attempts to decode a sequence of ITF black/white lines into single\r\n   * digit.\r\n   *\r\n   * @param counters the counts of runs of observed black/white/black/... values\r\n   * @return The decoded digit\r\n   * @throws NotFoundException if digit cannot be decoded\r\n   */\r\n  private static int decodeDigit(int[] counters) throws NotFoundException {\r\n\r\n    int bestVariance = MAX_AVG_VARIANCE; // worst variance we'll accept\r\n    int bestMatch = -1;\r\n    int max = PATTERNS.length;\r\n    for (int i = 0; i < max; i++) {\r\n      int[] pattern = PATTERNS[i];\r\n      int variance = patternMatchVariance(counters, pattern, MAX_INDIVIDUAL_VARIANCE);\r\n      if (variance < bestVariance) {\r\n        bestVariance = variance;\r\n        bestMatch = i;\r\n      }\r\n    }\r\n    if (bestMatch >= 0) {\r\n      return bestMatch;\r\n    } else {\r\n      throw NotFoundException.getNotFoundInstance();\r\n    }\r\n  }\r\n\r\n}\r\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/ITFWriter.java",
    "content": "/*\n * Copyright 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.oned;\n\nimport com.google.zxing.BarcodeFormat;\nimport com.google.zxing.EncodeHintType;\nimport com.google.zxing.WriterException;\nimport com.google.zxing.common.BitMatrix;\n\nimport java.util.Map;\n\n/**\n * This object renders a ITF code as a {@link BitMatrix}.\n * \n * @author erik.barbara@gmail.com (Erik Barbara)\n */\npublic final class ITFWriter extends OneDimensionalCodeWriter {\n\n  private static final int[] START_PATTERN = {1, 1, 1, 1};\n  private static final int[] END_PATTERN = {3, 1, 1};\n\n  @Override\n  public BitMatrix encode(String contents,\n                          BarcodeFormat format,\n                          int width,\n                          int height,\n                          Map<EncodeHintType,?> hints) throws WriterException {\n    if (format != BarcodeFormat.ITF) {\n      throw new IllegalArgumentException(\"Can only encode ITF, but got \" + format);\n    }\n\n    return super.encode(contents, format, width, height, hints);\n  }\n\n  @Override\n  public boolean[] encode(String contents) {\n    int length = contents.length();\n    if (length % 2 != 0) {\n      throw new IllegalArgumentException(\"The lenght of the input should be even\");\n    }\n    if (length > 80) {\n      throw new IllegalArgumentException(\n          \"Requested contents should be less than 80 digits long, but got \" + length);\n    }\n    boolean[] result = new boolean[9 + 9 * length];\n    int pos = appendPattern(result, 0, START_PATTERN, true);\n    for (int i = 0; i < length; i += 2) {\n      int one = Character.digit(contents.charAt(i), 10);\n      int two = Character.digit(contents.charAt(i+1), 10);\n      int[] encoding = new int[18];\n      for (int j = 0; j < 5; j++) {\n        encoding[(j << 1)] = ITFReader.PATTERNS[one][j];\n        encoding[(j << 1) + 1] = ITFReader.PATTERNS[two][j];\n      }\n      pos += appendPattern(result, pos, encoding, true);\n    }\n    appendPattern(result, pos, END_PATTERN, true);\n\n    return result;\n  }\n\n}"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/MultiFormatOneDReader.java",
    "content": "/*\n * Copyright 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.oned;\n\nimport com.google.zxing.BarcodeFormat;\nimport com.google.zxing.DecodeHintType;\nimport com.google.zxing.NotFoundException;\nimport com.google.zxing.Reader;\nimport com.google.zxing.ReaderException;\nimport com.google.zxing.Result;\nimport com.google.zxing.common.BitArray;\nimport com.google.zxing.oned.rss.RSS14Reader;\nimport com.google.zxing.oned.rss.expanded.RSSExpandedReader;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Map;\n\n/**\n * @author dswitkin@google.com (Daniel Switkin)\n * @author Sean Owen\n */\npublic final class MultiFormatOneDReader extends OneDReader {\n\n  private final OneDReader[] readers;\n\n  public MultiFormatOneDReader(Map<DecodeHintType,?> hints) {\n    Collection<BarcodeFormat> possibleFormats = hints == null ? null :\n        (Collection<BarcodeFormat>) hints.get(DecodeHintType.POSSIBLE_FORMATS);\n    boolean useCode39CheckDigit = hints != null &&\n        hints.get(DecodeHintType.ASSUME_CODE_39_CHECK_DIGIT) != null;\n    Collection<OneDReader> readers = new ArrayList<OneDReader>();\n    if (possibleFormats != null) {\n      if (possibleFormats.contains(BarcodeFormat.EAN_13) ||\n          possibleFormats.contains(BarcodeFormat.UPC_A) ||\n          possibleFormats.contains(BarcodeFormat.EAN_8) ||\n          possibleFormats.contains(BarcodeFormat.UPC_E)) {\n        readers.add(new MultiFormatUPCEANReader(hints));\n      }\n      if (possibleFormats.contains(BarcodeFormat.CODE_39)) {\n        readers.add(new Code39Reader(useCode39CheckDigit));\n      }\n      if (possibleFormats.contains(BarcodeFormat.CODE_93)) {\n        readers.add(new Code93Reader());\n      }\n      if (possibleFormats.contains(BarcodeFormat.CODE_128)) {\n        readers.add(new Code128Reader());\n      }\n      if (possibleFormats.contains(BarcodeFormat.ITF)) {\n         readers.add(new ITFReader());\n      }\n      if (possibleFormats.contains(BarcodeFormat.CODABAR)) {\n         readers.add(new CodaBarReader());\n      }\n      if (possibleFormats.contains(BarcodeFormat.RSS_14)) {\n         readers.add(new RSS14Reader());\n      }\n      if (possibleFormats.contains(BarcodeFormat.RSS_EXPANDED)){\n        readers.add(new RSSExpandedReader());\n      }\n    }\n    if (readers.isEmpty()) {\n      readers.add(new MultiFormatUPCEANReader(hints));\n      readers.add(new Code39Reader());\n      readers.add(new CodaBarReader());\n      readers.add(new Code93Reader());\n      readers.add(new Code128Reader());\n      readers.add(new ITFReader());\n      readers.add(new RSS14Reader());\n      readers.add(new RSSExpandedReader());\n    }\n    this.readers = readers.toArray(new OneDReader[readers.size()]);\n  }\n\n  @Override\n  public Result decodeRow(int rowNumber,\n                          BitArray row,\n                          Map<DecodeHintType,?> hints) throws NotFoundException {\n    for (OneDReader reader : readers) {\n      try {\n        return reader.decodeRow(rowNumber, row, hints);\n      } catch (ReaderException re) {\n        // continue\n      }\n    }\n\n    throw NotFoundException.getNotFoundInstance();\n  }\n\n  @Override\n  public void reset() {\n    for (Reader reader : readers) {\n      reader.reset();\n    }\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/MultiFormatUPCEANReader.java",
    "content": "/*\n * Copyright 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.oned;\n\nimport com.google.zxing.BarcodeFormat;\nimport com.google.zxing.DecodeHintType;\nimport com.google.zxing.NotFoundException;\nimport com.google.zxing.Reader;\nimport com.google.zxing.ReaderException;\nimport com.google.zxing.Result;\nimport com.google.zxing.common.BitArray;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Map;\n\n/**\n * <p>A reader that can read all available UPC/EAN formats. If a caller wants to try to\n * read all such formats, it is most efficient to use this implementation rather than invoke\n * individual readers.</p>\n *\n * @author Sean Owen\n */\npublic final class MultiFormatUPCEANReader extends OneDReader {\n\n  private final UPCEANReader[] readers;\n\n  public MultiFormatUPCEANReader(Map<DecodeHintType,?> hints) {\n    Collection<BarcodeFormat> possibleFormats = hints == null ? null :\n        (Collection<BarcodeFormat>) hints.get(DecodeHintType.POSSIBLE_FORMATS);\n    Collection<UPCEANReader> readers = new ArrayList<UPCEANReader>();\n    if (possibleFormats != null) {\n      if (possibleFormats.contains(BarcodeFormat.EAN_13)) {\n        readers.add(new EAN13Reader());\n      } else if (possibleFormats.contains(BarcodeFormat.UPC_A)) {\n        readers.add(new UPCAReader());\n      }\n      if (possibleFormats.contains(BarcodeFormat.EAN_8)) {\n        readers.add(new EAN8Reader());\n      }\n      if (possibleFormats.contains(BarcodeFormat.UPC_E)) {\n        readers.add(new UPCEReader());\n      }\n    }\n    if (readers.isEmpty()) {\n      readers.add(new EAN13Reader());\n      // UPC-A is covered by EAN-13\n      readers.add(new EAN8Reader());\n      readers.add(new UPCEReader());\n    }\n    this.readers = readers.toArray(new UPCEANReader[readers.size()]);\n  }\n\n  @Override\n  public Result decodeRow(int rowNumber,\n                          BitArray row,\n                          Map<DecodeHintType,?> hints) throws NotFoundException {\n    // Compute this location once and reuse it on multiple implementations\n    int[] startGuardPattern = UPCEANReader.findStartGuardPattern(row);\n    for (UPCEANReader reader : readers) {\n      Result result;\n      try {\n        result = reader.decodeRow(rowNumber, row, startGuardPattern, hints);\n      } catch (ReaderException re) {\n        continue;\n      }\n      // Special case: a 12-digit code encoded in UPC-A is identical to a \"0\"\n      // followed by those 12 digits encoded as EAN-13. Each will recognize such a code,\n      // UPC-A as a 12-digit string and EAN-13 as a 13-digit string starting with \"0\".\n      // Individually these are correct and their readers will both read such a code\n      // and correctly call it EAN-13, or UPC-A, respectively.\n      //\n      // In this case, if we've been looking for both types, we'd like to call it\n      // a UPC-A code. But for efficiency we only run the EAN-13 decoder to also read\n      // UPC-A. So we special case it here, and convert an EAN-13 result to a UPC-A\n      // result if appropriate.\n      //\n      // But, don't return UPC-A if UPC-A was not a requested format!\n      boolean ean13MayBeUPCA =\n          result.getBarcodeFormat() == BarcodeFormat.EAN_13 &&\n              result.getText().charAt(0) == '0';\n      Collection<BarcodeFormat> possibleFormats =\n          hints == null ? null : (Collection<BarcodeFormat>) hints.get(DecodeHintType.POSSIBLE_FORMATS);\n      boolean canReturnUPCA = possibleFormats == null || possibleFormats.contains(BarcodeFormat.UPC_A);\n\n      if (ean13MayBeUPCA && canReturnUPCA) {\n        // Transfer the metdata across\n        Result resultUPCA = new Result(result.getText().substring(1),\n                                       result.getRawBytes(),\n                                       result.getResultPoints(),\n                                       BarcodeFormat.UPC_A);\n        resultUPCA.putAllMetadata(result.getResultMetadata());\n        return resultUPCA;\n      }\n      return result;\n    }\n\n    throw NotFoundException.getNotFoundInstance();\n  }\n\n  @Override\n  public void reset() {\n    for (Reader reader : readers) {\n      reader.reset();\n    }\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/OneDReader.java",
    "content": "/*\n * Copyright 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.oned;\n\nimport com.google.zxing.BinaryBitmap;\nimport com.google.zxing.ChecksumException;\nimport com.google.zxing.DecodeHintType;\nimport com.google.zxing.FormatException;\nimport com.google.zxing.NotFoundException;\nimport com.google.zxing.Reader;\nimport com.google.zxing.ReaderException;\nimport com.google.zxing.Result;\nimport com.google.zxing.ResultMetadataType;\nimport com.google.zxing.ResultPoint;\nimport com.google.zxing.common.BitArray;\n\nimport java.util.Arrays;\nimport java.util.EnumMap;\nimport java.util.Map;\n\n/**\n * Encapsulates functionality and implementation that is common to all families\n * of one-dimensional barcodes.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n * @author Sean Owen\n */\npublic abstract class OneDReader implements Reader {\n\n  protected static final int INTEGER_MATH_SHIFT = 8;\n  protected static final int PATTERN_MATCH_RESULT_SCALE_FACTOR = 1 << INTEGER_MATH_SHIFT;\n\n  @Override\n  public Result decode(BinaryBitmap image) throws NotFoundException, FormatException {\n    return decode(image, null);\n  }\n\n  // Note that we don't try rotation without the try harder flag, even if rotation was supported.\n  @Override\n  public Result decode(BinaryBitmap image,\n                       Map<DecodeHintType,?> hints) throws NotFoundException, FormatException {\n    try {\n      return doDecode(image, hints);\n    } catch (NotFoundException nfe) {\n      boolean tryHarder = hints != null && hints.containsKey(DecodeHintType.TRY_HARDER);\n      if (tryHarder && image.isRotateSupported()) {\n        BinaryBitmap rotatedImage = image.rotateCounterClockwise();\n        Result result = doDecode(rotatedImage, hints);\n        // Record that we found it rotated 90 degrees CCW / 270 degrees CW\n        Map<ResultMetadataType,?> metadata = result.getResultMetadata();\n        int orientation = 270;\n        if (metadata != null && metadata.containsKey(ResultMetadataType.ORIENTATION)) {\n          // But if we found it reversed in doDecode(), add in that result here:\n          orientation = (orientation +\n              (Integer) metadata.get(ResultMetadataType.ORIENTATION)) % 360;\n        }\n        result.putMetadata(ResultMetadataType.ORIENTATION, orientation);\n        // Update result points\n        ResultPoint[] points = result.getResultPoints();\n        if (points != null) {\n          int height = rotatedImage.getHeight();\n          for (int i = 0; i < points.length; i++) {\n            points[i] = new ResultPoint(height - points[i].getY() - 1, points[i].getX());\n          }\n        }\n        return result;\n      } else {\n        throw nfe;\n      }\n    }\n  }\n\n  @Override\n  public void reset() {\n    // do nothing\n  }\n\n  /**\n   * We're going to examine rows from the middle outward, searching alternately above and below the\n   * middle, and farther out each time. rowStep is the number of rows between each successive\n   * attempt above and below the middle. So we'd scan row middle, then middle - rowStep, then\n   * middle + rowStep, then middle - (2 * rowStep), etc.\n   * rowStep is bigger as the image is taller, but is always at least 1. We've somewhat arbitrarily\n   * decided that moving up and down by about 1/16 of the image is pretty good; we try more of the\n   * image if \"trying harder\".\n   *\n   * @param image The image to decode\n   * @param hints Any hints that were requested\n   * @return The contents of the decoded barcode\n   * @throws NotFoundException Any spontaneous errors which occur\n   */\n  private Result doDecode(BinaryBitmap image,\n                          Map<DecodeHintType,?> hints) throws NotFoundException {\n    int width = image.getWidth();\n    int height = image.getHeight();\n    BitArray row = new BitArray(width);\n\n    int middle = height >> 1;\n    boolean tryHarder = hints != null && hints.containsKey(DecodeHintType.TRY_HARDER);\n    int rowStep = Math.max(1, height >> (tryHarder ? 8 : 5));\n    int maxLines;\n    if (tryHarder) {\n      maxLines = height; // Look at the whole image, not just the center\n    } else {\n      maxLines = 15; // 15 rows spaced 1/32 apart is roughly the middle half of the image\n    }\n\n    for (int x = 0; x < maxLines; x++) {\n\n      // Scanning from the middle out. Determine which row we're looking at next:\n      int rowStepsAboveOrBelow = (x + 1) >> 1;\n      boolean isAbove = (x & 0x01) == 0; // i.e. is x even?\n      int rowNumber = middle + rowStep * (isAbove ? rowStepsAboveOrBelow : -rowStepsAboveOrBelow);\n      if (rowNumber < 0 || rowNumber >= height) {\n        // Oops, if we run off the top or bottom, stop\n        break;\n      }\n\n      // Estimate black point for this row and load it:\n      try {\n        row = image.getBlackRow(rowNumber, row);\n      } catch (NotFoundException nfe) {\n        continue;\n      }\n\n      // While we have the image data in a BitArray, it's fairly cheap to reverse it in place to\n      // handle decoding upside down barcodes.\n      for (int attempt = 0; attempt < 2; attempt++) {\n        if (attempt == 1) { // trying again?\n          row.reverse(); // reverse the row and continue\n          // This means we will only ever draw result points *once* in the life of this method\n          // since we want to avoid drawing the wrong points after flipping the row, and,\n          // don't want to clutter with noise from every single row scan -- just the scans\n          // that start on the center line.\n          if (hints != null && hints.containsKey(DecodeHintType.NEED_RESULT_POINT_CALLBACK)) {\n            Map<DecodeHintType,Object> newHints = new EnumMap<DecodeHintType,Object>(DecodeHintType.class);\n            newHints.putAll(hints);\n            newHints.remove(DecodeHintType.NEED_RESULT_POINT_CALLBACK);\n            hints = newHints;\n          }\n        }\n        try {\n          // Look for a barcode\n          Result result = decodeRow(rowNumber, row, hints);\n          // We found our barcode\n          if (attempt == 1) {\n            // But it was upside down, so note that\n            result.putMetadata(ResultMetadataType.ORIENTATION, 180);\n            // And remember to flip the result points horizontally.\n            ResultPoint[] points = result.getResultPoints();\n            if (points != null) {\n              points[0] = new ResultPoint(width - points[0].getX() - 1, points[0].getY());\n              points[1] = new ResultPoint(width - points[1].getX() - 1, points[1].getY());\n            }\n          }\n          return result;\n        } catch (ReaderException re) {\n          // continue -- just couldn't decode this row\n        }\n      }\n    }\n\n    throw NotFoundException.getNotFoundInstance();\n  }\n\n  /**\n   * Records the size of successive runs of white and black pixels in a row, starting at a given point.\n   * The values are recorded in the given array, and the number of runs recorded is equal to the size\n   * of the array. If the row starts on a white pixel at the given start point, then the first count\n   * recorded is the run of white pixels starting from that point; likewise it is the count of a run\n   * of black pixels if the row begin on a black pixels at that point.\n   *\n   * @param row row to count from\n   * @param start offset into row to start at\n   * @param counters array into which to record counts\n   * @throws NotFoundException if counters cannot be filled entirely from row before running out\n   *  of pixels\n   */\n  protected static void recordPattern(BitArray row,\n                                      int start,\n                                      int[] counters) throws NotFoundException {\n    int numCounters = counters.length;\n    Arrays.fill(counters, 0, numCounters, 0);\n    int end = row.getSize();\n    if (start >= end) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n    boolean isWhite = !row.get(start);\n    int counterPosition = 0;\n    int i = start;\n    while (i < end) {\n      if (row.get(i) ^ isWhite) { // that is, exactly one is true\n        counters[counterPosition]++;\n      } else {\n        counterPosition++;\n        if (counterPosition == numCounters) {\n          break;\n        } else {\n          counters[counterPosition] = 1;\n          isWhite = !isWhite;\n        }\n      }\n      i++;\n    }\n    // If we read fully the last section of pixels and filled up our counters -- or filled\n    // the last counter but ran off the side of the image, OK. Otherwise, a problem.\n    if (!(counterPosition == numCounters || (counterPosition == numCounters - 1 && i == end))) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n  }\n\n  protected static void recordPatternInReverse(BitArray row, int start, int[] counters)\n      throws NotFoundException {\n    // This could be more efficient I guess\n    int numTransitionsLeft = counters.length;\n    boolean last = row.get(start);\n    while (start > 0 && numTransitionsLeft >= 0) {\n      if (row.get(--start) != last) {\n        numTransitionsLeft--;\n        last = !last;\n      }\n    }\n    if (numTransitionsLeft >= 0) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n    recordPattern(row, start + 1, counters);\n  }\n\n  /**\n   * Determines how closely a set of observed counts of runs of black/white values matches a given\n   * target pattern. This is reported as the ratio of the total variance from the expected pattern\n   * proportions across all pattern elements, to the length of the pattern.\n   *\n   * @param counters observed counters\n   * @param pattern expected pattern\n   * @param maxIndividualVariance The most any counter can differ before we give up\n   * @return ratio of total variance between counters and pattern compared to total pattern size,\n   *  where the ratio has been multiplied by 256. So, 0 means no variance (perfect match); 256 means\n   *  the total variance between counters and patterns equals the pattern length, higher values mean\n   *  even more variance\n   */\n  protected static int patternMatchVariance(int[] counters,\n                                            int[] pattern,\n                                            int maxIndividualVariance) {\n    int numCounters = counters.length;\n    int total = 0;\n    int patternLength = 0;\n    for (int i = 0; i < numCounters; i++) {\n      total += counters[i];\n      patternLength += pattern[i];\n    }\n    if (total < patternLength) {\n      // If we don't even have one pixel per unit of bar width, assume this is too small\n      // to reliably match, so fail:\n      return Integer.MAX_VALUE;\n    }\n    // We're going to fake floating-point math in integers. We just need to use more bits.\n    // Scale up patternLength so that intermediate values below like scaledCounter will have\n    // more \"significant digits\"\n    int unitBarWidth = (total << INTEGER_MATH_SHIFT) / patternLength;\n    maxIndividualVariance = (maxIndividualVariance * unitBarWidth) >> INTEGER_MATH_SHIFT;\n\n    int totalVariance = 0;\n    for (int x = 0; x < numCounters; x++) {\n      int counter = counters[x] << INTEGER_MATH_SHIFT;\n      int scaledPattern = pattern[x] * unitBarWidth;\n      int variance = counter > scaledPattern ? counter - scaledPattern : scaledPattern - counter;\n      if (variance > maxIndividualVariance) {\n        return Integer.MAX_VALUE;\n      }\n      totalVariance += variance;\n    }\n    return totalVariance / total;\n  }\n\n  /**\n   * <p>Attempts to decode a one-dimensional barcode format given a single row of\n   * an image.</p>\n   *\n   * @param rowNumber row number from top of the row\n   * @param row the black/white pixel data of the row\n   * @param hints decode hints\n   * @return {@link Result} containing encoded string and start/end of barcode\n   * @throws NotFoundException if an error occurs or barcode cannot be found\n   */\n  public abstract Result decodeRow(int rowNumber, BitArray row, Map<DecodeHintType,?> hints)\n      throws NotFoundException, ChecksumException, FormatException;\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/OneDimensionalCodeWriter.java",
    "content": "/*\n * Copyright 2011 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.oned;\n\nimport com.google.zxing.BarcodeFormat;\nimport com.google.zxing.EncodeHintType;\nimport com.google.zxing.Writer;\nimport com.google.zxing.WriterException;\nimport com.google.zxing.common.BitMatrix;\n\nimport java.util.Map;\n\n/**\n * <p>Encapsulates functionality and implementation that is common to one-dimensional barcodes.</p>\n *\n * @author dsbnatut@gmail.com (Kazuki Nishiura)\n */\npublic abstract class OneDimensionalCodeWriter implements Writer {\n\n  @Override\n  public BitMatrix encode(String contents, BarcodeFormat format, int width, int height)\n      throws WriterException {\n    return encode(contents, format, width, height, null);\n  }\n\n  /**\n   * Encode the contents following specified format.\n   * {@code width} and {@code height} are required size. This method may return bigger size\n   * {@code BitMatrix} when specified size is too small. The user can set both {@code width} and\n   * {@code height} to zero to get minimum size barcode. If negative value is set to {@code width}\n   * or {@code height}, {@code IllegalArgumentException} is thrown.\n   */\n  @Override\n  public BitMatrix encode(String contents,\n                          BarcodeFormat format,\n                          int width,\n                          int height,\n                          Map<EncodeHintType,?> hints) throws WriterException {\n    if (contents.length() == 0) {\n      throw new IllegalArgumentException(\"Found empty contents\");\n    }\n\n    if (width < 0 || height < 0) {\n      throw new IllegalArgumentException(\"Negative size is not allowed. Input: \"\n                                             + width + 'x' + height);\n    }\n\n    int sidesMargin = getDefaultMargin();\n    if (hints != null) {\n      Integer sidesMarginInt = (Integer) hints.get(EncodeHintType.MARGIN);\n      if (sidesMarginInt != null) {\n        sidesMargin = sidesMarginInt;\n      }\n    }\n\n    boolean[] code = encode(contents);\n    return renderResult(code, width, height, sidesMargin);\n  }\n\n  /**\n   * @return a byte array of horizontal pixels (0 = white, 1 = black)\n   */\n  private static BitMatrix renderResult(boolean[] code, int width, int height, int sidesMargin) {\n    int inputWidth = code.length;\n    // Add quiet zone on both sides.\n    int fullWidth = inputWidth + sidesMargin;\n    int outputWidth = Math.max(width, fullWidth);\n    int outputHeight = Math.max(1, height);\n\n    int multiple = outputWidth / fullWidth;\n    int leftPadding = (outputWidth - (inputWidth * multiple)) / 2;\n\n    BitMatrix output = new BitMatrix(outputWidth, outputHeight);\n    for (int inputX = 0, outputX = leftPadding; inputX < inputWidth; inputX++, outputX += multiple) {\n      if (code[inputX]) {\n        output.setRegion(outputX, 0, multiple, outputHeight);\n      }\n    }\n    return output;\n  }\n\n\n  /**\n   * Appends the given pattern to the target array starting at pos.\n   *\n   * @param startColor starting color - false for white, true for black\n   * @return the number of elements added to target.\n   */\n  protected static int appendPattern(boolean[] target, int pos, int[] pattern, boolean startColor) {\n    boolean color = startColor;\n    int numAdded = 0;\n    for (int len : pattern) {\n      for (int j = 0; j < len; j++) {\n        target[pos++] = color;\n      }\n      numAdded += len;\n      color = !color; // flip color after each segment\n    }\n    return numAdded;\n  }\n\n  public int getDefaultMargin() {\n    // CodaBar spec requires a side margin to be more than ten times wider than narrow space.\n    // This seems like a decent idea for a default for all formats.\n    return 10;\n  }\n\n  /**\n   * Encode the contents to byte array expression of one-dimensional barcode.\n   * Start code and end code should be included in result, and side margins should not be included.\n   *\n   * @return a {@code boolean[]} of horizontal pixels (false = white, true = black)\n   */\n  public abstract boolean[] encode(String contents);\n}\n\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/UPCAReader.java",
    "content": "/*\n * Copyright 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.oned;\n\nimport com.google.zxing.BarcodeFormat;\nimport com.google.zxing.BinaryBitmap;\nimport com.google.zxing.ChecksumException;\nimport com.google.zxing.DecodeHintType;\nimport com.google.zxing.FormatException;\nimport com.google.zxing.NotFoundException;\nimport com.google.zxing.Result;\nimport com.google.zxing.common.BitArray;\n\nimport java.util.Map;\n\n/**\n * <p>Implements decoding of the UPC-A format.</p>\n *\n * @author dswitkin@google.com (Daniel Switkin)\n * @author Sean Owen\n */\npublic final class UPCAReader extends UPCEANReader {\n\n  private final UPCEANReader ean13Reader = new EAN13Reader();\n\n  @Override\n  public Result decodeRow(int rowNumber,\n                          BitArray row,\n                          int[] startGuardRange,\n                          Map<DecodeHintType,?> hints)\n      throws NotFoundException, FormatException, ChecksumException {\n    return maybeReturnResult(ean13Reader.decodeRow(rowNumber, row, startGuardRange, hints));\n  }\n\n  @Override\n  public Result decodeRow(int rowNumber, BitArray row, Map<DecodeHintType,?> hints)\n      throws NotFoundException, FormatException, ChecksumException {\n    return maybeReturnResult(ean13Reader.decodeRow(rowNumber, row, hints));\n  }\n\n  @Override\n  public Result decode(BinaryBitmap image) throws NotFoundException, FormatException {\n    return maybeReturnResult(ean13Reader.decode(image));\n  }\n\n  @Override\n  public Result decode(BinaryBitmap image, Map<DecodeHintType,?> hints)\n      throws NotFoundException, FormatException {\n    return maybeReturnResult(ean13Reader.decode(image, hints));\n  }\n\n  @Override\n  BarcodeFormat getBarcodeFormat() {\n    return BarcodeFormat.UPC_A;\n  }\n\n  @Override\n  protected int decodeMiddle(BitArray row, int[] startRange, StringBuilder resultString)\n      throws NotFoundException {\n    return ean13Reader.decodeMiddle(row, startRange, resultString);\n  }\n\n  private static Result maybeReturnResult(Result result) throws FormatException {\n    String text = result.getText();\n    if (text.charAt(0) == '0') {\n      return new Result(text.substring(1), null, result.getResultPoints(), BarcodeFormat.UPC_A);\n    } else {\n      throw FormatException.getFormatInstance();\n    }\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/UPCAWriter.java",
    "content": "/*\n * Copyright 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.oned;\n\nimport com.google.zxing.BarcodeFormat;\nimport com.google.zxing.EncodeHintType;\nimport com.google.zxing.Writer;\nimport com.google.zxing.WriterException;\nimport com.google.zxing.common.BitMatrix;\n\nimport java.util.Map;\n\n/**\n * This object renders a UPC-A code as a {@link BitMatrix}.\n *\n * @author qwandor@google.com (Andrew Walbran)\n */\npublic final class UPCAWriter implements Writer {\n\n  private final EAN13Writer subWriter = new EAN13Writer();\n\n  @Override\n  public BitMatrix encode(String contents, BarcodeFormat format, int width, int height)\n      throws WriterException {\n    return encode(contents, format, width, height, null);\n  }\n\n  @Override\n  public BitMatrix encode(String contents,\n                          BarcodeFormat format,\n                          int width,\n                          int height,\n                          Map<EncodeHintType,?> hints) throws WriterException {\n    if (format != BarcodeFormat.UPC_A) {\n      throw new IllegalArgumentException(\"Can only encode UPC-A, but got \" + format);\n    }\n    return subWriter.encode(preencode(contents), BarcodeFormat.EAN_13, width, height, hints);\n  }\n\n  /**\n   * Transform a UPC-A code into the equivalent EAN-13 code, and add a check digit if it is not\n   * already present.\n   */\n  private static String preencode(String contents) {\n    int length = contents.length();\n    if (length == 11) {\n      // No check digit present, calculate it and add it\n      int sum = 0;\n      for (int i = 0; i < 11; ++i) {\n        sum += (contents.charAt(i) - '0') * (i % 2 == 0 ? 3 : 1);\n      }\n      contents += (1000 - sum) % 10;\n    } else if (length != 12) {\n      throw new IllegalArgumentException(\n          \"Requested contents should be 11 or 12 digits long, but got \" + contents.length());\n    }\n    return '0' + contents;\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/UPCEANExtension2Support.java",
    "content": "/*\n * Copyright (C) 2012 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.oned;\n\nimport com.google.zxing.BarcodeFormat;\nimport com.google.zxing.NotFoundException;\nimport com.google.zxing.Result;\nimport com.google.zxing.ResultMetadataType;\nimport com.google.zxing.ResultPoint;\nimport com.google.zxing.common.BitArray;\n\nimport java.util.EnumMap;\nimport java.util.Map;\n\n/**\n * @see UPCEANExtension5Support\n */\nfinal class UPCEANExtension2Support {\n\n  private final int[] decodeMiddleCounters = new int[4];\n  private final StringBuilder decodeRowStringBuffer = new StringBuilder();\n\n  Result decodeRow(int rowNumber, BitArray row, int[] extensionStartRange) throws NotFoundException {\n\n    StringBuilder result = decodeRowStringBuffer;\n    result.setLength(0);\n    int end = decodeMiddle(row, extensionStartRange, result);\n\n    String resultString = result.toString();\n    Map<ResultMetadataType,Object> extensionData = parseExtensionString(resultString);\n\n    Result extensionResult =\n        new Result(resultString,\n                   null,\n                   new ResultPoint[] {\n                       new ResultPoint((extensionStartRange[0] + extensionStartRange[1]) / 2.0f, (float) rowNumber),\n                       new ResultPoint((float) end, (float) rowNumber),\n                   },\n                   BarcodeFormat.UPC_EAN_EXTENSION);\n    if (extensionData != null) {\n      extensionResult.putAllMetadata(extensionData);\n    }\n    return extensionResult;\n  }\n\n  int decodeMiddle(BitArray row, int[] startRange, StringBuilder resultString) throws NotFoundException {\n    int[] counters = decodeMiddleCounters;\n    counters[0] = 0;\n    counters[1] = 0;\n    counters[2] = 0;\n    counters[3] = 0;\n    int end = row.getSize();\n    int rowOffset = startRange[1];\n\n    int checkParity = 0;\n\n    for (int x = 0; x < 2 && rowOffset < end; x++) {\n      int bestMatch = UPCEANReader.decodeDigit(row, counters, rowOffset, UPCEANReader.L_AND_G_PATTERNS);\n      resultString.append((char) ('0' + bestMatch % 10));\n      for (int counter : counters) {\n        rowOffset += counter;\n      }\n      if (bestMatch >= 10) {\n        checkParity |= 1 << (1 - x);\n      }\n      if (x != 1) {\n        // Read off separator if not last\n        rowOffset = row.getNextSet(rowOffset);\n        rowOffset = row.getNextUnset(rowOffset);\n      }\n    }\n\n    if (resultString.length() != 2) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n\n    if (Integer.parseInt(resultString.toString()) % 4 != checkParity) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n    \n    return rowOffset;\n  }\n\n  /**\n   * @param raw raw content of extension\n   * @return formatted interpretation of raw content as a {@link Map} mapping\n   *  one {@link ResultMetadataType} to appropriate value, or {@code null} if not known\n   */\n  private static Map<ResultMetadataType,Object> parseExtensionString(String raw) {\n    if (raw.length() != 2) {\n      return null;\n    }\n    Map<ResultMetadataType,Object> result = new EnumMap<ResultMetadataType,Object>(ResultMetadataType.class);\n    result.put(ResultMetadataType.ISSUE_NUMBER, Integer.valueOf(raw));\n    return result;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/UPCEANExtension5Support.java",
    "content": "/*\n * Copyright (C) 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.oned;\n\nimport com.google.zxing.BarcodeFormat;\nimport com.google.zxing.NotFoundException;\nimport com.google.zxing.Result;\nimport com.google.zxing.ResultMetadataType;\nimport com.google.zxing.ResultPoint;\nimport com.google.zxing.common.BitArray;\n\nimport java.util.EnumMap;\nimport java.util.Map;\n\n/**\n * @see UPCEANExtension2Support\n */\nfinal class UPCEANExtension5Support {\n\n  private static final int[] CHECK_DIGIT_ENCODINGS = {\n      0x18, 0x14, 0x12, 0x11, 0x0C, 0x06, 0x03, 0x0A, 0x09, 0x05\n  };\n\n  private final int[] decodeMiddleCounters = new int[4];\n  private final StringBuilder decodeRowStringBuffer = new StringBuilder();\n\n  Result decodeRow(int rowNumber, BitArray row, int[] extensionStartRange) throws NotFoundException {\n\n    StringBuilder result = decodeRowStringBuffer;\n    result.setLength(0);\n    int end = decodeMiddle(row, extensionStartRange, result);\n\n    String resultString = result.toString();\n    Map<ResultMetadataType,Object> extensionData = parseExtensionString(resultString);\n\n    Result extensionResult =\n        new Result(resultString,\n                   null,\n                   new ResultPoint[] {\n                       new ResultPoint((extensionStartRange[0] + extensionStartRange[1]) / 2.0f, (float) rowNumber),\n                       new ResultPoint((float) end, (float) rowNumber),\n                   },\n                   BarcodeFormat.UPC_EAN_EXTENSION);\n    if (extensionData != null) {\n      extensionResult.putAllMetadata(extensionData);\n    }\n    return extensionResult;\n  }\n\n  int decodeMiddle(BitArray row, int[] startRange, StringBuilder resultString) throws NotFoundException {\n    int[] counters = decodeMiddleCounters;\n    counters[0] = 0;\n    counters[1] = 0;\n    counters[2] = 0;\n    counters[3] = 0;\n    int end = row.getSize();\n    int rowOffset = startRange[1];\n\n    int lgPatternFound = 0;\n\n    for (int x = 0; x < 5 && rowOffset < end; x++) {\n      int bestMatch = UPCEANReader.decodeDigit(row, counters, rowOffset, UPCEANReader.L_AND_G_PATTERNS);\n      resultString.append((char) ('0' + bestMatch % 10));\n      for (int counter : counters) {\n        rowOffset += counter;\n      }\n      if (bestMatch >= 10) {\n        lgPatternFound |= 1 << (4 - x);\n      }\n      if (x != 4) {\n        // Read off separator if not last\n        rowOffset = row.getNextSet(rowOffset);\n        rowOffset = row.getNextUnset(rowOffset);\n      }\n    }\n\n    if (resultString.length() != 5) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n\n    int checkDigit = determineCheckDigit(lgPatternFound);\n    if (extensionChecksum(resultString.toString()) != checkDigit) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n    \n    return rowOffset;\n  }\n\n  private static int extensionChecksum(CharSequence s) {\n    int length = s.length();\n    int sum = 0;\n    for (int i = length - 2; i >= 0; i -= 2) {\n      sum += (int) s.charAt(i) - (int) '0';\n    }\n    sum *= 3;\n    for (int i = length - 1; i >= 0; i -= 2) {\n      sum += (int) s.charAt(i) - (int) '0';\n    }\n    sum *= 3;\n    return sum % 10;\n  }\n\n  private static int determineCheckDigit(int lgPatternFound)\n      throws NotFoundException {\n    for (int d = 0; d < 10; d++) {\n      if (lgPatternFound == CHECK_DIGIT_ENCODINGS[d]) {\n        return d;\n      }\n    }\n    throw NotFoundException.getNotFoundInstance();\n  }\n\n  /**\n   * @param raw raw content of extension\n   * @return formatted interpretation of raw content as a {@link Map} mapping\n   *  one {@link ResultMetadataType} to appropriate value, or {@code null} if not known\n   */\n  private static Map<ResultMetadataType,Object> parseExtensionString(String raw) {\n    if (raw.length() != 5) {\n      return null;\n    }\n    Object value = parseExtension5String(raw);\n    if (value == null) {\n      return null;\n    }\n    Map<ResultMetadataType,Object> result = new EnumMap<ResultMetadataType,Object>(ResultMetadataType.class);\n    result.put(ResultMetadataType.SUGGESTED_PRICE, value);\n    return result;\n  }\n\n  private static String parseExtension5String(String raw) {\n    String currency;\n    switch (raw.charAt(0)) {\n      case '0':\n        currency = \"£\";\n        break;\n      case '5':\n        currency = \"$\";\n        break;\n      case '9':\n        // Reference: http://www.jollytech.com\n        if (\"90000\".equals(raw)) {\n          // No suggested retail price\n          return null;\n        }\n        if (\"99991\".equals(raw)) {\n          // Complementary\n          return \"0.00\";\n        }\n        if (\"99990\".equals(raw)) {\n          return \"Used\";\n        }\n        // Otherwise... unknown currency?\n        currency = \"\";\n        break;\n      default:\n        currency = \"\";\n        break;\n    }\n    int rawAmount = Integer.parseInt(raw.substring(1));\n    String unitsString = String.valueOf(rawAmount / 100);\n    int hundredths = rawAmount % 100;\n    String hundredthsString = hundredths < 10 ? \"0\" + hundredths : String.valueOf(hundredths);\n    return currency + unitsString + '.' + hundredthsString;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/UPCEANExtensionSupport.java",
    "content": "/*\n * Copyright (C) 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.oned;\n\nimport com.google.zxing.NotFoundException;\nimport com.google.zxing.ReaderException;\nimport com.google.zxing.Result;\nimport com.google.zxing.common.BitArray;\n\nfinal class UPCEANExtensionSupport {\n\n  private static final int[] EXTENSION_START_PATTERN = {1,1,2};\n\n  private final UPCEANExtension2Support twoSupport = new UPCEANExtension2Support();\n  private final UPCEANExtension5Support fiveSupport = new UPCEANExtension5Support();\n\n  Result decodeRow(int rowNumber, BitArray row, int rowOffset) throws NotFoundException {\n    int[] extensionStartRange = UPCEANReader.findGuardPattern(row, rowOffset, false, EXTENSION_START_PATTERN);\n    try {\n      return fiveSupport.decodeRow(rowNumber, row, extensionStartRange);\n    } catch (ReaderException re) {\n      return twoSupport.decodeRow(rowNumber, row, extensionStartRange);\n    }\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/UPCEANReader.java",
    "content": "/*\n * Copyright 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.oned;\n\nimport com.google.zxing.BarcodeFormat;\nimport com.google.zxing.ChecksumException;\nimport com.google.zxing.DecodeHintType;\nimport com.google.zxing.FormatException;\nimport com.google.zxing.NotFoundException;\nimport com.google.zxing.ReaderException;\nimport com.google.zxing.Result;\nimport com.google.zxing.ResultMetadataType;\nimport com.google.zxing.ResultPoint;\nimport com.google.zxing.ResultPointCallback;\nimport com.google.zxing.common.BitArray;\n\nimport java.util.Arrays;\nimport java.util.Map;\n\n/**\n * <p>Encapsulates functionality and implementation that is common to UPC and EAN families\n * of one-dimensional barcodes.</p>\n *\n * @author dswitkin@google.com (Daniel Switkin)\n * @author Sean Owen\n * @author alasdair@google.com (Alasdair Mackintosh)\n */\npublic abstract class UPCEANReader extends OneDReader {\n\n  // These two values are critical for determining how permissive the decoding will be.\n  // We've arrived at these values through a lot of trial and error. Setting them any higher\n  // lets false positives creep in quickly.\n  private static final int MAX_AVG_VARIANCE = (int) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.48f);\n  private static final int MAX_INDIVIDUAL_VARIANCE = (int) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.7f);\n\n  /**\n   * Start/end guard pattern.\n   */\n  static final int[] START_END_PATTERN = {1, 1, 1,};\n\n  /**\n   * Pattern marking the middle of a UPC/EAN pattern, separating the two halves.\n   */\n  static final int[] MIDDLE_PATTERN = {1, 1, 1, 1, 1};\n\n  /**\n   * \"Odd\", or \"L\" patterns used to encode UPC/EAN digits.\n   */\n  static final int[][] L_PATTERNS = {\n      {3, 2, 1, 1}, // 0\n      {2, 2, 2, 1}, // 1\n      {2, 1, 2, 2}, // 2\n      {1, 4, 1, 1}, // 3\n      {1, 1, 3, 2}, // 4\n      {1, 2, 3, 1}, // 5\n      {1, 1, 1, 4}, // 6\n      {1, 3, 1, 2}, // 7\n      {1, 2, 1, 3}, // 8\n      {3, 1, 1, 2}  // 9\n  };\n\n  /**\n   * As above but also including the \"even\", or \"G\" patterns used to encode UPC/EAN digits.\n   */\n  static final int[][] L_AND_G_PATTERNS;\n\n  static {\n    L_AND_G_PATTERNS = new int[20][];\n    System.arraycopy(L_PATTERNS, 0, L_AND_G_PATTERNS, 0, 10);\n    for (int i = 10; i < 20; i++) {\n      int[] widths = L_PATTERNS[i - 10];\n      int[] reversedWidths = new int[widths.length];\n      for (int j = 0; j < widths.length; j++) {\n        reversedWidths[j] = widths[widths.length - j - 1];\n      }\n      L_AND_G_PATTERNS[i] = reversedWidths;\n    }\n  }\n\n  private final StringBuilder decodeRowStringBuffer;\n  private final UPCEANExtensionSupport extensionReader;\n  private final EANManufacturerOrgSupport eanManSupport;\n\n  protected UPCEANReader() {\n    decodeRowStringBuffer = new StringBuilder(20);\n    extensionReader = new UPCEANExtensionSupport();\n    eanManSupport = new EANManufacturerOrgSupport();\n  }\n\n  static int[] findStartGuardPattern(BitArray row) throws NotFoundException {\n    boolean foundStart = false;\n    int[] startRange = null;\n    int nextStart = 0;\n    int[] counters = new int[START_END_PATTERN.length];\n    while (!foundStart) {\n      Arrays.fill(counters, 0, START_END_PATTERN.length, 0);\n      startRange = findGuardPattern(row, nextStart, false, START_END_PATTERN, counters);\n      int start = startRange[0];\n      nextStart = startRange[1];\n      // Make sure there is a quiet zone at least as big as the start pattern before the barcode.\n      // If this check would run off the left edge of the image, do not accept this barcode,\n      // as it is very likely to be a false positive.\n      int quietStart = start - (nextStart - start);\n      if (quietStart >= 0) {\n        foundStart = row.isRange(quietStart, start, false);\n      }\n    }\n    return startRange;\n  }\n\n  @Override\n  public Result decodeRow(int rowNumber, BitArray row, Map<DecodeHintType,?> hints)\n      throws NotFoundException, ChecksumException, FormatException {\n    return decodeRow(rowNumber, row, findStartGuardPattern(row), hints);\n  }\n\n  /**\n   * <p>Like {@link #decodeRow(int, BitArray, java.util.Map)}, but\n   * allows caller to inform method about where the UPC/EAN start pattern is\n   * found. This allows this to be computed once and reused across many implementations.</p>\n   */\n  public Result decodeRow(int rowNumber,\n                          BitArray row,\n                          int[] startGuardRange,\n                          Map<DecodeHintType,?> hints)\n      throws NotFoundException, ChecksumException, FormatException {\n\n    ResultPointCallback resultPointCallback = hints == null ? null :\n        (ResultPointCallback) hints.get(DecodeHintType.NEED_RESULT_POINT_CALLBACK);\n\n    if (resultPointCallback != null) {\n      resultPointCallback.foundPossibleResultPoint(new ResultPoint(\n          (startGuardRange[0] + startGuardRange[1]) / 2.0f, rowNumber\n      ));\n    }\n\n    StringBuilder result = decodeRowStringBuffer;\n    result.setLength(0);\n    int endStart = decodeMiddle(row, startGuardRange, result);\n\n    if (resultPointCallback != null) {\n      resultPointCallback.foundPossibleResultPoint(new ResultPoint(\n          endStart, rowNumber\n      ));\n    }\n\n    int[] endRange = decodeEnd(row, endStart);\n\n    if (resultPointCallback != null) {\n      resultPointCallback.foundPossibleResultPoint(new ResultPoint(\n          (endRange[0] + endRange[1]) / 2.0f, rowNumber\n      ));\n    }\n\n\n    // Make sure there is a quiet zone at least as big as the end pattern after the barcode. The\n    // spec might want more whitespace, but in practice this is the maximum we can count on.\n    int end = endRange[1];\n    int quietEnd = end + (end - endRange[0]);\n    if (quietEnd >= row.getSize() || !row.isRange(end, quietEnd, false)) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n\n    String resultString = result.toString();\n    if (!checkChecksum(resultString)) {\n      throw ChecksumException.getChecksumInstance();\n    }\n\n    float left = (float) (startGuardRange[1] + startGuardRange[0]) / 2.0f;\n    float right = (float) (endRange[1] + endRange[0]) / 2.0f;\n    BarcodeFormat format = getBarcodeFormat();\n    Result decodeResult = new Result(resultString,\n        null, // no natural byte representation for these barcodes\n        new ResultPoint[]{\n            new ResultPoint(left, (float) rowNumber),\n            new ResultPoint(right, (float) rowNumber)},\n        format);\n\n    try {\n      Result extensionResult = extensionReader.decodeRow(rowNumber, row, endRange[1]);\n      decodeResult.putMetadata(ResultMetadataType.UPC_EAN_EXTENSION, extensionResult.getText());\n      decodeResult.putAllMetadata(extensionResult.getResultMetadata());\n      decodeResult.addResultPoints(extensionResult.getResultPoints());\n    } catch (ReaderException re) {\n      // continue\n    }\n\n    if (format == BarcodeFormat.EAN_13 || format == BarcodeFormat.UPC_A) {\n      String countryID = eanManSupport.lookupCountryIdentifier(resultString);\n      if (countryID != null) {\n        decodeResult.putMetadata(ResultMetadataType.POSSIBLE_COUNTRY, countryID);\n      }\n    }\n\n    return decodeResult;\n  }\n\n  /**\n   * @return {@link #checkStandardUPCEANChecksum(CharSequence)}\n   */\n  boolean checkChecksum(String s) throws ChecksumException, FormatException {\n    return checkStandardUPCEANChecksum(s);\n  }\n\n  /**\n   * Computes the UPC/EAN checksum on a string of digits, and reports\n   * whether the checksum is correct or not.\n   *\n   * @param s string of digits to check\n   * @return true iff string of digits passes the UPC/EAN checksum algorithm\n   * @throws FormatException if the string does not contain only digits\n   */\n  static boolean checkStandardUPCEANChecksum(CharSequence s) throws FormatException {\n    int length = s.length();\n    if (length == 0) {\n      return false;\n    }\n\n    int sum = 0;\n    for (int i = length - 2; i >= 0; i -= 2) {\n      int digit = (int) s.charAt(i) - (int) '0';\n      if (digit < 0 || digit > 9) {\n        throw FormatException.getFormatInstance();\n      }\n      sum += digit;\n    }\n    sum *= 3;\n    for (int i = length - 1; i >= 0; i -= 2) {\n      int digit = (int) s.charAt(i) - (int) '0';\n      if (digit < 0 || digit > 9) {\n        throw FormatException.getFormatInstance();\n      }\n      sum += digit;\n    }\n    return sum % 10 == 0;\n  }\n\n  int[] decodeEnd(BitArray row, int endStart) throws NotFoundException {\n    return findGuardPattern(row, endStart, false, START_END_PATTERN);\n  }\n\n  static int[] findGuardPattern(BitArray row,\n                                int rowOffset,\n                                boolean whiteFirst,\n                                int[] pattern) throws NotFoundException {\n    return findGuardPattern(row, rowOffset, whiteFirst, pattern, new int[pattern.length]);\n  }\n\n  /**\n   * @param row row of black/white values to search\n   * @param rowOffset position to start search\n   * @param whiteFirst if true, indicates that the pattern specifies white/black/white/...\n   * pixel counts, otherwise, it is interpreted as black/white/black/...\n   * @param pattern pattern of counts of number of black and white pixels that are being\n   * searched for as a pattern\n   * @param counters array of counters, as long as pattern, to re-use\n   * @return start/end horizontal offset of guard pattern, as an array of two ints\n   * @throws NotFoundException if pattern is not found\n   */\n  private static int[] findGuardPattern(BitArray row,\n                                        int rowOffset,\n                                        boolean whiteFirst,\n                                        int[] pattern,\n                                        int[] counters) throws NotFoundException {\n    int patternLength = pattern.length;\n    int width = row.getSize();\n    boolean isWhite = whiteFirst;\n    rowOffset = whiteFirst ? row.getNextUnset(rowOffset) : row.getNextSet(rowOffset);\n    int counterPosition = 0;\n    int patternStart = rowOffset;\n    for (int x = rowOffset; x < width; x++) {\n      if (row.get(x) ^ isWhite) {\n        counters[counterPosition]++;\n      } else {\n        if (counterPosition == patternLength - 1) {\n          if (patternMatchVariance(counters, pattern, MAX_INDIVIDUAL_VARIANCE) < MAX_AVG_VARIANCE) {\n            return new int[]{patternStart, x};\n          }\n          patternStart += counters[0] + counters[1];\n          System.arraycopy(counters, 2, counters, 0, patternLength - 2);\n          counters[patternLength - 2] = 0;\n          counters[patternLength - 1] = 0;\n          counterPosition--;\n        } else {\n          counterPosition++;\n        }\n        counters[counterPosition] = 1;\n        isWhite = !isWhite;\n      }\n    }\n    throw NotFoundException.getNotFoundInstance();\n  }\n\n  /**\n   * Attempts to decode a single UPC/EAN-encoded digit.\n   *\n   * @param row row of black/white values to decode\n   * @param counters the counts of runs of observed black/white/black/... values\n   * @param rowOffset horizontal offset to start decoding from\n   * @param patterns the set of patterns to use to decode -- sometimes different encodings\n   * for the digits 0-9 are used, and this indicates the encodings for 0 to 9 that should\n   * be used\n   * @return horizontal offset of first pixel beyond the decoded digit\n   * @throws NotFoundException if digit cannot be decoded\n   */\n  static int decodeDigit(BitArray row, int[] counters, int rowOffset, int[][] patterns)\n      throws NotFoundException {\n    recordPattern(row, rowOffset, counters);\n    int bestVariance = MAX_AVG_VARIANCE; // worst variance we'll accept\n    int bestMatch = -1;\n    int max = patterns.length;\n    for (int i = 0; i < max; i++) {\n      int[] pattern = patterns[i];\n      int variance = patternMatchVariance(counters, pattern, MAX_INDIVIDUAL_VARIANCE);\n      if (variance < bestVariance) {\n        bestVariance = variance;\n        bestMatch = i;\n      }\n    }\n    if (bestMatch >= 0) {\n      return bestMatch;\n    } else {\n      throw NotFoundException.getNotFoundInstance();\n    }\n  }\n\n  /**\n   * Get the format of this decoder.\n   *\n   * @return The 1D format.\n   */\n  abstract BarcodeFormat getBarcodeFormat();\n\n  /**\n   * Subclasses override this to decode the portion of a barcode between the start\n   * and end guard patterns.\n   *\n   * @param row row of black/white values to search\n   * @param startRange start/end offset of start guard pattern\n   * @param resultString {@link StringBuilder} to append decoded chars to\n   * @return horizontal offset of first pixel after the \"middle\" that was decoded\n   * @throws NotFoundException if decoding could not complete successfully\n   */\n  protected abstract int decodeMiddle(BitArray row,\n                                      int[] startRange,\n                                      StringBuilder resultString) throws NotFoundException;\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/UPCEANWriter.java",
    "content": "/*\n * Copyright 2009 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.oned;\n\n/**\n * <p>Encapsulates functionality and implementation that is common to UPC and EAN families\n * of one-dimensional barcodes.</p>\n *\n * @author aripollak@gmail.com (Ari Pollak)\n * @author dsbnatut@gmail.com (Kazuki Nishiura)\n */\npublic abstract class UPCEANWriter extends OneDimensionalCodeWriter {\n\n  @Override\n  public int getDefaultMargin() {\n    // Use a different default more appropriate for UPC/EAN\n    return UPCEANReader.START_END_PATTERN.length;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/UPCEReader.java",
    "content": "/*\n * Copyright 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.oned;\n\nimport com.google.zxing.BarcodeFormat;\nimport com.google.zxing.ChecksumException;\nimport com.google.zxing.FormatException;\nimport com.google.zxing.NotFoundException;\nimport com.google.zxing.common.BitArray;\n\n/**\n * <p>Implements decoding of the UPC-E format.</p>\n * <p/>\n * <p><a href=\"http://www.barcodeisland.com/upce.phtml\">This</a> is a great reference for\n * UPC-E information.</p>\n *\n * @author Sean Owen\n */\npublic final class UPCEReader extends UPCEANReader {\n\n  /**\n   * The pattern that marks the middle, and end, of a UPC-E pattern.\n   * There is no \"second half\" to a UPC-E barcode.\n   */\n  private static final int[] MIDDLE_END_PATTERN = {1, 1, 1, 1, 1, 1};\n\n  /**\n   * See {@link #L_AND_G_PATTERNS}; these values similarly represent patterns of\n   * even-odd parity encodings of digits that imply both the number system (0 or 1)\n   * used, and the check digit.\n   */\n  private static final int[][] NUMSYS_AND_CHECK_DIGIT_PATTERNS = {\n      {0x38, 0x34, 0x32, 0x31, 0x2C, 0x26, 0x23, 0x2A, 0x29, 0x25},\n      {0x07, 0x0B, 0x0D, 0x0E, 0x13, 0x19, 0x1C, 0x15, 0x16, 0x1A}\n  };\n\n  private final int[] decodeMiddleCounters;\n\n  public UPCEReader() {\n    decodeMiddleCounters = new int[4];\n  }\n\n  @Override\n  protected int decodeMiddle(BitArray row, int[] startRange, StringBuilder result)\n      throws NotFoundException {\n    int[] counters = decodeMiddleCounters;\n    counters[0] = 0;\n    counters[1] = 0;\n    counters[2] = 0;\n    counters[3] = 0;\n    int end = row.getSize();\n    int rowOffset = startRange[1];\n\n    int lgPatternFound = 0;\n\n    for (int x = 0; x < 6 && rowOffset < end; x++) {\n      int bestMatch = decodeDigit(row, counters, rowOffset, L_AND_G_PATTERNS);\n      result.append((char) ('0' + bestMatch % 10));\n      for (int counter : counters) {\n        rowOffset += counter;\n      }\n      if (bestMatch >= 10) {\n        lgPatternFound |= 1 << (5 - x);\n      }\n    }\n\n    determineNumSysAndCheckDigit(result, lgPatternFound);\n\n    return rowOffset;\n  }\n\n  @Override\n  protected int[] decodeEnd(BitArray row, int endStart) throws NotFoundException {\n    return findGuardPattern(row, endStart, true, MIDDLE_END_PATTERN);\n  }\n\n  @Override\n  protected boolean checkChecksum(String s) throws FormatException, ChecksumException {\n    return super.checkChecksum(convertUPCEtoUPCA(s));\n  }\n\n  private static void determineNumSysAndCheckDigit(StringBuilder resultString, int lgPatternFound)\n      throws NotFoundException {\n\n    for (int numSys = 0; numSys <= 1; numSys++) {\n      for (int d = 0; d < 10; d++) {\n        if (lgPatternFound == NUMSYS_AND_CHECK_DIGIT_PATTERNS[numSys][d]) {\n          resultString.insert(0, (char) ('0' + numSys));\n          resultString.append((char) ('0' + d));\n          return;\n        }\n      }\n    }\n    throw NotFoundException.getNotFoundInstance();\n  }\n\n  @Override\n  BarcodeFormat getBarcodeFormat() {\n    return BarcodeFormat.UPC_E;\n  }\n\n  /**\n   * Expands a UPC-E value back into its full, equivalent UPC-A code value.\n   *\n   * @param upce UPC-E code as string of digits\n   * @return equivalent UPC-A code as string of digits\n   */\n  public static String convertUPCEtoUPCA(String upce) {\n    char[] upceChars = new char[6];\n    upce.getChars(1, 7, upceChars, 0);\n    StringBuilder result = new StringBuilder(12);\n    result.append(upce.charAt(0));\n    char lastChar = upceChars[5];\n    switch (lastChar) {\n      case '0':\n      case '1':\n      case '2':\n        result.append(upceChars, 0, 2);\n        result.append(lastChar);\n        result.append(\"0000\");\n        result.append(upceChars, 2, 3);\n        break;\n      case '3':\n        result.append(upceChars, 0, 3);\n        result.append(\"00000\");\n        result.append(upceChars, 3, 2);\n        break;\n      case '4':\n        result.append(upceChars, 0, 4);\n        result.append(\"00000\");\n        result.append(upceChars[4]);\n        break;\n      default:\n        result.append(upceChars, 0, 5);\n        result.append(\"0000\");\n        result.append(lastChar);\n        break;\n    }\n    result.append(upce.charAt(7));\n    return result.toString();\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/rss/AbstractRSSReader.java",
    "content": "/*\n * Copyright (C) 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.oned.rss;\n\nimport com.google.zxing.NotFoundException;\nimport com.google.zxing.oned.OneDReader;\n\npublic abstract class AbstractRSSReader extends OneDReader {\n\n  private static final int MAX_AVG_VARIANCE = (int) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.2f);\n  private static final int MAX_INDIVIDUAL_VARIANCE = (int) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.4f);\n\n  private static final float MIN_FINDER_PATTERN_RATIO = 9.5f / 12.0f;\n  private static final float MAX_FINDER_PATTERN_RATIO = 12.5f / 14.0f;\n\n  private final int[] decodeFinderCounters;\n  private final int[] dataCharacterCounters;\n  private final float[] oddRoundingErrors;\n  private final float[] evenRoundingErrors;\n  private final int[] oddCounts;\n  private final int[] evenCounts;\n\n  protected AbstractRSSReader(){\n    decodeFinderCounters = new int[4];\n    dataCharacterCounters = new int[8];\n    oddRoundingErrors = new float[4];\n    evenRoundingErrors = new float[4];\n    oddCounts = new int[dataCharacterCounters.length / 2];\n    evenCounts = new int[dataCharacterCounters.length / 2];\n  }\n\n  protected final int[] getDecodeFinderCounters() {\n    return decodeFinderCounters;\n  }\n\n  protected final int[] getDataCharacterCounters() {\n    return dataCharacterCounters;\n  }\n\n  protected final float[] getOddRoundingErrors() {\n    return oddRoundingErrors;\n  }\n\n  protected final float[] getEvenRoundingErrors() {\n    return evenRoundingErrors;\n  }\n\n  protected final int[] getOddCounts() {\n    return oddCounts;\n  }\n\n  protected final int[] getEvenCounts() {\n    return evenCounts;\n  }\n\n  protected static int parseFinderValue(int[] counters,\n                                        int[][] finderPatterns) throws NotFoundException {\n    for (int value = 0; value < finderPatterns.length; value++) {\n      if (patternMatchVariance(counters, finderPatterns[value], MAX_INDIVIDUAL_VARIANCE) <\n          MAX_AVG_VARIANCE) {\n        return value;\n      }\n    }\n    throw NotFoundException.getNotFoundInstance();\n  }\n\n  protected static int count(int[] array) {\n    int count = 0;\n    for (int a : array) {\n      count += a;\n    }\n    return count;\n  }\n\n  protected static void increment(int[] array, float[] errors) {\n    int index = 0;\n    float biggestError = errors[0];\n    for (int i = 1; i < array.length; i++) {\n      if (errors[i] > biggestError) {\n        biggestError = errors[i];\n        index = i;\n      }\n    }\n    array[index]++;\n  }\n\n  protected static void decrement(int[] array, float[] errors) {\n    int index = 0;\n    float biggestError = errors[0];\n    for (int i = 1; i < array.length; i++) {\n      if (errors[i] < biggestError) {\n        biggestError = errors[i];\n        index = i;\n      }\n    }\n    array[index]--;\n  }\n\n  protected static boolean isFinderPattern(int[] counters) {\n    int firstTwoSum = counters[0] + counters[1];\n    int sum = firstTwoSum + counters[2] + counters[3];\n    float ratio = (float) firstTwoSum / (float) sum;\n    if (ratio >= MIN_FINDER_PATTERN_RATIO && ratio <= MAX_FINDER_PATTERN_RATIO) {\n      // passes ratio test in spec, but see if the counts are unreasonable\n      int minCounter = Integer.MAX_VALUE;\n      int maxCounter = Integer.MIN_VALUE;\n      for (int counter : counters) {\n        if (counter > maxCounter) {\n          maxCounter = counter;\n        }\n        if (counter < minCounter) {\n          minCounter = counter;\n        }\n      }\n      return maxCounter < 10 * minCounter;\n    }\n    return false;\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/rss/DataCharacter.java",
    "content": "/*\n * Copyright 2009 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.oned.rss;\n\npublic class DataCharacter {\n\n  private final int value;\n  private final int checksumPortion;\n\n  public DataCharacter(int value, int checksumPortion) {\n    this.value = value;\n    this.checksumPortion = checksumPortion;\n  }\n\n  public final int getValue() {\n    return value;\n  }\n\n  public final int getChecksumPortion() {\n    return checksumPortion;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/rss/FinderPattern.java",
    "content": "/*\n * Copyright 2009 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.oned.rss;\n\nimport com.google.zxing.ResultPoint;\n\npublic final class FinderPattern {\n\n  private final int value;\n  private final int[] startEnd;\n  private final ResultPoint[] resultPoints;\n\n  public FinderPattern(int value, int[] startEnd, int start, int end, int rowNumber) {\n    this.value = value;\n    this.startEnd = startEnd;\n    this.resultPoints = new ResultPoint[] {\n        new ResultPoint((float) start, (float) rowNumber),\n        new ResultPoint((float) end, (float) rowNumber),\n    };\n  }\n\n  public int getValue() {\n    return value;\n  }\n\n  public int[] getStartEnd() {\n    return startEnd;\n  }\n\n  public ResultPoint[] getResultPoints() {\n    return resultPoints;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/rss/Pair.java",
    "content": "/*\n * Copyright 2009 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.oned.rss;\n\nfinal class Pair extends DataCharacter {\n\n  private final FinderPattern finderPattern;\n  private int count;\n\n  Pair(int value, int checksumPortion, FinderPattern finderPattern) {\n    super(value, checksumPortion);\n    this.finderPattern = finderPattern;\n  }\n\n  FinderPattern getFinderPattern() {\n    return finderPattern;\n  }\n\n  int getCount() {\n    return count;\n  }\n\n  void incrementCount() {\n    count++;\n  }\n\n}"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/rss/RSS14Reader.java",
    "content": "/*\n * Copyright 2009 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.oned.rss;\n\nimport com.google.zxing.BarcodeFormat;\nimport com.google.zxing.DecodeHintType;\nimport com.google.zxing.NotFoundException;\nimport com.google.zxing.Result;\nimport com.google.zxing.ResultPoint;\nimport com.google.zxing.ResultPointCallback;\nimport com.google.zxing.common.BitArray;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * Decodes RSS-14, including truncated and stacked variants. See ISO/IEC 24724:2006.\n */\npublic final class RSS14Reader extends AbstractRSSReader {\n\n  private static final int[] OUTSIDE_EVEN_TOTAL_SUBSET = {1,10,34,70,126};\n  private static final int[] INSIDE_ODD_TOTAL_SUBSET = {4,20,48,81};\n  private static final int[] OUTSIDE_GSUM = {0,161,961,2015,2715};\n  private static final int[] INSIDE_GSUM = {0,336,1036,1516};\n  private static final int[] OUTSIDE_ODD_WIDEST = {8,6,4,3,1};\n  private static final int[] INSIDE_ODD_WIDEST = {2,4,6,8};\n\n  private static final int[][] FINDER_PATTERNS = {\n      {3,8,2,1},\n      {3,5,5,1},\n      {3,3,7,1},\n      {3,1,9,1},\n      {2,7,4,1},\n      {2,5,6,1},\n      {2,3,8,1},\n      {1,5,7,1},\n      {1,3,9,1},\n  };\n\n  private final List<Pair> possibleLeftPairs;\n  private final List<Pair> possibleRightPairs;\n\n  public RSS14Reader() {\n    possibleLeftPairs = new ArrayList<Pair>();\n    possibleRightPairs = new ArrayList<Pair>();\n  }\n\n  @Override\n  public Result decodeRow(int rowNumber,\n                          BitArray row,\n                          Map<DecodeHintType,?> hints) throws NotFoundException {\n    Pair leftPair = decodePair(row, false, rowNumber, hints);\n    addOrTally(possibleLeftPairs, leftPair);\n    row.reverse();\n    Pair rightPair = decodePair(row, true, rowNumber, hints);\n    addOrTally(possibleRightPairs, rightPair);\n    row.reverse();\n    for (Pair left : possibleLeftPairs) {\n      if (left.getCount() > 1) {\n        for (Pair right : possibleRightPairs) {\n          if (right.getCount() > 1) {\n            if (checkChecksum(left, right)) {\n              return constructResult(left, right);\n            }\n          }\n        }\n      }\n    }\n    throw NotFoundException.getNotFoundInstance();\n  }\n\n  private static void addOrTally(Collection<Pair> possiblePairs, Pair pair) {\n    if (pair == null) {\n      return;\n    }\n    boolean found = false;\n    for (Pair other : possiblePairs) {\n      if (other.getValue() == pair.getValue()) {\n        other.incrementCount();\n        found = true;\n        break;\n      }\n    }\n    if (!found) {\n      possiblePairs.add(pair);\n    }\n  }\n\n  @Override\n  public void reset() {\n    possibleLeftPairs.clear();\n    possibleRightPairs.clear();\n  }\n\n  private static Result constructResult(Pair leftPair, Pair rightPair) {\n    long symbolValue = 4537077L * leftPair.getValue() + rightPair.getValue();\n    String text = String.valueOf(symbolValue);\n\n    StringBuilder buffer = new StringBuilder(14);\n    for (int i = 13 - text.length(); i > 0; i--) {\n      buffer.append('0');\n    }\n    buffer.append(text);\n\n    int checkDigit = 0;\n    for (int i = 0; i < 13; i++) {\n      int digit = buffer.charAt(i) - '0';\n      checkDigit += (i & 0x01) == 0 ? 3 * digit : digit;\n    }\n    checkDigit = 10 - (checkDigit % 10);\n    if (checkDigit == 10) {\n      checkDigit = 0;\n    }\n    buffer.append(checkDigit);\n\n    ResultPoint[] leftPoints = leftPair.getFinderPattern().getResultPoints();\n    ResultPoint[] rightPoints = rightPair.getFinderPattern().getResultPoints();\n    return new Result(\n        String.valueOf(buffer.toString()),\n        null,\n        new ResultPoint[] { leftPoints[0], leftPoints[1], rightPoints[0], rightPoints[1], },\n        BarcodeFormat.RSS_14);\n  }\n\n  private static boolean checkChecksum(Pair leftPair, Pair rightPair) {\n    int leftFPValue = leftPair.getFinderPattern().getValue();\n    int rightFPValue = rightPair.getFinderPattern().getValue();\n    if ((leftFPValue == 0 && rightFPValue == 8) ||\n        (leftFPValue == 8 && rightFPValue == 0)) {\n    }\n    int checkValue = (leftPair.getChecksumPortion() + 16 * rightPair.getChecksumPortion()) % 79;\n    int targetCheckValue =\n        9 * leftPair.getFinderPattern().getValue() + rightPair.getFinderPattern().getValue();\n    if (targetCheckValue > 72) {\n      targetCheckValue--;\n    }\n    if (targetCheckValue > 8) {\n      targetCheckValue--;\n    }\n    return checkValue == targetCheckValue;\n  }\n\n  private Pair decodePair(BitArray row, boolean right, int rowNumber, Map<DecodeHintType,?> hints) {\n    try {\n      int[] startEnd = findFinderPattern(row, 0, right);\n      FinderPattern pattern = parseFoundFinderPattern(row, rowNumber, right, startEnd);\n\n      ResultPointCallback resultPointCallback = hints == null ? null :\n        (ResultPointCallback) hints.get(DecodeHintType.NEED_RESULT_POINT_CALLBACK);\n\n      if (resultPointCallback != null) {\n        float center = (startEnd[0] + startEnd[1]) / 2.0f;\n        if (right) {\n          // row is actually reversed\n          center = row.getSize() - 1 - center;\n        }\n        resultPointCallback.foundPossibleResultPoint(new ResultPoint(center, rowNumber));\n      }\n\n      DataCharacter outside = decodeDataCharacter(row, pattern, true);\n      DataCharacter inside = decodeDataCharacter(row, pattern, false);\n      return new Pair(1597 * outside.getValue() + inside.getValue(),\n                      outside.getChecksumPortion() + 4 * inside.getChecksumPortion(),\n                      pattern);\n    } catch (NotFoundException re) {\n      return null;\n    }\n  }\n\n  private DataCharacter decodeDataCharacter(BitArray row, FinderPattern pattern, boolean outsideChar)\n      throws NotFoundException {\n\n    int[] counters = getDataCharacterCounters();\n    counters[0] = 0;\n    counters[1] = 0;\n    counters[2] = 0;\n    counters[3] = 0;\n    counters[4] = 0;\n    counters[5] = 0;\n    counters[6] = 0;\n    counters[7] = 0;\n\n    if (outsideChar) {\n      recordPatternInReverse(row, pattern.getStartEnd()[0], counters);\n    } else {\n      recordPattern(row, pattern.getStartEnd()[1] + 1, counters);\n      // reverse it\n      for (int i = 0, j = counters.length - 1; i < j; i++, j--) {\n        int temp = counters[i];\n        counters[i] = counters[j];\n        counters[j] = temp;\n      }\n    }\n\n    int numModules = outsideChar ? 16 : 15;\n    float elementWidth = (float) count(counters) / (float) numModules;\n\n    int[] oddCounts = this.getOddCounts();\n    int[] evenCounts = this.getEvenCounts();\n    float[] oddRoundingErrors = this.getOddRoundingErrors();\n    float[] evenRoundingErrors = this.getEvenRoundingErrors();\n\n    for (int i = 0; i < counters.length; i++) {\n      float value = (float) counters[i] / elementWidth;\n      int count = (int) (value + 0.5f); // Round\n      if (count < 1) {\n        count = 1;\n      } else if (count > 8) {\n        count = 8;\n      }\n      int offset = i >> 1;\n      if ((i & 0x01) == 0) {\n        oddCounts[offset] = count;\n        oddRoundingErrors[offset] = value - count;\n      } else {\n        evenCounts[offset] = count;\n        evenRoundingErrors[offset] = value - count;\n      }\n    }\n\n    adjustOddEvenCounts(outsideChar, numModules);\n\n    int oddSum = 0;\n    int oddChecksumPortion = 0;\n    for (int i = oddCounts.length - 1; i >= 0; i--) {\n      oddChecksumPortion *= 9;\n      oddChecksumPortion += oddCounts[i];\n      oddSum += oddCounts[i];\n    }\n    int evenChecksumPortion = 0;\n    int evenSum = 0;\n    for (int i = evenCounts.length - 1; i >= 0; i--) {\n      evenChecksumPortion *= 9;\n      evenChecksumPortion += evenCounts[i];\n      evenSum += evenCounts[i];\n    }\n    int checksumPortion = oddChecksumPortion + 3*evenChecksumPortion;\n\n    if (outsideChar) {\n      if ((oddSum & 0x01) != 0 || oddSum > 12 || oddSum < 4) {\n        throw NotFoundException.getNotFoundInstance();\n      }\n      int group = (12 - oddSum) / 2;\n      int oddWidest = OUTSIDE_ODD_WIDEST[group];\n      int evenWidest = 9 - oddWidest;\n      int vOdd = RSSUtils.getRSSvalue(oddCounts, oddWidest, false);\n      int vEven = RSSUtils.getRSSvalue(evenCounts, evenWidest, true);\n      int tEven = OUTSIDE_EVEN_TOTAL_SUBSET[group];\n      int gSum = OUTSIDE_GSUM[group];\n      return new DataCharacter(vOdd * tEven + vEven + gSum, checksumPortion);\n    } else {\n      if ((evenSum & 0x01) != 0 || evenSum > 10 || evenSum < 4) {\n        throw NotFoundException.getNotFoundInstance();\n      }\n      int group = (10 - evenSum) / 2;\n      int oddWidest = INSIDE_ODD_WIDEST[group];\n      int evenWidest = 9 - oddWidest;\n      int vOdd = RSSUtils.getRSSvalue(oddCounts, oddWidest, true);\n      int vEven = RSSUtils.getRSSvalue(evenCounts, evenWidest, false);\n      int tOdd = INSIDE_ODD_TOTAL_SUBSET[group];\n      int gSum = INSIDE_GSUM[group];\n      return new DataCharacter(vEven * tOdd + vOdd + gSum, checksumPortion);\n    }\n\n  }\n\n  private int[] findFinderPattern(BitArray row, int rowOffset, boolean rightFinderPattern)\n      throws NotFoundException {\n\n    int[] counters = getDecodeFinderCounters();\n    counters[0] = 0;\n    counters[1] = 0;\n    counters[2] = 0;\n    counters[3] = 0;\n\n    int width = row.getSize();\n    boolean isWhite = false;\n    while (rowOffset < width) {\n      isWhite = !row.get(rowOffset);\n      if (rightFinderPattern == isWhite) {\n        // Will encounter white first when searching for right finder pattern\n        break;\n      }\n      rowOffset++;\n    }\n\n    int counterPosition = 0;\n    int patternStart = rowOffset;\n    for (int x = rowOffset; x < width; x++) {\n      if (row.get(x) ^ isWhite) {\n        counters[counterPosition]++;\n      } else {\n        if (counterPosition == 3) {\n          if (isFinderPattern(counters)) {\n            return new int[]{patternStart, x};\n          }\n          patternStart += counters[0] + counters[1];\n          counters[0] = counters[2];\n          counters[1] = counters[3];\n          counters[2] = 0;\n          counters[3] = 0;\n          counterPosition--;\n        } else {\n          counterPosition++;\n        }\n        counters[counterPosition] = 1;\n        isWhite = !isWhite;\n      }\n    }\n    throw NotFoundException.getNotFoundInstance();\n\n  }\n\n  private FinderPattern parseFoundFinderPattern(BitArray row, int rowNumber, boolean right, int[] startEnd)\n      throws NotFoundException {\n    // Actually we found elements 2-5\n    boolean firstIsBlack = row.get(startEnd[0]);\n    int firstElementStart = startEnd[0] - 1;\n    // Locate element 1\n    while (firstElementStart >= 0 && firstIsBlack ^ row.get(firstElementStart)) {\n      firstElementStart--;\n    }\n    firstElementStart++;\n    int firstCounter = startEnd[0] - firstElementStart;\n    // Make 'counters' hold 1-4\n    int[] counters = getDecodeFinderCounters();\n    System.arraycopy(counters, 0, counters, 1, counters.length - 1);\n    counters[0] = firstCounter;\n    int value = parseFinderValue(counters, FINDER_PATTERNS);\n    int start = firstElementStart;\n    int end = startEnd[1];\n    if (right) {\n      // row is actually reversed\n      start = row.getSize() - 1 - start;\n      end = row.getSize() - 1 - end;\n    }\n    return new FinderPattern(value, new int[] {firstElementStart, startEnd[1]}, start, end, rowNumber);\n  }\n\n  private void adjustOddEvenCounts(boolean outsideChar, int numModules) throws NotFoundException {\n\n    int oddSum = count(getOddCounts());\n    int evenSum = count(getEvenCounts());\n    int mismatch = oddSum + evenSum - numModules;\n    boolean oddParityBad = (oddSum & 0x01) == (outsideChar ? 1 : 0);\n    boolean evenParityBad = (evenSum & 0x01) == 1;\n\n    boolean incrementOdd = false;\n    boolean decrementOdd = false;\n    boolean incrementEven = false;\n    boolean decrementEven = false;\n\n    if (outsideChar) {\n      if (oddSum > 12) {\n        decrementOdd = true;\n      } else if (oddSum < 4) {\n        incrementOdd = true;\n      }\n      if (evenSum > 12) {\n        decrementEven = true;\n      } else if (evenSum < 4) {\n        incrementEven = true;\n      }\n    } else {\n      if (oddSum > 11) {\n        decrementOdd = true;\n      } else if (oddSum < 5) {\n        incrementOdd = true;\n      }\n      if (evenSum > 10) {\n        decrementEven = true;\n      } else if (evenSum < 4) {\n        incrementEven = true;\n      }\n    }\n\n    /*if (mismatch == 2) {\n      if (!(oddParityBad && evenParityBad)) {\n        throw ReaderException.getInstance();\n      }\n      decrementOdd = true;\n      decrementEven = true;\n    } else if (mismatch == -2) {\n      if (!(oddParityBad && evenParityBad)) {\n        throw ReaderException.getInstance();\n      }\n      incrementOdd = true;\n      incrementEven = true;\n    } else */if (mismatch == 1) {\n      if (oddParityBad) {\n        if (evenParityBad) {\n          throw NotFoundException.getNotFoundInstance();\n        }\n        decrementOdd = true;\n      } else {\n        if (!evenParityBad) {\n          throw NotFoundException.getNotFoundInstance();\n        }\n        decrementEven = true;\n      }\n    } else if (mismatch == -1) {\n      if (oddParityBad) {\n        if (evenParityBad) {\n          throw NotFoundException.getNotFoundInstance();\n        }\n        incrementOdd = true;\n      } else {\n        if (!evenParityBad) {\n          throw NotFoundException.getNotFoundInstance();\n        }\n        incrementEven = true;\n      }\n    } else if (mismatch == 0) {\n      if (oddParityBad) {\n        if (!evenParityBad) {\n          throw NotFoundException.getNotFoundInstance();\n        }\n        // Both bad\n        if (oddSum < evenSum) {\n          incrementOdd = true;\n          decrementEven = true;\n        } else {\n          decrementOdd = true;\n          incrementEven = true;\n        }\n      } else {\n        if (evenParityBad) {\n          throw NotFoundException.getNotFoundInstance();\n        }\n        // Nothing to do!\n      }\n    } else {\n      throw NotFoundException.getNotFoundInstance();\n    }\n\n    if (incrementOdd) {\n      if (decrementOdd) {\n        throw NotFoundException.getNotFoundInstance();\n      }\n      increment(getOddCounts(), getOddRoundingErrors());\n    }\n    if (decrementOdd) {\n      decrement(getOddCounts(), getOddRoundingErrors());\n    }\n    if (incrementEven) {\n      if (decrementEven) {\n        throw NotFoundException.getNotFoundInstance();\n      }\n      increment(getEvenCounts(), getOddRoundingErrors());\n    }\n    if (decrementEven) {\n      decrement(getEvenCounts(), getEvenRoundingErrors());\n    }\n\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/rss/RSSUtils.java",
    "content": "/*\n * Copyright 2009 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.oned.rss;\n\n/** Adapted from listings in ISO/IEC 24724 Appendix B and Appendix G. */\npublic final class RSSUtils {\n\n  private RSSUtils() {}\n\n  static int[] getRSSwidths(int val, int n, int elements, int maxWidth, boolean noNarrow) {\n    int[] widths = new int[elements];\n    int bar;\n    int narrowMask = 0;\n    for (bar = 0; bar < elements - 1; bar++) {\n      narrowMask |= 1 << bar;\n      int elmWidth = 1;\n      int subVal;\n      while (true) {\n        subVal = combins(n - elmWidth - 1, elements - bar - 2);\n        if (noNarrow && (narrowMask == 0) &&\n            (n - elmWidth - (elements - bar - 1) >= elements - bar - 1)) {\n          subVal -= combins(n - elmWidth - (elements - bar), elements - bar - 2);\n        }\n        if (elements - bar - 1 > 1) {\n          int lessVal = 0;\n          for (int mxwElement = n - elmWidth - (elements - bar - 2);\n               mxwElement > maxWidth;\n               mxwElement--) {\n            lessVal += combins(n - elmWidth - mxwElement - 1, elements - bar - 3);\n          }\n          subVal -= lessVal * (elements - 1 - bar);\n        } else if (n - elmWidth > maxWidth) {\n          subVal--;\n        }\n        val -= subVal;\n        if (val < 0) {\n          break;\n        }\n        elmWidth++;\n        narrowMask &= ~(1 << bar);\n      }\n      val += subVal;\n      n -= elmWidth;\n      widths[bar] = elmWidth;\n    }\n    widths[bar] = n;\n    return widths;\n  }\n\n  public static int getRSSvalue(int[] widths, int maxWidth, boolean noNarrow) {\n    int elements = widths.length;\n    int n = 0;\n    for (int width : widths) {\n      n += width;\n    }\n    int val = 0;\n    int narrowMask = 0;\n    for (int bar = 0; bar < elements - 1; bar++) {\n      int elmWidth;\n      for (elmWidth = 1, narrowMask |= 1 << bar;\n           elmWidth < widths[bar];\n           elmWidth++, narrowMask &= ~(1 << bar)) {\n        int subVal = combins(n - elmWidth - 1, elements - bar - 2);\n        if (noNarrow && (narrowMask == 0) &&\n            (n - elmWidth - (elements - bar - 1) >= elements - bar - 1)) {\n          subVal -= combins(n - elmWidth - (elements - bar),\n                            elements - bar - 2);\n        }\n        if (elements - bar - 1 > 1) {\n          int lessVal = 0;\n          for (int mxwElement = n - elmWidth - (elements - bar - 2);\n               mxwElement > maxWidth; mxwElement--) {\n            lessVal += combins(n - elmWidth - mxwElement - 1,\n                               elements - bar - 3);\n          }\n          subVal -= lessVal * (elements - 1 - bar);\n        } else if (n - elmWidth > maxWidth) {\n          subVal--;\n        }\n        val += subVal;\n      }\n      n -= elmWidth;\n    }\n    return val;\n  }\n\n  private static int combins(int n, int r) {\n    int maxDenom;\n    int minDenom;\n    if (n - r > r) {\n      minDenom = r;\n      maxDenom = n - r;\n    } else {\n      minDenom = n - r;\n      maxDenom = r;\n    }\n    int val = 1;\n    int j = 1;\n    for (int i = n; i > maxDenom; i--) {\n      val *= i;\n      if (j <= minDenom) {\n        val /= j;\n        j++;\n      }\n    }\n    while (j <= minDenom) {\n      val /= j;\n      j++;\n    }\n    return val;\n  }\n\n  static int[] elements(int[] eDist, int N, int K) {\n    int[] widths = new int[eDist.length + 2];\n    int twoK = K << 1;\n    widths[0] = 1;\n    int i;\n    int minEven = 10;\n    int barSum = 1;\n    for (i = 1; i < twoK - 2; i += 2) {\n      widths[i] = eDist[i - 1] - widths[i - 1];\n      widths[i + 1] = eDist[i] - widths[i];\n      barSum += widths[i] + widths[i + 1];\n      if (widths[i] < minEven) {\n        minEven = widths[i];\n      }\n    }\n    widths[twoK - 1] = N - barSum;\n    if (widths[twoK - 1] < minEven) {\n      minEven = widths[twoK - 1];\n    }\n    if (minEven > 1) {\n      for (i = 0; i < twoK; i += 2) {\n        widths[i] += minEven - 1;\n        widths[i + 1] -= minEven - 1;\n      }\n    }\n    return widths;\n  }\n\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/rss/expanded/BitArrayBuilder.java",
    "content": "/*\n * Copyright (C) 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * These authors would like to acknowledge the Spanish Ministry of Industry,\n * Tourism and Trade, for the support in the project TSI020301-2008-2\n * \"PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled\n * Mobile Dynamic Environments\", led by Treelogic\n * ( http://www.treelogic.com/ ):\n *\n *   http://www.piramidepse.com/\n */\n\npackage com.google.zxing.oned.rss.expanded;\n\nimport com.google.zxing.common.BitArray;\n\nimport java.util.List;\n\n/**\n * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)\n * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)\n */\nfinal class BitArrayBuilder {\n\n  private BitArrayBuilder() {\n  }\n\n  static BitArray buildBitArray(List<ExpandedPair> pairs) {\n    int charNumber = (pairs.size() << 1) - 1;\n    if (pairs.get(pairs.size() - 1).getRightChar() == null) {\n      charNumber -= 1;\n    }\n\n    int size = 12 * charNumber;\n\n    BitArray binary = new BitArray(size);\n    int accPos = 0;\n\n    ExpandedPair firstPair = pairs.get(0);\n    int firstValue = firstPair.getRightChar().getValue();\n    for(int i = 11; i >= 0; --i){\n      if ((firstValue & (1 << i)) != 0) {\n        binary.set(accPos);\n      }\n      accPos++;\n    }\n\n    for(int i = 1; i < pairs.size(); ++i){\n      ExpandedPair currentPair = pairs.get(i);\n\n      int leftValue = currentPair.getLeftChar().getValue();\n      for(int j = 11; j >= 0; --j){\n        if ((leftValue & (1 << j)) != 0) {\n          binary.set(accPos);\n        }\n        accPos++;\n      }\n\n      if(currentPair.getRightChar() != null){\n        int rightValue = currentPair.getRightChar().getValue();\n        for(int j = 11; j >= 0; --j){\n          if ((rightValue & (1 << j)) != 0) {\n            binary.set(accPos);\n          }\n          accPos++;\n        }\n      }\n    }\n    return binary;\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/rss/expanded/ExpandedPair.java",
    "content": "/*\n * Copyright (C) 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * These authors would like to acknowledge the Spanish Ministry of Industry,\n * Tourism and Trade, for the support in the project TSI020301-2008-2\n * \"PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled\n * Mobile Dynamic Environments\", led by Treelogic\n * ( http://www.treelogic.com/ ):\n *\n *   http://www.piramidepse.com/\n */\n\npackage com.google.zxing.oned.rss.expanded;\n\nimport com.google.zxing.oned.rss.DataCharacter;\nimport com.google.zxing.oned.rss.FinderPattern;\n\n/**\n * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)\n */\nfinal class ExpandedPair {\n\n  private final boolean mayBeLast;\n  private final DataCharacter leftChar;\n  private final DataCharacter rightChar;\n  private final FinderPattern finderPattern;\n\n  ExpandedPair(DataCharacter leftChar,\n               DataCharacter rightChar,\n               FinderPattern finderPattern,\n               boolean mayBeLast) {\n    this.leftChar      = leftChar;\n    this.rightChar     = rightChar;\n    this.finderPattern = finderPattern;\n    this.mayBeLast     = mayBeLast;\n  }\n\n  boolean mayBeLast(){\n    return this.mayBeLast;\n  }\n\n  DataCharacter getLeftChar() {\n    return this.leftChar;\n  }\n\n  DataCharacter getRightChar() {\n    return this.rightChar;\n  }\n\n  FinderPattern getFinderPattern() {\n    return this.finderPattern;\n  }\n\n  public boolean mustBeLast() {\n    return this.rightChar == null;\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/rss/expanded/RSSExpandedReader.java",
    "content": "/*\n * Copyright (C) 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * These authors would like to acknowledge the Spanish Ministry of Industry,\n * Tourism and Trade, for the support in the project TSI020301-2008-2\n * \"PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled\n * Mobile Dynamic Environments\", led by Treelogic\n * ( http://www.treelogic.com/ ):\n *\n *   http://www.piramidepse.com/\n */\n\npackage com.google.zxing.oned.rss.expanded;\n\nimport com.google.zxing.BarcodeFormat;\nimport com.google.zxing.DecodeHintType;\nimport com.google.zxing.NotFoundException;\nimport com.google.zxing.Result;\nimport com.google.zxing.ResultPoint;\nimport com.google.zxing.common.BitArray;\nimport com.google.zxing.oned.rss.AbstractRSSReader;\nimport com.google.zxing.oned.rss.DataCharacter;\nimport com.google.zxing.oned.rss.FinderPattern;\nimport com.google.zxing.oned.rss.RSSUtils;\nimport com.google.zxing.oned.rss.expanded.decoders.AbstractExpandedDecoder;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)\n * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)\n */\npublic final class RSSExpandedReader extends AbstractRSSReader {\n\n  private static final int[] SYMBOL_WIDEST = {7, 5, 4, 3, 1};\n  private static final int[] EVEN_TOTAL_SUBSET = {4, 20, 52, 104, 204};\n  private static final int[] GSUM = {0, 348, 1388, 2948, 3988};\n\n  private static final int[][] FINDER_PATTERNS = {\n    {1,8,4,1}, // A\n    {3,6,4,1}, // B\n    {3,4,6,1}, // C\n    {3,2,8,1}, // D\n    {2,6,5,1}, // E\n    {2,2,9,1}  // F\n  };\n\n  private static final int[][] WEIGHTS = {\n    {  1,   3,   9,  27,  81,  32,  96,  77},\n    { 20,  60, 180, 118, 143,   7,  21,  63},\n    {189, 145,  13,  39, 117, 140, 209, 205},\n    {193, 157,  49, 147,  19,  57, 171,  91},\n    { 62, 186, 136, 197, 169,  85,  44, 132},\n    {185, 133, 188, 142,   4,  12,  36, 108},\n    {113, 128, 173,  97,  80,  29,  87,  50},\n    {150,  28,  84,  41, 123, 158,  52, 156},\n    { 46, 138, 203, 187, 139, 206, 196, 166},\n    { 76,  17,  51, 153,  37, 111, 122, 155},\n    { 43, 129, 176, 106, 107, 110, 119, 146},\n    { 16,  48, 144,  10,  30,  90,  59, 177},\n    {109, 116, 137, 200, 178, 112, 125, 164},\n    { 70, 210, 208, 202, 184, 130, 179, 115},\n    {134, 191, 151,  31,  93,  68, 204, 190},\n    {148,  22,  66, 198, 172,   94, 71,   2},\n    {  6,  18,  54, 162,  64,  192,154,  40},\n    {120, 149,  25,  75,  14,   42,126, 167},\n    { 79,  26,  78,  23,  69,  207,199, 175},\n    {103,  98,  83,  38, 114, 131, 182, 124},\n    {161,  61, 183, 127, 170,  88,  53, 159},\n    { 55, 165,  73,   8,  24,  72,   5,  15},\n    { 45, 135, 194, 160,  58, 174, 100,  89}\n  };\n\n  private static final int FINDER_PAT_A = 0;\n  private static final int FINDER_PAT_B = 1;\n  private static final int FINDER_PAT_C = 2;\n  private static final int FINDER_PAT_D = 3;\n  private static final int FINDER_PAT_E = 4;\n  private static final int FINDER_PAT_F = 5;\n\n  private static final int[][] FINDER_PATTERN_SEQUENCES = {\n    { FINDER_PAT_A, FINDER_PAT_A },\n    { FINDER_PAT_A, FINDER_PAT_B, FINDER_PAT_B },\n    { FINDER_PAT_A, FINDER_PAT_C, FINDER_PAT_B, FINDER_PAT_D },\n    { FINDER_PAT_A, FINDER_PAT_E, FINDER_PAT_B, FINDER_PAT_D, FINDER_PAT_C },\n    { FINDER_PAT_A, FINDER_PAT_E, FINDER_PAT_B, FINDER_PAT_D, FINDER_PAT_D, FINDER_PAT_F },\n    { FINDER_PAT_A, FINDER_PAT_E, FINDER_PAT_B, FINDER_PAT_D, FINDER_PAT_E, FINDER_PAT_F, FINDER_PAT_F },\n    { FINDER_PAT_A, FINDER_PAT_A, FINDER_PAT_B, FINDER_PAT_B, FINDER_PAT_C, FINDER_PAT_C, FINDER_PAT_D, FINDER_PAT_D },\n    { FINDER_PAT_A, FINDER_PAT_A, FINDER_PAT_B, FINDER_PAT_B, FINDER_PAT_C, FINDER_PAT_C, FINDER_PAT_D, FINDER_PAT_E, FINDER_PAT_E },\n    { FINDER_PAT_A, FINDER_PAT_A, FINDER_PAT_B, FINDER_PAT_B, FINDER_PAT_C, FINDER_PAT_C, FINDER_PAT_D, FINDER_PAT_E, FINDER_PAT_F, FINDER_PAT_F },\n    { FINDER_PAT_A, FINDER_PAT_A, FINDER_PAT_B, FINDER_PAT_B, FINDER_PAT_C, FINDER_PAT_D, FINDER_PAT_D, FINDER_PAT_E, FINDER_PAT_E, FINDER_PAT_F, FINDER_PAT_F },\n  };\n\n  private static final int LONGEST_SEQUENCE_SIZE = FINDER_PATTERN_SEQUENCES[FINDER_PATTERN_SEQUENCES.length - 1].length;\n\n  private static final int MAX_PAIRS = 11;\n\n  private final List<ExpandedPair> pairs = new ArrayList<ExpandedPair>(MAX_PAIRS);\n  private final int [] startEnd = new int[2];\n  private final int [] currentSequence = new int[LONGEST_SEQUENCE_SIZE];\n\n  @Override\n  public Result decodeRow(int rowNumber,\n                          BitArray row,\n                          Map<DecodeHintType,?> hints) throws NotFoundException {\n    this.reset();\n    decodeRow2pairs(rowNumber, row);\n    return constructResult(this.pairs);\n  }\n\n  @Override\n  public void reset() {\n    this.pairs.clear();\n  }\n\n  // Not private for testing\n  List<ExpandedPair> decodeRow2pairs(int rowNumber, BitArray row) throws NotFoundException {\n    while(true){\n      ExpandedPair nextPair = retrieveNextPair(row, this.pairs, rowNumber);\n      this.pairs.add(nextPair);\n\n      if (nextPair.mayBeLast()) {\n        if (checkChecksum()) {\n          return this.pairs;\n        }\n        if (nextPair.mustBeLast()) {\n          throw NotFoundException.getNotFoundInstance();\n        }\n      }\n    }\n  }\n\n  private static Result constructResult(List<ExpandedPair> pairs) throws NotFoundException{\n    BitArray binary = BitArrayBuilder.buildBitArray(pairs);\n\n    AbstractExpandedDecoder decoder = AbstractExpandedDecoder.createDecoder(binary);\n    String resultingString = decoder.parseInformation();\n\n    ResultPoint[] firstPoints = pairs.get(0).getFinderPattern().getResultPoints();\n    ResultPoint[] lastPoints  = pairs.get(pairs.size() - 1).getFinderPattern().getResultPoints();\n\n    return new Result(\n          resultingString,\n          null,\n          new ResultPoint[]{firstPoints[0], firstPoints[1], lastPoints[0], lastPoints[1]},\n          BarcodeFormat.RSS_EXPANDED\n      );\n  }\n\n  private boolean checkChecksum() {\n    ExpandedPair firstPair = this.pairs.get(0);\n    DataCharacter checkCharacter = firstPair.getLeftChar();\n    DataCharacter firstCharacter = firstPair.getRightChar();\n\n    int checksum = firstCharacter.getChecksumPortion();\n    int s = 2;\n\n    for(int i = 1; i < this.pairs.size(); ++i){\n      ExpandedPair currentPair = this.pairs.get(i);\n      checksum += currentPair.getLeftChar().getChecksumPortion();\n      s++;\n      DataCharacter currentRightChar = currentPair.getRightChar();\n      if (currentRightChar != null) {\n        checksum += currentRightChar.getChecksumPortion();\n        s++;\n      }\n    }\n\n    checksum %= 211;\n\n    int checkCharacterValue = 211 * (s - 4) + checksum;\n\n    return checkCharacterValue == checkCharacter.getValue();\n  }\n\n  private static int getNextSecondBar(BitArray row, int initialPos){\n    int currentPos;\n    if (row.get(initialPos)) {\n      currentPos = row.getNextUnset(initialPos);\n      currentPos = row.getNextSet(currentPos);\n    } else {\n      currentPos = row.getNextSet(initialPos);\n      currentPos = row.getNextUnset(currentPos);\n    }\n    return currentPos;\n  }\n\n  // not private for testing\n  ExpandedPair retrieveNextPair(BitArray row, List<ExpandedPair> previousPairs, int rowNumber)\n      throws NotFoundException {\n    boolean isOddPattern  = previousPairs.size() % 2 == 0;\n\n    FinderPattern pattern;\n\n    boolean keepFinding = true;\n    int forcedOffset = -1;\n    do{\n      this.findNextPair(row, previousPairs, forcedOffset);\n      pattern = parseFoundFinderPattern(row, rowNumber, isOddPattern);\n      if (pattern == null){\n        forcedOffset = getNextSecondBar(row, this.startEnd[0]);\n      } else {\n        keepFinding = false;\n      }\n    }while(keepFinding);\n\n    boolean mayBeLast = checkPairSequence(previousPairs, pattern);\n\n    DataCharacter leftChar  = this.decodeDataCharacter(row, pattern, isOddPattern, true);\n    DataCharacter rightChar;\n    try{\n      rightChar = this.decodeDataCharacter(row, pattern, isOddPattern, false);\n    }catch(NotFoundException nfe){\n      if(mayBeLast) {\n        rightChar = null;\n      } else {\n        throw nfe;\n      }\n    }\n    return new ExpandedPair(leftChar, rightChar, pattern, mayBeLast);\n  }\n\n  private boolean checkPairSequence(List<ExpandedPair> previousPairs, FinderPattern pattern)\n      throws NotFoundException {\n    int currentSequenceLength = previousPairs.size() + 1;\n    if(currentSequenceLength > this.currentSequence.length) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n\n    for(int pos = 0; pos < previousPairs.size(); ++pos) {\n      this.currentSequence[pos] = previousPairs.get(pos).getFinderPattern().getValue();\n    }\n\n    this.currentSequence[currentSequenceLength - 1] = pattern.getValue();\n\n    for (int[] validSequence : FINDER_PATTERN_SEQUENCES) {\n      if (validSequence.length >= currentSequenceLength) {\n        boolean valid = true;\n        for (int pos = 0; pos < currentSequenceLength; ++pos) {\n          if (this.currentSequence[pos] != validSequence[pos]) {\n            valid = false;\n            break;\n          }\n        }\n\n        if (valid) {\n          return currentSequenceLength == validSequence.length;\n        }\n      }\n    }\n\n    throw NotFoundException.getNotFoundInstance();\n  }\n\n  private void findNextPair(BitArray row, List<ExpandedPair> previousPairs, int forcedOffset)\n      throws NotFoundException {\n    int[] counters = this.getDecodeFinderCounters();\n    counters[0] = 0;\n    counters[1] = 0;\n    counters[2] = 0;\n    counters[3] = 0;\n\n    int width = row.getSize();\n\n    int rowOffset;\n    if (forcedOffset >= 0) {\n      rowOffset = forcedOffset;\n    } else if (previousPairs.isEmpty()) {\n      rowOffset = 0;\n    } else{\n      ExpandedPair lastPair = previousPairs.get(previousPairs.size() - 1);\n      rowOffset = lastPair.getFinderPattern().getStartEnd()[1];\n    }\n    boolean searchingEvenPair = previousPairs.size() % 2 != 0;\n\n    boolean isWhite = false;\n    while (rowOffset < width) {\n      isWhite = !row.get(rowOffset);\n      if (!isWhite) {\n        break;\n      }\n      rowOffset++;\n    }\n\n    int counterPosition = 0;\n    int patternStart = rowOffset;\n    for (int x = rowOffset; x < width; x++) {\n      if (row.get(x) ^ isWhite) {\n        counters[counterPosition]++;\n      } else {\n        if (counterPosition == 3) {\n          if (searchingEvenPair) {\n            reverseCounters(counters);\n          }\n\n          if (isFinderPattern(counters)){\n            this.startEnd[0] = patternStart;\n            this.startEnd[1] = x;\n            return;\n          }\n\n          if (searchingEvenPair) {\n            reverseCounters(counters);\n          }\n\n          patternStart += counters[0] + counters[1];\n          counters[0] = counters[2];\n          counters[1] = counters[3];\n          counters[2] = 0;\n          counters[3] = 0;\n          counterPosition--;\n        } else {\n          counterPosition++;\n        }\n        counters[counterPosition] = 1;\n        isWhite = !isWhite;\n      }\n    }\n    throw NotFoundException.getNotFoundInstance();\n  }\n\n  private static void reverseCounters(int [] counters){\n    int length = counters.length;\n    for(int i = 0; i < length / 2; ++i){\n      int tmp = counters[i];\n      counters[i] = counters[length - i - 1];\n      counters[length - i - 1] = tmp;\n    }\n  }\n\n  private FinderPattern parseFoundFinderPattern(BitArray row, int rowNumber, boolean oddPattern) {\n    // Actually we found elements 2-5.\n    int firstCounter;\n    int start;\n    int end;\n\n    if(oddPattern){\n      // If pattern number is odd, we need to locate element 1 *before* the current block.\n\n      int firstElementStart = this.startEnd[0] - 1;\n      // Locate element 1\n      while (firstElementStart >= 0 && !row.get(firstElementStart)) {\n        firstElementStart--;\n      }\n\n      firstElementStart++;\n      firstCounter = this.startEnd[0] - firstElementStart;\n      start = firstElementStart;\n      end = this.startEnd[1];\n\n    }else{\n      // If pattern number is even, the pattern is reversed, so we need to locate element 1 *after* the current block.\n\n      start = this.startEnd[0];\n\n      end = row.getNextUnset(this.startEnd[1] + 1);\n      firstCounter = end - this.startEnd[1];\n    }\n\n    // Make 'counters' hold 1-4\n    int [] counters = this.getDecodeFinderCounters();\n    System.arraycopy(counters, 0, counters, 1, counters.length - 1);\n\n    counters[0] = firstCounter;\n    int value;\n    try {\n      value = parseFinderValue(counters, FINDER_PATTERNS);\n    } catch (NotFoundException nfe) {\n      return null;\n    }\n    return new FinderPattern(value, new int[] {start, end}, start, end, rowNumber);\n  }\n\n  DataCharacter decodeDataCharacter(BitArray row,\n                                    FinderPattern pattern,\n                                    boolean isOddPattern,\n                                    boolean leftChar) throws NotFoundException {\n    int[] counters = this.getDataCharacterCounters();\n    counters[0] = 0;\n    counters[1] = 0;\n    counters[2] = 0;\n    counters[3] = 0;\n    counters[4] = 0;\n    counters[5] = 0;\n    counters[6] = 0;\n    counters[7] = 0;\n\n    if (leftChar) {\n      recordPatternInReverse(row, pattern.getStartEnd()[0], counters);\n    } else {\n      recordPattern(row, pattern.getStartEnd()[1] + 1, counters);\n      // reverse it\n      for (int i = 0, j = counters.length - 1; i < j; i++, j--) {\n        int temp = counters[i];\n        counters[i] = counters[j];\n        counters[j] = temp;\n      }\n    }//counters[] has the pixels of the module\n\n    int numModules = 17; //left and right data characters have all the same length\n    float elementWidth = (float) count(counters) / (float) numModules;\n\n    int[] oddCounts = this.getOddCounts();\n    int[] evenCounts = this.getEvenCounts();\n    float[] oddRoundingErrors = this.getOddRoundingErrors();\n    float[] evenRoundingErrors = this.getEvenRoundingErrors();\n\n    for (int i = 0; i < counters.length; i++) {\n      float value = 1.0f * counters[i] / elementWidth;\n      int count = (int) (value + 0.5f); // Round\n      if (count < 1) {\n        count = 1;\n      } else if (count > 8) {\n        count = 8;\n      }\n      int offset = i >> 1;\n      if ((i & 0x01) == 0) {\n        oddCounts[offset] = count;\n        oddRoundingErrors[offset] = value - count;\n      } else {\n        evenCounts[offset] = count;\n        evenRoundingErrors[offset] = value - count;\n      }\n    }\n\n    adjustOddEvenCounts(numModules);\n\n    int weightRowNumber = 4 * pattern.getValue() + (isOddPattern?0:2) + (leftChar?0:1) - 1;\n\n    int oddSum = 0;\n    int oddChecksumPortion = 0;\n    for (int i = oddCounts.length - 1; i >= 0; i--) {\n      if(isNotA1left(pattern, isOddPattern, leftChar)){\n        int weight = WEIGHTS[weightRowNumber][2 * i];\n        oddChecksumPortion += oddCounts[i] * weight;\n      }\n      oddSum += oddCounts[i];\n    }\n    int evenChecksumPortion = 0;\n    int evenSum = 0;\n    for (int i = evenCounts.length - 1; i >= 0; i--) {\n      if(isNotA1left(pattern, isOddPattern, leftChar)){\n        int weight = WEIGHTS[weightRowNumber][2 * i + 1];\n        evenChecksumPortion += evenCounts[i] * weight;\n      }\n      evenSum += evenCounts[i];\n    }\n    int checksumPortion = oddChecksumPortion + evenChecksumPortion;\n\n    if ((oddSum & 0x01) != 0 || oddSum > 13 || oddSum < 4) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n\n    int group = (13 - oddSum) / 2;\n    int oddWidest = SYMBOL_WIDEST[group];\n    int evenWidest = 9 - oddWidest;\n    int vOdd = RSSUtils.getRSSvalue(oddCounts, oddWidest, true);\n    int vEven = RSSUtils.getRSSvalue(evenCounts, evenWidest, false);\n    int tEven = EVEN_TOTAL_SUBSET[group];\n    int gSum = GSUM[group];\n    int value = vOdd * tEven + vEven + gSum;\n\n    return new DataCharacter(value, checksumPortion);\n  }\n\n  private static boolean isNotA1left(FinderPattern pattern, boolean isOddPattern, boolean leftChar) {\n    // A1: pattern.getValue is 0 (A), and it's an oddPattern, and it is a left char\n    return !(pattern.getValue() == 0 && isOddPattern && leftChar);\n  }\n\n  private void adjustOddEvenCounts(int numModules) throws NotFoundException {\n\n    int oddSum = count(this.getOddCounts());\n    int evenSum = count(this.getEvenCounts());\n    int mismatch = oddSum + evenSum - numModules;\n    boolean oddParityBad = (oddSum & 0x01) == 1;\n    boolean evenParityBad = (evenSum & 0x01) == 0;\n\n    boolean incrementOdd = false;\n    boolean decrementOdd = false;\n\n    if (oddSum > 13) {\n      decrementOdd = true;\n    } else if (oddSum < 4) {\n      incrementOdd = true;\n    }\n    boolean incrementEven = false;\n    boolean decrementEven = false;\n    if (evenSum > 13) {\n      decrementEven = true;\n    } else if (evenSum < 4) {\n      incrementEven = true;\n    }\n\n    if (mismatch == 1) {\n      if (oddParityBad) {\n        if (evenParityBad) {\n          throw NotFoundException.getNotFoundInstance();\n        }\n        decrementOdd = true;\n      } else {\n        if (!evenParityBad) {\n          throw NotFoundException.getNotFoundInstance();\n        }\n        decrementEven = true;\n      }\n    } else if (mismatch == -1) {\n      if (oddParityBad) {\n        if (evenParityBad) {\n          throw NotFoundException.getNotFoundInstance();\n        }\n        incrementOdd = true;\n      } else {\n        if (!evenParityBad) {\n          throw NotFoundException.getNotFoundInstance();\n        }\n        incrementEven = true;\n      }\n    } else if (mismatch == 0) {\n      if (oddParityBad) {\n        if (!evenParityBad) {\n          throw NotFoundException.getNotFoundInstance();\n        }\n        // Both bad\n        if (oddSum < evenSum) {\n          incrementOdd = true;\n          decrementEven = true;\n        } else {\n          decrementOdd = true;\n          incrementEven = true;\n        }\n      } else {\n        if (evenParityBad) {\n          throw NotFoundException.getNotFoundInstance();\n        }\n        // Nothing to do!\n      }\n    } else {\n      throw NotFoundException.getNotFoundInstance();\n    }\n\n    if (incrementOdd) {\n      if (decrementOdd) {\n        throw NotFoundException.getNotFoundInstance();\n      }\n      increment(this.getOddCounts(), this.getOddRoundingErrors());\n    }\n    if (decrementOdd) {\n      decrement(this.getOddCounts(), this.getOddRoundingErrors());\n    }\n    if (incrementEven) {\n      if (decrementEven) {\n        throw NotFoundException.getNotFoundInstance();\n      }\n      increment(this.getEvenCounts(), this.getOddRoundingErrors());\n    }\n    if (decrementEven) {\n      decrement(this.getEvenCounts(), this.getEvenRoundingErrors());\n    }\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/rss/expanded/decoders/AI013103decoder.java",
    "content": "/*\n * Copyright (C) 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * These authors would like to acknowledge the Spanish Ministry of Industry,\n * Tourism and Trade, for the support in the project TSI020301-2008-2\n * \"PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled\n * Mobile Dynamic Environments\", led by Treelogic\n * ( http://www.treelogic.com/ ):\n *\n *   http://www.piramidepse.com/\n */\n\npackage com.google.zxing.oned.rss.expanded.decoders;\n\nimport com.google.zxing.common.BitArray;\n\n/**\n * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)\n */\nfinal class AI013103decoder extends AI013x0xDecoder {\n\n  AI013103decoder(BitArray information) {\n    super(information);\n  }\n\n  @Override\n  protected void addWeightCode(StringBuilder buf, int weight) {\n    buf.append(\"(3103)\");\n  }\n\n  @Override\n  protected int checkWeight(int weight) {\n    return weight;\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/rss/expanded/decoders/AI01320xDecoder.java",
    "content": "/*\n * Copyright (C) 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * These authors would like to acknowledge the Spanish Ministry of Industry,\n * Tourism and Trade, for the support in the project TSI020301-2008-2\n * \"PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled\n * Mobile Dynamic Environments\", led by Treelogic\n * ( http://www.treelogic.com/ ):\n *\n *   http://www.piramidepse.com/\n */\n\npackage com.google.zxing.oned.rss.expanded.decoders;\n\nimport com.google.zxing.common.BitArray;\n\n/**\n * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)\n */\nfinal class AI01320xDecoder extends AI013x0xDecoder {\n\n  AI01320xDecoder(BitArray information) {\n    super(information);\n  }\n\n  @Override\n  protected void addWeightCode(StringBuilder buf, int weight) {\n    if (weight < 10000) {\n      buf.append(\"(3202)\");\n    } else {\n      buf.append(\"(3203)\");\n    }\n  }\n\n  @Override\n  protected int checkWeight(int weight) {\n    if(weight < 10000) {\n      return weight;\n    }\n    return weight - 10000;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/rss/expanded/decoders/AI01392xDecoder.java",
    "content": "/*\n * Copyright (C) 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * These authors would like to acknowledge the Spanish Ministry of Industry,\n * Tourism and Trade, for the support in the project TSI020301-2008-2\n * \"PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled\n * Mobile Dynamic Environments\", led by Treelogic\n * ( http://www.treelogic.com/ ):\n *\n *   http://www.piramidepse.com/\n */\n\npackage com.google.zxing.oned.rss.expanded.decoders;\n\nimport com.google.zxing.NotFoundException;\nimport com.google.zxing.common.BitArray;\n\n/**\n * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)\n */\nfinal class AI01392xDecoder extends AI01decoder {\n\n  private static final int HEADER_SIZE = 5 + 1 + 2;\n  private static final int LAST_DIGIT_SIZE = 2;\n\n  AI01392xDecoder(BitArray information) {\n    super(information);\n  }\n\n  @Override\n  public String parseInformation() throws NotFoundException {\n    if (this.getInformation().getSize() < HEADER_SIZE + GTIN_SIZE) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n\n    StringBuilder buf = new StringBuilder();\n\n    encodeCompressedGtin(buf, HEADER_SIZE);\n\n    int lastAIdigit =\n        this.getGeneralDecoder().extractNumericValueFromBitArray(HEADER_SIZE + GTIN_SIZE, LAST_DIGIT_SIZE);\n    buf.append(\"(392\");\n    buf.append(lastAIdigit);\n    buf.append(')');\n\n    DecodedInformation decodedInformation =\n        this.getGeneralDecoder().decodeGeneralPurposeField(HEADER_SIZE + GTIN_SIZE + LAST_DIGIT_SIZE, null);\n    buf.append(decodedInformation.getNewString());\n\n    return buf.toString();\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/rss/expanded/decoders/AI01393xDecoder.java",
    "content": "/*\n * Copyright (C) 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * These authors would like to acknowledge the Spanish Ministry of Industry,\n * Tourism and Trade, for the support in the project TSI020301-2008-2\n * \"PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled\n * Mobile Dynamic Environments\", led by Treelogic\n * ( http://www.treelogic.com/ ):\n *\n *   http://www.piramidepse.com/\n */\npackage com.google.zxing.oned.rss.expanded.decoders;\n\nimport com.google.zxing.NotFoundException;\nimport com.google.zxing.common.BitArray;\n\n/**\n * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)\n */\nfinal class AI01393xDecoder extends AI01decoder {\n\n  private static final int HEADER_SIZE = 5 + 1 + 2;\n  private static final int LAST_DIGIT_SIZE = 2;\n  private static final int FIRST_THREE_DIGITS_SIZE = 10;\n\n  AI01393xDecoder(BitArray information) {\n    super(information);\n  }\n\n  @Override\n  public String parseInformation() throws NotFoundException {\n    if(this.getInformation().getSize() < HEADER_SIZE + GTIN_SIZE) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n\n    StringBuilder buf = new StringBuilder();\n\n    encodeCompressedGtin(buf, HEADER_SIZE);\n\n    int lastAIdigit =\n        this.getGeneralDecoder().extractNumericValueFromBitArray(HEADER_SIZE + GTIN_SIZE, LAST_DIGIT_SIZE);\n\n    buf.append(\"(393\");\n    buf.append(lastAIdigit);\n    buf.append(')');\n\n    int firstThreeDigits =\n        this.getGeneralDecoder().extractNumericValueFromBitArray(HEADER_SIZE + GTIN_SIZE + LAST_DIGIT_SIZE, FIRST_THREE_DIGITS_SIZE);\n    if(firstThreeDigits / 100 == 0) {\n      buf.append('0');\n    }\n    if(firstThreeDigits / 10 == 0) {\n      buf.append('0');\n    }\n    buf.append(firstThreeDigits);\n\n    DecodedInformation generalInformation =\n        this.getGeneralDecoder().decodeGeneralPurposeField(HEADER_SIZE + GTIN_SIZE + LAST_DIGIT_SIZE + FIRST_THREE_DIGITS_SIZE, null);\n    buf.append(generalInformation.getNewString());\n\n    return buf.toString();\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/rss/expanded/decoders/AI013x0x1xDecoder.java",
    "content": "/*\n * Copyright (C) 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * These authors would like to acknowledge the Spanish Ministry of Industry,\n * Tourism and Trade, for the support in the project TSI020301-2008-2\n * \"PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled\n * Mobile Dynamic Environments\", led by Treelogic\n * ( http://www.treelogic.com/ ):\n *\n *   http://www.piramidepse.com/\n */\n\npackage com.google.zxing.oned.rss.expanded.decoders;\n\nimport com.google.zxing.NotFoundException;\nimport com.google.zxing.common.BitArray;\n\n/**\n * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)\n * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)\n */\nfinal class AI013x0x1xDecoder extends AI01weightDecoder {\n\n  private static final int HEADER_SIZE = 7 + 1;\n  private static final int WEIGHT_SIZE = 20;\n  private static final int DATE_SIZE = 16;\n\n  private final String dateCode;\n  private final String firstAIdigits;\n\n  AI013x0x1xDecoder(BitArray information, String firstAIdigits, String dateCode) {\n    super(information);\n    this.dateCode = dateCode;\n    this.firstAIdigits = firstAIdigits;\n  }\n\n  @Override\n  public String parseInformation() throws NotFoundException {\n    if (this.getInformation().getSize() != HEADER_SIZE + GTIN_SIZE + WEIGHT_SIZE + DATE_SIZE) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n\n    StringBuilder buf = new StringBuilder();\n\n    encodeCompressedGtin(buf, HEADER_SIZE);\n    encodeCompressedWeight(buf, HEADER_SIZE + GTIN_SIZE, WEIGHT_SIZE);\n    encodeCompressedDate(buf, HEADER_SIZE + GTIN_SIZE + WEIGHT_SIZE);\n\n    return buf.toString();\n  }\n\n  private void encodeCompressedDate(StringBuilder buf, int currentPos) {\n    int numericDate = this.getGeneralDecoder().extractNumericValueFromBitArray(currentPos, DATE_SIZE);\n    if(numericDate == 38400) {\n      return;\n    }\n\n    buf.append('(');\n    buf.append(this.dateCode);\n    buf.append(')');\n\n    int day   = numericDate % 32;\n    numericDate /= 32;\n    int month = numericDate % 12 + 1;\n    numericDate /= 12;\n    int year  = numericDate;\n\n    if (year / 10 == 0) {\n      buf.append('0');\n    }\n    buf.append(year);\n    if (month / 10 == 0) {\n      buf.append('0');\n    }\n    buf.append(month);\n    if (day / 10 == 0) {\n      buf.append('0');\n    }\n    buf.append(day);\n  }\n\n  @Override\n  protected void addWeightCode(StringBuilder buf, int weight) {\n    int lastAI = weight / 100000;\n    buf.append('(');\n    buf.append(this.firstAIdigits);\n    buf.append(lastAI);\n    buf.append(')');\n  }\n\n  @Override\n  protected int checkWeight(int weight) {\n    return weight % 100000;\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/rss/expanded/decoders/AI013x0xDecoder.java",
    "content": "/*\n * Copyright (C) 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * These authors would like to acknowledge the Spanish Ministry of Industry,\n * Tourism and Trade, for the support in the project TSI020301-2008-2\n * \"PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled\n * Mobile Dynamic Environments\", led by Treelogic\n * ( http://www.treelogic.com/ ):\n *\n *   http://www.piramidepse.com/\n */\n\npackage com.google.zxing.oned.rss.expanded.decoders;\n\nimport com.google.zxing.NotFoundException;\nimport com.google.zxing.common.BitArray;\n\n/**\n * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)\n */\nabstract class AI013x0xDecoder extends AI01weightDecoder {\n\n  private static final int HEADER_SIZE = 4 + 1;\n  private static final int WEIGHT_SIZE = 15;\n\n  AI013x0xDecoder(BitArray information) {\n    super(information);\n  }\n\n  @Override\n  public String parseInformation() throws NotFoundException {\n    if (this.getInformation().getSize() != HEADER_SIZE + GTIN_SIZE + WEIGHT_SIZE) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n\n    StringBuilder buf = new StringBuilder();\n\n    encodeCompressedGtin(buf, HEADER_SIZE);\n    encodeCompressedWeight(buf, HEADER_SIZE + GTIN_SIZE, WEIGHT_SIZE);\n\n    return buf.toString();\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/rss/expanded/decoders/AI01AndOtherAIs.java",
    "content": "/*\n * Copyright (C) 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * These authors would like to acknowledge the Spanish Ministry of Industry,\n * Tourism and Trade, for the support in the project TSI020301-2008-2\n * \"PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled\n * Mobile Dynamic Environments\", led by Treelogic\n * ( http://www.treelogic.com/ ):\n *\n *   http://www.piramidepse.com/\n */\n\npackage com.google.zxing.oned.rss.expanded.decoders;\n\nimport com.google.zxing.NotFoundException;\nimport com.google.zxing.common.BitArray;\n\n/**\n * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)\n * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)\n */\nfinal class AI01AndOtherAIs extends AI01decoder {\n\n  private static final int HEADER_SIZE = 1 + 1 + 2; //first bit encodes the linkage flag,\n                          //the second one is the encodation method, and the other two are for the variable length\n  AI01AndOtherAIs(BitArray information) {\n    super(information);\n  }\n\n  @Override\n  public String parseInformation() throws NotFoundException {\n    StringBuilder buff = new StringBuilder();\n\n    buff.append(\"(01)\");\n    int initialGtinPosition = buff.length();\n    int firstGtinDigit = this.getGeneralDecoder().extractNumericValueFromBitArray(HEADER_SIZE, 4);\n    buff.append(firstGtinDigit);\n\n    this.encodeCompressedGtinWithoutAI(buff, HEADER_SIZE + 4, initialGtinPosition);\n\n    return this.getGeneralDecoder().decodeAllCodes(buff, HEADER_SIZE + 44);\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/rss/expanded/decoders/AI01decoder.java",
    "content": "/*\n * Copyright (C) 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * These authors would like to acknowledge the Spanish Ministry of Industry,\n * Tourism and Trade, for the support in the project TSI020301-2008-2\n * \"PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled\n * Mobile Dynamic Environments\", led by Treelogic\n * ( http://www.treelogic.com/ ):\n *\n *   http://www.piramidepse.com/\n */\n\npackage com.google.zxing.oned.rss.expanded.decoders;\n\nimport com.google.zxing.common.BitArray;\n\n/**\n * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)\n * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)\n */\nabstract class AI01decoder extends AbstractExpandedDecoder {\n\n  protected static final int GTIN_SIZE = 40;\n\n  AI01decoder(BitArray information) {\n    super(information);\n  }\n\n  protected final void encodeCompressedGtin(StringBuilder buf, int currentPos) {\n    buf.append(\"(01)\");\n    int initialPosition = buf.length();\n    buf.append('9');\n\n    encodeCompressedGtinWithoutAI(buf, currentPos, initialPosition);\n  }\n\n  protected final void encodeCompressedGtinWithoutAI(StringBuilder buf, int currentPos, int initialBufferPosition) {\n    for(int i = 0; i < 4; ++i){\n      int currentBlock = this.getGeneralDecoder().extractNumericValueFromBitArray(currentPos + 10 * i, 10);\n      if (currentBlock / 100 == 0) {\n        buf.append('0');\n      }\n      if (currentBlock / 10 == 0) {\n        buf.append('0');\n      }\n      buf.append(currentBlock);\n    }\n\n      appendCheckDigit(buf, initialBufferPosition);\n  }\n\n  private static void appendCheckDigit(StringBuilder buf, int currentPos){\n    int checkDigit = 0;\n    for (int i = 0; i < 13; i++) {\n      int digit = buf.charAt(i + currentPos) - '0';\n      checkDigit += (i & 0x01) == 0 ? 3 * digit : digit;\n    }\n\n    checkDigit = 10 - (checkDigit % 10);\n    if (checkDigit == 10) {\n      checkDigit = 0;\n    }\n\n    buf.append(checkDigit);\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/rss/expanded/decoders/AI01weightDecoder.java",
    "content": "/*\n * Copyright (C) 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * These authors would like to acknowledge the Spanish Ministry of Industry,\n * Tourism and Trade, for the support in the project TSI020301-2008-2\n * \"PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled\n * Mobile Dynamic Environments\", led by Treelogic\n * ( http://www.treelogic.com/ ):\n *\n *   http://www.piramidepse.com/\n */\n\npackage com.google.zxing.oned.rss.expanded.decoders;\n\nimport com.google.zxing.common.BitArray;\n\n/**\n * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)\n */\nabstract class AI01weightDecoder extends AI01decoder {\n\n  AI01weightDecoder(BitArray information) {\n    super(information);\n  }\n\n  protected final void encodeCompressedWeight(StringBuilder buf, int currentPos, int weightSize) {\n    int originalWeightNumeric = this.getGeneralDecoder().extractNumericValueFromBitArray(currentPos, weightSize);\n    addWeightCode(buf, originalWeightNumeric);\n\n    int weightNumeric = checkWeight(originalWeightNumeric);\n\n    int currentDivisor = 100000;\n    for(int i = 0; i < 5; ++i){\n      if (weightNumeric / currentDivisor == 0) {\n        buf.append('0');\n      }\n      currentDivisor /= 10;\n    }\n    buf.append(weightNumeric);\n  }\n\n  protected abstract void addWeightCode(StringBuilder buf, int weight);\n\n  protected abstract int checkWeight(int weight);\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/rss/expanded/decoders/AbstractExpandedDecoder.java",
    "content": "/*\n * Copyright (C) 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * These authors would like to acknowledge the Spanish Ministry of Industry,\n * Tourism and Trade, for the support in the project TSI020301-2008-2\n * \"PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled\n * Mobile Dynamic Environments\", led by Treelogic\n * ( http://www.treelogic.com/ ):\n *\n *   http://www.piramidepse.com/\n */\n\npackage com.google.zxing.oned.rss.expanded.decoders;\n\nimport com.google.zxing.NotFoundException;\nimport com.google.zxing.common.BitArray;\n\n/**\n * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)\n * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)\n */\npublic abstract class AbstractExpandedDecoder {\n\n  private final BitArray information;\n  private final GeneralAppIdDecoder generalDecoder;\n\n  AbstractExpandedDecoder(BitArray information){\n    this.information = information;\n    this.generalDecoder = new GeneralAppIdDecoder(information);\n  }\n\n  protected final BitArray getInformation() {\n    return information;\n  }\n\n  protected final GeneralAppIdDecoder getGeneralDecoder() {\n    return generalDecoder;\n  }\n\n  public abstract String parseInformation() throws NotFoundException;\n\n  public static AbstractExpandedDecoder createDecoder(BitArray information){\n    if (information.get(1)) {\n      return new AI01AndOtherAIs(information);\n    }\n    if (!information.get(2)) {\n      return new AnyAIDecoder(information);\n    }\n\n    int fourBitEncodationMethod = GeneralAppIdDecoder.extractNumericValueFromBitArray(information, 1, 4);\n\n    switch(fourBitEncodationMethod){\n      case 4: return new AI013103decoder(information);\n      case 5: return new AI01320xDecoder(information);\n    }\n\n    int fiveBitEncodationMethod = GeneralAppIdDecoder.extractNumericValueFromBitArray(information, 1, 5);\n    switch(fiveBitEncodationMethod){\n      case 12: return new AI01392xDecoder(information);\n      case 13: return new AI01393xDecoder(information);\n    }\n\n    int sevenBitEncodationMethod = GeneralAppIdDecoder.extractNumericValueFromBitArray(information, 1, 7);\n    switch(sevenBitEncodationMethod){\n      case 56: return new AI013x0x1xDecoder(information, \"310\", \"11\");\n      case 57: return new AI013x0x1xDecoder(information, \"320\", \"11\");\n      case 58: return new AI013x0x1xDecoder(information, \"310\", \"13\");\n      case 59: return new AI013x0x1xDecoder(information, \"320\", \"13\");\n      case 60: return new AI013x0x1xDecoder(information, \"310\", \"15\");\n      case 61: return new AI013x0x1xDecoder(information, \"320\", \"15\");\n      case 62: return new AI013x0x1xDecoder(information, \"310\", \"17\");\n      case 63: return new AI013x0x1xDecoder(information, \"320\", \"17\");\n    }\n\n    throw new IllegalStateException(\"unknown decoder: \" + information);\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/rss/expanded/decoders/AnyAIDecoder.java",
    "content": "/*\n * Copyright (C) 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * These authors would like to acknowledge the Spanish Ministry of Industry,\n * Tourism and Trade, for the support in the project TSI020301-2008-2\n * \"PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled\n * Mobile Dynamic Environments\", led by Treelogic\n * ( http://www.treelogic.com/ ):\n *\n *   http://www.piramidepse.com/\n */\n\npackage com.google.zxing.oned.rss.expanded.decoders;\n\nimport com.google.zxing.NotFoundException;\nimport com.google.zxing.common.BitArray;\n\n/**\n * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)\n * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)\n */\nfinal class AnyAIDecoder extends AbstractExpandedDecoder {\n\n  private static final int HEADER_SIZE = 2 + 1 + 2;\n\n  AnyAIDecoder(BitArray information) {\n    super(information);\n  }\n\n  @Override\n  public String parseInformation() throws NotFoundException {\n    StringBuilder buf = new StringBuilder();\n    return this.getGeneralDecoder().decodeAllCodes(buf, HEADER_SIZE);\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/rss/expanded/decoders/BlockParsedResult.java",
    "content": "/*\n * Copyright (C) 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * These authors would like to acknowledge the Spanish Ministry of Industry,\n * Tourism and Trade, for the support in the project TSI020301-2008-2\n * \"PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled\n * Mobile Dynamic Environments\", led by Treelogic\n * ( http://www.treelogic.com/ ):\n *\n *   http://www.piramidepse.com/\n */\n\npackage com.google.zxing.oned.rss.expanded.decoders;\n\n/**\n * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)\n * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)\n */\nfinal class BlockParsedResult {\n\n  private final DecodedInformation decodedInformation;\n  private final boolean finished;\n\n  BlockParsedResult(boolean finished) {\n    this(null, finished);\n  }\n\n  BlockParsedResult(DecodedInformation information, boolean finished) {\n    this.finished = finished;\n    this.decodedInformation = information;\n  }\n\n  DecodedInformation getDecodedInformation() {\n    return this.decodedInformation;\n  }\n\n  boolean isFinished() {\n    return this.finished;\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/rss/expanded/decoders/CurrentParsingState.java",
    "content": "/*\n * Copyright (C) 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * These authors would like to acknowledge the Spanish Ministry of Industry,\n * Tourism and Trade, for the support in the project TSI020301-2008-2\n * \"PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled\n * Mobile Dynamic Environments\", led by Treelogic\n * ( http://www.treelogic.com/ ):\n *\n *   http://www.piramidepse.com/\n */\n\npackage com.google.zxing.oned.rss.expanded.decoders;\n\n/**\n * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)\n */\nfinal class CurrentParsingState {\n\n  private int position;\n  private State encoding;\n\n  private enum State {\n    NUMERIC,\n    ALPHA,\n    ISO_IEC_646\n  }\n\n  CurrentParsingState() {\n    this.position = 0;\n    this.encoding = State.NUMERIC;\n  }\n\n  int getPosition() {\n    return position;\n  }\n\n  void setPosition(int position) {\n    this.position = position;\n  }\n\n  void incrementPosition(int delta) {\n    position += delta;\n  }\n\n  boolean isAlpha(){\n    return this.encoding == State.ALPHA;\n  }\n\n  boolean isNumeric(){\n    return this.encoding == State.NUMERIC;\n  }\n\n  boolean isIsoIec646(){\n    return this.encoding == State.ISO_IEC_646;\n  }\n\n  void setNumeric() {\n    this.encoding = State.NUMERIC;\n  }\n\n  void setAlpha() {\n    this.encoding = State.ALPHA;\n  }\n\n  void setIsoIec646() {\n    this.encoding = State.ISO_IEC_646;\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/rss/expanded/decoders/DecodedChar.java",
    "content": "/*\n * Copyright (C) 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * These authors would like to acknowledge the Spanish Ministry of Industry,\n * Tourism and Trade, for the support in the project TSI020301-2008-2\n * \"PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled\n * Mobile Dynamic Environments\", led by Treelogic\n * ( http://www.treelogic.com/ ):\n *\n *   http://www.piramidepse.com/\n */\n\npackage com.google.zxing.oned.rss.expanded.decoders;\n\n/**\n * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)\n * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)\n */\nfinal class DecodedChar extends DecodedObject {\n\n  private final char value;\n\n  static final char FNC1 = '$'; // It's not in Alphanumeric neither in ISO/IEC 646 charset\n\n  DecodedChar(int newPosition, char value) {\n    super(newPosition);\n    this.value = value;\n  }\n\n  char getValue(){\n    return this.value;\n  }\n\n  boolean isFNC1(){\n    return this.value == FNC1;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/rss/expanded/decoders/DecodedInformation.java",
    "content": "/*\n * Copyright (C) 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * These authors would like to acknowledge the Spanish Ministry of Industry,\n * Tourism and Trade, for the support in the project TSI020301-2008-2\n * \"PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled\n * Mobile Dynamic Environments\", led by Treelogic\n * ( http://www.treelogic.com/ ):\n *\n *   http://www.piramidepse.com/\n */\n\npackage com.google.zxing.oned.rss.expanded.decoders;\n\n/**\n * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)\n * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)\n */\nfinal class DecodedInformation extends DecodedObject {\n\n  private final String newString;\n  private final int remainingValue;\n  private final boolean remaining;\n\n  DecodedInformation(int newPosition, String newString){\n    super(newPosition);\n    this.newString = newString;\n    this.remaining = false;\n    this.remainingValue = 0;\n  }\n\n  DecodedInformation(int newPosition, String newString, int remainingValue){\n    super(newPosition);\n    this.remaining = true;\n    this.remainingValue = remainingValue;\n    this.newString = newString;\n  }\n\n  String getNewString(){\n    return this.newString;\n  }\n\n  boolean isRemaining(){\n    return this.remaining;\n  }\n\n  int getRemainingValue(){\n    return this.remainingValue;\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/rss/expanded/decoders/DecodedNumeric.java",
    "content": "/*\n * Copyright (C) 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * These authors would like to acknowledge the Spanish Ministry of Industry,\n * Tourism and Trade, for the support in the project TSI020301-2008-2\n * \"PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled\n * Mobile Dynamic Environments\", led by Treelogic\n * ( http://www.treelogic.com/ ):\n *\n *   http://www.piramidepse.com/\n */\n\npackage com.google.zxing.oned.rss.expanded.decoders;\n\n/**\n * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)\n * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)\n */\nfinal class DecodedNumeric extends DecodedObject {\n\n  private final int firstDigit;\n  private final int secondDigit;\n\n  static final int FNC1 = 10;\n\n  DecodedNumeric(int newPosition, int firstDigit, int secondDigit){\n    super(newPosition);\n\n    this.firstDigit  = firstDigit;\n    this.secondDigit = secondDigit;\n\n    if (this.firstDigit < 0 || this.firstDigit > 10) {\n      throw new IllegalArgumentException(\"Invalid firstDigit: \" + firstDigit);\n    }\n\n    if (this.secondDigit < 0 || this.secondDigit > 10) {\n      throw new IllegalArgumentException(\"Invalid secondDigit: \" + secondDigit);\n    }\n  }\n\n  int getFirstDigit(){\n    return this.firstDigit;\n  }\n\n  int getSecondDigit(){\n    return this.secondDigit;\n  }\n\n  int getValue(){\n    return this.firstDigit * 10 + this.secondDigit;\n  }\n\n  boolean isFirstDigitFNC1(){\n    return this.firstDigit == FNC1;\n  }\n\n  boolean isSecondDigitFNC1(){\n    return this.secondDigit == FNC1;\n  }\n\n  boolean isAnyFNC1(){\n    return this.firstDigit == FNC1 || this.secondDigit == FNC1;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/rss/expanded/decoders/DecodedObject.java",
    "content": "/*\n * Copyright (C) 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * These authors would like to acknowledge the Spanish Ministry of Industry,\n * Tourism and Trade, for the support in the project TSI020301-2008-2\n * \"PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled\n * Mobile Dynamic Environments\", led by Treelogic\n * ( http://www.treelogic.com/ ):\n *\n *   http://www.piramidepse.com/\n */\n\npackage com.google.zxing.oned.rss.expanded.decoders;\n\n/**\n * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)\n */\nabstract class DecodedObject {\n\n  private final int newPosition;\n\n  DecodedObject(int newPosition){\n    this.newPosition = newPosition;\n  }\n\n  final int getNewPosition() {\n    return this.newPosition;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/rss/expanded/decoders/FieldParser.java",
    "content": "/*\n * Copyright (C) 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * These authors would like to acknowledge the Spanish Ministry of Industry,\n * Tourism and Trade, for the support in the project TSI020301-2008-2\n * \"PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled\n * Mobile Dynamic Environments\", led by Treelogic\n * ( http://www.treelogic.com/ ):\n *\n *   http://www.piramidepse.com/\n */\n\npackage com.google.zxing.oned.rss.expanded.decoders;\n\nimport com.google.zxing.NotFoundException;\n\n/**\n * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)\n * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)\n */\nfinal class FieldParser {\n\n  private static final Object VARIABLE_LENGTH = new Object();\n\n  private static final Object [][] TWO_DIGIT_DATA_LENGTH = {\n    // \"DIGITS\", new Integer(LENGTH)\n    //    or\n    // \"DIGITS\", VARIABLE_LENGTH, new Integer(MAX_SIZE)\n\n    { \"00\", 18},\n    { \"01\", 14},\n    { \"02\", 14},\n\n    { \"10\", VARIABLE_LENGTH, 20},\n    { \"11\", 6},\n    { \"12\", 6},\n    { \"13\", 6},\n    { \"15\", 6},\n    { \"17\", 6},\n\n    { \"20\", 2},\n    { \"21\", VARIABLE_LENGTH, 20},\n    { \"22\", VARIABLE_LENGTH, 29},\n\n    { \"30\", VARIABLE_LENGTH, 8},\n    { \"37\", VARIABLE_LENGTH, 8},\n\n    //internal company codes\n    { \"90\", VARIABLE_LENGTH, 30},\n    { \"91\", VARIABLE_LENGTH, 30},\n    { \"92\", VARIABLE_LENGTH, 30},\n    { \"93\", VARIABLE_LENGTH, 30},\n    { \"94\", VARIABLE_LENGTH, 30},\n    { \"95\", VARIABLE_LENGTH, 30},\n    { \"96\", VARIABLE_LENGTH, 30},\n    { \"97\", VARIABLE_LENGTH, 30},\n    { \"98\", VARIABLE_LENGTH, 30},\n    { \"99\", VARIABLE_LENGTH, 30},\n  };\n\n  private static final Object [][] THREE_DIGIT_DATA_LENGTH = {\n    // Same format as above\n\n    { \"240\", VARIABLE_LENGTH, 30},\n    { \"241\", VARIABLE_LENGTH, 30},\n    { \"242\", VARIABLE_LENGTH, 6},\n    { \"250\", VARIABLE_LENGTH, 30},\n    { \"251\", VARIABLE_LENGTH, 30},\n    { \"253\", VARIABLE_LENGTH, 17},\n    { \"254\", VARIABLE_LENGTH, 20},\n\n    { \"400\", VARIABLE_LENGTH, 30},\n    { \"401\", VARIABLE_LENGTH, 30},\n    { \"402\", 17},\n    { \"403\", VARIABLE_LENGTH, 30},\n    { \"410\", 13},\n    { \"411\", 13},\n    { \"412\", 13},\n    { \"413\", 13},\n    { \"414\", 13},\n    { \"420\", VARIABLE_LENGTH, 20},\n    { \"421\", VARIABLE_LENGTH, 15},\n    { \"422\", 3},\n    { \"423\", VARIABLE_LENGTH, 15},\n    { \"424\", 3},\n    { \"425\", 3},\n    { \"426\", 3},\n  };\n\n  private static final Object [][] THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH = {\n    // Same format as above\n\n    { \"310\", 6},\n    { \"311\", 6},\n    { \"312\", 6},\n    { \"313\", 6},\n    { \"314\", 6},\n    { \"315\", 6},\n    { \"316\", 6},\n    { \"320\", 6},\n    { \"321\", 6},\n    { \"322\", 6},\n    { \"323\", 6},\n    { \"324\", 6},\n    { \"325\", 6},\n    { \"326\", 6},\n    { \"327\", 6},\n    { \"328\", 6},\n    { \"329\", 6},\n    { \"330\", 6},\n    { \"331\", 6},\n    { \"332\", 6},\n    { \"333\", 6},\n    { \"334\", 6},\n    { \"335\", 6},\n    { \"336\", 6},\n    { \"340\", 6},\n    { \"341\", 6},\n    { \"342\", 6},\n    { \"343\", 6},\n    { \"344\", 6},\n    { \"345\", 6},\n    { \"346\", 6},\n    { \"347\", 6},\n    { \"348\", 6},\n    { \"349\", 6},\n    { \"350\", 6},\n    { \"351\", 6},\n    { \"352\", 6},\n    { \"353\", 6},\n    { \"354\", 6},\n    { \"355\", 6},\n    { \"356\", 6},\n    { \"357\", 6},\n    { \"360\", 6},\n    { \"361\", 6},\n    { \"362\", 6},\n    { \"363\", 6},\n    { \"364\", 6},\n    { \"365\", 6},\n    { \"366\", 6},\n    { \"367\", 6},\n    { \"368\", 6},\n    { \"369\", 6},\n    { \"390\", VARIABLE_LENGTH, 15},\n    { \"391\", VARIABLE_LENGTH, 18},\n    { \"392\", VARIABLE_LENGTH, 15},\n    { \"393\", VARIABLE_LENGTH, 18},\n    { \"703\", VARIABLE_LENGTH, 30}\n  };\n\n  private static final Object [][] FOUR_DIGIT_DATA_LENGTH = {\n    // Same format as above\n\n    { \"7001\", 13},\n    { \"7002\", VARIABLE_LENGTH, 30},\n    { \"7003\", 10},\n\n    { \"8001\", 14},\n    { \"8002\", VARIABLE_LENGTH, 20},\n    { \"8003\", VARIABLE_LENGTH, 30},\n    { \"8004\", VARIABLE_LENGTH, 30},\n    { \"8005\", 6},\n    { \"8006\", 18},\n    { \"8007\", VARIABLE_LENGTH, 30},\n    { \"8008\", VARIABLE_LENGTH, 12},\n    { \"8018\", 18},\n    { \"8020\", VARIABLE_LENGTH, 25},\n    { \"8100\", 6},\n    { \"8101\", 10},\n    { \"8102\", 2},\n    { \"8110\", VARIABLE_LENGTH, 30},\n  };\n\n  private FieldParser() {\n  }\n\n  static String parseFieldsInGeneralPurpose(String rawInformation) throws NotFoundException{\n    if(rawInformation.length() == 0) {\n      return null;\n    }\n\n    // Processing 2-digit AIs\n\n    if(rawInformation.length() < 2) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n\n    String firstTwoDigits = rawInformation.substring(0, 2);\n\n    for (Object[] dataLength : TWO_DIGIT_DATA_LENGTH) {\n      if (dataLength[0].equals(firstTwoDigits)) {\n        if (dataLength[1] == VARIABLE_LENGTH) {\n          return processVariableAI(2, (Integer) dataLength[2], rawInformation);\n        }\n        return processFixedAI(2, (Integer) dataLength[1], rawInformation);\n      }\n    }\n\n    if(rawInformation.length() < 3) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n\n    String firstThreeDigits = rawInformation.substring(0, 3);\n\n    for (Object[] dataLength : THREE_DIGIT_DATA_LENGTH) {\n      if (dataLength[0].equals(firstThreeDigits)) {\n        if (dataLength[1] == VARIABLE_LENGTH) {\n          return processVariableAI(3, (Integer) dataLength[2], rawInformation);\n        }\n        return processFixedAI(3, (Integer) dataLength[1], rawInformation);\n      }\n    }\n\n\n    for (Object[] dataLength : THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH) {\n      if (dataLength[0].equals(firstThreeDigits)) {\n        if (dataLength[1] == VARIABLE_LENGTH) {\n          return processVariableAI(4, (Integer) dataLength[2], rawInformation);\n        }\n        return processFixedAI(4, (Integer) dataLength[1], rawInformation);\n      }\n    }\n\n    if(rawInformation.length() < 4) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n\n    String firstFourDigits = rawInformation.substring(0, 4);\n\n    for (Object[] dataLength : FOUR_DIGIT_DATA_LENGTH) {\n      if (dataLength[0].equals(firstFourDigits)) {\n        if (dataLength[1] == VARIABLE_LENGTH) {\n          return processVariableAI(4, (Integer) dataLength[2], rawInformation);\n        }\n        return processFixedAI(4, (Integer) dataLength[1], rawInformation);\n      }\n    }\n\n    throw NotFoundException.getNotFoundInstance();\n  }\n\n  private static String processFixedAI(int aiSize, int fieldSize, String rawInformation) throws NotFoundException{\n    if (rawInformation.length() < aiSize) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n\n    String ai = rawInformation.substring(0, aiSize);\n\n    if(rawInformation.length() < aiSize + fieldSize) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n\n    String field = rawInformation.substring(aiSize, aiSize + fieldSize);\n    String remaining = rawInformation.substring(aiSize + fieldSize);\n    String result = '(' + ai + ')' + field;\n    String parsedAI = parseFieldsInGeneralPurpose(remaining);\n    return parsedAI == null ? result : result + parsedAI;\n  }\n\n  private static String processVariableAI(int aiSize, int variableFieldSize, String rawInformation)\n      throws NotFoundException {\n    String ai = rawInformation.substring(0, aiSize);\n    int maxSize;\n    if (rawInformation.length() < aiSize + variableFieldSize) {\n      maxSize = rawInformation.length();\n    } else {\n      maxSize = aiSize + variableFieldSize;\n    }\n    String field = rawInformation.substring(aiSize, maxSize);\n    String remaining = rawInformation.substring(maxSize);\n    String result = '(' + ai + ')' + field;\n    String parsedAI = parseFieldsInGeneralPurpose(remaining);\n    return parsedAI == null ? result : result + parsedAI;\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/oned/rss/expanded/decoders/GeneralAppIdDecoder.java",
    "content": "/*\n * Copyright (C) 2010 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * These authors would like to acknowledge the Spanish Ministry of Industry,\n * Tourism and Trade, for the support in the project TSI020301-2008-2\n * \"PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled\n * Mobile Dynamic Environments\", led by Treelogic\n * ( http://www.treelogic.com/ ):\n *\n *   http://www.piramidepse.com/\n */\n\npackage com.google.zxing.oned.rss.expanded.decoders;\n\nimport com.google.zxing.NotFoundException;\nimport com.google.zxing.common.BitArray;\n\n/**\n * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)\n * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)\n */\nfinal class GeneralAppIdDecoder {\n\n  private final BitArray information;\n  private final CurrentParsingState current = new CurrentParsingState();\n  private final StringBuilder buffer = new StringBuilder();\n\n  GeneralAppIdDecoder(BitArray information){\n    this.information = information;\n  }\n\n  String decodeAllCodes(StringBuilder buff, int initialPosition) throws NotFoundException {\n    int currentPosition = initialPosition;\n    String remaining = null;\n    do{\n      DecodedInformation info = this.decodeGeneralPurposeField(currentPosition, remaining);\n      String parsedFields = FieldParser.parseFieldsInGeneralPurpose(info.getNewString());\n      if (parsedFields != null) {\n        buff.append(parsedFields);\n      }\n      if(info.isRemaining()) {\n        remaining = String.valueOf(info.getRemainingValue());\n      } else {\n        remaining = null;\n      }\n\n      if(currentPosition == info.getNewPosition()) {// No step forward!\n        break;\n      }\n      currentPosition = info.getNewPosition();\n    }while(true);\n\n    return buff.toString();\n  }\n\n  private boolean isStillNumeric(int pos) {\n    // It's numeric if it still has 7 positions\n    // and one of the first 4 bits is \"1\".\n    if(pos + 7 > this.information.getSize()){\n      return pos + 4 <= this.information.getSize();\n    }\n\n    for (int i = pos; i < pos + 3; ++i) {\n      if (this.information.get(i)) {\n        return true;\n      }\n    }\n\n    return this.information.get(pos + 3);\n  }\n\n  private DecodedNumeric decodeNumeric(int pos) {\n    if(pos + 7 > this.information.getSize()){\n      int numeric = extractNumericValueFromBitArray(pos, 4);\n      if(numeric == 0) {\n        return new DecodedNumeric(this.information.getSize(), DecodedNumeric.FNC1, DecodedNumeric.FNC1);\n      }\n      return new DecodedNumeric(this.information.getSize(), numeric - 1, DecodedNumeric.FNC1);\n    }\n    int numeric = extractNumericValueFromBitArray(pos, 7);\n\n    int digit1  = (numeric - 8) / 11;\n    int digit2  = (numeric - 8) % 11;\n\n    return new DecodedNumeric(pos + 7, digit1, digit2);\n  }\n\n  int extractNumericValueFromBitArray(int pos, int bits){\n    return extractNumericValueFromBitArray(this.information, pos, bits);\n  }\n\n  static int extractNumericValueFromBitArray(BitArray information, int pos, int bits) {\n    if(bits > 32) {\n      throw new IllegalArgumentException(\"extractNumberValueFromBitArray can't handle more than 32 bits\");\n    }\n\n    int value = 0;\n    for (int i = 0; i < bits; ++i) {\n      if (information.get(pos + i)) {\n        value |= 1 << (bits - i - 1);\n      }\n    }\n\n    return value;\n  }\n\n  DecodedInformation decodeGeneralPurposeField(int pos, String remaining) {\n    this.buffer.setLength(0);\n\n    if(remaining != null) {\n      this.buffer.append(remaining);\n    }\n\n    this.current.setPosition(pos);\n\n    DecodedInformation lastDecoded = parseBlocks();\n    if(lastDecoded != null && lastDecoded.isRemaining()) {\n      return new DecodedInformation(this.current.getPosition(), this.buffer.toString(), lastDecoded.getRemainingValue());\n    }\n    return new DecodedInformation(this.current.getPosition(), this.buffer.toString());\n  }\n\n  private DecodedInformation parseBlocks() {\n    boolean isFinished;\n    BlockParsedResult result;\n    do{\n      int initialPosition = current.getPosition();\n\n      if (current.isAlpha()){\n        result = parseAlphaBlock();\n        isFinished = result.isFinished();\n      }else if (current.isIsoIec646()){\n        result = parseIsoIec646Block();\n        isFinished = result.isFinished();\n      }else{ // it must be numeric\n        result = parseNumericBlock();\n        isFinished = result.isFinished();\n      }\n\n      boolean positionChanged = initialPosition != current.getPosition();\n      if(!positionChanged && !isFinished) {\n        break;\n      }\n    } while (!isFinished);\n\n    return result.getDecodedInformation();\n  }\n\n  private BlockParsedResult parseNumericBlock() {\n    while (isStillNumeric(current.getPosition())) {\n      DecodedNumeric numeric = decodeNumeric(current.getPosition());\n      current.setPosition(numeric.getNewPosition());\n\n      if(numeric.isFirstDigitFNC1()){\n        DecodedInformation information;\n        if (numeric.isSecondDigitFNC1()) {\n          information = new DecodedInformation(current.getPosition(), buffer.toString());\n        } else {\n          information = new DecodedInformation(current.getPosition(), buffer.toString(), numeric.getSecondDigit());\n        }\n        return new BlockParsedResult(information, true);\n      }\n      buffer.append(numeric.getFirstDigit());\n\n      if(numeric.isSecondDigitFNC1()){\n        DecodedInformation information = new DecodedInformation(current.getPosition(), buffer.toString());\n        return new BlockParsedResult(information, true);\n      }\n      buffer.append(numeric.getSecondDigit());\n    }\n\n    if (isNumericToAlphaNumericLatch(current.getPosition())) {\n      current.setAlpha();\n      current.incrementPosition(4);\n    }\n    return new BlockParsedResult(false);\n  }\n\n  private BlockParsedResult parseIsoIec646Block() {\n    while (isStillIsoIec646(current.getPosition())) {\n      DecodedChar iso = decodeIsoIec646(current.getPosition());\n      current.setPosition(iso.getNewPosition());\n\n      if (iso.isFNC1()) {\n        DecodedInformation information = new DecodedInformation(current.getPosition(), buffer.toString());\n        return new BlockParsedResult(information, true);\n      }\n      buffer.append(iso.getValue());\n    }\n\n    if (isAlphaOr646ToNumericLatch(current.getPosition())) {\n      current.incrementPosition(3);\n      current.setNumeric();\n    } else if (isAlphaTo646ToAlphaLatch(current.getPosition())) {\n      if (current.getPosition() + 5 < this.information.getSize()) {\n        current.incrementPosition(5);\n      } else {\n        current.setPosition(this.information.getSize());\n      }\n\n      current.setAlpha();\n    }\n    return new BlockParsedResult(false);\n  }\n\n  private BlockParsedResult parseAlphaBlock() {\n    while (isStillAlpha(current.getPosition())) {\n      DecodedChar alpha = decodeAlphanumeric(current.getPosition());\n      current.setPosition(alpha.getNewPosition());\n\n      if(alpha.isFNC1()) {\n        DecodedInformation information = new DecodedInformation(current.getPosition(), buffer.toString());\n        return new BlockParsedResult(information, true); //end of the char block\n      }\n\n      buffer.append(alpha.getValue());\n    }\n\n    if (isAlphaOr646ToNumericLatch(current.getPosition())) {\n      current.incrementPosition(3);\n      current.setNumeric();\n    } else if (isAlphaTo646ToAlphaLatch(current.getPosition())) {\n      if (current.getPosition() + 5 < this.information.getSize()) {\n        current.incrementPosition(5);\n      } else {\n        current.setPosition(this.information.getSize());\n      }\n\n      current.setIsoIec646();\n    }\n    return new BlockParsedResult(false);\n  }\n\n  private boolean isStillIsoIec646(int pos) {\n    if (pos + 5 > this.information.getSize()) {\n      return false;\n    }\n\n    int fiveBitValue = extractNumericValueFromBitArray(pos, 5);\n    if (fiveBitValue >= 5 && fiveBitValue < 16) {\n      return true;\n    }\n\n    if (pos + 7 > this.information.getSize()) {\n      return false;\n    }\n\n    int sevenBitValue = extractNumericValueFromBitArray(pos, 7);\n    if(sevenBitValue >= 64 && sevenBitValue < 116) {\n      return true;\n    }\n\n    if (pos + 8 > this.information.getSize()) {\n      return false;\n    }\n\n    int eightBitValue = extractNumericValueFromBitArray(pos, 8);\n    return eightBitValue >= 232 && eightBitValue < 253;\n\n  }\n\n  private DecodedChar decodeIsoIec646(int pos) {\n    int fiveBitValue = extractNumericValueFromBitArray(pos, 5);\n    if (fiveBitValue == 15) {\n      return new DecodedChar(pos + 5, DecodedChar.FNC1);\n    }\n\n    if (fiveBitValue >= 5 && fiveBitValue < 15) {\n      return new DecodedChar(pos + 5, (char) ('0' + fiveBitValue - 5));\n    }\n\n    int sevenBitValue = extractNumericValueFromBitArray(pos, 7);\n\n    if (sevenBitValue >= 64 && sevenBitValue < 90) {\n      return new DecodedChar(pos + 7, (char) (sevenBitValue + 1));\n    }\n\n    if (sevenBitValue >= 90 && sevenBitValue < 116) {\n      return new DecodedChar(pos + 7, (char) (sevenBitValue + 7));\n    }\n\n    int eightBitValue = extractNumericValueFromBitArray(pos, 8);\n    char c;\n    switch (eightBitValue) {\n      case 232:\n        c = '!';\n        break;\n      case 233:\n        c = '\"';\n        break;\n      case 234:\n        c = '%';\n        break;\n      case 235:\n        c = '&';\n        break;\n      case 236:\n        c = '\\'';\n        break;\n      case 237:\n        c = '(';\n        break;\n      case 238:\n        c = ')';\n        break;\n      case 239:\n        c = '*';\n        break;\n      case 240:\n        c = '+';\n        break;\n      case 241:\n        c = ',';\n        break;\n      case 242:\n        c = '-';\n        break;\n      case 243:\n        c = '.';\n        break;\n      case 244:\n        c = '/';\n        break;\n      case 245:\n        c = ':';\n        break;\n      case 246:\n        c = ';';\n        break;\n      case 247:\n        c = '<';\n        break;\n      case 248:\n        c = '=';\n        break;\n      case 249:\n        c = '>';\n        break;\n      case 250:\n        c = '?';\n        break;\n      case 251:\n        c = '_';\n        break;\n      case 252:\n        c = ' ';\n        break;\n      default:\n        throw new IllegalArgumentException(\"Decoding invalid ISO/IEC 646 value: \" + eightBitValue);\n    }\n    return new DecodedChar(pos + 8, c);\n  }\n\n  private boolean isStillAlpha(int pos) {\n    if(pos + 5 > this.information.getSize()) {\n      return false;\n    }\n\n    // We now check if it's a valid 5-bit value (0..9 and FNC1)\n    int fiveBitValue = extractNumericValueFromBitArray(pos, 5);\n    if (fiveBitValue >= 5 && fiveBitValue < 16) {\n      return true;\n    }\n\n    if (pos + 6 > this.information.getSize()) {\n      return false;\n    }\n\n    int sixBitValue =  extractNumericValueFromBitArray(pos, 6);\n    return sixBitValue >= 16 && sixBitValue < 63; // 63 not included\n  }\n\n  private DecodedChar decodeAlphanumeric(int pos) {\n    int fiveBitValue = extractNumericValueFromBitArray(pos, 5);\n    if (fiveBitValue == 15) {\n      return new DecodedChar(pos + 5, DecodedChar.FNC1);\n    }\n\n    if (fiveBitValue >= 5 && fiveBitValue < 15) {\n      return new DecodedChar(pos + 5, (char) ('0' + fiveBitValue - 5));\n    }\n\n    int sixBitValue =  extractNumericValueFromBitArray(pos, 6);\n\n    if (sixBitValue >= 32 && sixBitValue < 58) {\n      return new DecodedChar(pos + 6, (char) (sixBitValue + 33));\n    }\n\n    char c;\n    switch (sixBitValue){\n      case 58:\n        c = '*';\n        break;\n      case 59:\n        c = ',';\n        break;\n      case 60:\n        c = '-';\n        break;\n      case 61:\n        c = '.';\n        break;\n      case 62:\n        c = '/';\n        break;\n      default:\n        throw new IllegalStateException(\"Decoding invalid alphanumeric value: \" + sixBitValue);\n    }\n    return new DecodedChar(pos + 6, c);\n  }\n\n  private boolean isAlphaTo646ToAlphaLatch(int pos) {\n    if (pos + 1 > this.information.getSize()) {\n      return false;\n    }\n\n    for (int i = 0; i < 5 && i + pos < this.information.getSize(); ++i) {\n      if(i == 2){\n        if (!this.information.get(pos + 2)) {\n          return false;\n        }\n      } else if (this.information.get(pos + i)) {\n        return false;\n      }\n    }\n\n    return true;\n  }\n\n  private boolean isAlphaOr646ToNumericLatch(int pos) {\n    // Next is alphanumeric if there are 3 positions and they are all zeros\n    if (pos + 3 > this.information.getSize()) {\n      return false;\n    }\n\n    for (int i = pos; i < pos + 3; ++i) {\n      if (this.information.get(i)) {\n        return false;\n      }\n    }\n    return true;\n  }\n\n  private boolean isNumericToAlphaNumericLatch(int pos) {\n    // Next is alphanumeric if there are 4 positions and they are all zeros, or\n    // if there is a subset of this just before the end of the symbol\n    if (pos + 1 > this.information.getSize()) {\n      return false;\n    }\n\n    for (int i = 0; i < 4 && i + pos < this.information.getSize(); ++i) {\n      if (this.information.get(pos + i)) {\n        return false;\n      }\n    }\n    return true;\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/pdf417/PDF417Reader.java",
    "content": "/*\r\n * Copyright 2009 ZXing authors\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage com.google.zxing.pdf417;\r\n\r\nimport com.google.zxing.BarcodeFormat;\r\nimport com.google.zxing.BinaryBitmap;\r\nimport com.google.zxing.ChecksumException;\r\nimport com.google.zxing.DecodeHintType;\r\nimport com.google.zxing.FormatException;\r\nimport com.google.zxing.NotFoundException;\r\nimport com.google.zxing.Reader;\r\nimport com.google.zxing.Result;\r\nimport com.google.zxing.ResultPoint;\r\nimport com.google.zxing.common.BitMatrix;\r\nimport com.google.zxing.common.DecoderResult;\r\nimport com.google.zxing.common.DetectorResult;\r\nimport com.google.zxing.pdf417.decoder.Decoder;\r\nimport com.google.zxing.pdf417.detector.Detector;\r\n\r\nimport java.util.Map;\r\n\r\n/**\r\n * This implementation can detect and decode PDF417 codes in an image.\r\n *\r\n * @author SITA Lab (kevin.osullivan@sita.aero)\r\n */\r\npublic final class PDF417Reader implements Reader {\r\n\r\n  private static final ResultPoint[] NO_POINTS = new ResultPoint[0];\r\n\r\n  private final Decoder decoder = new Decoder();\r\n\r\n  /**\r\n   * Locates and decodes a PDF417 code in an image.\r\n   *\r\n   * @return a String representing the content encoded by the PDF417 code\r\n   * @throws NotFoundException if a PDF417 code cannot be found,\r\n   * @throws FormatException if a PDF417 cannot be decoded\r\n   */\r\n  @Override\r\n  public Result decode(BinaryBitmap image) throws NotFoundException, FormatException, ChecksumException {\r\n    return decode(image, null);\r\n  }\r\n\r\n  @Override\r\n  public Result decode(BinaryBitmap image, Map<DecodeHintType,?> hints)\r\n      throws NotFoundException, FormatException, ChecksumException {\r\n    DecoderResult decoderResult;\r\n    ResultPoint[] points;\r\n    if (hints != null && hints.containsKey(DecodeHintType.PURE_BARCODE)) {\r\n      BitMatrix bits = extractPureBits(image.getBlackMatrix());\r\n      decoderResult = decoder.decode(bits);\r\n      points = NO_POINTS;\r\n    } else {\r\n      DetectorResult detectorResult = new Detector(image).detect();\r\n      decoderResult = decoder.decode(detectorResult.getBits());\r\n      points = detectorResult.getPoints();\r\n    }\r\n    return new Result(decoderResult.getText(), decoderResult.getRawBytes(), points,\r\n        BarcodeFormat.PDF_417);\r\n  }\r\n\r\n  @Override\r\n  public void reset() {\r\n    // do nothing\r\n  }\r\n\r\n  /**\r\n   * This method detects a code in a \"pure\" image -- that is, pure monochrome image\r\n   * which contains only an unrotated, unskewed, image of a code, with some white border\r\n   * around it. This is a specialized method that works exceptionally fast in this special\r\n   * case.\r\n   *\r\n   * @see com.google.zxing.qrcode.QRCodeReader#extractPureBits(BitMatrix)\r\n   * @see com.google.zxing.datamatrix.DataMatrixReader#extractPureBits(BitMatrix)\r\n   */\r\n  private static BitMatrix extractPureBits(BitMatrix image) throws NotFoundException {\r\n\r\n    int[] leftTopBlack = image.getTopLeftOnBit();\r\n    int[] rightBottomBlack = image.getBottomRightOnBit();\r\n    if (leftTopBlack == null || rightBottomBlack == null) {\r\n      throw NotFoundException.getNotFoundInstance();\r\n    }\r\n\r\n    int moduleSize = moduleSize(leftTopBlack, image);\r\n\r\n    int top = leftTopBlack[1];\r\n    int bottom = rightBottomBlack[1];\r\n    int left = findPatternStart(leftTopBlack[0], top, image);\r\n    int right = findPatternEnd(leftTopBlack[0], top, image);\r\n\r\n    int matrixWidth = (right - left + 1) / moduleSize;\r\n    int matrixHeight = (bottom - top + 1) / moduleSize;\r\n    if (matrixWidth <= 0 || matrixHeight <= 0) {\r\n      throw NotFoundException.getNotFoundInstance();\r\n    }\r\n\r\n    // Push in the \"border\" by half the module width so that we start\r\n    // sampling in the middle of the module. Just in case the image is a\r\n    // little off, this will help recover.\r\n    int nudge = moduleSize >> 1;\r\n    top += nudge;\r\n    left += nudge;\r\n\r\n    // Now just read off the bits\r\n    BitMatrix bits = new BitMatrix(matrixWidth, matrixHeight);\r\n    for (int y = 0; y < matrixHeight; y++) {\r\n      int iOffset = top + y * moduleSize;\r\n      for (int x = 0; x < matrixWidth; x++) {\r\n        if (image.get(left + x * moduleSize, iOffset)) {\r\n          bits.set(x, y);\r\n        }\r\n      }\r\n    }\r\n    return bits;\r\n  }\r\n\r\n  private static int moduleSize(int[] leftTopBlack, BitMatrix image) throws NotFoundException {\r\n    int x = leftTopBlack[0];\r\n    int y = leftTopBlack[1];\r\n    int width = image.getWidth();\r\n    while (x < width && image.get(x, y)) {\r\n      x++;\r\n    }\r\n    if (x == width) {\r\n      throw NotFoundException.getNotFoundInstance();\r\n    }\r\n\r\n    int moduleSize = (x - leftTopBlack[0]) >>> 3; // We've crossed left first bar, which is 8x\r\n    if (moduleSize == 0) {\r\n      throw NotFoundException.getNotFoundInstance();\r\n    }\r\n\r\n    return moduleSize;\r\n  }\r\n\r\n  private static int findPatternStart(int x, int y, BitMatrix image) throws NotFoundException {\r\n    int width = image.getWidth();\r\n    int start = x;\r\n    // start should be on black\r\n    int transitions = 0;\r\n    boolean black = true;\r\n    while (start < width - 1 && transitions < 8) {\r\n      start++;\r\n      boolean newBlack = image.get(start, y);\r\n      if (black != newBlack) {\r\n        transitions++;\r\n      }\r\n      black = newBlack;\r\n    }\r\n    if (start == width - 1) {\r\n      throw NotFoundException.getNotFoundInstance();\r\n    }\r\n    return start;\r\n  }\r\n\r\n  private static int findPatternEnd(int x, int y, BitMatrix image) throws NotFoundException {\r\n    int width = image.getWidth();\r\n    int end = width - 1;\r\n    // end should be on black\r\n    while (end > x && !image.get(end, y)) {\r\n      end--;\r\n    }\r\n    int transitions = 0;\r\n    boolean black = true;\r\n    while (end > x && transitions < 9) {\r\n      end--;\r\n      boolean newBlack = image.get(end, y);\r\n      if (black != newBlack) {\r\n        transitions++;\r\n      }\r\n      black = newBlack;\r\n    }\r\n    if (end == x) {\r\n      throw NotFoundException.getNotFoundInstance();\r\n    }\r\n    return end;\r\n  }\r\n\r\n}\r\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/pdf417/decoder/BitMatrixParser.java",
    "content": "/*\r\n * Copyright 2009 ZXing authors\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage com.google.zxing.pdf417.decoder;\r\n\r\nimport com.google.zxing.FormatException;\r\nimport com.google.zxing.common.BitMatrix;\r\n\r\n/**\r\n * <p>\r\n * This class parses the BitMatrix image into codewords.\r\n * </p>\r\n *\r\n * @author SITA Lab (kevin.osullivan@sita.aero)\r\n */\r\nfinal class BitMatrixParser {\r\n\r\n  private static final int[] NO_ERRORS = new int[0];\r\n\r\n  private static final int MAX_ROW_DIFFERENCE = 6;\r\n  private static final int MAX_ROWS = 90;\r\n  //private static final int MAX_COLUMNS = 30;\r\n  // Maximum Codewords (Data + Error)\r\n  private static final int MAX_CW_CAPACITY = 929;\r\n  private static final int MODULES_IN_SYMBOL = 17;\r\n\r\n  private final BitMatrix bitMatrix;\r\n  private int rows = 0;\r\n  //private int columns = 0;\r\n\r\n  private int leftColumnECData = 0;\r\n  private int rightColumnECData = 0;\r\n  private int eraseCount = 0;\r\n  private int[] erasures;\r\n  private int ecLevel = -1;\r\n\r\n  BitMatrixParser(BitMatrix bitMatrix) {\r\n    this.bitMatrix = bitMatrix;\r\n  }\r\n\r\n  /**\r\n   * To ensure separability of rows, codewords of consecutive rows belong to\r\n   * different subsets of all possible codewords. This routine scans the\r\n   * symbols in the barcode. When it finds a number of consecutive rows which\r\n   * are the same, it assumes that this is a row of codewords and processes\r\n   * them into a codeword array.\r\n   *\r\n   * @return an array of codewords.\r\n   */\r\n  int[] readCodewords() throws FormatException {\r\n    int width = bitMatrix.getWidth();\r\n    int height = bitMatrix.getHeight();\r\n\r\n    erasures = new int[MAX_CW_CAPACITY];\r\n\r\n    // Get the number of pixels in a module across the X dimension\r\n    //float moduleWidth = bitMatrix.getModuleWidth();\r\n    float moduleWidth = 1.0f; // Image has been sampled and reduced\r\n\r\n    int[] rowCounters = new int[width];\r\n    int[] codewords = new int[MAX_CW_CAPACITY];\r\n    int next = 0;\r\n    int matchingConsecutiveScans = 0;\r\n    boolean rowInProgress = false;\r\n    int rowNumber = 0;\r\n    int rowHeight = 0;\r\n    for (int i = 1; i < height; i++) {\r\n      if (rowNumber >= MAX_ROWS) {\r\n        // Something is wrong, since we have exceeded\r\n        // the maximum rows in the specification.\r\n        throw FormatException.getFormatInstance();\r\n      }\r\n      int rowDifference = 0;\r\n      // Scan a line of modules and check the\r\n      // difference between this and the previous line\r\n      for (int j = 0; j < width; j++) {\r\n        // Accumulate differences between this line and the\r\n        // previous line.\r\n        if (bitMatrix.get(j, i) != bitMatrix.get(j, i - 1)) {\r\n          rowDifference++;\r\n        }\r\n      }\r\n      if (rowDifference <= moduleWidth * MAX_ROW_DIFFERENCE) {\r\n        for (int j = 0; j < width; j++) {\r\n          // Accumulate the black pixels on this line\r\n          if (bitMatrix.get(j, i)) {\r\n            rowCounters[j]++;\r\n          }\r\n        }\r\n        // Increment the number of consecutive rows of pixels\r\n        // that are more or less the same\r\n        matchingConsecutiveScans++;\r\n        // Height of a row is a multiple of the module size in pixels\r\n        // It's supposed to be >= 3x module width, but, accept anything >= 2x\r\n        if ((matchingConsecutiveScans + 1) >= 2.0f * moduleWidth) {\r\n          // We have some previous matches as well as a match here\r\n          // Set processing a unique row.\r\n          rowInProgress = true;\r\n        }\r\n      } else {\r\n        if (rowInProgress) {\r\n          // Process Row\r\n          next = processRow(rowCounters, rowNumber, rowHeight, codewords, next);\r\n          if (next == -1) {\r\n            // Something is wrong, since we have exceeded\r\n            // the maximum columns in the specification.\r\n            throw FormatException.getFormatInstance();\r\n          }\r\n          // Reinitialize the row counters.\r\n          for (int j = 0; j < rowCounters.length; j++) {\r\n            rowCounters[j] = 0;\r\n          }\r\n          rowNumber++;\r\n          rowHeight = 0;\r\n        }\r\n        matchingConsecutiveScans = 0;\r\n        rowInProgress = false;\r\n      }\r\n      rowHeight++;\r\n    }\r\n    // Check for a row that was in progress before we exited above.\r\n    if (rowInProgress) {\r\n      // Process Row\r\n      if (rowNumber >= MAX_ROWS) {\r\n        // Something is wrong, since we have exceeded\r\n        // the maximum rows in the specification.\r\n        throw FormatException.getFormatInstance();\r\n      }\r\n      next = processRow(rowCounters, rowNumber, rowHeight, codewords, next);\r\n      rowNumber++;\r\n      rows = rowNumber;\r\n    }\r\n    erasures = trimArray(erasures, eraseCount);\r\n    return trimArray(codewords, next);\r\n  }\r\n\r\n  /**\r\n   * Trim the array to the required size.\r\n   *\r\n   * @param array the array\r\n   * @param size  the size to trim it to\r\n   * @return the new trimmed array\r\n   */\r\n  private static int[] trimArray(int[] array, int size) {\r\n    if (size < 0) {\r\n      throw new IllegalArgumentException();\r\n    }\r\n    if (size == 0) {\r\n      return NO_ERRORS;\r\n    }\r\n    int[] a = new int[size];\r\n    System.arraycopy(array, 0, a, 0, size);\r\n    return a;\r\n  }\r\n\r\n  /**\r\n   * Convert the symbols in the row to codewords.\r\n   * Each PDF417 symbol character consists of four bar elements and four space\r\n   * elements, each of which can be one to six modules wide. The four bar and\r\n   * four space elements shall measure 17 modules in total.\r\n   *\r\n   * @param rowCounters an array containing the counts of black pixels for each column\r\n   *                    in the row.\r\n   * @param rowNumber   the current row number of codewords.\r\n   * @param rowHeight   the height of this row in pixels.\r\n   * @param codewords   the codeword array to save codewords into.\r\n   * @param next        the next available index into the codewords array.\r\n   * @return the next available index into the codeword array after processing\r\n   *         this row.\r\n   */\r\n  int processRow(int[] rowCounters, int rowNumber, int rowHeight, int[] codewords, int next)\r\n      throws FormatException {\r\n    int width = bitMatrix.getWidth();\r\n    int columnNumber = 0;\r\n    long symbol = 0;\r\n    for (int i = 0; i < width; i += MODULES_IN_SYMBOL) {\r\n      // This happens in real life and is almost surely a rare misdecode\r\n      if (i + MODULES_IN_SYMBOL > rowCounters.length) {\r\n        throw FormatException.getFormatInstance();\r\n      }\r\n      for (int mask = MODULES_IN_SYMBOL - 1; mask >= 0; mask--) {\r\n        if (rowCounters[i + (MODULES_IN_SYMBOL - 1 - mask)] >= rowHeight >>> 1) {\r\n          symbol |= 1L << mask;\r\n        }\r\n      }\r\n      if (columnNumber > 0) {\r\n        int cw = getCodeword(symbol);\r\n        if (cw < 0 && i < width - MODULES_IN_SYMBOL) {\r\n          // Skip errors on the Right row indicator column\r\n          if (eraseCount >= erasures.length) {\r\n            throw FormatException.getFormatInstance();\r\n          }\r\n          erasures[eraseCount] = next;\r\n          next++;\r\n          eraseCount++;\r\n        } else {\r\n          codewords[next++] = cw;\r\n        }\r\n      } else {\r\n        // Left row indicator column\r\n        int cw = getCodeword(symbol);\r\n        if (ecLevel < 0) {\r\n          if (rowNumber % 3 == 1) {\r\n            leftColumnECData = cw;\r\n          }\r\n        }\r\n      }\r\n      symbol = 0;\r\n      //columns = columnNumber;\r\n      columnNumber++;\r\n    }\r\n    if (columnNumber > 1) {\r\n      // Right row indicator column is in codeword[next]\r\n      //columns--;\r\n      // Overwrite the last codeword i.e. Right Row Indicator\r\n      --next;\r\n      if (ecLevel < 0) {\r\n        if (rowNumber % 3 == 2) {\r\n          rightColumnECData = codewords[next];\r\n          if (rightColumnECData == leftColumnECData && leftColumnECData != 0) {\r\n            ecLevel = ((rightColumnECData % 30) - rows % 3) / 3;\r\n          }\r\n        }\r\n      }\r\n      codewords[next] = 0;\r\n    }\r\n    return next;\r\n  }\r\n\r\n  /**\r\n   * Translate the symbol into a codeword.\r\n   *\r\n   * @param symbol\r\n   * @return the codeword corresponding to the symbol.\r\n   */\r\n  private static int getCodeword(long symbol) {\r\n    long sym = symbol & 0x3FFFF;\r\n    int i = findCodewordIndex(sym);\r\n    if (i == -1) {\r\n      return -1;\r\n    } else {\r\n      long cw = CODEWORD_TABLE[i] - 1;\r\n      cw %= 929;\r\n      return (int) cw;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Use a binary search to find the index of the codeword corresponding to\r\n   * this symbol.\r\n   *\r\n   * @param symbol the symbol from the barcode.\r\n   * @return the index into the codeword table.\r\n   */\r\n  private static int findCodewordIndex(long symbol) {\r\n    int first = 0;\r\n    int upto = SYMBOL_TABLE.length;\r\n    while (first < upto) {\r\n      int mid = (first + upto) >>> 1; // Compute mid point.\r\n      if (symbol < SYMBOL_TABLE[mid]) {\r\n        upto = mid; // repeat search in bottom half.\r\n      } else if (symbol > SYMBOL_TABLE[mid]) {\r\n        first = mid + 1; // Repeat search in top half.\r\n      } else {\r\n        return mid; // Found it. return position\r\n      }\r\n    }\r\n    return -1;\r\n  }\r\n\r\n  /**\r\n   * Returns an array of locations representing the erasures.\r\n   */\r\n  public int[] getErasures() {\r\n    return erasures;\r\n  }\r\n\r\n  public int getECLevel() {\r\n    return ecLevel;\r\n  }\r\n\r\n  /**\r\n   * The sorted table of all possible symbols. Extracted from the PDF417\r\n   * specification. The index of a symbol in this table corresponds to the\r\n   * index into the codeword table.\r\n   */\r\n  private static final int[] SYMBOL_TABLE = {0x1025e, 0x1027a, 0x1029e,\r\n      0x102bc, 0x102f2, 0x102f4, 0x1032e, 0x1034e, 0x1035c, 0x10396,\r\n      0x103a6, 0x103ac, 0x10422, 0x10428, 0x10436, 0x10442, 0x10444,\r\n      0x10448, 0x10450, 0x1045e, 0x10466, 0x1046c, 0x1047a, 0x10482,\r\n      0x1049e, 0x104a0, 0x104bc, 0x104c6, 0x104d8, 0x104ee, 0x104f2,\r\n      0x104f4, 0x10504, 0x10508, 0x10510, 0x1051e, 0x10520, 0x1053c,\r\n      0x10540, 0x10578, 0x10586, 0x1058c, 0x10598, 0x105b0, 0x105be,\r\n      0x105ce, 0x105dc, 0x105e2, 0x105e4, 0x105e8, 0x105f6, 0x1062e,\r\n      0x1064e, 0x1065c, 0x1068e, 0x1069c, 0x106b8, 0x106de, 0x106fa,\r\n      0x10716, 0x10726, 0x1072c, 0x10746, 0x1074c, 0x10758, 0x1076e,\r\n      0x10792, 0x10794, 0x107a2, 0x107a4, 0x107a8, 0x107b6, 0x10822,\r\n      0x10828, 0x10842, 0x10848, 0x10850, 0x1085e, 0x10866, 0x1086c,\r\n      0x1087a, 0x10882, 0x10884, 0x10890, 0x1089e, 0x108a0, 0x108bc,\r\n      0x108c6, 0x108cc, 0x108d8, 0x108ee, 0x108f2, 0x108f4, 0x10902,\r\n      0x10908, 0x1091e, 0x10920, 0x1093c, 0x10940, 0x10978, 0x10986,\r\n      0x10998, 0x109b0, 0x109be, 0x109ce, 0x109dc, 0x109e2, 0x109e4,\r\n      0x109e8, 0x109f6, 0x10a08, 0x10a10, 0x10a1e, 0x10a20, 0x10a3c,\r\n      0x10a40, 0x10a78, 0x10af0, 0x10b06, 0x10b0c, 0x10b18, 0x10b30,\r\n      0x10b3e, 0x10b60, 0x10b7c, 0x10b8e, 0x10b9c, 0x10bb8, 0x10bc2,\r\n      0x10bc4, 0x10bc8, 0x10bd0, 0x10bde, 0x10be6, 0x10bec, 0x10c2e,\r\n      0x10c4e, 0x10c5c, 0x10c62, 0x10c64, 0x10c68, 0x10c76, 0x10c8e,\r\n      0x10c9c, 0x10cb8, 0x10cc2, 0x10cc4, 0x10cc8, 0x10cd0, 0x10cde,\r\n      0x10ce6, 0x10cec, 0x10cfa, 0x10d0e, 0x10d1c, 0x10d38, 0x10d70,\r\n      0x10d7e, 0x10d82, 0x10d84, 0x10d88, 0x10d90, 0x10d9e, 0x10da0,\r\n      0x10dbc, 0x10dc6, 0x10dcc, 0x10dd8, 0x10dee, 0x10df2, 0x10df4,\r\n      0x10e16, 0x10e26, 0x10e2c, 0x10e46, 0x10e58, 0x10e6e, 0x10e86,\r\n      0x10e8c, 0x10e98, 0x10eb0, 0x10ebe, 0x10ece, 0x10edc, 0x10f0a,\r\n      0x10f12, 0x10f14, 0x10f22, 0x10f28, 0x10f36, 0x10f42, 0x10f44,\r\n      0x10f48, 0x10f50, 0x10f5e, 0x10f66, 0x10f6c, 0x10fb2, 0x10fb4,\r\n      0x11022, 0x11028, 0x11042, 0x11048, 0x11050, 0x1105e, 0x1107a,\r\n      0x11082, 0x11084, 0x11090, 0x1109e, 0x110a0, 0x110bc, 0x110c6,\r\n      0x110cc, 0x110d8, 0x110ee, 0x110f2, 0x110f4, 0x11102, 0x1111e,\r\n      0x11120, 0x1113c, 0x11140, 0x11178, 0x11186, 0x11198, 0x111b0,\r\n      0x111be, 0x111ce, 0x111dc, 0x111e2, 0x111e4, 0x111e8, 0x111f6,\r\n      0x11208, 0x1121e, 0x11220, 0x11278, 0x112f0, 0x1130c, 0x11330,\r\n      0x1133e, 0x11360, 0x1137c, 0x1138e, 0x1139c, 0x113b8, 0x113c2,\r\n      0x113c8, 0x113d0, 0x113de, 0x113e6, 0x113ec, 0x11408, 0x11410,\r\n      0x1141e, 0x11420, 0x1143c, 0x11440, 0x11478, 0x114f0, 0x115e0,\r\n      0x1160c, 0x11618, 0x11630, 0x1163e, 0x11660, 0x1167c, 0x116c0,\r\n      0x116f8, 0x1171c, 0x11738, 0x11770, 0x1177e, 0x11782, 0x11784,\r\n      0x11788, 0x11790, 0x1179e, 0x117a0, 0x117bc, 0x117c6, 0x117cc,\r\n      0x117d8, 0x117ee, 0x1182e, 0x11834, 0x1184e, 0x1185c, 0x11862,\r\n      0x11864, 0x11868, 0x11876, 0x1188e, 0x1189c, 0x118b8, 0x118c2,\r\n      0x118c8, 0x118d0, 0x118de, 0x118e6, 0x118ec, 0x118fa, 0x1190e,\r\n      0x1191c, 0x11938, 0x11970, 0x1197e, 0x11982, 0x11984, 0x11990,\r\n      0x1199e, 0x119a0, 0x119bc, 0x119c6, 0x119cc, 0x119d8, 0x119ee,\r\n      0x119f2, 0x119f4, 0x11a0e, 0x11a1c, 0x11a38, 0x11a70, 0x11a7e,\r\n      0x11ae0, 0x11afc, 0x11b08, 0x11b10, 0x11b1e, 0x11b20, 0x11b3c,\r\n      0x11b40, 0x11b78, 0x11b8c, 0x11b98, 0x11bb0, 0x11bbe, 0x11bce,\r\n      0x11bdc, 0x11be2, 0x11be4, 0x11be8, 0x11bf6, 0x11c16, 0x11c26,\r\n      0x11c2c, 0x11c46, 0x11c4c, 0x11c58, 0x11c6e, 0x11c86, 0x11c98,\r\n      0x11cb0, 0x11cbe, 0x11cce, 0x11cdc, 0x11ce2, 0x11ce4, 0x11ce8,\r\n      0x11cf6, 0x11d06, 0x11d0c, 0x11d18, 0x11d30, 0x11d3e, 0x11d60,\r\n      0x11d7c, 0x11d8e, 0x11d9c, 0x11db8, 0x11dc4, 0x11dc8, 0x11dd0,\r\n      0x11dde, 0x11de6, 0x11dec, 0x11dfa, 0x11e0a, 0x11e12, 0x11e14,\r\n      0x11e22, 0x11e24, 0x11e28, 0x11e36, 0x11e42, 0x11e44, 0x11e50,\r\n      0x11e5e, 0x11e66, 0x11e6c, 0x11e82, 0x11e84, 0x11e88, 0x11e90,\r\n      0x11e9e, 0x11ea0, 0x11ebc, 0x11ec6, 0x11ecc, 0x11ed8, 0x11eee,\r\n      0x11f1a, 0x11f2e, 0x11f32, 0x11f34, 0x11f4e, 0x11f5c, 0x11f62,\r\n      0x11f64, 0x11f68, 0x11f76, 0x12048, 0x1205e, 0x12082, 0x12084,\r\n      0x12090, 0x1209e, 0x120a0, 0x120bc, 0x120d8, 0x120f2, 0x120f4,\r\n      0x12108, 0x1211e, 0x12120, 0x1213c, 0x12140, 0x12178, 0x12186,\r\n      0x12198, 0x121b0, 0x121be, 0x121e2, 0x121e4, 0x121e8, 0x121f6,\r\n      0x12204, 0x12210, 0x1221e, 0x12220, 0x12278, 0x122f0, 0x12306,\r\n      0x1230c, 0x12330, 0x1233e, 0x12360, 0x1237c, 0x1238e, 0x1239c,\r\n      0x123b8, 0x123c2, 0x123c8, 0x123d0, 0x123e6, 0x123ec, 0x1241e,\r\n      0x12420, 0x1243c, 0x124f0, 0x125e0, 0x12618, 0x1263e, 0x12660,\r\n      0x1267c, 0x126c0, 0x126f8, 0x12738, 0x12770, 0x1277e, 0x12782,\r\n      0x12784, 0x12790, 0x1279e, 0x127a0, 0x127bc, 0x127c6, 0x127cc,\r\n      0x127d8, 0x127ee, 0x12820, 0x1283c, 0x12840, 0x12878, 0x128f0,\r\n      0x129e0, 0x12bc0, 0x12c18, 0x12c30, 0x12c3e, 0x12c60, 0x12c7c,\r\n      0x12cc0, 0x12cf8, 0x12df0, 0x12e1c, 0x12e38, 0x12e70, 0x12e7e,\r\n      0x12ee0, 0x12efc, 0x12f04, 0x12f08, 0x12f10, 0x12f20, 0x12f3c,\r\n      0x12f40, 0x12f78, 0x12f86, 0x12f8c, 0x12f98, 0x12fb0, 0x12fbe,\r\n      0x12fce, 0x12fdc, 0x1302e, 0x1304e, 0x1305c, 0x13062, 0x13068,\r\n      0x1308e, 0x1309c, 0x130b8, 0x130c2, 0x130c8, 0x130d0, 0x130de,\r\n      0x130ec, 0x130fa, 0x1310e, 0x13138, 0x13170, 0x1317e, 0x13182,\r\n      0x13184, 0x13190, 0x1319e, 0x131a0, 0x131bc, 0x131c6, 0x131cc,\r\n      0x131d8, 0x131f2, 0x131f4, 0x1320e, 0x1321c, 0x13270, 0x1327e,\r\n      0x132e0, 0x132fc, 0x13308, 0x1331e, 0x13320, 0x1333c, 0x13340,\r\n      0x13378, 0x13386, 0x13398, 0x133b0, 0x133be, 0x133ce, 0x133dc,\r\n      0x133e2, 0x133e4, 0x133e8, 0x133f6, 0x1340e, 0x1341c, 0x13438,\r\n      0x13470, 0x1347e, 0x134e0, 0x134fc, 0x135c0, 0x135f8, 0x13608,\r\n      0x13610, 0x1361e, 0x13620, 0x1363c, 0x13640, 0x13678, 0x136f0,\r\n      0x1370c, 0x13718, 0x13730, 0x1373e, 0x13760, 0x1377c, 0x1379c,\r\n      0x137b8, 0x137c2, 0x137c4, 0x137c8, 0x137d0, 0x137de, 0x137e6,\r\n      0x137ec, 0x13816, 0x13826, 0x1382c, 0x13846, 0x1384c, 0x13858,\r\n      0x1386e, 0x13874, 0x13886, 0x13898, 0x138b0, 0x138be, 0x138ce,\r\n      0x138dc, 0x138e2, 0x138e4, 0x138e8, 0x13906, 0x1390c, 0x13930,\r\n      0x1393e, 0x13960, 0x1397c, 0x1398e, 0x1399c, 0x139b8, 0x139c8,\r\n      0x139d0, 0x139de, 0x139e6, 0x139ec, 0x139fa, 0x13a06, 0x13a0c,\r\n      0x13a18, 0x13a30, 0x13a3e, 0x13a60, 0x13a7c, 0x13ac0, 0x13af8,\r\n      0x13b0e, 0x13b1c, 0x13b38, 0x13b70, 0x13b7e, 0x13b88, 0x13b90,\r\n      0x13b9e, 0x13ba0, 0x13bbc, 0x13bcc, 0x13bd8, 0x13bee, 0x13bf2,\r\n      0x13bf4, 0x13c12, 0x13c14, 0x13c22, 0x13c24, 0x13c28, 0x13c36,\r\n      0x13c42, 0x13c48, 0x13c50, 0x13c5e, 0x13c66, 0x13c6c, 0x13c82,\r\n      0x13c84, 0x13c90, 0x13c9e, 0x13ca0, 0x13cbc, 0x13cc6, 0x13ccc,\r\n      0x13cd8, 0x13cee, 0x13d02, 0x13d04, 0x13d08, 0x13d10, 0x13d1e,\r\n      0x13d20, 0x13d3c, 0x13d40, 0x13d78, 0x13d86, 0x13d8c, 0x13d98,\r\n      0x13db0, 0x13dbe, 0x13dce, 0x13ddc, 0x13de4, 0x13de8, 0x13df6,\r\n      0x13e1a, 0x13e2e, 0x13e32, 0x13e34, 0x13e4e, 0x13e5c, 0x13e62,\r\n      0x13e64, 0x13e68, 0x13e76, 0x13e8e, 0x13e9c, 0x13eb8, 0x13ec2,\r\n      0x13ec4, 0x13ec8, 0x13ed0, 0x13ede, 0x13ee6, 0x13eec, 0x13f26,\r\n      0x13f2c, 0x13f3a, 0x13f46, 0x13f4c, 0x13f58, 0x13f6e, 0x13f72,\r\n      0x13f74, 0x14082, 0x1409e, 0x140a0, 0x140bc, 0x14104, 0x14108,\r\n      0x14110, 0x1411e, 0x14120, 0x1413c, 0x14140, 0x14178, 0x1418c,\r\n      0x14198, 0x141b0, 0x141be, 0x141e2, 0x141e4, 0x141e8, 0x14208,\r\n      0x14210, 0x1421e, 0x14220, 0x1423c, 0x14240, 0x14278, 0x142f0,\r\n      0x14306, 0x1430c, 0x14318, 0x14330, 0x1433e, 0x14360, 0x1437c,\r\n      0x1438e, 0x143c2, 0x143c4, 0x143c8, 0x143d0, 0x143e6, 0x143ec,\r\n      0x14408, 0x14410, 0x1441e, 0x14420, 0x1443c, 0x14440, 0x14478,\r\n      0x144f0, 0x145e0, 0x1460c, 0x14618, 0x14630, 0x1463e, 0x14660,\r\n      0x1467c, 0x146c0, 0x146f8, 0x1471c, 0x14738, 0x14770, 0x1477e,\r\n      0x14782, 0x14784, 0x14788, 0x14790, 0x147a0, 0x147bc, 0x147c6,\r\n      0x147cc, 0x147d8, 0x147ee, 0x14810, 0x14820, 0x1483c, 0x14840,\r\n      0x14878, 0x148f0, 0x149e0, 0x14bc0, 0x14c30, 0x14c3e, 0x14c60,\r\n      0x14c7c, 0x14cc0, 0x14cf8, 0x14df0, 0x14e38, 0x14e70, 0x14e7e,\r\n      0x14ee0, 0x14efc, 0x14f04, 0x14f08, 0x14f10, 0x14f1e, 0x14f20,\r\n      0x14f3c, 0x14f40, 0x14f78, 0x14f86, 0x14f8c, 0x14f98, 0x14fb0,\r\n      0x14fce, 0x14fdc, 0x15020, 0x15040, 0x15078, 0x150f0, 0x151e0,\r\n      0x153c0, 0x15860, 0x1587c, 0x158c0, 0x158f8, 0x159f0, 0x15be0,\r\n      0x15c70, 0x15c7e, 0x15ce0, 0x15cfc, 0x15dc0, 0x15df8, 0x15e08,\r\n      0x15e10, 0x15e20, 0x15e40, 0x15e78, 0x15ef0, 0x15f0c, 0x15f18,\r\n      0x15f30, 0x15f60, 0x15f7c, 0x15f8e, 0x15f9c, 0x15fb8, 0x1604e,\r\n      0x1605c, 0x1608e, 0x1609c, 0x160b8, 0x160c2, 0x160c4, 0x160c8,\r\n      0x160de, 0x1610e, 0x1611c, 0x16138, 0x16170, 0x1617e, 0x16184,\r\n      0x16188, 0x16190, 0x1619e, 0x161a0, 0x161bc, 0x161c6, 0x161cc,\r\n      0x161d8, 0x161f2, 0x161f4, 0x1620e, 0x1621c, 0x16238, 0x16270,\r\n      0x1627e, 0x162e0, 0x162fc, 0x16304, 0x16308, 0x16310, 0x1631e,\r\n      0x16320, 0x1633c, 0x16340, 0x16378, 0x16386, 0x1638c, 0x16398,\r\n      0x163b0, 0x163be, 0x163ce, 0x163dc, 0x163e2, 0x163e4, 0x163e8,\r\n      0x163f6, 0x1640e, 0x1641c, 0x16438, 0x16470, 0x1647e, 0x164e0,\r\n      0x164fc, 0x165c0, 0x165f8, 0x16610, 0x1661e, 0x16620, 0x1663c,\r\n      0x16640, 0x16678, 0x166f0, 0x16718, 0x16730, 0x1673e, 0x16760,\r\n      0x1677c, 0x1678e, 0x1679c, 0x167b8, 0x167c2, 0x167c4, 0x167c8,\r\n      0x167d0, 0x167de, 0x167e6, 0x167ec, 0x1681c, 0x16838, 0x16870,\r\n      0x168e0, 0x168fc, 0x169c0, 0x169f8, 0x16bf0, 0x16c10, 0x16c1e,\r\n      0x16c20, 0x16c3c, 0x16c40, 0x16c78, 0x16cf0, 0x16de0, 0x16e18,\r\n      0x16e30, 0x16e3e, 0x16e60, 0x16e7c, 0x16ec0, 0x16ef8, 0x16f1c,\r\n      0x16f38, 0x16f70, 0x16f7e, 0x16f84, 0x16f88, 0x16f90, 0x16f9e,\r\n      0x16fa0, 0x16fbc, 0x16fc6, 0x16fcc, 0x16fd8, 0x17026, 0x1702c,\r\n      0x17046, 0x1704c, 0x17058, 0x1706e, 0x17086, 0x1708c, 0x17098,\r\n      0x170b0, 0x170be, 0x170ce, 0x170dc, 0x170e8, 0x17106, 0x1710c,\r\n      0x17118, 0x17130, 0x1713e, 0x17160, 0x1717c, 0x1718e, 0x1719c,\r\n      0x171b8, 0x171c2, 0x171c4, 0x171c8, 0x171d0, 0x171de, 0x171e6,\r\n      0x171ec, 0x171fa, 0x17206, 0x1720c, 0x17218, 0x17230, 0x1723e,\r\n      0x17260, 0x1727c, 0x172c0, 0x172f8, 0x1730e, 0x1731c, 0x17338,\r\n      0x17370, 0x1737e, 0x17388, 0x17390, 0x1739e, 0x173a0, 0x173bc,\r\n      0x173cc, 0x173d8, 0x173ee, 0x173f2, 0x173f4, 0x1740c, 0x17418,\r\n      0x17430, 0x1743e, 0x17460, 0x1747c, 0x174c0, 0x174f8, 0x175f0,\r\n      0x1760e, 0x1761c, 0x17638, 0x17670, 0x1767e, 0x176e0, 0x176fc,\r\n      0x17708, 0x17710, 0x1771e, 0x17720, 0x1773c, 0x17740, 0x17778,\r\n      0x17798, 0x177b0, 0x177be, 0x177dc, 0x177e2, 0x177e4, 0x177e8,\r\n      0x17822, 0x17824, 0x17828, 0x17836, 0x17842, 0x17844, 0x17848,\r\n      0x17850, 0x1785e, 0x17866, 0x1786c, 0x17882, 0x17884, 0x17888,\r\n      0x17890, 0x1789e, 0x178a0, 0x178bc, 0x178c6, 0x178cc, 0x178d8,\r\n      0x178ee, 0x178f2, 0x178f4, 0x17902, 0x17904, 0x17908, 0x17910,\r\n      0x1791e, 0x17920, 0x1793c, 0x17940, 0x17978, 0x17986, 0x1798c,\r\n      0x17998, 0x179b0, 0x179be, 0x179ce, 0x179dc, 0x179e2, 0x179e4,\r\n      0x179e8, 0x179f6, 0x17a04, 0x17a08, 0x17a10, 0x17a1e, 0x17a20,\r\n      0x17a3c, 0x17a40, 0x17a78, 0x17af0, 0x17b06, 0x17b0c, 0x17b18,\r\n      0x17b30, 0x17b3e, 0x17b60, 0x17b7c, 0x17b8e, 0x17b9c, 0x17bb8,\r\n      0x17bc4, 0x17bc8, 0x17bd0, 0x17bde, 0x17be6, 0x17bec, 0x17c2e,\r\n      0x17c32, 0x17c34, 0x17c4e, 0x17c5c, 0x17c62, 0x17c64, 0x17c68,\r\n      0x17c76, 0x17c8e, 0x17c9c, 0x17cb8, 0x17cc2, 0x17cc4, 0x17cc8,\r\n      0x17cd0, 0x17cde, 0x17ce6, 0x17cec, 0x17d0e, 0x17d1c, 0x17d38,\r\n      0x17d70, 0x17d82, 0x17d84, 0x17d88, 0x17d90, 0x17d9e, 0x17da0,\r\n      0x17dbc, 0x17dc6, 0x17dcc, 0x17dd8, 0x17dee, 0x17e26, 0x17e2c,\r\n      0x17e3a, 0x17e46, 0x17e4c, 0x17e58, 0x17e6e, 0x17e72, 0x17e74,\r\n      0x17e86, 0x17e8c, 0x17e98, 0x17eb0, 0x17ece, 0x17edc, 0x17ee2,\r\n      0x17ee4, 0x17ee8, 0x17ef6, 0x1813a, 0x18172, 0x18174, 0x18216,\r\n      0x18226, 0x1823a, 0x1824c, 0x18258, 0x1826e, 0x18272, 0x18274,\r\n      0x18298, 0x182be, 0x182e2, 0x182e4, 0x182e8, 0x182f6, 0x1835e,\r\n      0x1837a, 0x183ae, 0x183d6, 0x18416, 0x18426, 0x1842c, 0x1843a,\r\n      0x18446, 0x18458, 0x1846e, 0x18472, 0x18474, 0x18486, 0x184b0,\r\n      0x184be, 0x184ce, 0x184dc, 0x184e2, 0x184e4, 0x184e8, 0x184f6,\r\n      0x18506, 0x1850c, 0x18518, 0x18530, 0x1853e, 0x18560, 0x1857c,\r\n      0x1858e, 0x1859c, 0x185b8, 0x185c2, 0x185c4, 0x185c8, 0x185d0,\r\n      0x185de, 0x185e6, 0x185ec, 0x185fa, 0x18612, 0x18614, 0x18622,\r\n      0x18628, 0x18636, 0x18642, 0x18650, 0x1865e, 0x1867a, 0x18682,\r\n      0x18684, 0x18688, 0x18690, 0x1869e, 0x186a0, 0x186bc, 0x186c6,\r\n      0x186cc, 0x186d8, 0x186ee, 0x186f2, 0x186f4, 0x1872e, 0x1874e,\r\n      0x1875c, 0x18796, 0x187a6, 0x187ac, 0x187d2, 0x187d4, 0x18826,\r\n      0x1882c, 0x1883a, 0x18846, 0x1884c, 0x18858, 0x1886e, 0x18872,\r\n      0x18874, 0x18886, 0x18898, 0x188b0, 0x188be, 0x188ce, 0x188dc,\r\n      0x188e2, 0x188e4, 0x188e8, 0x188f6, 0x1890c, 0x18930, 0x1893e,\r\n      0x18960, 0x1897c, 0x1898e, 0x189b8, 0x189c2, 0x189c8, 0x189d0,\r\n      0x189de, 0x189e6, 0x189ec, 0x189fa, 0x18a18, 0x18a30, 0x18a3e,\r\n      0x18a60, 0x18a7c, 0x18ac0, 0x18af8, 0x18b1c, 0x18b38, 0x18b70,\r\n      0x18b7e, 0x18b82, 0x18b84, 0x18b88, 0x18b90, 0x18b9e, 0x18ba0,\r\n      0x18bbc, 0x18bc6, 0x18bcc, 0x18bd8, 0x18bee, 0x18bf2, 0x18bf4,\r\n      0x18c22, 0x18c24, 0x18c28, 0x18c36, 0x18c42, 0x18c48, 0x18c50,\r\n      0x18c5e, 0x18c66, 0x18c7a, 0x18c82, 0x18c84, 0x18c90, 0x18c9e,\r\n      0x18ca0, 0x18cbc, 0x18ccc, 0x18cf2, 0x18cf4, 0x18d04, 0x18d08,\r\n      0x18d10, 0x18d1e, 0x18d20, 0x18d3c, 0x18d40, 0x18d78, 0x18d86,\r\n      0x18d98, 0x18dce, 0x18de2, 0x18de4, 0x18de8, 0x18e2e, 0x18e32,\r\n      0x18e34, 0x18e4e, 0x18e5c, 0x18e62, 0x18e64, 0x18e68, 0x18e8e,\r\n      0x18e9c, 0x18eb8, 0x18ec2, 0x18ec4, 0x18ec8, 0x18ed0, 0x18efa,\r\n      0x18f16, 0x18f26, 0x18f2c, 0x18f46, 0x18f4c, 0x18f58, 0x18f6e,\r\n      0x18f8a, 0x18f92, 0x18f94, 0x18fa2, 0x18fa4, 0x18fa8, 0x18fb6,\r\n      0x1902c, 0x1903a, 0x19046, 0x1904c, 0x19058, 0x19072, 0x19074,\r\n      0x19086, 0x19098, 0x190b0, 0x190be, 0x190ce, 0x190dc, 0x190e2,\r\n      0x190e8, 0x190f6, 0x19106, 0x1910c, 0x19130, 0x1913e, 0x19160,\r\n      0x1917c, 0x1918e, 0x1919c, 0x191b8, 0x191c2, 0x191c8, 0x191d0,\r\n      0x191de, 0x191e6, 0x191ec, 0x191fa, 0x19218, 0x1923e, 0x19260,\r\n      0x1927c, 0x192c0, 0x192f8, 0x19338, 0x19370, 0x1937e, 0x19382,\r\n      0x19384, 0x19390, 0x1939e, 0x193a0, 0x193bc, 0x193c6, 0x193cc,\r\n      0x193d8, 0x193ee, 0x193f2, 0x193f4, 0x19430, 0x1943e, 0x19460,\r\n      0x1947c, 0x194c0, 0x194f8, 0x195f0, 0x19638, 0x19670, 0x1967e,\r\n      0x196e0, 0x196fc, 0x19702, 0x19704, 0x19708, 0x19710, 0x19720,\r\n      0x1973c, 0x19740, 0x19778, 0x19786, 0x1978c, 0x19798, 0x197b0,\r\n      0x197be, 0x197ce, 0x197dc, 0x197e2, 0x197e4, 0x197e8, 0x19822,\r\n      0x19824, 0x19842, 0x19848, 0x19850, 0x1985e, 0x19866, 0x1987a,\r\n      0x19882, 0x19884, 0x19890, 0x1989e, 0x198a0, 0x198bc, 0x198cc,\r\n      0x198f2, 0x198f4, 0x19902, 0x19908, 0x1991e, 0x19920, 0x1993c,\r\n      0x19940, 0x19978, 0x19986, 0x19998, 0x199ce, 0x199e2, 0x199e4,\r\n      0x199e8, 0x19a08, 0x19a10, 0x19a1e, 0x19a20, 0x19a3c, 0x19a40,\r\n      0x19a78, 0x19af0, 0x19b18, 0x19b3e, 0x19b60, 0x19b9c, 0x19bc2,\r\n      0x19bc4, 0x19bc8, 0x19bd0, 0x19be6, 0x19c2e, 0x19c34, 0x19c4e,\r\n      0x19c5c, 0x19c62, 0x19c64, 0x19c68, 0x19c8e, 0x19c9c, 0x19cb8,\r\n      0x19cc2, 0x19cc8, 0x19cd0, 0x19ce6, 0x19cfa, 0x19d0e, 0x19d1c,\r\n      0x19d38, 0x19d70, 0x19d7e, 0x19d82, 0x19d84, 0x19d88, 0x19d90,\r\n      0x19da0, 0x19dcc, 0x19df2, 0x19df4, 0x19e16, 0x19e26, 0x19e2c,\r\n      0x19e46, 0x19e4c, 0x19e58, 0x19e74, 0x19e86, 0x19e8c, 0x19e98,\r\n      0x19eb0, 0x19ebe, 0x19ece, 0x19ee2, 0x19ee4, 0x19ee8, 0x19f0a,\r\n      0x19f12, 0x19f14, 0x19f22, 0x19f24, 0x19f28, 0x19f42, 0x19f44,\r\n      0x19f48, 0x19f50, 0x19f5e, 0x19f6c, 0x19f9a, 0x19fae, 0x19fb2,\r\n      0x19fb4, 0x1a046, 0x1a04c, 0x1a072, 0x1a074, 0x1a086, 0x1a08c,\r\n      0x1a098, 0x1a0b0, 0x1a0be, 0x1a0e2, 0x1a0e4, 0x1a0e8, 0x1a0f6,\r\n      0x1a106, 0x1a10c, 0x1a118, 0x1a130, 0x1a13e, 0x1a160, 0x1a17c,\r\n      0x1a18e, 0x1a19c, 0x1a1b8, 0x1a1c2, 0x1a1c4, 0x1a1c8, 0x1a1d0,\r\n      0x1a1de, 0x1a1e6, 0x1a1ec, 0x1a218, 0x1a230, 0x1a23e, 0x1a260,\r\n      0x1a27c, 0x1a2c0, 0x1a2f8, 0x1a31c, 0x1a338, 0x1a370, 0x1a37e,\r\n      0x1a382, 0x1a384, 0x1a388, 0x1a390, 0x1a39e, 0x1a3a0, 0x1a3bc,\r\n      0x1a3c6, 0x1a3cc, 0x1a3d8, 0x1a3ee, 0x1a3f2, 0x1a3f4, 0x1a418,\r\n      0x1a430, 0x1a43e, 0x1a460, 0x1a47c, 0x1a4c0, 0x1a4f8, 0x1a5f0,\r\n      0x1a61c, 0x1a638, 0x1a670, 0x1a67e, 0x1a6e0, 0x1a6fc, 0x1a702,\r\n      0x1a704, 0x1a708, 0x1a710, 0x1a71e, 0x1a720, 0x1a73c, 0x1a740,\r\n      0x1a778, 0x1a786, 0x1a78c, 0x1a798, 0x1a7b0, 0x1a7be, 0x1a7ce,\r\n      0x1a7dc, 0x1a7e2, 0x1a7e4, 0x1a7e8, 0x1a830, 0x1a860, 0x1a87c,\r\n      0x1a8c0, 0x1a8f8, 0x1a9f0, 0x1abe0, 0x1ac70, 0x1ac7e, 0x1ace0,\r\n      0x1acfc, 0x1adc0, 0x1adf8, 0x1ae04, 0x1ae08, 0x1ae10, 0x1ae20,\r\n      0x1ae3c, 0x1ae40, 0x1ae78, 0x1aef0, 0x1af06, 0x1af0c, 0x1af18,\r\n      0x1af30, 0x1af3e, 0x1af60, 0x1af7c, 0x1af8e, 0x1af9c, 0x1afb8,\r\n      0x1afc4, 0x1afc8, 0x1afd0, 0x1afde, 0x1b042, 0x1b05e, 0x1b07a,\r\n      0x1b082, 0x1b084, 0x1b088, 0x1b090, 0x1b09e, 0x1b0a0, 0x1b0bc,\r\n      0x1b0cc, 0x1b0f2, 0x1b0f4, 0x1b102, 0x1b104, 0x1b108, 0x1b110,\r\n      0x1b11e, 0x1b120, 0x1b13c, 0x1b140, 0x1b178, 0x1b186, 0x1b198,\r\n      0x1b1ce, 0x1b1e2, 0x1b1e4, 0x1b1e8, 0x1b204, 0x1b208, 0x1b210,\r\n      0x1b21e, 0x1b220, 0x1b23c, 0x1b240, 0x1b278, 0x1b2f0, 0x1b30c,\r\n      0x1b33e, 0x1b360, 0x1b39c, 0x1b3c2, 0x1b3c4, 0x1b3c8, 0x1b3d0,\r\n      0x1b3e6, 0x1b410, 0x1b41e, 0x1b420, 0x1b43c, 0x1b440, 0x1b478,\r\n      0x1b4f0, 0x1b5e0, 0x1b618, 0x1b660, 0x1b67c, 0x1b6c0, 0x1b738,\r\n      0x1b782, 0x1b784, 0x1b788, 0x1b790, 0x1b79e, 0x1b7a0, 0x1b7cc,\r\n      0x1b82e, 0x1b84e, 0x1b85c, 0x1b88e, 0x1b89c, 0x1b8b8, 0x1b8c2,\r\n      0x1b8c4, 0x1b8c8, 0x1b8d0, 0x1b8e6, 0x1b8fa, 0x1b90e, 0x1b91c,\r\n      0x1b938, 0x1b970, 0x1b97e, 0x1b982, 0x1b984, 0x1b988, 0x1b990,\r\n      0x1b99e, 0x1b9a0, 0x1b9cc, 0x1b9f2, 0x1b9f4, 0x1ba0e, 0x1ba1c,\r\n      0x1ba38, 0x1ba70, 0x1ba7e, 0x1bae0, 0x1bafc, 0x1bb08, 0x1bb10,\r\n      0x1bb20, 0x1bb3c, 0x1bb40, 0x1bb98, 0x1bbce, 0x1bbe2, 0x1bbe4,\r\n      0x1bbe8, 0x1bc16, 0x1bc26, 0x1bc2c, 0x1bc46, 0x1bc4c, 0x1bc58,\r\n      0x1bc72, 0x1bc74, 0x1bc86, 0x1bc8c, 0x1bc98, 0x1bcb0, 0x1bcbe,\r\n      0x1bcce, 0x1bce2, 0x1bce4, 0x1bce8, 0x1bd06, 0x1bd0c, 0x1bd18,\r\n      0x1bd30, 0x1bd3e, 0x1bd60, 0x1bd7c, 0x1bd9c, 0x1bdc2, 0x1bdc4,\r\n      0x1bdc8, 0x1bdd0, 0x1bde6, 0x1bdfa, 0x1be12, 0x1be14, 0x1be22,\r\n      0x1be24, 0x1be28, 0x1be42, 0x1be44, 0x1be48, 0x1be50, 0x1be5e,\r\n      0x1be66, 0x1be82, 0x1be84, 0x1be88, 0x1be90, 0x1be9e, 0x1bea0,\r\n      0x1bebc, 0x1becc, 0x1bef4, 0x1bf1a, 0x1bf2e, 0x1bf32, 0x1bf34,\r\n      0x1bf4e, 0x1bf5c, 0x1bf62, 0x1bf64, 0x1bf68, 0x1c09a, 0x1c0b2,\r\n      0x1c0b4, 0x1c11a, 0x1c132, 0x1c134, 0x1c162, 0x1c164, 0x1c168,\r\n      0x1c176, 0x1c1ba, 0x1c21a, 0x1c232, 0x1c234, 0x1c24e, 0x1c25c,\r\n      0x1c262, 0x1c264, 0x1c268, 0x1c276, 0x1c28e, 0x1c2c2, 0x1c2c4,\r\n      0x1c2c8, 0x1c2d0, 0x1c2de, 0x1c2e6, 0x1c2ec, 0x1c2fa, 0x1c316,\r\n      0x1c326, 0x1c33a, 0x1c346, 0x1c34c, 0x1c372, 0x1c374, 0x1c41a,\r\n      0x1c42e, 0x1c432, 0x1c434, 0x1c44e, 0x1c45c, 0x1c462, 0x1c464,\r\n      0x1c468, 0x1c476, 0x1c48e, 0x1c49c, 0x1c4b8, 0x1c4c2, 0x1c4c8,\r\n      0x1c4d0, 0x1c4de, 0x1c4e6, 0x1c4ec, 0x1c4fa, 0x1c51c, 0x1c538,\r\n      0x1c570, 0x1c57e, 0x1c582, 0x1c584, 0x1c588, 0x1c590, 0x1c59e,\r\n      0x1c5a0, 0x1c5bc, 0x1c5c6, 0x1c5cc, 0x1c5d8, 0x1c5ee, 0x1c5f2,\r\n      0x1c5f4, 0x1c616, 0x1c626, 0x1c62c, 0x1c63a, 0x1c646, 0x1c64c,\r\n      0x1c658, 0x1c66e, 0x1c672, 0x1c674, 0x1c686, 0x1c68c, 0x1c698,\r\n      0x1c6b0, 0x1c6be, 0x1c6ce, 0x1c6dc, 0x1c6e2, 0x1c6e4, 0x1c6e8,\r\n      0x1c712, 0x1c714, 0x1c722, 0x1c728, 0x1c736, 0x1c742, 0x1c744,\r\n      0x1c748, 0x1c750, 0x1c75e, 0x1c766, 0x1c76c, 0x1c77a, 0x1c7ae,\r\n      0x1c7d6, 0x1c7ea, 0x1c81a, 0x1c82e, 0x1c832, 0x1c834, 0x1c84e,\r\n      0x1c85c, 0x1c862, 0x1c864, 0x1c868, 0x1c876, 0x1c88e, 0x1c89c,\r\n      0x1c8b8, 0x1c8c2, 0x1c8c8, 0x1c8d0, 0x1c8de, 0x1c8e6, 0x1c8ec,\r\n      0x1c8fa, 0x1c90e, 0x1c938, 0x1c970, 0x1c97e, 0x1c982, 0x1c984,\r\n      0x1c990, 0x1c99e, 0x1c9a0, 0x1c9bc, 0x1c9c6, 0x1c9cc, 0x1c9d8,\r\n      0x1c9ee, 0x1c9f2, 0x1c9f4, 0x1ca38, 0x1ca70, 0x1ca7e, 0x1cae0,\r\n      0x1cafc, 0x1cb02, 0x1cb04, 0x1cb08, 0x1cb10, 0x1cb20, 0x1cb3c,\r\n      0x1cb40, 0x1cb78, 0x1cb86, 0x1cb8c, 0x1cb98, 0x1cbb0, 0x1cbbe,\r\n      0x1cbce, 0x1cbdc, 0x1cbe2, 0x1cbe4, 0x1cbe8, 0x1cbf6, 0x1cc16,\r\n      0x1cc26, 0x1cc2c, 0x1cc3a, 0x1cc46, 0x1cc58, 0x1cc72, 0x1cc74,\r\n      0x1cc86, 0x1ccb0, 0x1ccbe, 0x1ccce, 0x1cce2, 0x1cce4, 0x1cce8,\r\n      0x1cd06, 0x1cd0c, 0x1cd18, 0x1cd30, 0x1cd3e, 0x1cd60, 0x1cd7c,\r\n      0x1cd9c, 0x1cdc2, 0x1cdc4, 0x1cdc8, 0x1cdd0, 0x1cdde, 0x1cde6,\r\n      0x1cdfa, 0x1ce22, 0x1ce28, 0x1ce42, 0x1ce50, 0x1ce5e, 0x1ce66,\r\n      0x1ce7a, 0x1ce82, 0x1ce84, 0x1ce88, 0x1ce90, 0x1ce9e, 0x1cea0,\r\n      0x1cebc, 0x1cecc, 0x1cef2, 0x1cef4, 0x1cf2e, 0x1cf32, 0x1cf34,\r\n      0x1cf4e, 0x1cf5c, 0x1cf62, 0x1cf64, 0x1cf68, 0x1cf96, 0x1cfa6,\r\n      0x1cfac, 0x1cfca, 0x1cfd2, 0x1cfd4, 0x1d02e, 0x1d032, 0x1d034,\r\n      0x1d04e, 0x1d05c, 0x1d062, 0x1d064, 0x1d068, 0x1d076, 0x1d08e,\r\n      0x1d09c, 0x1d0b8, 0x1d0c2, 0x1d0c4, 0x1d0c8, 0x1d0d0, 0x1d0de,\r\n      0x1d0e6, 0x1d0ec, 0x1d0fa, 0x1d11c, 0x1d138, 0x1d170, 0x1d17e,\r\n      0x1d182, 0x1d184, 0x1d188, 0x1d190, 0x1d19e, 0x1d1a0, 0x1d1bc,\r\n      0x1d1c6, 0x1d1cc, 0x1d1d8, 0x1d1ee, 0x1d1f2, 0x1d1f4, 0x1d21c,\r\n      0x1d238, 0x1d270, 0x1d27e, 0x1d2e0, 0x1d2fc, 0x1d302, 0x1d304,\r\n      0x1d308, 0x1d310, 0x1d31e, 0x1d320, 0x1d33c, 0x1d340, 0x1d378,\r\n      0x1d386, 0x1d38c, 0x1d398, 0x1d3b0, 0x1d3be, 0x1d3ce, 0x1d3dc,\r\n      0x1d3e2, 0x1d3e4, 0x1d3e8, 0x1d3f6, 0x1d470, 0x1d47e, 0x1d4e0,\r\n      0x1d4fc, 0x1d5c0, 0x1d5f8, 0x1d604, 0x1d608, 0x1d610, 0x1d620,\r\n      0x1d640, 0x1d678, 0x1d6f0, 0x1d706, 0x1d70c, 0x1d718, 0x1d730,\r\n      0x1d73e, 0x1d760, 0x1d77c, 0x1d78e, 0x1d79c, 0x1d7b8, 0x1d7c2,\r\n      0x1d7c4, 0x1d7c8, 0x1d7d0, 0x1d7de, 0x1d7e6, 0x1d7ec, 0x1d826,\r\n      0x1d82c, 0x1d83a, 0x1d846, 0x1d84c, 0x1d858, 0x1d872, 0x1d874,\r\n      0x1d886, 0x1d88c, 0x1d898, 0x1d8b0, 0x1d8be, 0x1d8ce, 0x1d8e2,\r\n      0x1d8e4, 0x1d8e8, 0x1d8f6, 0x1d90c, 0x1d918, 0x1d930, 0x1d93e,\r\n      0x1d960, 0x1d97c, 0x1d99c, 0x1d9c2, 0x1d9c4, 0x1d9c8, 0x1d9d0,\r\n      0x1d9e6, 0x1d9fa, 0x1da0c, 0x1da18, 0x1da30, 0x1da3e, 0x1da60,\r\n      0x1da7c, 0x1dac0, 0x1daf8, 0x1db38, 0x1db82, 0x1db84, 0x1db88,\r\n      0x1db90, 0x1db9e, 0x1dba0, 0x1dbcc, 0x1dbf2, 0x1dbf4, 0x1dc22,\r\n      0x1dc42, 0x1dc44, 0x1dc48, 0x1dc50, 0x1dc5e, 0x1dc66, 0x1dc7a,\r\n      0x1dc82, 0x1dc84, 0x1dc88, 0x1dc90, 0x1dc9e, 0x1dca0, 0x1dcbc,\r\n      0x1dccc, 0x1dcf2, 0x1dcf4, 0x1dd04, 0x1dd08, 0x1dd10, 0x1dd1e,\r\n      0x1dd20, 0x1dd3c, 0x1dd40, 0x1dd78, 0x1dd86, 0x1dd98, 0x1ddce,\r\n      0x1dde2, 0x1dde4, 0x1dde8, 0x1de2e, 0x1de32, 0x1de34, 0x1de4e,\r\n      0x1de5c, 0x1de62, 0x1de64, 0x1de68, 0x1de8e, 0x1de9c, 0x1deb8,\r\n      0x1dec2, 0x1dec4, 0x1dec8, 0x1ded0, 0x1dee6, 0x1defa, 0x1df16,\r\n      0x1df26, 0x1df2c, 0x1df46, 0x1df4c, 0x1df58, 0x1df72, 0x1df74,\r\n      0x1df8a, 0x1df92, 0x1df94, 0x1dfa2, 0x1dfa4, 0x1dfa8, 0x1e08a,\r\n      0x1e092, 0x1e094, 0x1e0a2, 0x1e0a4, 0x1e0a8, 0x1e0b6, 0x1e0da,\r\n      0x1e10a, 0x1e112, 0x1e114, 0x1e122, 0x1e124, 0x1e128, 0x1e136,\r\n      0x1e142, 0x1e144, 0x1e148, 0x1e150, 0x1e166, 0x1e16c, 0x1e17a,\r\n      0x1e19a, 0x1e1b2, 0x1e1b4, 0x1e20a, 0x1e212, 0x1e214, 0x1e222,\r\n      0x1e224, 0x1e228, 0x1e236, 0x1e242, 0x1e248, 0x1e250, 0x1e25e,\r\n      0x1e266, 0x1e26c, 0x1e27a, 0x1e282, 0x1e284, 0x1e288, 0x1e290,\r\n      0x1e2a0, 0x1e2bc, 0x1e2c6, 0x1e2cc, 0x1e2d8, 0x1e2ee, 0x1e2f2,\r\n      0x1e2f4, 0x1e31a, 0x1e332, 0x1e334, 0x1e35c, 0x1e362, 0x1e364,\r\n      0x1e368, 0x1e3ba, 0x1e40a, 0x1e412, 0x1e414, 0x1e422, 0x1e428,\r\n      0x1e436, 0x1e442, 0x1e448, 0x1e450, 0x1e45e, 0x1e466, 0x1e46c,\r\n      0x1e47a, 0x1e482, 0x1e484, 0x1e490, 0x1e49e, 0x1e4a0, 0x1e4bc,\r\n      0x1e4c6, 0x1e4cc, 0x1e4d8, 0x1e4ee, 0x1e4f2, 0x1e4f4, 0x1e502,\r\n      0x1e504, 0x1e508, 0x1e510, 0x1e51e, 0x1e520, 0x1e53c, 0x1e540,\r\n      0x1e578, 0x1e586, 0x1e58c, 0x1e598, 0x1e5b0, 0x1e5be, 0x1e5ce,\r\n      0x1e5dc, 0x1e5e2, 0x1e5e4, 0x1e5e8, 0x1e5f6, 0x1e61a, 0x1e62e,\r\n      0x1e632, 0x1e634, 0x1e64e, 0x1e65c, 0x1e662, 0x1e668, 0x1e68e,\r\n      0x1e69c, 0x1e6b8, 0x1e6c2, 0x1e6c4, 0x1e6c8, 0x1e6d0, 0x1e6e6,\r\n      0x1e6fa, 0x1e716, 0x1e726, 0x1e72c, 0x1e73a, 0x1e746, 0x1e74c,\r\n      0x1e758, 0x1e772, 0x1e774, 0x1e792, 0x1e794, 0x1e7a2, 0x1e7a4,\r\n      0x1e7a8, 0x1e7b6, 0x1e812, 0x1e814, 0x1e822, 0x1e824, 0x1e828,\r\n      0x1e836, 0x1e842, 0x1e844, 0x1e848, 0x1e850, 0x1e85e, 0x1e866,\r\n      0x1e86c, 0x1e87a, 0x1e882, 0x1e884, 0x1e888, 0x1e890, 0x1e89e,\r\n      0x1e8a0, 0x1e8bc, 0x1e8c6, 0x1e8cc, 0x1e8d8, 0x1e8ee, 0x1e8f2,\r\n      0x1e8f4, 0x1e902, 0x1e904, 0x1e908, 0x1e910, 0x1e920, 0x1e93c,\r\n      0x1e940, 0x1e978, 0x1e986, 0x1e98c, 0x1e998, 0x1e9b0, 0x1e9be,\r\n      0x1e9ce, 0x1e9dc, 0x1e9e2, 0x1e9e4, 0x1e9e8, 0x1e9f6, 0x1ea04,\r\n      0x1ea08, 0x1ea10, 0x1ea20, 0x1ea40, 0x1ea78, 0x1eaf0, 0x1eb06,\r\n      0x1eb0c, 0x1eb18, 0x1eb30, 0x1eb3e, 0x1eb60, 0x1eb7c, 0x1eb8e,\r\n      0x1eb9c, 0x1ebb8, 0x1ebc2, 0x1ebc4, 0x1ebc8, 0x1ebd0, 0x1ebde,\r\n      0x1ebe6, 0x1ebec, 0x1ec1a, 0x1ec2e, 0x1ec32, 0x1ec34, 0x1ec4e,\r\n      0x1ec5c, 0x1ec62, 0x1ec64, 0x1ec68, 0x1ec8e, 0x1ec9c, 0x1ecb8,\r\n      0x1ecc2, 0x1ecc4, 0x1ecc8, 0x1ecd0, 0x1ece6, 0x1ecfa, 0x1ed0e,\r\n      0x1ed1c, 0x1ed38, 0x1ed70, 0x1ed7e, 0x1ed82, 0x1ed84, 0x1ed88,\r\n      0x1ed90, 0x1ed9e, 0x1eda0, 0x1edcc, 0x1edf2, 0x1edf4, 0x1ee16,\r\n      0x1ee26, 0x1ee2c, 0x1ee3a, 0x1ee46, 0x1ee4c, 0x1ee58, 0x1ee6e,\r\n      0x1ee72, 0x1ee74, 0x1ee86, 0x1ee8c, 0x1ee98, 0x1eeb0, 0x1eebe,\r\n      0x1eece, 0x1eedc, 0x1eee2, 0x1eee4, 0x1eee8, 0x1ef12, 0x1ef22,\r\n      0x1ef24, 0x1ef28, 0x1ef36, 0x1ef42, 0x1ef44, 0x1ef48, 0x1ef50,\r\n      0x1ef5e, 0x1ef66, 0x1ef6c, 0x1ef7a, 0x1efae, 0x1efb2, 0x1efb4,\r\n      0x1efd6, 0x1f096, 0x1f0a6, 0x1f0ac, 0x1f0ba, 0x1f0ca, 0x1f0d2,\r\n      0x1f0d4, 0x1f116, 0x1f126, 0x1f12c, 0x1f13a, 0x1f146, 0x1f14c,\r\n      0x1f158, 0x1f16e, 0x1f172, 0x1f174, 0x1f18a, 0x1f192, 0x1f194,\r\n      0x1f1a2, 0x1f1a4, 0x1f1a8, 0x1f1da, 0x1f216, 0x1f226, 0x1f22c,\r\n      0x1f23a, 0x1f246, 0x1f258, 0x1f26e, 0x1f272, 0x1f274, 0x1f286,\r\n      0x1f28c, 0x1f298, 0x1f2b0, 0x1f2be, 0x1f2ce, 0x1f2dc, 0x1f2e2,\r\n      0x1f2e4, 0x1f2e8, 0x1f2f6, 0x1f30a, 0x1f312, 0x1f314, 0x1f322,\r\n      0x1f328, 0x1f342, 0x1f344, 0x1f348, 0x1f350, 0x1f35e, 0x1f366,\r\n      0x1f37a, 0x1f39a, 0x1f3ae, 0x1f3b2, 0x1f3b4, 0x1f416, 0x1f426,\r\n      0x1f42c, 0x1f43a, 0x1f446, 0x1f44c, 0x1f458, 0x1f46e, 0x1f472,\r\n      0x1f474, 0x1f486, 0x1f48c, 0x1f498, 0x1f4b0, 0x1f4be, 0x1f4ce,\r\n      0x1f4dc, 0x1f4e2, 0x1f4e4, 0x1f4e8, 0x1f4f6, 0x1f506, 0x1f50c,\r\n      0x1f518, 0x1f530, 0x1f53e, 0x1f560, 0x1f57c, 0x1f58e, 0x1f59c,\r\n      0x1f5b8, 0x1f5c2, 0x1f5c4, 0x1f5c8, 0x1f5d0, 0x1f5de, 0x1f5e6,\r\n      0x1f5ec, 0x1f5fa, 0x1f60a, 0x1f612, 0x1f614, 0x1f622, 0x1f624,\r\n      0x1f628, 0x1f636, 0x1f642, 0x1f644, 0x1f648, 0x1f650, 0x1f65e,\r\n      0x1f666, 0x1f67a, 0x1f682, 0x1f684, 0x1f688, 0x1f690, 0x1f69e,\r\n      0x1f6a0, 0x1f6bc, 0x1f6cc, 0x1f6f2, 0x1f6f4, 0x1f71a, 0x1f72e,\r\n      0x1f732, 0x1f734, 0x1f74e, 0x1f75c, 0x1f762, 0x1f764, 0x1f768,\r\n      0x1f776, 0x1f796, 0x1f7a6, 0x1f7ac, 0x1f7ba, 0x1f7d2, 0x1f7d4,\r\n      0x1f89a, 0x1f8ae, 0x1f8b2, 0x1f8b4, 0x1f8d6, 0x1f8ea, 0x1f91a,\r\n      0x1f92e, 0x1f932, 0x1f934, 0x1f94e, 0x1f95c, 0x1f962, 0x1f964,\r\n      0x1f968, 0x1f976, 0x1f996, 0x1f9a6, 0x1f9ac, 0x1f9ba, 0x1f9ca,\r\n      0x1f9d2, 0x1f9d4, 0x1fa1a, 0x1fa2e, 0x1fa32, 0x1fa34, 0x1fa4e,\r\n      0x1fa5c, 0x1fa62, 0x1fa64, 0x1fa68, 0x1fa76, 0x1fa8e, 0x1fa9c,\r\n      0x1fab8, 0x1fac2, 0x1fac4, 0x1fac8, 0x1fad0, 0x1fade, 0x1fae6,\r\n      0x1faec, 0x1fb16, 0x1fb26, 0x1fb2c, 0x1fb3a, 0x1fb46, 0x1fb4c,\r\n      0x1fb58, 0x1fb6e, 0x1fb72, 0x1fb74, 0x1fb8a, 0x1fb92, 0x1fb94,\r\n      0x1fba2, 0x1fba4, 0x1fba8, 0x1fbb6, 0x1fbda};\r\n\r\n  /**\r\n   * This table contains to codewords for all symbols.\r\n   */\r\n  private static final int[] CODEWORD_TABLE = {2627, 1819, 2622, 2621, 1813,\r\n      1812, 2729, 2724, 2723, 2779, 2774, 2773, 902, 896, 908, 868, 865,\r\n      861, 859, 2511, 873, 871, 1780, 835, 2493, 825, 2491, 842, 837, 844,\r\n      1764, 1762, 811, 810, 809, 2483, 807, 2482, 806, 2480, 815, 814, 813,\r\n      812, 2484, 817, 816, 1745, 1744, 1742, 1746, 2655, 2637, 2635, 2626,\r\n      2625, 2623, 2628, 1820, 2752, 2739, 2737, 2728, 2727, 2725, 2730,\r\n      2785, 2783, 2778, 2777, 2775, 2780, 787, 781, 747, 739, 736, 2413,\r\n      754, 752, 1719, 692, 689, 681, 2371, 678, 2369, 700, 697, 694, 703,\r\n      1688, 1686, 642, 638, 2343, 631, 2341, 627, 2338, 651, 646, 643, 2345,\r\n      654, 652, 1652, 1650, 1647, 1654, 601, 599, 2322, 596, 2321, 594,\r\n      2319, 2317, 611, 610, 608, 606, 2324, 603, 2323, 615, 614, 612, 1617,\r\n      1616, 1614, 1612, 616, 1619, 1618, 2575, 2538, 2536, 905, 901, 898,\r\n      909, 2509, 2507, 2504, 870, 867, 864, 860, 2512, 875, 872, 1781, 2490,\r\n      2489, 2487, 2485, 1748, 836, 834, 832, 830, 2494, 827, 2492, 843, 841,\r\n      839, 845, 1765, 1763, 2701, 2676, 2674, 2653, 2648, 2656, 2634, 2633,\r\n      2631, 2629, 1821, 2638, 2636, 2770, 2763, 2761, 2750, 2745, 2753,\r\n      2736, 2735, 2733, 2731, 1848, 2740, 2738, 2786, 2784, 591, 588, 576,\r\n      569, 566, 2296, 1590, 537, 534, 526, 2276, 522, 2274, 545, 542, 539,\r\n      548, 1572, 1570, 481, 2245, 466, 2242, 462, 2239, 492, 485, 482, 2249,\r\n      496, 494, 1534, 1531, 1528, 1538, 413, 2196, 406, 2191, 2188, 425,\r\n      419, 2202, 415, 2199, 432, 430, 427, 1472, 1467, 1464, 433, 1476,\r\n      1474, 368, 367, 2160, 365, 2159, 362, 2157, 2155, 2152, 378, 377, 375,\r\n      2166, 372, 2165, 369, 2162, 383, 381, 379, 2168, 1419, 1418, 1416,\r\n      1414, 385, 1411, 384, 1423, 1422, 1420, 1424, 2461, 802, 2441, 2439,\r\n      790, 786, 783, 794, 2409, 2406, 2403, 750, 742, 738, 2414, 756, 753,\r\n      1720, 2367, 2365, 2362, 2359, 1663, 693, 691, 684, 2373, 680, 2370,\r\n      702, 699, 696, 704, 1690, 1687, 2337, 2336, 2334, 2332, 1624, 2329,\r\n      1622, 640, 637, 2344, 634, 2342, 630, 2340, 650, 648, 645, 2346, 655,\r\n      653, 1653, 1651, 1649, 1655, 2612, 2597, 2595, 2571, 2568, 2565, 2576,\r\n      2534, 2529, 2526, 1787, 2540, 2537, 907, 904, 900, 910, 2503, 2502,\r\n      2500, 2498, 1768, 2495, 1767, 2510, 2508, 2506, 869, 866, 863, 2513,\r\n      876, 874, 1782, 2720, 2713, 2711, 2697, 2694, 2691, 2702, 2672, 2670,\r\n      2664, 1828, 2678, 2675, 2647, 2646, 2644, 2642, 1823, 2639, 1822,\r\n      2654, 2652, 2650, 2657, 2771, 1855, 2765, 2762, 1850, 1849, 2751,\r\n      2749, 2747, 2754, 353, 2148, 344, 342, 336, 2142, 332, 2140, 345,\r\n      1375, 1373, 306, 2130, 299, 2128, 295, 2125, 319, 314, 311, 2132,\r\n      1354, 1352, 1349, 1356, 262, 257, 2101, 253, 2096, 2093, 274, 273,\r\n      267, 2107, 263, 2104, 280, 278, 275, 1316, 1311, 1308, 1320, 1318,\r\n      2052, 202, 2050, 2044, 2040, 219, 2063, 212, 2060, 208, 2055, 224,\r\n      221, 2066, 1260, 1258, 1252, 231, 1248, 229, 1266, 1264, 1261, 1268,\r\n      155, 1998, 153, 1996, 1994, 1991, 1988, 165, 164, 2007, 162, 2006,\r\n      159, 2003, 2000, 172, 171, 169, 2012, 166, 2010, 1186, 1184, 1182,\r\n      1179, 175, 1176, 173, 1192, 1191, 1189, 1187, 176, 1194, 1193, 2313,\r\n      2307, 2305, 592, 589, 2294, 2292, 2289, 578, 572, 568, 2297, 580,\r\n      1591, 2272, 2267, 2264, 1547, 538, 536, 529, 2278, 525, 2275, 547,\r\n      544, 541, 1574, 1571, 2237, 2235, 2229, 1493, 2225, 1489, 478, 2247,\r\n      470, 2244, 465, 2241, 493, 488, 484, 2250, 498, 495, 1536, 1533, 1530,\r\n      1539, 2187, 2186, 2184, 2182, 1432, 2179, 1430, 2176, 1427, 414, 412,\r\n      2197, 409, 2195, 405, 2193, 2190, 426, 424, 421, 2203, 418, 2201, 431,\r\n      429, 1473, 1471, 1469, 1466, 434, 1477, 1475, 2478, 2472, 2470, 2459,\r\n      2457, 2454, 2462, 803, 2437, 2432, 2429, 1726, 2443, 2440, 792, 789,\r\n      785, 2401, 2399, 2393, 1702, 2389, 1699, 2411, 2408, 2405, 745, 741,\r\n      2415, 758, 755, 1721, 2358, 2357, 2355, 2353, 1661, 2350, 1660, 2347,\r\n      1657, 2368, 2366, 2364, 2361, 1666, 690, 687, 2374, 683, 2372, 701,\r\n      698, 705, 1691, 1689, 2619, 2617, 2610, 2608, 2605, 2613, 2593, 2588,\r\n      2585, 1803, 2599, 2596, 2563, 2561, 2555, 1797, 2551, 1795, 2573,\r\n      2570, 2567, 2577, 2525, 2524, 2522, 2520, 1786, 2517, 1785, 2514,\r\n      1783, 2535, 2533, 2531, 2528, 1788, 2541, 2539, 906, 903, 911, 2721,\r\n      1844, 2715, 2712, 1838, 1836, 2699, 2696, 2693, 2703, 1827, 1826,\r\n      1824, 2673, 2671, 2669, 2666, 1829, 2679, 2677, 1858, 1857, 2772,\r\n      1854, 1853, 1851, 1856, 2766, 2764, 143, 1987, 139, 1986, 135, 133,\r\n      131, 1984, 128, 1983, 125, 1981, 138, 137, 136, 1985, 1133, 1132,\r\n      1130, 112, 110, 1974, 107, 1973, 104, 1971, 1969, 122, 121, 119, 117,\r\n      1977, 114, 1976, 124, 1115, 1114, 1112, 1110, 1117, 1116, 84, 83,\r\n      1953, 81, 1952, 78, 1950, 1948, 1945, 94, 93, 91, 1959, 88, 1958, 85,\r\n      1955, 99, 97, 95, 1961, 1086, 1085, 1083, 1081, 1078, 100, 1090, 1089,\r\n      1087, 1091, 49, 47, 1917, 44, 1915, 1913, 1910, 1907, 59, 1926, 56,\r\n      1925, 53, 1922, 1919, 66, 64, 1931, 61, 1929, 1042, 1040, 1038, 71,\r\n      1035, 70, 1032, 68, 1048, 1047, 1045, 1043, 1050, 1049, 12, 10, 1869,\r\n      1867, 1864, 1861, 21, 1880, 19, 1877, 1874, 1871, 28, 1888, 25, 1886,\r\n      22, 1883, 982, 980, 977, 974, 32, 30, 991, 989, 987, 984, 34, 995,\r\n      994, 992, 2151, 2150, 2147, 2146, 2144, 356, 355, 354, 2149, 2139,\r\n      2138, 2136, 2134, 1359, 343, 341, 338, 2143, 335, 2141, 348, 347, 346,\r\n      1376, 1374, 2124, 2123, 2121, 2119, 1326, 2116, 1324, 310, 308, 305,\r\n      2131, 302, 2129, 298, 2127, 320, 318, 316, 313, 2133, 322, 321, 1355,\r\n      1353, 1351, 1357, 2092, 2091, 2089, 2087, 1276, 2084, 1274, 2081,\r\n      1271, 259, 2102, 256, 2100, 252, 2098, 2095, 272, 269, 2108, 266,\r\n      2106, 281, 279, 277, 1317, 1315, 1313, 1310, 282, 1321, 1319, 2039,\r\n      2037, 2035, 2032, 1203, 2029, 1200, 1197, 207, 2053, 205, 2051, 201,\r\n      2049, 2046, 2043, 220, 218, 2064, 215, 2062, 211, 2059, 228, 226, 223,\r\n      2069, 1259, 1257, 1254, 232, 1251, 230, 1267, 1265, 1263, 2316, 2315,\r\n      2312, 2311, 2309, 2314, 2304, 2303, 2301, 2299, 1593, 2308, 2306, 590,\r\n      2288, 2287, 2285, 2283, 1578, 2280, 1577, 2295, 2293, 2291, 579, 577,\r\n      574, 571, 2298, 582, 581, 1592, 2263, 2262, 2260, 2258, 1545, 2255,\r\n      1544, 2252, 1541, 2273, 2271, 2269, 2266, 1550, 535, 532, 2279, 528,\r\n      2277, 546, 543, 549, 1575, 1573, 2224, 2222, 2220, 1486, 2217, 1485,\r\n      2214, 1482, 1479, 2238, 2236, 2234, 2231, 1496, 2228, 1492, 480, 477,\r\n      2248, 473, 2246, 469, 2243, 490, 487, 2251, 497, 1537, 1535, 1532,\r\n      2477, 2476, 2474, 2479, 2469, 2468, 2466, 2464, 1730, 2473, 2471,\r\n      2453, 2452, 2450, 2448, 1729, 2445, 1728, 2460, 2458, 2456, 2463, 805,\r\n      804, 2428, 2427, 2425, 2423, 1725, 2420, 1724, 2417, 1722, 2438, 2436,\r\n      2434, 2431, 1727, 2444, 2442, 793, 791, 788, 795, 2388, 2386, 2384,\r\n      1697, 2381, 1696, 2378, 1694, 1692, 2402, 2400, 2398, 2395, 1703,\r\n      2392, 1701, 2412, 2410, 2407, 751, 748, 744, 2416, 759, 757, 1807,\r\n      2620, 2618, 1806, 1805, 2611, 2609, 2607, 2614, 1802, 1801, 1799,\r\n      2594, 2592, 2590, 2587, 1804, 2600, 2598, 1794, 1793, 1791, 1789,\r\n      2564, 2562, 2560, 2557, 1798, 2554, 1796, 2574, 2572, 2569, 2578,\r\n      1847, 1846, 2722, 1843, 1842, 1840, 1845, 2716, 2714, 1835, 1834,\r\n      1832, 1830, 1839, 1837, 2700, 2698, 2695, 2704, 1817, 1811, 1810, 897,\r\n      862, 1777, 829, 826, 838, 1760, 1758, 808, 2481, 1741, 1740, 1738,\r\n      1743, 2624, 1818, 2726, 2776, 782, 740, 737, 1715, 686, 679, 695,\r\n      1682, 1680, 639, 628, 2339, 647, 644, 1645, 1643, 1640, 1648, 602,\r\n      600, 597, 595, 2320, 593, 2318, 609, 607, 604, 1611, 1610, 1608, 1606,\r\n      613, 1615, 1613, 2328, 926, 924, 892, 886, 899, 857, 850, 2505, 1778,\r\n      824, 823, 821, 819, 2488, 818, 2486, 833, 831, 828, 840, 1761, 1759,\r\n      2649, 2632, 2630, 2746, 2734, 2732, 2782, 2781, 570, 567, 1587, 531,\r\n      527, 523, 540, 1566, 1564, 476, 467, 463, 2240, 486, 483, 1524, 1521,\r\n      1518, 1529, 411, 403, 2192, 399, 2189, 423, 416, 1462, 1457, 1454,\r\n      428, 1468, 1465, 2210, 366, 363, 2158, 360, 2156, 357, 2153, 376, 373,\r\n      370, 2163, 1410, 1409, 1407, 1405, 382, 1402, 380, 1417, 1415, 1412,\r\n      1421, 2175, 2174, 777, 774, 771, 784, 732, 725, 722, 2404, 743, 1716,\r\n      676, 674, 668, 2363, 665, 2360, 685, 1684, 1681, 626, 624, 622, 2335,\r\n      620, 2333, 617, 2330, 641, 635, 649, 1646, 1644, 1642, 2566, 928, 925,\r\n      2530, 2527, 894, 891, 888, 2501, 2499, 2496, 858, 856, 854, 851, 1779,\r\n      2692, 2668, 2665, 2645, 2643, 2640, 2651, 2768, 2759, 2757, 2744,\r\n      2743, 2741, 2748, 352, 1382, 340, 337, 333, 1371, 1369, 307, 300, 296,\r\n      2126, 315, 312, 1347, 1342, 1350, 261, 258, 250, 2097, 246, 2094, 271,\r\n      268, 264, 1306, 1301, 1298, 276, 1312, 1309, 2115, 203, 2048, 195,\r\n      2045, 191, 2041, 213, 209, 2056, 1246, 1244, 1238, 225, 1234, 222,\r\n      1256, 1253, 1249, 1262, 2080, 2079, 154, 1997, 150, 1995, 147, 1992,\r\n      1989, 163, 160, 2004, 156, 2001, 1175, 1174, 1172, 1170, 1167, 170,\r\n      1164, 167, 1185, 1183, 1180, 1177, 174, 1190, 1188, 2025, 2024, 2022,\r\n      587, 586, 564, 559, 556, 2290, 573, 1588, 520, 518, 512, 2268, 508,\r\n      2265, 530, 1568, 1565, 461, 457, 2233, 450, 2230, 446, 2226, 479, 471,\r\n      489, 1526, 1523, 1520, 397, 395, 2185, 392, 2183, 389, 2180, 2177,\r\n      410, 2194, 402, 422, 1463, 1461, 1459, 1456, 1470, 2455, 799, 2433,\r\n      2430, 779, 776, 773, 2397, 2394, 2390, 734, 728, 724, 746, 1717, 2356,\r\n      2354, 2351, 2348, 1658, 677, 675, 673, 670, 667, 688, 1685, 1683,\r\n      2606, 2589, 2586, 2559, 2556, 2552, 927, 2523, 2521, 2518, 2515, 1784,\r\n      2532, 895, 893, 890, 2718, 2709, 2707, 2689, 2687, 2684, 2663, 2662,\r\n      2660, 2658, 1825, 2667, 2769, 1852, 2760, 2758, 142, 141, 1139, 1138,\r\n      134, 132, 129, 126, 1982, 1129, 1128, 1126, 1131, 113, 111, 108, 105,\r\n      1972, 101, 1970, 120, 118, 115, 1109, 1108, 1106, 1104, 123, 1113,\r\n      1111, 82, 79, 1951, 75, 1949, 72, 1946, 92, 89, 86, 1956, 1077, 1076,\r\n      1074, 1072, 98, 1069, 96, 1084, 1082, 1079, 1088, 1968, 1967, 48, 45,\r\n      1916, 42, 1914, 39, 1911, 1908, 60, 57, 54, 1923, 50, 1920, 1031,\r\n      1030, 1028, 1026, 67, 1023, 65, 1020, 62, 1041, 1039, 1036, 1033, 69,\r\n      1046, 1044, 1944, 1943, 1941, 11, 9, 1868, 7, 1865, 1862, 1859, 20,\r\n      1878, 16, 1875, 13, 1872, 970, 968, 966, 963, 29, 960, 26, 23, 983,\r\n      981, 978, 975, 33, 971, 31, 990, 988, 985, 1906, 1904, 1902, 993, 351,\r\n      2145, 1383, 331, 330, 328, 326, 2137, 323, 2135, 339, 1372, 1370, 294,\r\n      293, 291, 289, 2122, 286, 2120, 283, 2117, 309, 303, 317, 1348, 1346,\r\n      1344, 245, 244, 242, 2090, 239, 2088, 236, 2085, 2082, 260, 2099, 249,\r\n      270, 1307, 1305, 1303, 1300, 1314, 189, 2038, 186, 2036, 183, 2033,\r\n      2030, 2026, 206, 198, 2047, 194, 216, 1247, 1245, 1243, 1240, 227,\r\n      1237, 1255, 2310, 2302, 2300, 2286, 2284, 2281, 565, 563, 561, 558,\r\n      575, 1589, 2261, 2259, 2256, 2253, 1542, 521, 519, 517, 514, 2270,\r\n      511, 533, 1569, 1567, 2223, 2221, 2218, 2215, 1483, 2211, 1480, 459,\r\n      456, 453, 2232, 449, 474, 491, 1527, 1525, 1522, 2475, 2467, 2465,\r\n      2451, 2449, 2446, 801, 800, 2426, 2424, 2421, 2418, 1723, 2435, 780,\r\n      778, 775, 2387, 2385, 2382, 2379, 1695, 2375, 1693, 2396, 735, 733,\r\n      730, 727, 749, 1718, 2616, 2615, 2604, 2603, 2601, 2584, 2583, 2581,\r\n      2579, 1800, 2591, 2550, 2549, 2547, 2545, 1792, 2542, 1790, 2558, 929,\r\n      2719, 1841, 2710, 2708, 1833, 1831, 2690, 2688, 2686, 1815, 1809,\r\n      1808, 1774, 1756, 1754, 1737, 1736, 1734, 1739, 1816, 1711, 1676,\r\n      1674, 633, 629, 1638, 1636, 1633, 1641, 598, 1605, 1604, 1602, 1600,\r\n      605, 1609, 1607, 2327, 887, 853, 1775, 822, 820, 1757, 1755, 1584,\r\n      524, 1560, 1558, 468, 464, 1514, 1511, 1508, 1519, 408, 404, 400,\r\n      1452, 1447, 1444, 417, 1458, 1455, 2208, 364, 361, 358, 2154, 1401,\r\n      1400, 1398, 1396, 374, 1393, 371, 1408, 1406, 1403, 1413, 2173, 2172,\r\n      772, 726, 723, 1712, 672, 669, 666, 682, 1678, 1675, 625, 623, 621,\r\n      618, 2331, 636, 632, 1639, 1637, 1635, 920, 918, 884, 880, 889, 849,\r\n      848, 847, 846, 2497, 855, 852, 1776, 2641, 2742, 2787, 1380, 334,\r\n      1367, 1365, 301, 297, 1340, 1338, 1335, 1343, 255, 251, 247, 1296,\r\n      1291, 1288, 265, 1302, 1299, 2113, 204, 196, 192, 2042, 1232, 1230,\r\n      1224, 214, 1220, 210, 1242, 1239, 1235, 1250, 2077, 2075, 151, 148,\r\n      1993, 144, 1990, 1163, 1162, 1160, 1158, 1155, 161, 1152, 157, 1173,\r\n      1171, 1168, 1165, 168, 1181, 1178, 2021, 2020, 2018, 2023, 585, 560,\r\n      557, 1585, 516, 509, 1562, 1559, 458, 447, 2227, 472, 1516, 1513,\r\n      1510, 398, 396, 393, 390, 2181, 386, 2178, 407, 1453, 1451, 1449,\r\n      1446, 420, 1460, 2209, 769, 764, 720, 712, 2391, 729, 1713, 664, 663,\r\n      661, 659, 2352, 656, 2349, 671, 1679, 1677, 2553, 922, 919, 2519,\r\n      2516, 885, 883, 881, 2685, 2661, 2659, 2767, 2756, 2755, 140, 1137,\r\n      1136, 130, 127, 1125, 1124, 1122, 1127, 109, 106, 102, 1103, 1102,\r\n      1100, 1098, 116, 1107, 1105, 1980, 80, 76, 73, 1947, 1068, 1067, 1065,\r\n      1063, 90, 1060, 87, 1075, 1073, 1070, 1080, 1966, 1965, 46, 43, 40,\r\n      1912, 36, 1909, 1019, 1018, 1016, 1014, 58, 1011, 55, 1008, 51, 1029,\r\n      1027, 1024, 1021, 63, 1037, 1034, 1940, 1939, 1937, 1942, 8, 1866, 4,\r\n      1863, 1, 1860, 956, 954, 952, 949, 946, 17, 14, 969, 967, 964, 961,\r\n      27, 957, 24, 979, 976, 972, 1901, 1900, 1898, 1896, 986, 1905, 1903,\r\n      350, 349, 1381, 329, 327, 324, 1368, 1366, 292, 290, 287, 284, 2118,\r\n      304, 1341, 1339, 1337, 1345, 243, 240, 237, 2086, 233, 2083, 254,\r\n      1297, 1295, 1293, 1290, 1304, 2114, 190, 187, 184, 2034, 180, 2031,\r\n      177, 2027, 199, 1233, 1231, 1229, 1226, 217, 1223, 1241, 2078, 2076,\r\n      584, 555, 554, 552, 550, 2282, 562, 1586, 507, 506, 504, 502, 2257,\r\n      499, 2254, 515, 1563, 1561, 445, 443, 441, 2219, 438, 2216, 435, 2212,\r\n      460, 454, 475, 1517, 1515, 1512, 2447, 798, 797, 2422, 2419, 770, 768,\r\n      766, 2383, 2380, 2376, 721, 719, 717, 714, 731, 1714, 2602, 2582,\r\n      2580, 2548, 2546, 2543, 923, 921, 2717, 2706, 2705, 2683, 2682, 2680,\r\n      1771, 1752, 1750, 1733, 1732, 1731, 1735, 1814, 1707, 1670, 1668,\r\n      1631, 1629, 1626, 1634, 1599, 1598, 1596, 1594, 1603, 1601, 2326,\r\n      1772, 1753, 1751, 1581, 1554, 1552, 1504, 1501, 1498, 1509, 1442,\r\n      1437, 1434, 401, 1448, 1445, 2206, 1392, 1391, 1389, 1387, 1384, 359,\r\n      1399, 1397, 1394, 1404, 2171, 2170, 1708, 1672, 1669, 619, 1632, 1630,\r\n      1628, 1773, 1378, 1363, 1361, 1333, 1328, 1336, 1286, 1281, 1278, 248,\r\n      1292, 1289, 2111, 1218, 1216, 1210, 197, 1206, 193, 1228, 1225, 1221,\r\n      1236, 2073, 2071, 1151, 1150, 1148, 1146, 152, 1143, 149, 1140, 145,\r\n      1161, 1159, 1156, 1153, 158, 1169, 1166, 2017, 2016, 2014, 2019, 1582,\r\n      510, 1556, 1553, 452, 448, 1506, 1500, 394, 391, 387, 1443, 1441,\r\n      1439, 1436, 1450, 2207, 765, 716, 713, 1709, 662, 660, 657, 1673,\r\n      1671, 916, 914, 879, 878, 877, 882, 1135, 1134, 1121, 1120, 1118,\r\n      1123, 1097, 1096, 1094, 1092, 103, 1101, 1099, 1979, 1059, 1058, 1056,\r\n      1054, 77, 1051, 74, 1066, 1064, 1061, 1071, 1964, 1963, 1007, 1006,\r\n      1004, 1002, 999, 41, 996, 37, 1017, 1015, 1012, 1009, 52, 1025, 1022,\r\n      1936, 1935, 1933, 1938, 942, 940, 938, 935, 932, 5, 2, 955, 953, 950,\r\n      947, 18, 943, 15, 965, 962, 958, 1895, 1894, 1892, 1890, 973, 1899,\r\n      1897, 1379, 325, 1364, 1362, 288, 285, 1334, 1332, 1330, 241, 238,\r\n      234, 1287, 1285, 1283, 1280, 1294, 2112, 188, 185, 181, 178, 2028,\r\n      1219, 1217, 1215, 1212, 200, 1209, 1227, 2074, 2072, 583, 553, 551,\r\n      1583, 505, 503, 500, 513, 1557, 1555, 444, 442, 439, 436, 2213, 455,\r\n      451, 1507, 1505, 1502, 796, 763, 762, 760, 767, 711, 710, 708, 706,\r\n      2377, 718, 715, 1710, 2544, 917, 915, 2681, 1627, 1597, 1595, 2325,\r\n      1769, 1749, 1747, 1499, 1438, 1435, 2204, 1390, 1388, 1385, 1395,\r\n      2169, 2167, 1704, 1665, 1662, 1625, 1623, 1620, 1770, 1329, 1282,\r\n      1279, 2109, 1214, 1207, 1222, 2068, 2065, 1149, 1147, 1144, 1141, 146,\r\n      1157, 1154, 2013, 2011, 2008, 2015, 1579, 1549, 1546, 1495, 1487,\r\n      1433, 1431, 1428, 1425, 388, 1440, 2205, 1705, 658, 1667, 1664, 1119,\r\n      1095, 1093, 1978, 1057, 1055, 1052, 1062, 1962, 1960, 1005, 1003,\r\n      1000, 997, 38, 1013, 1010, 1932, 1930, 1927, 1934, 941, 939, 936, 933,\r\n      6, 930, 3, 951, 948, 944, 1889, 1887, 1884, 1881, 959, 1893, 1891, 35,\r\n      1377, 1360, 1358, 1327, 1325, 1322, 1331, 1277, 1275, 1272, 1269, 235,\r\n      1284, 2110, 1205, 1204, 1201, 1198, 182, 1195, 179, 1213, 2070, 2067,\r\n      1580, 501, 1551, 1548, 440, 437, 1497, 1494, 1490, 1503, 761, 709,\r\n      707, 1706, 913, 912, 2198, 1386, 2164, 2161, 1621, 1766, 2103, 1208,\r\n      2058, 2054, 1145, 1142, 2005, 2002, 1999, 2009, 1488, 1429, 1426,\r\n      2200, 1698, 1659, 1656, 1975, 1053, 1957, 1954, 1001, 998, 1924, 1921,\r\n      1918, 1928, 937, 934, 931, 1879, 1876, 1873, 1870, 945, 1885, 1882,\r\n      1323, 1273, 1270, 2105, 1202, 1199, 1196, 1211, 2061, 2057, 1576,\r\n      1543, 1540, 1484, 1481, 1478, 1491, 1700};\r\n}\r\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/pdf417/decoder/DecodedBitStreamParser.java",
    "content": "/*\r\n * Copyright 2009 ZXing authors\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage com.google.zxing.pdf417.decoder;\r\n\r\nimport com.google.zxing.FormatException;\r\nimport com.google.zxing.common.DecoderResult;\r\n\r\nimport java.math.BigInteger;\r\n\r\n/**\r\n * <p>This class contains the methods for decoding the PDF417 codewords.</p>\r\n *\r\n * @author SITA Lab (kevin.osullivan@sita.aero)\r\n */\r\nfinal class DecodedBitStreamParser {\r\n\r\n  private enum Mode {\r\n    ALPHA,\r\n    LOWER,\r\n    MIXED,\r\n    PUNCT,\r\n    ALPHA_SHIFT,\r\n    PUNCT_SHIFT\r\n  }\r\n\r\n  private static final int TEXT_COMPACTION_MODE_LATCH = 900;\r\n  private static final int BYTE_COMPACTION_MODE_LATCH = 901;\r\n  private static final int NUMERIC_COMPACTION_MODE_LATCH = 902;\r\n  private static final int BYTE_COMPACTION_MODE_LATCH_6 = 924;\r\n  private static final int BEGIN_MACRO_PDF417_CONTROL_BLOCK = 928;\r\n  private static final int BEGIN_MACRO_PDF417_OPTIONAL_FIELD = 923;\r\n  private static final int MACRO_PDF417_TERMINATOR = 922;\r\n  private static final int MODE_SHIFT_TO_BYTE_COMPACTION_MODE = 913;\r\n  private static final int MAX_NUMERIC_CODEWORDS = 15;\r\n\r\n  private static final int PL = 25;\r\n  private static final int LL = 27;\r\n  private static final int AS = 27;\r\n  private static final int ML = 28;\r\n  private static final int AL = 28;\r\n  private static final int PS = 29;\r\n  private static final int PAL = 29;\r\n\r\n  private static final char[] PUNCT_CHARS = {\r\n      ';', '<', '>', '@', '[', '\\\\', '}', '_', '`', '~', '!',\r\n      '\\r', '\\t', ',', ':', '\\n', '-', '.', '$', '/', '\"', '|', '*',\r\n      '(', ')', '?', '{', '}', '\\''};\r\n\r\n  private static final char[] MIXED_CHARS = {\r\n      '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '&',\r\n      '\\r', '\\t', ',', ':', '#', '-', '.', '$', '/', '+', '%', '*',\r\n      '=', '^'};\r\n\r\n  /**\r\n   * Table containing values for the exponent of 900.\r\n   * This is used in the numeric compaction decode algorithm.\r\n   */\r\n  private static final BigInteger[] EXP900;\r\n  static {\r\n    EXP900 = new BigInteger[16];\r\n    EXP900[0] = BigInteger.ONE;\r\n    BigInteger nineHundred = BigInteger.valueOf(900);\r\n    EXP900[1] = nineHundred;\r\n    for (int i = 2; i < EXP900.length; i++) {\r\n      EXP900[i] = EXP900[i - 1].multiply(nineHundred);\r\n    }\r\n  }\r\n\r\n  private DecodedBitStreamParser() {\r\n  }\r\n\r\n  static DecoderResult decode(int[] codewords) throws FormatException {\r\n    StringBuilder result = new StringBuilder(100);\r\n    // Get compaction mode\r\n    int codeIndex = 1;\r\n    int code = codewords[codeIndex++];\r\n    while (codeIndex < codewords[0]) {\r\n      switch (code) {\r\n        case TEXT_COMPACTION_MODE_LATCH:\r\n          codeIndex = textCompaction(codewords, codeIndex, result);\r\n          break;\r\n        case BYTE_COMPACTION_MODE_LATCH:\r\n          codeIndex = byteCompaction(code, codewords, codeIndex, result);\r\n          break;\r\n        case NUMERIC_COMPACTION_MODE_LATCH:\r\n          codeIndex = numericCompaction(codewords, codeIndex, result);\r\n          break;\r\n        case MODE_SHIFT_TO_BYTE_COMPACTION_MODE:\r\n          codeIndex = byteCompaction(code, codewords, codeIndex, result);\r\n          break;\r\n        case BYTE_COMPACTION_MODE_LATCH_6:\r\n          codeIndex = byteCompaction(code, codewords, codeIndex, result);\r\n          break;\r\n        default:\r\n          // Default to text compaction. During testing numerous barcodes\r\n          // appeared to be missing the starting mode. In these cases defaulting\r\n          // to text compaction seems to work.\r\n          codeIndex--;\r\n          codeIndex = textCompaction(codewords, codeIndex, result);\r\n          break;\r\n      }\r\n      if (codeIndex < codewords.length) {\r\n        code = codewords[codeIndex++];\r\n      } else {\r\n        throw FormatException.getFormatInstance();\r\n      }\r\n    }\r\n    if (result.length() == 0) {\r\n      throw FormatException.getFormatInstance();\r\n    }\r\n    return new DecoderResult(null, result.toString(), null, null);\r\n  }\r\n\r\n  /**\r\n   * Text Compaction mode (see 5.4.1.5) permits all printable ASCII characters to be\r\n   * encoded, i.e. values 32 - 126 inclusive in accordance with ISO/IEC 646 (IRV), as\r\n   * well as selected control characters.\r\n   *\r\n   * @param codewords The array of codewords (data + error)\r\n   * @param codeIndex The current index into the codeword array.\r\n   * @param result    The decoded data is appended to the result.\r\n   * @return The next index into the codeword array.\r\n   */\r\n  private static int textCompaction(int[] codewords, int codeIndex, StringBuilder result) {\r\n    // 2 character per codeword\r\n    int[] textCompactionData = new int[codewords[0] << 1];\r\n    // Used to hold the byte compaction value if there is a mode shift\r\n    int[] byteCompactionData = new int[codewords[0] << 1];\r\n\r\n    int index = 0;\r\n    boolean end = false;\r\n    while ((codeIndex < codewords[0]) && !end) {\r\n      int code = codewords[codeIndex++];\r\n      if (code < TEXT_COMPACTION_MODE_LATCH) {\r\n        textCompactionData[index] = code / 30;\r\n        textCompactionData[index + 1] = code % 30;\r\n        index += 2;\r\n      } else {\r\n        switch (code) {\r\n          case TEXT_COMPACTION_MODE_LATCH:\r\n            // reinitialize text compaction mode to alpha sub mode\r\n            textCompactionData[index++] = TEXT_COMPACTION_MODE_LATCH;\r\n            break;\r\n          case BYTE_COMPACTION_MODE_LATCH:\r\n            codeIndex--;\r\n            end = true;\r\n            break;\r\n          case NUMERIC_COMPACTION_MODE_LATCH:\r\n            codeIndex--;\r\n            end = true;\r\n            break;\r\n          case MODE_SHIFT_TO_BYTE_COMPACTION_MODE:\r\n            // The Mode Shift codeword 913 shall cause a temporary\r\n            // switch from Text Compaction mode to Byte Compaction mode.\r\n            // This switch shall be in effect for only the next codeword,\r\n            // after which the mode shall revert to the prevailing sub-mode\r\n            // of the Text Compaction mode. Codeword 913 is only available\r\n            // in Text Compaction mode; its use is described in 5.4.2.4.\r\n            textCompactionData[index] = MODE_SHIFT_TO_BYTE_COMPACTION_MODE;\r\n            code = codewords[codeIndex++];\r\n            byteCompactionData[index] = code; //Integer.toHexString(code);\r\n            index++;\r\n            break;\r\n          case BYTE_COMPACTION_MODE_LATCH_6:\r\n            codeIndex--;\r\n            end = true;\r\n            break;\r\n        }\r\n      }\r\n    }\r\n    decodeTextCompaction(textCompactionData, byteCompactionData, index, result);\r\n    return codeIndex;\r\n  }\r\n\r\n  /**\r\n   * The Text Compaction mode includes all the printable ASCII characters\r\n   * (i.e. values from 32 to 126) and three ASCII control characters: HT or tab\r\n   * (ASCII value 9), LF or line feed (ASCII value 10), and CR or carriage\r\n   * return (ASCII value 13). The Text Compaction mode also includes various latch\r\n   * and shift characters which are used exclusively within the mode. The Text\r\n   * Compaction mode encodes up to 2 characters per codeword. The compaction rules\r\n   * for converting data into PDF417 codewords are defined in 5.4.2.2. The sub-mode\r\n   * switches are defined in 5.4.2.3.\r\n   *\r\n   * @param textCompactionData The text compaction data.\r\n   * @param byteCompactionData The byte compaction data if there\r\n   *                           was a mode shift.\r\n   * @param length             The size of the text compaction and byte compaction data.\r\n   * @param result             The decoded data is appended to the result.\r\n   */\r\n  private static void decodeTextCompaction(int[] textCompactionData,\r\n                                           int[] byteCompactionData,\r\n                                           int length,\r\n                                           StringBuilder result) {\r\n    // Beginning from an initial state of the Alpha sub-mode\r\n    // The default compaction mode for PDF417 in effect at the start of each symbol shall always be Text\r\n    // Compaction mode Alpha sub-mode (uppercase alphabetic). A latch codeword from another mode to the Text\r\n    // Compaction mode shall always switch to the Text Compaction Alpha sub-mode.\r\n    Mode subMode = Mode.ALPHA;\r\n    Mode priorToShiftMode = Mode.ALPHA;\r\n    int i = 0;\r\n    while (i < length) {\r\n      int subModeCh = textCompactionData[i];\r\n      char ch = 0;\r\n      switch (subMode) {\r\n        case ALPHA:\r\n          // Alpha (uppercase alphabetic)\r\n          if (subModeCh < 26) {\r\n            // Upper case Alpha Character\r\n            ch = (char) ('A' + subModeCh);\r\n          } else {\r\n            if (subModeCh == 26) {\r\n              ch = ' ';\r\n            } else if (subModeCh == LL) {\r\n              subMode = Mode.LOWER;\r\n            } else if (subModeCh == ML) {\r\n              subMode = Mode.MIXED;\r\n            } else if (subModeCh == PS) {\r\n              // Shift to punctuation\r\n              priorToShiftMode = subMode;\r\n              subMode = Mode.PUNCT_SHIFT;\r\n            } else if (subModeCh == MODE_SHIFT_TO_BYTE_COMPACTION_MODE) {\r\n              result.append((char) byteCompactionData[i]);\r\n            } else if (subModeCh == TEXT_COMPACTION_MODE_LATCH) {\r\n              subMode = Mode.ALPHA;\r\n            }\r\n          }\r\n          break;\r\n\r\n        case LOWER:\r\n          // Lower (lowercase alphabetic)\r\n          if (subModeCh < 26) {\r\n            ch = (char) ('a' + subModeCh);\r\n          } else {\r\n            if (subModeCh == 26) {\r\n              ch = ' ';\r\n            } else if (subModeCh == AS) {\r\n              // Shift to alpha\r\n              priorToShiftMode = subMode;\r\n              subMode = Mode.ALPHA_SHIFT;\r\n            } else if (subModeCh == ML) {\r\n              subMode = Mode.MIXED;\r\n            } else if (subModeCh == PS) {\r\n              // Shift to punctuation\r\n              priorToShiftMode = subMode;\r\n              subMode = Mode.PUNCT_SHIFT;\r\n            } else if (subModeCh == MODE_SHIFT_TO_BYTE_COMPACTION_MODE) {\r\n              result.append((char) byteCompactionData[i]);\r\n            } else if (subModeCh == TEXT_COMPACTION_MODE_LATCH) {\r\n              subMode = Mode.ALPHA;\r\n            }\r\n          }\r\n          break;\r\n\r\n        case MIXED:\r\n          // Mixed (numeric and some punctuation)\r\n          if (subModeCh < PL) {\r\n            ch = MIXED_CHARS[subModeCh];\r\n          } else {\r\n            if (subModeCh == PL) {\r\n              subMode = Mode.PUNCT;\r\n            } else if (subModeCh == 26) {\r\n              ch = ' ';\r\n            } else if (subModeCh == LL) {\r\n              subMode = Mode.LOWER;\r\n            } else if (subModeCh == AL) {\r\n              subMode = Mode.ALPHA;\r\n            } else if (subModeCh == PS) {\r\n              // Shift to punctuation\r\n              priorToShiftMode = subMode;\r\n              subMode = Mode.PUNCT_SHIFT;\r\n            } else if (subModeCh == MODE_SHIFT_TO_BYTE_COMPACTION_MODE) {\r\n              result.append((char) byteCompactionData[i]);\r\n            } else if (subModeCh == TEXT_COMPACTION_MODE_LATCH) {\r\n              subMode = Mode.ALPHA;\r\n            }\r\n          }\r\n          break;\r\n\r\n        case PUNCT:\r\n          // Punctuation\r\n          if (subModeCh < PAL) {\r\n            ch = PUNCT_CHARS[subModeCh];\r\n          } else {\r\n            if (subModeCh == PAL) {\r\n              subMode = Mode.ALPHA;\r\n            } else if (subModeCh == MODE_SHIFT_TO_BYTE_COMPACTION_MODE) {\r\n              result.append((char) byteCompactionData[i]);\r\n            } else if (subModeCh == TEXT_COMPACTION_MODE_LATCH) {\r\n              subMode = Mode.ALPHA;\r\n            }\r\n          }\r\n          break;\r\n\r\n        case ALPHA_SHIFT:\r\n          // Restore sub-mode\r\n          subMode = priorToShiftMode;\r\n          if (subModeCh < 26) {\r\n            ch = (char) ('A' + subModeCh);\r\n          } else {\r\n            if (subModeCh == 26) {\r\n              ch = ' ';\r\n            } else if (subModeCh == TEXT_COMPACTION_MODE_LATCH) {\r\n              subMode = Mode.ALPHA;\r\n            }\r\n          }\r\n          break;\r\n\r\n        case PUNCT_SHIFT:\r\n          // Restore sub-mode\r\n          subMode = priorToShiftMode;\r\n          if (subModeCh < PAL) {\r\n            ch = PUNCT_CHARS[subModeCh];\r\n          } else {\r\n            if (subModeCh == PAL) {\r\n              subMode = Mode.ALPHA;\r\n            } else if (subModeCh == MODE_SHIFT_TO_BYTE_COMPACTION_MODE) {\r\n              // PS before Shift-to-Byte is used as a padding character, \r\n              // see 5.4.2.4 of the specification\r\n              result.append((char) byteCompactionData[i]);\r\n            } else if (subModeCh == TEXT_COMPACTION_MODE_LATCH) {\r\n              subMode = Mode.ALPHA;\r\n            }\r\n          }\r\n          break;\r\n      }\r\n      if (ch != 0) {\r\n        // Append decoded character to result\r\n        result.append(ch);\r\n      }\r\n      i++;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Byte Compaction mode (see 5.4.3) permits all 256 possible 8-bit byte values to be encoded.\r\n   * This includes all ASCII characters value 0 to 127 inclusive and provides for international\r\n   * character set support.\r\n   *\r\n   * @param mode      The byte compaction mode i.e. 901 or 924\r\n   * @param codewords The array of codewords (data + error)\r\n   * @param codeIndex The current index into the codeword array.\r\n   * @param result    The decoded data is appended to the result.\r\n   * @return The next index into the codeword array.\r\n   */\r\n  private static int byteCompaction(int mode, int[] codewords, int codeIndex, StringBuilder result) {\r\n    if (mode == BYTE_COMPACTION_MODE_LATCH) {\r\n      // Total number of Byte Compaction characters to be encoded\r\n      // is not a multiple of 6\r\n      int count = 0;\r\n      long value = 0;\r\n      char[] decodedData = new char[6];\r\n      int[] byteCompactedCodewords = new int[6];\r\n      boolean end = false;\r\n      int nextCode = codewords[codeIndex++];\r\n      while ((codeIndex < codewords[0]) && !end) {\r\n        byteCompactedCodewords[count++] = nextCode;\r\n        // Base 900\r\n        value = 900 * value + nextCode;\r\n        nextCode = codewords[codeIndex++];\r\n        // perhaps it should be ok to check only nextCode >= TEXT_COMPACTION_MODE_LATCH\r\n        if (nextCode == TEXT_COMPACTION_MODE_LATCH ||\r\n            nextCode == BYTE_COMPACTION_MODE_LATCH ||\r\n            nextCode == NUMERIC_COMPACTION_MODE_LATCH ||\r\n            nextCode == BYTE_COMPACTION_MODE_LATCH_6 ||\r\n            nextCode == BEGIN_MACRO_PDF417_CONTROL_BLOCK ||\r\n            nextCode == BEGIN_MACRO_PDF417_OPTIONAL_FIELD ||\r\n            nextCode == MACRO_PDF417_TERMINATOR) {\r\n          codeIndex--;\r\n          end = true;\r\n        } else {\r\n          if ((count % 5 == 0) && (count > 0)) {\r\n            // Decode every 5 codewords\r\n            // Convert to Base 256\r\n            for (int j = 0; j < 6; ++j) {\r\n              decodedData[5 - j] = (char) (value % 256);\r\n              value >>= 8;\r\n            }\r\n            result.append(decodedData);\r\n            count = 0;\r\n          }\r\n       }\r\n     }\r\n\r\n     // if the end of all codewords is reached the last codeword needs to be added\r\n     if (codeIndex == codewords[0] && nextCode < TEXT_COMPACTION_MODE_LATCH) {\r\n        byteCompactedCodewords[count++] = nextCode;\r\n     }\r\n\r\n     // If Byte Compaction mode is invoked with codeword 901,\r\n     // the last group of codewords is interpreted directly\r\n     // as one byte per codeword, without compaction.\r\n     for (int i = 0; i < count; i++) {\r\n        result.append((char)byteCompactedCodewords[i]);\r\n     }\r\n\r\n    } else if (mode == BYTE_COMPACTION_MODE_LATCH_6) {\r\n      // Total number of Byte Compaction characters to be encoded\r\n      // is an integer multiple of 6\r\n      int count = 0;\r\n      long value = 0;\r\n      boolean end = false;\r\n      while (codeIndex < codewords[0] && !end) {\r\n        int code = codewords[codeIndex++];\r\n        if (code < TEXT_COMPACTION_MODE_LATCH) {\r\n          count++;\r\n          // Base 900\r\n          value = 900 * value + code;\r\n        } else {\r\n          if (code == TEXT_COMPACTION_MODE_LATCH ||\r\n              code == BYTE_COMPACTION_MODE_LATCH ||\r\n              code == NUMERIC_COMPACTION_MODE_LATCH ||\r\n              code == BYTE_COMPACTION_MODE_LATCH_6 ||\r\n              code == BEGIN_MACRO_PDF417_CONTROL_BLOCK ||\r\n              code == BEGIN_MACRO_PDF417_OPTIONAL_FIELD ||\r\n              code == MACRO_PDF417_TERMINATOR) {\r\n            codeIndex--;\r\n            end = true;\r\n          }\r\n        }\r\n        if ((count % 5 == 0) && (count > 0)) {\r\n          // Decode every 5 codewords\r\n          // Convert to Base 256\r\n          char[] decodedData = new char[6];\r\n          for (int j = 0; j < 6; ++j) {\r\n            decodedData[5 - j] = (char) (value & 0xFF);\r\n            value >>= 8;\r\n          }\r\n          result.append(decodedData);\r\n          count = 0;\r\n        }\r\n      }\r\n    }\r\n    return codeIndex;\r\n  }\r\n\r\n  /**\r\n   * Numeric Compaction mode (see 5.4.4) permits efficient encoding of numeric data strings.\r\n   *\r\n   * @param codewords The array of codewords (data + error)\r\n   * @param codeIndex The current index into the codeword array.\r\n   * @param result    The decoded data is appended to the result.\r\n   * @return The next index into the codeword array.\r\n   */\r\n  private static int numericCompaction(int[] codewords, int codeIndex, StringBuilder result) throws FormatException {\r\n    int count = 0;\r\n    boolean end = false;\r\n\r\n    int[] numericCodewords = new int[MAX_NUMERIC_CODEWORDS];\r\n\r\n    while (codeIndex < codewords[0] && !end) {\r\n      int code = codewords[codeIndex++];\r\n      if (codeIndex == codewords[0]) {\r\n        end = true;\r\n      }\r\n      if (code < TEXT_COMPACTION_MODE_LATCH) {\r\n        numericCodewords[count] = code;\r\n        count++;\r\n      } else {\r\n        if (code == TEXT_COMPACTION_MODE_LATCH ||\r\n            code == BYTE_COMPACTION_MODE_LATCH ||\r\n            code == BYTE_COMPACTION_MODE_LATCH_6 ||\r\n            code == BEGIN_MACRO_PDF417_CONTROL_BLOCK ||\r\n            code == BEGIN_MACRO_PDF417_OPTIONAL_FIELD ||\r\n            code == MACRO_PDF417_TERMINATOR) {\r\n          codeIndex--;\r\n          end = true;          \r\n        }\r\n      }\r\n      if (count % MAX_NUMERIC_CODEWORDS == 0 ||\r\n          code == NUMERIC_COMPACTION_MODE_LATCH ||\r\n          end) {\r\n        // Re-invoking Numeric Compaction mode (by using codeword 902\r\n        // while in Numeric Compaction mode) serves  to terminate the\r\n        // current Numeric Compaction mode grouping as described in 5.4.4.2,\r\n        // and then to start a new one grouping.\r\n        String s = decodeBase900toBase10(numericCodewords, count);\r\n        result.append(s);\r\n        count = 0;\r\n      }\r\n    }\r\n    return codeIndex;\r\n  }\r\n\r\n  /**\r\n   * Convert a list of Numeric Compacted codewords from Base 900 to Base 10.\r\n   *\r\n   * @param codewords The array of codewords\r\n   * @param count     The number of codewords\r\n   * @return The decoded string representing the Numeric data.\r\n   */\r\n  /*\r\n     EXAMPLE\r\n     Encode the fifteen digit numeric string 000213298174000\r\n     Prefix the numeric string with a 1 and set the initial value of\r\n     t = 1 000 213 298 174 000\r\n     Calculate codeword 0\r\n     d0 = 1 000 213 298 174 000 mod 900 = 200\r\n\r\n     t = 1 000 213 298 174 000 div 900 = 1 111 348 109 082\r\n     Calculate codeword 1\r\n     d1 = 1 111 348 109 082 mod 900 = 282\r\n\r\n     t = 1 111 348 109 082 div 900 = 1 234 831 232\r\n     Calculate codeword 2\r\n     d2 = 1 234 831 232 mod 900 = 632\r\n\r\n     t = 1 234 831 232 div 900 = 1 372 034\r\n     Calculate codeword 3\r\n     d3 = 1 372 034 mod 900 = 434\r\n\r\n     t = 1 372 034 div 900 = 1 524\r\n     Calculate codeword 4\r\n     d4 = 1 524 mod 900 = 624\r\n\r\n     t = 1 524 div 900 = 1\r\n     Calculate codeword 5\r\n     d5 = 1 mod 900 = 1\r\n     t = 1 div 900 = 0\r\n     Codeword sequence is: 1, 624, 434, 632, 282, 200\r\n\r\n     Decode the above codewords involves\r\n       1 x 900 power of 5 + 624 x 900 power of 4 + 434 x 900 power of 3 +\r\n     632 x 900 power of 2 + 282 x 900 power of 1 + 200 x 900 power of 0 = 1000213298174000\r\n\r\n     Remove leading 1 =>  Result is 000213298174000\r\n   */\r\n  private static String decodeBase900toBase10(int[] codewords, int count) throws FormatException {\r\n    BigInteger result = BigInteger.ZERO;\r\n    for (int i = 0; i < count; i++) {\r\n      result = result.add(EXP900[count - i - 1].multiply(BigInteger.valueOf(codewords[i])));\r\n    }\r\n    String resultString = result.toString();\r\n    if (resultString.charAt(0) != '1') {\r\n      throw FormatException.getFormatInstance();\r\n    }\r\n    return resultString.substring(1);\r\n  }\r\n\r\n}\r\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/pdf417/decoder/Decoder.java",
    "content": "/*\r\n * Copyright 2009 ZXing authors\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage com.google.zxing.pdf417.decoder;\r\n\r\nimport com.google.zxing.ChecksumException;\r\nimport com.google.zxing.FormatException;\r\nimport com.google.zxing.common.BitMatrix;\r\nimport com.google.zxing.common.DecoderResult;\r\nimport com.google.zxing.pdf417.decoder.ec.ErrorCorrection;\r\n\r\n/**\r\n * <p>The main class which implements PDF417 Code decoding -- as\r\n * opposed to locating and extracting the PDF417 Code from an image.</p>\r\n *\r\n * @author SITA Lab (kevin.osullivan@sita.aero)\r\n */\r\npublic final class Decoder {\r\n\r\n  private static final int MAX_ERRORS = 3;\r\n  private static final int MAX_EC_CODEWORDS = 512;\r\n  private final ErrorCorrection errorCorrection;\r\n\r\n  public Decoder() {\r\n    errorCorrection = new ErrorCorrection();\r\n  }\r\n\r\n  /**\r\n   * <p>Convenience method that can decode a PDF417 Code represented as a 2D array of booleans.\r\n   * \"true\" is taken to mean a black module.</p>\r\n   *\r\n   * @param image booleans representing white/black PDF417 modules\r\n   * @return text and bytes encoded within the PDF417 Code\r\n   */\r\n  public DecoderResult decode(boolean[][] image) throws FormatException, ChecksumException {\r\n    int dimension = image.length;\r\n    BitMatrix bits = new BitMatrix(dimension);\r\n    for (int i = 0; i < dimension; i++) {\r\n      for (int j = 0; j < dimension; j++) {\r\n        if (image[j][i]) {\r\n          bits.set(j, i);\r\n        }\r\n      }\r\n    }\r\n    return decode(bits);\r\n  }\r\n\r\n  /**\r\n   * <p>Decodes a PDF417 Code represented as a {@link BitMatrix}.\r\n   * A 1 or \"true\" is taken to mean a black module.</p>\r\n   *\r\n   * @param bits booleans representing white/black PDF417 Code modules\r\n   * @return text and bytes encoded within the PDF417 Code\r\n   * @throws FormatException if the PDF417 Code cannot be decoded\r\n   */\r\n  public DecoderResult decode(BitMatrix bits) throws FormatException, ChecksumException {\r\n    // Construct a parser to read the data codewords and error-correction level\r\n    BitMatrixParser parser = new BitMatrixParser(bits);\r\n    int[] codewords = parser.readCodewords();\r\n    if (codewords.length == 0) {\r\n      throw FormatException.getFormatInstance();\r\n    }\r\n\r\n    int ecLevel = parser.getECLevel();\r\n    int numECCodewords = 1 << (ecLevel + 1);\r\n    int[] erasures = parser.getErasures();\r\n\r\n    correctErrors(codewords, erasures, numECCodewords);\r\n    verifyCodewordCount(codewords, numECCodewords);\r\n\r\n    // Decode the codewords\r\n    return DecodedBitStreamParser.decode(codewords);\r\n  }\r\n\r\n  /**\r\n   * Verify that all is OK with the codeword array.\r\n   *\r\n   * @param codewords\r\n   * @return an index to the first data codeword.\r\n   */\r\n  private static void verifyCodewordCount(int[] codewords, int numECCodewords) throws FormatException {\r\n    if (codewords.length < 4) {\r\n      // Codeword array size should be at least 4 allowing for\r\n      // Count CW, At least one Data CW, Error Correction CW, Error Correction CW\r\n      throw FormatException.getFormatInstance();\r\n    }\r\n    // The first codeword, the Symbol Length Descriptor, shall always encode the total number of data\r\n    // codewords in the symbol, including the Symbol Length Descriptor itself, data codewords and pad\r\n    // codewords, but excluding the number of error correction codewords.\r\n    int numberOfCodewords = codewords[0];\r\n    if (numberOfCodewords > codewords.length) {\r\n      throw FormatException.getFormatInstance();\r\n    }\r\n    if (numberOfCodewords == 0) {\r\n      // Reset to the length of the array - 8 (Allow for at least level 3 Error Correction (8 Error Codewords)\r\n      if (numECCodewords < codewords.length) {\r\n        codewords[0] = codewords.length - numECCodewords;\r\n      } else {\r\n        throw FormatException.getFormatInstance();\r\n      }\r\n    }\r\n  }\r\n\r\n  /**\r\n   * <p>Given data and error-correction codewords received, possibly corrupted by errors, attempts to\r\n   * correct the errors in-place.</p>\r\n   *\r\n   * @param codewords   data and error correction codewords\r\n   * @param erasures positions of any known erasures\r\n   * @param numECCodewords number of error correction codewards that were available in codewords\r\n   * @throws ChecksumException if error correction fails\r\n   */\r\n  private void correctErrors(int[] codewords,\r\n                             int[] erasures,\r\n                             int numECCodewords) throws ChecksumException {\r\n    if (erasures.length > numECCodewords / 2 + MAX_ERRORS ||\r\n        numECCodewords < 0 || numECCodewords > MAX_EC_CODEWORDS) {\r\n      // Too many errors or EC Codewords is corrupted\r\n      throw ChecksumException.getChecksumInstance();\r\n    }\r\n    errorCorrection.decode(codewords, numECCodewords, erasures);\r\n  }\r\n\r\n}\r\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/pdf417/decoder/ec/ErrorCorrection.java",
    "content": "/*\n * Copyright 2012 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.pdf417.decoder.ec;\n\nimport com.google.zxing.ChecksumException;\n\n/**\n * <p>PDF417 error correction implementation.</p>\n *\n * <p>This <a href=\"http://en.wikipedia.org/wiki/Reed%E2%80%93Solomon_error_correction#Example\">example</a>\n * is quite useful in understanding the algorithm.</p>\n *\n * @author Sean Owen\n * @see com.google.zxing.common.reedsolomon.ReedSolomonDecoder\n */\npublic final class ErrorCorrection {\n\n  private final ModulusGF field;\n\n  public ErrorCorrection() {\n    this.field = ModulusGF.PDF417_GF;\n  }\n\n  public void decode(int[] received,\n                     int numECCodewords,\n                     int[] erasures) throws ChecksumException {\n\n    ModulusPoly poly = new ModulusPoly(field, received);\n    int[] S = new int[numECCodewords];\n    boolean error = false;\n    for (int i = numECCodewords; i > 0; i--) {\n      int eval = poly.evaluateAt(field.exp(i));\n      S[numECCodewords - i] = eval;\n      if (eval != 0) {\n        error = true;\n      }\n    }\n\n    if (error) {\n\n      ModulusPoly knownErrors = field.getOne();\n      for (int erasure : erasures) {\n        int b = field.exp(received.length - 1 - erasure);\n        // Add (1 - bx) term:\n        ModulusPoly term = new ModulusPoly(field, new int[] { field.subtract(0, b), 1 });\n        knownErrors = knownErrors.multiply(term);\n      }\n\n      ModulusPoly syndrome = new ModulusPoly(field, S);\n      //syndrome = syndrome.multiply(knownErrors);\n\n      ModulusPoly[] sigmaOmega =\n          runEuclideanAlgorithm(field.buildMonomial(numECCodewords, 1), syndrome, numECCodewords);\n      ModulusPoly sigma = sigmaOmega[0];\n      ModulusPoly omega = sigmaOmega[1];\n\n      //sigma = sigma.multiply(knownErrors);\n\n      int[] errorLocations = findErrorLocations(sigma);\n      int[] errorMagnitudes = findErrorMagnitudes(omega, sigma, errorLocations);\n\n      for (int i = 0; i < errorLocations.length; i++) {\n        int position = received.length - 1 - field.log(errorLocations[i]);\n        if (position < 0) {\n          throw ChecksumException.getChecksumInstance();\n        }\n        received[position] = field.subtract(received[position], errorMagnitudes[i]);\n      }\n    }\n  }\n\n  private ModulusPoly[] runEuclideanAlgorithm(ModulusPoly a, ModulusPoly b, int R)\n      throws ChecksumException {\n    // Assume a's degree is >= b's\n    if (a.getDegree() < b.getDegree()) {\n      ModulusPoly temp = a;\n      a = b;\n      b = temp;\n    }\n\n    ModulusPoly rLast = a;\n    ModulusPoly r = b;\n    ModulusPoly tLast = field.getZero();\n    ModulusPoly t = field.getOne();\n\n    // Run Euclidean algorithm until r's degree is less than R/2\n    while (r.getDegree() >= R / 2) {\n      ModulusPoly rLastLast = rLast;\n      ModulusPoly tLastLast = tLast;\n      rLast = r;\n      tLast = t;\n\n      // Divide rLastLast by rLast, with quotient in q and remainder in r\n      if (rLast.isZero()) {\n        // Oops, Euclidean algorithm already terminated?\n        throw ChecksumException.getChecksumInstance();\n      }\n      r = rLastLast;\n      ModulusPoly q = field.getZero();\n      int denominatorLeadingTerm = rLast.getCoefficient(rLast.getDegree());\n      int dltInverse = field.inverse(denominatorLeadingTerm);\n      while (r.getDegree() >= rLast.getDegree() && !r.isZero()) {\n        int degreeDiff = r.getDegree() - rLast.getDegree();\n        int scale = field.multiply(r.getCoefficient(r.getDegree()), dltInverse);\n        q = q.add(field.buildMonomial(degreeDiff, scale));\n        r = r.subtract(rLast.multiplyByMonomial(degreeDiff, scale));\n      }\n\n      t = q.multiply(tLast).subtract(tLastLast).negative();\n    }\n\n    int sigmaTildeAtZero = t.getCoefficient(0);\n    if (sigmaTildeAtZero == 0) {\n      throw ChecksumException.getChecksumInstance();\n    }\n\n    int inverse = field.inverse(sigmaTildeAtZero);\n    ModulusPoly sigma = t.multiply(inverse);\n    ModulusPoly omega = r.multiply(inverse);\n    return new ModulusPoly[]{sigma, omega};\n  }\n\n  private int[] findErrorLocations(ModulusPoly errorLocator) throws ChecksumException {\n    // This is a direct application of Chien's search\n    int numErrors = errorLocator.getDegree();\n    int[] result = new int[numErrors];\n    int e = 0;\n    for (int i = 1; i < field.getSize() && e < numErrors; i++) {\n      if (errorLocator.evaluateAt(i) == 0) {\n        result[e] = field.inverse(i);\n        e++;\n      }\n    }\n    if (e != numErrors) {\n      throw ChecksumException.getChecksumInstance();\n    }\n    return result;\n  }\n\n  private int[] findErrorMagnitudes(ModulusPoly errorEvaluator,\n                                    ModulusPoly errorLocator,\n                                    int[] errorLocations) {\n    int errorLocatorDegree = errorLocator.getDegree();\n    int[] formalDerivativeCoefficients = new int[errorLocatorDegree];\n    for (int i = 1; i <= errorLocatorDegree; i++) {\n      formalDerivativeCoefficients[errorLocatorDegree - i] =\n          field.multiply(i, errorLocator.getCoefficient(i));\n    }\n    ModulusPoly formalDerivative = new ModulusPoly(field, formalDerivativeCoefficients);\n\n    // This is directly applying Forney's Formula\n    int s = errorLocations.length;\n    int[] result = new int[s];\n    for (int i = 0; i < s; i++) {\n      int xiInverse = field.inverse(errorLocations[i]);\n      int numerator = field.subtract(0, errorEvaluator.evaluateAt(xiInverse));\n      int denominator = field.inverse(formalDerivative.evaluateAt(xiInverse));\n      result[i] = field.multiply(numerator, denominator);\n    }\n    return result;\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/pdf417/decoder/ec/ModulusGF.java",
    "content": "/*\n * Copyright 2012 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.pdf417.decoder.ec;\n\n/**\n * <p>A field based on powers of a generator integer, modulo some modulus.</p>\n *\n * @author Sean Owen\n * @see com.google.zxing.common.reedsolomon.GenericGF\n */\npublic final class ModulusGF {\n\n  public static final ModulusGF PDF417_GF = new ModulusGF(929, 3);\n\n  private final int[] expTable;\n  private final int[] logTable;\n  private final ModulusPoly zero;\n  private final ModulusPoly one;\n  private final int modulus;\n\n  public ModulusGF(int modulus, int generator) {\n    this.modulus = modulus;\n    expTable = new int[modulus];\n    logTable = new int[modulus];\n    int x = 1;\n    for (int i = 0; i < modulus; i++) {\n      expTable[i] = x;\n      x = (x * generator) % modulus;\n    }\n    for (int i = 0; i < modulus-1; i++) {\n      logTable[expTable[i]] = i;\n    }\n    // logTable[0] == 0 but this should never be used\n    zero = new ModulusPoly(this, new int[]{0});\n    one = new ModulusPoly(this, new int[]{1});\n  }\n\n\n  ModulusPoly getZero() {\n    return zero;\n  }\n\n  ModulusPoly getOne() {\n    return one;\n  }\n\n  ModulusPoly buildMonomial(int degree, int coefficient) {\n    if (degree < 0) {\n      throw new IllegalArgumentException();\n    }\n    if (coefficient == 0) {\n      return zero;\n    }\n    int[] coefficients = new int[degree + 1];\n    coefficients[0] = coefficient;\n    return new ModulusPoly(this, coefficients);\n  }\n\n  int add(int a, int b) {\n    return (a + b) % modulus;\n  }\n\n  int subtract(int a, int b) {\n    return (modulus + a - b) % modulus;\n  }\n\n  int exp(int a) {\n    return expTable[a];\n  }\n\n  int log(int a) {\n    if (a == 0) {\n      throw new IllegalArgumentException();\n    }\n    return logTable[a];\n  }\n\n  int inverse(int a) {\n    if (a == 0) {\n      throw new ArithmeticException();\n    }\n    return expTable[modulus - logTable[a] - 1];\n  }\n\n  int multiply(int a, int b) {\n    if (a == 0 || b == 0) {\n      return 0;\n    }\n    return expTable[(logTable[a] + logTable[b]) % (modulus - 1)];\n  }\n\n  int getSize() {\n    return modulus;\n  }\n  \n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/pdf417/decoder/ec/ModulusPoly.java",
    "content": "/*\n * Copyright 2012 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.pdf417.decoder.ec;\n\n/**\n * @author Sean Owen\n * @see com.google.zxing.common.reedsolomon.GenericGFPoly\n */\nfinal class ModulusPoly {\n\n  private final ModulusGF field;\n  private final int[] coefficients;\n\n  ModulusPoly(ModulusGF field, int[] coefficients) {\n    if (coefficients.length == 0) {\n      throw new IllegalArgumentException();\n    }\n    this.field = field;\n    int coefficientsLength = coefficients.length;\n    if (coefficientsLength > 1 && coefficients[0] == 0) {\n      // Leading term must be non-zero for anything except the constant polynomial \"0\"\n      int firstNonZero = 1;\n      while (firstNonZero < coefficientsLength && coefficients[firstNonZero] == 0) {\n        firstNonZero++;\n      }\n      if (firstNonZero == coefficientsLength) {\n        this.coefficients = field.getZero().coefficients;\n      } else {\n        this.coefficients = new int[coefficientsLength - firstNonZero];\n        System.arraycopy(coefficients,\n            firstNonZero,\n            this.coefficients,\n            0,\n            this.coefficients.length);\n      }\n    } else {\n      this.coefficients = coefficients;\n    }\n  }\n\n  int[] getCoefficients() {\n    return coefficients;\n  }\n\n  /**\n   * @return degree of this polynomial\n   */\n  int getDegree() {\n    return coefficients.length - 1;\n  }\n\n  /**\n   * @return true iff this polynomial is the monomial \"0\"\n   */\n  boolean isZero() {\n    return coefficients[0] == 0;\n  }\n\n  /**\n   * @return coefficient of x^degree term in this polynomial\n   */\n  int getCoefficient(int degree) {\n    return coefficients[coefficients.length - 1 - degree];\n  }\n\n  /**\n   * @return evaluation of this polynomial at a given point\n   */\n  int evaluateAt(int a) {\n    if (a == 0) {\n      // Just return the x^0 coefficient\n      return getCoefficient(0);\n    }\n    int size = coefficients.length;\n    if (a == 1) {\n      // Just the sum of the coefficients\n      int result = 0;\n      for (int coefficient : coefficients) {\n        result = field.add(result, coefficient);\n      }\n      return result;\n    }\n    int result = coefficients[0];\n    for (int i = 1; i < size; i++) {\n      result = field.add(field.multiply(a, result), coefficients[i]);\n    }\n    return result;\n  }\n\n  ModulusPoly add(ModulusPoly other) {\n    if (!field.equals(other.field)) {\n      throw new IllegalArgumentException(\"ModulusPolys do not have same ModulusGF field\");\n    }\n    if (isZero()) {\n      return other;\n    }\n    if (other.isZero()) {\n      return this;\n    }\n\n    int[] smallerCoefficients = this.coefficients;\n    int[] largerCoefficients = other.coefficients;\n    if (smallerCoefficients.length > largerCoefficients.length) {\n      int[] temp = smallerCoefficients;\n      smallerCoefficients = largerCoefficients;\n      largerCoefficients = temp;\n    }\n    int[] sumDiff = new int[largerCoefficients.length];\n    int lengthDiff = largerCoefficients.length - smallerCoefficients.length;\n    // Copy high-order terms only found in higher-degree polynomial's coefficients\n    System.arraycopy(largerCoefficients, 0, sumDiff, 0, lengthDiff);\n\n    for (int i = lengthDiff; i < largerCoefficients.length; i++) {\n      sumDiff[i] = field.add(smallerCoefficients[i - lengthDiff], largerCoefficients[i]);\n    }\n\n    return new ModulusPoly(field, sumDiff);\n  }\n\n  ModulusPoly subtract(ModulusPoly other) {\n    if (!field.equals(other.field)) {\n      throw new IllegalArgumentException(\"ModulusPolys do not have same ModulusGF field\");\n    }\n    if (other.isZero()) {\n      return this;\n    }\n    return add(other.negative());\n  }\n\n  ModulusPoly multiply(ModulusPoly other) {\n    if (!field.equals(other.field)) {\n      throw new IllegalArgumentException(\"ModulusPolys do not have same ModulusGF field\");\n    }\n    if (isZero() || other.isZero()) {\n      return field.getZero();\n    }\n    int[] aCoefficients = this.coefficients;\n    int aLength = aCoefficients.length;\n    int[] bCoefficients = other.coefficients;\n    int bLength = bCoefficients.length;\n    int[] product = new int[aLength + bLength - 1];\n    for (int i = 0; i < aLength; i++) {\n      int aCoeff = aCoefficients[i];\n      for (int j = 0; j < bLength; j++) {\n        product[i + j] = field.add(product[i + j], field.multiply(aCoeff, bCoefficients[j]));\n      }\n    }\n    return new ModulusPoly(field, product);\n  }\n\n  ModulusPoly negative() {\n    int size = coefficients.length;\n    int[] negativeCoefficients = new int[size];\n    for (int i = 0; i < size; i++) {\n      negativeCoefficients[i] = field.subtract(0, coefficients[i]);\n    }\n    return new ModulusPoly(field, negativeCoefficients);\n  }\n\n  ModulusPoly multiply(int scalar) {\n    if (scalar == 0) {\n      return field.getZero();\n    }\n    if (scalar == 1) {\n      return this;\n    }\n    int size = coefficients.length;\n    int[] product = new int[size];\n    for (int i = 0; i < size; i++) {\n      product[i] = field.multiply(coefficients[i], scalar);\n    }\n    return new ModulusPoly(field, product);\n  }\n\n  ModulusPoly multiplyByMonomial(int degree, int coefficient) {\n    if (degree < 0) {\n      throw new IllegalArgumentException();\n    }\n    if (coefficient == 0) {\n      return field.getZero();\n    }\n    int size = coefficients.length;\n    int[] product = new int[size + degree];\n    for (int i = 0; i < size; i++) {\n      product[i] = field.multiply(coefficients[i], coefficient);\n    }\n    return new ModulusPoly(field, product);\n  }\n\n  ModulusPoly[] divide(ModulusPoly other) {\n    if (!field.equals(other.field)) {\n      throw new IllegalArgumentException(\"ModulusPolys do not have same ModulusGF field\");\n    }\n    if (other.isZero()) {\n      throw new IllegalArgumentException(\"Divide by 0\");\n    }\n\n    ModulusPoly quotient = field.getZero();\n    ModulusPoly remainder = this;\n\n    int denominatorLeadingTerm = other.getCoefficient(other.getDegree());\n    int inverseDenominatorLeadingTerm = field.inverse(denominatorLeadingTerm);\n\n    while (remainder.getDegree() >= other.getDegree() && !remainder.isZero()) {\n      int degreeDifference = remainder.getDegree() - other.getDegree();\n      int scale = field.multiply(remainder.getCoefficient(remainder.getDegree()), inverseDenominatorLeadingTerm);\n      ModulusPoly term = other.multiplyByMonomial(degreeDifference, scale);\n      ModulusPoly iterationQuotient = field.buildMonomial(degreeDifference, scale);\n      quotient = quotient.add(iterationQuotient);\n      remainder = remainder.subtract(term);\n    }\n\n    return new ModulusPoly[] { quotient, remainder };\n  }\n\n  @Override\n  public String toString() {\n    StringBuilder result = new StringBuilder(8 * getDegree());\n    for (int degree = getDegree(); degree >= 0; degree--) {\n      int coefficient = getCoefficient(degree);\n      if (coefficient != 0) {\n        if (coefficient < 0) {\n          result.append(\" - \");\n          coefficient = -coefficient;\n        } else {\n          if (result.length() > 0) {\n            result.append(\" + \");\n          }\n        }\n        if (degree == 0 || coefficient != 1) {\n          result.append(coefficient);\n        }\n        if (degree != 0) {\n          if (degree == 1) {\n            result.append('x');\n          } else {\n            result.append(\"x^\");\n            result.append(degree);\n          }\n        }\n      }\n    }\n    return result.toString();\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/pdf417/detector/Detector.java",
    "content": "/*\n * Copyright 2009 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.pdf417.detector;\n\nimport com.google.zxing.BinaryBitmap;\nimport com.google.zxing.DecodeHintType;\nimport com.google.zxing.NotFoundException;\nimport com.google.zxing.ResultPoint;\nimport com.google.zxing.common.BitMatrix;\nimport com.google.zxing.common.DetectorResult;\nimport com.google.zxing.common.GridSampler;\nimport com.google.zxing.common.detector.MathUtils;\n\nimport java.util.Arrays;\nimport java.util.Map;\n\n/**\n * <p>Encapsulates logic that can detect a PDF417 Code in an image, even if the\n * PDF417 Code is rotated or skewed, or partially obscured.</p>\n *\n * @author SITA Lab (kevin.osullivan@sita.aero)\n * @author dswitkin@google.com (Daniel Switkin)\n */\npublic final class Detector {\n\n  private static final int INTEGER_MATH_SHIFT = 8;\n  private static final int PATTERN_MATCH_RESULT_SCALE_FACTOR = 1 << INTEGER_MATH_SHIFT;\n  private static final int MAX_AVG_VARIANCE = (int) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.42f);\n  private static final int MAX_INDIVIDUAL_VARIANCE = (int) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.8f);\n  private static final int SKEW_THRESHOLD = 3;\n\n  // B S B S B S B S Bar/Space pattern\n  // 11111111 0 1 0 1 0 1 000\n  private static final int[] START_PATTERN = {8, 1, 1, 1, 1, 1, 1, 3};\n\n  // 11111111 0 1 0 1 0 1 000\n  private static final int[] START_PATTERN_REVERSE = {3, 1, 1, 1, 1, 1, 1, 8};\n\n  // 1111111 0 1 000 1 0 1 00 1\n  private static final int[] STOP_PATTERN = {7, 1, 1, 3, 1, 1, 1, 2, 1};\n\n  // B S B S B S B S B Bar/Space pattern\n  // 1111111 0 1 000 1 0 1 00 1\n  private static final int[] STOP_PATTERN_REVERSE = {1, 2, 1, 1, 1, 3, 1, 1, 7};\n\n  private final BinaryBitmap image;\n\n  public Detector(BinaryBitmap image) {\n    this.image = image;\n  }\n\n  /**\n   * <p>Detects a PDF417 Code in an image, simply.</p>\n   *\n   * @return {@link DetectorResult} encapsulating results of detecting a PDF417 Code\n   * @throws NotFoundException if no QR Code can be found\n   */\n  public DetectorResult detect() throws NotFoundException {\n    return detect(null);\n  }\n\n  /**\n   * <p>Detects a PDF417 Code in an image. Only checks 0 and 180 degree rotations.</p>\n   *\n   * @param hints optional hints to detector\n   * @return {@link DetectorResult} encapsulating results of detecting a PDF417 Code\n   * @throws NotFoundException if no PDF417 Code can be found\n   */\n  public DetectorResult detect(Map<DecodeHintType,?> hints) throws NotFoundException {\n    // Fetch the 1 bit matrix once up front.\n    BitMatrix matrix = image.getBlackMatrix();\n\n    boolean tryHarder = hints != null && hints.containsKey(DecodeHintType.TRY_HARDER);\n\n    // Try to find the vertices assuming the image is upright.\n    ResultPoint[] vertices = findVertices(matrix, tryHarder);\n    if (vertices == null) {\n      // Maybe the image is rotated 180 degrees?\n      vertices = findVertices180(matrix, tryHarder);\n      if (vertices != null) {\n        correctCodeWordVertices(vertices, true);\n      }\n    } else {\n      correctCodeWordVertices(vertices, false);\n    }\n\n    if (vertices == null) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n\n    float moduleWidth = computeModuleWidth(vertices);\n    if (moduleWidth < 1.0f) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n\n    int dimension = computeDimension(vertices[4], vertices[6],\n        vertices[5], vertices[7], moduleWidth);\n    if (dimension < 1) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n\n    int ydimension = computeYDimension(vertices[4], vertices[6], vertices[5], vertices[7], moduleWidth);\n    ydimension = ydimension > dimension ? ydimension : dimension;\n\n    // Deskew and sample image.\n    BitMatrix bits = sampleGrid(matrix, vertices[4], vertices[5], vertices[6], vertices[7], dimension, ydimension);\n    return new DetectorResult(bits, new ResultPoint[]{vertices[5], vertices[4], vertices[6], vertices[7]});\n  }\n\n  /**\n   * Locate the vertices and the codewords area of a black blob using the Start\n   * and Stop patterns as locators.\n   *\n   * @param matrix the scanned barcode image.\n   * @return an array containing the vertices:\n   *           vertices[0] x, y top left barcode\n   *           vertices[1] x, y bottom left barcode\n   *           vertices[2] x, y top right barcode\n   *           vertices[3] x, y bottom right barcode\n   *           vertices[4] x, y top left codeword area\n   *           vertices[5] x, y bottom left codeword area\n   *           vertices[6] x, y top right codeword area\n   *           vertices[7] x, y bottom right codeword area\n   */\n  private static ResultPoint[] findVertices(BitMatrix matrix, boolean tryHarder) {\n    int height = matrix.getHeight();\n    int width = matrix.getWidth();\n\n    ResultPoint[] result = new ResultPoint[8];\n    boolean found = false;\n\n    int[] counters = new int[START_PATTERN.length];\n\n    int rowStep = Math.max(1, height >> (tryHarder ? 9 : 7));\n\n    // Top Left\n    for (int i = 0; i < height; i += rowStep) {\n      int[] loc = findGuardPattern(matrix, 0, i, width, false, START_PATTERN, counters);\n      if (loc != null) {\n        result[0] = new ResultPoint(loc[0], i);\n        result[4] = new ResultPoint(loc[1], i);\n        found = true;\n        break;\n      }\n    }\n    // Bottom left\n    if (found) { // Found the Top Left vertex\n      found = false;\n      for (int i = height - 1; i > 0; i -= rowStep) {\n        int[] loc = findGuardPattern(matrix, 0, i, width, false, START_PATTERN, counters);\n        if (loc != null) {\n          result[1] = new ResultPoint(loc[0], i);\n          result[5] = new ResultPoint(loc[1], i);\n          found = true;\n          break;\n        }\n      }\n    }\n\n    counters = new int[STOP_PATTERN.length];\n\n    // Top right\n    if (found) { // Found the Bottom Left vertex\n      found = false;\n      for (int i = 0; i < height; i += rowStep) {\n        int[] loc = findGuardPattern(matrix, 0, i, width, false, STOP_PATTERN, counters);\n        if (loc != null) {\n          result[2] = new ResultPoint(loc[1], i);\n          result[6] = new ResultPoint(loc[0], i);\n          found = true;\n          break;\n        }\n      }\n    }\n    // Bottom right\n    if (found) { // Found the Top right vertex\n      found = false;\n      for (int i = height - 1; i > 0; i -= rowStep) {\n        int[] loc = findGuardPattern(matrix, 0, i, width, false, STOP_PATTERN, counters);\n        if (loc != null) {\n          result[3] = new ResultPoint(loc[1], i);\n          result[7] = new ResultPoint(loc[0], i);\n          found = true;\n          break;\n        }\n      }\n    }\n    return found ? result : null;\n  }\n\n  /**\n   * Locate the vertices and the codewords area of a black blob using the Start\n   * and Stop patterns as locators. This assumes that the image is rotated 180\n   * degrees and if it locates the start and stop patterns at it will re-map\n   * the vertices for a 0 degree rotation.\n   * TODO: Change assumption about barcode location.\n   *\n   * @param matrix the scanned barcode image.\n   * @return an array containing the vertices:\n   *           vertices[0] x, y top left barcode\n   *           vertices[1] x, y bottom left barcode\n   *           vertices[2] x, y top right barcode\n   *           vertices[3] x, y bottom right barcode\n   *           vertices[4] x, y top left codeword area\n   *           vertices[5] x, y bottom left codeword area\n   *           vertices[6] x, y top right codeword area\n   *           vertices[7] x, y bottom right codeword area\n   */\n  private static ResultPoint[] findVertices180(BitMatrix matrix, boolean tryHarder) {\n    int height = matrix.getHeight();\n    int width = matrix.getWidth();\n    int halfWidth = width >> 1;\n\n    ResultPoint[] result = new ResultPoint[8];\n    boolean found = false;\n\n    int[] counters = new int[START_PATTERN_REVERSE.length];\n\n    int rowStep = Math.max(1, height >> (tryHarder ? 9 : 7));\n\n    // Top Left\n    for (int i = height - 1; i > 0; i -= rowStep) {\n      int[] loc = findGuardPattern(matrix, halfWidth, i, halfWidth, true, START_PATTERN_REVERSE, counters);\n      if (loc != null) {\n        result[0] = new ResultPoint(loc[1], i);\n        result[4] = new ResultPoint(loc[0], i);\n        found = true;\n        break;\n      }\n    }\n    // Bottom Left\n    if (found) { // Found the Top Left vertex\n      found = false;\n      for (int i = 0; i < height; i += rowStep) {\n        int[] loc = findGuardPattern(matrix, halfWidth, i, halfWidth, true, START_PATTERN_REVERSE, counters);\n        if (loc != null) {\n          result[1] = new ResultPoint(loc[1], i);\n          result[5] = new ResultPoint(loc[0], i);\n          found = true;\n          break;\n        }\n      }\n    }\n    \n    counters = new int[STOP_PATTERN_REVERSE.length];\n    \n    // Top Right\n    if (found) { // Found the Bottom Left vertex\n      found = false;\n      for (int i = height - 1; i > 0; i -= rowStep) {\n        int[] loc = findGuardPattern(matrix, 0, i, halfWidth, false, STOP_PATTERN_REVERSE, counters);\n        if (loc != null) {\n          result[2] = new ResultPoint(loc[0], i);\n          result[6] = new ResultPoint(loc[1], i);\n          found = true;\n          break;\n        }\n      }\n    }\n    // Bottom Right\n    if (found) { // Found the Top Right vertex\n      found = false;\n      for (int i = 0; i < height; i += rowStep) {\n        int[] loc = findGuardPattern(matrix, 0, i, halfWidth, false, STOP_PATTERN_REVERSE, counters);\n        if (loc != null) {\n          result[3] = new ResultPoint(loc[0], i);\n          result[7] = new ResultPoint(loc[1], i);\n          found = true;\n          break;\n        }\n      }\n    }\n    return found ? result : null;\n  }\n\n  /**\n   * Because we scan horizontally to detect the start and stop patterns, the vertical component of\n   * the codeword coordinates will be slightly wrong if there is any skew or rotation in the image.\n   * This method moves those points back onto the edges of the theoretically perfect bounding\n   * quadrilateral if needed.\n   *\n   * @param vertices The eight vertices located by findVertices().\n   */\n  private static void correctCodeWordVertices(ResultPoint[] vertices, boolean upsideDown) {\n\n    float v0x = vertices[0].getX();\n    float v0y = vertices[0].getY();\n    float v2x = vertices[2].getX();\n    float v2y = vertices[2].getY();\n    float v4x = vertices[4].getX();\n    float v4y = vertices[4].getY();\n    float v6x = vertices[6].getX();\n    float v6y = vertices[6].getY();\n\n    float skew = v4y - v6y;\n    if (upsideDown) {\n      skew = -skew;\n    }\n    if (skew > SKEW_THRESHOLD) {\n      // Fix v4\n      float deltax = v6x - v0x;\n      float deltay = v6y - v0y;\n      float delta2 = deltax * deltax + deltay * deltay;\n      float correction = (v4x - v0x) * deltax / delta2;\n      vertices[4] = new ResultPoint(v0x + correction * deltax, v0y + correction * deltay);\n    } else if (-skew > SKEW_THRESHOLD) {\n      // Fix v6\n      float deltax = v2x - v4x;\n      float deltay = v2y - v4y;\n      float delta2 = deltax * deltax + deltay * deltay;\n      float correction = (v2x - v6x) * deltax / delta2;\n      vertices[6] = new ResultPoint(v2x - correction * deltax, v2y - correction * deltay);\n    }\n\n    float v1x = vertices[1].getX();\n    float v1y = vertices[1].getY();\n    float v3x = vertices[3].getX();\n    float v3y = vertices[3].getY();\n    float v5x = vertices[5].getX();\n    float v5y = vertices[5].getY();\n    float v7x = vertices[7].getX();\n    float v7y = vertices[7].getY();\n\n    skew = v7y - v5y;\n    if (upsideDown) {\n      skew = -skew;\n    }\n    if (skew > SKEW_THRESHOLD) {\n      // Fix v5\n      float deltax = v7x - v1x;\n      float deltay = v7y - v1y;\n      float delta2 = deltax * deltax + deltay * deltay;\n      float correction = (v5x - v1x) * deltax / delta2;\n      vertices[5] = new ResultPoint(v1x + correction * deltax, v1y + correction * deltay);\n    } else if (-skew > SKEW_THRESHOLD) {\n      // Fix v7\n      float deltax = v3x - v5x;\n      float deltay = v3y - v5y;\n      float delta2 = deltax * deltax + deltay * deltay;\n      float correction = (v3x - v7x) * deltax / delta2;\n      vertices[7] = new ResultPoint(v3x - correction * deltax, v3y - correction * deltay);\n    }\n  }\n\n  /**\n   * <p>Estimates module size (pixels in a module) based on the Start and End\n   * finder patterns.</p>\n   *\n   * @param vertices an array of vertices:\n   *           vertices[0] x, y top left barcode\n   *           vertices[1] x, y bottom left barcode\n   *           vertices[2] x, y top right barcode\n   *           vertices[3] x, y bottom right barcode\n   *           vertices[4] x, y top left codeword area\n   *           vertices[5] x, y bottom left codeword area\n   *           vertices[6] x, y top right codeword area\n   *           vertices[7] x, y bottom right codeword area\n   * @return the module size.\n   */\n  private static float computeModuleWidth(ResultPoint[] vertices) {\n    float pixels1 = ResultPoint.distance(vertices[0], vertices[4]);\n    float pixels2 = ResultPoint.distance(vertices[1], vertices[5]);\n    float moduleWidth1 = (pixels1 + pixels2) / (17 * 2.0f);\n    float pixels3 = ResultPoint.distance(vertices[6], vertices[2]);\n    float pixels4 = ResultPoint.distance(vertices[7], vertices[3]);\n    float moduleWidth2 = (pixels3 + pixels4) / (18 * 2.0f);\n    return (moduleWidth1 + moduleWidth2) / 2.0f;\n  }\n\n  /**\n   * Computes the dimension (number of modules in a row) of the PDF417 Code\n   * based on vertices of the codeword area and estimated module size.\n   *\n   * @param topLeft     of codeword area\n   * @param topRight    of codeword area\n   * @param bottomLeft  of codeword area\n   * @param bottomRight of codeword are\n   * @param moduleWidth estimated module size\n   * @return the number of modules in a row.\n   */\n  private static int computeDimension(ResultPoint topLeft,\n                                      ResultPoint topRight,\n                                      ResultPoint bottomLeft,\n                                      ResultPoint bottomRight,\n                                      float moduleWidth) {\n    int topRowDimension = MathUtils.round(ResultPoint.distance(topLeft, topRight) / moduleWidth);\n    int bottomRowDimension = MathUtils.round(ResultPoint.distance(bottomLeft, bottomRight) / moduleWidth);\n    return ((((topRowDimension + bottomRowDimension) >> 1) + 8) / 17) * 17;\n  }\n\n  /**\n   * Computes the y dimension (number of modules in a column) of the PDF417 Code\n   * based on vertices of the codeword area and estimated module size.\n   *\n   * @param topLeft     of codeword area\n   * @param topRight    of codeword area\n   * @param bottomLeft  of codeword area\n   * @param bottomRight of codeword are\n   * @param moduleWidth estimated module size\n   * @return the number of modules in a row.\n   */\n  private static int computeYDimension(ResultPoint topLeft,\n                                      ResultPoint topRight,\n                                      ResultPoint bottomLeft,\n                                      ResultPoint bottomRight,\n                                      float moduleWidth) {\n    int leftColumnDimension = MathUtils.round(ResultPoint.distance(topLeft, bottomLeft) / moduleWidth);\n    int rightColumnDimension = MathUtils.round(ResultPoint.distance(topRight, bottomRight) / moduleWidth);\n    return (leftColumnDimension + rightColumnDimension) >> 1;\n  }\n\n  private static BitMatrix sampleGrid(BitMatrix matrix,\n                                      ResultPoint topLeft,\n                                      ResultPoint bottomLeft,\n                                      ResultPoint topRight,\n                                      ResultPoint bottomRight,\n                                      int xdimension,\n                                      int ydimension) throws NotFoundException {\n\n    // Note that unlike the QR Code sampler, we didn't find the center of modules, but the\n    // very corners. So there is no 0.5f here; 0.0f is right.\n    GridSampler sampler = GridSampler.getInstance();\n\n    return sampler.sampleGrid(\n        matrix, \n        xdimension, ydimension,\n        0.0f, // p1ToX\n        0.0f, // p1ToY\n        xdimension, // p2ToX\n        0.0f, // p2ToY\n        xdimension, // p3ToX\n        ydimension, // p3ToY\n        0.0f, // p4ToX\n        ydimension, // p4ToY\n        topLeft.getX(), // p1FromX\n        topLeft.getY(), // p1FromY\n        topRight.getX(), // p2FromX\n        topRight.getY(), // p2FromY\n        bottomRight.getX(), // p3FromX\n        bottomRight.getY(), // p3FromY\n        bottomLeft.getX(), // p4FromX\n        bottomLeft.getY()); // p4FromY\n  }\n\n  /**\n   * @param matrix row of black/white values to search\n   * @param column x position to start search\n   * @param row y position to start search\n   * @param width the number of pixels to search on this row\n   * @param pattern pattern of counts of number of black and white pixels that are\n   *                 being searched for as a pattern\n   * @param counters array of counters, as long as pattern, to re-use \n   * @return start/end horizontal offset of guard pattern, as an array of two ints.\n   */\n  private static int[] findGuardPattern(BitMatrix matrix,\n                                        int column,\n                                        int row,\n                                        int width,\n                                        boolean whiteFirst,\n                                        int[] pattern,\n                                        int[] counters) {\n    Arrays.fill(counters, 0, counters.length, 0);\n    int patternLength = pattern.length;\n    boolean isWhite = whiteFirst;\n\n    int counterPosition = 0;\n    int patternStart = column;\n    for (int x = column; x < column + width; x++) {\n      boolean pixel = matrix.get(x, row);\n      if (pixel ^ isWhite) {\n        counters[counterPosition]++;\n      } else {\n        if (counterPosition == patternLength - 1) {\n          if (patternMatchVariance(counters, pattern, MAX_INDIVIDUAL_VARIANCE) < MAX_AVG_VARIANCE) {\n            return new int[]{patternStart, x};\n          }\n          patternStart += counters[0] + counters[1];\n          System.arraycopy(counters, 2, counters, 0, patternLength - 2);\n          counters[patternLength - 2] = 0;\n          counters[patternLength - 1] = 0;\n          counterPosition--;\n        } else {\n          counterPosition++;\n        }\n        counters[counterPosition] = 1;\n        isWhite = !isWhite;\n      }\n    }\n    return null;\n  }\n\n  /**\n   * Determines how closely a set of observed counts of runs of black/white\n   * values matches a given target pattern. This is reported as the ratio of\n   * the total variance from the expected pattern proportions across all\n   * pattern elements, to the length of the pattern.\n   *\n   * @param counters observed counters\n   * @param pattern expected pattern\n   * @param maxIndividualVariance The most any counter can differ before we give up\n   * @return ratio of total variance between counters and pattern compared to\n   *         total pattern size, where the ratio has been multiplied by 256.\n   *         So, 0 means no variance (perfect match); 256 means the total\n   *         variance between counters and patterns equals the pattern length,\n   *         higher values mean even more variance\n   */\n  private static int patternMatchVariance(int[] counters, int[] pattern, int maxIndividualVariance) {\n    int numCounters = counters.length;\n    int total = 0;\n    int patternLength = 0;\n    for (int i = 0; i < numCounters; i++) {\n      total += counters[i];\n      patternLength += pattern[i];\n    }\n    if (total < patternLength) {\n      // If we don't even have one pixel per unit of bar width, assume this\n      // is too small to reliably match, so fail:\n      return Integer.MAX_VALUE;\n    }\n    // We're going to fake floating-point math in integers. We just need to use more bits.\n    // Scale up patternLength so that intermediate values below like scaledCounter will have\n    // more \"significant digits\".\n    int unitBarWidth = (total << INTEGER_MATH_SHIFT) / patternLength;\n    maxIndividualVariance = (maxIndividualVariance * unitBarWidth) >> 8;\n\n    int totalVariance = 0;\n    for (int x = 0; x < numCounters; x++) {\n      int counter = counters[x] << INTEGER_MATH_SHIFT;\n      int scaledPattern = pattern[x] * unitBarWidth;\n      int variance = counter > scaledPattern ? counter - scaledPattern : scaledPattern - counter;\n      if (variance > maxIndividualVariance) {\n        return Integer.MAX_VALUE;\n      }\n      totalVariance += variance;\n    }\n    return totalVariance / total;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/pdf417/encoder/BarcodeMatrix.java",
    "content": "/*\n * Copyright 2011 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.pdf417.encoder;\n\n/**\n * Holds all of the information for a barcode in a format where it can be easily accessable\n *\n * @author Jacob Haynes\n */\nfinal class BarcodeMatrix {\n\n  private final BarcodeRow[] matrix;\n  private int currentRow;\n  private final int height;\n  private final int width;\n\n  /**\n   * @param height the height of the matrix (Rows)\n   * @param width  the width of the matrix (Cols)\n   */\n  BarcodeMatrix(int height, int width) {\n    matrix = new BarcodeRow[height + 2];\n    //Initializes the array to the correct width\n    for (int i = 0, matrixLength = matrix.length; i < matrixLength; i++) {\n      matrix[i] = new BarcodeRow((width + 4) * 17 + 1);\n    }\n    this.width = width * 17;\n    this.height = height + 2;\n    this.currentRow = 0;\n  }\n\n  void set(int x, int y, byte value) {\n    matrix[y].set(x, value);\n  }\n\n  void setMatrix(int x, int y, boolean black) {\n    set(x, y, (byte) (black ? 1 : 0));\n  }\n\n  void startRow() {\n    ++currentRow;\n  }\n\n  BarcodeRow getCurrentRow() {\n    return matrix[currentRow];\n  }\n\n  byte[][] getMatrix() {\n    return getScaledMatrix(1, 1);\n  }\n\n  byte[][] getScaledMatrix(int Scale) {\n    return getScaledMatrix(Scale, Scale);\n  }\n\n  byte[][] getScaledMatrix(int xScale, int yScale) {\n    byte[][] matrixOut = new byte[height * yScale][width * xScale];\n    int yMax = height * yScale;\n    for (int ii = 0; ii < yMax; ii++) {\n      matrixOut[yMax - ii - 1] = matrix[ii / yScale].getScaledRow(xScale);\n    }\n    return matrixOut;\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/pdf417/encoder/BarcodeRow.java",
    "content": "/*\n * Copyright 2011 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.pdf417.encoder;\n\n/**\n * @author Jacob Haynes\n */\nfinal class BarcodeRow {\n\n  private final byte[] row;\n  //A tacker for position in the bar\n  private int currentLocation;\n\n  /**\n   * Creates a Barcode row of the width\n   *\n   * @param width\n   */\n  BarcodeRow(int width) {\n    this.row = new byte[width];\n    currentLocation = 0;\n  }\n\n  /**\n   * Sets a specific location in the bar\n   *\n   * @param x The location in the bar\n   * @param value Black if true, white if false;\n   */\n  void set(int x, byte value) {\n    row[x] = value;\n  }\n\n  /**\n   * Sets a specific location in the bar\n   *\n   * @param x The location in the bar\n   * @param black Black if true, white if false;\n   */\n  void set(int x, boolean black) {\n    row[x] = (byte) (black ? 1 : 0);\n  }\n\n  /**\n   * @param black A boolean which is true if the bar black false if it is white\n   * @param width How many spots wide the bar is.\n   */\n  void addBar(boolean black, int width) {\n    for (int ii = 0; ii < width; ii++) {\n      set(currentLocation++, black);\n    }\n  }\n\n  byte[] getRow() {\n    return row;\n  }\n\n  /**\n   * This function scales the row\n   *\n   * @param scale How much you want the image to be scaled, must be greater than or equal to 1.\n   * @return the scaled row\n   */\n  byte[] getScaledRow(int scale) {\n    byte[] output = new byte[row.length * scale];\n    for (int i = 0; i < output.length; i++) {\n      output[i] = row[i / scale];\n    }\n    return output;\n  }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/pdf417/encoder/Compaction.java",
    "content": "/*\n * Copyright 2011 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.pdf417.encoder;\n\npublic enum Compaction {\n  \n  AUTO,\n  TEXT,\n  BYTE,\n  NUMERIC\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/pdf417/encoder/Dimensions.java",
    "content": "/*\n * Copyright 2012 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.pdf417.encoder;\n\n/**\n * Data object to specify the minimum and maximum number of rows and columns for a PDF417 barcode.\n *\n * @author qwandor@google.com (Andrew Walbran)\n */\npublic final class Dimensions {\n\n  private final int minCols;\n  private final int maxCols;\n  private final int minRows;\n  private final int maxRows;\n\n  public Dimensions(int minCols, int maxCols, int minRows, int maxRows) {\n    this.minCols = minCols;\n    this.maxCols = maxCols;\n    this.minRows = minRows;\n    this.maxRows = maxRows;\n  }\n\n  public int getMinCols() {\n    return minCols;\n  }\n\n  public int getMaxCols() {\n    return maxCols;\n  }\n\n  public int getMinRows() {\n    return minRows;\n  }\n\n  public int getMaxRows() {\n    return maxRows;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/pdf417/encoder/PDF417.java",
    "content": "/*\n * Copyright 2006 Jeremias Maerki in part, and ZXing Authors in part\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * This file has been modified from its original form in Barcode4J.\n */\n\npackage com.google.zxing.pdf417.encoder;\n\nimport com.google.zxing.WriterException;\n\n/**\n * Top-level class for the logic part of the PDF417 implementation.\n */\nfinal class PDF417 {\n\n  /**\n   * The start pattern (17 bits)\n   */\n  private static final int START_PATTERN = 0x1fea8;\n  /**\n   * The stop pattern (18 bits)\n   */\n  private static final int STOP_PATTERN = 0x3fa29;\n\n  /**\n   * The codeword table from the Annex A of ISO/IEC 15438:2001(E).\n   */\n  private static final int[][] CODEWORD_TABLE = {\n      {0x1d5c0, 0x1eaf0, 0x1f57c, 0x1d4e0, 0x1ea78, 0x1f53e,\n          0x1a8c0, 0x1d470, 0x1a860, 0x15040, 0x1a830, 0x15020,\n          0x1adc0, 0x1d6f0, 0x1eb7c, 0x1ace0, 0x1d678, 0x1eb3e,\n          0x158c0, 0x1ac70, 0x15860, 0x15dc0, 0x1aef0, 0x1d77c,\n          0x15ce0, 0x1ae78, 0x1d73e, 0x15c70, 0x1ae3c, 0x15ef0,\n          0x1af7c, 0x15e78, 0x1af3e, 0x15f7c, 0x1f5fa, 0x1d2e0,\n          0x1e978, 0x1f4be, 0x1a4c0, 0x1d270, 0x1e93c, 0x1a460,\n          0x1d238, 0x14840, 0x1a430, 0x1d21c, 0x14820, 0x1a418,\n          0x14810, 0x1a6e0, 0x1d378, 0x1e9be, 0x14cc0, 0x1a670,\n          0x1d33c, 0x14c60, 0x1a638, 0x1d31e, 0x14c30, 0x1a61c,\n          0x14ee0, 0x1a778, 0x1d3be, 0x14e70, 0x1a73c, 0x14e38,\n          0x1a71e, 0x14f78, 0x1a7be, 0x14f3c, 0x14f1e, 0x1a2c0,\n          0x1d170, 0x1e8bc, 0x1a260, 0x1d138, 0x1e89e, 0x14440,\n          0x1a230, 0x1d11c, 0x14420, 0x1a218, 0x14410, 0x14408,\n          0x146c0, 0x1a370, 0x1d1bc, 0x14660, 0x1a338, 0x1d19e,\n          0x14630, 0x1a31c, 0x14618, 0x1460c, 0x14770, 0x1a3bc,\n          0x14738, 0x1a39e, 0x1471c, 0x147bc, 0x1a160, 0x1d0b8,\n          0x1e85e, 0x14240, 0x1a130, 0x1d09c, 0x14220, 0x1a118,\n          0x1d08e, 0x14210, 0x1a10c, 0x14208, 0x1a106, 0x14360,\n          0x1a1b8, 0x1d0de, 0x14330, 0x1a19c, 0x14318, 0x1a18e,\n          0x1430c, 0x14306, 0x1a1de, 0x1438e, 0x14140, 0x1a0b0,\n          0x1d05c, 0x14120, 0x1a098, 0x1d04e, 0x14110, 0x1a08c,\n          0x14108, 0x1a086, 0x14104, 0x141b0, 0x14198, 0x1418c,\n          0x140a0, 0x1d02e, 0x1a04c, 0x1a046, 0x14082, 0x1cae0,\n          0x1e578, 0x1f2be, 0x194c0, 0x1ca70, 0x1e53c, 0x19460,\n          0x1ca38, 0x1e51e, 0x12840, 0x19430, 0x12820, 0x196e0,\n          0x1cb78, 0x1e5be, 0x12cc0, 0x19670, 0x1cb3c, 0x12c60,\n          0x19638, 0x12c30, 0x12c18, 0x12ee0, 0x19778, 0x1cbbe,\n          0x12e70, 0x1973c, 0x12e38, 0x12e1c, 0x12f78, 0x197be,\n          0x12f3c, 0x12fbe, 0x1dac0, 0x1ed70, 0x1f6bc, 0x1da60,\n          0x1ed38, 0x1f69e, 0x1b440, 0x1da30, 0x1ed1c, 0x1b420,\n          0x1da18, 0x1ed0e, 0x1b410, 0x1da0c, 0x192c0, 0x1c970,\n          0x1e4bc, 0x1b6c0, 0x19260, 0x1c938, 0x1e49e, 0x1b660,\n          0x1db38, 0x1ed9e, 0x16c40, 0x12420, 0x19218, 0x1c90e,\n          0x16c20, 0x1b618, 0x16c10, 0x126c0, 0x19370, 0x1c9bc,\n          0x16ec0, 0x12660, 0x19338, 0x1c99e, 0x16e60, 0x1b738,\n          0x1db9e, 0x16e30, 0x12618, 0x16e18, 0x12770, 0x193bc,\n          0x16f70, 0x12738, 0x1939e, 0x16f38, 0x1b79e, 0x16f1c,\n          0x127bc, 0x16fbc, 0x1279e, 0x16f9e, 0x1d960, 0x1ecb8,\n          0x1f65e, 0x1b240, 0x1d930, 0x1ec9c, 0x1b220, 0x1d918,\n          0x1ec8e, 0x1b210, 0x1d90c, 0x1b208, 0x1b204, 0x19160,\n          0x1c8b8, 0x1e45e, 0x1b360, 0x19130, 0x1c89c, 0x16640,\n          0x12220, 0x1d99c, 0x1c88e, 0x16620, 0x12210, 0x1910c,\n          0x16610, 0x1b30c, 0x19106, 0x12204, 0x12360, 0x191b8,\n          0x1c8de, 0x16760, 0x12330, 0x1919c, 0x16730, 0x1b39c,\n          0x1918e, 0x16718, 0x1230c, 0x12306, 0x123b8, 0x191de,\n          0x167b8, 0x1239c, 0x1679c, 0x1238e, 0x1678e, 0x167de,\n          0x1b140, 0x1d8b0, 0x1ec5c, 0x1b120, 0x1d898, 0x1ec4e,\n          0x1b110, 0x1d88c, 0x1b108, 0x1d886, 0x1b104, 0x1b102,\n          0x12140, 0x190b0, 0x1c85c, 0x16340, 0x12120, 0x19098,\n          0x1c84e, 0x16320, 0x1b198, 0x1d8ce, 0x16310, 0x12108,\n          0x19086, 0x16308, 0x1b186, 0x16304, 0x121b0, 0x190dc,\n          0x163b0, 0x12198, 0x190ce, 0x16398, 0x1b1ce, 0x1638c,\n          0x12186, 0x16386, 0x163dc, 0x163ce, 0x1b0a0, 0x1d858,\n          0x1ec2e, 0x1b090, 0x1d84c, 0x1b088, 0x1d846, 0x1b084,\n          0x1b082, 0x120a0, 0x19058, 0x1c82e, 0x161a0, 0x12090,\n          0x1904c, 0x16190, 0x1b0cc, 0x19046, 0x16188, 0x12084,\n          0x16184, 0x12082, 0x120d8, 0x161d8, 0x161cc, 0x161c6,\n          0x1d82c, 0x1d826, 0x1b042, 0x1902c, 0x12048, 0x160c8,\n          0x160c4, 0x160c2, 0x18ac0, 0x1c570, 0x1e2bc, 0x18a60,\n          0x1c538, 0x11440, 0x18a30, 0x1c51c, 0x11420, 0x18a18,\n          0x11410, 0x11408, 0x116c0, 0x18b70, 0x1c5bc, 0x11660,\n          0x18b38, 0x1c59e, 0x11630, 0x18b1c, 0x11618, 0x1160c,\n          0x11770, 0x18bbc, 0x11738, 0x18b9e, 0x1171c, 0x117bc,\n          0x1179e, 0x1cd60, 0x1e6b8, 0x1f35e, 0x19a40, 0x1cd30,\n          0x1e69c, 0x19a20, 0x1cd18, 0x1e68e, 0x19a10, 0x1cd0c,\n          0x19a08, 0x1cd06, 0x18960, 0x1c4b8, 0x1e25e, 0x19b60,\n          0x18930, 0x1c49c, 0x13640, 0x11220, 0x1cd9c, 0x1c48e,\n          0x13620, 0x19b18, 0x1890c, 0x13610, 0x11208, 0x13608,\n          0x11360, 0x189b8, 0x1c4de, 0x13760, 0x11330, 0x1cdde,\n          0x13730, 0x19b9c, 0x1898e, 0x13718, 0x1130c, 0x1370c,\n          0x113b8, 0x189de, 0x137b8, 0x1139c, 0x1379c, 0x1138e,\n          0x113de, 0x137de, 0x1dd40, 0x1eeb0, 0x1f75c, 0x1dd20,\n          0x1ee98, 0x1f74e, 0x1dd10, 0x1ee8c, 0x1dd08, 0x1ee86,\n          0x1dd04, 0x19940, 0x1ccb0, 0x1e65c, 0x1bb40, 0x19920,\n          0x1eedc, 0x1e64e, 0x1bb20, 0x1dd98, 0x1eece, 0x1bb10,\n          0x19908, 0x1cc86, 0x1bb08, 0x1dd86, 0x19902, 0x11140,\n          0x188b0, 0x1c45c, 0x13340, 0x11120, 0x18898, 0x1c44e,\n          0x17740, 0x13320, 0x19998, 0x1ccce, 0x17720, 0x1bb98,\n          0x1ddce, 0x18886, 0x17710, 0x13308, 0x19986, 0x17708,\n          0x11102, 0x111b0, 0x188dc, 0x133b0, 0x11198, 0x188ce,\n          0x177b0, 0x13398, 0x199ce, 0x17798, 0x1bbce, 0x11186,\n          0x13386, 0x111dc, 0x133dc, 0x111ce, 0x177dc, 0x133ce,\n          0x1dca0, 0x1ee58, 0x1f72e, 0x1dc90, 0x1ee4c, 0x1dc88,\n          0x1ee46, 0x1dc84, 0x1dc82, 0x198a0, 0x1cc58, 0x1e62e,\n          0x1b9a0, 0x19890, 0x1ee6e, 0x1b990, 0x1dccc, 0x1cc46,\n          0x1b988, 0x19884, 0x1b984, 0x19882, 0x1b982, 0x110a0,\n          0x18858, 0x1c42e, 0x131a0, 0x11090, 0x1884c, 0x173a0,\n          0x13190, 0x198cc, 0x18846, 0x17390, 0x1b9cc, 0x11084,\n          0x17388, 0x13184, 0x11082, 0x13182, 0x110d8, 0x1886e,\n          0x131d8, 0x110cc, 0x173d8, 0x131cc, 0x110c6, 0x173cc,\n          0x131c6, 0x110ee, 0x173ee, 0x1dc50, 0x1ee2c, 0x1dc48,\n          0x1ee26, 0x1dc44, 0x1dc42, 0x19850, 0x1cc2c, 0x1b8d0,\n          0x19848, 0x1cc26, 0x1b8c8, 0x1dc66, 0x1b8c4, 0x19842,\n          0x1b8c2, 0x11050, 0x1882c, 0x130d0, 0x11048, 0x18826,\n          0x171d0, 0x130c8, 0x19866, 0x171c8, 0x1b8e6, 0x11042,\n          0x171c4, 0x130c2, 0x171c2, 0x130ec, 0x171ec, 0x171e6,\n          0x1ee16, 0x1dc22, 0x1cc16, 0x19824, 0x19822, 0x11028,\n          0x13068, 0x170e8, 0x11022, 0x13062, 0x18560, 0x10a40,\n          0x18530, 0x10a20, 0x18518, 0x1c28e, 0x10a10, 0x1850c,\n          0x10a08, 0x18506, 0x10b60, 0x185b8, 0x1c2de, 0x10b30,\n          0x1859c, 0x10b18, 0x1858e, 0x10b0c, 0x10b06, 0x10bb8,\n          0x185de, 0x10b9c, 0x10b8e, 0x10bde, 0x18d40, 0x1c6b0,\n          0x1e35c, 0x18d20, 0x1c698, 0x18d10, 0x1c68c, 0x18d08,\n          0x1c686, 0x18d04, 0x10940, 0x184b0, 0x1c25c, 0x11b40,\n          0x10920, 0x1c6dc, 0x1c24e, 0x11b20, 0x18d98, 0x1c6ce,\n          0x11b10, 0x10908, 0x18486, 0x11b08, 0x18d86, 0x10902,\n          0x109b0, 0x184dc, 0x11bb0, 0x10998, 0x184ce, 0x11b98,\n          0x18dce, 0x11b8c, 0x10986, 0x109dc, 0x11bdc, 0x109ce,\n          0x11bce, 0x1cea0, 0x1e758, 0x1f3ae, 0x1ce90, 0x1e74c,\n          0x1ce88, 0x1e746, 0x1ce84, 0x1ce82, 0x18ca0, 0x1c658,\n          0x19da0, 0x18c90, 0x1c64c, 0x19d90, 0x1cecc, 0x1c646,\n          0x19d88, 0x18c84, 0x19d84, 0x18c82, 0x19d82, 0x108a0,\n          0x18458, 0x119a0, 0x10890, 0x1c66e, 0x13ba0, 0x11990,\n          0x18ccc, 0x18446, 0x13b90, 0x19dcc, 0x10884, 0x13b88,\n          0x11984, 0x10882, 0x11982, 0x108d8, 0x1846e, 0x119d8,\n          0x108cc, 0x13bd8, 0x119cc, 0x108c6, 0x13bcc, 0x119c6,\n          0x108ee, 0x119ee, 0x13bee, 0x1ef50, 0x1f7ac, 0x1ef48,\n          0x1f7a6, 0x1ef44, 0x1ef42, 0x1ce50, 0x1e72c, 0x1ded0,\n          0x1ef6c, 0x1e726, 0x1dec8, 0x1ef66, 0x1dec4, 0x1ce42,\n          0x1dec2, 0x18c50, 0x1c62c, 0x19cd0, 0x18c48, 0x1c626,\n          0x1bdd0, 0x19cc8, 0x1ce66, 0x1bdc8, 0x1dee6, 0x18c42,\n          0x1bdc4, 0x19cc2, 0x1bdc2, 0x10850, 0x1842c, 0x118d0,\n          0x10848, 0x18426, 0x139d0, 0x118c8, 0x18c66, 0x17bd0,\n          0x139c8, 0x19ce6, 0x10842, 0x17bc8, 0x1bde6, 0x118c2,\n          0x17bc4, 0x1086c, 0x118ec, 0x10866, 0x139ec, 0x118e6,\n          0x17bec, 0x139e6, 0x17be6, 0x1ef28, 0x1f796, 0x1ef24,\n          0x1ef22, 0x1ce28, 0x1e716, 0x1de68, 0x1ef36, 0x1de64,\n          0x1ce22, 0x1de62, 0x18c28, 0x1c616, 0x19c68, 0x18c24,\n          0x1bce8, 0x19c64, 0x18c22, 0x1bce4, 0x19c62, 0x1bce2,\n          0x10828, 0x18416, 0x11868, 0x18c36, 0x138e8, 0x11864,\n          0x10822, 0x179e8, 0x138e4, 0x11862, 0x179e4, 0x138e2,\n          0x179e2, 0x11876, 0x179f6, 0x1ef12, 0x1de34, 0x1de32,\n          0x19c34, 0x1bc74, 0x1bc72, 0x11834, 0x13874, 0x178f4,\n          0x178f2, 0x10540, 0x10520, 0x18298, 0x10510, 0x10508,\n          0x10504, 0x105b0, 0x10598, 0x1058c, 0x10586, 0x105dc,\n          0x105ce, 0x186a0, 0x18690, 0x1c34c, 0x18688, 0x1c346,\n          0x18684, 0x18682, 0x104a0, 0x18258, 0x10da0, 0x186d8,\n          0x1824c, 0x10d90, 0x186cc, 0x10d88, 0x186c6, 0x10d84,\n          0x10482, 0x10d82, 0x104d8, 0x1826e, 0x10dd8, 0x186ee,\n          0x10dcc, 0x104c6, 0x10dc6, 0x104ee, 0x10dee, 0x1c750,\n          0x1c748, 0x1c744, 0x1c742, 0x18650, 0x18ed0, 0x1c76c,\n          0x1c326, 0x18ec8, 0x1c766, 0x18ec4, 0x18642, 0x18ec2,\n          0x10450, 0x10cd0, 0x10448, 0x18226, 0x11dd0, 0x10cc8,\n          0x10444, 0x11dc8, 0x10cc4, 0x10442, 0x11dc4, 0x10cc2,\n          0x1046c, 0x10cec, 0x10466, 0x11dec, 0x10ce6, 0x11de6,\n          0x1e7a8, 0x1e7a4, 0x1e7a2, 0x1c728, 0x1cf68, 0x1e7b6,\n          0x1cf64, 0x1c722, 0x1cf62, 0x18628, 0x1c316, 0x18e68,\n          0x1c736, 0x19ee8, 0x18e64, 0x18622, 0x19ee4, 0x18e62,\n          0x19ee2, 0x10428, 0x18216, 0x10c68, 0x18636, 0x11ce8,\n          0x10c64, 0x10422, 0x13de8, 0x11ce4, 0x10c62, 0x13de4,\n          0x11ce2, 0x10436, 0x10c76, 0x11cf6, 0x13df6, 0x1f7d4,\n          0x1f7d2, 0x1e794, 0x1efb4, 0x1e792, 0x1efb2, 0x1c714,\n          0x1cf34, 0x1c712, 0x1df74, 0x1cf32, 0x1df72, 0x18614,\n          0x18e34, 0x18612, 0x19e74, 0x18e32, 0x1bef4},\n      {0x1f560, 0x1fab8, 0x1ea40, 0x1f530, 0x1fa9c, 0x1ea20,\n          0x1f518, 0x1fa8e, 0x1ea10, 0x1f50c, 0x1ea08, 0x1f506,\n          0x1ea04, 0x1eb60, 0x1f5b8, 0x1fade, 0x1d640, 0x1eb30,\n          0x1f59c, 0x1d620, 0x1eb18, 0x1f58e, 0x1d610, 0x1eb0c,\n          0x1d608, 0x1eb06, 0x1d604, 0x1d760, 0x1ebb8, 0x1f5de,\n          0x1ae40, 0x1d730, 0x1eb9c, 0x1ae20, 0x1d718, 0x1eb8e,\n          0x1ae10, 0x1d70c, 0x1ae08, 0x1d706, 0x1ae04, 0x1af60,\n          0x1d7b8, 0x1ebde, 0x15e40, 0x1af30, 0x1d79c, 0x15e20,\n          0x1af18, 0x1d78e, 0x15e10, 0x1af0c, 0x15e08, 0x1af06,\n          0x15f60, 0x1afb8, 0x1d7de, 0x15f30, 0x1af9c, 0x15f18,\n          0x1af8e, 0x15f0c, 0x15fb8, 0x1afde, 0x15f9c, 0x15f8e,\n          0x1e940, 0x1f4b0, 0x1fa5c, 0x1e920, 0x1f498, 0x1fa4e,\n          0x1e910, 0x1f48c, 0x1e908, 0x1f486, 0x1e904, 0x1e902,\n          0x1d340, 0x1e9b0, 0x1f4dc, 0x1d320, 0x1e998, 0x1f4ce,\n          0x1d310, 0x1e98c, 0x1d308, 0x1e986, 0x1d304, 0x1d302,\n          0x1a740, 0x1d3b0, 0x1e9dc, 0x1a720, 0x1d398, 0x1e9ce,\n          0x1a710, 0x1d38c, 0x1a708, 0x1d386, 0x1a704, 0x1a702,\n          0x14f40, 0x1a7b0, 0x1d3dc, 0x14f20, 0x1a798, 0x1d3ce,\n          0x14f10, 0x1a78c, 0x14f08, 0x1a786, 0x14f04, 0x14fb0,\n          0x1a7dc, 0x14f98, 0x1a7ce, 0x14f8c, 0x14f86, 0x14fdc,\n          0x14fce, 0x1e8a0, 0x1f458, 0x1fa2e, 0x1e890, 0x1f44c,\n          0x1e888, 0x1f446, 0x1e884, 0x1e882, 0x1d1a0, 0x1e8d8,\n          0x1f46e, 0x1d190, 0x1e8cc, 0x1d188, 0x1e8c6, 0x1d184,\n          0x1d182, 0x1a3a0, 0x1d1d8, 0x1e8ee, 0x1a390, 0x1d1cc,\n          0x1a388, 0x1d1c6, 0x1a384, 0x1a382, 0x147a0, 0x1a3d8,\n          0x1d1ee, 0x14790, 0x1a3cc, 0x14788, 0x1a3c6, 0x14784,\n          0x14782, 0x147d8, 0x1a3ee, 0x147cc, 0x147c6, 0x147ee,\n          0x1e850, 0x1f42c, 0x1e848, 0x1f426, 0x1e844, 0x1e842,\n          0x1d0d0, 0x1e86c, 0x1d0c8, 0x1e866, 0x1d0c4, 0x1d0c2,\n          0x1a1d0, 0x1d0ec, 0x1a1c8, 0x1d0e6, 0x1a1c4, 0x1a1c2,\n          0x143d0, 0x1a1ec, 0x143c8, 0x1a1e6, 0x143c4, 0x143c2,\n          0x143ec, 0x143e6, 0x1e828, 0x1f416, 0x1e824, 0x1e822,\n          0x1d068, 0x1e836, 0x1d064, 0x1d062, 0x1a0e8, 0x1d076,\n          0x1a0e4, 0x1a0e2, 0x141e8, 0x1a0f6, 0x141e4, 0x141e2,\n          0x1e814, 0x1e812, 0x1d034, 0x1d032, 0x1a074, 0x1a072,\n          0x1e540, 0x1f2b0, 0x1f95c, 0x1e520, 0x1f298, 0x1f94e,\n          0x1e510, 0x1f28c, 0x1e508, 0x1f286, 0x1e504, 0x1e502,\n          0x1cb40, 0x1e5b0, 0x1f2dc, 0x1cb20, 0x1e598, 0x1f2ce,\n          0x1cb10, 0x1e58c, 0x1cb08, 0x1e586, 0x1cb04, 0x1cb02,\n          0x19740, 0x1cbb0, 0x1e5dc, 0x19720, 0x1cb98, 0x1e5ce,\n          0x19710, 0x1cb8c, 0x19708, 0x1cb86, 0x19704, 0x19702,\n          0x12f40, 0x197b0, 0x1cbdc, 0x12f20, 0x19798, 0x1cbce,\n          0x12f10, 0x1978c, 0x12f08, 0x19786, 0x12f04, 0x12fb0,\n          0x197dc, 0x12f98, 0x197ce, 0x12f8c, 0x12f86, 0x12fdc,\n          0x12fce, 0x1f6a0, 0x1fb58, 0x16bf0, 0x1f690, 0x1fb4c,\n          0x169f8, 0x1f688, 0x1fb46, 0x168fc, 0x1f684, 0x1f682,\n          0x1e4a0, 0x1f258, 0x1f92e, 0x1eda0, 0x1e490, 0x1fb6e,\n          0x1ed90, 0x1f6cc, 0x1f246, 0x1ed88, 0x1e484, 0x1ed84,\n          0x1e482, 0x1ed82, 0x1c9a0, 0x1e4d8, 0x1f26e, 0x1dba0,\n          0x1c990, 0x1e4cc, 0x1db90, 0x1edcc, 0x1e4c6, 0x1db88,\n          0x1c984, 0x1db84, 0x1c982, 0x1db82, 0x193a0, 0x1c9d8,\n          0x1e4ee, 0x1b7a0, 0x19390, 0x1c9cc, 0x1b790, 0x1dbcc,\n          0x1c9c6, 0x1b788, 0x19384, 0x1b784, 0x19382, 0x1b782,\n          0x127a0, 0x193d8, 0x1c9ee, 0x16fa0, 0x12790, 0x193cc,\n          0x16f90, 0x1b7cc, 0x193c6, 0x16f88, 0x12784, 0x16f84,\n          0x12782, 0x127d8, 0x193ee, 0x16fd8, 0x127cc, 0x16fcc,\n          0x127c6, 0x16fc6, 0x127ee, 0x1f650, 0x1fb2c, 0x165f8,\n          0x1f648, 0x1fb26, 0x164fc, 0x1f644, 0x1647e, 0x1f642,\n          0x1e450, 0x1f22c, 0x1ecd0, 0x1e448, 0x1f226, 0x1ecc8,\n          0x1f666, 0x1ecc4, 0x1e442, 0x1ecc2, 0x1c8d0, 0x1e46c,\n          0x1d9d0, 0x1c8c8, 0x1e466, 0x1d9c8, 0x1ece6, 0x1d9c4,\n          0x1c8c2, 0x1d9c2, 0x191d0, 0x1c8ec, 0x1b3d0, 0x191c8,\n          0x1c8e6, 0x1b3c8, 0x1d9e6, 0x1b3c4, 0x191c2, 0x1b3c2,\n          0x123d0, 0x191ec, 0x167d0, 0x123c8, 0x191e6, 0x167c8,\n          0x1b3e6, 0x167c4, 0x123c2, 0x167c2, 0x123ec, 0x167ec,\n          0x123e6, 0x167e6, 0x1f628, 0x1fb16, 0x162fc, 0x1f624,\n          0x1627e, 0x1f622, 0x1e428, 0x1f216, 0x1ec68, 0x1f636,\n          0x1ec64, 0x1e422, 0x1ec62, 0x1c868, 0x1e436, 0x1d8e8,\n          0x1c864, 0x1d8e4, 0x1c862, 0x1d8e2, 0x190e8, 0x1c876,\n          0x1b1e8, 0x1d8f6, 0x1b1e4, 0x190e2, 0x1b1e2, 0x121e8,\n          0x190f6, 0x163e8, 0x121e4, 0x163e4, 0x121e2, 0x163e2,\n          0x121f6, 0x163f6, 0x1f614, 0x1617e, 0x1f612, 0x1e414,\n          0x1ec34, 0x1e412, 0x1ec32, 0x1c834, 0x1d874, 0x1c832,\n          0x1d872, 0x19074, 0x1b0f4, 0x19072, 0x1b0f2, 0x120f4,\n          0x161f4, 0x120f2, 0x161f2, 0x1f60a, 0x1e40a, 0x1ec1a,\n          0x1c81a, 0x1d83a, 0x1903a, 0x1b07a, 0x1e2a0, 0x1f158,\n          0x1f8ae, 0x1e290, 0x1f14c, 0x1e288, 0x1f146, 0x1e284,\n          0x1e282, 0x1c5a0, 0x1e2d8, 0x1f16e, 0x1c590, 0x1e2cc,\n          0x1c588, 0x1e2c6, 0x1c584, 0x1c582, 0x18ba0, 0x1c5d8,\n          0x1e2ee, 0x18b90, 0x1c5cc, 0x18b88, 0x1c5c6, 0x18b84,\n          0x18b82, 0x117a0, 0x18bd8, 0x1c5ee, 0x11790, 0x18bcc,\n          0x11788, 0x18bc6, 0x11784, 0x11782, 0x117d8, 0x18bee,\n          0x117cc, 0x117c6, 0x117ee, 0x1f350, 0x1f9ac, 0x135f8,\n          0x1f348, 0x1f9a6, 0x134fc, 0x1f344, 0x1347e, 0x1f342,\n          0x1e250, 0x1f12c, 0x1e6d0, 0x1e248, 0x1f126, 0x1e6c8,\n          0x1f366, 0x1e6c4, 0x1e242, 0x1e6c2, 0x1c4d0, 0x1e26c,\n          0x1cdd0, 0x1c4c8, 0x1e266, 0x1cdc8, 0x1e6e6, 0x1cdc4,\n          0x1c4c2, 0x1cdc2, 0x189d0, 0x1c4ec, 0x19bd0, 0x189c8,\n          0x1c4e6, 0x19bc8, 0x1cde6, 0x19bc4, 0x189c2, 0x19bc2,\n          0x113d0, 0x189ec, 0x137d0, 0x113c8, 0x189e6, 0x137c8,\n          0x19be6, 0x137c4, 0x113c2, 0x137c2, 0x113ec, 0x137ec,\n          0x113e6, 0x137e6, 0x1fba8, 0x175f0, 0x1bafc, 0x1fba4,\n          0x174f8, 0x1ba7e, 0x1fba2, 0x1747c, 0x1743e, 0x1f328,\n          0x1f996, 0x132fc, 0x1f768, 0x1fbb6, 0x176fc, 0x1327e,\n          0x1f764, 0x1f322, 0x1767e, 0x1f762, 0x1e228, 0x1f116,\n          0x1e668, 0x1e224, 0x1eee8, 0x1f776, 0x1e222, 0x1eee4,\n          0x1e662, 0x1eee2, 0x1c468, 0x1e236, 0x1cce8, 0x1c464,\n          0x1dde8, 0x1cce4, 0x1c462, 0x1dde4, 0x1cce2, 0x1dde2,\n          0x188e8, 0x1c476, 0x199e8, 0x188e4, 0x1bbe8, 0x199e4,\n          0x188e2, 0x1bbe4, 0x199e2, 0x1bbe2, 0x111e8, 0x188f6,\n          0x133e8, 0x111e4, 0x177e8, 0x133e4, 0x111e2, 0x177e4,\n          0x133e2, 0x177e2, 0x111f6, 0x133f6, 0x1fb94, 0x172f8,\n          0x1b97e, 0x1fb92, 0x1727c, 0x1723e, 0x1f314, 0x1317e,\n          0x1f734, 0x1f312, 0x1737e, 0x1f732, 0x1e214, 0x1e634,\n          0x1e212, 0x1ee74, 0x1e632, 0x1ee72, 0x1c434, 0x1cc74,\n          0x1c432, 0x1dcf4, 0x1cc72, 0x1dcf2, 0x18874, 0x198f4,\n          0x18872, 0x1b9f4, 0x198f2, 0x1b9f2, 0x110f4, 0x131f4,\n          0x110f2, 0x173f4, 0x131f2, 0x173f2, 0x1fb8a, 0x1717c,\n          0x1713e, 0x1f30a, 0x1f71a, 0x1e20a, 0x1e61a, 0x1ee3a,\n          0x1c41a, 0x1cc3a, 0x1dc7a, 0x1883a, 0x1987a, 0x1b8fa,\n          0x1107a, 0x130fa, 0x171fa, 0x170be, 0x1e150, 0x1f0ac,\n          0x1e148, 0x1f0a6, 0x1e144, 0x1e142, 0x1c2d0, 0x1e16c,\n          0x1c2c8, 0x1e166, 0x1c2c4, 0x1c2c2, 0x185d0, 0x1c2ec,\n          0x185c8, 0x1c2e6, 0x185c4, 0x185c2, 0x10bd0, 0x185ec,\n          0x10bc8, 0x185e6, 0x10bc4, 0x10bc2, 0x10bec, 0x10be6,\n          0x1f1a8, 0x1f8d6, 0x11afc, 0x1f1a4, 0x11a7e, 0x1f1a2,\n          0x1e128, 0x1f096, 0x1e368, 0x1e124, 0x1e364, 0x1e122,\n          0x1e362, 0x1c268, 0x1e136, 0x1c6e8, 0x1c264, 0x1c6e4,\n          0x1c262, 0x1c6e2, 0x184e8, 0x1c276, 0x18de8, 0x184e4,\n          0x18de4, 0x184e2, 0x18de2, 0x109e8, 0x184f6, 0x11be8,\n          0x109e4, 0x11be4, 0x109e2, 0x11be2, 0x109f6, 0x11bf6,\n          0x1f9d4, 0x13af8, 0x19d7e, 0x1f9d2, 0x13a7c, 0x13a3e,\n          0x1f194, 0x1197e, 0x1f3b4, 0x1f192, 0x13b7e, 0x1f3b2,\n          0x1e114, 0x1e334, 0x1e112, 0x1e774, 0x1e332, 0x1e772,\n          0x1c234, 0x1c674, 0x1c232, 0x1cef4, 0x1c672, 0x1cef2,\n          0x18474, 0x18cf4, 0x18472, 0x19df4, 0x18cf2, 0x19df2,\n          0x108f4, 0x119f4, 0x108f2, 0x13bf4, 0x119f2, 0x13bf2,\n          0x17af0, 0x1bd7c, 0x17a78, 0x1bd3e, 0x17a3c, 0x17a1e,\n          0x1f9ca, 0x1397c, 0x1fbda, 0x17b7c, 0x1393e, 0x17b3e,\n          0x1f18a, 0x1f39a, 0x1f7ba, 0x1e10a, 0x1e31a, 0x1e73a,\n          0x1ef7a, 0x1c21a, 0x1c63a, 0x1ce7a, 0x1defa, 0x1843a,\n          0x18c7a, 0x19cfa, 0x1bdfa, 0x1087a, 0x118fa, 0x139fa,\n          0x17978, 0x1bcbe, 0x1793c, 0x1791e, 0x138be, 0x179be,\n          0x178bc, 0x1789e, 0x1785e, 0x1e0a8, 0x1e0a4, 0x1e0a2,\n          0x1c168, 0x1e0b6, 0x1c164, 0x1c162, 0x182e8, 0x1c176,\n          0x182e4, 0x182e2, 0x105e8, 0x182f6, 0x105e4, 0x105e2,\n          0x105f6, 0x1f0d4, 0x10d7e, 0x1f0d2, 0x1e094, 0x1e1b4,\n          0x1e092, 0x1e1b2, 0x1c134, 0x1c374, 0x1c132, 0x1c372,\n          0x18274, 0x186f4, 0x18272, 0x186f2, 0x104f4, 0x10df4,\n          0x104f2, 0x10df2, 0x1f8ea, 0x11d7c, 0x11d3e, 0x1f0ca,\n          0x1f1da, 0x1e08a, 0x1e19a, 0x1e3ba, 0x1c11a, 0x1c33a,\n          0x1c77a, 0x1823a, 0x1867a, 0x18efa, 0x1047a, 0x10cfa,\n          0x11dfa, 0x13d78, 0x19ebe, 0x13d3c, 0x13d1e, 0x11cbe,\n          0x13dbe, 0x17d70, 0x1bebc, 0x17d38, 0x1be9e, 0x17d1c,\n          0x17d0e, 0x13cbc, 0x17dbc, 0x13c9e, 0x17d9e, 0x17cb8,\n          0x1be5e, 0x17c9c, 0x17c8e, 0x13c5e, 0x17cde, 0x17c5c,\n          0x17c4e, 0x17c2e, 0x1c0b4, 0x1c0b2, 0x18174, 0x18172,\n          0x102f4, 0x102f2, 0x1e0da, 0x1c09a, 0x1c1ba, 0x1813a,\n          0x1837a, 0x1027a, 0x106fa, 0x10ebe, 0x11ebc, 0x11e9e,\n          0x13eb8, 0x19f5e, 0x13e9c, 0x13e8e, 0x11e5e, 0x13ede,\n          0x17eb0, 0x1bf5c, 0x17e98, 0x1bf4e, 0x17e8c, 0x17e86,\n          0x13e5c, 0x17edc, 0x13e4e, 0x17ece, 0x17e58, 0x1bf2e,\n          0x17e4c, 0x17e46, 0x13e2e, 0x17e6e, 0x17e2c, 0x17e26,\n          0x10f5e, 0x11f5c, 0x11f4e, 0x13f58, 0x19fae, 0x13f4c,\n          0x13f46, 0x11f2e, 0x13f6e, 0x13f2c, 0x13f26},\n      {0x1abe0, 0x1d5f8, 0x153c0, 0x1a9f0, 0x1d4fc, 0x151e0,\n          0x1a8f8, 0x1d47e, 0x150f0, 0x1a87c, 0x15078, 0x1fad0,\n          0x15be0, 0x1adf8, 0x1fac8, 0x159f0, 0x1acfc, 0x1fac4,\n          0x158f8, 0x1ac7e, 0x1fac2, 0x1587c, 0x1f5d0, 0x1faec,\n          0x15df8, 0x1f5c8, 0x1fae6, 0x15cfc, 0x1f5c4, 0x15c7e,\n          0x1f5c2, 0x1ebd0, 0x1f5ec, 0x1ebc8, 0x1f5e6, 0x1ebc4,\n          0x1ebc2, 0x1d7d0, 0x1ebec, 0x1d7c8, 0x1ebe6, 0x1d7c4,\n          0x1d7c2, 0x1afd0, 0x1d7ec, 0x1afc8, 0x1d7e6, 0x1afc4,\n          0x14bc0, 0x1a5f0, 0x1d2fc, 0x149e0, 0x1a4f8, 0x1d27e,\n          0x148f0, 0x1a47c, 0x14878, 0x1a43e, 0x1483c, 0x1fa68,\n          0x14df0, 0x1a6fc, 0x1fa64, 0x14cf8, 0x1a67e, 0x1fa62,\n          0x14c7c, 0x14c3e, 0x1f4e8, 0x1fa76, 0x14efc, 0x1f4e4,\n          0x14e7e, 0x1f4e2, 0x1e9e8, 0x1f4f6, 0x1e9e4, 0x1e9e2,\n          0x1d3e8, 0x1e9f6, 0x1d3e4, 0x1d3e2, 0x1a7e8, 0x1d3f6,\n          0x1a7e4, 0x1a7e2, 0x145e0, 0x1a2f8, 0x1d17e, 0x144f0,\n          0x1a27c, 0x14478, 0x1a23e, 0x1443c, 0x1441e, 0x1fa34,\n          0x146f8, 0x1a37e, 0x1fa32, 0x1467c, 0x1463e, 0x1f474,\n          0x1477e, 0x1f472, 0x1e8f4, 0x1e8f2, 0x1d1f4, 0x1d1f2,\n          0x1a3f4, 0x1a3f2, 0x142f0, 0x1a17c, 0x14278, 0x1a13e,\n          0x1423c, 0x1421e, 0x1fa1a, 0x1437c, 0x1433e, 0x1f43a,\n          0x1e87a, 0x1d0fa, 0x14178, 0x1a0be, 0x1413c, 0x1411e,\n          0x141be, 0x140bc, 0x1409e, 0x12bc0, 0x195f0, 0x1cafc,\n          0x129e0, 0x194f8, 0x1ca7e, 0x128f0, 0x1947c, 0x12878,\n          0x1943e, 0x1283c, 0x1f968, 0x12df0, 0x196fc, 0x1f964,\n          0x12cf8, 0x1967e, 0x1f962, 0x12c7c, 0x12c3e, 0x1f2e8,\n          0x1f976, 0x12efc, 0x1f2e4, 0x12e7e, 0x1f2e2, 0x1e5e8,\n          0x1f2f6, 0x1e5e4, 0x1e5e2, 0x1cbe8, 0x1e5f6, 0x1cbe4,\n          0x1cbe2, 0x197e8, 0x1cbf6, 0x197e4, 0x197e2, 0x1b5e0,\n          0x1daf8, 0x1ed7e, 0x169c0, 0x1b4f0, 0x1da7c, 0x168e0,\n          0x1b478, 0x1da3e, 0x16870, 0x1b43c, 0x16838, 0x1b41e,\n          0x1681c, 0x125e0, 0x192f8, 0x1c97e, 0x16de0, 0x124f0,\n          0x1927c, 0x16cf0, 0x1b67c, 0x1923e, 0x16c78, 0x1243c,\n          0x16c3c, 0x1241e, 0x16c1e, 0x1f934, 0x126f8, 0x1937e,\n          0x1fb74, 0x1f932, 0x16ef8, 0x1267c, 0x1fb72, 0x16e7c,\n          0x1263e, 0x16e3e, 0x1f274, 0x1277e, 0x1f6f4, 0x1f272,\n          0x16f7e, 0x1f6f2, 0x1e4f4, 0x1edf4, 0x1e4f2, 0x1edf2,\n          0x1c9f4, 0x1dbf4, 0x1c9f2, 0x1dbf2, 0x193f4, 0x193f2,\n          0x165c0, 0x1b2f0, 0x1d97c, 0x164e0, 0x1b278, 0x1d93e,\n          0x16470, 0x1b23c, 0x16438, 0x1b21e, 0x1641c, 0x1640e,\n          0x122f0, 0x1917c, 0x166f0, 0x12278, 0x1913e, 0x16678,\n          0x1b33e, 0x1663c, 0x1221e, 0x1661e, 0x1f91a, 0x1237c,\n          0x1fb3a, 0x1677c, 0x1233e, 0x1673e, 0x1f23a, 0x1f67a,\n          0x1e47a, 0x1ecfa, 0x1c8fa, 0x1d9fa, 0x191fa, 0x162e0,\n          0x1b178, 0x1d8be, 0x16270, 0x1b13c, 0x16238, 0x1b11e,\n          0x1621c, 0x1620e, 0x12178, 0x190be, 0x16378, 0x1213c,\n          0x1633c, 0x1211e, 0x1631e, 0x121be, 0x163be, 0x16170,\n          0x1b0bc, 0x16138, 0x1b09e, 0x1611c, 0x1610e, 0x120bc,\n          0x161bc, 0x1209e, 0x1619e, 0x160b8, 0x1b05e, 0x1609c,\n          0x1608e, 0x1205e, 0x160de, 0x1605c, 0x1604e, 0x115e0,\n          0x18af8, 0x1c57e, 0x114f0, 0x18a7c, 0x11478, 0x18a3e,\n          0x1143c, 0x1141e, 0x1f8b4, 0x116f8, 0x18b7e, 0x1f8b2,\n          0x1167c, 0x1163e, 0x1f174, 0x1177e, 0x1f172, 0x1e2f4,\n          0x1e2f2, 0x1c5f4, 0x1c5f2, 0x18bf4, 0x18bf2, 0x135c0,\n          0x19af0, 0x1cd7c, 0x134e0, 0x19a78, 0x1cd3e, 0x13470,\n          0x19a3c, 0x13438, 0x19a1e, 0x1341c, 0x1340e, 0x112f0,\n          0x1897c, 0x136f0, 0x11278, 0x1893e, 0x13678, 0x19b3e,\n          0x1363c, 0x1121e, 0x1361e, 0x1f89a, 0x1137c, 0x1f9ba,\n          0x1377c, 0x1133e, 0x1373e, 0x1f13a, 0x1f37a, 0x1e27a,\n          0x1e6fa, 0x1c4fa, 0x1cdfa, 0x189fa, 0x1bae0, 0x1dd78,\n          0x1eebe, 0x174c0, 0x1ba70, 0x1dd3c, 0x17460, 0x1ba38,\n          0x1dd1e, 0x17430, 0x1ba1c, 0x17418, 0x1ba0e, 0x1740c,\n          0x132e0, 0x19978, 0x1ccbe, 0x176e0, 0x13270, 0x1993c,\n          0x17670, 0x1bb3c, 0x1991e, 0x17638, 0x1321c, 0x1761c,\n          0x1320e, 0x1760e, 0x11178, 0x188be, 0x13378, 0x1113c,\n          0x17778, 0x1333c, 0x1111e, 0x1773c, 0x1331e, 0x1771e,\n          0x111be, 0x133be, 0x177be, 0x172c0, 0x1b970, 0x1dcbc,\n          0x17260, 0x1b938, 0x1dc9e, 0x17230, 0x1b91c, 0x17218,\n          0x1b90e, 0x1720c, 0x17206, 0x13170, 0x198bc, 0x17370,\n          0x13138, 0x1989e, 0x17338, 0x1b99e, 0x1731c, 0x1310e,\n          0x1730e, 0x110bc, 0x131bc, 0x1109e, 0x173bc, 0x1319e,\n          0x1739e, 0x17160, 0x1b8b8, 0x1dc5e, 0x17130, 0x1b89c,\n          0x17118, 0x1b88e, 0x1710c, 0x17106, 0x130b8, 0x1985e,\n          0x171b8, 0x1309c, 0x1719c, 0x1308e, 0x1718e, 0x1105e,\n          0x130de, 0x171de, 0x170b0, 0x1b85c, 0x17098, 0x1b84e,\n          0x1708c, 0x17086, 0x1305c, 0x170dc, 0x1304e, 0x170ce,\n          0x17058, 0x1b82e, 0x1704c, 0x17046, 0x1302e, 0x1706e,\n          0x1702c, 0x17026, 0x10af0, 0x1857c, 0x10a78, 0x1853e,\n          0x10a3c, 0x10a1e, 0x10b7c, 0x10b3e, 0x1f0ba, 0x1e17a,\n          0x1c2fa, 0x185fa, 0x11ae0, 0x18d78, 0x1c6be, 0x11a70,\n          0x18d3c, 0x11a38, 0x18d1e, 0x11a1c, 0x11a0e, 0x10978,\n          0x184be, 0x11b78, 0x1093c, 0x11b3c, 0x1091e, 0x11b1e,\n          0x109be, 0x11bbe, 0x13ac0, 0x19d70, 0x1cebc, 0x13a60,\n          0x19d38, 0x1ce9e, 0x13a30, 0x19d1c, 0x13a18, 0x19d0e,\n          0x13a0c, 0x13a06, 0x11970, 0x18cbc, 0x13b70, 0x11938,\n          0x18c9e, 0x13b38, 0x1191c, 0x13b1c, 0x1190e, 0x13b0e,\n          0x108bc, 0x119bc, 0x1089e, 0x13bbc, 0x1199e, 0x13b9e,\n          0x1bd60, 0x1deb8, 0x1ef5e, 0x17a40, 0x1bd30, 0x1de9c,\n          0x17a20, 0x1bd18, 0x1de8e, 0x17a10, 0x1bd0c, 0x17a08,\n          0x1bd06, 0x17a04, 0x13960, 0x19cb8, 0x1ce5e, 0x17b60,\n          0x13930, 0x19c9c, 0x17b30, 0x1bd9c, 0x19c8e, 0x17b18,\n          0x1390c, 0x17b0c, 0x13906, 0x17b06, 0x118b8, 0x18c5e,\n          0x139b8, 0x1189c, 0x17bb8, 0x1399c, 0x1188e, 0x17b9c,\n          0x1398e, 0x17b8e, 0x1085e, 0x118de, 0x139de, 0x17bde,\n          0x17940, 0x1bcb0, 0x1de5c, 0x17920, 0x1bc98, 0x1de4e,\n          0x17910, 0x1bc8c, 0x17908, 0x1bc86, 0x17904, 0x17902,\n          0x138b0, 0x19c5c, 0x179b0, 0x13898, 0x19c4e, 0x17998,\n          0x1bcce, 0x1798c, 0x13886, 0x17986, 0x1185c, 0x138dc,\n          0x1184e, 0x179dc, 0x138ce, 0x179ce, 0x178a0, 0x1bc58,\n          0x1de2e, 0x17890, 0x1bc4c, 0x17888, 0x1bc46, 0x17884,\n          0x17882, 0x13858, 0x19c2e, 0x178d8, 0x1384c, 0x178cc,\n          0x13846, 0x178c6, 0x1182e, 0x1386e, 0x178ee, 0x17850,\n          0x1bc2c, 0x17848, 0x1bc26, 0x17844, 0x17842, 0x1382c,\n          0x1786c, 0x13826, 0x17866, 0x17828, 0x1bc16, 0x17824,\n          0x17822, 0x13816, 0x17836, 0x10578, 0x182be, 0x1053c,\n          0x1051e, 0x105be, 0x10d70, 0x186bc, 0x10d38, 0x1869e,\n          0x10d1c, 0x10d0e, 0x104bc, 0x10dbc, 0x1049e, 0x10d9e,\n          0x11d60, 0x18eb8, 0x1c75e, 0x11d30, 0x18e9c, 0x11d18,\n          0x18e8e, 0x11d0c, 0x11d06, 0x10cb8, 0x1865e, 0x11db8,\n          0x10c9c, 0x11d9c, 0x10c8e, 0x11d8e, 0x1045e, 0x10cde,\n          0x11dde, 0x13d40, 0x19eb0, 0x1cf5c, 0x13d20, 0x19e98,\n          0x1cf4e, 0x13d10, 0x19e8c, 0x13d08, 0x19e86, 0x13d04,\n          0x13d02, 0x11cb0, 0x18e5c, 0x13db0, 0x11c98, 0x18e4e,\n          0x13d98, 0x19ece, 0x13d8c, 0x11c86, 0x13d86, 0x10c5c,\n          0x11cdc, 0x10c4e, 0x13ddc, 0x11cce, 0x13dce, 0x1bea0,\n          0x1df58, 0x1efae, 0x1be90, 0x1df4c, 0x1be88, 0x1df46,\n          0x1be84, 0x1be82, 0x13ca0, 0x19e58, 0x1cf2e, 0x17da0,\n          0x13c90, 0x19e4c, 0x17d90, 0x1becc, 0x19e46, 0x17d88,\n          0x13c84, 0x17d84, 0x13c82, 0x17d82, 0x11c58, 0x18e2e,\n          0x13cd8, 0x11c4c, 0x17dd8, 0x13ccc, 0x11c46, 0x17dcc,\n          0x13cc6, 0x17dc6, 0x10c2e, 0x11c6e, 0x13cee, 0x17dee,\n          0x1be50, 0x1df2c, 0x1be48, 0x1df26, 0x1be44, 0x1be42,\n          0x13c50, 0x19e2c, 0x17cd0, 0x13c48, 0x19e26, 0x17cc8,\n          0x1be66, 0x17cc4, 0x13c42, 0x17cc2, 0x11c2c, 0x13c6c,\n          0x11c26, 0x17cec, 0x13c66, 0x17ce6, 0x1be28, 0x1df16,\n          0x1be24, 0x1be22, 0x13c28, 0x19e16, 0x17c68, 0x13c24,\n          0x17c64, 0x13c22, 0x17c62, 0x11c16, 0x13c36, 0x17c76,\n          0x1be14, 0x1be12, 0x13c14, 0x17c34, 0x13c12, 0x17c32,\n          0x102bc, 0x1029e, 0x106b8, 0x1835e, 0x1069c, 0x1068e,\n          0x1025e, 0x106de, 0x10eb0, 0x1875c, 0x10e98, 0x1874e,\n          0x10e8c, 0x10e86, 0x1065c, 0x10edc, 0x1064e, 0x10ece,\n          0x11ea0, 0x18f58, 0x1c7ae, 0x11e90, 0x18f4c, 0x11e88,\n          0x18f46, 0x11e84, 0x11e82, 0x10e58, 0x1872e, 0x11ed8,\n          0x18f6e, 0x11ecc, 0x10e46, 0x11ec6, 0x1062e, 0x10e6e,\n          0x11eee, 0x19f50, 0x1cfac, 0x19f48, 0x1cfa6, 0x19f44,\n          0x19f42, 0x11e50, 0x18f2c, 0x13ed0, 0x19f6c, 0x18f26,\n          0x13ec8, 0x11e44, 0x13ec4, 0x11e42, 0x13ec2, 0x10e2c,\n          0x11e6c, 0x10e26, 0x13eec, 0x11e66, 0x13ee6, 0x1dfa8,\n          0x1efd6, 0x1dfa4, 0x1dfa2, 0x19f28, 0x1cf96, 0x1bf68,\n          0x19f24, 0x1bf64, 0x19f22, 0x1bf62, 0x11e28, 0x18f16,\n          0x13e68, 0x11e24, 0x17ee8, 0x13e64, 0x11e22, 0x17ee4,\n          0x13e62, 0x17ee2, 0x10e16, 0x11e36, 0x13e76, 0x17ef6,\n          0x1df94, 0x1df92, 0x19f14, 0x1bf34, 0x19f12, 0x1bf32,\n          0x11e14, 0x13e34, 0x11e12, 0x17e74, 0x13e32, 0x17e72,\n          0x1df8a, 0x19f0a, 0x1bf1a, 0x11e0a, 0x13e1a, 0x17e3a,\n          0x1035c, 0x1034e, 0x10758, 0x183ae, 0x1074c, 0x10746,\n          0x1032e, 0x1076e, 0x10f50, 0x187ac, 0x10f48, 0x187a6,\n          0x10f44, 0x10f42, 0x1072c, 0x10f6c, 0x10726, 0x10f66,\n          0x18fa8, 0x1c7d6, 0x18fa4, 0x18fa2, 0x10f28, 0x18796,\n          0x11f68, 0x18fb6, 0x11f64, 0x10f22, 0x11f62, 0x10716,\n          0x10f36, 0x11f76, 0x1cfd4, 0x1cfd2, 0x18f94, 0x19fb4,\n          0x18f92, 0x19fb2, 0x10f14, 0x11f34, 0x10f12, 0x13f74,\n          0x11f32, 0x13f72, 0x1cfca, 0x18f8a, 0x19f9a, 0x10f0a,\n          0x11f1a, 0x13f3a, 0x103ac, 0x103a6, 0x107a8, 0x183d6,\n          0x107a4, 0x107a2, 0x10396, 0x107b6, 0x187d4, 0x187d2,\n          0x10794, 0x10fb4, 0x10792, 0x10fb2, 0x1c7ea}};\n\n  private static final float PREFERRED_RATIO = 3.0f;\n  private static final float DEFAULT_MODULE_WIDTH = 0.357f; //1px in mm\n  private static final float HEIGHT = 2.0f; //mm\n\n  private BarcodeMatrix barcodeMatrix;\n  private boolean compact;\n  private Compaction compaction;\n  private int minCols;\n  private int maxCols;\n  private int maxRows;\n  private int minRows;\n\n  PDF417() {\n    this(false);\n  }\n\n  PDF417(boolean compact) {\n    this.compact = compact;\n    compaction = Compaction.AUTO;\n    minCols = 2;\n    maxCols = 30;\n    maxRows = 30;\n    minRows = 2;\n  }\n\n  BarcodeMatrix getBarcodeMatrix() {\n    return barcodeMatrix;\n  }\n\n  /**\n   * Calculates the necessary number of rows as described in annex Q of ISO/IEC 15438:2001(E).\n   *\n   * @param m the number of source codewords prior to the additional of the Symbol Length\n   *          Descriptor and any pad codewords\n   * @param k the number of error correction codewords\n   * @param c the number of columns in the symbol in the data region (excluding start, stop and\n   *          row indicator codewords)\n   * @return the number of rows in the symbol (r)\n   */\n  private static int getNumberOfRows(int m, int k, int c) throws WriterException {\n    int r = calculateNumberOfRows(m, k, c);\n    if (r > 90) {\n      throw new WriterException(\n          \"The message doesn't fit in the configured symbol size.\"\n              + \" The resultant number of rows for this barcode exceeds 90.\"\n              + \" Please increase the number of columns or decrease the error correction\"\n              + \" level to reduce the number of rows.\");\n    }\n    if (r < 2) {\n      throw new WriterException(\n          \"The message is too short for the configured symbol size.\"\n              + \" The resultant number of rows is less than 3.\"\n              + \" Please decrease the number of columns or increase the error correction\"\n              + \" level to increase the number of rows.\");\n    }\n    return r;\n  }\n\n  /**\n   * Calculates the necessary number of rows as described in annex Q of ISO/IEC 15438:2001(E).\n   *\n   * @param m the number of source codewords prior to the additional of the Symbol Length\n   *          Descriptor and any pad codewords\n   * @param k the number of error correction codewords\n   * @param c the number of columns in the symbol in the data region (excluding start, stop and\n   *          row indicator codewords)\n   * @return the number of rows in the symbol (r)\n   */\n  private static int calculateNumberOfRows(int m, int k, int c) {\n    int r = ((m + 1 + k) / c) + 1;\n    if (c * r >= (m + 1 + k + c)) {\n      r--;\n    }\n    return r;\n  }\n\n  /**\n   * Calculates the number of pad codewords as described in 4.9.2 of ISO/IEC 15438:2001(E).\n   *\n   * @param m the number of source codewords prior to the additional of the Symbol Length\n   *          Descriptor and any pad codewords\n   * @param k the number of error correction codewords\n   * @param c the number of columns in the symbol in the data region (excluding start, stop and\n   *          row indicator codewords)\n   * @param r the number of rows in the symbol\n   * @return the number of pad codewords\n   */\n  private static int getNumberOfPadCodewords(int m, int k, int c, int r) {\n    int n = c * r - k;\n    return n > m + 1 ? n - m - 1 : 0;\n  }\n\n  private static void encodeChar(int pattern, int len, BarcodeRow logic) {\n    int map = 1 << len - 1;\n    boolean last = (pattern & map) != 0; //Initialize to inverse of first bit\n    int width = 0;\n    for (int i = 0; i < len; i++) {\n      boolean black = (pattern & map) != 0;\n      if (last == black) {\n        width++;\n      } else {\n        logic.addBar(last, width);\n\n        last = black;\n        width = 1;\n      }\n      map >>= 1;\n    }\n    logic.addBar(last, width);\n  }\n\n  private void encodeLowLevel(CharSequence fullCodewords,\n                              int c,\n                              int r,\n                              int errorCorrectionLevel,\n                              BarcodeMatrix logic) {\n\n    int idx = 0;\n    for (int y = 0; y < r; y++) {\n      int cluster = y % 3;\n      logic.startRow();\n      encodeChar(START_PATTERN, 17, logic.getCurrentRow());\n\n      int left;\n      int right;\n      if (cluster == 0) {\n        left = (30 * (y / 3)) + ((r - 1) / 3);\n        right = (30 * (y / 3)) + (c - 1);\n      } else if (cluster == 1) {\n        left = (30 * (y / 3)) + (errorCorrectionLevel * 3) + ((r - 1) % 3);\n        right = (30 * (y / 3)) + ((r - 1) / 3);\n      } else {\n        left = (30 * (y / 3)) + (c - 1);\n        right = (30 * (y / 3)) + (errorCorrectionLevel * 3) + ((r - 1) % 3);\n      }\n\n      int pattern = CODEWORD_TABLE[cluster][left];\n      encodeChar(pattern, 17, logic.getCurrentRow());\n\n      for (int x = 0; x < c; x++) {\n        pattern = CODEWORD_TABLE[cluster][fullCodewords.charAt(idx)];\n        encodeChar(pattern, 17, logic.getCurrentRow());\n        idx++;\n      }\n\n      if (compact) {\n        encodeChar(STOP_PATTERN, 1, logic.getCurrentRow()); // encodes stop line for compact pdf417\n      } else {\n        pattern = CODEWORD_TABLE[cluster][right];\n        encodeChar(pattern, 17, logic.getCurrentRow());\n\n        encodeChar(STOP_PATTERN, 18, logic.getCurrentRow());\n      }\n    }\n  }\n\n  /**\n   * Generates the barcode logic.\n   *\n   * @param msg        the message to encode\n   */\n  void generateBarcodeLogic(String msg, int errorCorrectionLevel) throws WriterException {\n\n    //1. step: High-level encoding\n    int errorCorrectionCodeWords = PDF417ErrorCorrection.getErrorCorrectionCodewordCount(errorCorrectionLevel);\n    String highLevel = PDF417HighLevelEncoder.encodeHighLevel(msg, compaction);\n    int sourceCodeWords = highLevel.length();\n\n    int[] dimension = determineDimensions(sourceCodeWords, errorCorrectionCodeWords);\n\n    int cols = dimension[0];\n    int rows = dimension[1];\n\n    int pad = getNumberOfPadCodewords(sourceCodeWords, errorCorrectionCodeWords, cols, rows);\n\n    //2. step: construct data codewords\n    if (sourceCodeWords + errorCorrectionCodeWords + 1 > 929) { // +1 for symbol length CW\n      throw new WriterException(\n          \"Encoded message contains to many code words, message to big (\" + msg.length() + \" bytes)\");\n    }\n    int n = sourceCodeWords + pad + 1;\n    StringBuilder sb = new StringBuilder(n);\n    sb.append((char) n);\n    sb.append(highLevel);\n    for (int i = 0; i < pad; i++) {\n      sb.append((char) 900); //PAD characters\n    }\n    String dataCodewords = sb.toString();\n\n    //3. step: Error correction\n    String ec = PDF417ErrorCorrection.generateErrorCorrection(dataCodewords, errorCorrectionLevel);\n    String fullCodewords = dataCodewords + ec;\n\n    //4. step: low-level encoding\n    barcodeMatrix = new BarcodeMatrix(rows, cols);\n    encodeLowLevel(fullCodewords, cols, rows, errorCorrectionLevel, barcodeMatrix);\n  }\n\n  /**\n   * Determine optimal nr of columns and rows for the specified number of\n   * codewords.\n   *\n   * @param sourceCodeWords number of code words\n   * @param errorCorrectionCodeWords number of error correction code words\n   * @return dimension object containing cols as width and rows as height\n   */\n  int[] determineDimensions(int sourceCodeWords, int errorCorrectionCodeWords) throws WriterException {\n    float ratio = 0.0f;\n    int[] dimension = null;\n\n    for (int cols = minCols; cols <= maxCols; cols++) {\n\n      int rows = calculateNumberOfRows(sourceCodeWords, errorCorrectionCodeWords, cols);\n\n      if (rows < minRows) {\n        break;\n      }\n\n      if (rows > maxRows) {\n        continue;\n      }\n\n      float newRatio = ((17 * cols + 69) * DEFAULT_MODULE_WIDTH) / (rows * HEIGHT);\n\n      // ignore if previous ratio is closer to preferred ratio\n      if (dimension != null && Math.abs(newRatio - PREFERRED_RATIO) > Math.abs(ratio - PREFERRED_RATIO)) {\n        continue;\n      }\n\n      ratio = newRatio;\n      dimension = new int[] {cols, rows};\n    }\n\n     // Handle case when min values were larger than necessary\n     if (dimension == null) {\n       int rows = calculateNumberOfRows(sourceCodeWords, errorCorrectionCodeWords, minCols);\n       if (rows < minRows) {\n         dimension = new int[]{minCols, minRows};\n       }\n     }\n\n    if (dimension == null) {\n      throw new WriterException(\"Unable to fit message in columns\");\n    }\n\n    return dimension;\n  }\n\n  /**\n   * Sets max/min row/col values\n   */\n  void setDimensions(int maxCols, int minCols, int maxRows, int minRows) {\n    this.maxCols = maxCols;\n    this.minCols = minCols;\n    this.maxRows = maxRows;\n    this.minRows = minRows;\n  }\n\n  /**\n   * Sets compaction to values stored in {@link Compaction} enum\n   */\n  void setCompaction(Compaction compaction) {\n    this.compaction = compaction;\n  }\n\n  /**\n   * Sets compact to be true or false\n   * @param compact\n   */\n  void setCompact(boolean compact) {\n    this.compact = compact;\n  }\n\n}\n\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/pdf417/encoder/PDF417ErrorCorrection.java",
    "content": "/*\n * Copyright 2006 Jeremias Maerki in part, and ZXing Authors in part\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * This file has been modified from its original form in Barcode4J.\n */\n\npackage com.google.zxing.pdf417.encoder;\n\nimport com.google.zxing.WriterException;\n\n/**\n * PDF417 error correction code following the algorithm described in ISO/IEC 15438:2001(E) in\n * chapter 4.10.\n */\nfinal class PDF417ErrorCorrection {\n\n  /**\n   * Tables of coefficients for calculating error correction words\n   * (see annex F, ISO/IEC 15438:2001(E))\n   */\n  private static final int[][] EC_COEFFICIENTS = {\n      {27, 917},\n      {522, 568, 723, 809},\n      {237, 308, 436, 284, 646, 653, 428, 379},\n      {274, 562, 232, 755, 599, 524, 801, 132, 295, 116, 442, 428, 295,\n          42, 176, 65},\n      {361, 575, 922, 525, 176, 586, 640, 321, 536, 742, 677, 742, 687,\n          284, 193, 517, 273, 494, 263, 147, 593, 800, 571, 320, 803,\n          133, 231, 390, 685, 330, 63, 410},\n      {539, 422, 6, 93, 862, 771, 453, 106, 610, 287, 107, 505, 733,\n          877, 381, 612, 723, 476, 462, 172, 430, 609, 858, 822, 543,\n          376, 511, 400, 672, 762, 283, 184, 440, 35, 519, 31, 460,\n          594, 225, 535, 517, 352, 605, 158, 651, 201, 488, 502, 648,\n          733, 717, 83, 404, 97, 280, 771, 840, 629, 4, 381, 843,\n          623, 264, 543},\n      {521, 310, 864, 547, 858, 580, 296, 379, 53, 779, 897, 444, 400,\n          925, 749, 415, 822, 93, 217, 208, 928, 244, 583, 620, 246,\n          148, 447, 631, 292, 908, 490, 704, 516, 258, 457, 907, 594,\n          723, 674, 292, 272, 96, 684, 432, 686, 606, 860, 569, 193,\n          219, 129, 186, 236, 287, 192, 775, 278, 173, 40, 379, 712,\n          463, 646, 776, 171, 491, 297, 763, 156, 732, 95, 270, 447,\n          90, 507, 48, 228, 821, 808, 898, 784, 663, 627, 378, 382,\n          262, 380, 602, 754, 336, 89, 614, 87, 432, 670, 616, 157,\n          374, 242, 726, 600, 269, 375, 898, 845, 454, 354, 130, 814,\n          587, 804, 34, 211, 330, 539, 297, 827, 865, 37, 517, 834,\n          315, 550, 86, 801, 4, 108, 539},\n      {524, 894, 75, 766, 882, 857, 74, 204, 82, 586, 708, 250, 905,\n          786, 138, 720, 858, 194, 311, 913, 275, 190, 375, 850, 438,\n          733, 194, 280, 201, 280, 828, 757, 710, 814, 919, 89, 68,\n          569, 11, 204, 796, 605, 540, 913, 801, 700, 799, 137, 439,\n          418, 592, 668, 353, 859, 370, 694, 325, 240, 216, 257, 284,\n          549, 209, 884, 315, 70, 329, 793, 490, 274, 877, 162, 749,\n          812, 684, 461, 334, 376, 849, 521, 307, 291, 803, 712, 19,\n          358, 399, 908, 103, 511, 51, 8, 517, 225, 289, 470, 637,\n          731, 66, 255, 917, 269, 463, 830, 730, 433, 848, 585, 136,\n          538, 906, 90, 2, 290, 743, 199, 655, 903, 329, 49, 802,\n          580, 355, 588, 188, 462, 10, 134, 628, 320, 479, 130, 739,\n          71, 263, 318, 374, 601, 192, 605, 142, 673, 687, 234, 722,\n          384, 177, 752, 607, 640, 455, 193, 689, 707, 805, 641, 48,\n          60, 732, 621, 895, 544, 261, 852, 655, 309, 697, 755, 756,\n          60, 231, 773, 434, 421, 726, 528, 503, 118, 49, 795, 32,\n          144, 500, 238, 836, 394, 280, 566, 319, 9, 647, 550, 73,\n          914, 342, 126, 32, 681, 331, 792, 620, 60, 609, 441, 180,\n          791, 893, 754, 605, 383, 228, 749, 760, 213, 54, 297, 134,\n          54, 834, 299, 922, 191, 910, 532, 609, 829, 189, 20, 167,\n          29, 872, 449, 83, 402, 41, 656, 505, 579, 481, 173, 404,\n          251, 688, 95, 497, 555, 642, 543, 307, 159, 924, 558, 648,\n          55, 497, 10},\n      {352, 77, 373, 504, 35, 599, 428, 207, 409, 574, 118, 498, 285,\n          380, 350, 492, 197, 265, 920, 155, 914, 299, 229, 643, 294,\n          871, 306, 88, 87, 193, 352, 781, 846, 75, 327, 520, 435,\n          543, 203, 666, 249, 346, 781, 621, 640, 268, 794, 534, 539,\n          781, 408, 390, 644, 102, 476, 499, 290, 632, 545, 37, 858,\n          916, 552, 41, 542, 289, 122, 272, 383, 800, 485, 98, 752,\n          472, 761, 107, 784, 860, 658, 741, 290, 204, 681, 407, 855,\n          85, 99, 62, 482, 180, 20, 297, 451, 593, 913, 142, 808,\n          684, 287, 536, 561, 76, 653, 899, 729, 567, 744, 390, 513,\n          192, 516, 258, 240, 518, 794, 395, 768, 848, 51, 610, 384,\n          168, 190, 826, 328, 596, 786, 303, 570, 381, 415, 641, 156,\n          237, 151, 429, 531, 207, 676, 710, 89, 168, 304, 402, 40,\n          708, 575, 162, 864, 229, 65, 861, 841, 512, 164, 477, 221,\n          92, 358, 785, 288, 357, 850, 836, 827, 736, 707, 94, 8,\n          494, 114, 521, 2, 499, 851, 543, 152, 729, 771, 95, 248,\n          361, 578, 323, 856, 797, 289, 51, 684, 466, 533, 820, 669,\n          45, 902, 452, 167, 342, 244, 173, 35, 463, 651, 51, 699,\n          591, 452, 578, 37, 124, 298, 332, 552, 43, 427, 119, 662,\n          777, 475, 850, 764, 364, 578, 911, 283, 711, 472, 420, 245,\n          288, 594, 394, 511, 327, 589, 777, 699, 688, 43, 408, 842,\n          383, 721, 521, 560, 644, 714, 559, 62, 145, 873, 663, 713,\n          159, 672, 729, 624, 59, 193, 417, 158, 209, 563, 564, 343,\n          693, 109, 608, 563, 365, 181, 772, 677, 310, 248, 353, 708,\n          410, 579, 870, 617, 841, 632, 860, 289, 536, 35, 777, 618,\n          586, 424, 833, 77, 597, 346, 269, 757, 632, 695, 751, 331,\n          247, 184, 45, 787, 680, 18, 66, 407, 369, 54, 492, 228,\n          613, 830, 922, 437, 519, 644, 905, 789, 420, 305, 441, 207,\n          300, 892, 827, 141, 537, 381, 662, 513, 56, 252, 341, 242,\n          797, 838, 837, 720, 224, 307, 631, 61, 87, 560, 310, 756,\n          665, 397, 808, 851, 309, 473, 795, 378, 31, 647, 915, 459,\n          806, 590, 731, 425, 216, 548, 249, 321, 881, 699, 535, 673,\n          782, 210, 815, 905, 303, 843, 922, 281, 73, 469, 791, 660,\n          162, 498, 308, 155, 422, 907, 817, 187, 62, 16, 425, 535,\n          336, 286, 437, 375, 273, 610, 296, 183, 923, 116, 667, 751,\n          353, 62, 366, 691, 379, 687, 842, 37, 357, 720, 742, 330,\n          5, 39, 923, 311, 424, 242, 749, 321, 54, 669, 316, 342,\n          299, 534, 105, 667, 488, 640, 672, 576, 540, 316, 486, 721,\n          610, 46, 656, 447, 171, 616, 464, 190, 531, 297, 321, 762,\n          752, 533, 175, 134, 14, 381, 433, 717, 45, 111, 20, 596,\n          284, 736, 138, 646, 411, 877, 669, 141, 919, 45, 780, 407,\n          164, 332, 899, 165, 726, 600, 325, 498, 655, 357, 752, 768,\n          223, 849, 647, 63, 310, 863, 251, 366, 304, 282, 738, 675,\n          410, 389, 244, 31, 121, 303, 263}};\n\n  private PDF417ErrorCorrection() {\n  }\n\n  /**\n   * Determines the number of error correction codewords for a specified error correction\n   * level.\n   *\n   * @param errorCorrectionLevel the error correction level (0-8)\n   * @return the number of codewords generated for error correction\n   */\n  static int getErrorCorrectionCodewordCount(int errorCorrectionLevel) {\n    if (errorCorrectionLevel < 0 || errorCorrectionLevel > 8) {\n      throw new IllegalArgumentException(\"Error correction level must be between 0 and 8!\");\n    }\n    return 1 << (errorCorrectionLevel + 1);\n  }\n\n  /**\n   * Returns the recommended minimum error correction level as described in annex E of\n   * ISO/IEC 15438:2001(E).\n   *\n   * @param n the number of data codewords\n   * @return the recommended minimum error correction level\n   */\n  static int getRecommendedMinimumErrorCorrectionLevel(int n) throws WriterException {\n    if (n <= 0) {\n      throw new IllegalArgumentException(\"n must be > 0\");\n    }\n    if (n <= 40) {\n      return 2;\n    }\n    if (n <= 160) {\n      return 3;\n    }\n    if (n <= 320) {\n      return 4;\n    }\n    if (n <= 863) {\n      return 5;\n    }\n    throw new WriterException(\"No recommendation possible\");\n  }\n\n  /**\n   * Generates the error correction codewords according to 4.10 in ISO/IEC 15438:2001(E).\n   *\n   * @param dataCodewords        the data codewords\n   * @param errorCorrectionLevel the error correction level (0-8)\n   * @return the String representing the error correction codewords\n   */\n  static String generateErrorCorrection(CharSequence dataCodewords, int errorCorrectionLevel) {\n    int k = getErrorCorrectionCodewordCount(errorCorrectionLevel);\n    char[] e = new char[k];\n    int sld = dataCodewords.length();\n    for (int i = 0; i < sld; i++) {\n      int t1 = (dataCodewords.charAt(i) + e[e.length - 1]) % 929;\n      int t2;\n      int t3;\n      for (int j = k - 1; j >= 1; j--) {\n        t2 = (t1 * EC_COEFFICIENTS[errorCorrectionLevel][j]) % 929;\n        t3 = 929 - t2;\n        e[j] = (char) ((e[j - 1] + t3) % 929);\n      }\n      t2 = (t1 * EC_COEFFICIENTS[errorCorrectionLevel][0]) % 929;\n      t3 = 929 - t2;\n      e[0] = (char) (t3 % 929);\n    }\n    StringBuilder sb = new StringBuilder(k);\n    for (int j = k - 1; j >= 0; j--) {\n      if (e[j] != 0) {\n        e[j] = (char) (929 - e[j]);\n      }\n      sb.append(e[j]);\n    }\n    return sb.toString();\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/pdf417/encoder/PDF417HighLevelEncoder.java",
    "content": "/*\n * Copyright 2006 Jeremias Maerki in part, and ZXing Authors in part\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * This file has been modified from its original form in Barcode4J.\n */\n\npackage com.google.zxing.pdf417.encoder;\n\nimport com.google.zxing.WriterException;\n\nimport java.math.BigInteger;\nimport java.util.Arrays;\n\n/**\n * PDF417 high-level encoder following the algorithm described in ISO/IEC 15438:2001(E) in\n * annex P.\n */\nfinal class PDF417HighLevelEncoder {\n\n  /**\n   * code for Text compaction\n   */\n  private static final int TEXT_COMPACTION = 0;\n\n  /**\n   * code for Byte compaction\n   */\n  private static final int BYTE_COMPACTION = 1;\n\n  /**\n   * code for Numeric compaction\n   */\n  private static final int NUMERIC_COMPACTION = 2;\n\n  /**\n   * Text compaction submode Alpha\n   */\n  private static final int SUBMODE_ALPHA = 0;\n\n  /**\n   * Text compaction submode Lower\n   */\n  private static final int SUBMODE_LOWER = 1;\n\n  /**\n   * Text compaction submode Mixed\n   */\n  private static final int SUBMODE_MIXED = 2;\n\n  /**\n   * Text compaction submode Punctuation\n   */\n  private static final int SUBMODE_PUNCTUATION = 3;\n\n  /**\n   * mode latch to Text Compaction mode\n   */\n  private static final int LATCH_TO_TEXT = 900;\n\n  /**\n   * mode latch to Byte Compaction mode (number of characters NOT a multiple of 6)\n   */\n  private static final int LATCH_TO_BYTE_PADDED = 901;\n\n  /**\n   * mode latch to Numeric Compaction mode\n   */\n  private static final int LATCH_TO_NUMERIC = 902;\n\n  /**\n   * mode shift to Byte Compaction mode\n   */\n  private static final int SHIFT_TO_BYTE = 913;\n\n  /**\n   * mode latch to Byte Compaction mode (number of characters a multiple of 6)\n   */\n  private static final int LATCH_TO_BYTE = 924;\n\n  /**\n   * Raw code table for text compaction Mixed sub-mode\n   */\n  private static final byte[] TEXT_MIXED_RAW = {\n      48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 38, 13, 9, 44, 58,\n      35, 45, 46, 36, 47, 43, 37, 42, 61, 94, 0, 32, 0, 0, 0};\n\n  /**\n   * Raw code table for text compaction: Punctuation sub-mode\n   */\n  private static final byte[] TEXT_PUNCTUATION_RAW = {\n      59, 60, 62, 64, 91, 92, 93, 95, 96, 126, 33, 13, 9, 44, 58,\n      10, 45, 46, 36, 47, 34, 124, 42, 40, 41, 63, 123, 125, 39, 0};\n\n  private static final byte[] MIXED = new byte[128];\n  private static final byte[] PUNCTUATION = new byte[128];\n\n  private PDF417HighLevelEncoder() {\n  }\n\n  static {\n    //Construct inverse lookups\n    Arrays.fill(MIXED, (byte) -1);\n    for (byte i = 0; i < TEXT_MIXED_RAW.length; i++) {\n      byte b = TEXT_MIXED_RAW[i];\n      if (b > 0) {\n        MIXED[b] = i;\n      }\n    }\n    Arrays.fill(PUNCTUATION, (byte) -1);\n    for (byte i = 0; i < TEXT_PUNCTUATION_RAW.length; i++) {\n      byte b = TEXT_PUNCTUATION_RAW[i];\n      if (b > 0) {\n        PUNCTUATION[b] = i;\n      }\n    }\n  }\n\n  /**\n   * Converts the message to a byte array using the default encoding (cp437) as defined by the\n   * specification\n   *\n   * @param msg the message\n   * @return the byte array of the message\n   */\n  private static byte[] getBytesForMessage(String msg) {\n    return msg.getBytes();\n  }\n\n  /**\n   * Performs high-level encoding of a PDF417 message using the algorithm described in annex P\n   * of ISO/IEC 15438:2001(E). If byte compaction has been selected, then only byte compaction\n   * is used.\n   *\n   * @param msg the message\n   * @return the encoded message (the char values range from 0 to 928)\n   */\n  static String encodeHighLevel(String msg, Compaction compaction) throws WriterException {\n    byte[] bytes = null; //Fill later and only if needed\n\n    //the codewords 0..928 are encoded as Unicode characters\n    StringBuilder sb = new StringBuilder(msg.length());\n\n    int len = msg.length();\n    int p = 0;\n    int textSubMode = SUBMODE_ALPHA;\n\n    // User selected encoding mode\n    if (compaction == Compaction.TEXT) {\n      encodeText(msg, p, len, sb, textSubMode);\n\n    } else if (compaction == Compaction.BYTE) {\n      bytes = getBytesForMessage(msg);\n      encodeBinary(bytes, p, bytes.length, BYTE_COMPACTION, sb);\n\n    } else if (compaction == Compaction.NUMERIC) {\n      sb.append((char) LATCH_TO_NUMERIC);\n      encodeNumeric(msg, p, len, sb);\n\n    } else {\n      int encodingMode = TEXT_COMPACTION; //Default mode, see 4.4.2.1\n      while (p < len) {\n        int n = determineConsecutiveDigitCount(msg, p);\n        if (n >= 13) {\n          sb.append((char) LATCH_TO_NUMERIC);\n          encodingMode = NUMERIC_COMPACTION;\n          textSubMode = SUBMODE_ALPHA; //Reset after latch\n          encodeNumeric(msg, p, n, sb);\n          p += n;\n        } else {\n          int t = determineConsecutiveTextCount(msg, p);\n          if (t >= 5 || n == len) {\n            if (encodingMode != TEXT_COMPACTION) {\n              sb.append((char) LATCH_TO_TEXT);\n              encodingMode = TEXT_COMPACTION;\n              textSubMode = SUBMODE_ALPHA; //start with submode alpha after latch\n            }\n            textSubMode = encodeText(msg, p, t, sb, textSubMode);\n            p += t;\n          } else {\n            if (bytes == null) {\n              bytes = getBytesForMessage(msg);\n            }\n            int b = determineConsecutiveBinaryCount(msg, bytes, p);\n            if (b == 0) {\n              b = 1;\n            }\n            if (b == 1 && encodingMode == TEXT_COMPACTION) {\n              //Switch for one byte (instead of latch)\n              encodeBinary(bytes, p, 1, TEXT_COMPACTION, sb);\n            } else {\n              //Mode latch performed by encodeBinary()\n              encodeBinary(bytes, p, b, encodingMode, sb);\n              encodingMode = BYTE_COMPACTION;\n              textSubMode = SUBMODE_ALPHA; //Reset after latch\n            }\n            p += b;\n          }\n        }\n      }\n    }\n\n    return sb.toString();\n  }\n\n  /**\n   * Encode parts of the message using Text Compaction as described in ISO/IEC 15438:2001(E),\n   * chapter 4.4.2.\n   *\n   * @param msg            the message\n   * @param startpos       the start position within the message\n   * @param count          the number of characters to encode\n   * @param sb             receives the encoded codewords\n   * @param initialSubmode should normally be SUBMODE_ALPHA\n   * @return the text submode in which this method ends\n   */\n  private static int encodeText(CharSequence msg,\n                                int startpos,\n                                int count,\n                                StringBuilder sb,\n                                int initialSubmode) {\n    StringBuilder tmp = new StringBuilder(count);\n    int submode = initialSubmode;\n    int idx = 0;\n    while (true) {\n      char ch = msg.charAt(startpos + idx);\n      switch (submode) {\n        case SUBMODE_ALPHA:\n          if (isAlphaUpper(ch)) {\n            if (ch == ' ') {\n              tmp.append((char) 26); //space\n            } else {\n              tmp.append((char) (ch - 65));\n            }\n          } else {\n            if (isAlphaLower(ch)) {\n              submode = SUBMODE_LOWER;\n              tmp.append((char) 27); //ll\n              continue;\n            } else if (isMixed(ch)) {\n              submode = SUBMODE_MIXED;\n              tmp.append((char) 28); //ml\n              continue;\n            } else {\n              tmp.append((char) 29); //ps\n              tmp.append((char) PUNCTUATION[ch]);\n              break;\n            }\n          }\n          break;\n        case SUBMODE_LOWER:\n          if (isAlphaLower(ch)) {\n            if (ch == ' ') {\n              tmp.append((char) 26); //space\n            } else {\n              tmp.append((char) (ch - 97));\n            }\n          } else {\n            if (isAlphaUpper(ch)) {\n              tmp.append((char) 27); //as\n              tmp.append((char) (ch - 65));\n              //space cannot happen here, it is also in \"Lower\"\n              break;\n            } else if (isMixed(ch)) {\n              submode = SUBMODE_MIXED;\n              tmp.append((char) 28); //ml\n              continue;\n            } else {\n              tmp.append((char) 29); //ps\n              tmp.append((char) PUNCTUATION[ch]);\n              break;\n            }\n          }\n          break;\n        case SUBMODE_MIXED:\n          if (isMixed(ch)) {\n            tmp.append((char) MIXED[ch]);\n          } else {\n            if (isAlphaUpper(ch)) {\n              submode = SUBMODE_ALPHA;\n              tmp.append((char) 28); //al\n              continue;\n            } else if (isAlphaLower(ch)) {\n              submode = SUBMODE_LOWER;\n              tmp.append((char) 27); //ll\n              continue;\n            } else {\n              if (startpos + idx + 1 < count) {\n                char next = msg.charAt(startpos + idx + 1);\n                if (isPunctuation(next)) {\n                  submode = SUBMODE_PUNCTUATION;\n                  tmp.append((char) 25); //pl\n                  continue;\n                }\n              }\n              tmp.append((char) 29); //ps\n              tmp.append((char) PUNCTUATION[ch]);\n            }\n          }\n          break;\n        default: //SUBMODE_PUNCTUATION\n          if (isPunctuation(ch)) {\n            tmp.append((char) PUNCTUATION[ch]);\n          } else {\n            submode = SUBMODE_ALPHA;\n            tmp.append((char) 29); //al\n            continue;\n          }\n      }\n      idx++;\n      if (idx >= count) {\n        break;\n      }\n    }\n    char h = 0;\n    int len = tmp.length();\n    for (int i = 0; i < len; i++) {\n      boolean odd = (i % 2) != 0;\n      if (odd) {\n        h = (char) ((h * 30) + tmp.charAt(i));\n        sb.append(h);\n      } else {\n        h = tmp.charAt(i);\n      }\n    }\n    if ((len % 2) != 0) {\n      sb.append((char) ((h * 30) + 29)); //ps\n    }\n    return submode;\n  }\n\n  /**\n   * Encode parts of the message using Byte Compaction as described in ISO/IEC 15438:2001(E),\n   * chapter 4.4.3. The Unicode characters will be converted to binary using the cp437\n   * codepage.\n   *\n   * @param bytes     the message converted to a byte array\n   * @param startpos  the start position within the message\n   * @param count     the number of bytes to encode\n   * @param startmode the mode from which this method starts\n   * @param sb        receives the encoded codewords\n   */\n  private static void encodeBinary(byte[] bytes,\n                                   int startpos,\n                                   int count,\n                                   int startmode,\n                                   StringBuilder sb) {\n    if (count == 1 && startmode == TEXT_COMPACTION) {\n      sb.append((char) SHIFT_TO_BYTE);\n    }\n\n    int idx = startpos;\n    // Encode sixpacks\n    if (count >= 6) {\n      sb.append((char) LATCH_TO_BYTE);\n      char[] chars = new char[5];\n      while ((startpos + count - idx) >= 6) {\n        long t = 0;\n        for (int i = 0; i < 6; i++) {\n          t <<= 8;\n          t += bytes[idx + i] & 0xff;\n        }\n        for (int i = 0; i < 5; i++) {\n          chars[i] = (char) (t % 900);\n          t /= 900;\n        }\n        for (int i = chars.length - 1; i >= 0; i--) {\n          sb.append(chars[i]);\n        }\n        idx += 6;\n      }\n    }\n    //Encode rest (remaining n<5 bytes if any)\n    if (idx < startpos + count) {\n      sb.append((char) LATCH_TO_BYTE_PADDED);\n    }\n    for (int i = idx; i < startpos + count; i++) {\n      int ch = bytes[i] & 0xff;\n      sb.append((char) ch);\n    }\n  }\n\n  private static void encodeNumeric(String msg, int startpos, int count, StringBuilder sb) {\n    int idx = 0;\n    StringBuilder tmp = new StringBuilder(count / 3 + 1);\n    BigInteger num900 = BigInteger.valueOf(900);\n    BigInteger num0 = BigInteger.valueOf(0);\n    while (idx < count - 1) {\n      tmp.setLength(0);\n      int len = Math.min(44, count - idx);\n      String part = '1' + msg.substring(startpos + idx, startpos + idx + len);\n      BigInteger bigint = new BigInteger(part);\n      do {\n        BigInteger c = bigint.mod(num900);\n        tmp.append((char) c.intValue());\n        bigint = bigint.divide(num900);\n      } while (!bigint.equals(num0));\n\n      //Reverse temporary string\n      for (int i = tmp.length() - 1; i >= 0; i--) {\n        sb.append(tmp.charAt(i));\n      }\n      idx += len;\n    }\n  }\n\n\n  private static boolean isDigit(char ch) {\n    return ch >= '0' && ch <= '9';\n  }\n\n  private static boolean isAlphaUpper(char ch) {\n    return ch == ' ' || (ch >= 'A' && ch <= 'Z');\n  }\n\n  private static boolean isAlphaLower(char ch) {\n    return ch == ' ' || (ch >= 'a' && ch <= 'z');\n  }\n\n  private static boolean isMixed(char ch) {\n    return MIXED[ch] != -1;\n  }\n\n  private static boolean isPunctuation(char ch) {\n    return PUNCTUATION[ch] != -1;\n  }\n\n  private static boolean isText(char ch) {\n    return ch == '\\t' || ch == '\\n' || ch == '\\r' || (ch >= 32 && ch <= 126);\n  }\n\n  /**\n   * Determines the number of consecutive characters that are encodable using numeric compaction.\n   *\n   * @param msg      the message\n   * @param startpos the start position within the message\n   * @return the requested character count\n   */\n  private static int determineConsecutiveDigitCount(CharSequence msg, int startpos) {\n    int count = 0;\n    int len = msg.length();\n    int idx = startpos;\n    if (idx < len) {\n      char ch = msg.charAt(idx);\n      while (isDigit(ch) && idx < len) {\n        count++;\n        idx++;\n        if (idx < len) {\n          ch = msg.charAt(idx);\n        }\n      }\n    }\n    return count;\n  }\n\n  /**\n   * Determines the number of consecutive characters that are encodable using text compaction.\n   *\n   * @param msg      the message\n   * @param startpos the start position within the message\n   * @return the requested character count\n   */\n  private static int determineConsecutiveTextCount(CharSequence msg, int startpos) {\n    int len = msg.length();\n    int idx = startpos;\n    while (idx < len) {\n      char ch = msg.charAt(idx);\n      int numericCount = 0;\n      while (numericCount < 13 && isDigit(ch) && idx < len) {\n        numericCount++;\n        idx++;\n        if (idx < len) {\n          ch = msg.charAt(idx);\n        }\n      }\n      if (numericCount >= 13) {\n        return idx - startpos - numericCount;\n      }\n      if (numericCount > 0) {\n        //Heuristic: All text-encodable chars or digits are binary encodable\n        continue;\n      }\n      ch = msg.charAt(idx);\n\n      //Check if character is encodable\n      if (!isText(ch)) {\n        break;\n      }\n      idx++;\n    }\n    return idx - startpos;\n  }\n\n  /**\n   * Determines the number of consecutive characters that are encodable using binary compaction.\n   *\n   * @param msg      the message\n   * @param bytes    the message converted to a byte array\n   * @param startpos the start position within the message\n   * @return the requested character count\n   */\n  private static int determineConsecutiveBinaryCount(CharSequence msg, byte[] bytes, int startpos)\n      throws WriterException {\n    int len = msg.length();\n    int idx = startpos;\n    while (idx < len) {\n      char ch = msg.charAt(idx);\n      int numericCount = 0;\n\n      while (numericCount < 13 && isDigit(ch)) {\n        numericCount++;\n        //textCount++;\n        int i = idx + numericCount;\n        if (i >= len) {\n          break;\n        }\n        ch = msg.charAt(i);\n      }\n      if (numericCount >= 13) {\n        return idx - startpos;\n      }\n      int textCount = 0;\n      while (textCount < 5 && isText(ch)) {\n        textCount++;\n        int i = idx + textCount;\n        if (i >= len) {\n          break;\n        }\n        ch = msg.charAt(i);\n      }\n      if (textCount >= 5) {\n        return idx - startpos;\n      }\n      ch = msg.charAt(idx);\n\n      //Check if character is encodable\n      //Sun returns a ASCII 63 (?) for a character that cannot be mapped. Let's hope all\n      //other VMs do the same\n      if (bytes[idx] == 63 && ch != '?') {\n        throw new WriterException(\"Non-encodable character detected: \" + ch + \" (Unicode: \" + (int) ch + ')');\n      }\n      idx++;\n    }\n    return idx - startpos;\n  }\n\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/pdf417/encoder/PDF417Writer.java",
    "content": "/*\n * Copyright 2012 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.pdf417.encoder;\n\nimport com.google.zxing.BarcodeFormat;\nimport com.google.zxing.EncodeHintType;\nimport com.google.zxing.Writer;\nimport com.google.zxing.WriterException;\nimport com.google.zxing.common.BitMatrix;\n\nimport java.util.EnumMap;\nimport java.util.Map;\n\n/**\n * @author Jacob Haynes\n * @author qwandor@google.com (Andrew Walbran)\n */\npublic final class PDF417Writer implements Writer {\n\n  @Override\n  public BitMatrix encode(String contents,\n                          BarcodeFormat format,\n                          int width,\n                          int height,\n                          Map<EncodeHintType,?> hints) throws WriterException {\n    if (format != BarcodeFormat.PDF_417) {\n      throw new IllegalArgumentException(\"Can only encode PDF_417, but got \" + format);\n    }\n\n    PDF417 encoder = new PDF417();\n\n    if (hints != null) {\n      if (hints.containsKey(EncodeHintType.PDF417_COMPACT)) {\n        encoder.setCompact((Boolean) hints.get(EncodeHintType.PDF417_COMPACT));\n      }\n      if (hints.containsKey(EncodeHintType.PDF417_COMPACTION)) {\n        encoder.setCompaction((Compaction) hints.get(EncodeHintType.PDF417_COMPACTION));\n      }\n      if (hints.containsKey(EncodeHintType.PDF417_DIMENSIONS)) {\n        Dimensions dimensions = (Dimensions) hints.get(EncodeHintType.PDF417_DIMENSIONS);\n        encoder.setDimensions(dimensions.getMaxCols(),\n                              dimensions.getMinCols(),\n                              dimensions.getMaxRows(),\n                              dimensions.getMinRows());\n      }\n    }\n\n    return bitMatrixFromEncoder(encoder, contents, width, height);\n  }\n\n  @Override\n  public BitMatrix encode(String contents,\n                          BarcodeFormat format,\n                          int width,\n                          int height) throws WriterException {\n    return encode(contents, format, width, height, null);\n  }\n\n  /**\n   * @deprecated Use {@link #encode(String, BarcodeFormat, int, int, Map)} instead, with hints to\n   * specify the encoding options.\n   */\n  @Deprecated\n  public BitMatrix encode(String contents,\n                          BarcodeFormat format,\n                          boolean compact,\n                          int width,\n                          int height,\n                          int minCols,\n                          int maxCols,\n                          int minRows,\n                          int maxRows,\n                          Compaction compaction) throws WriterException {\n    Map<EncodeHintType, Object> hints = new EnumMap<EncodeHintType,Object>(EncodeHintType.class);\n    hints.put(EncodeHintType.PDF417_COMPACT, compact);\n    hints.put(EncodeHintType.PDF417_COMPACTION, compaction);\n    hints.put(EncodeHintType.PDF417_DIMENSIONS, new Dimensions(minCols, maxCols, minRows, maxRows));\n    return encode(contents, format, width, height, hints);\n  }\n\n  /**\n   * Takes encoder, accounts for width/height, and retrieves bit matrix\n   */\n  private static BitMatrix bitMatrixFromEncoder(PDF417 encoder,\n                                                String contents,\n                                                int width,\n                                                int height) throws WriterException {\n    int errorCorrectionLevel = 2;\n    encoder.generateBarcodeLogic(contents, errorCorrectionLevel);\n\n    int lineThickness = 2;\n    int aspectRatio = 4;\n    byte[][] originalScale = encoder.getBarcodeMatrix().getScaledMatrix(lineThickness, aspectRatio * lineThickness);\n    boolean rotated = false;\n    if ((height > width) ^ (originalScale[0].length < originalScale.length)) {\n      originalScale = rotateArray(originalScale);\n      rotated = true;\n    }\n\n    int scaleX = width / originalScale[0].length;\n    int scaleY = height / originalScale.length;\n\n    int scale;\n    if (scaleX < scaleY) {\n      scale = scaleX;\n    } else {\n      scale = scaleY;\n    }\n\n    if (scale > 1) {\n      byte[][] scaledMatrix =\n          encoder.getBarcodeMatrix().getScaledMatrix(scale * lineThickness, scale * aspectRatio * lineThickness);\n      if (rotated) {\n        scaledMatrix = rotateArray(scaledMatrix);\n      }\n      return bitMatrixFrombitArray(scaledMatrix);\n    }\n    return bitMatrixFrombitArray(originalScale);\n  }\n\n  /**\n   * This takes an array holding the values of the PDF 417\n   *\n   * @param input a byte array of information with 0 is black, and 1 is white\n   * @return BitMatrix of the input\n   */\n  private static BitMatrix bitMatrixFrombitArray(byte[][] input) {\n    // Creates a small whitespace border around the barcode\n    int whiteSpace = 30;\n\n    // Creates the bitmatrix with extra space for whitespace\n    BitMatrix output = new BitMatrix(input[0].length + 2 * whiteSpace, input.length + 2 * whiteSpace);\n    output.clear();\n    for (int y = 0, yOutput = output.getHeight() - whiteSpace; y < input.length; y++, yOutput--) {\n      for (int x = 0; x < input[0].length; x++) {\n        // Zero is white in the bytematrix\n        if (input[y][x] == 1) {\n          output.set(x + whiteSpace, yOutput);\n        }\n      }\n    }\n    return output;\n  }\n\n  /**\n   * Takes and rotates the it 90 degrees\n   */\n  private static byte[][] rotateArray(byte[][] bitarray) {\n    byte[][] temp = new byte[bitarray[0].length][bitarray.length];\n    for (int ii = 0; ii < bitarray.length; ii++) {\n      // This makes the direction consistent on screen when rotating the\n      // screen;\n      int inverseii = bitarray.length - ii - 1;\n      for (int jj = 0; jj < bitarray[0].length; jj++) {\n        temp[jj][inverseii] = bitarray[ii][jj];\n      }\n    }\n    return temp;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/qrcode/QRCodeReader.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.qrcode;\n\nimport com.google.zxing.BarcodeFormat;\nimport com.google.zxing.BinaryBitmap;\nimport com.google.zxing.ChecksumException;\nimport com.google.zxing.DecodeHintType;\nimport com.google.zxing.FormatException;\nimport com.google.zxing.NotFoundException;\nimport com.google.zxing.Reader;\nimport com.google.zxing.Result;\nimport com.google.zxing.ResultMetadataType;\nimport com.google.zxing.ResultPoint;\nimport com.google.zxing.common.BitMatrix;\nimport com.google.zxing.common.DecoderResult;\nimport com.google.zxing.common.DetectorResult;\nimport com.google.zxing.qrcode.decoder.Decoder;\nimport com.google.zxing.qrcode.detector.Detector;\n\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * This implementation can detect and decode QR Codes in an image.\n *\n * @author Sean Owen\n */\npublic class QRCodeReader implements Reader {\n\n  private static final ResultPoint[] NO_POINTS = new ResultPoint[0];\n\n  private final Decoder decoder = new Decoder();\n\n  protected Decoder getDecoder() {\n    return decoder;\n  }\n\n  /**\n   * Locates and decodes a QR code in an image.\n   *\n   * @return a String representing the content encoded by the QR code\n   * @throws NotFoundException if a QR code cannot be found\n   * @throws FormatException if a QR code cannot be decoded\n   * @throws ChecksumException if error correction fails\n   */\n  @Override\n  public Result decode(BinaryBitmap image) throws NotFoundException, ChecksumException, FormatException {\n    return decode(image, null);\n  }\n\n  @Override\n  public Result decode(BinaryBitmap image, Map<DecodeHintType,?> hints)\n      throws NotFoundException, ChecksumException, FormatException {\n    DecoderResult decoderResult;\n    ResultPoint[] points;\n    if (hints != null && hints.containsKey(DecodeHintType.PURE_BARCODE)) {\n      BitMatrix bits = extractPureBits(image.getBlackMatrix());\n      decoderResult = decoder.decode(bits, hints);\n      points = NO_POINTS;\n    } else {\n      DetectorResult detectorResult = new Detector(image.getBlackMatrix()).detect(hints);\n      decoderResult = decoder.decode(detectorResult.getBits(), hints);\n      points = detectorResult.getPoints();\n    }\n\n    Result result = new Result(decoderResult.getText(), decoderResult.getRawBytes(), points, BarcodeFormat.QR_CODE);\n    List<byte[]> byteSegments = decoderResult.getByteSegments();\n    if (byteSegments != null) {\n      result.putMetadata(ResultMetadataType.BYTE_SEGMENTS, byteSegments);\n    }\n    String ecLevel = decoderResult.getECLevel();\n    if (ecLevel != null) {\n      result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, ecLevel);\n    }\n    return result;\n  }\n\n  @Override\n  public void reset() {\n    // do nothing\n  }\n\n  /**\n   * This method detects a code in a \"pure\" image -- that is, pure monochrome image\n   * which contains only an unrotated, unskewed, image of a code, with some white border\n   * around it. This is a specialized method that works exceptionally fast in this special\n   * case.\n   *\n   * @see com.google.zxing.pdf417.PDF417Reader#extractPureBits(BitMatrix)\n   * @see com.google.zxing.datamatrix.DataMatrixReader#extractPureBits(BitMatrix)\n   */\n  private static BitMatrix extractPureBits(BitMatrix image) throws NotFoundException {\n\n    int[] leftTopBlack = image.getTopLeftOnBit();\n    int[] rightBottomBlack = image.getBottomRightOnBit();\n    if (leftTopBlack == null || rightBottomBlack == null) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n\n    float moduleSize = moduleSize(leftTopBlack, image);\n\n    int top = leftTopBlack[1];\n    int bottom = rightBottomBlack[1];\n    int left = leftTopBlack[0];\n    int right = rightBottomBlack[0];\n\n    if (bottom - top != right - left) {\n      // Special case, where bottom-right module wasn't black so we found something else in the last row\n      // Assume it's a square, so use height as the width\n      right = left + (bottom - top);\n    }\n\n    int matrixWidth = Math.round((right - left + 1) / moduleSize);\n    int matrixHeight = Math.round((bottom - top + 1) / moduleSize);\n    if (matrixWidth <= 0 || matrixHeight <= 0) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n    if (matrixHeight != matrixWidth) {\n      // Only possibly decode square regions\n      throw NotFoundException.getNotFoundInstance();\n    }\n\n    // Push in the \"border\" by half the module width so that we start\n    // sampling in the middle of the module. Just in case the image is a\n    // little off, this will help recover.\n    int nudge = (int) (moduleSize / 2.0f);\n    top += nudge;\n    left += nudge;\n\n    // Now just read off the bits\n    BitMatrix bits = new BitMatrix(matrixWidth, matrixHeight);\n    for (int y = 0; y < matrixHeight; y++) {\n      int iOffset = top + (int) (y * moduleSize);\n      for (int x = 0; x < matrixWidth; x++) {\n        if (image.get(left + (int) (x * moduleSize), iOffset)) {\n          bits.set(x, y);\n        }\n      }\n    }\n    return bits;\n  }\n\n  private static float moduleSize(int[] leftTopBlack, BitMatrix image) throws NotFoundException {\n    int height = image.getHeight();\n    int width = image.getWidth();\n    int x = leftTopBlack[0];\n    int y = leftTopBlack[1];\n    boolean inBlack = true;\n    int transitions = 0;\n    while (x < width && y < height) {\n      if (inBlack != image.get(x, y)) {\n        if (++transitions == 5) {\n          break;\n        }\n        inBlack = !inBlack;\n      }\n      x++;\n      y++;\n    }\n    if (x == width || y == height) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n    return (x - leftTopBlack[0]) / 7.0f;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/qrcode/QRCodeWriter.java",
    "content": "/*\n * Copyright 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.qrcode;\n\nimport com.google.zxing.BarcodeFormat;\nimport com.google.zxing.EncodeHintType;\nimport com.google.zxing.Writer;\nimport com.google.zxing.WriterException;\nimport com.google.zxing.common.BitMatrix;\nimport com.google.zxing.qrcode.encoder.ByteMatrix;\nimport com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;\nimport com.google.zxing.qrcode.encoder.Encoder;\nimport com.google.zxing.qrcode.encoder.QRCode;\n\nimport java.util.Map;\n\n/**\n * This object renders a QR Code as a BitMatrix 2D array of greyscale values.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n */\npublic final class QRCodeWriter implements Writer {\n\n  private static final int QUIET_ZONE_SIZE = 4;\n\n  @Override\n  public BitMatrix encode(String contents, BarcodeFormat format, int width, int height)\n      throws WriterException {\n\n    return encode(contents, format, width, height, null);\n  }\n\n  @Override\n  public BitMatrix encode(String contents,\n                          BarcodeFormat format,\n                          int width,\n                          int height,\n                          Map<EncodeHintType,?> hints) throws WriterException {\n\n    if (contents.length() == 0) {\n      throw new IllegalArgumentException(\"Found empty contents\");\n    }\n\n    if (format != BarcodeFormat.QR_CODE) {\n      throw new IllegalArgumentException(\"Can only encode QR_CODE, but got \" + format);\n    }\n\n    if (width < 0 || height < 0) {\n      throw new IllegalArgumentException(\"Requested dimensions are too small: \" + width + 'x' +\n          height);\n    }\n\n    ErrorCorrectionLevel errorCorrectionLevel = ErrorCorrectionLevel.L;\n    int quietZone = QUIET_ZONE_SIZE;\n    if (hints != null) {\n      ErrorCorrectionLevel requestedECLevel = (ErrorCorrectionLevel) hints.get(EncodeHintType.ERROR_CORRECTION);\n      if (requestedECLevel != null) {\n        errorCorrectionLevel = requestedECLevel;\n      }\n      Integer quietZoneInt = (Integer) hints.get(EncodeHintType.MARGIN);\n      if (quietZoneInt != null) {\n        quietZone = quietZoneInt;\n      }\n    }\n\n    QRCode code = Encoder.encode(contents, errorCorrectionLevel, hints);\n    return renderResult(code, width, height, quietZone);\n  }\n\n  // Note that the input matrix uses 0 == white, 1 == black, while the output matrix uses\n  // 0 == black, 255 == white (i.e. an 8 bit greyscale bitmap).\n  private static BitMatrix renderResult(QRCode code, int width, int height, int quietZone) {\n    ByteMatrix input = code.getMatrix();\n    if (input == null) {\n      throw new IllegalStateException();\n    }\n    int inputWidth = input.getWidth();\n    int inputHeight = input.getHeight();\n    int qrWidth = inputWidth + (quietZone << 1);\n    int qrHeight = inputHeight + (quietZone << 1);\n    int outputWidth = Math.max(width, qrWidth);\n    int outputHeight = Math.max(height, qrHeight);\n\n    int multiple = Math.min(outputWidth / qrWidth, outputHeight / qrHeight);\n    // Padding includes both the quiet zone and the extra white pixels to accommodate the requested\n    // dimensions. For example, if input is 25x25 the QR will be 33x33 including the quiet zone.\n    // If the requested size is 200x160, the multiple will be 4, for a QR of 132x132. These will\n    // handle all the padding from 100x100 (the actual QR) up to 200x160.\n    int leftPadding = (outputWidth - (inputWidth * multiple)) / 2;\n    int topPadding = (outputHeight - (inputHeight * multiple)) / 2;\n\n    BitMatrix output = new BitMatrix(outputWidth, outputHeight);\n\n    for (int inputY = 0, outputY = topPadding; inputY < inputHeight; inputY++, outputY += multiple) {\n      // Write the contents of this row of the barcode\n      for (int inputX = 0, outputX = leftPadding; inputX < inputWidth; inputX++, outputX += multiple) {\n        if (input.get(inputX, inputY) == 1) {\n          output.setRegion(outputX, outputY, multiple, multiple);\n        }\n      }\n    }\n\n    return output;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/qrcode/decoder/BitMatrixParser.java",
    "content": "/*\r\n * Copyright 2007 ZXing authors\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage com.google.zxing.qrcode.decoder;\r\n\r\nimport com.google.zxing.FormatException;\r\nimport com.google.zxing.common.BitMatrix;\r\n\r\n/**\r\n * @author Sean Owen\r\n */\r\nfinal class BitMatrixParser {\r\n\r\n  private final BitMatrix bitMatrix;\r\n  private Version parsedVersion;\r\n  private FormatInformation parsedFormatInfo;\r\n\r\n  /**\r\n   * @param bitMatrix {@link BitMatrix} to parse\r\n   * @throws FormatException if dimension is not >= 21 and 1 mod 4\r\n   */\r\n  BitMatrixParser(BitMatrix bitMatrix) throws FormatException {\r\n    int dimension = bitMatrix.getHeight();\r\n    if (dimension < 21 || (dimension & 0x03) != 1) {\r\n      throw FormatException.getFormatInstance();\r\n    }\r\n    this.bitMatrix = bitMatrix;\r\n  }\r\n\r\n  /**\r\n   * <p>Reads format information from one of its two locations within the QR Code.</p>\r\n   *\r\n   * @return {@link FormatInformation} encapsulating the QR Code's format info\r\n   * @throws FormatException if both format information locations cannot be parsed as\r\n   * the valid encoding of format information\r\n   */\r\n  FormatInformation readFormatInformation() throws FormatException {\r\n\r\n    if (parsedFormatInfo != null) {\r\n      return parsedFormatInfo;\r\n    }\r\n\r\n    // Read top-left format info bits\r\n    int formatInfoBits1 = 0;\r\n    for (int i = 0; i < 6; i++) {\r\n      formatInfoBits1 = copyBit(i, 8, formatInfoBits1);\r\n    }\r\n    // .. and skip a bit in the timing pattern ...\r\n    formatInfoBits1 = copyBit(7, 8, formatInfoBits1);\r\n    formatInfoBits1 = copyBit(8, 8, formatInfoBits1);\r\n    formatInfoBits1 = copyBit(8, 7, formatInfoBits1);\r\n    // .. and skip a bit in the timing pattern ...\r\n    for (int j = 5; j >= 0; j--) {\r\n      formatInfoBits1 = copyBit(8, j, formatInfoBits1);\r\n    }\r\n\r\n    // Read the top-right/bottom-left pattern too\r\n    int dimension = bitMatrix.getHeight();\r\n    int formatInfoBits2 = 0;\r\n    int jMin = dimension - 7;\r\n    for (int j = dimension - 1; j >= jMin; j--) {\r\n      formatInfoBits2 = copyBit(8, j, formatInfoBits2);\r\n    }\r\n    for (int i = dimension - 8; i < dimension; i++) {\r\n      formatInfoBits2 = copyBit(i, 8, formatInfoBits2);\r\n    }\r\n\r\n    parsedFormatInfo = FormatInformation.decodeFormatInformation(formatInfoBits1, formatInfoBits2);\r\n    if (parsedFormatInfo != null) {\r\n      return parsedFormatInfo;\r\n    }\r\n    throw FormatException.getFormatInstance();\r\n  }\r\n\r\n  /**\r\n   * <p>Reads version information from one of its two locations within the QR Code.</p>\r\n   *\r\n   * @return {@link Version} encapsulating the QR Code's version\r\n   * @throws FormatException if both version information locations cannot be parsed as\r\n   * the valid encoding of version information\r\n   */\r\n  Version readVersion() throws FormatException {\r\n\r\n    if (parsedVersion != null) {\r\n      return parsedVersion;\r\n    }\r\n\r\n    int dimension = bitMatrix.getHeight();\r\n\r\n    int provisionalVersion = (dimension - 17) >> 2;\r\n    if (provisionalVersion <= 6) {\r\n      return Version.getVersionForNumber(provisionalVersion);\r\n    }\r\n\r\n    // Read top-right version info: 3 wide by 6 tall\r\n    int versionBits = 0;\r\n    int ijMin = dimension - 11;\r\n    for (int j = 5; j >= 0; j--) {\r\n      for (int i = dimension - 9; i >= ijMin; i--) {\r\n        versionBits = copyBit(i, j, versionBits);\r\n      }\r\n    }\r\n\r\n    Version theParsedVersion = Version.decodeVersionInformation(versionBits);\r\n    if (theParsedVersion != null && theParsedVersion.getDimensionForVersion() == dimension) {\r\n      parsedVersion = theParsedVersion;\r\n      return theParsedVersion;\r\n    }\r\n\r\n    // Hmm, failed. Try bottom left: 6 wide by 3 tall\r\n    versionBits = 0;\r\n    for (int i = 5; i >= 0; i--) {\r\n      for (int j = dimension - 9; j >= ijMin; j--) {\r\n        versionBits = copyBit(i, j, versionBits);\r\n      }\r\n    }\r\n\r\n    theParsedVersion = Version.decodeVersionInformation(versionBits);\r\n    if (theParsedVersion != null && theParsedVersion.getDimensionForVersion() == dimension) {\r\n      parsedVersion = theParsedVersion;\r\n      return theParsedVersion;\r\n    }\r\n    throw FormatException.getFormatInstance();\r\n  }\r\n\r\n  private int copyBit(int i, int j, int versionBits) {\r\n    return bitMatrix.get(i, j) ? (versionBits << 1) | 0x1 : versionBits << 1;\r\n  }\r\n\r\n  /**\r\n   * <p>Reads the bits in the {@link BitMatrix} representing the finder pattern in the\r\n   * correct order in order to reconstitute the codewords bytes contained within the\r\n   * QR Code.</p>\r\n   *\r\n   * @return bytes encoded within the QR Code\r\n   * @throws FormatException if the exact number of bytes expected is not read\r\n   */\r\n  byte[] readCodewords() throws FormatException {\r\n\r\n    FormatInformation formatInfo = readFormatInformation();\r\n    Version version = readVersion();\r\n\r\n    // Get the data mask for the format used in this QR Code. This will exclude\r\n    // some bits from reading as we wind through the bit matrix.\r\n    DataMask dataMask = DataMask.forReference((int) formatInfo.getDataMask());\r\n    int dimension = bitMatrix.getHeight();\r\n    dataMask.unmaskBitMatrix(bitMatrix, dimension);\r\n\r\n    BitMatrix functionPattern = version.buildFunctionPattern();\r\n\r\n    boolean readingUp = true;\r\n    byte[] result = new byte[version.getTotalCodewords()];\r\n    int resultOffset = 0;\r\n    int currentByte = 0;\r\n    int bitsRead = 0;\r\n    // Read columns in pairs, from right to left\r\n    for (int j = dimension - 1; j > 0; j -= 2) {\r\n      if (j == 6) {\r\n        // Skip whole column with vertical alignment pattern;\r\n        // saves time and makes the other code proceed more cleanly\r\n        j--;\r\n      }\r\n      // Read alternatingly from bottom to top then top to bottom\r\n      for (int count = 0; count < dimension; count++) {\r\n        int i = readingUp ? dimension - 1 - count : count;\r\n        for (int col = 0; col < 2; col++) {\r\n          // Ignore bits covered by the function pattern\r\n          if (!functionPattern.get(j - col, i)) {\r\n            // Read a bit\r\n            bitsRead++;\r\n            currentByte <<= 1;\r\n            if (bitMatrix.get(j - col, i)) {\r\n              currentByte |= 1;\r\n            }\r\n            // If we've made a whole byte, save it off\r\n            if (bitsRead == 8) {\r\n              result[resultOffset++] = (byte) currentByte;\r\n              bitsRead = 0;\r\n              currentByte = 0;\r\n            }\r\n          }\r\n        }\r\n      }\r\n      readingUp ^= true; // readingUp = !readingUp; // switch directions\r\n    }\r\n    if (resultOffset != version.getTotalCodewords()) {\r\n      throw FormatException.getFormatInstance();\r\n    }\r\n    return result;\r\n  }\r\n\r\n}"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/qrcode/decoder/DataBlock.java",
    "content": "/*\r\n * Copyright 2007 ZXing authors\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage com.google.zxing.qrcode.decoder;\r\n\r\n/**\r\n * <p>Encapsulates a block of data within a QR Code. QR Codes may split their data into\r\n * multiple blocks, each of which is a unit of data and error-correction codewords. Each\r\n * is represented by an instance of this class.</p>\r\n *\r\n * @author Sean Owen\r\n */\r\nfinal class DataBlock {\r\n\r\n  private final int numDataCodewords;\r\n  private final byte[] codewords;\r\n\r\n  private DataBlock(int numDataCodewords, byte[] codewords) {\r\n    this.numDataCodewords = numDataCodewords;\r\n    this.codewords = codewords;\r\n  }\r\n\r\n  /**\r\n   * <p>When QR Codes use multiple data blocks, they are actually interleaved.\r\n   * That is, the first byte of data block 1 to n is written, then the second bytes, and so on. This\r\n   * method will separate the data into original blocks.</p>\r\n   *\r\n   * @param rawCodewords bytes as read directly from the QR Code\r\n   * @param version version of the QR Code\r\n   * @param ecLevel error-correction level of the QR Code\r\n   * @return DataBlocks containing original bytes, \"de-interleaved\" from representation in the\r\n   *         QR Code\r\n   */\r\n  static DataBlock[] getDataBlocks(byte[] rawCodewords,\r\n                                   Version version,\r\n                                   ErrorCorrectionLevel ecLevel) {\r\n\r\n    if (rawCodewords.length != version.getTotalCodewords()) {\r\n      throw new IllegalArgumentException();\r\n    }\r\n\r\n    // Figure out the number and size of data blocks used by this version and\r\n    // error correction level\r\n    Version.ECBlocks ecBlocks = version.getECBlocksForLevel(ecLevel);\r\n\r\n    // First count the total number of data blocks\r\n    int totalBlocks = 0;\r\n    Version.ECB[] ecBlockArray = ecBlocks.getECBlocks();\r\n    for (Version.ECB ecBlock : ecBlockArray) {\r\n      totalBlocks += ecBlock.getCount();\r\n    }\r\n\r\n    // Now establish DataBlocks of the appropriate size and number of data codewords\r\n    DataBlock[] result = new DataBlock[totalBlocks];\r\n    int numResultBlocks = 0;\r\n    for (Version.ECB ecBlock : ecBlockArray) {\r\n      for (int i = 0; i < ecBlock.getCount(); i++) {\r\n        int numDataCodewords = ecBlock.getDataCodewords();\r\n        int numBlockCodewords = ecBlocks.getECCodewordsPerBlock() + numDataCodewords;\r\n        result[numResultBlocks++] = new DataBlock(numDataCodewords, new byte[numBlockCodewords]);\r\n      }\r\n    }\r\n\r\n    // All blocks have the same amount of data, except that the last n\r\n    // (where n may be 0) have 1 more byte. Figure out where these start.\r\n    int shorterBlocksTotalCodewords = result[0].codewords.length;\r\n    int longerBlocksStartAt = result.length - 1;\r\n    while (longerBlocksStartAt >= 0) {\r\n      int numCodewords = result[longerBlocksStartAt].codewords.length;\r\n      if (numCodewords == shorterBlocksTotalCodewords) {\r\n        break;\r\n      }\r\n      longerBlocksStartAt--;\r\n    }\r\n    longerBlocksStartAt++;\r\n\r\n    int shorterBlocksNumDataCodewords = shorterBlocksTotalCodewords - ecBlocks.getECCodewordsPerBlock();\r\n    // The last elements of result may be 1 element longer;\r\n    // first fill out as many elements as all of them have\r\n    int rawCodewordsOffset = 0;\r\n    for (int i = 0; i < shorterBlocksNumDataCodewords; i++) {\r\n      for (int j = 0; j < numResultBlocks; j++) {\r\n        result[j].codewords[i] = rawCodewords[rawCodewordsOffset++];\r\n      }\r\n    }\r\n    // Fill out the last data block in the longer ones\r\n    for (int j = longerBlocksStartAt; j < numResultBlocks; j++) {\r\n      result[j].codewords[shorterBlocksNumDataCodewords] = rawCodewords[rawCodewordsOffset++];\r\n    }\r\n    // Now add in error correction blocks\r\n    int max = result[0].codewords.length;\r\n    for (int i = shorterBlocksNumDataCodewords; i < max; i++) {\r\n      for (int j = 0; j < numResultBlocks; j++) {\r\n        int iOffset = j < longerBlocksStartAt ? i : i + 1;\r\n        result[j].codewords[iOffset] = rawCodewords[rawCodewordsOffset++];\r\n      }\r\n    }\r\n    return result;\r\n  }\r\n\r\n  int getNumDataCodewords() {\r\n    return numDataCodewords;\r\n  }\r\n\r\n  byte[] getCodewords() {\r\n    return codewords;\r\n  }\r\n\r\n}\r\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/qrcode/decoder/DataMask.java",
    "content": "/*\r\n * Copyright 2007 ZXing authors\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage com.google.zxing.qrcode.decoder;\r\n\r\nimport com.google.zxing.common.BitMatrix;\r\n\r\n/**\r\n * <p>Encapsulates data masks for the data bits in a QR code, per ISO 18004:2006 6.8. Implementations\r\n * of this class can un-mask a raw BitMatrix. For simplicity, they will unmask the entire BitMatrix,\r\n * including areas used for finder patterns, timing patterns, etc. These areas should be unused\r\n * after the point they are unmasked anyway.</p>\r\n *\r\n * <p>Note that the diagram in section 6.8.1 is misleading since it indicates that i is column position\r\n * and j is row position. In fact, as the text says, i is row position and j is column position.</p>\r\n *\r\n * @author Sean Owen\r\n */\r\nabstract class DataMask {\r\n\r\n  /**\r\n   * See ISO 18004:2006 6.8.1\r\n   */\r\n  private static final DataMask[] DATA_MASKS = {\r\n      new DataMask000(),\r\n      new DataMask001(),\r\n      new DataMask010(),\r\n      new DataMask011(),\r\n      new DataMask100(),\r\n      new DataMask101(),\r\n      new DataMask110(),\r\n      new DataMask111(),\r\n  };\r\n\r\n  private DataMask() {\r\n  }\r\n\r\n  /**\r\n   * <p>Implementations of this method reverse the data masking process applied to a QR Code and\r\n   * make its bits ready to read.</p>\r\n   *\r\n   * @param bits representation of QR Code bits\r\n   * @param dimension dimension of QR Code, represented by bits, being unmasked\r\n   */\r\n  final void unmaskBitMatrix(BitMatrix bits, int dimension) {\r\n    for (int i = 0; i < dimension; i++) {\r\n      for (int j = 0; j < dimension; j++) {\r\n        if (isMasked(i, j)) {\r\n          bits.flip(j, i);\r\n        }\r\n      }\r\n    }\r\n  }\r\n\r\n  abstract boolean isMasked(int i, int j);\r\n\r\n  /**\r\n   * @param reference a value between 0 and 7 indicating one of the eight possible\r\n   * data mask patterns a QR Code may use\r\n   * @return DataMask encapsulating the data mask pattern\r\n   */\r\n  static DataMask forReference(int reference) {\r\n    if (reference < 0 || reference > 7) {\r\n      throw new IllegalArgumentException();\r\n    }\r\n    return DATA_MASKS[reference];\r\n  }\r\n\r\n  /**\r\n   * 000: mask bits for which (x + y) mod 2 == 0\r\n   */\r\n  private static final class DataMask000 extends DataMask {\r\n    @Override\r\n    boolean isMasked(int i, int j) {\r\n      return ((i + j) & 0x01) == 0;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 001: mask bits for which x mod 2 == 0\r\n   */\r\n  private static final class DataMask001 extends DataMask {\r\n    @Override\r\n    boolean isMasked(int i, int j) {\r\n      return (i & 0x01) == 0;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 010: mask bits for which y mod 3 == 0\r\n   */\r\n  private static final class DataMask010 extends DataMask {\r\n    @Override\r\n    boolean isMasked(int i, int j) {\r\n      return j % 3 == 0;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 011: mask bits for which (x + y) mod 3 == 0\r\n   */\r\n  private static final class DataMask011 extends DataMask {\r\n    @Override\r\n    boolean isMasked(int i, int j) {\r\n      return (i + j) % 3 == 0;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 100: mask bits for which (x/2 + y/3) mod 2 == 0\r\n   */\r\n  private static final class DataMask100 extends DataMask {\r\n    @Override\r\n    boolean isMasked(int i, int j) {\r\n      return (((i >>> 1) + (j /3)) & 0x01) == 0;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 101: mask bits for which xy mod 2 + xy mod 3 == 0\r\n   */\r\n  private static final class DataMask101 extends DataMask {\r\n    @Override\r\n    boolean isMasked(int i, int j) {\r\n      int temp = i * j;\r\n      return (temp & 0x01) + (temp % 3) == 0;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 110: mask bits for which (xy mod 2 + xy mod 3) mod 2 == 0\r\n   */\r\n  private static final class DataMask110 extends DataMask {\r\n    @Override\r\n    boolean isMasked(int i, int j) {\r\n      int temp = i * j;\r\n      return (((temp & 0x01) + (temp % 3)) & 0x01) == 0;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 111: mask bits for which ((x+y)mod 2 + xy mod 3) mod 2 == 0\r\n   */\r\n  private static final class DataMask111 extends DataMask {\r\n    @Override\r\n    boolean isMasked(int i, int j) {\r\n      return ((((i + j) & 0x01) + ((i * j) % 3)) & 0x01) == 0;\r\n    }\r\n  }\r\n}\r\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/qrcode/decoder/DecodedBitStreamParser.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.qrcode.decoder;\n\nimport com.google.zxing.DecodeHintType;\nimport com.google.zxing.FormatException;\nimport com.google.zxing.common.BitSource;\nimport com.google.zxing.common.CharacterSetECI;\nimport com.google.zxing.common.DecoderResult;\nimport com.google.zxing.common.StringUtils;\n\nimport java.io.UnsupportedEncodingException;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * <p>QR Codes can encode text as bits in one of several modes, and can use multiple modes\n * in one QR Code. This class decodes the bits back into text.</p>\n *\n * <p>See ISO 18004:2006, 6.4.3 - 6.4.7</p>\n *\n * @author Sean Owen\n */\nfinal class DecodedBitStreamParser {\n\n  /**\n   * See ISO 18004:2006, 6.4.4 Table 5\n   */\n  private static final char[] ALPHANUMERIC_CHARS = {\n      '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B',\n      'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',\n      'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',\n      ' ', '$', '%', '*', '+', '-', '.', '/', ':'\n  };\n  private static final int GB2312_SUBSET = 1;\n\n  private DecodedBitStreamParser() {\n  }\n\n  static DecoderResult decode(byte[] bytes,\n                              Version version,\n                              ErrorCorrectionLevel ecLevel,\n                              Map<DecodeHintType,?> hints) throws FormatException {\n    BitSource bits = new BitSource(bytes);\n    StringBuilder result = new StringBuilder(50);\n    CharacterSetECI currentCharacterSetECI = null;\n    boolean fc1InEffect = false;\n    List<byte[]> byteSegments = new ArrayList<byte[]>(1);\n    Mode mode;\n    do {\n      // While still another segment to read...\n      if (bits.available() < 4) {\n        // OK, assume we're done. Really, a TERMINATOR mode should have been recorded here\n        mode = Mode.TERMINATOR;\n      } else {\n        try {\n          mode = Mode.forBits(bits.readBits(4)); // mode is encoded by 4 bits\n        } catch (IllegalArgumentException iae) {\n          throw FormatException.getFormatInstance();\n        }\n      }\n      if (mode != Mode.TERMINATOR) {\n        if (mode == Mode.FNC1_FIRST_POSITION || mode == Mode.FNC1_SECOND_POSITION) {\n          // We do little with FNC1 except alter the parsed result a bit according to the spec\n          fc1InEffect = true;\n        } else if (mode == Mode.STRUCTURED_APPEND) {\n          if (bits.available() < 16) {\n            throw FormatException.getFormatInstance();\n          }\n          // not really supported; all we do is ignore it\n          // Read next 8 bits (symbol sequence #) and 8 bits (parity data), then continue\n          bits.readBits(16);\n        } else if (mode == Mode.ECI) {\n          // Count doesn't apply to ECI\n          int value = parseECIValue(bits);\n          currentCharacterSetECI = CharacterSetECI.getCharacterSetECIByValue(value);\n          if (currentCharacterSetECI == null) {\n            throw FormatException.getFormatInstance();\n          }\n        } else {\n          // First handle Hanzi mode which does not start with character count\n          if (mode == Mode.HANZI) {\n            //chinese mode contains a sub set indicator right after mode indicator\n            int subset = bits.readBits(4);\n            int countHanzi = bits.readBits(mode.getCharacterCountBits(version));\n            if (subset == GB2312_SUBSET) {\n              decodeHanziSegment(bits, result, countHanzi);\n            }\n          } else {\n            // \"Normal\" QR code modes:\n            // How many characters will follow, encoded in this mode?\n            int count = bits.readBits(mode.getCharacterCountBits(version));\n            if (mode == Mode.NUMERIC) {\n              decodeNumericSegment(bits, result, count);\n            } else if (mode == Mode.ALPHANUMERIC) {\n              decodeAlphanumericSegment(bits, result, count, fc1InEffect);\n            } else if (mode == Mode.BYTE) {\n              decodeByteSegment(bits, result, count, currentCharacterSetECI, byteSegments, hints);\n            } else if (mode == Mode.KANJI) {\n              decodeKanjiSegment(bits, result, count);\n            } else {\n              throw FormatException.getFormatInstance();\n            }\n          }\n        }\n      }\n    } while (mode != Mode.TERMINATOR);\n\n    return new DecoderResult(bytes,\n                             result.toString(),\n                             byteSegments.isEmpty() ? null : byteSegments,\n                             ecLevel == null ? null : ecLevel.toString());\n  }\n\n  /**\n   * See specification GBT 18284-2000\n   */\n  private static void decodeHanziSegment(BitSource bits,\n                                         StringBuilder result,\n                                         int count) throws FormatException {\n    // Don't crash trying to read more bits than we have available.\n    if (count * 13 > bits.available()) {\n      throw FormatException.getFormatInstance();\n    }\n\n    // Each character will require 2 bytes. Read the characters as 2-byte pairs\n    // and decode as GB2312 afterwards\n    byte[] buffer = new byte[2 * count];\n    int offset = 0;\n    while (count > 0) {\n      // Each 13 bits encodes a 2-byte character\n      int twoBytes = bits.readBits(13);\n      int assembledTwoBytes = ((twoBytes / 0x060) << 8) | (twoBytes % 0x060);\n      if (assembledTwoBytes < 0x003BF) {\n        // In the 0xA1A1 to 0xAAFE range\n        assembledTwoBytes += 0x0A1A1;\n      } else {\n        // In the 0xB0A1 to 0xFAFE range\n        assembledTwoBytes += 0x0A6A1;\n      }\n      buffer[offset] = (byte) ((assembledTwoBytes >> 8) & 0xFF);\n      buffer[offset + 1] = (byte) (assembledTwoBytes & 0xFF);\n      offset += 2;\n      count--;\n    }\n\n    try {\n      result.append(new String(buffer, StringUtils.GB2312));\n    } catch (UnsupportedEncodingException uee) {\n      throw FormatException.getFormatInstance();\n    }\n  }\n\n  private static void decodeKanjiSegment(BitSource bits,\n                                         StringBuilder result,\n                                         int count) throws FormatException {\n    // Don't crash trying to read more bits than we have available.\n    if (count * 13 > bits.available()) {\n      throw FormatException.getFormatInstance();\n    }\n\n    // Each character will require 2 bytes. Read the characters as 2-byte pairs\n    // and decode as Shift_JIS afterwards\n    byte[] buffer = new byte[2 * count];\n    int offset = 0;\n    while (count > 0) {\n      // Each 13 bits encodes a 2-byte character\n      int twoBytes = bits.readBits(13);\n      int assembledTwoBytes = ((twoBytes / 0x0C0) << 8) | (twoBytes % 0x0C0);\n      if (assembledTwoBytes < 0x01F00) {\n        // In the 0x8140 to 0x9FFC range\n        assembledTwoBytes += 0x08140;\n      } else {\n        // In the 0xE040 to 0xEBBF range\n        assembledTwoBytes += 0x0C140;\n      }\n      buffer[offset] = (byte) (assembledTwoBytes >> 8);\n      buffer[offset + 1] = (byte) assembledTwoBytes;\n      offset += 2;\n      count--;\n    }\n    // Shift_JIS may not be supported in some environments:\n    try {\n      result.append(new String(buffer, StringUtils.SHIFT_JIS));\n    } catch (UnsupportedEncodingException uee) {\n      throw FormatException.getFormatInstance();\n    }\n  }\n\n  private static void decodeByteSegment(BitSource bits,\n                                        StringBuilder result,\n                                        int count,\n                                        CharacterSetECI currentCharacterSetECI,\n                                        Collection<byte[]> byteSegments,\n                                        Map<DecodeHintType,?> hints) throws FormatException {\n    // Don't crash trying to read more bits than we have available.\n    if (count << 3 > bits.available()) {\n      throw FormatException.getFormatInstance();\n    }\n\n    byte[] readBytes = new byte[count];\n    for (int i = 0; i < count; i++) {\n      readBytes[i] = (byte) bits.readBits(8);\n    }\n    String encoding;\n    if (currentCharacterSetECI == null) {\n      // The spec isn't clear on this mode; see\n      // section 6.4.5: t does not say which encoding to assuming\n      // upon decoding. I have seen ISO-8859-1 used as well as\n      // Shift_JIS -- without anything like an ECI designator to\n      // give a hint.\n      encoding = StringUtils.guessEncoding(readBytes, hints);\n    } else {\n      encoding = currentCharacterSetECI.name();\n    }\n    try {\n      result.append(new String(readBytes, encoding));\n    } catch (UnsupportedEncodingException uce) {\n      throw FormatException.getFormatInstance();\n    }\n    byteSegments.add(readBytes);\n  }\n\n  private static char toAlphaNumericChar(int value) throws FormatException {\n    if (value >= ALPHANUMERIC_CHARS.length) {\n      throw FormatException.getFormatInstance();\n    }\n    return ALPHANUMERIC_CHARS[value];\n  }\n\n  private static void decodeAlphanumericSegment(BitSource bits,\n                                                StringBuilder result,\n                                                int count,\n                                                boolean fc1InEffect) throws FormatException {\n    // Read two characters at a time\n    int start = result.length();\n    while (count > 1) {\n      if (bits.available() < 11) {\n        throw FormatException.getFormatInstance();\n      }\n      int nextTwoCharsBits = bits.readBits(11);\n      result.append(toAlphaNumericChar(nextTwoCharsBits / 45));\n      result.append(toAlphaNumericChar(nextTwoCharsBits % 45));\n      count -= 2;\n    }\n    if (count == 1) {\n      // special case: one character left\n      if (bits.available() < 6) {\n        throw FormatException.getFormatInstance();\n      }\n      result.append(toAlphaNumericChar(bits.readBits(6)));\n    }\n    // See section 6.4.8.1, 6.4.8.2\n    if (fc1InEffect) {\n      // We need to massage the result a bit if in an FNC1 mode:\n      for (int i = start; i < result.length(); i++) {\n        if (result.charAt(i) == '%') {\n          if (i < result.length() - 1 && result.charAt(i + 1) == '%') {\n            // %% is rendered as %\n            result.deleteCharAt(i + 1);\n          } else {\n            // In alpha mode, % should be converted to FNC1 separator 0x1D\n            result.setCharAt(i, (char) 0x1D);\n          }\n        }\n      }\n    }\n  }\n\n  private static void decodeNumericSegment(BitSource bits,\n                                           StringBuilder result,\n                                           int count) throws FormatException {\n    // Read three digits at a time\n    while (count >= 3) {\n      // Each 10 bits encodes three digits\n      if (bits.available() < 10) {\n        throw FormatException.getFormatInstance();\n      }\n      int threeDigitsBits = bits.readBits(10);\n      if (threeDigitsBits >= 1000) {\n        throw FormatException.getFormatInstance();\n      }\n      result.append(toAlphaNumericChar(threeDigitsBits / 100));\n      result.append(toAlphaNumericChar((threeDigitsBits / 10) % 10));\n      result.append(toAlphaNumericChar(threeDigitsBits % 10));\n      count -= 3;\n    }\n    if (count == 2) {\n      // Two digits left over to read, encoded in 7 bits\n      if (bits.available() < 7) {\n        throw FormatException.getFormatInstance();\n      }\n      int twoDigitsBits = bits.readBits(7);\n      if (twoDigitsBits >= 100) {\n        throw FormatException.getFormatInstance();\n      }\n      result.append(toAlphaNumericChar(twoDigitsBits / 10));\n      result.append(toAlphaNumericChar(twoDigitsBits % 10));\n    } else if (count == 1) {\n      // One digit left over to read\n      if (bits.available() < 4) {\n        throw FormatException.getFormatInstance();\n      }\n      int digitBits = bits.readBits(4);\n      if (digitBits >= 10) {\n        throw FormatException.getFormatInstance();\n      }\n      result.append(toAlphaNumericChar(digitBits));\n    }\n  }\n\n  private static int parseECIValue(BitSource bits) throws FormatException {\n    int firstByte = bits.readBits(8);\n    if ((firstByte & 0x80) == 0) {\n      // just one byte\n      return firstByte & 0x7F;\n    }\n    if ((firstByte & 0xC0) == 0x80) {\n      // two bytes\n      int secondByte = bits.readBits(8);\n      return ((firstByte & 0x3F) << 8) | secondByte;\n    }\n    if ((firstByte & 0xE0) == 0xC0) {\n      // three bytes\n      int secondThirdBytes = bits.readBits(16);\n      return ((firstByte & 0x1F) << 16) | secondThirdBytes;\n    }\n    throw FormatException.getFormatInstance();\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/qrcode/decoder/Decoder.java",
    "content": "/*\r\n * Copyright 2007 ZXing authors\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage com.google.zxing.qrcode.decoder;\r\n\r\nimport com.google.zxing.ChecksumException;\r\nimport com.google.zxing.DecodeHintType;\r\nimport com.google.zxing.FormatException;\r\nimport com.google.zxing.common.BitMatrix;\r\nimport com.google.zxing.common.DecoderResult;\r\nimport com.google.zxing.common.reedsolomon.GenericGF;\r\nimport com.google.zxing.common.reedsolomon.ReedSolomonDecoder;\r\nimport com.google.zxing.common.reedsolomon.ReedSolomonException;\r\n\r\nimport java.util.Map;\r\n\r\n/**\r\n * <p>The main class which implements QR Code decoding -- as opposed to locating and extracting\r\n * the QR Code from an image.</p>\r\n *\r\n * @author Sean Owen\r\n */\r\npublic final class Decoder {\r\n\r\n  private final ReedSolomonDecoder rsDecoder;\r\n\r\n  public Decoder() {\r\n    rsDecoder = new ReedSolomonDecoder(GenericGF.QR_CODE_FIELD_256);\r\n  }\r\n\r\n  public DecoderResult decode(boolean[][] image) throws ChecksumException, FormatException {\r\n    return decode(image, null);\r\n  }\r\n\r\n  /**\r\n   * <p>Convenience method that can decode a QR Code represented as a 2D array of booleans.\r\n   * \"true\" is taken to mean a black module.</p>\r\n   *\r\n   * @param image booleans representing white/black QR Code modules\r\n   * @return text and bytes encoded within the QR Code\r\n   * @throws FormatException if the QR Code cannot be decoded\r\n   * @throws ChecksumException if error correction fails\r\n   */\r\n  public DecoderResult decode(boolean[][] image, Map<DecodeHintType,?> hints)\r\n      throws ChecksumException, FormatException {\r\n    int dimension = image.length;\r\n    BitMatrix bits = new BitMatrix(dimension);\r\n    for (int i = 0; i < dimension; i++) {\r\n      for (int j = 0; j < dimension; j++) {\r\n        if (image[i][j]) {\r\n          bits.set(j, i);\r\n        }\r\n      }\r\n    }\r\n    return decode(bits, hints);\r\n  }\r\n\r\n  public DecoderResult decode(BitMatrix bits) throws ChecksumException, FormatException {\r\n    return decode(bits, null);\r\n  }\r\n\r\n  /**\r\n   * <p>Decodes a QR Code represented as a {@link BitMatrix}. A 1 or \"true\" is taken to mean a black module.</p>\r\n   *\r\n   * @param bits booleans representing white/black QR Code modules\r\n   * @return text and bytes encoded within the QR Code\r\n   * @throws FormatException if the QR Code cannot be decoded\r\n   * @throws ChecksumException if error correction fails\r\n   */\r\n  public DecoderResult decode(BitMatrix bits, Map<DecodeHintType,?> hints)\r\n      throws FormatException, ChecksumException {\r\n\r\n    // Construct a parser and read version, error-correction level\r\n    BitMatrixParser parser = new BitMatrixParser(bits);\r\n    Version version = parser.readVersion();\r\n    ErrorCorrectionLevel ecLevel = parser.readFormatInformation().getErrorCorrectionLevel();\r\n\r\n    // Read codewords\r\n    byte[] codewords = parser.readCodewords();\r\n    // Separate into data blocks\r\n    DataBlock[] dataBlocks = DataBlock.getDataBlocks(codewords, version, ecLevel);\r\n\r\n    // Count total number of data bytes\r\n    int totalBytes = 0;\r\n    for (DataBlock dataBlock : dataBlocks) {\r\n      totalBytes += dataBlock.getNumDataCodewords();\r\n    }\r\n    byte[] resultBytes = new byte[totalBytes];\r\n    int resultOffset = 0;\r\n\r\n    // Error-correct and copy data blocks together into a stream of bytes\r\n    for (DataBlock dataBlock : dataBlocks) {\r\n      byte[] codewordBytes = dataBlock.getCodewords();\r\n      int numDataCodewords = dataBlock.getNumDataCodewords();\r\n      correctErrors(codewordBytes, numDataCodewords);\r\n      for (int i = 0; i < numDataCodewords; i++) {\r\n        resultBytes[resultOffset++] = codewordBytes[i];\r\n      }\r\n    }\r\n\r\n    // Decode the contents of that stream of bytes\r\n    return DecodedBitStreamParser.decode(resultBytes, version, ecLevel, hints);\r\n  }\r\n\r\n  /**\r\n   * <p>Given data and error-correction codewords received, possibly corrupted by errors, attempts to\r\n   * correct the errors in-place using Reed-Solomon error correction.</p>\r\n   *\r\n   * @param codewordBytes data and error correction codewords\r\n   * @param numDataCodewords number of codewords that are data bytes\r\n   * @throws ChecksumException if error correction fails\r\n   */\r\n  private void correctErrors(byte[] codewordBytes, int numDataCodewords) throws ChecksumException {\r\n    int numCodewords = codewordBytes.length;\r\n    // First read into an array of ints\r\n    int[] codewordsInts = new int[numCodewords];\r\n    for (int i = 0; i < numCodewords; i++) {\r\n      codewordsInts[i] = codewordBytes[i] & 0xFF;\r\n    }\r\n    int numECCodewords = codewordBytes.length - numDataCodewords;\r\n    try {\r\n      rsDecoder.decode(codewordsInts, numECCodewords);\r\n    } catch (ReedSolomonException rse) {\r\n      throw ChecksumException.getChecksumInstance();\r\n    }\r\n    // Copy back into array of bytes -- only need to worry about the bytes that were data\r\n    // We don't care about errors in the error-correction codewords\r\n    for (int i = 0; i < numDataCodewords; i++) {\r\n      codewordBytes[i] = (byte) codewordsInts[i];\r\n    }\r\n  }\r\n\r\n}\r\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/qrcode/decoder/ErrorCorrectionLevel.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.qrcode.decoder;\n\n/**\n * <p>See ISO 18004:2006, 6.5.1. This enum encapsulates the four error correction levels\n * defined by the QR code standard.</p>\n *\n * @author Sean Owen\n */\npublic enum ErrorCorrectionLevel {\n\n  /** L = ~7% correction */\n  L(0x01),\n  /** M = ~15% correction */\n  M(0x00),\n  /** Q = ~25% correction */\n  Q(0x03),\n  /** H = ~30% correction */\n  H(0x02);\n\n  private static final ErrorCorrectionLevel[] FOR_BITS = {M, L, H, Q};\n\n  private final int bits;\n\n  ErrorCorrectionLevel(int bits) {\n    this.bits = bits;\n  }\n\n  public int getBits() {\n    return bits;\n  }\n\n  /**\n   * @param bits int containing the two bits encoding a QR Code's error correction level\n   * @return ErrorCorrectionLevel representing the encoded error correction level\n   */\n  public static ErrorCorrectionLevel forBits(int bits) {\n    if (bits < 0 || bits >= FOR_BITS.length) {\n      throw new IllegalArgumentException();\n    }\n    return FOR_BITS[bits];\n  }\n\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/qrcode/decoder/FormatInformation.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.qrcode.decoder;\n\n/**\n * <p>Encapsulates a QR Code's format information, including the data mask used and\n * error correction level.</p>\n *\n * @author Sean Owen\n * @see DataMask\n * @see ErrorCorrectionLevel\n */\nfinal class FormatInformation {\n\n  private static final int FORMAT_INFO_MASK_QR = 0x5412;\n\n  /**\n   * See ISO 18004:2006, Annex C, Table C.1\n   */\n  private static final int[][] FORMAT_INFO_DECODE_LOOKUP = {\n      {0x5412, 0x00},\n      {0x5125, 0x01},\n      {0x5E7C, 0x02},\n      {0x5B4B, 0x03},\n      {0x45F9, 0x04},\n      {0x40CE, 0x05},\n      {0x4F97, 0x06},\n      {0x4AA0, 0x07},\n      {0x77C4, 0x08},\n      {0x72F3, 0x09},\n      {0x7DAA, 0x0A},\n      {0x789D, 0x0B},\n      {0x662F, 0x0C},\n      {0x6318, 0x0D},\n      {0x6C41, 0x0E},\n      {0x6976, 0x0F},\n      {0x1689, 0x10},\n      {0x13BE, 0x11},\n      {0x1CE7, 0x12},\n      {0x19D0, 0x13},\n      {0x0762, 0x14},\n      {0x0255, 0x15},\n      {0x0D0C, 0x16},\n      {0x083B, 0x17},\n      {0x355F, 0x18},\n      {0x3068, 0x19},\n      {0x3F31, 0x1A},\n      {0x3A06, 0x1B},\n      {0x24B4, 0x1C},\n      {0x2183, 0x1D},\n      {0x2EDA, 0x1E},\n      {0x2BED, 0x1F},\n  };\n\n  /**\n   * Offset i holds the number of 1 bits in the binary representation of i\n   */\n  private static final int[] BITS_SET_IN_HALF_BYTE =\n      {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};\n\n  private final ErrorCorrectionLevel errorCorrectionLevel;\n  private final byte dataMask;\n\n  private FormatInformation(int formatInfo) {\n    // Bits 3,4\n    errorCorrectionLevel = ErrorCorrectionLevel.forBits((formatInfo >> 3) & 0x03);\n    // Bottom 3 bits\n    dataMask = (byte) (formatInfo & 0x07);\n  }\n\n  static int numBitsDiffering(int a, int b) {\n    a ^= b; // a now has a 1 bit exactly where its bit differs with b's\n    // Count bits set quickly with a series of lookups:\n    return BITS_SET_IN_HALF_BYTE[a & 0x0F] +\n        BITS_SET_IN_HALF_BYTE[(a >>> 4 & 0x0F)] +\n        BITS_SET_IN_HALF_BYTE[(a >>> 8 & 0x0F)] +\n        BITS_SET_IN_HALF_BYTE[(a >>> 12 & 0x0F)] +\n        BITS_SET_IN_HALF_BYTE[(a >>> 16 & 0x0F)] +\n        BITS_SET_IN_HALF_BYTE[(a >>> 20 & 0x0F)] +\n        BITS_SET_IN_HALF_BYTE[(a >>> 24 & 0x0F)] +\n        BITS_SET_IN_HALF_BYTE[(a >>> 28 & 0x0F)];\n  }\n\n  /**\n   * @param maskedFormatInfo1 format info indicator, with mask still applied\n   * @param maskedFormatInfo2 second copy of same info; both are checked at the same time\n   *  to establish best match\n   * @return information about the format it specifies, or {@code null}\n   *  if doesn't seem to match any known pattern\n   */\n  static FormatInformation decodeFormatInformation(int maskedFormatInfo1, int maskedFormatInfo2) {\n    FormatInformation formatInfo = doDecodeFormatInformation(maskedFormatInfo1, maskedFormatInfo2);\n    if (formatInfo != null) {\n      return formatInfo;\n    }\n    // Should return null, but, some QR codes apparently\n    // do not mask this info. Try again by actually masking the pattern\n    // first\n    return doDecodeFormatInformation(maskedFormatInfo1 ^ FORMAT_INFO_MASK_QR,\n                                     maskedFormatInfo2 ^ FORMAT_INFO_MASK_QR);\n  }\n\n  private static FormatInformation doDecodeFormatInformation(int maskedFormatInfo1, int maskedFormatInfo2) {\n    // Find the int in FORMAT_INFO_DECODE_LOOKUP with fewest bits differing\n    int bestDifference = Integer.MAX_VALUE;\n    int bestFormatInfo = 0;\n    for (int[] decodeInfo : FORMAT_INFO_DECODE_LOOKUP) {\n      int targetInfo = decodeInfo[0];\n      if (targetInfo == maskedFormatInfo1 || targetInfo == maskedFormatInfo2) {\n        // Found an exact match\n        return new FormatInformation(decodeInfo[1]);\n      }\n      int bitsDifference = numBitsDiffering(maskedFormatInfo1, targetInfo);\n      if (bitsDifference < bestDifference) {\n        bestFormatInfo = decodeInfo[1];\n        bestDifference = bitsDifference;\n      }\n      if (maskedFormatInfo1 != maskedFormatInfo2) {\n        // also try the other option\n        bitsDifference = numBitsDiffering(maskedFormatInfo2, targetInfo);\n        if (bitsDifference < bestDifference) {\n          bestFormatInfo = decodeInfo[1];\n          bestDifference = bitsDifference;\n        }\n      }\n    }\n    // Hamming distance of the 32 masked codes is 7, by construction, so <= 3 bits\n    // differing means we found a match\n    if (bestDifference <= 3) {\n      return new FormatInformation(bestFormatInfo);\n    }\n    return null;\n  }\n\n  ErrorCorrectionLevel getErrorCorrectionLevel() {\n    return errorCorrectionLevel;\n  }\n\n  byte getDataMask() {\n    return dataMask;\n  }\n\n  @Override\n  public int hashCode() {\n    return (errorCorrectionLevel.ordinal() << 3) | (int) dataMask;\n  }\n\n  @Override\n  public boolean equals(Object o) {\n    if (!(o instanceof FormatInformation)) {\n      return false;\n    }\n    FormatInformation other = (FormatInformation) o;\n    return this.errorCorrectionLevel == other.errorCorrectionLevel &&\n        this.dataMask == other.dataMask;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/qrcode/decoder/Mode.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.qrcode.decoder;\n\n/**\n * <p>See ISO 18004:2006, 6.4.1, Tables 2 and 3. This enum encapsulates the various modes in which\n * data can be encoded to bits in the QR code standard.</p>\n *\n * @author Sean Owen\n */\npublic enum Mode {\n\n  TERMINATOR(new int[]{0, 0, 0}, 0x00), // Not really a mode...\n  NUMERIC(new int[]{10, 12, 14}, 0x01),\n  ALPHANUMERIC(new int[]{9, 11, 13}, 0x02),\n  STRUCTURED_APPEND(new int[]{0, 0, 0}, 0x03), // Not supported\n  BYTE(new int[]{8, 16, 16}, 0x04),\n  ECI(new int[]{0, 0, 0}, 0x07), // character counts don't apply\n  KANJI(new int[]{8, 10, 12}, 0x08),\n  FNC1_FIRST_POSITION(new int[]{0, 0, 0}, 0x05),\n  FNC1_SECOND_POSITION(new int[]{0, 0, 0}, 0x09),\n  /** See GBT 18284-2000; \"Hanzi\" is a transliteration of this mode name. */\n  HANZI(new int[]{8, 10, 12}, 0x0D);\n\n  private final int[] characterCountBitsForVersions;\n  private final int bits;\n\n  Mode(int[] characterCountBitsForVersions, int bits) {\n    this.characterCountBitsForVersions = characterCountBitsForVersions;\n    this.bits = bits;\n  }\n\n  /**\n   * @param bits four bits encoding a QR Code data mode\n   * @return Mode encoded by these bits\n   * @throws IllegalArgumentException if bits do not correspond to a known mode\n   */\n  public static Mode forBits(int bits) {\n    switch (bits) {\n      case 0x0:\n        return TERMINATOR;\n      case 0x1:\n        return NUMERIC;\n      case 0x2:\n        return ALPHANUMERIC;\n      case 0x3:\n        return STRUCTURED_APPEND;\n      case 0x4:\n        return BYTE;\n      case 0x5:\n        return FNC1_FIRST_POSITION;\n      case 0x7:\n        return ECI;\n      case 0x8:\n        return KANJI;\n      case 0x9:\n        return FNC1_SECOND_POSITION;\n      case 0xD:\n        // 0xD is defined in GBT 18284-2000, may not be supported in foreign country\n        return HANZI;\n      default:\n        throw new IllegalArgumentException();\n    }\n  }\n\n  /**\n   * @param version version in question\n   * @return number of bits used, in this QR Code symbol {@link Version}, to encode the\n   *         count of characters that will follow encoded in this Mode\n   */\n  public int getCharacterCountBits(Version version) {\n    int number = version.getVersionNumber();\n    int offset;\n    if (number <= 9) {\n      offset = 0;\n    } else if (number <= 26) {\n      offset = 1;\n    } else {\n      offset = 2;\n    }\n    return characterCountBitsForVersions[offset];\n  }\n\n  public int getBits() {\n    return bits;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/qrcode/decoder/Version.java",
    "content": "/*\r\n * Copyright 2007 ZXing authors\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage com.google.zxing.qrcode.decoder;\r\n\r\nimport com.google.zxing.FormatException;\r\nimport com.google.zxing.common.BitMatrix;\r\n\r\n/**\r\n * See ISO 18004:2006 Annex D\r\n *\r\n * @author Sean Owen\r\n */\r\npublic final class Version {\r\n\r\n  /**\r\n   * See ISO 18004:2006 Annex D.\r\n   * Element i represents the raw version bits that specify version i + 7\r\n   */\r\n  private static final int[] VERSION_DECODE_INFO = {\r\n      0x07C94, 0x085BC, 0x09A99, 0x0A4D3, 0x0BBF6,\r\n      0x0C762, 0x0D847, 0x0E60D, 0x0F928, 0x10B78,\r\n      0x1145D, 0x12A17, 0x13532, 0x149A6, 0x15683,\r\n      0x168C9, 0x177EC, 0x18EC4, 0x191E1, 0x1AFAB,\r\n      0x1B08E, 0x1CC1A, 0x1D33F, 0x1ED75, 0x1F250,\r\n      0x209D5, 0x216F0, 0x228BA, 0x2379F, 0x24B0B,\r\n      0x2542E, 0x26A64, 0x27541, 0x28C69\r\n  };\r\n\r\n  private static final Version[] VERSIONS = buildVersions();\r\n\r\n  private final int versionNumber;\r\n  private final int[] alignmentPatternCenters;\r\n  private final ECBlocks[] ecBlocks;\r\n  private final int totalCodewords;\r\n\r\n  private Version(int versionNumber,\r\n                  int[] alignmentPatternCenters,\r\n                  ECBlocks... ecBlocks) {\r\n    this.versionNumber = versionNumber;\r\n    this.alignmentPatternCenters = alignmentPatternCenters;\r\n    this.ecBlocks = ecBlocks;\r\n    int total = 0;\r\n    int ecCodewords = ecBlocks[0].getECCodewordsPerBlock();\r\n    ECB[] ecbArray = ecBlocks[0].getECBlocks();\r\n    for (ECB ecBlock : ecbArray) {\r\n      total += ecBlock.getCount() * (ecBlock.getDataCodewords() + ecCodewords);\r\n    }\r\n    this.totalCodewords = total;\r\n  }\r\n\r\n  public int getVersionNumber() {\r\n    return versionNumber;\r\n  }\r\n\r\n  public int[] getAlignmentPatternCenters() {\r\n    return alignmentPatternCenters;\r\n  }\r\n\r\n  public int getTotalCodewords() {\r\n    return totalCodewords;\r\n  }\r\n\r\n  public int getDimensionForVersion() {\r\n    return 17 + 4 * versionNumber;\r\n  }\r\n\r\n  public ECBlocks getECBlocksForLevel(ErrorCorrectionLevel ecLevel) {\r\n    return ecBlocks[ecLevel.ordinal()];\r\n  }\r\n\r\n  /**\r\n   * <p>Deduces version information purely from QR Code dimensions.</p>\r\n   *\r\n   * @param dimension dimension in modules\r\n   * @return Version for a QR Code of that dimension\r\n   * @throws FormatException if dimension is not 1 mod 4\r\n   */\r\n  public static Version getProvisionalVersionForDimension(int dimension) throws FormatException {\r\n    if (dimension % 4 != 1) {\r\n      throw FormatException.getFormatInstance();\r\n    }\r\n    try {\r\n      return getVersionForNumber((dimension - 17) >> 2);\r\n    } catch (IllegalArgumentException iae) {\r\n      throw FormatException.getFormatInstance();\r\n    }\r\n  }\r\n\r\n  public static Version getVersionForNumber(int versionNumber) {\r\n    if (versionNumber < 1 || versionNumber > 40) {\r\n      throw new IllegalArgumentException();\r\n    }\r\n    return VERSIONS[versionNumber - 1];\r\n  }\r\n\r\n  static Version decodeVersionInformation(int versionBits) {\r\n    int bestDifference = Integer.MAX_VALUE;\r\n    int bestVersion = 0;\r\n    for (int i = 0; i < VERSION_DECODE_INFO.length; i++) {\r\n      int targetVersion = VERSION_DECODE_INFO[i];\r\n      // Do the version info bits match exactly? done.\r\n      if (targetVersion == versionBits) {\r\n        return getVersionForNumber(i + 7);\r\n      }\r\n      // Otherwise see if this is the closest to a real version info bit string\r\n      // we have seen so far\r\n      int bitsDifference = FormatInformation.numBitsDiffering(versionBits, targetVersion);\r\n      if (bitsDifference < bestDifference) {\r\n        bestVersion = i + 7;\r\n        bestDifference = bitsDifference;\r\n      }\r\n    }\r\n    // We can tolerate up to 3 bits of error since no two version info codewords will\r\n    // differ in less than 8 bits.\r\n    if (bestDifference <= 3) {\r\n      return getVersionForNumber(bestVersion);\r\n    }\r\n    // If we didn't find a close enough match, fail\r\n    return null;\r\n  }\r\n\r\n  /**\r\n   * See ISO 18004:2006 Annex E\r\n   */\r\n  BitMatrix buildFunctionPattern() {\r\n    int dimension = getDimensionForVersion();\r\n    BitMatrix bitMatrix = new BitMatrix(dimension);\r\n\r\n    // Top left finder pattern + separator + format\r\n    bitMatrix.setRegion(0, 0, 9, 9);\r\n    // Top right finder pattern + separator + format\r\n    bitMatrix.setRegion(dimension - 8, 0, 8, 9);\r\n    // Bottom left finder pattern + separator + format\r\n    bitMatrix.setRegion(0, dimension - 8, 9, 8);\r\n\r\n    // Alignment patterns\r\n    int max = alignmentPatternCenters.length;\r\n    for (int x = 0; x < max; x++) {\r\n      int i = alignmentPatternCenters[x] - 2;\r\n      for (int y = 0; y < max; y++) {\r\n        if ((x == 0 && (y == 0 || y == max - 1)) || (x == max - 1 && y == 0)) {\r\n          // No alignment patterns near the three finder paterns\r\n          continue;\r\n        }\r\n        bitMatrix.setRegion(alignmentPatternCenters[y] - 2, i, 5, 5);\r\n      }\r\n    }\r\n\r\n    // Vertical timing pattern\r\n    bitMatrix.setRegion(6, 9, 1, dimension - 17);\r\n    // Horizontal timing pattern\r\n    bitMatrix.setRegion(9, 6, dimension - 17, 1);\r\n\r\n    if (versionNumber > 6) {\r\n      // Version info, top right\r\n      bitMatrix.setRegion(dimension - 11, 0, 3, 6);\r\n      // Version info, bottom left\r\n      bitMatrix.setRegion(0, dimension - 11, 6, 3);\r\n    }\r\n\r\n    return bitMatrix;\r\n  }\r\n\r\n  /**\r\n   * <p>Encapsulates a set of error-correction blocks in one symbol version. Most versions will\r\n   * use blocks of differing sizes within one version, so, this encapsulates the parameters for\r\n   * each set of blocks. It also holds the number of error-correction codewords per block since it\r\n   * will be the same across all blocks within one version.</p>\r\n   */\r\n  public static final class ECBlocks {\r\n    private final int ecCodewordsPerBlock;\r\n    private final ECB[] ecBlocks;\r\n\r\n    ECBlocks(int ecCodewordsPerBlock, ECB... ecBlocks) {\r\n      this.ecCodewordsPerBlock = ecCodewordsPerBlock;\r\n      this.ecBlocks = ecBlocks;\r\n    }\r\n\r\n    public int getECCodewordsPerBlock() {\r\n      return ecCodewordsPerBlock;\r\n    }\r\n\r\n    public int getNumBlocks() {\r\n      int total = 0;\r\n      for (ECB ecBlock : ecBlocks) {\r\n        total += ecBlock.getCount();\r\n      }\r\n      return total;\r\n    }\r\n\r\n    public int getTotalECCodewords() {\r\n      return ecCodewordsPerBlock * getNumBlocks();\r\n    }\r\n\r\n    public ECB[] getECBlocks() {\r\n      return ecBlocks;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * <p>Encapsualtes the parameters for one error-correction block in one symbol version.\r\n   * This includes the number of data codewords, and the number of times a block with these\r\n   * parameters is used consecutively in the QR code version's format.</p>\r\n   */\r\n  public static final class ECB {\r\n    private final int count;\r\n    private final int dataCodewords;\r\n\r\n    ECB(int count, int dataCodewords) {\r\n      this.count = count;\r\n      this.dataCodewords = dataCodewords;\r\n    }\r\n\r\n    public int getCount() {\r\n      return count;\r\n    }\r\n\r\n    public int getDataCodewords() {\r\n      return dataCodewords;\r\n    }\r\n  }\r\n\r\n  @Override\r\n  public String toString() {\r\n    return String.valueOf(versionNumber);\r\n  }\r\n\r\n  /**\r\n   * See ISO 18004:2006 6.5.1 Table 9\r\n   */\r\n  private static Version[] buildVersions() {\r\n    return new Version[]{\r\n        new Version(1, new int[]{},\r\n            new ECBlocks(7, new ECB(1, 19)),\r\n            new ECBlocks(10, new ECB(1, 16)),\r\n            new ECBlocks(13, new ECB(1, 13)),\r\n            new ECBlocks(17, new ECB(1, 9))),\r\n        new Version(2, new int[]{6, 18},\r\n            new ECBlocks(10, new ECB(1, 34)),\r\n            new ECBlocks(16, new ECB(1, 28)),\r\n            new ECBlocks(22, new ECB(1, 22)),\r\n            new ECBlocks(28, new ECB(1, 16))),\r\n        new Version(3, new int[]{6, 22},\r\n            new ECBlocks(15, new ECB(1, 55)),\r\n            new ECBlocks(26, new ECB(1, 44)),\r\n            new ECBlocks(18, new ECB(2, 17)),\r\n            new ECBlocks(22, new ECB(2, 13))),\r\n        new Version(4, new int[]{6, 26},\r\n            new ECBlocks(20, new ECB(1, 80)),\r\n            new ECBlocks(18, new ECB(2, 32)),\r\n            new ECBlocks(26, new ECB(2, 24)),\r\n            new ECBlocks(16, new ECB(4, 9))),\r\n        new Version(5, new int[]{6, 30},\r\n            new ECBlocks(26, new ECB(1, 108)),\r\n            new ECBlocks(24, new ECB(2, 43)),\r\n            new ECBlocks(18, new ECB(2, 15),\r\n                new ECB(2, 16)),\r\n            new ECBlocks(22, new ECB(2, 11),\r\n                new ECB(2, 12))),\r\n        new Version(6, new int[]{6, 34},\r\n            new ECBlocks(18, new ECB(2, 68)),\r\n            new ECBlocks(16, new ECB(4, 27)),\r\n            new ECBlocks(24, new ECB(4, 19)),\r\n            new ECBlocks(28, new ECB(4, 15))),\r\n        new Version(7, new int[]{6, 22, 38},\r\n            new ECBlocks(20, new ECB(2, 78)),\r\n            new ECBlocks(18, new ECB(4, 31)),\r\n            new ECBlocks(18, new ECB(2, 14),\r\n                new ECB(4, 15)),\r\n            new ECBlocks(26, new ECB(4, 13),\r\n                new ECB(1, 14))),\r\n        new Version(8, new int[]{6, 24, 42},\r\n            new ECBlocks(24, new ECB(2, 97)),\r\n            new ECBlocks(22, new ECB(2, 38),\r\n                new ECB(2, 39)),\r\n            new ECBlocks(22, new ECB(4, 18),\r\n                new ECB(2, 19)),\r\n            new ECBlocks(26, new ECB(4, 14),\r\n                new ECB(2, 15))),\r\n        new Version(9, new int[]{6, 26, 46},\r\n            new ECBlocks(30, new ECB(2, 116)),\r\n            new ECBlocks(22, new ECB(3, 36),\r\n                new ECB(2, 37)),\r\n            new ECBlocks(20, new ECB(4, 16),\r\n                new ECB(4, 17)),\r\n            new ECBlocks(24, new ECB(4, 12),\r\n                new ECB(4, 13))),\r\n        new Version(10, new int[]{6, 28, 50},\r\n            new ECBlocks(18, new ECB(2, 68),\r\n                new ECB(2, 69)),\r\n            new ECBlocks(26, new ECB(4, 43),\r\n                new ECB(1, 44)),\r\n            new ECBlocks(24, new ECB(6, 19),\r\n                new ECB(2, 20)),\r\n            new ECBlocks(28, new ECB(6, 15),\r\n                new ECB(2, 16))),\r\n        new Version(11, new int[]{6, 30, 54},\r\n            new ECBlocks(20, new ECB(4, 81)),\r\n            new ECBlocks(30, new ECB(1, 50),\r\n                new ECB(4, 51)),\r\n            new ECBlocks(28, new ECB(4, 22),\r\n                new ECB(4, 23)),\r\n            new ECBlocks(24, new ECB(3, 12),\r\n                new ECB(8, 13))),\r\n        new Version(12, new int[]{6, 32, 58},\r\n            new ECBlocks(24, new ECB(2, 92),\r\n                new ECB(2, 93)),\r\n            new ECBlocks(22, new ECB(6, 36),\r\n                new ECB(2, 37)),\r\n            new ECBlocks(26, new ECB(4, 20),\r\n                new ECB(6, 21)),\r\n            new ECBlocks(28, new ECB(7, 14),\r\n                new ECB(4, 15))),\r\n        new Version(13, new int[]{6, 34, 62},\r\n            new ECBlocks(26, new ECB(4, 107)),\r\n            new ECBlocks(22, new ECB(8, 37),\r\n                new ECB(1, 38)),\r\n            new ECBlocks(24, new ECB(8, 20),\r\n                new ECB(4, 21)),\r\n            new ECBlocks(22, new ECB(12, 11),\r\n                new ECB(4, 12))),\r\n        new Version(14, new int[]{6, 26, 46, 66},\r\n            new ECBlocks(30, new ECB(3, 115),\r\n                new ECB(1, 116)),\r\n            new ECBlocks(24, new ECB(4, 40),\r\n                new ECB(5, 41)),\r\n            new ECBlocks(20, new ECB(11, 16),\r\n                new ECB(5, 17)),\r\n            new ECBlocks(24, new ECB(11, 12),\r\n                new ECB(5, 13))),\r\n        new Version(15, new int[]{6, 26, 48, 70},\r\n            new ECBlocks(22, new ECB(5, 87),\r\n                new ECB(1, 88)),\r\n            new ECBlocks(24, new ECB(5, 41),\r\n                new ECB(5, 42)),\r\n            new ECBlocks(30, new ECB(5, 24),\r\n                new ECB(7, 25)),\r\n            new ECBlocks(24, new ECB(11, 12),\r\n                new ECB(7, 13))),\r\n        new Version(16, new int[]{6, 26, 50, 74},\r\n            new ECBlocks(24, new ECB(5, 98),\r\n                new ECB(1, 99)),\r\n            new ECBlocks(28, new ECB(7, 45),\r\n                new ECB(3, 46)),\r\n            new ECBlocks(24, new ECB(15, 19),\r\n                new ECB(2, 20)),\r\n            new ECBlocks(30, new ECB(3, 15),\r\n                new ECB(13, 16))),\r\n        new Version(17, new int[]{6, 30, 54, 78},\r\n            new ECBlocks(28, new ECB(1, 107),\r\n                new ECB(5, 108)),\r\n            new ECBlocks(28, new ECB(10, 46),\r\n                new ECB(1, 47)),\r\n            new ECBlocks(28, new ECB(1, 22),\r\n                new ECB(15, 23)),\r\n            new ECBlocks(28, new ECB(2, 14),\r\n                new ECB(17, 15))),\r\n        new Version(18, new int[]{6, 30, 56, 82},\r\n            new ECBlocks(30, new ECB(5, 120),\r\n                new ECB(1, 121)),\r\n            new ECBlocks(26, new ECB(9, 43),\r\n                new ECB(4, 44)),\r\n            new ECBlocks(28, new ECB(17, 22),\r\n                new ECB(1, 23)),\r\n            new ECBlocks(28, new ECB(2, 14),\r\n                new ECB(19, 15))),\r\n        new Version(19, new int[]{6, 30, 58, 86},\r\n            new ECBlocks(28, new ECB(3, 113),\r\n                new ECB(4, 114)),\r\n            new ECBlocks(26, new ECB(3, 44),\r\n                new ECB(11, 45)),\r\n            new ECBlocks(26, new ECB(17, 21),\r\n                new ECB(4, 22)),\r\n            new ECBlocks(26, new ECB(9, 13),\r\n                new ECB(16, 14))),\r\n        new Version(20, new int[]{6, 34, 62, 90},\r\n            new ECBlocks(28, new ECB(3, 107),\r\n                new ECB(5, 108)),\r\n            new ECBlocks(26, new ECB(3, 41),\r\n                new ECB(13, 42)),\r\n            new ECBlocks(30, new ECB(15, 24),\r\n                new ECB(5, 25)),\r\n            new ECBlocks(28, new ECB(15, 15),\r\n                new ECB(10, 16))),\r\n        new Version(21, new int[]{6, 28, 50, 72, 94},\r\n            new ECBlocks(28, new ECB(4, 116),\r\n                new ECB(4, 117)),\r\n            new ECBlocks(26, new ECB(17, 42)),\r\n            new ECBlocks(28, new ECB(17, 22),\r\n                new ECB(6, 23)),\r\n            new ECBlocks(30, new ECB(19, 16),\r\n                new ECB(6, 17))),\r\n        new Version(22, new int[]{6, 26, 50, 74, 98},\r\n            new ECBlocks(28, new ECB(2, 111),\r\n                new ECB(7, 112)),\r\n            new ECBlocks(28, new ECB(17, 46)),\r\n            new ECBlocks(30, new ECB(7, 24),\r\n                new ECB(16, 25)),\r\n            new ECBlocks(24, new ECB(34, 13))),\r\n        new Version(23, new int[]{6, 30, 54, 78, 102},\r\n            new ECBlocks(30, new ECB(4, 121),\r\n                new ECB(5, 122)),\r\n            new ECBlocks(28, new ECB(4, 47),\r\n                new ECB(14, 48)),\r\n            new ECBlocks(30, new ECB(11, 24),\r\n                new ECB(14, 25)),\r\n            new ECBlocks(30, new ECB(16, 15),\r\n                new ECB(14, 16))),\r\n        new Version(24, new int[]{6, 28, 54, 80, 106},\r\n            new ECBlocks(30, new ECB(6, 117),\r\n                new ECB(4, 118)),\r\n            new ECBlocks(28, new ECB(6, 45),\r\n                new ECB(14, 46)),\r\n            new ECBlocks(30, new ECB(11, 24),\r\n                new ECB(16, 25)),\r\n            new ECBlocks(30, new ECB(30, 16),\r\n                new ECB(2, 17))),\r\n        new Version(25, new int[]{6, 32, 58, 84, 110},\r\n            new ECBlocks(26, new ECB(8, 106),\r\n                new ECB(4, 107)),\r\n            new ECBlocks(28, new ECB(8, 47),\r\n                new ECB(13, 48)),\r\n            new ECBlocks(30, new ECB(7, 24),\r\n                new ECB(22, 25)),\r\n            new ECBlocks(30, new ECB(22, 15),\r\n                new ECB(13, 16))),\r\n        new Version(26, new int[]{6, 30, 58, 86, 114},\r\n            new ECBlocks(28, new ECB(10, 114),\r\n                new ECB(2, 115)),\r\n            new ECBlocks(28, new ECB(19, 46),\r\n                new ECB(4, 47)),\r\n            new ECBlocks(28, new ECB(28, 22),\r\n                new ECB(6, 23)),\r\n            new ECBlocks(30, new ECB(33, 16),\r\n                new ECB(4, 17))),\r\n        new Version(27, new int[]{6, 34, 62, 90, 118},\r\n            new ECBlocks(30, new ECB(8, 122),\r\n                new ECB(4, 123)),\r\n            new ECBlocks(28, new ECB(22, 45),\r\n                new ECB(3, 46)),\r\n            new ECBlocks(30, new ECB(8, 23),\r\n                new ECB(26, 24)),\r\n            new ECBlocks(30, new ECB(12, 15),\r\n                new ECB(28, 16))),\r\n        new Version(28, new int[]{6, 26, 50, 74, 98, 122},\r\n            new ECBlocks(30, new ECB(3, 117),\r\n                new ECB(10, 118)),\r\n            new ECBlocks(28, new ECB(3, 45),\r\n                new ECB(23, 46)),\r\n            new ECBlocks(30, new ECB(4, 24),\r\n                new ECB(31, 25)),\r\n            new ECBlocks(30, new ECB(11, 15),\r\n                new ECB(31, 16))),\r\n        new Version(29, new int[]{6, 30, 54, 78, 102, 126},\r\n            new ECBlocks(30, new ECB(7, 116),\r\n                new ECB(7, 117)),\r\n            new ECBlocks(28, new ECB(21, 45),\r\n                new ECB(7, 46)),\r\n            new ECBlocks(30, new ECB(1, 23),\r\n                new ECB(37, 24)),\r\n            new ECBlocks(30, new ECB(19, 15),\r\n                new ECB(26, 16))),\r\n        new Version(30, new int[]{6, 26, 52, 78, 104, 130},\r\n            new ECBlocks(30, new ECB(5, 115),\r\n                new ECB(10, 116)),\r\n            new ECBlocks(28, new ECB(19, 47),\r\n                new ECB(10, 48)),\r\n            new ECBlocks(30, new ECB(15, 24),\r\n                new ECB(25, 25)),\r\n            new ECBlocks(30, new ECB(23, 15),\r\n                new ECB(25, 16))),\r\n        new Version(31, new int[]{6, 30, 56, 82, 108, 134},\r\n            new ECBlocks(30, new ECB(13, 115),\r\n                new ECB(3, 116)),\r\n            new ECBlocks(28, new ECB(2, 46),\r\n                new ECB(29, 47)),\r\n            new ECBlocks(30, new ECB(42, 24),\r\n                new ECB(1, 25)),\r\n            new ECBlocks(30, new ECB(23, 15),\r\n                new ECB(28, 16))),\r\n        new Version(32, new int[]{6, 34, 60, 86, 112, 138},\r\n            new ECBlocks(30, new ECB(17, 115)),\r\n            new ECBlocks(28, new ECB(10, 46),\r\n                new ECB(23, 47)),\r\n            new ECBlocks(30, new ECB(10, 24),\r\n                new ECB(35, 25)),\r\n            new ECBlocks(30, new ECB(19, 15),\r\n                new ECB(35, 16))),\r\n        new Version(33, new int[]{6, 30, 58, 86, 114, 142},\r\n            new ECBlocks(30, new ECB(17, 115),\r\n                new ECB(1, 116)),\r\n            new ECBlocks(28, new ECB(14, 46),\r\n                new ECB(21, 47)),\r\n            new ECBlocks(30, new ECB(29, 24),\r\n                new ECB(19, 25)),\r\n            new ECBlocks(30, new ECB(11, 15),\r\n                new ECB(46, 16))),\r\n        new Version(34, new int[]{6, 34, 62, 90, 118, 146},\r\n            new ECBlocks(30, new ECB(13, 115),\r\n                new ECB(6, 116)),\r\n            new ECBlocks(28, new ECB(14, 46),\r\n                new ECB(23, 47)),\r\n            new ECBlocks(30, new ECB(44, 24),\r\n                new ECB(7, 25)),\r\n            new ECBlocks(30, new ECB(59, 16),\r\n                new ECB(1, 17))),\r\n        new Version(35, new int[]{6, 30, 54, 78, 102, 126, 150},\r\n            new ECBlocks(30, new ECB(12, 121),\r\n                new ECB(7, 122)),\r\n            new ECBlocks(28, new ECB(12, 47),\r\n                new ECB(26, 48)),\r\n            new ECBlocks(30, new ECB(39, 24),\r\n                new ECB(14, 25)),\r\n            new ECBlocks(30, new ECB(22, 15),\r\n                new ECB(41, 16))),\r\n        new Version(36, new int[]{6, 24, 50, 76, 102, 128, 154},\r\n            new ECBlocks(30, new ECB(6, 121),\r\n                new ECB(14, 122)),\r\n            new ECBlocks(28, new ECB(6, 47),\r\n                new ECB(34, 48)),\r\n            new ECBlocks(30, new ECB(46, 24),\r\n                new ECB(10, 25)),\r\n            new ECBlocks(30, new ECB(2, 15),\r\n                new ECB(64, 16))),\r\n        new Version(37, new int[]{6, 28, 54, 80, 106, 132, 158},\r\n            new ECBlocks(30, new ECB(17, 122),\r\n                new ECB(4, 123)),\r\n            new ECBlocks(28, new ECB(29, 46),\r\n                new ECB(14, 47)),\r\n            new ECBlocks(30, new ECB(49, 24),\r\n                new ECB(10, 25)),\r\n            new ECBlocks(30, new ECB(24, 15),\r\n                new ECB(46, 16))),\r\n        new Version(38, new int[]{6, 32, 58, 84, 110, 136, 162},\r\n            new ECBlocks(30, new ECB(4, 122),\r\n                new ECB(18, 123)),\r\n            new ECBlocks(28, new ECB(13, 46),\r\n                new ECB(32, 47)),\r\n            new ECBlocks(30, new ECB(48, 24),\r\n                new ECB(14, 25)),\r\n            new ECBlocks(30, new ECB(42, 15),\r\n                new ECB(32, 16))),\r\n        new Version(39, new int[]{6, 26, 54, 82, 110, 138, 166},\r\n            new ECBlocks(30, new ECB(20, 117),\r\n                new ECB(4, 118)),\r\n            new ECBlocks(28, new ECB(40, 47),\r\n                new ECB(7, 48)),\r\n            new ECBlocks(30, new ECB(43, 24),\r\n                new ECB(22, 25)),\r\n            new ECBlocks(30, new ECB(10, 15),\r\n                new ECB(67, 16))),\r\n        new Version(40, new int[]{6, 30, 58, 86, 114, 142, 170},\r\n            new ECBlocks(30, new ECB(19, 118),\r\n                new ECB(6, 119)),\r\n            new ECBlocks(28, new ECB(18, 47),\r\n                new ECB(31, 48)),\r\n            new ECBlocks(30, new ECB(34, 24),\r\n                new ECB(34, 25)),\r\n            new ECBlocks(30, new ECB(20, 15),\r\n                new ECB(61, 16)))\r\n    };\r\n  }\r\n\r\n}\r\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/qrcode/detector/AlignmentPattern.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.qrcode.detector;\n\nimport com.google.zxing.ResultPoint;\n\n/**\n * <p>Encapsulates an alignment pattern, which are the smaller square patterns found in\n * all but the simplest QR Codes.</p>\n *\n * @author Sean Owen\n */\npublic final class AlignmentPattern extends ResultPoint {\n\n  private final float estimatedModuleSize;\n\n  AlignmentPattern(float posX, float posY, float estimatedModuleSize) {\n    super(posX, posY);\n    this.estimatedModuleSize = estimatedModuleSize;\n  }\n\n  /**\n   * <p>Determines if this alignment pattern \"about equals\" an alignment pattern at the stated\n   * position and size -- meaning, it is at nearly the same center with nearly the same size.</p>\n   */\n  boolean aboutEquals(float moduleSize, float i, float j) {\n    if (Math.abs(i - getY()) <= moduleSize && Math.abs(j - getX()) <= moduleSize) {\n      float moduleSizeDiff = Math.abs(moduleSize - estimatedModuleSize);\n      return moduleSizeDiff <= 1.0f || moduleSizeDiff <= estimatedModuleSize;\n    }\n    return false;\n  }\n\n  /**\n   * Combines this object's current estimate of a finder pattern position and module size\n   * with a new estimate. It returns a new {@code FinderPattern} containing an average of the two.\n   */\n  AlignmentPattern combineEstimate(float i, float j, float newModuleSize) {\n    float combinedX = (getX() + j) / 2.0f;\n    float combinedY = (getY() + i) / 2.0f;\n    float combinedModuleSize = (estimatedModuleSize + newModuleSize) / 2.0f;\n    return new AlignmentPattern(combinedX, combinedY, combinedModuleSize);\n  }\n\n}"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/qrcode/detector/AlignmentPatternFinder.java",
    "content": "/*\r\n * Copyright 2007 ZXing authors\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage com.google.zxing.qrcode.detector;\r\n\r\nimport com.google.zxing.NotFoundException;\r\nimport com.google.zxing.ResultPointCallback;\r\nimport com.google.zxing.common.BitMatrix;\r\n\r\nimport java.util.ArrayList;\r\nimport java.util.List;\r\n\r\n/**\r\n * <p>This class attempts to find alignment patterns in a QR Code. Alignment patterns look like finder\r\n * patterns but are smaller and appear at regular intervals throughout the image.</p>\r\n *\r\n * <p>At the moment this only looks for the bottom-right alignment pattern.</p>\r\n *\r\n * <p>This is mostly a simplified copy of {@link FinderPatternFinder}. It is copied,\r\n * pasted and stripped down here for maximum performance but does unfortunately duplicate\r\n * some code.</p>\r\n *\r\n * <p>This class is thread-safe but not reentrant. Each thread must allocate its own object.</p>\r\n *\r\n * @author Sean Owen\r\n */\r\nfinal class AlignmentPatternFinder {\r\n\r\n  private final BitMatrix image;\r\n  private final List<AlignmentPattern> possibleCenters;\r\n  private final int startX;\r\n  private final int startY;\r\n  private final int width;\r\n  private final int height;\r\n  private final float moduleSize;\r\n  private final int[] crossCheckStateCount;\r\n  private final ResultPointCallback resultPointCallback;\r\n\r\n  /**\r\n   * <p>Creates a finder that will look in a portion of the whole image.</p>\r\n   *\r\n   * @param image image to search\r\n   * @param startX left column from which to start searching\r\n   * @param startY top row from which to start searching\r\n   * @param width width of region to search\r\n   * @param height height of region to search\r\n   * @param moduleSize estimated module size so far\r\n   */\r\n  AlignmentPatternFinder(BitMatrix image,\r\n                         int startX,\r\n                         int startY,\r\n                         int width,\r\n                         int height,\r\n                         float moduleSize,\r\n                         ResultPointCallback resultPointCallback) {\r\n    this.image = image;\r\n    this.possibleCenters = new ArrayList<AlignmentPattern>(5);\r\n    this.startX = startX;\r\n    this.startY = startY;\r\n    this.width = width;\r\n    this.height = height;\r\n    this.moduleSize = moduleSize;\r\n    this.crossCheckStateCount = new int[3];\r\n    this.resultPointCallback = resultPointCallback;\r\n  }\r\n\r\n  /**\r\n   * <p>This method attempts to find the bottom-right alignment pattern in the image. It is a bit messy since\r\n   * it's pretty performance-critical and so is written to be fast foremost.</p>\r\n   *\r\n   * @return {@link AlignmentPattern} if found\r\n   * @throws NotFoundException if not found\r\n   */\r\n  AlignmentPattern find() throws NotFoundException {\r\n    int startX = this.startX;\r\n    int height = this.height;\r\n    int maxJ = startX + width;\r\n    int middleI = startY + (height >> 1);\r\n    // We are looking for black/white/black modules in 1:1:1 ratio;\r\n    // this tracks the number of black/white/black modules seen so far\r\n    int[] stateCount = new int[3];\r\n    for (int iGen = 0; iGen < height; iGen++) {\r\n      // Search from middle outwards\r\n      int i = middleI + ((iGen & 0x01) == 0 ? (iGen + 1) >> 1 : -((iGen + 1) >> 1));\r\n      stateCount[0] = 0;\r\n      stateCount[1] = 0;\r\n      stateCount[2] = 0;\r\n      int j = startX;\r\n      // Burn off leading white pixels before anything else; if we start in the middle of\r\n      // a white run, it doesn't make sense to count its length, since we don't know if the\r\n      // white run continued to the left of the start point\r\n      while (j < maxJ && !image.get(j, i)) {\r\n        j++;\r\n      }\r\n      int currentState = 0;\r\n      while (j < maxJ) {\r\n        if (image.get(j, i)) {\r\n          // Black pixel\r\n          if (currentState == 1) { // Counting black pixels\r\n            stateCount[currentState]++;\r\n          } else { // Counting white pixels\r\n            if (currentState == 2) { // A winner?\r\n              if (foundPatternCross(stateCount)) { // Yes\r\n                AlignmentPattern confirmed = handlePossibleCenter(stateCount, i, j);\r\n                if (confirmed != null) {\r\n                  return confirmed;\r\n                }\r\n              }\r\n              stateCount[0] = stateCount[2];\r\n              stateCount[1] = 1;\r\n              stateCount[2] = 0;\r\n              currentState = 1;\r\n            } else {\r\n              stateCount[++currentState]++;\r\n            }\r\n          }\r\n        } else { // White pixel\r\n          if (currentState == 1) { // Counting black pixels\r\n            currentState++;\r\n          }\r\n          stateCount[currentState]++;\r\n        }\r\n        j++;\r\n      }\r\n      if (foundPatternCross(stateCount)) {\r\n        AlignmentPattern confirmed = handlePossibleCenter(stateCount, i, maxJ);\r\n        if (confirmed != null) {\r\n          return confirmed;\r\n        }\r\n      }\r\n\r\n    }\r\n\r\n    // Hmm, nothing we saw was observed and confirmed twice. If we had\r\n    // any guess at all, return it.\r\n    if (!possibleCenters.isEmpty()) {\r\n      return possibleCenters.get(0);\r\n    }\r\n\r\n    throw NotFoundException.getNotFoundInstance();\r\n  }\r\n\r\n  /**\r\n   * Given a count of black/white/black pixels just seen and an end position,\r\n   * figures the location of the center of this black/white/black run.\r\n   */\r\n  private static float centerFromEnd(int[] stateCount, int end) {\r\n    return (float) (end - stateCount[2]) - stateCount[1] / 2.0f;\r\n  }\r\n\r\n  /**\r\n   * @param stateCount count of black/white/black pixels just read\r\n   * @return true iff the proportions of the counts is close enough to the 1/1/1 ratios\r\n   *         used by alignment patterns to be considered a match\r\n   */\r\n  private boolean foundPatternCross(int[] stateCount) {\r\n    float moduleSize = this.moduleSize;\r\n    float maxVariance = moduleSize / 2.0f;\r\n    for (int i = 0; i < 3; i++) {\r\n      if (Math.abs(moduleSize - stateCount[i]) >= maxVariance) {\r\n        return false;\r\n      }\r\n    }\r\n    return true;\r\n  }\r\n\r\n  /**\r\n   * <p>After a horizontal scan finds a potential alignment pattern, this method\r\n   * \"cross-checks\" by scanning down vertically through the center of the possible\r\n   * alignment pattern to see if the same proportion is detected.</p>\r\n   *\r\n   * @param startI row where an alignment pattern was detected\r\n   * @param centerJ center of the section that appears to cross an alignment pattern\r\n   * @param maxCount maximum reasonable number of modules that should be\r\n   * observed in any reading state, based on the results of the horizontal scan\r\n   * @return vertical center of alignment pattern, or {@link Float#NaN} if not found\r\n   */\r\n  private float crossCheckVertical(int startI, int centerJ, int maxCount,\r\n      int originalStateCountTotal) {\r\n    BitMatrix image = this.image;\r\n\r\n    int maxI = image.getHeight();\r\n    int[] stateCount = crossCheckStateCount;\r\n    stateCount[0] = 0;\r\n    stateCount[1] = 0;\r\n    stateCount[2] = 0;\r\n\r\n    // Start counting up from center\r\n    int i = startI;\r\n    while (i >= 0 && image.get(centerJ, i) && stateCount[1] <= maxCount) {\r\n      stateCount[1]++;\r\n      i--;\r\n    }\r\n    // If already too many modules in this state or ran off the edge:\r\n    if (i < 0 || stateCount[1] > maxCount) {\r\n      return Float.NaN;\r\n    }\r\n    while (i >= 0 && !image.get(centerJ, i) && stateCount[0] <= maxCount) {\r\n      stateCount[0]++;\r\n      i--;\r\n    }\r\n    if (stateCount[0] > maxCount) {\r\n      return Float.NaN;\r\n    }\r\n\r\n    // Now also count down from center\r\n    i = startI + 1;\r\n    while (i < maxI && image.get(centerJ, i) && stateCount[1] <= maxCount) {\r\n      stateCount[1]++;\r\n      i++;\r\n    }\r\n    if (i == maxI || stateCount[1] > maxCount) {\r\n      return Float.NaN;\r\n    }\r\n    while (i < maxI && !image.get(centerJ, i) && stateCount[2] <= maxCount) {\r\n      stateCount[2]++;\r\n      i++;\r\n    }\r\n    if (stateCount[2] > maxCount) {\r\n      return Float.NaN;\r\n    }\r\n\r\n    int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2];\r\n    if (5 * Math.abs(stateCountTotal - originalStateCountTotal) >= 2 * originalStateCountTotal) {\r\n      return Float.NaN;\r\n    }\r\n\r\n    return foundPatternCross(stateCount) ? centerFromEnd(stateCount, i) : Float.NaN;\r\n  }\r\n\r\n  /**\r\n   * <p>This is called when a horizontal scan finds a possible alignment pattern. It will\r\n   * cross check with a vertical scan, and if successful, will see if this pattern had been\r\n   * found on a previous horizontal scan. If so, we consider it confirmed and conclude we have\r\n   * found the alignment pattern.</p>\r\n   *\r\n   * @param stateCount reading state module counts from horizontal scan\r\n   * @param i row where alignment pattern may be found\r\n   * @param j end of possible alignment pattern in row\r\n   * @return {@link AlignmentPattern} if we have found the same pattern twice, or null if not\r\n   */\r\n  private AlignmentPattern handlePossibleCenter(int[] stateCount, int i, int j) {\r\n    int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2];\r\n    float centerJ = centerFromEnd(stateCount, j);\r\n    float centerI = crossCheckVertical(i, (int) centerJ, 2 * stateCount[1], stateCountTotal);\r\n    if (!Float.isNaN(centerI)) {\r\n      float estimatedModuleSize = (float) (stateCount[0] + stateCount[1] + stateCount[2]) / 3.0f;\r\n      for (AlignmentPattern center : possibleCenters) {\r\n        // Look for about the same center and module size:\r\n        if (center.aboutEquals(estimatedModuleSize, centerI, centerJ)) {\r\n          return center.combineEstimate(centerI, centerJ, estimatedModuleSize);\r\n        }\r\n      }\r\n      // Hadn't found this before; save it\r\n      AlignmentPattern point = new AlignmentPattern(centerJ, centerI, estimatedModuleSize);\r\n      possibleCenters.add(point);\r\n      if (resultPointCallback != null) {\r\n        resultPointCallback.foundPossibleResultPoint(point);\r\n      }\r\n    }\r\n    return null;\r\n  }\r\n\r\n}\r\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/qrcode/detector/Detector.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.qrcode.detector;\n\nimport com.google.zxing.DecodeHintType;\nimport com.google.zxing.FormatException;\nimport com.google.zxing.NotFoundException;\nimport com.google.zxing.ResultPoint;\nimport com.google.zxing.ResultPointCallback;\nimport com.google.zxing.common.BitMatrix;\nimport com.google.zxing.common.DetectorResult;\nimport com.google.zxing.common.GridSampler;\nimport com.google.zxing.common.PerspectiveTransform;\nimport com.google.zxing.common.detector.MathUtils;\nimport com.google.zxing.qrcode.decoder.Version;\n\nimport java.util.Map;\n\n/**\n * <p>Encapsulates logic that can detect a QR Code in an image, even if the QR Code\n * is rotated or skewed, or partially obscured.</p>\n *\n * @author Sean Owen\n */\npublic class Detector {\n\n  private final BitMatrix image;\n  private ResultPointCallback resultPointCallback;\n\n  public Detector(BitMatrix image) {\n    this.image = image;\n  }\n\n  protected final BitMatrix getImage() {\n    return image;\n  }\n\n  protected final ResultPointCallback getResultPointCallback() {\n    return resultPointCallback;\n  }\n\n  /**\n   * <p>Detects a QR Code in an image, simply.</p>\n   *\n   * @return {@link DetectorResult} encapsulating results of detecting a QR Code\n   * @throws NotFoundException if no QR Code can be found\n   */\n  public DetectorResult detect() throws NotFoundException, FormatException {\n    return detect(null);\n  }\n\n  /**\n   * <p>Detects a QR Code in an image, simply.</p>\n   *\n   * @param hints optional hints to detector\n   * @return {@link NotFoundException} encapsulating results of detecting a QR Code\n   * @throws NotFoundException if QR Code cannot be found\n   * @throws FormatException if a QR Code cannot be decoded\n   */\n  public final DetectorResult detect(Map<DecodeHintType,?> hints) throws NotFoundException, FormatException {\n\n    resultPointCallback = hints == null ? null :\n        (ResultPointCallback) hints.get(DecodeHintType.NEED_RESULT_POINT_CALLBACK);\n\n    FinderPatternFinder finder = new FinderPatternFinder(image, resultPointCallback);\n    FinderPatternInfo info = finder.find(hints);\n\n    return processFinderPatternInfo(info);\n  }\n\n  protected final DetectorResult processFinderPatternInfo(FinderPatternInfo info)\n      throws NotFoundException, FormatException {\n\n    FinderPattern topLeft = info.getTopLeft();\n    FinderPattern topRight = info.getTopRight();\n    FinderPattern bottomLeft = info.getBottomLeft();\n\n    float moduleSize = calculateModuleSize(topLeft, topRight, bottomLeft);\n    if (moduleSize < 1.0f) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n    int dimension = computeDimension(topLeft, topRight, bottomLeft, moduleSize);\n    Version provisionalVersion = Version.getProvisionalVersionForDimension(dimension);\n    int modulesBetweenFPCenters = provisionalVersion.getDimensionForVersion() - 7;\n\n    AlignmentPattern alignmentPattern = null;\n    // Anything above version 1 has an alignment pattern\n    if (provisionalVersion.getAlignmentPatternCenters().length > 0) {\n\n      // Guess where a \"bottom right\" finder pattern would have been\n      float bottomRightX = topRight.getX() - topLeft.getX() + bottomLeft.getX();\n      float bottomRightY = topRight.getY() - topLeft.getY() + bottomLeft.getY();\n\n      // Estimate that alignment pattern is closer by 3 modules\n      // from \"bottom right\" to known top left location\n      float correctionToTopLeft = 1.0f - 3.0f / (float) modulesBetweenFPCenters;\n      int estAlignmentX = (int) (topLeft.getX() + correctionToTopLeft * (bottomRightX - topLeft.getX()));\n      int estAlignmentY = (int) (topLeft.getY() + correctionToTopLeft * (bottomRightY - topLeft.getY()));\n\n      // Kind of arbitrary -- expand search radius before giving up\n      for (int i = 4; i <= 16; i <<= 1) {\n        try {\n          alignmentPattern = findAlignmentInRegion(moduleSize,\n              estAlignmentX,\n              estAlignmentY,\n              (float) i);\n          break;\n        } catch (NotFoundException re) {\n          // try next round\n        }\n      }\n      // If we didn't find alignment pattern... well try anyway without it\n    }\n\n    PerspectiveTransform transform =\n        createTransform(topLeft, topRight, bottomLeft, alignmentPattern, dimension);\n\n    BitMatrix bits = sampleGrid(image, transform, dimension);\n\n    ResultPoint[] points;\n    if (alignmentPattern == null) {\n      points = new ResultPoint[]{bottomLeft, topLeft, topRight};\n    } else {\n      points = new ResultPoint[]{bottomLeft, topLeft, topRight, alignmentPattern};\n    }\n    return new DetectorResult(bits, points);\n  }\n\n  private static PerspectiveTransform createTransform(ResultPoint topLeft,\n                                                      ResultPoint topRight,\n                                                      ResultPoint bottomLeft,\n                                                      ResultPoint alignmentPattern,\n                                                      int dimension) {\n    float dimMinusThree = (float) dimension - 3.5f;\n    float bottomRightX;\n    float bottomRightY;\n    float sourceBottomRightX;\n    float sourceBottomRightY;\n    if (alignmentPattern != null) {\n      bottomRightX = alignmentPattern.getX();\n      bottomRightY = alignmentPattern.getY();\n      sourceBottomRightX = dimMinusThree - 3.0f;\n      sourceBottomRightY = sourceBottomRightX;\n    } else {\n      // Don't have an alignment pattern, just make up the bottom-right point\n      bottomRightX = (topRight.getX() - topLeft.getX()) + bottomLeft.getX();\n      bottomRightY = (topRight.getY() - topLeft.getY()) + bottomLeft.getY();\n      sourceBottomRightX = dimMinusThree;\n      sourceBottomRightY = dimMinusThree;\n    }\n\n    return PerspectiveTransform.quadrilateralToQuadrilateral(\n        3.5f,\n        3.5f,\n        dimMinusThree,\n        3.5f,\n        sourceBottomRightX,\n        sourceBottomRightY,\n        3.5f,\n        dimMinusThree,\n        topLeft.getX(),\n        topLeft.getY(),\n        topRight.getX(),\n        topRight.getY(),\n        bottomRightX,\n        bottomRightY,\n        bottomLeft.getX(),\n        bottomLeft.getY());\n  }\n\n  private static BitMatrix sampleGrid(BitMatrix image,\n                                      PerspectiveTransform transform,\n                                      int dimension) throws NotFoundException {\n\n    GridSampler sampler = GridSampler.getInstance();\n    return sampler.sampleGrid(image, dimension, dimension, transform);\n  }\n\n  /**\n   * <p>Computes the dimension (number of modules on a size) of the QR Code based on the position\n   * of the finder patterns and estimated module size.</p>\n   */\n  private static int computeDimension(ResultPoint topLeft,\n                                      ResultPoint topRight,\n                                      ResultPoint bottomLeft,\n                                      float moduleSize) throws NotFoundException {\n    int tltrCentersDimension = MathUtils.round(ResultPoint.distance(topLeft, topRight) / moduleSize);\n    int tlblCentersDimension = MathUtils.round(ResultPoint.distance(topLeft, bottomLeft) / moduleSize);\n    int dimension = ((tltrCentersDimension + tlblCentersDimension) >> 1) + 7;\n    switch (dimension & 0x03) { // mod 4\n      case 0:\n        dimension++;\n        break;\n        // 1? do nothing\n      case 2:\n        dimension--;\n        break;\n      case 3:\n        throw NotFoundException.getNotFoundInstance();\n    }\n    return dimension;\n  }\n\n  /**\n   * <p>Computes an average estimated module size based on estimated derived from the positions\n   * of the three finder patterns.</p>\n   */\n  protected final float calculateModuleSize(ResultPoint topLeft,\n                                            ResultPoint topRight,\n                                            ResultPoint bottomLeft) {\n    // Take the average\n    return (calculateModuleSizeOneWay(topLeft, topRight) +\n        calculateModuleSizeOneWay(topLeft, bottomLeft)) / 2.0f;\n  }\n\n  /**\n   * <p>Estimates module size based on two finder patterns -- it uses\n   * {@link #sizeOfBlackWhiteBlackRunBothWays(int, int, int, int)} to figure the\n   * width of each, measuring along the axis between their centers.</p>\n   */\n  private float calculateModuleSizeOneWay(ResultPoint pattern, ResultPoint otherPattern) {\n    float moduleSizeEst1 = sizeOfBlackWhiteBlackRunBothWays((int) pattern.getX(),\n        (int) pattern.getY(),\n        (int) otherPattern.getX(),\n        (int) otherPattern.getY());\n    float moduleSizeEst2 = sizeOfBlackWhiteBlackRunBothWays((int) otherPattern.getX(),\n        (int) otherPattern.getY(),\n        (int) pattern.getX(),\n        (int) pattern.getY());\n    if (Float.isNaN(moduleSizeEst1)) {\n      return moduleSizeEst2 / 7.0f;\n    }\n    if (Float.isNaN(moduleSizeEst2)) {\n      return moduleSizeEst1 / 7.0f;\n    }\n    // Average them, and divide by 7 since we've counted the width of 3 black modules,\n    // and 1 white and 1 black module on either side. Ergo, divide sum by 14.\n    return (moduleSizeEst1 + moduleSizeEst2) / 14.0f;\n  }\n\n  /**\n   * See {@link #sizeOfBlackWhiteBlackRun(int, int, int, int)}; computes the total width of\n   * a finder pattern by looking for a black-white-black run from the center in the direction\n   * of another point (another finder pattern center), and in the opposite direction too.</p>\n   */\n  private float sizeOfBlackWhiteBlackRunBothWays(int fromX, int fromY, int toX, int toY) {\n\n    float result = sizeOfBlackWhiteBlackRun(fromX, fromY, toX, toY);\n\n    // Now count other way -- don't run off image though of course\n    float scale = 1.0f;\n    int otherToX = fromX - (toX - fromX);\n    if (otherToX < 0) {\n      scale = (float) fromX / (float) (fromX - otherToX);\n      otherToX = 0;\n    } else if (otherToX >= image.getWidth()) {\n      scale = (float) (image.getWidth() - 1 - fromX) / (float) (otherToX - fromX);\n      otherToX = image.getWidth() - 1;\n    }\n    int otherToY = (int) (fromY - (toY - fromY) * scale);\n\n    scale = 1.0f;\n    if (otherToY < 0) {\n      scale = (float) fromY / (float) (fromY - otherToY);\n      otherToY = 0;\n    } else if (otherToY >= image.getHeight()) {\n      scale = (float) (image.getHeight() - 1 - fromY) / (float) (otherToY - fromY);\n      otherToY = image.getHeight() - 1;\n    }\n    otherToX = (int) (fromX + (otherToX - fromX) * scale);\n\n    result += sizeOfBlackWhiteBlackRun(fromX, fromY, otherToX, otherToY);\n\n    // Middle pixel is double-counted this way; subtract 1\n    return result - 1.0f;\n  }\n\n  /**\n   * <p>This method traces a line from a point in the image, in the direction towards another point.\n   * It begins in a black region, and keeps going until it finds white, then black, then white again.\n   * It reports the distance from the start to this point.</p>\n   *\n   * <p>This is used when figuring out how wide a finder pattern is, when the finder pattern\n   * may be skewed or rotated.</p>\n   */\n  private float sizeOfBlackWhiteBlackRun(int fromX, int fromY, int toX, int toY) {\n    // Mild variant of Bresenham's algorithm;\n    // see http://en.wikipedia.org/wiki/Bresenham's_line_algorithm\n    boolean steep = Math.abs(toY - fromY) > Math.abs(toX - fromX);\n    if (steep) {\n      int temp = fromX;\n      fromX = fromY;\n      fromY = temp;\n      temp = toX;\n      toX = toY;\n      toY = temp;\n    }\n\n    int dx = Math.abs(toX - fromX);\n    int dy = Math.abs(toY - fromY);\n    int error = -dx >> 1;\n    int xstep = fromX < toX ? 1 : -1;\n    int ystep = fromY < toY ? 1 : -1;\n\n    // In black pixels, looking for white, first or second time.\n    int state = 0;\n    // Loop up until x == toX, but not beyond\n    int xLimit = toX + xstep;\n    for (int x = fromX, y = fromY; x != xLimit; x += xstep) {\n      int realX = steep ? y : x;\n      int realY = steep ? x : y;\n\n      // Does current pixel mean we have moved white to black or vice versa?\n      // Scanning black in state 0,2 and white in state 1, so if we find the wrong\n      // color, advance to next state or end if we are in state 2 already\n      if ((state == 1) == image.get(realX, realY)) {\n        if (state == 2) {\n          return MathUtils.distance(x, y, fromX, fromY);\n        }\n        state++;\n      }\n\n      error += dy;\n      if (error > 0) {\n        if (y == toY) {\n          break;\n        }\n        y += ystep;\n        error -= dx;\n      }\n    }\n    // Found black-white-black; give the benefit of the doubt that the next pixel outside the image\n    // is \"white\" so this last point at (toX+xStep,toY) is the right ending. This is really a\n    // small approximation; (toX+xStep,toY+yStep) might be really correct. Ignore this.\n    if (state == 2) {\n      return MathUtils.distance(toX + xstep, toY, fromX, fromY);\n    }\n    // else we didn't find even black-white-black; no estimate is really possible\n    return Float.NaN;\n  }\n\n  /**\n   * <p>Attempts to locate an alignment pattern in a limited region of the image, which is\n   * guessed to contain it. This method uses {@link AlignmentPattern}.</p>\n   *\n   * @param overallEstModuleSize estimated module size so far\n   * @param estAlignmentX x coordinate of center of area probably containing alignment pattern\n   * @param estAlignmentY y coordinate of above\n   * @param allowanceFactor number of pixels in all directions to search from the center\n   * @return {@link AlignmentPattern} if found, or null otherwise\n   * @throws NotFoundException if an unexpected error occurs during detection\n   */\n  protected final AlignmentPattern findAlignmentInRegion(float overallEstModuleSize,\n                                                         int estAlignmentX,\n                                                         int estAlignmentY,\n                                                         float allowanceFactor)\n      throws NotFoundException {\n    // Look for an alignment pattern (3 modules in size) around where it\n    // should be\n    int allowance = (int) (allowanceFactor * overallEstModuleSize);\n    int alignmentAreaLeftX = Math.max(0, estAlignmentX - allowance);\n    int alignmentAreaRightX = Math.min(image.getWidth() - 1, estAlignmentX + allowance);\n    if (alignmentAreaRightX - alignmentAreaLeftX < overallEstModuleSize * 3) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n\n    int alignmentAreaTopY = Math.max(0, estAlignmentY - allowance);\n    int alignmentAreaBottomY = Math.min(image.getHeight() - 1, estAlignmentY + allowance);\n    if (alignmentAreaBottomY - alignmentAreaTopY < overallEstModuleSize * 3) {\n      throw NotFoundException.getNotFoundInstance();\n    }\n\n    AlignmentPatternFinder alignmentFinder =\n        new AlignmentPatternFinder(\n            image,\n            alignmentAreaLeftX,\n            alignmentAreaTopY,\n            alignmentAreaRightX - alignmentAreaLeftX,\n            alignmentAreaBottomY - alignmentAreaTopY,\n            overallEstModuleSize,\n            resultPointCallback);\n    return alignmentFinder.find();\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/qrcode/detector/FinderPattern.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.qrcode.detector;\n\nimport com.google.zxing.ResultPoint;\n\n/**\n * <p>Encapsulates a finder pattern, which are the three square patterns found in\n * the corners of QR Codes. It also encapsulates a count of similar finder patterns,\n * as a convenience to the finder's bookkeeping.</p>\n *\n * @author Sean Owen\n */\npublic final class FinderPattern extends ResultPoint {\n\n  private final float estimatedModuleSize;\n  private int count;\n\n  FinderPattern(float posX, float posY, float estimatedModuleSize) {\n    this(posX, posY, estimatedModuleSize, 1);\n  }\n\n  private FinderPattern(float posX, float posY, float estimatedModuleSize, int count) {\n    super(posX, posY);\n    this.estimatedModuleSize = estimatedModuleSize;\n    this.count = count;\n  }\n\n  public float getEstimatedModuleSize() {\n    return estimatedModuleSize;\n  }\n\n  int getCount() {\n    return count;\n  }\n\n  void incrementCount() {\n    this.count++;\n  }\n\n  /**\n   * <p>Determines if this finder pattern \"about equals\" a finder pattern at the stated\n   * position and size -- meaning, it is at nearly the same center with nearly the same size.</p>\n   */\n  boolean aboutEquals(float moduleSize, float i, float j) {\n    if (Math.abs(i - getY()) <= moduleSize && Math.abs(j - getX()) <= moduleSize) {\n      float moduleSizeDiff = Math.abs(moduleSize - estimatedModuleSize);\n      return moduleSizeDiff <= 1.0f || moduleSizeDiff <= estimatedModuleSize;\n    }\n    return false;\n  }\n\n  /**\n   * Combines this object's current estimate of a finder pattern position and module size\n   * with a new estimate. It returns a new {@code FinderPattern} containing a weighted average\n   * based on count.\n   */\n  FinderPattern combineEstimate(float i, float j, float newModuleSize) {\n    int combinedCount = count + 1;\n    float combinedX = (count * getX() + j) / combinedCount;\n    float combinedY = (count * getY() + i) / combinedCount;\n    float combinedModuleSize = (count * estimatedModuleSize + newModuleSize) / combinedCount;\n    return new FinderPattern(combinedX, combinedY, combinedModuleSize, combinedCount);\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/qrcode/detector/FinderPatternFinder.java",
    "content": "/*\r\n * Copyright 2007 ZXing authors\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n *      http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\npackage com.google.zxing.qrcode.detector;\r\n\r\nimport com.google.zxing.DecodeHintType;\r\nimport com.google.zxing.NotFoundException;\r\nimport com.google.zxing.ResultPoint;\r\nimport com.google.zxing.ResultPointCallback;\r\nimport com.google.zxing.common.BitMatrix;\r\n\r\nimport java.io.Serializable;\r\nimport java.util.ArrayList;\r\nimport java.util.Collections;\r\nimport java.util.Comparator;\r\nimport java.util.List;\r\nimport java.util.Map;\r\n\r\n/**\r\n * <p>This class attempts to find finder patterns in a QR Code. Finder patterns are the square\r\n * markers at three corners of a QR Code.</p>\r\n *\r\n * <p>This class is thread-safe but not reentrant. Each thread must allocate its own object.\r\n *\r\n * @author Sean Owen\r\n */\r\npublic class FinderPatternFinder {\r\n\r\n  private static final int CENTER_QUORUM = 2;\r\n  protected static final int MIN_SKIP = 3; // 1 pixel/module times 3 modules/center\r\n  protected static final int MAX_MODULES = 57; // support up to version 10 for mobile clients\r\n  private static final int INTEGER_MATH_SHIFT = 8;\r\n\r\n  private final BitMatrix image;\r\n  private final List<FinderPattern> possibleCenters;\r\n  private boolean hasSkipped;\r\n  private final int[] crossCheckStateCount;\r\n  private final ResultPointCallback resultPointCallback;\r\n\r\n  /**\r\n   * <p>Creates a finder that will search the image for three finder patterns.</p>\r\n   *\r\n   * @param image image to search\r\n   */\r\n  public FinderPatternFinder(BitMatrix image) {\r\n    this(image, null);\r\n  }\r\n\r\n  public FinderPatternFinder(BitMatrix image, ResultPointCallback resultPointCallback) {\r\n    this.image = image;\r\n    this.possibleCenters = new ArrayList<FinderPattern>();\r\n    this.crossCheckStateCount = new int[5];\r\n    this.resultPointCallback = resultPointCallback;\r\n  }\r\n\r\n  protected final BitMatrix getImage() {\r\n    return image;\r\n  }\r\n\r\n  protected final List<FinderPattern> getPossibleCenters() {\r\n    return possibleCenters;\r\n  }\r\n\r\n  final FinderPatternInfo find(Map<DecodeHintType,?> hints) throws NotFoundException {\r\n    boolean tryHarder = hints != null && hints.containsKey(DecodeHintType.TRY_HARDER);\r\n    int maxI = image.getHeight();\r\n    int maxJ = image.getWidth();\r\n    // We are looking for black/white/black/white/black modules in\r\n    // 1:1:3:1:1 ratio; this tracks the number of such modules seen so far\r\n\r\n    // Let's assume that the maximum version QR Code we support takes up 1/4 the height of the\r\n    // image, and then account for the center being 3 modules in size. This gives the smallest\r\n    // number of pixels the center could be, so skip this often. When trying harder, look for all\r\n    // QR versions regardless of how dense they are.\r\n    int iSkip = (3 * maxI) / (4 * MAX_MODULES);\r\n    if (iSkip < MIN_SKIP || tryHarder) {\r\n      iSkip = MIN_SKIP;\r\n    }\r\n\r\n    boolean done = false;\r\n    int[] stateCount = new int[5];\r\n    for (int i = iSkip - 1; i < maxI && !done; i += iSkip) {\r\n      // Get a row of black/white values\r\n      stateCount[0] = 0;\r\n      stateCount[1] = 0;\r\n      stateCount[2] = 0;\r\n      stateCount[3] = 0;\r\n      stateCount[4] = 0;\r\n      int currentState = 0;\r\n      for (int j = 0; j < maxJ; j++) {\r\n        if (image.get(j, i)) {\r\n          // Black pixel\r\n          if ((currentState & 1) == 1) { // Counting white pixels\r\n            currentState++;\r\n          }\r\n          stateCount[currentState]++;\r\n        } else { // White pixel\r\n          if ((currentState & 1) == 0) { // Counting black pixels\r\n            if (currentState == 4) { // A winner?\r\n              if (foundPatternCross(stateCount)) { // Yes\r\n                boolean confirmed = handlePossibleCenter(stateCount, i, j);\r\n                if (confirmed) {\r\n                  // Start examining every other line. Checking each line turned out to be too\r\n                  // expensive and didn't improve performance.\r\n                  iSkip = 2;\r\n                  if (hasSkipped) {\r\n                    done = haveMultiplyConfirmedCenters();\r\n                  } else {\r\n                    int rowSkip = findRowSkip();\r\n                    if (rowSkip > stateCount[2]) {\r\n                      // Skip rows between row of lower confirmed center\r\n                      // and top of presumed third confirmed center\r\n                      // but back up a bit to get a full chance of detecting\r\n                      // it, entire width of center of finder pattern\r\n\r\n                      // Skip by rowSkip, but back off by stateCount[2] (size of last center\r\n                      // of pattern we saw) to be conservative, and also back off by iSkip which\r\n                      // is about to be re-added\r\n                      i += rowSkip - stateCount[2] - iSkip;\r\n                      j = maxJ - 1;\r\n                    }\r\n                  }\r\n                } else {\r\n                  stateCount[0] = stateCount[2];\r\n                  stateCount[1] = stateCount[3];\r\n                  stateCount[2] = stateCount[4];\r\n                  stateCount[3] = 1;\r\n                  stateCount[4] = 0;\r\n                  currentState = 3;\r\n                  continue;\r\n                }\r\n                // Clear state to start looking again\r\n                currentState = 0;\r\n                stateCount[0] = 0;\r\n                stateCount[1] = 0;\r\n                stateCount[2] = 0;\r\n                stateCount[3] = 0;\r\n                stateCount[4] = 0;\r\n              } else { // No, shift counts back by two\r\n                stateCount[0] = stateCount[2];\r\n                stateCount[1] = stateCount[3];\r\n                stateCount[2] = stateCount[4];\r\n                stateCount[3] = 1;\r\n                stateCount[4] = 0;\r\n                currentState = 3;\r\n              }\r\n            } else {\r\n              stateCount[++currentState]++;\r\n            }\r\n          } else { // Counting white pixels\r\n            stateCount[currentState]++;\r\n          }\r\n        }\r\n      }\r\n      if (foundPatternCross(stateCount)) {\r\n        boolean confirmed = handlePossibleCenter(stateCount, i, maxJ);\r\n        if (confirmed) {\r\n          iSkip = stateCount[0];\r\n          if (hasSkipped) {\r\n            // Found a third one\r\n            done = haveMultiplyConfirmedCenters();\r\n          }\r\n        }\r\n      }\r\n    }\r\n\r\n    FinderPattern[] patternInfo = selectBestPatterns();\r\n    ResultPoint.orderBestPatterns(patternInfo);\r\n\r\n    return new FinderPatternInfo(patternInfo);\r\n  }\r\n\r\n  /**\r\n   * Given a count of black/white/black/white/black pixels just seen and an end position,\r\n   * figures the location of the center of this run.\r\n   */\r\n  private static float centerFromEnd(int[] stateCount, int end) {\r\n    return (float) (end - stateCount[4] - stateCount[3]) - stateCount[2] / 2.0f;\r\n  }\r\n\r\n  /**\r\n   * @param stateCount count of black/white/black/white/black pixels just read\r\n   * @return true iff the proportions of the counts is close enough to the 1/1/3/1/1 ratios\r\n   *         used by finder patterns to be considered a match\r\n   */\r\n  protected static boolean foundPatternCross(int[] stateCount) {\r\n    int totalModuleSize = 0;\r\n    for (int i = 0; i < 5; i++) {\r\n      int count = stateCount[i];\r\n      if (count == 0) {\r\n        return false;\r\n      }\r\n      totalModuleSize += count;\r\n    }\r\n    if (totalModuleSize < 7) {\r\n      return false;\r\n    }\r\n    int moduleSize = (totalModuleSize << INTEGER_MATH_SHIFT) / 7;\r\n    int maxVariance = moduleSize / 2;\r\n    // Allow less than 50% variance from 1-1-3-1-1 proportions\r\n    return Math.abs(moduleSize - (stateCount[0] << INTEGER_MATH_SHIFT)) < maxVariance &&\r\n        Math.abs(moduleSize - (stateCount[1] << INTEGER_MATH_SHIFT)) < maxVariance &&\r\n        Math.abs(3 * moduleSize - (stateCount[2] << INTEGER_MATH_SHIFT)) < 3 * maxVariance &&\r\n        Math.abs(moduleSize - (stateCount[3] << INTEGER_MATH_SHIFT)) < maxVariance &&\r\n        Math.abs(moduleSize - (stateCount[4] << INTEGER_MATH_SHIFT)) < maxVariance;\r\n  }\r\n\r\n  private int[] getCrossCheckStateCount() {\r\n    crossCheckStateCount[0] = 0;\r\n    crossCheckStateCount[1] = 0;\r\n    crossCheckStateCount[2] = 0;\r\n    crossCheckStateCount[3] = 0;\r\n    crossCheckStateCount[4] = 0;\r\n    return crossCheckStateCount;\r\n  }\r\n\r\n  /**\r\n   * <p>After a horizontal scan finds a potential finder pattern, this method\r\n   * \"cross-checks\" by scanning down vertically through the center of the possible\r\n   * finder pattern to see if the same proportion is detected.</p>\r\n   *\r\n   * @param startI row where a finder pattern was detected\r\n   * @param centerJ center of the section that appears to cross a finder pattern\r\n   * @param maxCount maximum reasonable number of modules that should be\r\n   * observed in any reading state, based on the results of the horizontal scan\r\n   * @return vertical center of finder pattern, or {@link Float#NaN} if not found\r\n   */\r\n  private float crossCheckVertical(int startI, int centerJ, int maxCount,\r\n      int originalStateCountTotal) {\r\n    BitMatrix image = this.image;\r\n\r\n    int maxI = image.getHeight();\r\n    int[] stateCount = getCrossCheckStateCount();\r\n\r\n    // Start counting up from center\r\n    int i = startI;\r\n    while (i >= 0 && image.get(centerJ, i)) {\r\n      stateCount[2]++;\r\n      i--;\r\n    }\r\n    if (i < 0) {\r\n      return Float.NaN;\r\n    }\r\n    while (i >= 0 && !image.get(centerJ, i) && stateCount[1] <= maxCount) {\r\n      stateCount[1]++;\r\n      i--;\r\n    }\r\n    // If already too many modules in this state or ran off the edge:\r\n    if (i < 0 || stateCount[1] > maxCount) {\r\n      return Float.NaN;\r\n    }\r\n    while (i >= 0 && image.get(centerJ, i) && stateCount[0] <= maxCount) {\r\n      stateCount[0]++;\r\n      i--;\r\n    }\r\n    if (stateCount[0] > maxCount) {\r\n      return Float.NaN;\r\n    }\r\n\r\n    // Now also count down from center\r\n    i = startI + 1;\r\n    while (i < maxI && image.get(centerJ, i)) {\r\n      stateCount[2]++;\r\n      i++;\r\n    }\r\n    if (i == maxI) {\r\n      return Float.NaN;\r\n    }\r\n    while (i < maxI && !image.get(centerJ, i) && stateCount[3] < maxCount) {\r\n      stateCount[3]++;\r\n      i++;\r\n    }\r\n    if (i == maxI || stateCount[3] >= maxCount) {\r\n      return Float.NaN;\r\n    }\r\n    while (i < maxI && image.get(centerJ, i) && stateCount[4] < maxCount) {\r\n      stateCount[4]++;\r\n      i++;\r\n    }\r\n    if (stateCount[4] >= maxCount) {\r\n      return Float.NaN;\r\n    }\r\n\r\n    // If we found a finder-pattern-like section, but its size is more than 40% different than\r\n    // the original, assume it's a false positive\r\n    int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] +\r\n        stateCount[4];\r\n    if (5 * Math.abs(stateCountTotal - originalStateCountTotal) >= 2 * originalStateCountTotal) {\r\n      return Float.NaN;\r\n    }\r\n\r\n    return foundPatternCross(stateCount) ? centerFromEnd(stateCount, i) : Float.NaN;\r\n  }\r\n\r\n  /**\r\n   * <p>Like {@link #crossCheckVertical(int, int, int, int)}, and in fact is basically identical,\r\n   * except it reads horizontally instead of vertically. This is used to cross-cross\r\n   * check a vertical cross check and locate the real center of the alignment pattern.</p>\r\n   */\r\n  private float crossCheckHorizontal(int startJ, int centerI, int maxCount,\r\n      int originalStateCountTotal) {\r\n    BitMatrix image = this.image;\r\n\r\n    int maxJ = image.getWidth();\r\n    int[] stateCount = getCrossCheckStateCount();\r\n\r\n    int j = startJ;\r\n    while (j >= 0 && image.get(j, centerI)) {\r\n      stateCount[2]++;\r\n      j--;\r\n    }\r\n    if (j < 0) {\r\n      return Float.NaN;\r\n    }\r\n    while (j >= 0 && !image.get(j, centerI) && stateCount[1] <= maxCount) {\r\n      stateCount[1]++;\r\n      j--;\r\n    }\r\n    if (j < 0 || stateCount[1] > maxCount) {\r\n      return Float.NaN;\r\n    }\r\n    while (j >= 0 && image.get(j, centerI) && stateCount[0] <= maxCount) {\r\n      stateCount[0]++;\r\n      j--;\r\n    }\r\n    if (stateCount[0] > maxCount) {\r\n      return Float.NaN;\r\n    }\r\n\r\n    j = startJ + 1;\r\n    while (j < maxJ && image.get(j, centerI)) {\r\n      stateCount[2]++;\r\n      j++;\r\n    }\r\n    if (j == maxJ) {\r\n      return Float.NaN;\r\n    }\r\n    while (j < maxJ && !image.get(j, centerI) && stateCount[3] < maxCount) {\r\n      stateCount[3]++;\r\n      j++;\r\n    }\r\n    if (j == maxJ || stateCount[3] >= maxCount) {\r\n      return Float.NaN;\r\n    }\r\n    while (j < maxJ && image.get(j, centerI) && stateCount[4] < maxCount) {\r\n      stateCount[4]++;\r\n      j++;\r\n    }\r\n    if (stateCount[4] >= maxCount) {\r\n      return Float.NaN;\r\n    }\r\n\r\n    // If we found a finder-pattern-like section, but its size is significantly different than\r\n    // the original, assume it's a false positive\r\n    int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] +\r\n        stateCount[4];\r\n    if (5 * Math.abs(stateCountTotal - originalStateCountTotal) >= originalStateCountTotal) {\r\n      return Float.NaN;\r\n    }\r\n\r\n    return foundPatternCross(stateCount) ? centerFromEnd(stateCount, j) : Float.NaN;\r\n  }\r\n\r\n  /**\r\n   * <p>This is called when a horizontal scan finds a possible alignment pattern. It will\r\n   * cross check with a vertical scan, and if successful, will, ah, cross-cross-check\r\n   * with another horizontal scan. This is needed primarily to locate the real horizontal\r\n   * center of the pattern in cases of extreme skew.</p>\r\n   *\r\n   * <p>If that succeeds the finder pattern location is added to a list that tracks\r\n   * the number of times each location has been nearly-matched as a finder pattern.\r\n   * Each additional find is more evidence that the location is in fact a finder\r\n   * pattern center\r\n   *\r\n   * @param stateCount reading state module counts from horizontal scan\r\n   * @param i row where finder pattern may be found\r\n   * @param j end of possible finder pattern in row\r\n   * @return true if a finder pattern candidate was found this time\r\n   */\r\n  protected final boolean handlePossibleCenter(int[] stateCount, int i, int j) {\r\n    int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] +\r\n        stateCount[4];\r\n    float centerJ = centerFromEnd(stateCount, j);\r\n    float centerI = crossCheckVertical(i, (int) centerJ, stateCount[2], stateCountTotal);\r\n    if (!Float.isNaN(centerI)) {\r\n      // Re-cross check\r\n      centerJ = crossCheckHorizontal((int) centerJ, (int) centerI, stateCount[2], stateCountTotal);\r\n      if (!Float.isNaN(centerJ)) {\r\n        float estimatedModuleSize = (float) stateCountTotal / 7.0f;\r\n        boolean found = false;\r\n        for (int index = 0; index < possibleCenters.size(); index++) {\r\n          FinderPattern center = possibleCenters.get(index);\r\n          // Look for about the same center and module size:\r\n          if (center.aboutEquals(estimatedModuleSize, centerI, centerJ)) {\r\n            possibleCenters.set(index, center.combineEstimate(centerI, centerJ, estimatedModuleSize));\r\n            found = true;\r\n            break;\r\n          }\r\n        }\r\n        if (!found) {\r\n          FinderPattern point = new FinderPattern(centerJ, centerI, estimatedModuleSize);\r\n          possibleCenters.add(point);\r\n          if (resultPointCallback != null) {\r\n            resultPointCallback.foundPossibleResultPoint(point);\r\n          }\r\n        }\r\n        return true;\r\n      }\r\n    }\r\n    return false;\r\n  }\r\n\r\n  /**\r\n   * @return number of rows we could safely skip during scanning, based on the first\r\n   *         two finder patterns that have been located. In some cases their position will\r\n   *         allow us to infer that the third pattern must lie below a certain point farther\r\n   *         down in the image.\r\n   */\r\n  private int findRowSkip() {\r\n    int max = possibleCenters.size();\r\n    if (max <= 1) {\r\n      return 0;\r\n    }\r\n    FinderPattern firstConfirmedCenter = null;\r\n    for (FinderPattern center : possibleCenters) {\r\n      if (center.getCount() >= CENTER_QUORUM) {\r\n        if (firstConfirmedCenter == null) {\r\n          firstConfirmedCenter = center;\r\n        } else {\r\n          // We have two confirmed centers\r\n          // How far down can we skip before resuming looking for the next\r\n          // pattern? In the worst case, only the difference between the\r\n          // difference in the x / y coordinates of the two centers.\r\n          // This is the case where you find top left last.\r\n          hasSkipped = true;\r\n          return (int) (Math.abs(firstConfirmedCenter.getX() - center.getX()) -\r\n              Math.abs(firstConfirmedCenter.getY() - center.getY())) / 2;\r\n        }\r\n      }\r\n    }\r\n    return 0;\r\n  }\r\n\r\n  /**\r\n   * @return true iff we have found at least 3 finder patterns that have been detected\r\n   *         at least {@link #CENTER_QUORUM} times each, and, the estimated module size of the\r\n   *         candidates is \"pretty similar\"\r\n   */\r\n  private boolean haveMultiplyConfirmedCenters() {\r\n    int confirmedCount = 0;\r\n    float totalModuleSize = 0.0f;\r\n    int max = possibleCenters.size();\r\n    for (FinderPattern pattern : possibleCenters) {\r\n      if (pattern.getCount() >= CENTER_QUORUM) {\r\n        confirmedCount++;\r\n        totalModuleSize += pattern.getEstimatedModuleSize();\r\n      }\r\n    }\r\n    if (confirmedCount < 3) {\r\n      return false;\r\n    }\r\n    // OK, we have at least 3 confirmed centers, but, it's possible that one is a \"false positive\"\r\n    // and that we need to keep looking. We detect this by asking if the estimated module sizes\r\n    // vary too much. We arbitrarily say that when the total deviation from average exceeds\r\n    // 5% of the total module size estimates, it's too much.\r\n    float average = totalModuleSize / (float) max;\r\n    float totalDeviation = 0.0f;\r\n    for (FinderPattern pattern : possibleCenters) {\r\n      totalDeviation += Math.abs(pattern.getEstimatedModuleSize() - average);\r\n    }\r\n    return totalDeviation <= 0.05f * totalModuleSize;\r\n  }\r\n\r\n  /**\r\n   * @return the 3 best {@link FinderPattern}s from our list of candidates. The \"best\" are\r\n   *         those that have been detected at least {@link #CENTER_QUORUM} times, and whose module\r\n   *         size differs from the average among those patterns the least\r\n   * @throws NotFoundException if 3 such finder patterns do not exist\r\n   */\r\n  private FinderPattern[] selectBestPatterns() throws NotFoundException {\r\n\r\n    int startSize = possibleCenters.size();\r\n    if (startSize < 3) {\r\n      // Couldn't find enough finder patterns\r\n      throw NotFoundException.getNotFoundInstance();\r\n    }\r\n\r\n    // Filter outlier possibilities whose module size is too different\r\n    if (startSize > 3) {\r\n      // But we can only afford to do so if we have at least 4 possibilities to choose from\r\n      float totalModuleSize = 0.0f;\r\n      float square = 0.0f;\r\n      for (FinderPattern center : possibleCenters) {\r\n        float size = center.getEstimatedModuleSize();\r\n        totalModuleSize += size;\r\n        square += size * size;\r\n      }\r\n      float average = totalModuleSize / (float) startSize;\r\n      float stdDev = (float) Math.sqrt(square / startSize - average * average);\r\n\r\n      Collections.sort(possibleCenters, new FurthestFromAverageComparator(average));\r\n\r\n      float limit = Math.max(0.2f * average, stdDev);\r\n\r\n      for (int i = 0; i < possibleCenters.size() && possibleCenters.size() > 3; i++) {\r\n        FinderPattern pattern = possibleCenters.get(i);\r\n        if (Math.abs(pattern.getEstimatedModuleSize() - average) > limit) {\r\n          possibleCenters.remove(i);\r\n          i--;\r\n        }\r\n      }\r\n    }\r\n\r\n    if (possibleCenters.size() > 3) {\r\n      // Throw away all but those first size candidate points we found.\r\n\r\n      float totalModuleSize = 0.0f;\r\n      for (FinderPattern possibleCenter : possibleCenters) {\r\n        totalModuleSize += possibleCenter.getEstimatedModuleSize();\r\n      }\r\n\r\n      float average = totalModuleSize / (float) possibleCenters.size();\r\n\r\n      Collections.sort(possibleCenters, new CenterComparator(average));\r\n\r\n      possibleCenters.subList(3, possibleCenters.size()).clear();\r\n    }\r\n\r\n    return new FinderPattern[]{\r\n        possibleCenters.get(0),\r\n        possibleCenters.get(1),\r\n        possibleCenters.get(2)\r\n    };\r\n  }\r\n\r\n  /**\r\n   * <p>Orders by furthest from average</p>\r\n   */\r\n  private static final class FurthestFromAverageComparator implements Comparator<FinderPattern>, Serializable {\r\n    private final float average;\r\n    private FurthestFromAverageComparator(float f) {\r\n      average = f;\r\n    }\r\n    @Override\r\n    public int compare(FinderPattern center1, FinderPattern center2) {\r\n      float dA = Math.abs(center2.getEstimatedModuleSize() - average);\r\n      float dB = Math.abs(center1.getEstimatedModuleSize() - average);\r\n      return dA < dB ? -1 : dA == dB ? 0 : 1;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * <p>Orders by {@link FinderPattern#getCount()}, descending.</p>\r\n   */\r\n  private static final class CenterComparator implements Comparator<FinderPattern>, Serializable {\r\n    private final float average;\r\n    private CenterComparator(float f) {\r\n      average = f;\r\n    }\r\n    @Override\r\n    public int compare(FinderPattern center1, FinderPattern center2) {\r\n      if (center2.getCount() == center1.getCount()) {\r\n        float dA = Math.abs(center2.getEstimatedModuleSize() - average);\r\n        float dB = Math.abs(center1.getEstimatedModuleSize() - average);\r\n        return dA < dB ? 1 : dA == dB ? 0 : -1;\r\n      } else {\r\n        return center2.getCount() - center1.getCount();\r\n      }\r\n    }\r\n  }\r\n\r\n}\r\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/qrcode/detector/FinderPatternInfo.java",
    "content": "/*\n * Copyright 2007 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.qrcode.detector;\n\n/**\n * <p>Encapsulates information about finder patterns in an image, including the location of\n * the three finder patterns, and their estimated module size.</p>\n *\n * @author Sean Owen\n */\npublic final class FinderPatternInfo {\n\n  private final FinderPattern bottomLeft;\n  private final FinderPattern topLeft;\n  private final FinderPattern topRight;\n\n  public FinderPatternInfo(FinderPattern[] patternCenters) {\n    this.bottomLeft = patternCenters[0];\n    this.topLeft = patternCenters[1];\n    this.topRight = patternCenters[2];\n  }\n\n  public FinderPattern getBottomLeft() {\n    return bottomLeft;\n  }\n\n  public FinderPattern getTopLeft() {\n    return topLeft;\n  }\n\n  public FinderPattern getTopRight() {\n    return topRight;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/qrcode/encoder/BlockPair.java",
    "content": "/*\n * Copyright 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.qrcode.encoder;\n\nfinal class BlockPair {\n\n  private final byte[] dataBytes;\n  private final byte[] errorCorrectionBytes;\n\n  BlockPair(byte[] data, byte[] errorCorrection) {\n    dataBytes = data;\n    errorCorrectionBytes = errorCorrection;\n  }\n\n  public byte[] getDataBytes() {\n    return dataBytes;\n  }\n\n  public byte[] getErrorCorrectionBytes() {\n    return errorCorrectionBytes;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/qrcode/encoder/ByteMatrix.java",
    "content": "/*\n * Copyright 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.qrcode.encoder;\n\n/**\n * A class which wraps a 2D array of bytes. The default usage is signed. If you want to use it as a\n * unsigned container, it's up to you to do byteValue & 0xff at each location.\n *\n * JAVAPORT: The original code was a 2D array of ints, but since it only ever gets assigned\n * -1, 0, and 1, I'm going to use less memory and go with bytes.\n *\n * @author dswitkin@google.com (Daniel Switkin)\n */\npublic final class ByteMatrix {\n\n  private final byte[][] bytes;\n  private final int width;\n  private final int height;\n\n  public ByteMatrix(int width, int height) {\n    bytes = new byte[height][width];\n    this.width = width;\n    this.height = height;\n  }\n\n  public int getHeight() {\n    return height;\n  }\n\n  public int getWidth() {\n    return width;\n  }\n\n  public byte get(int x, int y) {\n    return bytes[y][x];\n  }\n\n  public byte[][] getArray() {\n    return bytes;\n  }\n\n  public void set(int x, int y, byte value) {\n    bytes[y][x] = value;\n  }\n\n  public void set(int x, int y, int value) {\n    bytes[y][x] = (byte) value;\n  }\n\n  public void set(int x, int y, boolean value) {\n    bytes[y][x] = (byte) (value ? 1 : 0);\n  }\n\n  public void clear(byte value) {\n    for (int y = 0; y < height; ++y) {\n      for (int x = 0; x < width; ++x) {\n        bytes[y][x] = value;\n      }\n    }\n  }\n\n  @Override\n  public String toString() {\n    StringBuilder result = new StringBuilder(2 * width * height + 2);\n    for (int y = 0; y < height; ++y) {\n      for (int x = 0; x < width; ++x) {\n        switch (bytes[y][x]) {\n          case 0:\n            result.append(\" 0\");\n            break;\n          case 1:\n            result.append(\" 1\");\n            break;\n          default:\n            result.append(\"  \");\n            break;\n        }\n      }\n      result.append('\\n');\n    }\n    return result.toString();\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/qrcode/encoder/Encoder.java",
    "content": "/*\n * Copyright 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.qrcode.encoder;\n\nimport com.google.zxing.EncodeHintType;\nimport com.google.zxing.WriterException;\nimport com.google.zxing.common.BitArray;\nimport com.google.zxing.common.CharacterSetECI;\nimport com.google.zxing.common.reedsolomon.GenericGF;\nimport com.google.zxing.common.reedsolomon.ReedSolomonEncoder;\nimport com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;\nimport com.google.zxing.qrcode.decoder.Mode;\nimport com.google.zxing.qrcode.decoder.Version;\n\nimport java.io.UnsupportedEncodingException;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Map;\n\n/**\n * @author satorux@google.com (Satoru Takabayashi) - creator\n * @author dswitkin@google.com (Daniel Switkin) - ported from C++\n */\npublic final class Encoder {\n\n  // The original table is defined in the table 5 of JISX0510:2004 (p.19).\n  private static final int[] ALPHANUMERIC_TABLE = {\n      -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  // 0x00-0x0f\n      -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  // 0x10-0x1f\n      36, -1, -1, -1, 37, 38, -1, -1, -1, -1, 39, 40, -1, 41, 42, 43,  // 0x20-0x2f\n      0,   1,  2,  3,  4,  5,  6,  7,  8,  9, 44, -1, -1, -1, -1, -1,  // 0x30-0x3f\n      -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,  // 0x40-0x4f\n      25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1,  // 0x50-0x5f\n  };\n\n  static final String DEFAULT_BYTE_MODE_ENCODING = \"ISO-8859-1\";\n\n  private Encoder() {\n  }\n\n  // The mask penalty calculation is complicated.  See Table 21 of JISX0510:2004 (p.45) for details.\n  // Basically it applies four rules and summate all penalties.\n  private static int calculateMaskPenalty(ByteMatrix matrix) {\n    return MaskUtil.applyMaskPenaltyRule1(matrix)\n        + MaskUtil.applyMaskPenaltyRule2(matrix)\n        + MaskUtil.applyMaskPenaltyRule3(matrix)\n        + MaskUtil.applyMaskPenaltyRule4(matrix);\n  }\n\n  /**\n   *  Encode \"bytes\" with the error correction level \"ecLevel\". The encoding mode will be chosen\n   * internally by chooseMode(). On success, store the result in \"qrCode\".\n   *\n   * We recommend you to use QRCode.EC_LEVEL_L (the lowest level) for\n   * \"getECLevel\" since our primary use is to show QR code on desktop screens. We don't need very\n   * strong error correction for this purpose.\n   *\n   * Note that there is no way to encode bytes in MODE_KANJI. We might want to add EncodeWithMode()\n   * with which clients can specify the encoding mode. For now, we don't need the functionality.\n   */\n  public static QRCode encode(String content, ErrorCorrectionLevel ecLevel) throws WriterException {\n    return encode(content, ecLevel, null);\n  }\n\n  public static QRCode encode(String content,\n                              ErrorCorrectionLevel ecLevel,\n                              Map<EncodeHintType,?> hints) throws WriterException {\n\n    // Determine what character encoding has been specified by the caller, if any\n    String encoding = hints == null ? null : (String) hints.get(EncodeHintType.CHARACTER_SET);\n    if (encoding == null) {\n      encoding = DEFAULT_BYTE_MODE_ENCODING;\n    }\n\n    // Pick an encoding mode appropriate for the content. Note that this will not attempt to use\n    // multiple modes / segments even if that were more efficient. Twould be nice.\n    Mode mode = chooseMode(content, encoding);\n\n    // This will store the header information, like mode and\n    // length, as well as \"header\" segments like an ECI segment.\n    BitArray headerBits = new BitArray();\n\n    // Append ECI segment if applicable\n    if (mode == Mode.BYTE && !DEFAULT_BYTE_MODE_ENCODING.equals(encoding)) {\n      CharacterSetECI eci = CharacterSetECI.getCharacterSetECIByName(encoding);\n      if (eci != null) {\n        appendECI(eci, headerBits);\n      }\n    }\n\n    // (With ECI in place,) Write the mode marker\n    appendModeInfo(mode, headerBits);\n\n    // Collect data within the main segment, separately, to count its size if needed. Don't add it to\n    // main payload yet.\n    BitArray dataBits = new BitArray();\n    appendBytes(content, mode, dataBits, encoding);\n\n    // Hard part: need to know version to know how many bits length takes. But need to know how many\n    // bits it takes to know version. First we take a guess at version by assuming version will be\n    // the minimum, 1:\n\n    int provisionalBitsNeeded = headerBits.getSize()\n        + mode.getCharacterCountBits(Version.getVersionForNumber(1))\n        + dataBits.getSize();\n    Version provisionalVersion = chooseVersion(provisionalBitsNeeded, ecLevel);\n\n    // Use that guess to calculate the right version. I am still not sure this works in 100% of cases.\n\n    int bitsNeeded = headerBits.getSize()\n        + mode.getCharacterCountBits(provisionalVersion)\n        + dataBits.getSize();\n    Version version = chooseVersion(bitsNeeded, ecLevel);\n\n    BitArray headerAndDataBits = new BitArray();\n    headerAndDataBits.appendBitArray(headerBits);\n    // Find \"length\" of main segment and write it\n    int numLetters = mode == Mode.BYTE ? dataBits.getSizeInBytes() : content.length();\n    appendLengthInfo(numLetters, version, mode, headerAndDataBits);\n    // Put data together into the overall payload\n    headerAndDataBits.appendBitArray(dataBits);\n\n    Version.ECBlocks ecBlocks = version.getECBlocksForLevel(ecLevel);\n    int numDataBytes = version.getTotalCodewords() - ecBlocks.getTotalECCodewords();\n\n    // Terminate the bits properly.\n    terminateBits(numDataBytes, headerAndDataBits);\n\n    // Interleave data bits with error correction code.\n    BitArray finalBits = interleaveWithECBytes(headerAndDataBits,\n                                               version.getTotalCodewords(),\n                                               numDataBytes,\n                                               ecBlocks.getNumBlocks());\n\n    QRCode qrCode = new QRCode();\n\n    qrCode.setECLevel(ecLevel);\n    qrCode.setMode(mode);\n    qrCode.setVersion(version);\n\n    //  Choose the mask pattern and set to \"qrCode\".\n    int dimension = version.getDimensionForVersion();\n    ByteMatrix matrix = new ByteMatrix(dimension, dimension);\n    int maskPattern = chooseMaskPattern(finalBits, ecLevel, version, matrix);\n    qrCode.setMaskPattern(maskPattern);\n\n    // Build the matrix and set it to \"qrCode\".\n    MatrixUtil.buildMatrix(finalBits, ecLevel, version, maskPattern, matrix);\n    qrCode.setMatrix(matrix);\n\n    return qrCode;\n  }\n\n  /**\n   * @return the code point of the table used in alphanumeric mode or\n   *  -1 if there is no corresponding code in the table.\n   */\n  static int getAlphanumericCode(int code) {\n    if (code < ALPHANUMERIC_TABLE.length) {\n      return ALPHANUMERIC_TABLE[code];\n    }\n    return -1;\n  }\n\n  public static Mode chooseMode(String content) {\n    return chooseMode(content, null);\n  }\n\n  /**\n   * Choose the best mode by examining the content. Note that 'encoding' is used as a hint;\n   * if it is Shift_JIS, and the input is only double-byte Kanji, then we return {@link Mode#KANJI}.\n   */\n  private static Mode chooseMode(String content, String encoding) {\n    if (\"Shift_JIS\".equals(encoding)) {\n      // Choose Kanji mode if all input are double-byte characters\n      return isOnlyDoubleByteKanji(content) ? Mode.KANJI : Mode.BYTE;\n    }\n    boolean hasNumeric = false;\n    boolean hasAlphanumeric = false;\n    for (int i = 0; i < content.length(); ++i) {\n      char c = content.charAt(i);\n      if (c >= '0' && c <= '9') {\n        hasNumeric = true;\n      } else if (getAlphanumericCode(c) != -1) {\n        hasAlphanumeric = true;\n      } else {\n        return Mode.BYTE;\n      }\n    }\n    if (hasAlphanumeric) {\n      return Mode.ALPHANUMERIC;\n    }\n    if (hasNumeric) {\n      return Mode.NUMERIC;\n    }\n    return Mode.BYTE;\n  }\n\n  private static boolean isOnlyDoubleByteKanji(String content) {\n    byte[] bytes;\n    try {\n      bytes = content.getBytes(\"Shift_JIS\");\n    } catch (UnsupportedEncodingException uee) {\n      return false;\n    }\n    int length = bytes.length;\n    if (length % 2 != 0) {\n      return false;\n    }\n    for (int i = 0; i < length; i += 2) {\n      int byte1 = bytes[i] & 0xFF;\n      if ((byte1 < 0x81 || byte1 > 0x9F) && (byte1 < 0xE0 || byte1 > 0xEB)) {\n        return false;\n      }\n    }\n    return true;\n  }\n\n  private static int chooseMaskPattern(BitArray bits,\n                                       ErrorCorrectionLevel ecLevel,\n                                       Version version,\n                                       ByteMatrix matrix) throws WriterException {\n\n    int minPenalty = Integer.MAX_VALUE;  // Lower penalty is better.\n    int bestMaskPattern = -1;\n    // We try all mask patterns to choose the best one.\n    for (int maskPattern = 0; maskPattern < QRCode.NUM_MASK_PATTERNS; maskPattern++) {\n      MatrixUtil.buildMatrix(bits, ecLevel, version, maskPattern, matrix);\n      int penalty = calculateMaskPenalty(matrix);\n      if (penalty < minPenalty) {\n        minPenalty = penalty;\n        bestMaskPattern = maskPattern;\n      }\n    }\n    return bestMaskPattern;\n  }\n\n  private static Version chooseVersion(int numInputBits, ErrorCorrectionLevel ecLevel) throws WriterException {\n    // In the following comments, we use numbers of Version 7-H.\n    for (int versionNum = 1; versionNum <= 40; versionNum++) {\n      Version version = Version.getVersionForNumber(versionNum);\n      // numBytes = 196\n      int numBytes = version.getTotalCodewords();\n      // getNumECBytes = 130\n      Version.ECBlocks ecBlocks = version.getECBlocksForLevel(ecLevel);\n      int numEcBytes = ecBlocks.getTotalECCodewords();\n      // getNumDataBytes = 196 - 130 = 66\n      int numDataBytes = numBytes - numEcBytes;\n      int totalInputBytes = (numInputBits + 7) / 8;\n      if (numDataBytes >= totalInputBytes) {\n        return version;\n      }\n    }\n    throw new WriterException(\"Data too big\");\n  }\n\n  /**\n   * Terminate bits as described in 8.4.8 and 8.4.9 of JISX0510:2004 (p.24).\n   */\n  static void terminateBits(int numDataBytes, BitArray bits) throws WriterException {\n    int capacity = numDataBytes << 3;\n    if (bits.getSize() > capacity) {\n      throw new WriterException(\"data bits cannot fit in the QR Code\" + bits.getSize() + \" > \" +\n          capacity);\n    }\n    for (int i = 0; i < 4 && bits.getSize() < capacity; ++i) {\n      bits.appendBit(false);\n    }\n    // Append termination bits. See 8.4.8 of JISX0510:2004 (p.24) for details.\n    // If the last byte isn't 8-bit aligned, we'll add padding bits.\n    int numBitsInLastByte = bits.getSize() & 0x07;    \n    if (numBitsInLastByte > 0) {\n      for (int i = numBitsInLastByte; i < 8; i++) {\n        bits.appendBit(false);\n      }\n    }\n    // If we have more space, we'll fill the space with padding patterns defined in 8.4.9 (p.24).\n    int numPaddingBytes = numDataBytes - bits.getSizeInBytes();\n    for (int i = 0; i < numPaddingBytes; ++i) {\n      bits.appendBits((i & 0x01) == 0 ? 0xEC : 0x11, 8);\n    }\n    if (bits.getSize() != capacity) {\n      throw new WriterException(\"Bits size does not equal capacity\");\n    }\n  }\n\n  /**\n   * Get number of data bytes and number of error correction bytes for block id \"blockID\". Store\n   * the result in \"numDataBytesInBlock\", and \"numECBytesInBlock\". See table 12 in 8.5.1 of\n   * JISX0510:2004 (p.30)\n   */\n  static void getNumDataBytesAndNumECBytesForBlockID(int numTotalBytes,\n                                                     int numDataBytes,\n                                                     int numRSBlocks,\n                                                     int blockID,\n                                                     int[] numDataBytesInBlock,\n                                                     int[] numECBytesInBlock) throws WriterException {\n    if (blockID >= numRSBlocks) {\n      throw new WriterException(\"Block ID too large\");\n    }\n    // numRsBlocksInGroup2 = 196 % 5 = 1\n    int numRsBlocksInGroup2 = numTotalBytes % numRSBlocks;\n    // numRsBlocksInGroup1 = 5 - 1 = 4\n    int numRsBlocksInGroup1 = numRSBlocks - numRsBlocksInGroup2;\n    // numTotalBytesInGroup1 = 196 / 5 = 39\n    int numTotalBytesInGroup1 = numTotalBytes / numRSBlocks;\n    // numTotalBytesInGroup2 = 39 + 1 = 40\n    int numTotalBytesInGroup2 = numTotalBytesInGroup1 + 1;\n    // numDataBytesInGroup1 = 66 / 5 = 13\n    int numDataBytesInGroup1 = numDataBytes / numRSBlocks;\n    // numDataBytesInGroup2 = 13 + 1 = 14\n    int numDataBytesInGroup2 = numDataBytesInGroup1 + 1;\n    // numEcBytesInGroup1 = 39 - 13 = 26\n    int numEcBytesInGroup1 = numTotalBytesInGroup1 - numDataBytesInGroup1;\n    // numEcBytesInGroup2 = 40 - 14 = 26\n    int numEcBytesInGroup2 = numTotalBytesInGroup2 - numDataBytesInGroup2;\n    // Sanity checks.\n    // 26 = 26\n    if (numEcBytesInGroup1 != numEcBytesInGroup2) {\n      throw new WriterException(\"EC bytes mismatch\");\n    }\n    // 5 = 4 + 1.\n    if (numRSBlocks != numRsBlocksInGroup1 + numRsBlocksInGroup2) {\n      throw new WriterException(\"RS blocks mismatch\");\n    }\n    // 196 = (13 + 26) * 4 + (14 + 26) * 1\n    if (numTotalBytes !=\n        ((numDataBytesInGroup1 + numEcBytesInGroup1) *\n            numRsBlocksInGroup1) +\n            ((numDataBytesInGroup2 + numEcBytesInGroup2) *\n                numRsBlocksInGroup2)) {\n      throw new WriterException(\"Total bytes mismatch\");\n    }\n\n    if (blockID < numRsBlocksInGroup1) {\n      numDataBytesInBlock[0] = numDataBytesInGroup1;\n      numECBytesInBlock[0] = numEcBytesInGroup1;\n    } else {\n      numDataBytesInBlock[0] = numDataBytesInGroup2;\n      numECBytesInBlock[0] = numEcBytesInGroup2;\n    }\n  }\n\n  /**\n   * Interleave \"bits\" with corresponding error correction bytes. On success, store the result in\n   * \"result\". The interleave rule is complicated. See 8.6 of JISX0510:2004 (p.37) for details.\n   */\n  static BitArray interleaveWithECBytes(BitArray bits,\n                                        int numTotalBytes,\n                                        int numDataBytes,\n                                        int numRSBlocks) throws WriterException {\n\n    // \"bits\" must have \"getNumDataBytes\" bytes of data.\n    if (bits.getSizeInBytes() != numDataBytes) {\n      throw new WriterException(\"Number of bits and data bytes does not match\");\n    }\n\n    // Step 1.  Divide data bytes into blocks and generate error correction bytes for them. We'll\n    // store the divided data bytes blocks and error correction bytes blocks into \"blocks\".\n    int dataBytesOffset = 0;\n    int maxNumDataBytes = 0;\n    int maxNumEcBytes = 0;\n\n    // Since, we know the number of reedsolmon blocks, we can initialize the vector with the number.\n    Collection<BlockPair> blocks = new ArrayList<BlockPair>(numRSBlocks);\n\n    for (int i = 0; i < numRSBlocks; ++i) {\n      int[] numDataBytesInBlock = new int[1];\n      int[] numEcBytesInBlock = new int[1];\n      getNumDataBytesAndNumECBytesForBlockID(\n          numTotalBytes, numDataBytes, numRSBlocks, i,\n          numDataBytesInBlock, numEcBytesInBlock);\n\n      int size = numDataBytesInBlock[0];\n      byte[] dataBytes = new byte[size];\n      bits.toBytes(8*dataBytesOffset, dataBytes, 0, size);\n      byte[] ecBytes = generateECBytes(dataBytes, numEcBytesInBlock[0]);\n      blocks.add(new BlockPair(dataBytes, ecBytes));\n\n      maxNumDataBytes = Math.max(maxNumDataBytes, size);\n      maxNumEcBytes = Math.max(maxNumEcBytes, ecBytes.length);\n      dataBytesOffset += numDataBytesInBlock[0];\n    }\n    if (numDataBytes != dataBytesOffset) {\n      throw new WriterException(\"Data bytes does not match offset\");\n    }\n\n    BitArray result = new BitArray();\n\n    // First, place data blocks.\n    for (int i = 0; i < maxNumDataBytes; ++i) {\n      for (BlockPair block : blocks) {\n        byte[] dataBytes = block.getDataBytes();\n        if (i < dataBytes.length) {\n          result.appendBits(dataBytes[i], 8);\n        }\n      }\n    }\n    // Then, place error correction blocks.\n    for (int i = 0; i < maxNumEcBytes; ++i) {\n      for (BlockPair block : blocks) {\n        byte[] ecBytes = block.getErrorCorrectionBytes();\n        if (i < ecBytes.length) {\n          result.appendBits(ecBytes[i], 8);\n        }\n      }\n    }\n    if (numTotalBytes != result.getSizeInBytes()) {  // Should be same.\n      throw new WriterException(\"Interleaving error: \" + numTotalBytes + \" and \" +\n          result.getSizeInBytes() + \" differ.\");\n    }\n\n    return result;\n  }\n\n  static byte[] generateECBytes(byte[] dataBytes, int numEcBytesInBlock) {\n    int numDataBytes = dataBytes.length;\n    int[] toEncode = new int[numDataBytes + numEcBytesInBlock];\n    for (int i = 0; i < numDataBytes; i++) {\n      toEncode[i] = dataBytes[i] & 0xFF;\n    }\n    new ReedSolomonEncoder(GenericGF.QR_CODE_FIELD_256).encode(toEncode, numEcBytesInBlock);\n\n    byte[] ecBytes = new byte[numEcBytesInBlock];\n    for (int i = 0; i < numEcBytesInBlock; i++) {\n      ecBytes[i] = (byte) toEncode[numDataBytes + i];\n    }\n    return ecBytes;\n  }\n\n  /**\n   * Append mode info. On success, store the result in \"bits\".\n   */\n  static void appendModeInfo(Mode mode, BitArray bits) {\n    bits.appendBits(mode.getBits(), 4);\n  }\n\n\n  /**\n   * Append length info. On success, store the result in \"bits\".\n   */\n  static void appendLengthInfo(int numLetters, Version version, Mode mode, BitArray bits) throws WriterException {\n    int numBits = mode.getCharacterCountBits(version);\n    if (numLetters >= (1 << numBits)) {\n      throw new WriterException(numLetters + \" is bigger than \" + ((1 << numBits) - 1));\n    }\n    bits.appendBits(numLetters, numBits);\n  }\n\n  /**\n   * Append \"bytes\" in \"mode\" mode (encoding) into \"bits\". On success, store the result in \"bits\".\n   */\n  static void appendBytes(String content,\n                          Mode mode,\n                          BitArray bits,\n                          String encoding) throws WriterException {\n    switch (mode) {\n      case NUMERIC:\n        appendNumericBytes(content, bits);\n        break;\n      case ALPHANUMERIC:\n        appendAlphanumericBytes(content, bits);\n        break;\n      case BYTE:\n        append8BitBytes(content, bits, encoding);\n        break;\n      case KANJI:\n        appendKanjiBytes(content, bits);\n        break;\n      default:\n        throw new WriterException(\"Invalid mode: \" + mode);\n    }\n  }\n\n  static void appendNumericBytes(CharSequence content, BitArray bits) {\n    int length = content.length();\n    int i = 0;\n    while (i < length) {\n      int num1 = content.charAt(i) - '0';\n      if (i + 2 < length) {\n        // Encode three numeric letters in ten bits.\n        int num2 = content.charAt(i + 1) - '0';\n        int num3 = content.charAt(i + 2) - '0';\n        bits.appendBits(num1 * 100 + num2 * 10 + num3, 10);\n        i += 3;\n      } else if (i + 1 < length) {\n        // Encode two numeric letters in seven bits.\n        int num2 = content.charAt(i + 1) - '0';\n        bits.appendBits(num1 * 10 + num2, 7);\n        i += 2;\n      } else {\n        // Encode one numeric letter in four bits.\n        bits.appendBits(num1, 4);\n        i++;\n      }\n    }\n  }\n\n  static void appendAlphanumericBytes(CharSequence content, BitArray bits) throws WriterException {\n    int length = content.length();\n    int i = 0;\n    while (i < length) {\n      int code1 = getAlphanumericCode(content.charAt(i));\n      if (code1 == -1) {\n        throw new WriterException();\n      }\n      if (i + 1 < length) {\n        int code2 = getAlphanumericCode(content.charAt(i + 1));\n        if (code2 == -1) {\n          throw new WriterException();\n        }\n        // Encode two alphanumeric letters in 11 bits.\n        bits.appendBits(code1 * 45 + code2, 11);\n        i += 2;\n      } else {\n        // Encode one alphanumeric letter in six bits.\n        bits.appendBits(code1, 6);\n        i++;\n      }\n    }\n  }\n\n  static void append8BitBytes(String content, BitArray bits, String encoding)\n      throws WriterException {\n    byte[] bytes;\n    try {\n      bytes = content.getBytes(encoding);\n    } catch (UnsupportedEncodingException uee) {\n      throw new WriterException(uee);\n    }\n    for (byte b : bytes) {\n      bits.appendBits(b, 8);\n    }\n  }\n\n  static void appendKanjiBytes(String content, BitArray bits) throws WriterException {\n    byte[] bytes;\n    try {\n      bytes = content.getBytes(\"Shift_JIS\");\n    } catch (UnsupportedEncodingException uee) {\n      throw new WriterException(uee);\n    }\n    int length = bytes.length;\n    for (int i = 0; i < length; i += 2) {\n      int byte1 = bytes[i] & 0xFF;\n      int byte2 = bytes[i + 1] & 0xFF;\n      int code = (byte1 << 8) | byte2;\n      int subtracted = -1;\n      if (code >= 0x8140 && code <= 0x9ffc) {\n        subtracted = code - 0x8140;\n      } else if (code >= 0xe040 && code <= 0xebbf) {\n        subtracted = code - 0xc140;\n      }\n      if (subtracted == -1) {\n        throw new WriterException(\"Invalid byte sequence\");\n      }\n      int encoded = ((subtracted >> 8) * 0xc0) + (subtracted & 0xff);\n      bits.appendBits(encoded, 13);\n    }\n  }\n\n  private static void appendECI(CharacterSetECI eci, BitArray bits) {\n    bits.appendBits(Mode.ECI.getBits(), 4);\n    // This is correct for values up to 127, which is all we need now.\n    bits.appendBits(eci.getValue(), 8);\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/qrcode/encoder/MaskUtil.java",
    "content": "/*\n * Copyright 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.qrcode.encoder;\n\n/**\n * @author Satoru Takabayashi\n * @author Daniel Switkin\n * @author Sean Owen\n */\nfinal class MaskUtil {\n\n  // Penalty weights from section 6.8.2.1\n  private static final int N1 = 3;\n  private static final int N2 = 3;\n  private static final int N3 = 40;\n  private static final int N4 = 10;\n\n  private MaskUtil() {\n    // do nothing\n  }\n\n  /**\n   * Apply mask penalty rule 1 and return the penalty. Find repetitive cells with the same color and\n   * give penalty to them. Example: 00000 or 11111.\n   */\n  static int applyMaskPenaltyRule1(ByteMatrix matrix) {\n    return applyMaskPenaltyRule1Internal(matrix, true) + applyMaskPenaltyRule1Internal(matrix, false);\n  }\n\n  /**\n   * Apply mask penalty rule 2 and return the penalty. Find 2x2 blocks with the same color and give\n   * penalty to them. This is actually equivalent to the spec's rule, which is to find MxN blocks and give a\n   * penalty proportional to (M-1)x(N-1), because this is the number of 2x2 blocks inside such a block.\n   */\n  static int applyMaskPenaltyRule2(ByteMatrix matrix) {\n    int penalty = 0;\n    byte[][] array = matrix.getArray();\n    int width = matrix.getWidth();\n    int height = matrix.getHeight();\n    for (int y = 0; y < height - 1; y++) {\n      for (int x = 0; x < width - 1; x++) {\n        int value = array[y][x];\n        if (value == array[y][x + 1] && value == array[y + 1][x] && value == array[y + 1][x + 1]) {\n          penalty++;\n        }\n      }\n    }\n    return N2 * penalty;\n  }\n\n  /**\n   * Apply mask penalty rule 3 and return the penalty. Find consecutive cells of 00001011101 or\n   * 10111010000, and give penalty to them.  If we find patterns like 000010111010000, we give\n   * penalties twice (i.e. 40 * 2).\n   */\n  static int applyMaskPenaltyRule3(ByteMatrix matrix) {\n    int penalty = 0;\n    byte[][] array = matrix.getArray();\n    int width = matrix.getWidth();\n    int height = matrix.getHeight();\n    for (int y = 0; y < height; y++) {\n      for (int x = 0; x < width; x++) {\n        // Tried to simplify following conditions but failed.\n        if (x + 6 < width &&\n            array[y][x] == 1 &&\n            array[y][x +  1] == 0 &&\n            array[y][x +  2] == 1 &&\n            array[y][x +  3] == 1 &&\n            array[y][x +  4] == 1 &&\n            array[y][x +  5] == 0 &&\n            array[y][x +  6] == 1 &&\n            ((x + 10 < width &&\n                array[y][x +  7] == 0 &&\n                array[y][x +  8] == 0 &&\n                array[y][x +  9] == 0 &&\n                array[y][x + 10] == 0) ||\n             (x - 4 >= 0 &&\n                array[y][x -  1] == 0 &&\n                array[y][x -  2] == 0 &&\n                array[y][x -  3] == 0 &&\n                array[y][x -  4] == 0))) {\n          penalty += N3;\n        }\n        if (y + 6 < height &&\n            array[y][x] == 1  &&\n            array[y +  1][x] == 0  &&\n            array[y +  2][x] == 1  &&\n            array[y +  3][x] == 1  &&\n            array[y +  4][x] == 1  &&\n            array[y +  5][x] == 0  &&\n            array[y +  6][x] == 1 &&\n            ((y + 10 < height &&\n                array[y +  7][x] == 0 &&\n                array[y +  8][x] == 0 &&\n                array[y +  9][x] == 0 &&\n                array[y + 10][x] == 0) ||\n             (y - 4 >= 0 &&\n                array[y -  1][x] == 0 &&\n                array[y -  2][x] == 0 &&\n                array[y -  3][x] == 0 &&\n                array[y -  4][x] == 0))) {\n          penalty += N3;\n        }\n      }\n    }\n    return penalty;\n  }\n\n  /**\n   * Apply mask penalty rule 4 and return the penalty. Calculate the ratio of dark cells and give\n   * penalty if the ratio is far from 50%. It gives 10 penalty for 5% distance.\n   */\n  static int applyMaskPenaltyRule4(ByteMatrix matrix) {\n    int numDarkCells = 0;\n    byte[][] array = matrix.getArray();\n    int width = matrix.getWidth();\n    int height = matrix.getHeight();\n    for (int y = 0; y < height; y++) {\n      byte[] arrayY = array[y];\n      for (int x = 0; x < width; x++) {\n        if (arrayY[x] == 1) {\n          numDarkCells++;\n        }\n      }\n    }\n    int numTotalCells = matrix.getHeight() * matrix.getWidth();\n    double darkRatio = (double) numDarkCells / numTotalCells;\n    int fivePercentVariances = (int) (Math.abs(darkRatio - 0.5) * 20.0); // * 100.0 / 5.0\n    return fivePercentVariances * N4;\n  }\n\n  /**\n   * Return the mask bit for \"getMaskPattern\" at \"x\" and \"y\". See 8.8 of JISX0510:2004 for mask\n   * pattern conditions.\n   */\n  static boolean getDataMaskBit(int maskPattern, int x, int y) {\n    int intermediate;\n    int temp;\n    switch (maskPattern) {\n      case 0:\n        intermediate = (y + x) & 0x1;\n        break;\n      case 1:\n        intermediate = y & 0x1;\n        break;\n      case 2:\n        intermediate = x % 3;\n        break;\n      case 3:\n        intermediate = (y + x) % 3;\n        break;\n      case 4:\n        intermediate = ((y >>> 1) + (x / 3)) & 0x1;\n        break;\n      case 5:\n        temp = y * x;\n        intermediate = (temp & 0x1) + (temp % 3);\n        break;\n      case 6:\n        temp = y * x;\n        intermediate = ((temp & 0x1) + (temp % 3)) & 0x1;\n        break;\n      case 7:\n        temp = y * x;\n        intermediate = ((temp % 3) + ((y + x) & 0x1)) & 0x1;\n        break;\n      default:\n        throw new IllegalArgumentException(\"Invalid mask pattern: \" + maskPattern);\n    }\n    return intermediate == 0;\n  }\n\n  /**\n   * Helper function for applyMaskPenaltyRule1. We need this for doing this calculation in both\n   * vertical and horizontal orders respectively.\n   */\n  private static int applyMaskPenaltyRule1Internal(ByteMatrix matrix, boolean isHorizontal) {\n    int penalty = 0;\n    int iLimit = isHorizontal ? matrix.getHeight() : matrix.getWidth();\n    int jLimit = isHorizontal ? matrix.getWidth() : matrix.getHeight();\n    byte[][] array = matrix.getArray();\n    for (int i = 0; i < iLimit; i++) {\n      int numSameBitCells = 0;\n      int prevBit = -1;\n      for (int j = 0; j < jLimit; j++) {\n        int bit = isHorizontal ? array[i][j] : array[j][i];\n        if (bit == prevBit) {\n          numSameBitCells++;\n        } else {\n          if (numSameBitCells >= 5) {\n            penalty += N1 + (numSameBitCells - 5);\n          }\n          numSameBitCells = 1;  // Include the cell itself.\n          prevBit = bit;\n        }\n      }\n      if (numSameBitCells > 5) {\n        penalty += N1 + (numSameBitCells - 5);\n      }\n    }\n    return penalty;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/qrcode/encoder/MatrixUtil.java",
    "content": "/*\n * Copyright 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.qrcode.encoder;\n\nimport com.google.zxing.WriterException;\nimport com.google.zxing.common.BitArray;\nimport com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;\nimport com.google.zxing.qrcode.decoder.Version;\n\n/**\n * @author satorux@google.com (Satoru Takabayashi) - creator\n * @author dswitkin@google.com (Daniel Switkin) - ported from C++\n */\nfinal class MatrixUtil {\n\n  private MatrixUtil() {\n    // do nothing\n  }\n\n  private static final int[][] POSITION_DETECTION_PATTERN =  {\n      {1, 1, 1, 1, 1, 1, 1},\n      {1, 0, 0, 0, 0, 0, 1},\n      {1, 0, 1, 1, 1, 0, 1},\n      {1, 0, 1, 1, 1, 0, 1},\n      {1, 0, 1, 1, 1, 0, 1},\n      {1, 0, 0, 0, 0, 0, 1},\n      {1, 1, 1, 1, 1, 1, 1},\n  };\n\n  private static final int[][] POSITION_ADJUSTMENT_PATTERN = {\n      {1, 1, 1, 1, 1},\n      {1, 0, 0, 0, 1},\n      {1, 0, 1, 0, 1},\n      {1, 0, 0, 0, 1},\n      {1, 1, 1, 1, 1},\n  };\n\n  // From Appendix E. Table 1, JIS0510X:2004 (p 71). The table was double-checked by komatsu.\n  private static final int[][] POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE = {\n      {-1, -1, -1, -1,  -1,  -1,  -1},  // Version 1\n      { 6, 18, -1, -1,  -1,  -1,  -1},  // Version 2\n      { 6, 22, -1, -1,  -1,  -1,  -1},  // Version 3\n      { 6, 26, -1, -1,  -1,  -1,  -1},  // Version 4\n      { 6, 30, -1, -1,  -1,  -1,  -1},  // Version 5\n      { 6, 34, -1, -1,  -1,  -1,  -1},  // Version 6\n      { 6, 22, 38, -1,  -1,  -1,  -1},  // Version 7\n      { 6, 24, 42, -1,  -1,  -1,  -1},  // Version 8\n      { 6, 26, 46, -1,  -1,  -1,  -1},  // Version 9\n      { 6, 28, 50, -1,  -1,  -1,  -1},  // Version 10\n      { 6, 30, 54, -1,  -1,  -1,  -1},  // Version 11\n      { 6, 32, 58, -1,  -1,  -1,  -1},  // Version 12\n      { 6, 34, 62, -1,  -1,  -1,  -1},  // Version 13\n      { 6, 26, 46, 66,  -1,  -1,  -1},  // Version 14\n      { 6, 26, 48, 70,  -1,  -1,  -1},  // Version 15\n      { 6, 26, 50, 74,  -1,  -1,  -1},  // Version 16\n      { 6, 30, 54, 78,  -1,  -1,  -1},  // Version 17\n      { 6, 30, 56, 82,  -1,  -1,  -1},  // Version 18\n      { 6, 30, 58, 86,  -1,  -1,  -1},  // Version 19\n      { 6, 34, 62, 90,  -1,  -1,  -1},  // Version 20\n      { 6, 28, 50, 72,  94,  -1,  -1},  // Version 21\n      { 6, 26, 50, 74,  98,  -1,  -1},  // Version 22\n      { 6, 30, 54, 78, 102,  -1,  -1},  // Version 23\n      { 6, 28, 54, 80, 106,  -1,  -1},  // Version 24\n      { 6, 32, 58, 84, 110,  -1,  -1},  // Version 25\n      { 6, 30, 58, 86, 114,  -1,  -1},  // Version 26\n      { 6, 34, 62, 90, 118,  -1,  -1},  // Version 27\n      { 6, 26, 50, 74,  98, 122,  -1},  // Version 28\n      { 6, 30, 54, 78, 102, 126,  -1},  // Version 29\n      { 6, 26, 52, 78, 104, 130,  -1},  // Version 30\n      { 6, 30, 56, 82, 108, 134,  -1},  // Version 31\n      { 6, 34, 60, 86, 112, 138,  -1},  // Version 32\n      { 6, 30, 58, 86, 114, 142,  -1},  // Version 33\n      { 6, 34, 62, 90, 118, 146,  -1},  // Version 34\n      { 6, 30, 54, 78, 102, 126, 150},  // Version 35\n      { 6, 24, 50, 76, 102, 128, 154},  // Version 36\n      { 6, 28, 54, 80, 106, 132, 158},  // Version 37\n      { 6, 32, 58, 84, 110, 136, 162},  // Version 38\n      { 6, 26, 54, 82, 110, 138, 166},  // Version 39\n      { 6, 30, 58, 86, 114, 142, 170},  // Version 40\n  };\n\n  // Type info cells at the left top corner.\n  private static final int[][] TYPE_INFO_COORDINATES = {\n      {8, 0},\n      {8, 1},\n      {8, 2},\n      {8, 3},\n      {8, 4},\n      {8, 5},\n      {8, 7},\n      {8, 8},\n      {7, 8},\n      {5, 8},\n      {4, 8},\n      {3, 8},\n      {2, 8},\n      {1, 8},\n      {0, 8},\n  };\n\n  // From Appendix D in JISX0510:2004 (p. 67)\n  private static final int VERSION_INFO_POLY = 0x1f25;  // 1 1111 0010 0101\n\n  // From Appendix C in JISX0510:2004 (p.65).\n  private static final int TYPE_INFO_POLY = 0x537;\n  private static final int TYPE_INFO_MASK_PATTERN = 0x5412;\n\n  // Set all cells to -1.  -1 means that the cell is empty (not set yet).\n  //\n  // JAVAPORT: We shouldn't need to do this at all. The code should be rewritten to begin encoding\n  // with the ByteMatrix initialized all to zero.\n  static void clearMatrix(ByteMatrix matrix) {\n    matrix.clear((byte) -1);\n  }\n\n  // Build 2D matrix of QR Code from \"dataBits\" with \"ecLevel\", \"version\" and \"getMaskPattern\". On\n  // success, store the result in \"matrix\" and return true.\n  static void buildMatrix(BitArray dataBits,\n                          ErrorCorrectionLevel ecLevel,\n                          Version version,\n                          int maskPattern,\n                          ByteMatrix matrix) throws WriterException {\n    clearMatrix(matrix);\n    embedBasicPatterns(version, matrix);\n    // Type information appear with any version.\n    embedTypeInfo(ecLevel, maskPattern, matrix);\n    // Version info appear if version >= 7.\n    maybeEmbedVersionInfo(version, matrix);\n    // Data should be embedded at end.\n    embedDataBits(dataBits, maskPattern, matrix);\n  }\n\n  // Embed basic patterns. On success, modify the matrix and return true.\n  // The basic patterns are:\n  // - Position detection patterns\n  // - Timing patterns\n  // - Dark dot at the left bottom corner\n  // - Position adjustment patterns, if need be\n  static void embedBasicPatterns(Version version, ByteMatrix matrix) throws WriterException {\n    // Let's get started with embedding big squares at corners.\n    embedPositionDetectionPatternsAndSeparators(matrix);\n    // Then, embed the dark dot at the left bottom corner.\n    embedDarkDotAtLeftBottomCorner(matrix);\n\n    // Position adjustment patterns appear if version >= 2.\n    maybeEmbedPositionAdjustmentPatterns(version, matrix);\n    // Timing patterns should be embedded after position adj. patterns.\n    embedTimingPatterns(matrix);\n  }\n\n  // Embed type information. On success, modify the matrix.\n  static void embedTypeInfo(ErrorCorrectionLevel ecLevel, int maskPattern, ByteMatrix matrix)\n      throws WriterException {\n    BitArray typeInfoBits = new BitArray();\n    makeTypeInfoBits(ecLevel, maskPattern, typeInfoBits);\n\n    for (int i = 0; i < typeInfoBits.getSize(); ++i) {\n      // Place bits in LSB to MSB order.  LSB (least significant bit) is the last value in\n      // \"typeInfoBits\".\n      boolean bit = typeInfoBits.get(typeInfoBits.getSize() - 1 - i);\n\n      // Type info bits at the left top corner. See 8.9 of JISX0510:2004 (p.46).\n      int x1 = TYPE_INFO_COORDINATES[i][0];\n      int y1 = TYPE_INFO_COORDINATES[i][1];\n      matrix.set(x1, y1, bit);\n\n      if (i < 8) {\n        // Right top corner.\n        int x2 = matrix.getWidth() - i - 1;\n        int y2 = 8;\n        matrix.set(x2, y2, bit);\n      } else {\n        // Left bottom corner.\n        int x2 = 8;\n        int y2 = matrix.getHeight() - 7 + (i - 8);\n        matrix.set(x2, y2, bit);\n      }\n    }\n  }\n\n  // Embed version information if need be. On success, modify the matrix and return true.\n  // See 8.10 of JISX0510:2004 (p.47) for how to embed version information.\n  static void maybeEmbedVersionInfo(Version version, ByteMatrix matrix) throws WriterException {\n    if (version.getVersionNumber() < 7) {  // Version info is necessary if version >= 7.\n      return;  // Don't need version info.\n    }\n    BitArray versionInfoBits = new BitArray();\n    makeVersionInfoBits(version, versionInfoBits);\n\n    int bitIndex = 6 * 3 - 1;  // It will decrease from 17 to 0.\n    for (int i = 0; i < 6; ++i) {\n      for (int j = 0; j < 3; ++j) {\n        // Place bits in LSB (least significant bit) to MSB order.\n        boolean bit = versionInfoBits.get(bitIndex);\n        bitIndex--;\n        // Left bottom corner.\n        matrix.set(i, matrix.getHeight() - 11 + j, bit);\n        // Right bottom corner.\n        matrix.set(matrix.getHeight() - 11 + j, i, bit);\n      }\n    }\n  }\n\n  // Embed \"dataBits\" using \"getMaskPattern\". On success, modify the matrix and return true.\n  // For debugging purposes, it skips masking process if \"getMaskPattern\" is -1.\n  // See 8.7 of JISX0510:2004 (p.38) for how to embed data bits.\n  static void embedDataBits(BitArray dataBits, int maskPattern, ByteMatrix matrix)\n      throws WriterException {\n    int bitIndex = 0;\n    int direction = -1;\n    // Start from the right bottom cell.\n    int x = matrix.getWidth() - 1;\n    int y = matrix.getHeight() - 1;\n    while (x > 0) {\n      // Skip the vertical timing pattern.\n      if (x == 6) {\n        x -= 1;\n      }\n      while (y >= 0 && y < matrix.getHeight()) {\n        for (int i = 0; i < 2; ++i) {\n          int xx = x - i;\n          // Skip the cell if it's not empty.\n          if (!isEmpty(matrix.get(xx, y))) {\n            continue;\n          }\n          boolean bit;\n          if (bitIndex < dataBits.getSize()) {\n            bit = dataBits.get(bitIndex);\n            ++bitIndex;\n          } else {\n            // Padding bit. If there is no bit left, we'll fill the left cells with 0, as described\n            // in 8.4.9 of JISX0510:2004 (p. 24).\n            bit = false;\n          }\n\n          // Skip masking if mask_pattern is -1.\n          if (maskPattern != -1 && MaskUtil.getDataMaskBit(maskPattern, xx, y)) {\n            bit = !bit;\n          }\n          matrix.set(xx, y, bit);\n        }\n        y += direction;\n      }\n      direction = -direction;  // Reverse the direction.\n      y += direction;\n      x -= 2;  // Move to the left.\n    }\n    // All bits should be consumed.\n    if (bitIndex != dataBits.getSize()) {\n      throw new WriterException(\"Not all bits consumed: \" + bitIndex + '/' + dataBits.getSize());\n    }\n  }\n\n  // Return the position of the most significant bit set (to one) in the \"value\". The most\n  // significant bit is position 32. If there is no bit set, return 0. Examples:\n  // - findMSBSet(0) => 0\n  // - findMSBSet(1) => 1\n  // - findMSBSet(255) => 8\n  static int findMSBSet(int value) {\n    int numDigits = 0;\n    while (value != 0) {\n      value >>>= 1;\n      ++numDigits;\n    }\n    return numDigits;\n  }\n\n  // Calculate BCH (Bose-Chaudhuri-Hocquenghem) code for \"value\" using polynomial \"poly\". The BCH\n  // code is used for encoding type information and version information.\n  // Example: Calculation of version information of 7.\n  // f(x) is created from 7.\n  //   - 7 = 000111 in 6 bits\n  //   - f(x) = x^2 + x^1 + x^0\n  // g(x) is given by the standard (p. 67)\n  //   - g(x) = x^12 + x^11 + x^10 + x^9 + x^8 + x^5 + x^2 + 1\n  // Multiply f(x) by x^(18 - 6)\n  //   - f'(x) = f(x) * x^(18 - 6)\n  //   - f'(x) = x^14 + x^13 + x^12\n  // Calculate the remainder of f'(x) / g(x)\n  //         x^2\n  //         __________________________________________________\n  //   g(x) )x^14 + x^13 + x^12\n  //         x^14 + x^13 + x^12 + x^11 + x^10 + x^7 + x^4 + x^2\n  //         --------------------------------------------------\n  //                              x^11 + x^10 + x^7 + x^4 + x^2\n  //\n  // The remainder is x^11 + x^10 + x^7 + x^4 + x^2\n  // Encode it in binary: 110010010100\n  // The return value is 0xc94 (1100 1001 0100)\n  //\n  // Since all coefficients in the polynomials are 1 or 0, we can do the calculation by bit\n  // operations. We don't care if cofficients are positive or negative.\n  static int calculateBCHCode(int value, int poly) {\n    // If poly is \"1 1111 0010 0101\" (version info poly), msbSetInPoly is 13. We'll subtract 1\n    // from 13 to make it 12.\n    int msbSetInPoly = findMSBSet(poly);\n    value <<= msbSetInPoly - 1;\n    // Do the division business using exclusive-or operations.\n    while (findMSBSet(value) >= msbSetInPoly) {\n      value ^= poly << (findMSBSet(value) - msbSetInPoly);\n    }\n    // Now the \"value\" is the remainder (i.e. the BCH code)\n    return value;\n  }\n\n  // Make bit vector of type information. On success, store the result in \"bits\" and return true.\n  // Encode error correction level and mask pattern. See 8.9 of\n  // JISX0510:2004 (p.45) for details.\n  static void makeTypeInfoBits(ErrorCorrectionLevel ecLevel, int maskPattern, BitArray bits)\n      throws WriterException {\n    if (!QRCode.isValidMaskPattern(maskPattern)) {\n      throw new WriterException(\"Invalid mask pattern\");\n    }\n    int typeInfo = (ecLevel.getBits() << 3) | maskPattern;\n    bits.appendBits(typeInfo, 5);\n\n    int bchCode = calculateBCHCode(typeInfo, TYPE_INFO_POLY);\n    bits.appendBits(bchCode, 10);\n\n    BitArray maskBits = new BitArray();\n    maskBits.appendBits(TYPE_INFO_MASK_PATTERN, 15);\n    bits.xor(maskBits);\n\n    if (bits.getSize() != 15) {  // Just in case.\n      throw new WriterException(\"should not happen but we got: \" + bits.getSize());\n    }\n  }\n\n  // Make bit vector of version information. On success, store the result in \"bits\" and return true.\n  // See 8.10 of JISX0510:2004 (p.45) for details.\n  static void makeVersionInfoBits(Version version, BitArray bits) throws WriterException {\n    bits.appendBits(version.getVersionNumber(), 6);\n    int bchCode = calculateBCHCode(version.getVersionNumber(), VERSION_INFO_POLY);\n    bits.appendBits(bchCode, 12);\n\n    if (bits.getSize() != 18) {  // Just in case.\n      throw new WriterException(\"should not happen but we got: \" + bits.getSize());\n    }\n  }\n\n  // Check if \"value\" is empty.\n  private static boolean isEmpty(int value) {\n    return value == -1;\n  }\n\n  private static void embedTimingPatterns(ByteMatrix matrix) {\n    // -8 is for skipping position detection patterns (size 7), and two horizontal/vertical\n    // separation patterns (size 1). Thus, 8 = 7 + 1.\n    for (int i = 8; i < matrix.getWidth() - 8; ++i) {\n      int bit = (i + 1) % 2;\n      // Horizontal line.\n      if (isEmpty(matrix.get(i, 6))) {\n        matrix.set(i, 6, bit);\n      }\n      // Vertical line.\n      if (isEmpty(matrix.get(6, i))) {\n        matrix.set(6, i, bit);\n      }\n    }\n  }\n\n  // Embed the lonely dark dot at left bottom corner. JISX0510:2004 (p.46)\n  private static void embedDarkDotAtLeftBottomCorner(ByteMatrix matrix) throws WriterException {\n    if (matrix.get(8, matrix.getHeight() - 8) == 0) {\n      throw new WriterException();\n    }\n    matrix.set(8, matrix.getHeight() - 8, 1);\n  }\n\n  private static void embedHorizontalSeparationPattern(int xStart,\n                                                       int yStart,\n                                                       ByteMatrix matrix) throws WriterException {\n    for (int x = 0; x < 8; ++x) {\n      if (!isEmpty(matrix.get(xStart + x, yStart))) {\n        throw new WriterException();\n      }\n      matrix.set(xStart + x, yStart, 0);\n    }\n  }\n\n  private static void embedVerticalSeparationPattern(int xStart,\n                                                     int yStart,\n                                                     ByteMatrix matrix) throws WriterException {\n    for (int y = 0; y < 7; ++y) {\n      if (!isEmpty(matrix.get(xStart, yStart + y))) {\n        throw new WriterException();\n      }\n      matrix.set(xStart, yStart + y, 0);\n    }\n  }\n\n  // Note that we cannot unify the function with embedPositionDetectionPattern() despite they are\n  // almost identical, since we cannot write a function that takes 2D arrays in different sizes in\n  // C/C++. We should live with the fact.\n  private static void embedPositionAdjustmentPattern(int xStart, int yStart, ByteMatrix matrix) {\n    for (int y = 0; y < 5; ++y) {\n      for (int x = 0; x < 5; ++x) {\n        matrix.set(xStart + x, yStart + y, POSITION_ADJUSTMENT_PATTERN[y][x]);\n      }\n    }\n  }\n\n  private static void embedPositionDetectionPattern(int xStart, int yStart, ByteMatrix matrix) {\n    for (int y = 0; y < 7; ++y) {\n      for (int x = 0; x < 7; ++x) {\n        matrix.set(xStart + x, yStart + y, POSITION_DETECTION_PATTERN[y][x]);\n      }\n    }\n  }\n\n  // Embed position detection patterns and surrounding vertical/horizontal separators.\n  private static void embedPositionDetectionPatternsAndSeparators(ByteMatrix matrix) throws WriterException {\n    // Embed three big squares at corners.\n    int pdpWidth = POSITION_DETECTION_PATTERN[0].length;\n    // Left top corner.\n    embedPositionDetectionPattern(0, 0, matrix);\n    // Right top corner.\n    embedPositionDetectionPattern(matrix.getWidth() - pdpWidth, 0, matrix);\n    // Left bottom corner.\n    embedPositionDetectionPattern(0, matrix.getWidth() - pdpWidth, matrix);\n\n    // Embed horizontal separation patterns around the squares.\n    int hspWidth = 8;\n    // Left top corner.\n    embedHorizontalSeparationPattern(0, hspWidth - 1, matrix);\n    // Right top corner.\n    embedHorizontalSeparationPattern(matrix.getWidth() - hspWidth,\n        hspWidth - 1, matrix);\n    // Left bottom corner.\n    embedHorizontalSeparationPattern(0, matrix.getWidth() - hspWidth, matrix);\n\n    // Embed vertical separation patterns around the squares.\n    int vspSize = 7;\n    // Left top corner.\n    embedVerticalSeparationPattern(vspSize, 0, matrix);\n    // Right top corner.\n    embedVerticalSeparationPattern(matrix.getHeight() - vspSize - 1, 0, matrix);\n    // Left bottom corner.\n    embedVerticalSeparationPattern(vspSize, matrix.getHeight() - vspSize,\n        matrix);\n  }\n\n  // Embed position adjustment patterns if need be.\n  private static void maybeEmbedPositionAdjustmentPatterns(Version version, ByteMatrix matrix) {\n    if (version.getVersionNumber() < 2) {  // The patterns appear if version >= 2\n      return;\n    }\n    int index = version.getVersionNumber() - 1;\n    int[] coordinates = POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[index];\n    int numCoordinates = POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[index].length;\n    for (int i = 0; i < numCoordinates; ++i) {\n      for (int j = 0; j < numCoordinates; ++j) {\n        int y = coordinates[i];\n        int x = coordinates[j];\n        if (x == -1 || y == -1) {\n          continue;\n        }\n        // If the cell is unset, we embed the position adjustment pattern here.\n        if (isEmpty(matrix.get(x, y))) {\n          // -2 is necessary since the x/y coordinates point to the center of the pattern, not the\n          // left top corner.\n          embedPositionAdjustmentPattern(x - 2, y - 2, matrix);\n        }\n      }\n    }\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/LibraryProject/src/com/google/zxing/qrcode/encoder/QRCode.java",
    "content": "/*\n * Copyright 2008 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.google.zxing.qrcode.encoder;\n\nimport com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;\nimport com.google.zxing.qrcode.decoder.Mode;\nimport com.google.zxing.qrcode.decoder.Version;\n\n/**\n * @author satorux@google.com (Satoru Takabayashi) - creator\n * @author dswitkin@google.com (Daniel Switkin) - ported from C++\n */\npublic final class QRCode {\n\n  public static final int NUM_MASK_PATTERNS = 8;\n\n  private Mode mode;\n  private ErrorCorrectionLevel ecLevel;\n  private Version version;\n  private int maskPattern;\n  private ByteMatrix matrix;\n\n  public QRCode() {\n    maskPattern = -1;\n  }\n\n  public Mode getMode() {\n    return mode;\n  }\n\n  public ErrorCorrectionLevel getECLevel() {\n    return ecLevel;\n  }\n\n  public Version getVersion() {\n    return version;\n  }\n\n  public int getMaskPattern() {\n    return maskPattern;\n  }\n\n  public ByteMatrix getMatrix() {\n    return matrix;\n  }\n\n  @Override\n  public String toString() {\n    StringBuilder result = new StringBuilder(200);\n    result.append(\"<<\\n\");\n    result.append(\" mode: \");\n    result.append(mode);\n    result.append(\"\\n ecLevel: \");\n    result.append(ecLevel);\n    result.append(\"\\n version: \");\n    result.append(version);\n    result.append(\"\\n maskPattern: \");\n    result.append(maskPattern);\n    if (matrix == null) {\n      result.append(\"\\n matrix: null\\n\");\n    } else {\n      result.append(\"\\n matrix:\\n\");\n      result.append(matrix.toString());\n    }\n    result.append(\">>\\n\");\n    return result.toString();\n  }\n\n  public void setMode(Mode value) {\n    mode = value;\n  }\n\n  public void setECLevel(ErrorCorrectionLevel value) {\n    ecLevel = value;\n  }\n\n  public void setVersion(Version version) {\n    this.version = version;\n  }\n\n  public void setMaskPattern(int value) {\n    maskPattern = value;\n  }\n\n  public void setMatrix(ByteMatrix value) {\n    matrix = value;\n  }\n\n  // Check if \"mask_pattern\" is valid.\n  public static boolean isValidMaskPattern(int maskPattern) {\n    return maskPattern >= 0 && maskPattern < NUM_MASK_PATTERNS;\n  }\n\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/README.md",
    "content": "Building Android\r\n================\r\n\r\n## Building localy ##\r\n\r\nSteps if you have Netbeans setup for Android or want to do that.\r\n\r\n1. Setup Netbeans for Android development.\r\n\t1. Download and install JDK (be sure to set JAVA_HOME - it will be important for the SDK).\r\n\t2. Download and install Netebeans.\r\n\t3. Download and install Android SDK (do NOT use ADT boundle).\r\n\t4. Download and install NBAndroid: http://www.nbandroid.org/p/installation.html\r\n\t5. Set path of Android SDK in Netbeans (for installation for all users this is: ```c:\\Program Files (x86)\\Android\\android-sdk\\```).\r\n\r\n2. Install Phonegap:\r\n\r\n\t1. Add to Windows PATH Android SDK tools: ```;C:\\...[android-sdk]\\platform-tools;C:\\...[android-sdk]\\tools```\r\n\t2. Copy ANT home from Netbeans and add it your PATH too.\r\n\t3. Add Java bin to PATH: ```;%JAVA_HOME%\\bin;%ANT_HOME%\\bin```\r\n\r\n3. Install cordova command line\r\n\t1. Install node.js.\r\n\t2. Install cordova command line:\r\n\t```\r\n\tnpm install -g cordova\r\n\t```\r\n\r\n4. Create and build test project to check command line tools:\r\n\t```\r\n\tcordova create hello com.example.hello \"Hello World\"\r\n\tcd hello\r\n\tcordova platform add android\r\n\tcordova build\r\n\t```\r\n\r\n5. To open project in Netbeans just use Open Project and in the folder you created the project navigate to platforms\\android.\r\n\r\n6. Add the plugin following instructions from this page: https://github.com/phonegap/phonegap-plugins/tree/master/Android/BarcodeScanner\r\n\r\n## Preparing for PhoneGap Build ##\r\n\r\nThe process may vary depending on version of Zxing project, but base steps should be the same.\r\n\r\n1. Get latest zxing-android project and create a LibraryProject from that:\r\n\t1. Checked out zxing-android from SVN (http://zxing.googlecode.com/svn/trunk/).\r\n\t2. Overlayed the source from zxing-core.\r\n\t3. Set to library project.\r\n\t4. Change intent names to avoid conflict with ZXing app.\r\n\t5. Remove two lines from AndroidManifest.xml to avoid shortcuts being created.\r\n2. Update plugin.xml with any needed resources (you can use ```plugin.xml.generate.php``` to generate some stuff for Android).\r\n3. Refactor LibraryProject for usage with PGB:\r\n\t1. Commented out call to showHelpOnFirstLaunch (it will probably not work anyway).\r\n\t2. Replace R class with FakeR class calls (this is needed beacuse R class will be in a different namespace).\r\n\t3. Add FakeR initialization in each class it was added (note that if some classes extened other then you might want to add a protected fakeR variable to their parent - see e.g. ResultHandler class and it's children).\r\n\t4. Comment out ```(<string name=\"app_name\">[^<>]+</string>)``` from strings.xml (to avoid replacing original application name).\r\n4. Build LibraryProject, rename and copy it.\r\n\r\n## Building with plugman ##\r\n\r\n[Plugman](https://github.com/apache/cordova-plugman) is a Node.js tool used by PG Build.\r\n\r\nWorkflow for creating and building example project with the plugin:\r\n\r\n1. Create and build example project:\r\n\t```\r\n\tcordova create hello com.example.hello \"HelloWorld\"\r\n\tcd hello\r\n\tcordova platform add android\r\n\tcordova build\r\n\t```\r\n\t\r\n\tWarning! White space characters are not allowed in app name (and any other that cannot be used in an activity or class name). See: https://issues.apache.org/jira/browse/CB-4148\r\n\t\r\n\tNote. If you wish to remove Android platform (to e.g. generate it with your www assests) you will need to remove \"platforms\\android\" and \"merges\\android\\\".\r\n\r\n2. Copy plugin files to \"hello\\plugins\\com.phonegap.plugins.barcodescanner\\\". You can simply download from github:\r\n\t```\r\n\tgit clone https://github.com/wildabeast/BarcodeScanner.git plugins\\com.phonegap.plugins.barcodescanner\r\n\t```\r\n\r\n3. Install the plugin (current dir. being \"hello\"):\r\n\t```\r\n\tplugman --plugins_dir plugins --plugin com.phonegap.plugins.barcodescanner --platform android --project platforms\\android\r\n\tplugman install --plugins_dir plugins --plugin com.phonegap.plugins.barcodescanner --platform android --project platforms\\android\r\n\t```\r\n\t\r\n\tNote. To manually remove plugin you need to re-create plugins\\android.json (and remove changes done by the plugin - you can simply remove whole platform as described in first step and re-create).\r\n\r\n4. Build & deploy Android project with whatever Android IDE (or ANT + ADK tools).\r\n\r\nNote. Plugin sub-dir (here \"com.phonegap.plugins.barcodescanner\") need to be the same as the plugin ID only since PhoneGap 3.0.\r\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/android/com/phonegap/plugins/barcodescanner/BarcodeScanner.java",
    "content": "/**\n * PhoneGap is available under *either* the terms of the modified BSD license *or* the\n * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.\n *\n * Copyright (c) Matt Kane 2010\n * Copyright (c) 2011, IBM Corporation\n * Copyright (c) 2013, Maciej Nux Jaros\n */\npackage com.phonegap.plugins.barcodescanner;\n\nimport org.json.JSONArray;\nimport org.json.JSONException;\nimport org.json.JSONObject;\n\nimport android.app.Activity;\nimport android.content.Intent;\nimport android.util.Log;\n\nimport org.apache.cordova.CordovaPlugin;\nimport org.apache.cordova.CallbackContext;\nimport org.apache.cordova.PluginResult;\n\nimport android.util.Log;\n\n/**\n * This calls out to the ZXing barcode reader and returns the result.\n *\n * @sa https://github.com/apache/cordova-android/blob/master/framework/src/org/apache/cordova/CordovaPlugin.java\n */\npublic class BarcodeScanner extends CordovaPlugin {\n    public static final int REQUEST_CODE = 0x0ba7c0de;\n\n    private static final String SCAN = \"scan\";\n    private static final String ENCODE = \"encode\";\n    private static final String CANCELLED = \"cancelled\";\n    private static final String FORMAT = \"format\";\n    private static final String TEXT = \"text\";\n    private static final String DATA = \"data\";\n    private static final String TYPE = \"type\";\n    private static final String SCAN_INTENT = \"com.google.zxing.client.android.SCAN\";\n    private static final String ENCODE_DATA = \"ENCODE_DATA\";\n    private static final String ENCODE_TYPE = \"ENCODE_TYPE\";\n    private static final String ENCODE_INTENT = \"com.phonegap.plugins.barcodescanner.ENCODE\";\n    private static final String TEXT_TYPE = \"TEXT_TYPE\";\n    private static final String EMAIL_TYPE = \"EMAIL_TYPE\";\n    private static final String PHONE_TYPE = \"PHONE_TYPE\";\n    private static final String SMS_TYPE = \"SMS_TYPE\";\n\n    private static final String LOG_TAG = \"BarcodeScanner\";\n\n    private CallbackContext callbackContext;\n\n    /**\n     * Constructor.\n     */\n    public BarcodeScanner() {\n    }\n\n    /**\n     * Executes the request.\n     *\n     * This method is called from the WebView thread. To do a non-trivial amount of work, use:\n     *     cordova.getThreadPool().execute(runnable);\n     *\n     * To run on the UI thread, use:\n     *     cordova.getActivity().runOnUiThread(runnable);\n     *\n     * @param action          The action to execute.\n     * @param args            The exec() arguments.\n     * @param callbackContext The callback context used when calling back into JavaScript.\n     * @return                Whether the action was valid.\n     *\n     * @sa https://github.com/apache/cordova-android/blob/master/framework/src/org/apache/cordova/CordovaPlugin.java\n     */\n    @Override\n    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) {\n        this.callbackContext = callbackContext;\n\n        if (action.equals(ENCODE)) {\n            JSONObject obj = args.optJSONObject(0);\n            if (obj != null) {\n                String type = obj.optString(TYPE);\n                String data = obj.optString(DATA);\n\n                // If the type is null then force the type to text\n                if (type == null) {\n                    type = TEXT_TYPE;\n                }\n\n                if (data == null) {\n                    callbackContext.error(\"User did not specify data to encode\");\n                    return true;\n                }\n\n                encode(type, data);\n            } else {\n                callbackContext.error(\"User did not specify data to encode\");\n                return true;\n            }\n        } else if (action.equals(SCAN)) {\n            scan(args);\n        } else {\n            return false;\n        }\n        return true;\n    }\n\n    /**\n     * Starts an intent to scan and decode a barcode.\n     */\n    public void scan(JSONArray args) {\n        Intent intentScan = new Intent(SCAN_INTENT);\n        intentScan.addCategory(Intent.CATEGORY_DEFAULT);\n\n        // add config as intent extras\n        if(args.length() > 0) {\n\n            JSONObject obj;\n            JSONArray names;\n            String key;\n            Object value;\n\n            for(int i=0; i<args.length(); i++) {\n\n                try {\n                    obj = args.getJSONObject(i);\n                } catch(JSONException e) {\n                    Log.i(\"CordovaLog\", e.getLocalizedMessage());\n                    continue;\n                }\n\n                names = obj.names();\n                for(int j=0; j<names.length(); j++) {\n                    try {\n                        key = names.getString(j);\n                        value = obj.get(key);\n\n                        if(value instanceof Integer) {\n                            intentScan.putExtra(key, (Integer)value);\n                        } else if(value instanceof String) {\n                            intentScan.putExtra(key, (String)value);\n                        }\n\n                    } catch(JSONException e) {\n                        Log.i(\"CordovaLog\", e.getLocalizedMessage());\n                        continue;\n                    }\n                }\n            }\n\n        }\n\n        // avoid calling other phonegap apps\n        intentScan.setPackage(this.cordova.getActivity().getApplicationContext().getPackageName());\n\n        this.cordova.startActivityForResult((CordovaPlugin) this, intentScan, REQUEST_CODE);\n    }\n\n    /**\n     * Called when the barcode scanner intent completes.\n     *\n     * @param requestCode The request code originally supplied to startActivityForResult(),\n     *                       allowing you to identify who this result came from.\n     * @param resultCode  The integer result code returned by the child activity through its setResult().\n     * @param intent      An Intent, which can return result data to the caller (various data can be attached to Intent \"extras\").\n     */\n    @Override\n    public void onActivityResult(int requestCode, int resultCode, Intent intent) {\n        if (requestCode == REQUEST_CODE) {\n            if (resultCode == Activity.RESULT_OK) {\n                JSONObject obj = new JSONObject();\n                try {\n                    obj.put(TEXT, intent.getStringExtra(\"SCAN_RESULT\"));\n                    obj.put(FORMAT, intent.getStringExtra(\"SCAN_RESULT_FORMAT\"));\n                    obj.put(CANCELLED, false);\n                } catch (JSONException e) {\n                    Log.d(LOG_TAG, \"This should never happen\");\n                }\n                //this.success(new PluginResult(PluginResult.Status.OK, obj), this.callback);\n                this.callbackContext.success(obj);\n            } else if (resultCode == Activity.RESULT_CANCELED) {\n                JSONObject obj = new JSONObject();\n                try {\n                    obj.put(TEXT, \"\");\n                    obj.put(FORMAT, \"\");\n                    obj.put(CANCELLED, true);\n                } catch (JSONException e) {\n                    Log.d(LOG_TAG, \"This should never happen\");\n                }\n                //this.success(new PluginResult(PluginResult.Status.OK, obj), this.callback);\n                this.callbackContext.success(obj);\n            } else {\n                //this.error(new PluginResult(PluginResult.Status.ERROR), this.callback);\n                this.callbackContext.error(\"Unexpected error\");\n            }\n        }\n    }\n\n    /**\n     * Initiates a barcode encode.\n     *\n     * @param type Endoiding type.\n     * @param data The data to encode in the bar code.\n     */\n    public void encode(String type, String data) {\n        Intent intentEncode = new Intent(ENCODE_INTENT);\n        intentEncode.putExtra(ENCODE_TYPE, type);\n        intentEncode.putExtra(ENCODE_DATA, data);\n        // avoid calling other phonegap apps\n        intentEncode.setPackage(this.cordova.getActivity().getApplicationContext().getPackageName());\n\n        this.cordova.getActivity().startActivity(intentEncode);\n    }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/browser/BarcodeScannerProxy.js",
    "content": "function scan(success, error) {\n    var code = window.prompt(\"Enter barcode value (empty value will fire the error handler):\");\n    if(code) {\n        var result = {\n            text:code,\n            format:\"Fake\",\n            cancelled:false\n        };\n        success(result);\n    } else {\n        error(\"No barcode\");\n    }\n}\n\nfunction encode(type, data, success, errorCallback) {\n    success();\n}\n\nmodule.exports = {\n    scan: scan,\n    encode: encode\n};\n\nrequire(\"cordova/exec/proxy\").add(\"BarcodeScanner\",module.exports);"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/ios/CDVBarcodeScanner.mm",
    "content": "/*\n * PhoneGap is available under *either* the terms of the modified BSD license *or* the\n * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.\n *\n * Copyright 2011 Matt Kane. All rights reserved.\n * Copyright (c) 2011, IBM Corporation\n */\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n#import <AVFoundation/AVFoundation.h>\n#import <AssetsLibrary/AssetsLibrary.h>\n#import <AudioToolbox/AudioToolbox.h>\n\n//------------------------------------------------------------------------------\n// use the all-in-one version of zxing that we built\n//------------------------------------------------------------------------------\n#import \"zxing-all-in-one.h\"\n#import <Cordova/CDVPlugin.h>\n\n\n//------------------------------------------------------------------------------\n// Delegate to handle orientation functions\n//------------------------------------------------------------------------------\n@protocol CDVBarcodeScannerOrientationDelegate <NSObject>\n\n- (NSUInteger)supportedInterfaceOrientations;\n- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation;\n- (BOOL)shouldAutorotate;\n\n@end\n\n//------------------------------------------------------------------------------\n// Adds a shutter button to the UI, and changes the scan from continuous to\n// only performing a scan when you click the shutter button.  For testing.\n//------------------------------------------------------------------------------\n#define USE_SHUTTER 0\n\n//------------------------------------------------------------------------------\n@class CDVbcsProcessor;\n@class CDVbcsViewController;\n\n//------------------------------------------------------------------------------\n// plugin class\n//------------------------------------------------------------------------------\n@interface CDVBarcodeScanner : CDVPlugin {}\n- (NSString*)isScanNotPossible;\n- (void)scan:(CDVInvokedUrlCommand*)command;\n- (void)encode:(CDVInvokedUrlCommand*)command;\n- (void)returnImage:(NSString*)filePath format:(NSString*)format callback:(NSString*)callback;\n- (void)returnSuccess:(NSString*)scannedText format:(NSString*)format cancelled:(BOOL)cancelled flipped:(BOOL)flipped callback:(NSString*)callback;\n- (void)returnError:(NSString*)message callback:(NSString*)callback;\n@end\n\n//------------------------------------------------------------------------------\n// class that does the grunt work\n//------------------------------------------------------------------------------\n@interface CDVbcsProcessor : NSObject <AVCaptureVideoDataOutputSampleBufferDelegate> {}\n@property (nonatomic, retain) CDVBarcodeScanner*           plugin;\n@property (nonatomic, retain) NSString*                   callback;\n@property (nonatomic, retain) UIViewController*           parentViewController;\n@property (nonatomic, retain) CDVbcsViewController*        viewController;\n@property (nonatomic, retain) AVCaptureSession*           captureSession;\n@property (nonatomic, retain) AVCaptureVideoPreviewLayer* previewLayer;\n@property (nonatomic, retain) NSString*                   alternateXib;\n@property (nonatomic, retain) NSMutableArray*             results;\n@property (nonatomic)         BOOL                        is1D;\n@property (nonatomic)         BOOL                        is2D;\n@property (nonatomic)         BOOL                        capturing;\n@property (nonatomic)         BOOL                        isFrontCamera;\n@property (nonatomic)         BOOL                        isFlipped;\n\n\n- (id)initWithPlugin:(CDVBarcodeScanner*)plugin callback:(NSString*)callback parentViewController:(UIViewController*)parentViewController alterateOverlayXib:(NSString *)alternateXib;\n- (void)scanBarcode;\n- (void)barcodeScanSucceeded:(NSString*)text format:(NSString*)format;\n- (void)barcodeScanFailed:(NSString*)message;\n- (void)barcodeScanCancelled;\n- (void)openDialog;\n- (NSString*)setUpCaptureSession;\n- (void)captureOutput:(AVCaptureOutput*)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection*)connection;\n- (NSString*)formatStringFrom:(zxing::BarcodeFormat)format;\n- (UIImage*)getImageFromSample:(CMSampleBufferRef)sampleBuffer;\n- (zxing::Ref<zxing::LuminanceSource>) getLuminanceSourceFromSample:(CMSampleBufferRef)sampleBuffer imageBytes:(uint8_t**)ptr;\n- (UIImage*) getImageFromLuminanceSource:(zxing::LuminanceSource*)luminanceSource;\n- (void)dumpImage:(UIImage*)image;\n@end\n\n//------------------------------------------------------------------------------\n// Qr encoder processor\n//------------------------------------------------------------------------------\n@interface CDVqrProcessor: NSObject\n@property (nonatomic, retain) CDVBarcodeScanner*          plugin;\n@property (nonatomic, retain) NSString*                   callback;\n@property (nonatomic, retain) NSString*                   stringToEncode;\n@property                     NSInteger                   size;\n\n- (id)initWithPlugin:(CDVBarcodeScanner*)plugin callback:(NSString*)callback stringToEncode:(NSString*)stringToEncode;\n- (void)generateImage;\n@end\n\n//------------------------------------------------------------------------------\n// view controller for the ui\n//------------------------------------------------------------------------------\n@interface CDVbcsViewController : UIViewController <CDVBarcodeScannerOrientationDelegate> {}\n@property (nonatomic, retain) CDVbcsProcessor*  processor;\n@property (nonatomic, retain) NSString*        alternateXib;\n@property (nonatomic)         BOOL             shutterPressed;\n@property (nonatomic, retain) IBOutlet UIView* overlayView;\n// unsafe_unretained is equivalent to assign - used to prevent retain cycles in the property below\n@property (nonatomic, unsafe_unretained) id orientationDelegate;\n\n- (id)initWithProcessor:(CDVbcsProcessor*)processor alternateOverlay:(NSString *)alternateXib;\n- (void)startCapturing;\n- (UIView*)buildOverlayView;\n- (UIImage*)buildReticleImage;\n- (void)shutterButtonPressed;\n- (IBAction)cancelButtonPressed:(id)sender;\n\n@end\n\n//------------------------------------------------------------------------------\n// plugin class\n//------------------------------------------------------------------------------\n@implementation CDVBarcodeScanner\n\n//--------------------------------------------------------------------------\n- (NSString*)isScanNotPossible {\n    NSString* result = nil;\n    \n    Class aClass = NSClassFromString(@\"AVCaptureSession\");\n    if (aClass == nil) {\n        return @\"AVFoundation Framework not available\";\n    }\n    \n    return result;\n}\n\n//--------------------------------------------------------------------------\n- (void)scan:(CDVInvokedUrlCommand*)command {\n    CDVbcsProcessor* processor;\n    NSString*       callback;\n    NSString*       capabilityError;\n    \n    callback = command.callbackId;\n    \n    // We allow the user to define an alternate xib file for loading the overlay.\n    NSString *overlayXib = nil;\n    if ( [command.arguments count] >= 1 )\n    {\n        overlayXib = [command.arguments objectAtIndex:0];\n    }\n    \n    capabilityError = [self isScanNotPossible];\n    if (capabilityError) {\n        [self returnError:capabilityError callback:callback];\n        return;\n    }\n    \n    processor = [[CDVbcsProcessor alloc]\n                 initWithPlugin:self\n                 callback:callback\n                 parentViewController:self.viewController\n                 alterateOverlayXib:overlayXib\n                 ];\n    // queue [processor scanBarcode] to run on the event loop\n    [processor performSelector:@selector(scanBarcode) withObject:nil afterDelay:0];\n}\n\n//--------------------------------------------------------------------------\n- (void)encode:(CDVInvokedUrlCommand*)command {\n    if([command.arguments count] < 1)\n        [self returnError:@\"Too few arguments!\" callback:command.callbackId];\n    \n    CDVqrProcessor* processor;\n    NSString*       callback;\n    callback = command.callbackId;\n    \n    processor = [[CDVqrProcessor alloc]\n                 initWithPlugin:self\n                 callback:callback\n                 stringToEncode: command.arguments[0][@\"data\"]\n                 ];\n    \n    [processor retain];\n    [processor retain];\n    [processor retain];\n    // queue [processor generateImage] to run on the event loop\n    [processor performSelector:@selector(generateImage) withObject:nil afterDelay:0];\n}\n\n- (void)returnImage:(NSString*)filePath format:(NSString*)format callback:(NSString*)callback{\n    NSMutableDictionary* resultDict = [[[NSMutableDictionary alloc] init] autorelease];\n    [resultDict setObject:format forKey:@\"format\"];\n    [resultDict setObject:filePath forKey:@\"file\"];\n    \n    CDVPluginResult* result = [CDVPluginResult\n                               resultWithStatus: CDVCommandStatus_OK\n                               messageAsDictionary:resultDict\n                               ];\n    \n    [[self commandDelegate] sendPluginResult:result callbackId:callback];\n}\n\n//--------------------------------------------------------------------------\n- (void)returnSuccess:(NSString*)scannedText format:(NSString*)format cancelled:(BOOL)cancelled flipped:(BOOL)flipped callback:(NSString*)callback{\n    NSNumber* cancelledNumber = [NSNumber numberWithInt:(cancelled?1:0)];\n    \n    NSMutableDictionary* resultDict = [[NSMutableDictionary alloc] init];\n    [resultDict setObject:scannedText     forKey:@\"text\"];\n    [resultDict setObject:format          forKey:@\"format\"];\n    [resultDict setObject:cancelledNumber forKey:@\"cancelled\"];\n    \n    CDVPluginResult* result = [CDVPluginResult\n                               resultWithStatus: CDVCommandStatus_OK\n                               messageAsDictionary: resultDict\n                               ];\n    [self.commandDelegate sendPluginResult:result callbackId:callback];\n}\n\n//--------------------------------------------------------------------------\n- (void)returnError:(NSString*)message callback:(NSString*)callback {\n    CDVPluginResult* result = [CDVPluginResult\n                               resultWithStatus: CDVCommandStatus_ERROR\n                               messageAsString: message\n                               ];\n    \n    [self.commandDelegate sendPluginResult:result callbackId:callback];\n}\n\n@end\n\n//------------------------------------------------------------------------------\n// class that does the grunt work\n//------------------------------------------------------------------------------\n@implementation CDVbcsProcessor\n\n@synthesize plugin               = _plugin;\n@synthesize callback             = _callback;\n@synthesize parentViewController = _parentViewController;\n@synthesize viewController       = _viewController;\n@synthesize captureSession       = _captureSession;\n@synthesize previewLayer         = _previewLayer;\n@synthesize alternateXib         = _alternateXib;\n@synthesize is1D                 = _is1D;\n@synthesize is2D                 = _is2D;\n@synthesize capturing            = _capturing;\n@synthesize results              = _results;\n\nSystemSoundID _soundFileObject;\n\n//--------------------------------------------------------------------------\n- (id)initWithPlugin:(CDVBarcodeScanner*)plugin\n            callback:(NSString*)callback\nparentViewController:(UIViewController*)parentViewController\n  alterateOverlayXib:(NSString *)alternateXib {\n    self = [super init];\n    if (!self) return self;\n    \n    self.plugin               = plugin;\n    self.callback             = callback;\n    self.parentViewController = parentViewController;\n    self.alternateXib         = alternateXib;\n    \n    self.is1D      = YES;\n    self.is2D      = YES;\n    self.capturing = NO;\n    self.results = [NSMutableArray new];\n    \n    CFURLRef soundFileURLRef  = CFBundleCopyResourceURL(CFBundleGetMainBundle(), CFSTR(\"CDVBarcodeScanner.bundle/beep\"), CFSTR (\"caf\"), NULL);\n    AudioServicesCreateSystemSoundID(soundFileURLRef, &_soundFileObject);\n    \n    return self;\n}\n\n//--------------------------------------------------------------------------\n- (void)dealloc {\n    self.plugin = nil;\n    self.callback = nil;\n    self.parentViewController = nil;\n    self.viewController = nil;\n    self.captureSession = nil;\n    self.previewLayer = nil;\n    self.alternateXib = nil;\n    self.results = nil;\n    \n    self.capturing = NO;\n    \n    AudioServicesRemoveSystemSoundCompletion(_soundFileObject);\n    AudioServicesDisposeSystemSoundID(_soundFileObject);\n    \n    [super dealloc];\n}\n\n//--------------------------------------------------------------------------\n- (void)scanBarcode {\n    \n//    self.captureSession = nil;\n//    self.previewLayer = nil;\n    NSString* errorMessage = [self setUpCaptureSession];\n    if (errorMessage) {\n        [self barcodeScanFailed:errorMessage];\n        return;\n    }\n    \n    self.viewController = [[CDVbcsViewController alloc] initWithProcessor: self alternateOverlay:self.alternateXib];\n    // here we set the orientation delegate to the MainViewController of the app (orientation controlled in the Project Settings)\n    self.viewController.orientationDelegate = self.plugin.viewController;\n    \n    // delayed [self openDialog];\n    [self performSelector:@selector(openDialog) withObject:nil afterDelay:1];\n}\n\n//--------------------------------------------------------------------------\n- (void)openDialog {\n    [self.parentViewController\n     presentViewController:self.viewController\n     animated:YES completion:nil\n     ];\n}\n\n//--------------------------------------------------------------------------\n- (void)barcodeScanDone {\n    self.capturing = NO;\n    [self.captureSession stopRunning];\n    [self.parentViewController dismissViewControllerAnimated:YES completion:nil];\n    \n    // viewcontroller holding onto a reference to us, release them so they\n    // will release us\n    self.viewController = nil;\n}\n\n//--------------------------------------------------------------------------\n- (BOOL)checkResult:(NSString *)result {\n    [self.results addObject:result];\n    \n    NSInteger treshold = 7;\n    \n    if (self.results.count > treshold) {\n        [self.results removeObjectAtIndex:0];\n    }\n    \n    if (self.results.count < treshold)\n    {\n        return NO;\n    }\n    \n    BOOL allEqual = YES;\n    NSString *compareString = [self.results objectAtIndex:0];\n    \n    for (NSString *aResult in self.results)\n    {\n        if (![compareString isEqualToString:aResult])\n        {\n            allEqual = NO;\n            //NSLog(@\"Did not fit: %@\",self.results);\n            break;\n        }\n    }\n    \n    return allEqual;\n}\n\n//--------------------------------------------------------------------------\n- (void)barcodeScanSucceeded:(NSString*)text format:(NSString*)format {\n    dispatch_sync(dispatch_get_main_queue(), ^{\n        [self barcodeScanDone];\n        AudioServicesPlaySystemSound(_soundFileObject);\n        [self.plugin returnSuccess:text format:format cancelled:FALSE flipped:FALSE callback:self.callback];\n    });\n}\n\n//--------------------------------------------------------------------------\n- (void)barcodeScanFailed:(NSString*)message {\n    [self barcodeScanDone];\n    [self.plugin returnError:message callback:self.callback];\n}\n\n//--------------------------------------------------------------------------\n- (void)barcodeScanCancelled {\n    [self barcodeScanDone];\n    [self.plugin returnSuccess:@\"\" format:@\"\" cancelled:TRUE flipped:self.isFlipped callback:self.callback];\n    if (self.isFlipped) {\n        self.isFlipped = NO;\n    }\n}\n\n\n- (void)flipCamera\n{\n    self.isFlipped = YES;\n    self.isFrontCamera = !self.isFrontCamera;\n    [self performSelector:@selector(barcodeScanCancelled) withObject:nil afterDelay:0];\n    [self performSelector:@selector(scanBarcode) withObject:nil afterDelay:0.1];\n}\n\n//--------------------------------------------------------------------------\n- (NSString*)setUpCaptureSession {\n    NSError* error = nil;\n    \n    AVCaptureSession* captureSession = [[AVCaptureSession alloc] init];\n    self.captureSession = captureSession;\n    \n    AVCaptureDevice* __block device = nil;\n    if (self.isFrontCamera) {\n        \n        NSArray* devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];\n        [devices enumerateObjectsUsingBlock:^(AVCaptureDevice *obj, NSUInteger idx, BOOL *stop) {\n            if (obj.position == AVCaptureDevicePositionFront) {\n                device = obj;\n            }\n        }];\n    } else {\n        device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];\n        if (!device) return @\"unable to obtain video capture device\";\n        \n    }\n    \n    \n    AVCaptureDeviceInput* input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];\n    if (!input) return @\"unable to obtain video capture device input\";\n    \n    AVCaptureVideoDataOutput* output = [[AVCaptureVideoDataOutput alloc] init];\n    if (!output) return @\"unable to obtain video capture output\";\n    \n    NSDictionary* videoOutputSettings = [NSDictionary\n                                         dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA]\n                                         forKey:(id)kCVPixelBufferPixelFormatTypeKey\n                                         ];\n    \n    output.alwaysDiscardsLateVideoFrames = YES;\n    output.videoSettings = videoOutputSettings;\n    \n    [output setSampleBufferDelegate:self queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0)];\n    \n    if (![captureSession canSetSessionPreset:AVCaptureSessionPresetMedium]) {\n        return @\"unable to preset medium quality video capture\";\n    }\n    \n    captureSession.sessionPreset = AVCaptureSessionPresetMedium;\n    \n    if ([captureSession canAddInput:input]) {\n        [captureSession addInput:input];\n    }\n    else {\n        return @\"unable to add video capture device input to session\";\n    }\n    \n    if ([captureSession canAddOutput:output]) {\n        [captureSession addOutput:output];\n    }\n    else {\n        return @\"unable to add video capture output to session\";\n    }\n    \n    // setup capture preview layer\n    self.previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:captureSession];\n    \n    // run on next event loop pass [captureSession startRunning]\n    [captureSession performSelector:@selector(startRunning) withObject:nil afterDelay:0];\n    \n    return nil;\n}\n\n//--------------------------------------------------------------------------\n// this method gets sent the captured frames\n//--------------------------------------------------------------------------\n- (void)captureOutput:(AVCaptureOutput*)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection*)connection {\n    \n    if (!self.capturing) return;\n    \n#if USE_SHUTTER\n    if (!self.viewController.shutterPressed) return;\n    self.viewController.shutterPressed = NO;\n    \n    UIView* flashView = [[UIView alloc] initWithFrame:self.viewController.view.frame];\n    [flashView setBackgroundColor:[UIColor whiteColor]];\n    [self.viewController.view.window addSubview:flashView];\n    \n    [UIView\n     animateWithDuration:.4f\n     animations:^{\n         [flashView setAlpha:0.f];\n     }\n     completion:^(BOOL finished){\n         [flashView removeFromSuperview];\n     }\n     ];\n    \n    //         [self dumpImage: [[self getImageFromSample:sampleBuffer] autorelease]];\n#endif\n    \n    \n    using namespace zxing;\n    \n    // LuminanceSource is pretty dumb; we have to give it a pointer to\n    // a byte array, but then can't get it back out again.  We need to\n    // get it back to free it.  Saving it in imageBytes.\n    uint8_t* imageBytes;\n    \n    //        NSTimeInterval timeStart = [NSDate timeIntervalSinceReferenceDate];\n    \n    try {\n        DecodeHints decodeHints;\n        decodeHints.addFormat(BarcodeFormat_QR_CODE);\n        decodeHints.addFormat(BarcodeFormat_DATA_MATRIX);\n        decodeHints.addFormat(BarcodeFormat_UPC_E);\n        decodeHints.addFormat(BarcodeFormat_UPC_A);\n        decodeHints.addFormat(BarcodeFormat_EAN_8);\n        decodeHints.addFormat(BarcodeFormat_EAN_13);\n        decodeHints.addFormat(BarcodeFormat_CODE_128);\n        decodeHints.addFormat(BarcodeFormat_CODE_39);\n        decodeHints.addFormat(BarcodeFormat_ITF);\n        \n        // here's the meat of the decode process\n        Ref<LuminanceSource>   luminanceSource   ([self getLuminanceSourceFromSample: sampleBuffer imageBytes:&imageBytes]);\n        //            [self dumpImage: [[self getImageFromLuminanceSource:luminanceSource] autorelease]];\n        Ref<Binarizer>         binarizer         (new HybridBinarizer(luminanceSource));\n        Ref<BinaryBitmap>      bitmap            (new BinaryBitmap(binarizer));\n        Ref<MultiFormatReader> reader            (new MultiFormatReader());\n        Ref<Result>            result            (reader->decode(bitmap, decodeHints));\n        Ref<String>            resultText        (result->getText());\n        BarcodeFormat          formatVal =       result->getBarcodeFormat();\n        NSString*              format    =       [self formatStringFrom:formatVal];\n        \n        \n        const char* cString      = resultText->getText().c_str();\n        NSString*   resultString = [[NSString alloc] initWithCString:cString encoding:NSUTF8StringEncoding];\n        \n        if ([self checkResult:resultString]) {\n            [self barcodeScanSucceeded:resultString format:format];\n        }\n        \n        \n        \n    }\n    catch (zxing::ReaderException &rex) {\n        //            NSString *message = [[[NSString alloc] initWithCString:rex.what() encoding:NSUTF8StringEncoding] autorelease];\n        //            NSLog(@\"decoding: ReaderException: %@\", message);\n    }\n    catch (zxing::IllegalArgumentException &iex) {\n        //            NSString *message = [[[NSString alloc] initWithCString:iex.what() encoding:NSUTF8StringEncoding] autorelease];\n        //            NSLog(@\"decoding: IllegalArgumentException: %@\", message);\n    }\n    catch (...) {\n        //            NSLog(@\"decoding: unknown exception\");\n        //            [self barcodeScanFailed:@\"unknown exception decoding barcode\"];\n    }\n    \n    //        NSTimeInterval timeElapsed  = [NSDate timeIntervalSinceReferenceDate] - timeStart;\n    //        NSLog(@\"decoding completed in %dms\", (int) (timeElapsed * 1000));\n    \n    // free the buffer behind the LuminanceSource\n    if (imageBytes) {\n        free(imageBytes);\n    }\n}\n\n//--------------------------------------------------------------------------\n// convert barcode format to string\n//--------------------------------------------------------------------------\n- (NSString*)formatStringFrom:(zxing::BarcodeFormat)format {\n    if (format == zxing::BarcodeFormat_QR_CODE)      return @\"QR_CODE\";\n    if (format == zxing::BarcodeFormat_DATA_MATRIX)  return @\"DATA_MATRIX\";\n    if (format == zxing::BarcodeFormat_UPC_E)        return @\"UPC_E\";\n    if (format == zxing::BarcodeFormat_UPC_A)        return @\"UPC_A\";\n    if (format == zxing::BarcodeFormat_EAN_8)        return @\"EAN_8\";\n    if (format == zxing::BarcodeFormat_EAN_13)       return @\"EAN_13\";\n    if (format == zxing::BarcodeFormat_CODE_128)     return @\"CODE_128\";\n    if (format == zxing::BarcodeFormat_CODE_39)      return @\"CODE_39\";\n    if (format == zxing::BarcodeFormat_ITF)          return @\"ITF\";\n    return @\"???\";\n}\n\n//--------------------------------------------------------------------------\n// convert capture's sample buffer (scanned picture) into the thing that\n// zxing needs.\n//--------------------------------------------------------------------------\n- (zxing::Ref<zxing::LuminanceSource>) getLuminanceSourceFromSample:(CMSampleBufferRef)sampleBuffer imageBytes:(uint8_t**)ptr {\n    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);\n    CVPixelBufferLockBaseAddress(imageBuffer, 0);\n    \n    size_t   bytesPerRow =            CVPixelBufferGetBytesPerRow(imageBuffer);\n    size_t   width       =            CVPixelBufferGetWidth(imageBuffer);\n    size_t   height      =            CVPixelBufferGetHeight(imageBuffer);\n    uint8_t* baseAddress = (uint8_t*) CVPixelBufferGetBaseAddress(imageBuffer);\n    \n    // only going to get 90% of the min(width,height) of the captured image\n    size_t    greyWidth  = 9 * MIN(width, height) / 10;\n    uint8_t*  greyData   = (uint8_t*) malloc(greyWidth * greyWidth);\n    \n    // remember this pointer so we can free it later\n    *ptr = greyData;\n    \n    if (!greyData) {\n        CVPixelBufferUnlockBaseAddress(imageBuffer,0);\n        throw new zxing::ReaderException(\"out of memory\");\n    }\n    \n    size_t offsetX = (width  - greyWidth) / 2;\n    size_t offsetY = (height - greyWidth) / 2;\n    \n    // pixel-by-pixel ...\n    for (size_t i=0; i<greyWidth; i++) {\n        for (size_t j=0; j<greyWidth; j++) {\n            // i,j are the coordinates from the sample buffer\n            // ni, nj are the coordinates in the LuminanceSource\n            // in this case, there's a rotation taking place\n            size_t ni = greyWidth-j;\n            size_t nj = i;\n            \n            size_t baseOffset = (j+offsetY)*bytesPerRow + (i + offsetX)*4;\n            \n            // convert from color to grayscale\n            // http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale\n            size_t value = 0.11 * baseAddress[baseOffset] +\n            0.59 * baseAddress[baseOffset + 1] +\n            0.30 * baseAddress[baseOffset + 2];\n            \n            greyData[nj*greyWidth + ni] = value;\n        }\n    }\n    \n    CVPixelBufferUnlockBaseAddress(imageBuffer,0);\n    \n    using namespace zxing;\n    \n    Ref<LuminanceSource> luminanceSource (\n                                          new GreyscaleLuminanceSource(greyData, (int)greyWidth, (int)greyWidth, 0, 0, (int)greyWidth, (int)greyWidth)\n                                          );\n    \n    return luminanceSource;\n}\n\n//--------------------------------------------------------------------------\n// for debugging\n//--------------------------------------------------------------------------\n- (UIImage*) getImageFromLuminanceSource:(zxing::LuminanceSource*)luminanceSource  {\n    unsigned char* bytes = luminanceSource->getMatrix();\n    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();\n    CGContextRef context = CGBitmapContextCreate(\n                                                 bytes,\n                                                 luminanceSource->getWidth(), luminanceSource->getHeight(), 8, luminanceSource->getWidth(),\n                                                 colorSpace,\n                                                 kCGImageAlphaNone\n                                                 );\n    \n    CGImageRef cgImage = CGBitmapContextCreateImage(context);\n    UIImage*   image   = [[UIImage alloc] initWithCGImage:cgImage];\n    \n    CGContextRelease(context);\n    CGColorSpaceRelease(colorSpace);\n    CGImageRelease(cgImage);\n    free(bytes);\n    \n    return image;\n}\n\n//--------------------------------------------------------------------------\n// for debugging\n//--------------------------------------------------------------------------\n- (UIImage*)getImageFromSample:(CMSampleBufferRef)sampleBuffer {\n    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);\n    CVPixelBufferLockBaseAddress(imageBuffer, 0);\n    \n    size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);\n    size_t width       = CVPixelBufferGetWidth(imageBuffer);\n    size_t height      = CVPixelBufferGetHeight(imageBuffer);\n    \n    uint8_t* baseAddress    = (uint8_t*) CVPixelBufferGetBaseAddress(imageBuffer);\n    int      length         = (int)(height * bytesPerRow);\n    uint8_t* newBaseAddress = (uint8_t*) malloc(length);\n    memcpy(newBaseAddress, baseAddress, length);\n    baseAddress = newBaseAddress;\n    \n    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();\n    CGContextRef context = CGBitmapContextCreate(\n                                                 baseAddress,\n                                                 width, height, 8, bytesPerRow,\n                                                 colorSpace,\n                                                 kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst\n                                                 );\n    \n    CGImageRef cgImage = CGBitmapContextCreateImage(context);\n    UIImage*   image   = [[UIImage alloc] initWithCGImage:cgImage];\n    \n    CVPixelBufferUnlockBaseAddress(imageBuffer,0);\n    CGContextRelease(context);\n    CGColorSpaceRelease(colorSpace);\n    CGImageRelease(cgImage);\n    \n    free(baseAddress);\n    \n    return image;\n}\n\n//--------------------------------------------------------------------------\n// for debugging\n//--------------------------------------------------------------------------\n- (void)dumpImage:(UIImage*)image {\n    NSLog(@\"writing image to library: %dx%d\", (int)image.size.width, (int)image.size.height);\n    ALAssetsLibrary* assetsLibrary = [[ALAssetsLibrary alloc] init];\n    [assetsLibrary\n     writeImageToSavedPhotosAlbum:image.CGImage\n     orientation:ALAssetOrientationUp\n     completionBlock:^(NSURL* assetURL, NSError* error){\n         if (error) NSLog(@\"   error writing image to library\");\n         else       NSLog(@\"   wrote image to library %@\", assetURL);\n     }\n     ];\n}\n\n@end\n\n//------------------------------------------------------------------------------\n// qr encoder processor\n//------------------------------------------------------------------------------\n@implementation CDVqrProcessor\n@synthesize plugin               = _plugin;\n@synthesize callback             = _callback;\n@synthesize stringToEncode       = _stringToEncode;\n@synthesize size                 = _size;\n\n- (id)initWithPlugin:(CDVBarcodeScanner*)plugin callback:(NSString*)callback stringToEncode:(NSString*)stringToEncode{\n    self = [super init];\n    if (!self) return self;\n    \n    self.plugin          = plugin;\n    self.callback        = callback;\n    self.stringToEncode  = stringToEncode;\n    self.size            = 300;\n    \n    return self;\n}\n\n//--------------------------------------------------------------------------\n- (void)dealloc {\n    self.plugin = nil;\n    self.callback = nil;\n    self.stringToEncode = nil;\n    \n    [super dealloc];\n}\n//--------------------------------------------------------------------------\n- (void)generateImage{\n    /* setup qr filter */\n    CIFilter *filter = [CIFilter filterWithName:@\"CIQRCodeGenerator\"];\n    [filter setDefaults];\n    \n    /* set filter's input message\n     * the encoding string has to be convert to a UTF-8 encoded NSData object */\n    [filter setValue:[self.stringToEncode dataUsingEncoding:NSUTF8StringEncoding]\n              forKey:@\"inputMessage\"];\n    \n    /* on ios >= 7.0  set low image error correction level */\n    if (floor(NSFoundationVersionNumber) >= NSFoundationVersionNumber_iOS_7_0)\n        [filter setValue:@\"L\" forKey:@\"inputCorrectionLevel\"];\n    \n    /* prepare cgImage */\n    CIImage *outputImage = [filter outputImage];\n    CIContext *context = [CIContext contextWithOptions:nil];\n    CGImageRef cgImage = [context createCGImage:outputImage\n                                       fromRect:[outputImage extent]];\n    \n    /* returned qr code image */\n    UIImage *qrImage = [UIImage imageWithCGImage:cgImage\n                                           scale:1.\n                                     orientation:UIImageOrientationUp];\n    /* resize generated image */\n    CGFloat width = _size;\n    CGFloat height = _size;\n    \n    UIGraphicsBeginImageContext(CGSizeMake(width, height));\n    \n    CGContextRef ctx = UIGraphicsGetCurrentContext();\n    CGContextSetInterpolationQuality(ctx, kCGInterpolationNone);\n    [qrImage drawInRect:CGRectMake(0, 0, width, height)];\n    qrImage = UIGraphicsGetImageFromCurrentImageContext();\n    \n    /* clean up */\n    UIGraphicsEndImageContext();\n    CGImageRelease(cgImage);\n    \n    /* save image to file */\n    NSString* filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@\"tmpqrcode.jpeg\"];\n    [UIImageJPEGRepresentation(qrImage, 1.0) writeToFile:filePath atomically:YES];\n    \n    /* return file path back to cordova */\n    [self.plugin returnImage:filePath format:@\"QR_CODE\" callback: self.callback];\n}\n@end\n\n//------------------------------------------------------------------------------\n// view controller for the ui\n//------------------------------------------------------------------------------\n@implementation CDVbcsViewController\n@synthesize processor      = _processor;\n@synthesize shutterPressed = _shutterPressed;\n@synthesize alternateXib   = _alternateXib;\n@synthesize overlayView    = _overlayView;\n\n//--------------------------------------------------------------------------\n- (id)initWithProcessor:(CDVbcsProcessor*)processor alternateOverlay:(NSString *)alternateXib {\n    self = [super init];\n    if (!self) return self;\n    \n    self.processor = processor;\n    self.shutterPressed = NO;\n    self.alternateXib = alternateXib;\n    self.overlayView = nil;\n    return self;\n}\n\n//--------------------------------------------------------------------------\n- (void)dealloc {\n    self.view = nil;\n    self.processor = nil;\n    self.shutterPressed = NO;\n    self.alternateXib = nil;\n    self.overlayView = nil;\n    [super dealloc];\n}\n\n//--------------------------------------------------------------------------\n- (void)loadView {\n    self.view = [[UIView alloc] initWithFrame: self.processor.parentViewController.view.frame];\n    \n    // setup capture preview layer\n    AVCaptureVideoPreviewLayer* previewLayer = self.processor.previewLayer;\n    previewLayer.frame = self.view.bounds;\n    previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;\n    \n    if ([previewLayer.connection isVideoOrientationSupported]) {\n        [previewLayer.connection setVideoOrientation:AVCaptureVideoOrientationPortrait];\n    }\n    \n    [self.view.layer insertSublayer:previewLayer below:[[self.view.layer sublayers] objectAtIndex:0]];\n    \n    [self.view addSubview:[self buildOverlayView]];\n}\n\n//--------------------------------------------------------------------------\n- (void)viewWillAppear:(BOOL)animated {\n    \n    // set video orientation to what the camera sees\n    self.processor.previewLayer.connection.videoOrientation = [[UIApplication sharedApplication] statusBarOrientation];\n    \n    // this fixes the bug when the statusbar is landscape, and the preview layer\n    // starts up in portrait (not filling the whole view)\n    self.processor.previewLayer.frame = self.view.bounds;\n}\n\n//--------------------------------------------------------------------------\n- (void)viewDidAppear:(BOOL)animated {\n    [self startCapturing];\n    \n    [super viewDidAppear:animated];\n}\n\n//--------------------------------------------------------------------------\n- (void)startCapturing {\n    self.processor.capturing = YES;\n}\n\n//--------------------------------------------------------------------------\n- (void)shutterButtonPressed {\n    self.shutterPressed = YES;\n}\n\n//--------------------------------------------------------------------------\n- (IBAction)cancelButtonPressed:(id)sender {\n    [self.processor performSelector:@selector(barcodeScanCancelled) withObject:nil afterDelay:0];\n}\n\n- (void)flipCameraButtonPressed:(id)sender\n{\n    [self.processor performSelector:@selector(flipCamera) withObject:nil afterDelay:0];\n}\n\n//--------------------------------------------------------------------------\n- (UIView *)buildOverlayViewFromXib\n{\n    [[NSBundle mainBundle] loadNibNamed:self.alternateXib owner:self options:NULL];\n    \n    if ( self.overlayView == nil )\n    {\n        NSLog(@\"%@\", @\"An error occurred loading the overlay xib.  It appears that the overlayView outlet is not set.\");\n        return nil;\n    }\n    \n    return self.overlayView;\n}\n\n//--------------------------------------------------------------------------\n- (UIView*)buildOverlayView {\n    \n    if ( nil != self.alternateXib )\n    {\n        return [self buildOverlayViewFromXib];\n    }\n    CGRect bounds = self.view.bounds;\n    bounds = CGRectMake(0, 0, bounds.size.width, bounds.size.height);\n    \n    UIView* overlayView = [[UIView alloc] initWithFrame:bounds];\n    overlayView.autoresizesSubviews = YES;\n    overlayView.autoresizingMask    = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;\n    overlayView.opaque              = NO;\n\n    UIToolbar* toolbar = [[UIToolbar alloc] init];\n    toolbar.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin;\n    \n    id cancelButton = [[UIBarButtonItem alloc]\n                       initWithBarButtonSystemItem:UIBarButtonSystemItemCancel\n                       target:(id)self\n                       action:@selector(cancelButtonPressed:)\n                       ];\n    \n    \n    id flexSpace = [[UIBarButtonItem alloc]\n                    initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace\n                    target:nil\n                    action:nil\n                    ];\n    \n    id flipCamera = [[UIBarButtonItem alloc]\n                       initWithBarButtonSystemItem:UIBarButtonSystemItemCamera\n                       target:(id)self\n                       action:@selector(flipCameraButtonPressed:)\n                       ];\n    \n#if USE_SHUTTER\n    id shutterButton = [[UIBarButtonItem alloc]\n                        initWithBarButtonSystemItem:UIBarButtonSystemItemCamera\n                        target:(id)self\n                        action:@selector(shutterButtonPressed)\n                        ];\n    \n    toolbar.items = [NSArray arrayWithObjects:flexSpace,cancelButton,flexSpace, flipCamera ,shutterButton,nil];\n#else\n    toolbar.items = [NSArray arrayWithObjects:flexSpace,cancelButton,flexSpace, flipCamera,nil];\n#endif\n    bounds = overlayView.bounds;\n    \n    [toolbar sizeToFit];\n    CGFloat toolbarHeight  = [toolbar frame].size.height;\n    CGFloat rootViewHeight = CGRectGetHeight(bounds);\n    CGFloat rootViewWidth  = CGRectGetWidth(bounds);\n    CGRect  rectArea       = CGRectMake(0, rootViewHeight - toolbarHeight, rootViewWidth, toolbarHeight);\n    [toolbar setFrame:rectArea];\n    \n    [overlayView addSubview: toolbar];\n    \n    UIImage* reticleImage = [self buildReticleImage];\n    UIView* reticleView = [[UIImageView alloc] initWithImage: reticleImage];\n    CGFloat minAxis = MIN(rootViewHeight, rootViewWidth);\n    \n    rectArea = CGRectMake(\n                          0.5 * (rootViewWidth  - minAxis),\n                          0.5 * (rootViewHeight - minAxis),\n                          minAxis,\n                          minAxis\n                          );\n    \n    [reticleView setFrame:rectArea];\n    \n    reticleView.opaque           = NO;\n    reticleView.contentMode      = UIViewContentModeScaleAspectFit;\n    reticleView.autoresizingMask = 0\n    | UIViewAutoresizingFlexibleLeftMargin\n    | UIViewAutoresizingFlexibleRightMargin\n    | UIViewAutoresizingFlexibleTopMargin\n    | UIViewAutoresizingFlexibleBottomMargin\n    ;\n    \n    [overlayView addSubview: reticleView];\n    \n    return overlayView;\n}\n\n//--------------------------------------------------------------------------\n\n#define RETICLE_SIZE    500.0f\n#define RETICLE_WIDTH    10.0f\n#define RETICLE_OFFSET   60.0f\n#define RETICLE_ALPHA     0.4f\n\n//-------------------------------------------------------------------------\n// builds the green box and red line\n//-------------------------------------------------------------------------\n- (UIImage*)buildReticleImage {\n    UIImage* result;\n    UIGraphicsBeginImageContext(CGSizeMake(RETICLE_SIZE, RETICLE_SIZE));\n    CGContextRef context = UIGraphicsGetCurrentContext();\n    \n    if (self.processor.is1D) {\n        UIColor* color = [UIColor colorWithRed:1.0 green:0.0 blue:0.0 alpha:RETICLE_ALPHA];\n        CGContextSetStrokeColorWithColor(context, color.CGColor);\n        CGContextSetLineWidth(context, RETICLE_WIDTH);\n        CGContextBeginPath(context);\n        CGFloat lineOffset = RETICLE_OFFSET+(0.5*RETICLE_WIDTH);\n        CGContextMoveToPoint(context, lineOffset, RETICLE_SIZE/2);\n        CGContextAddLineToPoint(context, RETICLE_SIZE-lineOffset, 0.5*RETICLE_SIZE);\n        CGContextStrokePath(context);\n    }\n    \n    if (self.processor.is2D) {\n        UIColor* color = [UIColor colorWithRed:0.0 green:1.0 blue:0.0 alpha:RETICLE_ALPHA];\n        CGContextSetStrokeColorWithColor(context, color.CGColor);\n        CGContextSetLineWidth(context, RETICLE_WIDTH);\n        CGContextStrokeRect(context,\n                            CGRectMake(\n                                       RETICLE_OFFSET,\n                                       RETICLE_OFFSET,\n                                       RETICLE_SIZE-2*RETICLE_OFFSET,\n                                       RETICLE_SIZE-2*RETICLE_OFFSET\n                                       )\n                            );\n    }\n    \n    result = UIGraphicsGetImageFromCurrentImageContext();\n    UIGraphicsEndImageContext();\n    return result;\n}\n\n#pragma mark CDVBarcodeScannerOrientationDelegate\n\n- (BOOL)shouldAutorotate\n{\n    return NO;\n}\n\n- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation\n{\n    return UIInterfaceOrientationPortrait;\n}\n\n- (NSUInteger)supportedInterfaceOrientations\n{\n    return UIInterfaceOrientationMaskPortrait;\n}\n\n- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation\n{\n    if ((self.orientationDelegate != nil) && [self.orientationDelegate respondsToSelector:@selector(shouldAutorotateToInterfaceOrientation:)]) {\n        return [self.orientationDelegate shouldAutorotateToInterfaceOrientation:interfaceOrientation];\n    }\n    \n    return YES;\n}\n\n- (void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)orientation duration:(NSTimeInterval)duration\n{\n    [CATransaction begin];\n    \n    self.processor.previewLayer.connection.videoOrientation = orientation;\n    [self.processor.previewLayer layoutSublayers];\n    self.processor.previewLayer.frame = self.view.bounds;\n    \n    [CATransaction commit];\n    [super willAnimateRotationToInterfaceOrientation:orientation duration:duration];\n}\n\n@end\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/ios/scannerOverlay.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<archive type=\"com.apple.InterfaceBuilder3.CocoaTouch.XIB\" version=\"8.00\">\n\t<data>\n\t\t<int key=\"IBDocument.SystemTarget\">1280</int>\n\t\t<string key=\"IBDocument.SystemVersion\">11C74</string>\n\t\t<string key=\"IBDocument.InterfaceBuilderVersion\">1938</string>\n\t\t<string key=\"IBDocument.AppKitVersion\">1138.23</string>\n\t\t<string key=\"IBDocument.HIToolboxVersion\">567.00</string>\n\t\t<object class=\"NSMutableDictionary\" key=\"IBDocument.PluginVersions\">\n\t\t\t<string key=\"NS.key.0\">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>\n\t\t\t<string key=\"NS.object.0\">933</string>\n\t\t</object>\n\t\t<array key=\"IBDocument.IntegratedClassDependencies\">\n\t\t\t<string>IBUINavigationItem</string>\n\t\t\t<string>IBUIBarButtonItem</string>\n\t\t\t<string>IBUIView</string>\n\t\t\t<string>IBUINavigationBar</string>\n\t\t\t<string>IBProxyObject</string>\n\t\t</array>\n\t\t<array key=\"IBDocument.PluginDependencies\">\n\t\t\t<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>\n\t\t</array>\n\t\t<object class=\"NSMutableDictionary\" key=\"IBDocument.Metadata\">\n\t\t\t<string key=\"NS.key.0\">PluginDependencyRecalculationVersion</string>\n\t\t\t<integer value=\"1\" key=\"NS.object.0\"/>\n\t\t</object>\n\t\t<array class=\"NSMutableArray\" key=\"IBDocument.RootObjects\" id=\"1000\">\n\t\t\t<object class=\"IBProxyObject\" id=\"372490531\">\n\t\t\t\t<string key=\"IBProxiedObjectIdentifier\">IBFilesOwner</string>\n\t\t\t\t<string key=\"targetRuntimeIdentifier\">IBCocoaTouchFramework</string>\n\t\t\t</object>\n\t\t\t<object class=\"IBProxyObject\" id=\"975951072\">\n\t\t\t\t<string key=\"IBProxiedObjectIdentifier\">IBFirstResponder</string>\n\t\t\t\t<string key=\"targetRuntimeIdentifier\">IBCocoaTouchFramework</string>\n\t\t\t</object>\n\t\t\t<object class=\"IBUIView\" id=\"191373211\">\n\t\t\t\t<reference key=\"NSNextResponder\"/>\n\t\t\t\t<int key=\"NSvFlags\">274</int>\n\t\t\t\t<array class=\"NSMutableArray\" key=\"NSSubviews\">\n\t\t\t\t\t<object class=\"IBUINavigationBar\" id=\"1064216609\">\n\t\t\t\t\t\t<reference key=\"NSNextResponder\" ref=\"191373211\"/>\n\t\t\t\t\t\t<int key=\"NSvFlags\">290</int>\n\t\t\t\t\t\t<string key=\"NSFrameSize\">{320, 44}</string>\n\t\t\t\t\t\t<reference key=\"NSSuperview\" ref=\"191373211\"/>\n\t\t\t\t\t\t<reference key=\"NSWindow\"/>\n\t\t\t\t\t\t<reference key=\"NSNextKeyView\"/>\n\t\t\t\t\t\t<string key=\"NSReuseIdentifierKey\">_NS:260</string>\n\t\t\t\t\t\t<string key=\"targetRuntimeIdentifier\">IBCocoaTouchFramework</string>\n\t\t\t\t\t\t<int key=\"IBUIBarStyle\">1</int>\n\t\t\t\t\t\t<array class=\"NSMutableArray\" key=\"IBUIItems\">\n\t\t\t\t\t\t\t<object class=\"IBUINavigationItem\" id=\"240626599\">\n\t\t\t\t\t\t\t\t<reference key=\"IBUINavigationBar\" ref=\"1064216609\"/>\n\t\t\t\t\t\t\t\t<string key=\"IBUITitle\">Barcode Scanner</string>\n\t\t\t\t\t\t\t\t<object class=\"IBUIBarButtonItem\" key=\"IBUILeftBarButtonItem\" id=\"1053701234\">\n\t\t\t\t\t\t\t\t\t<string key=\"IBUITitle\">Cancel</string>\n\t\t\t\t\t\t\t\t\t<string key=\"targetRuntimeIdentifier\">IBCocoaTouchFramework</string>\n\t\t\t\t\t\t\t\t\t<int key=\"IBUIStyle\">1</int>\n\t\t\t\t\t\t\t\t\t<reference key=\"IBUINavigationItem\" ref=\"240626599\"/>\n\t\t\t\t\t\t\t\t</object>\n\t\t\t\t\t\t\t\t<string key=\"targetRuntimeIdentifier\">IBCocoaTouchFramework</string>\n\t\t\t\t\t\t\t</object>\n\t\t\t\t\t\t</array>\n\t\t\t\t\t</object>\n\t\t\t\t</array>\n\t\t\t\t<string key=\"NSFrameSize\">{320, 460}</string>\n\t\t\t\t<reference key=\"NSSuperview\"/>\n\t\t\t\t<reference key=\"NSWindow\"/>\n\t\t\t\t<reference key=\"NSNextKeyView\" ref=\"1064216609\"/>\n\t\t\t\t<object class=\"NSColor\" key=\"IBUIBackgroundColor\">\n\t\t\t\t\t<int key=\"NSColorSpace\">3</int>\n\t\t\t\t\t<bytes key=\"NSWhite\">MSAwAA</bytes>\n\t\t\t\t\t<object class=\"NSColorSpace\" key=\"NSCustomColorSpace\">\n\t\t\t\t\t\t<int key=\"NSID\">2</int>\n\t\t\t\t\t</object>\n\t\t\t\t</object>\n\t\t\t\t<string key=\"targetRuntimeIdentifier\">IBCocoaTouchFramework</string>\n\t\t\t</object>\n\t\t</array>\n\t\t<object class=\"IBObjectContainer\" key=\"IBDocument.Objects\">\n\t\t\t<array class=\"NSMutableArray\" key=\"connectionRecords\">\n\t\t\t\t<object class=\"IBConnectionRecord\">\n\t\t\t\t\t<object class=\"IBCocoaTouchOutletConnection\" key=\"connection\">\n\t\t\t\t\t\t<string key=\"label\">overlayView</string>\n\t\t\t\t\t\t<reference key=\"source\" ref=\"372490531\"/>\n\t\t\t\t\t\t<reference key=\"destination\" ref=\"191373211\"/>\n\t\t\t\t\t</object>\n\t\t\t\t\t<int key=\"connectionID\">9</int>\n\t\t\t\t</object>\n\t\t\t</array>\n\t\t\t<object class=\"IBMutableOrderedSet\" key=\"objectRecords\">\n\t\t\t\t<array key=\"orderedObjects\">\n\t\t\t\t\t<object class=\"IBObjectRecord\">\n\t\t\t\t\t\t<int key=\"objectID\">0</int>\n\t\t\t\t\t\t<array key=\"object\" id=\"0\"/>\n\t\t\t\t\t\t<reference key=\"children\" ref=\"1000\"/>\n\t\t\t\t\t\t<nil key=\"parent\"/>\n\t\t\t\t\t</object>\n\t\t\t\t\t<object class=\"IBObjectRecord\">\n\t\t\t\t\t\t<int key=\"objectID\">1</int>\n\t\t\t\t\t\t<reference key=\"object\" ref=\"191373211\"/>\n\t\t\t\t\t\t<array class=\"NSMutableArray\" key=\"children\">\n\t\t\t\t\t\t\t<reference ref=\"1064216609\"/>\n\t\t\t\t\t\t</array>\n\t\t\t\t\t\t<reference key=\"parent\" ref=\"0\"/>\n\t\t\t\t\t</object>\n\t\t\t\t\t<object class=\"IBObjectRecord\">\n\t\t\t\t\t\t<int key=\"objectID\">-1</int>\n\t\t\t\t\t\t<reference key=\"object\" ref=\"372490531\"/>\n\t\t\t\t\t\t<reference key=\"parent\" ref=\"0\"/>\n\t\t\t\t\t\t<string key=\"objectName\">File's Owner</string>\n\t\t\t\t\t</object>\n\t\t\t\t\t<object class=\"IBObjectRecord\">\n\t\t\t\t\t\t<int key=\"objectID\">-2</int>\n\t\t\t\t\t\t<reference key=\"object\" ref=\"975951072\"/>\n\t\t\t\t\t\t<reference key=\"parent\" ref=\"0\"/>\n\t\t\t\t\t</object>\n\t\t\t\t\t<object class=\"IBObjectRecord\">\n\t\t\t\t\t\t<int key=\"objectID\">3</int>\n\t\t\t\t\t\t<reference key=\"object\" ref=\"1064216609\"/>\n\t\t\t\t\t\t<array class=\"NSMutableArray\" key=\"children\">\n\t\t\t\t\t\t\t<reference ref=\"240626599\"/>\n\t\t\t\t\t\t</array>\n\t\t\t\t\t\t<reference key=\"parent\" ref=\"191373211\"/>\n\t\t\t\t\t</object>\n\t\t\t\t\t<object class=\"IBObjectRecord\">\n\t\t\t\t\t\t<int key=\"objectID\">4</int>\n\t\t\t\t\t\t<reference key=\"object\" ref=\"240626599\"/>\n\t\t\t\t\t\t<array class=\"NSMutableArray\" key=\"children\">\n\t\t\t\t\t\t\t<reference ref=\"1053701234\"/>\n\t\t\t\t\t\t</array>\n\t\t\t\t\t\t<reference key=\"parent\" ref=\"1064216609\"/>\n\t\t\t\t\t</object>\n\t\t\t\t\t<object class=\"IBObjectRecord\">\n\t\t\t\t\t\t<int key=\"objectID\">10</int>\n\t\t\t\t\t\t<reference key=\"object\" ref=\"1053701234\"/>\n\t\t\t\t\t\t<reference key=\"parent\" ref=\"240626599\"/>\n\t\t\t\t\t</object>\n\t\t\t\t</array>\n\t\t\t</object>\n\t\t\t<dictionary class=\"NSMutableDictionary\" key=\"flattenedProperties\">\n\t\t\t\t<string key=\"-1.CustomClassName\">PGbcsViewController</string>\n\t\t\t\t<string key=\"-1.IBPluginDependency\">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>\n\t\t\t\t<string key=\"-2.CustomClassName\">UIResponder</string>\n\t\t\t\t<string key=\"-2.IBPluginDependency\">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>\n\t\t\t\t<string key=\"1.IBPluginDependency\">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>\n\t\t\t\t<string key=\"10.IBPluginDependency\">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>\n\t\t\t\t<string key=\"3.IBPluginDependency\">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>\n\t\t\t\t<string key=\"4.IBPluginDependency\">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>\n\t\t\t</dictionary>\n\t\t\t<dictionary class=\"NSMutableDictionary\" key=\"unlocalizedProperties\"/>\n\t\t\t<nil key=\"activeLocalization\"/>\n\t\t\t<dictionary class=\"NSMutableDictionary\" key=\"localizations\"/>\n\t\t\t<nil key=\"sourceID\"/>\n\t\t\t<int key=\"maxID\">11</int>\n\t\t</object>\n\t\t<object class=\"IBClassDescriber\" key=\"IBDocument.Classes\">\n\t\t\t<array class=\"NSMutableArray\" key=\"referencedPartialClassDescriptions\">\n\t\t\t\t<object class=\"IBPartialClassDescription\">\n\t\t\t\t\t<string key=\"className\">PGbcsViewController</string>\n\t\t\t\t\t<string key=\"superclassName\">UIViewController</string>\n\t\t\t\t\t<object class=\"NSMutableDictionary\" key=\"outlets\">\n\t\t\t\t\t\t<string key=\"NS.key.0\">overlayView</string>\n\t\t\t\t\t\t<string key=\"NS.object.0\">UIView</string>\n\t\t\t\t\t</object>\n\t\t\t\t\t<object class=\"NSMutableDictionary\" key=\"toOneOutletInfosByName\">\n\t\t\t\t\t\t<string key=\"NS.key.0\">overlayView</string>\n\t\t\t\t\t\t<object class=\"IBToOneOutletInfo\" key=\"NS.object.0\">\n\t\t\t\t\t\t\t<string key=\"name\">overlayView</string>\n\t\t\t\t\t\t\t<string key=\"candidateClassName\">UIView</string>\n\t\t\t\t\t\t</object>\n\t\t\t\t\t</object>\n\t\t\t\t\t<object class=\"IBClassDescriptionSource\" key=\"sourceIdentifier\">\n\t\t\t\t\t\t<string key=\"majorKey\">IBProjectSource</string>\n\t\t\t\t\t\t<string key=\"minorKey\">./Classes/PGbcsViewController.h</string>\n\t\t\t\t\t</object>\n\t\t\t\t</object>\n\t\t\t</array>\n\t\t</object>\n\t\t<int key=\"IBDocument.localizationMode\">0</int>\n\t\t<string key=\"IBDocument.TargetRuntimeIdentifier\">IBCocoaTouchFramework</string>\n\t\t<bool key=\"IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion\">YES</bool>\n\t\t<int key=\"IBDocument.defaultPropertyAccessControl\">3</int>\n\t\t<string key=\"IBCocoaTouchPluginVersion\">933</string>\n\t</data>\n</archive>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/ios/zxing-all-in-one.cpp",
    "content": "\n#include \"zxing-all-in-one.h\"\n\n// file: zxing/BarcodeFormat.cpp\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n/*\n *  Created by Christian Brunschen on 13/05/2008.\n *  Copyright 2008 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/BarcodeFormat.h>\n\nnamespace zxing {\n\nconst char *barcodeFormatNames[] = {\n    \"None\",\n    \"QR_CODE\",\n    \"DATA_MATRIX\",\n    \"UPC_E\",\n    \"UPC_A\",\n    \"EAN_8\",\n    \"EAN_13\",\n    \"CODE_128\",\n    \"CODE_39\",\n    \"ITF\"\n};\n\n}\n\n// file: zxing/Binarizer.cpp\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n/*\n *  Binarizer.cpp\n *  zxing\n *\n *  Created by Ralf Kistner on 16/10/2009.\n *  Copyright 2008 ZXing authors All rights reserved.\n *  Modified by Lukasz Warchol on 02/02/2010.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/Binarizer.h>\n\nnamespace zxing {\n\n\tBinarizer::Binarizer(Ref<LuminanceSource> source) : source_(source) {\n  }\n\n\tBinarizer::~Binarizer() {\n\t}\n\n\tRef<LuminanceSource> Binarizer::getLuminanceSource() const {\n\t\treturn source_;\n\t}\n\n}\n\n// file: zxing/BinaryBitmap.cpp\n\n/*\n *  BinaryBitmap.cpp\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/BinaryBitmap.h>\n\nnamespace zxing {\n\n\tBinaryBitmap::BinaryBitmap(Ref<Binarizer> binarizer) : binarizer_(binarizer) {\n\n\t}\n\n\tBinaryBitmap::~BinaryBitmap() {\n\t}\n\n\tRef<BitArray> BinaryBitmap::getBlackRow(int y, Ref<BitArray> row) {\n\t\treturn binarizer_->getBlackRow(y, row);\n\t}\n\n\tRef<BitMatrix> BinaryBitmap::getBlackMatrix() {\n\t\treturn binarizer_->getBlackMatrix();\n\t}\n\n\tint BinaryBitmap::getWidth() const {\n\t\treturn getLuminanceSource()->getWidth();\n\t}\n\n\tint BinaryBitmap::getHeight() const {\n\t\treturn getLuminanceSource()->getHeight();\n\t}\n\n\tRef<LuminanceSource> BinaryBitmap::getLuminanceSource() const {\n\t\treturn binarizer_->getLuminanceSource();\n\t}\n\n\n\tbool BinaryBitmap::isCropSupported() const {\n\t  return getLuminanceSource()->isCropSupported();\n\t}\n\n\tRef<BinaryBitmap> BinaryBitmap::crop(int left, int top, int width, int height) {\n\t  return Ref<BinaryBitmap> (new BinaryBitmap(binarizer_->createBinarizer(getLuminanceSource()->crop(left, top, width, height))));\n\t}\n\n\tbool BinaryBitmap::isRotateSupported() const {\n\t  return getLuminanceSource()->isRotateSupported();\n\t}\n\n\tRef<BinaryBitmap> BinaryBitmap::rotateCounterClockwise() {\n\t  return Ref<BinaryBitmap> (new BinaryBitmap(binarizer_->createBinarizer(getLuminanceSource()->rotateCounterClockwise())));\n\t}\n}\n\n// file: zxing/DecodeHints.cpp\n\n/*\n *  DecodeHintType.cpp\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/DecodeHints.h>\n// #include <zxing/common/IllegalArgumentException.h>\nnamespace zxing {\n\nconst DecodeHintType DecodeHints::CHARACTER_SET;\n\nconst DecodeHints DecodeHints::PRODUCT_HINT(\n    BARCODEFORMAT_UPC_E_HINT |\n    BARCODEFORMAT_UPC_A_HINT |\n    BARCODEFORMAT_EAN_8_HINT |\n    BARCODEFORMAT_EAN_13_HINT);\n\nconst DecodeHints DecodeHints::ONED_HINT(\n    BARCODEFORMAT_UPC_E_HINT |\n    BARCODEFORMAT_UPC_A_HINT |\n    BARCODEFORMAT_EAN_8_HINT |\n    BARCODEFORMAT_EAN_13_HINT |\n    BARCODEFORMAT_CODE_128_HINT |\n    BARCODEFORMAT_CODE_39_HINT |\n    BARCODEFORMAT_ITF_HINT);\n\nconst DecodeHints DecodeHints::DEFAULT_HINT(\n    BARCODEFORMAT_UPC_E_HINT |\n    BARCODEFORMAT_UPC_A_HINT |\n    BARCODEFORMAT_EAN_8_HINT |\n    BARCODEFORMAT_EAN_13_HINT |\n    BARCODEFORMAT_CODE_128_HINT |\n    BARCODEFORMAT_CODE_39_HINT |\n    BARCODEFORMAT_ITF_HINT |\n    BARCODEFORMAT_DATA_MATRIX_HINT |\n    BARCODEFORMAT_QR_CODE_HINT);\n\nDecodeHints::DecodeHints() {\n  hints = 0;\n}\n\nDecodeHints::DecodeHints(DecodeHintType init) {\n  hints = init;\n}\n\nvoid DecodeHints::addFormat(BarcodeFormat toadd) {\n  switch (toadd) {\n    case BarcodeFormat_QR_CODE: hints |= BARCODEFORMAT_QR_CODE_HINT; break;\n    case BarcodeFormat_DATA_MATRIX: hints |= BARCODEFORMAT_DATA_MATRIX_HINT; break;\n    case BarcodeFormat_UPC_E: hints |= BARCODEFORMAT_UPC_E_HINT; break;\n    case BarcodeFormat_UPC_A: hints |= BARCODEFORMAT_UPC_A_HINT; break;\n    case BarcodeFormat_EAN_8: hints |= BARCODEFORMAT_EAN_8_HINT; break;\n    case BarcodeFormat_EAN_13: hints |= BARCODEFORMAT_EAN_13_HINT; break;\n    case BarcodeFormat_CODE_128: hints |= BARCODEFORMAT_CODE_128_HINT; break;\n    case BarcodeFormat_CODE_39: hints |= BARCODEFORMAT_CODE_39_HINT; break;\n    case BarcodeFormat_ITF: hints |= BARCODEFORMAT_ITF_HINT; break;\n    default: throw IllegalArgumentException(\"Unrecognizd barcode format\");\n  }\n}\n\nbool DecodeHints::containsFormat(BarcodeFormat tocheck) const {\n  DecodeHintType checkAgainst;\n  switch (tocheck) {\n    case BarcodeFormat_QR_CODE: checkAgainst = BARCODEFORMAT_QR_CODE_HINT; break;\n    case BarcodeFormat_DATA_MATRIX: checkAgainst = BARCODEFORMAT_DATA_MATRIX_HINT; break;\n    case BarcodeFormat_UPC_E: checkAgainst = BARCODEFORMAT_UPC_E_HINT; break;\n    case BarcodeFormat_UPC_A: checkAgainst = BARCODEFORMAT_UPC_A_HINT; break;\n    case BarcodeFormat_EAN_8: checkAgainst = BARCODEFORMAT_EAN_8_HINT; break;\n    case BarcodeFormat_EAN_13: checkAgainst = BARCODEFORMAT_EAN_13_HINT; break;\n    case BarcodeFormat_CODE_128: checkAgainst = BARCODEFORMAT_CODE_128_HINT; break;\n    case BarcodeFormat_CODE_39: checkAgainst = BARCODEFORMAT_CODE_39_HINT; break;\n    case BarcodeFormat_ITF: checkAgainst = BARCODEFORMAT_ITF_HINT; break;\n    default: throw IllegalArgumentException(\"Unrecognizd barcode format\");\n  }\n  return (hints & checkAgainst);\n}\n\nvoid DecodeHints::setTryHarder(bool toset) {\n  if (toset) {\n    hints |= TRYHARDER_HINT;\n  } else {\n    hints &= ~TRYHARDER_HINT;\n  }\n}\n\nbool DecodeHints::getTryHarder() const {\n  return (hints & TRYHARDER_HINT);\n}\n\nvoid DecodeHints::setResultPointCallback(Ref<ResultPointCallback> const& _callback) {\n    callback = _callback;\n}\n\nRef<ResultPointCallback> DecodeHints::getResultPointCallback() const {\n    return callback;\n}\n\n} /* namespace */\n\n// file: zxing/Exception.cpp\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n/*\n *  Exception.cpp\n *  ZXing\n *\n *  Created by Christian Brunschen on 03/06/2008.\n *  Copyright 2008-2011 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n\n */\n\n// #include <zxing/Exception.h>\n\nnamespace zxing {\n\nException::Exception() {}\n\nException::Exception(const char *msg) :\n    message(msg) {\n}\n\nconst char* Exception::what() const throw() {\n  return message.c_str();\n}\n\nException::~Exception() throw() {\n}\n\n}\n\n// file: zxing/FormatException.cpp\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n/*\n *  FormatException.cpp\n *  zxing\n *\n *  Created by Christian Brunschen on 13/05/2008.\n *  Copyright 2008 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/FormatException.h>\n\nnamespace zxing {\n\nFormatException::FormatException() {}\n\nFormatException::FormatException(const char *msg) :\n    ReaderException(msg) {\n}\n\nFormatException::~FormatException() throw() {\n}\n\n}\n\n// file: zxing/LuminanceSource.cpp\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n/*\n *  LuminanceSource.cpp\n *  zxing\n *\n *  Copyright 2008 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <sstream>\n// #include <zxing/LuminanceSource.h>\n// #include <zxing/common/IllegalArgumentException.h>\n\nnamespace zxing {\n\nLuminanceSource::LuminanceSource() {\n}\n\nLuminanceSource::~LuminanceSource() {\n}\n\nbool LuminanceSource::isCropSupported() const {\n  return false;\n}\n\nRef<LuminanceSource> LuminanceSource::crop(int left, int top, int width, int height) {\n  (void)left;\n  (void)top;\n  (void)width;\n  (void)height;\n  throw IllegalArgumentException(\"This luminance source does not support cropping.\");\n}\n\nbool LuminanceSource::isRotateSupported() const {\n  return false;\n}\n\nRef<LuminanceSource> LuminanceSource::rotateCounterClockwise() {\n  throw IllegalArgumentException(\"This luminance source does not support rotation.\");\n}\n\nLuminanceSource::operator std::string() {\n  unsigned char* row = 0;\n  std::ostringstream oss;\n  for (int y = 0; y < getHeight(); y++) {\n    row = getRow(y, row);\n    for (int x = 0; x < getWidth(); x++) {\n      int luminance = row[x] & 0xFF;\n      char c;\n      if (luminance < 0x40) {\n        c = '#';\n      } else if (luminance < 0x80) {\n        c = '+';\n      } else if (luminance < 0xC0) {\n        c = '.';\n      } else {\n        c = ' ';\n      }\n      oss << c;\n    }\n    oss << '\\n';\n  }\n  delete [] row;\n  return oss.str();\n}\n\n\n\n}\n\n// file: zxing/MultiFormatReader.cpp\n\n/*\n *  MultiFormatBarcodeReader.cpp\n *  ZXing\n *\n *  Created by Lukasz Warchol on 10-01-26.\n *  Modified by Luiz Silva on 09/02/2010.\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/MultiFormatReader.h>\n// #include <zxing/qrcode/QRCodeReader.h>\n// #include <zxing/datamatrix/DataMatrixReader.h>\n// #include <zxing/oned/MultiFormatUPCEANReader.h>\n// #include <zxing/oned/MultiFormatOneDReader.h>\n// #include <zxing/ReaderException.h>\n\nnamespace zxing {\n  MultiFormatReader::MultiFormatReader() {\n\n  }\n\n  Ref<Result> MultiFormatReader::decode(Ref<BinaryBitmap> image) {\n    setHints(DecodeHints::DEFAULT_HINT);\n    return decodeInternal(image);\n  }\n\n  Ref<Result> MultiFormatReader::decode(Ref<BinaryBitmap> image, DecodeHints hints) {\n    setHints(hints);\n    return decodeInternal(image);\n  }\n\n  Ref<Result> MultiFormatReader::decodeWithState(Ref<BinaryBitmap> image) {\n    // Make sure to set up the default state so we don't crash\n    if (readers_.size() == 0) {\n      setHints(DecodeHints::DEFAULT_HINT);\n    }\n    return decodeInternal(image);\n  }\n\n  void MultiFormatReader::setHints(DecodeHints hints) {\n    hints_ = hints;\n    readers_.clear();\n    bool tryHarder = hints.getTryHarder();\n\n    bool addOneDReader = hints.containsFormat(BarcodeFormat_UPC_E) ||\n                         hints.containsFormat(BarcodeFormat_UPC_A) ||\n                         hints.containsFormat(BarcodeFormat_EAN_8) ||\n                         hints.containsFormat(BarcodeFormat_EAN_13) ||\n                         hints.containsFormat(BarcodeFormat_CODE_128) ||\n                         hints.containsFormat(BarcodeFormat_CODE_39) ||\n                         hints.containsFormat(BarcodeFormat_ITF);\n    if (addOneDReader && !tryHarder) {\n      readers_.push_back(Ref<Reader>(new zxing::oned::MultiFormatOneDReader(hints)));\n    }\n    if (hints.containsFormat(BarcodeFormat_QR_CODE)) {\n      readers_.push_back(Ref<Reader>(new zxing::qrcode::QRCodeReader()));\n    }\n    if (hints.containsFormat(BarcodeFormat_DATA_MATRIX)) {\n      readers_.push_back(Ref<Reader>(new zxing::datamatrix::DataMatrixReader()));\n    }\n    //TODO: add PDF417 here once PDF417 reader is implemented\n    if (addOneDReader && tryHarder) {\n      readers_.push_back(Ref<Reader>(new zxing::oned::MultiFormatOneDReader(hints)));\n    }\n    if (readers_.size() == 0) {\n      if (!tryHarder) {\n        readers_.push_back(Ref<Reader>(new zxing::oned::MultiFormatOneDReader(hints)));\n      }\n      readers_.push_back(Ref<Reader>(new zxing::qrcode::QRCodeReader()));\n      if (tryHarder) {\n        readers_.push_back(Ref<Reader>(new zxing::oned::MultiFormatOneDReader(hints)));\n      }\n    }\n  }\n\n  Ref<Result> MultiFormatReader::decodeInternal(Ref<BinaryBitmap> image) {\n    for (unsigned int i = 0; i < readers_.size(); i++) {\n      try {\n        return readers_[i]->decode(image, hints_);\n      } catch (ReaderException const& re) {\n        // continue\n      }\n    }\n    throw ReaderException(\"No code detected\");\n  }\n\n  MultiFormatReader::~MultiFormatReader() {\n\n  }\n}\n\n// file: zxing/NotFoundException.cpp\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n/*\n * Copyright 20011 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/NotFoundException.h>\n\nnamespace zxing {\n\n  NotFoundException::NotFoundException(const char *msg)\n    : ReaderException(msg) {}\n\n  NotFoundException::~NotFoundException() throw() {\n  }\n\n}\n\n// file: zxing/Reader.cpp\n\n/*\n *  Reader.cpp\n *  zxing\n *\n *  Created by Christian Brunschen on 13/05/2008.\n *  Copyright 2008 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/Reader.h>\n\nnamespace zxing {\n\nReader::~Reader() { }\n\nRef<Result> Reader::decode(Ref<BinaryBitmap> image) {\n  return decode(image, DecodeHints::DEFAULT_HINT);\n}\n\n}\n\n// file: zxing/ReaderException.cpp\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n/*\n *  ReaderException.cpp\n *  zxing\n *\n *  Created by Christian Brunschen on 13/05/2008.\n *  Copyright 2008-2011 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/ReaderException.h>\n\nnamespace zxing {\n\nReaderException::ReaderException() {}\n\nReaderException::ReaderException(const char *msg) :\n    Exception(msg) {\n}\n\nReaderException::~ReaderException() throw() {\n}\n\n}\n\n// file: zxing/Result.cpp\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n/*\n *  Result.cpp\n *  zxing\n *\n *  Created by Christian Brunschen on 13/05/2008.\n *  Copyright 2008 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/Result.h>\n\nnamespace zxing {\nusing namespace std;\n\nResult::Result(Ref<String> text, ArrayRef<unsigned char> rawBytes, std::vector<Ref<ResultPoint> > resultPoints,\n               BarcodeFormat format) :\n  text_(text), rawBytes_(rawBytes), resultPoints_(resultPoints), format_(format) {\n}\n\nResult::~Result() {\n}\n\nRef<String> Result::getText() {\n  return text_;\n}\n\nArrayRef<unsigned char> Result::getRawBytes() {\n  return rawBytes_;\n}\n\nconst std::vector<Ref<ResultPoint> >& Result::getResultPoints() const {\n  return resultPoints_;\n}\n\nstd::vector<Ref<ResultPoint> >& Result::getResultPoints() {\n  return resultPoints_;\n}\n\nBarcodeFormat Result::getBarcodeFormat() const {\n  return format_;\n}\n\nostream& operator<<(ostream &out, Result& result) {\n  if (result.text_ != 0) {\n    out << result.text_->getText();\n  } else {\n    out << \"[\" << result.rawBytes_->size() << \" bytes]\";\n  }\n  return out;\n}\n\n}\n\n// file: zxing/ResultPoint.cpp\n\n/*\n *  ResultPoint.cpp\n *  zxing\n *\n *  Created by Christian Brunschen on 13/05/2008.\n *  Copyright 2008 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/ResultPoint.h>\n// #include <math.h>\n\nnamespace zxing {\n\nResultPoint::ResultPoint() : posX_(0), posY_(0) {}\n\nResultPoint::ResultPoint(float x, float y) : posX_(x), posY_(y) {}\n\nResultPoint::~ResultPoint() {}\n\nfloat ResultPoint::getX() const {\n  return posX_;\n}\n\nfloat ResultPoint::getY() const {\n  return posY_;\n}\n\nbool ResultPoint::equals(Ref<ResultPoint> other) {\n  return posX_ == other->getX() && posY_ == other->getY();\n}\n\n/**\n * <p>Orders an array of three ResultPoints in an order [A,B,C] such that AB < AC and\n * BC < AC and the angle between BC and BA is less than 180 degrees.\n */\nvoid ResultPoint::orderBestPatterns(std::vector<Ref<ResultPoint> > &patterns) {\n    // Find distances between pattern centers\n    float zeroOneDistance = distance(patterns[0]->getX(), patterns[1]->getX(),patterns[0]->getY(), patterns[1]->getY());\n    float oneTwoDistance = distance(patterns[1]->getX(), patterns[2]->getX(),patterns[1]->getY(), patterns[2]->getY());\n    float zeroTwoDistance = distance(patterns[0]->getX(), patterns[2]->getX(),patterns[0]->getY(), patterns[2]->getY());\n\n    Ref<ResultPoint> pointA, pointB, pointC;\n    // Assume one closest to other two is B; A and C will just be guesses at first\n    if (oneTwoDistance >= zeroOneDistance && oneTwoDistance >= zeroTwoDistance) {\n      pointB = patterns[0];\n      pointA = patterns[1];\n      pointC = patterns[2];\n    } else if (zeroTwoDistance >= oneTwoDistance && zeroTwoDistance >= zeroOneDistance) {\n      pointB = patterns[1];\n      pointA = patterns[0];\n      pointC = patterns[2];\n    } else {\n      pointB = patterns[2];\n      pointA = patterns[0];\n      pointC = patterns[1];\n    }\n\n    // Use cross product to figure out whether A and C are correct or flipped.\n    // This asks whether BC x BA has a positive z component, which is the arrangement\n    // we want for A, B, C. If it's negative, then we've got it flipped around and\n    // should swap A and C.\n    if (crossProductZ(pointA, pointB, pointC) < 0.0f) {\n      Ref<ResultPoint> temp = pointA;\n      pointA = pointC;\n      pointC = temp;\n    }\n\n    patterns[0] = pointA;\n    patterns[1] = pointB;\n    patterns[2] = pointC;\n}\n\nfloat ResultPoint::distance(Ref<ResultPoint> point1, Ref<ResultPoint> point2) {\n  return distance(point1->getX(), point1->getY(), point2->getX(), point2->getY());\n}\n\nfloat ResultPoint::distance(float x1, float x2, float y1, float y2) {\n  float xDiff = x1 - x2;\n  float yDiff = y1 - y2;\n  return (float) sqrt((double) (xDiff * xDiff + yDiff * yDiff));\n}\n\nfloat ResultPoint::crossProductZ(Ref<ResultPoint> pointA, Ref<ResultPoint> pointB, Ref<ResultPoint> pointC) {\n  float bX = pointB->getX();\n  float bY = pointB->getY();\n  return ((pointC->getX() - bX) * (pointA->getY() - bY)) - ((pointC->getY() - bY) * (pointA->getX() - bX));\n}\n}\n\n// file: zxing/ResultPointCallback.cpp\n\n/*\n *  ResultPointCallback.cpp\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/ResultPointCallback.h>\n\nnamespace zxing {\n\nResultPointCallback::~ResultPointCallback() {}\n\n}\n\n// file: zxing/common/Array.cpp\n\n/*\n *  Array.cpp\n *  zxing\n *\n *  Created by Christian Brunschen on 07/05/2008.\n *  Copyright 2008 Google UK. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/common/Array.h>\n\n\n// file: zxing/common/BitArray.cpp\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n/*\n *  Copyright 2010 ZXing authors. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/common/BitArray.h>\n\nusing namespace std;\n\nnamespace zxing {\n\n\nsize_t BitArray::wordsForBits(size_t bits) {\n  int arraySize = (int)((bits + bitsPerWord_ - 1) >> logBits_);\n  return arraySize;\n}\n\nBitArray::BitArray(size_t size) :\n    size_(size), bits_(wordsForBits(size), (const unsigned int)0) {\n}\n\nBitArray::~BitArray() {\n}\n\nsize_t BitArray::getSize() {\n  return size_;\n}\n\nvoid BitArray::setBulk(size_t i, unsigned int newBits) {\n  bits_[i >> logBits_] = newBits;\n}\n\nvoid BitArray::setRange(int start, int end) {\n  if (end < start) {\n    throw IllegalArgumentException(\"invalid call to BitArray::setRange\");\n  }\n  if (end == start) {\n    return;\n  }\n  end--; // will be easier to treat this as the last actually set bit -- inclusive\n  int firstInt = start >> 5;\n  int lastInt = end >> 5;\n  for (int i = firstInt; i <= lastInt; i++) {\n    int firstBit = i > firstInt ? 0 : start & 0x1F;\n    int lastBit = i < lastInt ? 31 : end & 0x1F;\n    int mask;\n    if (firstBit == 0 && lastBit == 31) {\n      mask = -1;\n    } else {\n      mask = 0;\n      for (int j = firstBit; j <= lastBit; j++) {\n        mask |= 1 << j;\n      }\n    }\n    bits_[i] |= mask;\n  }\n}\n\nvoid BitArray::clear() {\n  size_t max = bits_.size();\n  for (size_t i = 0; i < max; i++) {\n    bits_[i] = 0;\n  }\n}\n\nbool BitArray::isRange(size_t start, size_t end, bool value) {\n  if (end < start) {\n    throw IllegalArgumentException(\"end must be after start\");\n  }\n  if (end == start) {\n    return true;\n  }\n  // treat the 'end' as inclusive, rather than exclusive\n  end--;\n  size_t firstWord = start >> logBits_;\n  size_t lastWord = end >> logBits_;\n  for (size_t i = firstWord; i <= lastWord; i++) {\n    size_t firstBit = i > firstWord ? 0 : start & bitsMask_;\n    size_t lastBit = i < lastWord ? bitsPerWord_ - 1: end & bitsMask_;\n    unsigned int mask;\n    if (firstBit == 0 && lastBit == bitsPerWord_ - 1) {\n      mask = numeric_limits<unsigned int>::max();\n    } else {\n      mask = 0;\n      for (size_t j = firstBit; j <= lastBit; j++) {\n        mask |= 1 << j;\n      }\n    }\n    if (value) {\n      if ((bits_[i] & mask) != mask) {\n        return false;\n      }\n    } else {\n      if ((bits_[i] & mask) != 0) {\n        return false;\n      }\n    }\n  }\n  return true;\n}\n\nvector<unsigned int>& BitArray::getBitArray() {\n  return bits_;\n}\n\nvoid BitArray::reverse() {\n  std::vector<unsigned int> newBits(bits_.size(),(const unsigned int) 0);\n  for (size_t i = 0; i < size_; i++) {\n    if (get(size_ - i - 1)) {\n      newBits[i >> logBits_] |= 1<< (i & bitsMask_);\n    }\n  }\n  bits_ = newBits;\n}\n}\n\n// file: zxing/common/BitMatrix.cpp\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n/*\n *  Copyright 2010 ZXing authors. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/common/BitMatrix.h>\n// #include <zxing/common/IllegalArgumentException.h>\n\n// #include <iostream>\n// #include <sstream>\n// #include <string>\n\nusing std::ostream;\nusing std::ostringstream;\n\nusing zxing::BitMatrix;\nusing zxing::BitArray;\nusing zxing::Ref;\n\nnamespace {\n  size_t wordsForSize(size_t width,\n                      size_t height,\n                      unsigned int bitsPerWord,\n                      unsigned int logBits) {\n    size_t bits = width * height;\n    int arraySize = (int)((bits + bitsPerWord - 1) >> logBits);\n    return arraySize;\n  }\n}\n\nBitMatrix::BitMatrix(size_t dimension) :\n  width_(dimension), height_(dimension), words_(0), bits_(NULL) {\n  words_ = wordsForSize(width_, height_, bitsPerWord, logBits);\n  bits_ = new unsigned int[words_];\n  clear();\n}\n\nBitMatrix::BitMatrix(size_t width, size_t height) :\n  width_(width), height_(height), words_(0), bits_(NULL) {\n  words_ = wordsForSize(width_, height_, bitsPerWord, logBits);\n  bits_ = new unsigned int[words_];\n  clear();\n}\n\nBitMatrix::~BitMatrix() {\n  delete[] bits_;\n}\n\n\nvoid BitMatrix::flip(size_t x, size_t y) {\n  size_t offset = x + width_ * y;\n  bits_[offset >> logBits] ^= 1 << (offset & bitsMask);\n}\n\nvoid BitMatrix::clear() {\n  std::fill(bits_, bits_+words_, 0);\n}\n\nvoid BitMatrix::setRegion(size_t left, size_t top, size_t width, size_t height) {\n  if ((long)top < 0 || (long)left < 0) {\n    throw IllegalArgumentException(\"topI and leftJ must be nonnegative\");\n  }\n  if (height < 1 || width < 1) {\n    throw IllegalArgumentException(\"height and width must be at least 1\");\n  }\n  size_t right = left + width;\n  size_t bottom = top + height;\n  if (right > width_ || bottom > height_) {\n    throw IllegalArgumentException(\"top + height and left + width must be <= matrix dimension\");\n  }\n  for (size_t y = top; y < bottom; y++) {\n    int yOffset = (int)(width_ * y);\n    for (size_t x = left; x < right; x++) {\n      size_t offset = x + yOffset;\n      bits_[offset >> logBits] |= 1 << (offset & bitsMask);\n    }\n  }\n}\n\nRef<BitArray> BitMatrix::getRow(int y, Ref<BitArray> row) {\n  if (row.empty() || row->getSize() < width_) {\n    row = new BitArray(width_);\n  } else {\n    row->clear();\n  }\n  size_t start = y * width_;\n  size_t end = start + width_ - 1; // end is inclusive\n  size_t firstWord = start >> logBits;\n  size_t lastWord = end >> logBits;\n  size_t bitOffset = start & bitsMask;\n  for (size_t i = firstWord; i <= lastWord; i++) {\n    size_t firstBit = i > firstWord ? 0 : start & bitsMask;\n    size_t lastBit = i < lastWord ? bitsPerWord - 1 : end & bitsMask;\n    unsigned int mask;\n    if (firstBit == 0 && lastBit == logBits) {\n      mask = std::numeric_limits<unsigned int>::max();\n    } else {\n      mask = 0;\n      for (size_t j = firstBit; j <= lastBit; j++) {\n        mask |= 1 << j;\n      }\n    }\n    row->setBulk((i - firstWord) << logBits, (bits_[i] & mask) >> bitOffset);\n    if (firstBit == 0 && bitOffset != 0) {\n      unsigned int prevBulk = row->getBitArray()[i - firstWord - 1];\n      prevBulk |= (bits_[i] & mask) << (bitsPerWord - bitOffset);\n      row->setBulk((i - firstWord - 1) << logBits, prevBulk);\n    }\n  }\n  return row;\n}\n\nsize_t BitMatrix::getWidth() const {\n  return width_;\n}\n\nsize_t BitMatrix::getHeight() const {\n  return height_;\n}\n\nsize_t BitMatrix::getDimension() const {\n  return width_;\n}\n\nunsigned int* BitMatrix::getBits() const {\n  return bits_;\n}\n\nnamespace zxing {\n  ostream& operator<<(ostream &out, const BitMatrix &bm) {\n    for (size_t y = 0; y < bm.height_; y++) {\n      for (size_t x = 0; x < bm.width_; x++) {\n        out << (bm.get(x, y) ? \"X \" : \"  \");\n      }\n      out << \"\\n\";\n    }\n    return out;\n  }\n}\n\nconst char* BitMatrix::description() {\n  ostringstream out;\n  out << *this;\n  return out.str().c_str();\n}\n\n// file: zxing/common/BitSource.cpp\n\n/*\n *  BitSource.cpp\n *  zxing\n *\n *  Created by Christian Brunschen on 09/05/2008.\n *  Copyright 2008 Google UK. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/common/BitSource.h>\n// #include <zxing/common/IllegalArgumentException.h>\n\nnamespace zxing {\n\nint BitSource::readBits(int numBits) {\n  if (numBits < 0 || numBits > 32) {\n    throw IllegalArgumentException(\"cannot read <1 or >32 bits\");\n  } else if (numBits > available()) {\n    throw IllegalArgumentException(\"reading more bits than are available\");\n  }\n\n  int result = 0;\n\n  // First, read remainder from current byte\n  if (bitOffset_ > 0) {\n    int bitsLeft = 8 - bitOffset_;\n    int toRead = numBits < bitsLeft ? numBits : bitsLeft;\n    int bitsToNotRead = bitsLeft - toRead;\n    int mask = (0xFF >> (8 - toRead)) << bitsToNotRead;\n    result = (bytes_[byteOffset_] & mask) >> bitsToNotRead;\n    numBits -= toRead;\n    bitOffset_ += toRead;\n    if (bitOffset_ == 8) {\n      bitOffset_ = 0;\n      byteOffset_++;\n    }\n  }\n\n  // Next read whole bytes\n  if (numBits > 0) {\n    while (numBits >= 8) {\n      result = (result << 8) | (bytes_[byteOffset_] & 0xFF);\n      byteOffset_++;\n      numBits -= 8;\n    }\n\n\n    // Finally read a partial byte\n    if (numBits > 0) {\n      int bitsToNotRead = 8 - numBits;\n      int mask = (0xFF >> bitsToNotRead) << bitsToNotRead;\n      result = (result << numBits) | ((bytes_[byteOffset_] & mask) >> bitsToNotRead);\n      bitOffset_ += numBits;\n    }\n  }\n\n  return result;\n}\n\nint BitSource::available() {\n  return (int)(8 * (bytes_.size() - byteOffset_) - bitOffset_);\n}\n}\n\n// file: zxing/common/CharacterSetECI.cpp\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n/*\n * Copyright 2008-2011 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/common/CharacterSetECI.h>\n// #include <sstream>\n// #include <zxing/common/IllegalArgumentException.h>\n\nusing std::string;\n\nusing zxing::common::CharacterSetECI;\nusing zxing::IllegalArgumentException;\n\nstd::map<int, CharacterSetECI*> CharacterSetECI::VALUE_TO_ECI;\nstd::map<std::string, CharacterSetECI*> CharacterSetECI::NAME_TO_ECI;\n\nconst bool CharacterSetECI::inited = CharacterSetECI::init_tables();\n\nbool CharacterSetECI::init_tables() {\n  addCharacterSet(0, \"Cp437\");\n  { char const* s[] = {\"ISO8859_1\", \"ISO-8859-1\", 0};\n    addCharacterSet(1, s); }\n  addCharacterSet(2, \"Cp437\");\n  { char const* s[] = {\"ISO8859_1\", \"ISO-8859-1\", 0};\n    addCharacterSet(3, s); }\n  addCharacterSet(4, \"ISO8859_2\");\n  addCharacterSet(5, \"ISO8859_3\");\n  addCharacterSet(6, \"ISO8859_4\");\n  addCharacterSet(7, \"ISO8859_5\");\n  addCharacterSet(8, \"ISO8859_6\");\n  addCharacterSet(9, \"ISO8859_7\");\n  addCharacterSet(10, \"ISO8859_8\");\n  addCharacterSet(11, \"ISO8859_9\");\n  addCharacterSet(12, \"ISO8859_10\");\n  addCharacterSet(13, \"ISO8859_11\");\n  addCharacterSet(15, \"ISO8859_13\");\n  addCharacterSet(16, \"ISO8859_14\");\n  addCharacterSet(17, \"ISO8859_15\");\n  addCharacterSet(18, \"ISO8859_16\");\n  { char const* s[] = {\"SJIS\", \"Shift_JIS\", 0};\n    addCharacterSet(20, s ); }\n  return true;\n}\n\nCharacterSetECI::CharacterSetECI(int value, char const* encodingName_)\n  : ECI(value), encodingName(encodingName_) {}\n\nchar const* CharacterSetECI::getEncodingName() {\n  return encodingName;\n}\n\nvoid CharacterSetECI::addCharacterSet(int value, char const* encodingName) {\n  CharacterSetECI* eci = new CharacterSetECI(value, encodingName);\n  VALUE_TO_ECI[value] = eci; // can't use valueOf\n  NAME_TO_ECI[string(encodingName)] = eci;\n}\n\nvoid CharacterSetECI::addCharacterSet(int value, char const* const* encodingNames) {\n  CharacterSetECI* eci = new CharacterSetECI(value, encodingNames[0]);\n  VALUE_TO_ECI[value] = eci;\n  for (int i = 0; encodingNames[i]; i++) {\n    NAME_TO_ECI[string(encodingNames[i])] = eci;\n  }\n}\n\nCharacterSetECI* CharacterSetECI::getCharacterSetECIByValue(int value) {\n  if (value < 0 || value >= 900) {\n    std::ostringstream oss;\n    oss << \"Bad ECI value: \" << value;\n    throw IllegalArgumentException(oss.str().c_str());\n  }\n  return VALUE_TO_ECI[value];\n}\n\nCharacterSetECI* CharacterSetECI::getCharacterSetECIByName(string const& name) {\n  return NAME_TO_ECI[name];\n}\n\n// file: zxing/common/Counted.cpp\n\n/*\n *  Counted.cpp\n *  zxing\n *\n *  Created by Christian Brunschen on 07/05/2008.\n *  Copyright 2008 Google UK. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/common/Counted.h>\n\nnamespace zxing {\n\nusing namespace std;\n\ntemplate<class T>\nostream& operator<<(ostream &out, Ref<T>& ref) {\n  out << \"Ref(\" << (ref.object_ ? (*ref.object_) : \"NULL\") << \")\";\n  return out;\n}\n}\n\n// file: zxing/common/DecoderResult.cpp\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n/*\n *  DecoderResult.cpp\n *  zxing\n *\n *  Created by Christian Brunschen on 20/05/2008.\n *  Copyright 2008-2011 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/common/DecoderResult.h>\n\nusing namespace std;\nusing namespace zxing;\n\nDecoderResult::DecoderResult(ArrayRef<unsigned char> rawBytes,\n                             Ref<String> text,\n                             ArrayRef< ArrayRef<unsigned char> >& byteSegments,\n                             string const& ecLevel) :\n  rawBytes_(rawBytes),\n  text_(text),\n  byteSegments_(byteSegments),\n  ecLevel_(ecLevel) {}\n\nDecoderResult::DecoderResult(ArrayRef<unsigned char> rawBytes,\n                             Ref<String> text)\n  : rawBytes_(rawBytes), text_(text) {}\n\nArrayRef<unsigned char> DecoderResult::getRawBytes() {\n  return rawBytes_;\n}\n\nRef<String> DecoderResult::getText() {\n  return text_;\n}\n\n// file: zxing/common/DetectorResult.cpp\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n/*\n *  DetectorResult.cpp\n *  zxing\n *\n *  Created by Christian Brunschen on 14/05/2008.\n *  Copyright 2008 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/common/DetectorResult.h>\n\nnamespace zxing {\n\nDetectorResult::DetectorResult(Ref<BitMatrix> bits, std::vector<Ref<ResultPoint> > points, Ref<PerspectiveTransform> transform) :\n  bits_(bits), points_(points), transform_(transform) {\n}\n\nRef<BitMatrix> DetectorResult::getBits() {\n  return bits_;\n}\n\nstd::vector<Ref<ResultPoint> > DetectorResult::getPoints() {\n  return points_;\n}\n\nRef<PerspectiveTransform> DetectorResult::getTransform() {\n  return transform_;\n}\n\n}\n\n// file: zxing/common/ECI.cpp\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n/*\n * Copyright 2008-2011 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/common/ECI.h>\n// #include <sstream>\n// #include <zxing/common/CharacterSetECI.h>\n// #include <zxing/common/IllegalArgumentException.h>\n\nusing zxing::common::ECI;\nusing zxing::IllegalArgumentException;\n\nECI::ECI(int value_) : value(value_) {}\n\nint ECI::getValue() const {\n  return value;\n}\n\nECI* ECI::getECIByValue(int value) {\n  if (value < 0 || value > 999999) {\n    std::ostringstream oss;\n    oss << \"Bad ECI value: \" << value;\n    throw IllegalArgumentException(oss.str().c_str());\n  }\n  if (value < 900) { // Character set ECIs use 000000 - 000899\n    return CharacterSetECI::getCharacterSetECIByValue(value);\n  }\n  return 0;\n}\n\n// file: zxing/common/EdgeDetector.cpp\n\n/*\n *  EdgeDetector.cpp\n *  zxing\n *\n *  Created by Ralf Kistner on 7/12/2009.\n *  Copyright 2008 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/common/EdgeDetector.h>\n// #include <algorithm>\n// #include <cmath>\n\nusing namespace std;\n\nnamespace zxing {\nnamespace EdgeDetector {\n\nvoid findEdgePoints(std::vector<Point>& points, const BitMatrix& image, Point start, Point end, bool invert, int skip, float deviation) {\n  float xdist = end.x - start.x;\n  float ydist = end.y - start.y;\n  float length = sqrt(xdist * xdist + ydist * ydist);\n\n\n  int var;\n\n  if (abs(xdist) > abs(ydist)) {\n    // Horizontal\n    if (xdist < 0)\n      skip = -skip;\n\n    var = int(abs(deviation * length / xdist));\n\n    float dy = ydist / xdist * skip;\n    bool left = (skip < 0) ^ invert;\n    int x = int(start.x);\n\n    int steps = int(xdist / skip);\n    for (int i = 0; i < steps; i++) {\n      x += skip;\n      if (x < 0 || x >= (int)image.getWidth())\n        continue; // In case we start off the edge\n      int my = int(start.y + dy * i);\n      int ey = min(my + var + 1, (int)image.getHeight() - 1);\n      int sy = max(my - var, 0);\n      for (int y = sy + 1; y < ey; y++) {\n        if (left) {\n          if (image.get(x, y) && !image.get(x, y + 1)) {\n            points.push_back(Point(x, y + 0.5f));\n          }\n        } else {\n          if (!image.get(x, y) && image.get(x, y + 1)) {\n            points.push_back(Point(x, y + 0.5f));\n          }\n        }\n      }\n    }\n  } else {\n    // Vertical\n    if (ydist < 0)\n      skip = -skip;\n\n    var = int(abs(deviation * length / ydist));\n\n    float dx = xdist / ydist * skip;\n    bool down = (skip > 0) ^ invert;\n    int y = int(start.y);\n\n    int steps = int(ydist / skip);\n    for (int i = 0; i < steps; i++) {\n      y += skip;\n      if (y < 0 || y >= (int)image.getHeight())\n        continue; // In case we start off the edge\n      int mx = int(start.x + dx * i);\n      int ex = min(mx + var + 1, (int)image.getWidth() - 1);\n      int sx = max(mx - var, 0);\n      for (int x = sx + 1; x < ex; x++) {\n        if (down) {\n          if (image.get(x, y) && !image.get(x + 1, y)) {\n            points.push_back(Point(x + 0.5f, y));\n          }\n\n        } else {\n          if (!image.get(x, y) && image.get(x + 1, y)) {\n            points.push_back(Point(x + 0.5f, y));\n          }\n        }\n\n      }\n    }\n\n  }\n}\n\nLine findLine(const BitMatrix& image, Line estimate, bool invert, int deviation, float threshold, int skip) {\n  float t = threshold * threshold;\n\n  Point start = estimate.start;\n  Point end = estimate.end;\n\n  vector<Point> edges;\n  edges.clear();\n  findEdgePoints(edges, image, start, end, invert, skip, deviation);\n\n  int n = (int)edges.size();\n\n  float xdist = end.x - start.x;\n  float ydist = end.y - start.y;\n\n  bool horizontal = abs(xdist) > abs(ydist);\n\n  float max = 0;\n  Line bestLine(start, end);  // prepopulate with the given line, in case we can't find any line for some reason\n\n  for (int i = -deviation; i < deviation; i++) {\n    float x1, y1;\n    if (horizontal) {\n      y1 = start.y + i;\n      x1 = start.x - i * ydist / xdist;\n    } else {\n      y1 = start.y - i * xdist / ydist;\n      x1 = start.x + i;\n    }\n\n    for (int j = -deviation; j < deviation; j++) {\n      float x2, y2;\n      if (horizontal) {\n        y2 = end.y + j;\n        x2 = end.x - j * ydist / xdist;\n      } else {\n        y2 = end.y - j * xdist / ydist;\n        x2 = end.x + j;\n      }\n\n      float dx = x1 - x2;\n      float dy = y1 - y2;\n      float length = sqrt(dx * dx + dy * dy);\n\n      float score = 0;\n\n      for(int k = 0; k < n; k++) {\n        const Point& edge = edges[k];\n        float dist = ((x1 - edge.x) * dy - (y1 - edge.y) * dx) / length;\n        // Similar to least squares method\n        float s = t - dist * dist;\n        if (s > 0)\n          score += s;\n      }\n\n      if (score > max) {\n        max = score;\n        bestLine.start = Point(x1, y1);\n        bestLine.end = Point(x2, y2);\n      }\n    }\n  }\n\n  return bestLine;\n}\n\nPoint intersection(Line a, Line b) {\n  float dxa = a.start.x - a.end.x;\n  float dxb = b.start.x - b.end.x;\n  float dya = a.start.y - a.end.y;\n  float dyb = b.start.y - b.end.y;\n\n  float p = a.start.x * a.end.y - a.start.y * a.end.x;\n  float q = b.start.x * b.end.y - b.start.y * b.end.x;\n  float denom = dxa * dyb - dya * dxb;\n  if(denom == 0)  // Lines don't intersect\n    return Point(INFINITY, INFINITY);\n\n  float x = (p * dxb - dxa * q) / denom;\n  float y = (p * dyb - dya * q) / denom;\n\n  return Point(x, y);\n}\n\n} // namespace EdgeDetector\n} // namespace zxing\n\n// file: zxing/common/GlobalHistogramBinarizer.cpp\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n/*\n *  GlobalHistogramBinarizer.cpp\n *  zxing\n *\n *  Copyright 2010 ZXing authors. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/common/GlobalHistogramBinarizer.h>\n// #include <zxing/common/IllegalArgumentException.h>\n// #include <zxing/common/Array.h>\n\nnamespace zxing {\nusing namespace std;\n\nconst int LUMINANCE_BITS_25 = 5;\nconst int LUMINANCE_SHIFT_25 = 8 - LUMINANCE_BITS_25;\nconst int LUMINANCE_BUCKETS_25 = 1 << LUMINANCE_BITS_25;\n\nGlobalHistogramBinarizer::GlobalHistogramBinarizer(Ref<LuminanceSource> source) :\n  Binarizer(source), cached_matrix_(NULL), cached_row_(NULL), cached_row_num_(-1) {\n\n}\n\nGlobalHistogramBinarizer::~GlobalHistogramBinarizer() {\n}\n\n\nRef<BitArray> GlobalHistogramBinarizer::getBlackRow(int y, Ref<BitArray> row) {\n  if (y == cached_row_num_) {\n    if (cached_row_ != NULL) {\n      return cached_row_;\n    } else {\n      throw IllegalArgumentException(\"Too little dynamic range in luminance\");\n    }\n  }\n\n  vector<int> histogram(LUMINANCE_BUCKETS_25, 0);\n  LuminanceSource& source = *getLuminanceSource();\n  int width = source.getWidth();\n  if (row == NULL || static_cast<int>(row->getSize()) < width) {\n    row = new BitArray(width);\n  } else {\n    row->clear();\n  }\n\n  //TODO(flyashi): cache this instead of allocating and deleting per row\n  unsigned char* row_pixels = NULL;\n  try {\n    row_pixels = new unsigned char[width];\n    row_pixels = source.getRow(y, row_pixels);\n    for (int x = 0; x < width; x++) {\n      histogram[row_pixels[x] >> LUMINANCE_SHIFT_25]++;\n    }\n    int blackPoint = estimate(histogram);\n\n    BitArray& array = *row;\n    int left = row_pixels[0];\n    int center = row_pixels[1];\n    for (int x = 1; x < width - 1; x++) {\n      int right = row_pixels[x + 1];\n      // A simple -1 4 -1 box filter with a weight of 2.\n      int luminance = ((center << 2) - left - right) >> 1;\n      if (luminance < blackPoint) {\n        array.set(x);\n      }\n      left = center;\n      center = right;\n    }\n\n    cached_row_ = row;\n    cached_row_num_ = y;\n    delete [] row_pixels;\n    return row;\n  } catch (IllegalArgumentException const& iae) {\n    // Cache the fact that this row failed.\n    cached_row_ = NULL;\n    cached_row_num_ = y;\n    delete [] row_pixels;\n    throw iae;\n  }\n}\n\nRef<BitMatrix> GlobalHistogramBinarizer::getBlackMatrix() {\n  if (cached_matrix_ != NULL) {\n    return cached_matrix_;\n  }\n\n  // Faster than working with the reference\n  LuminanceSource& source = *getLuminanceSource();\n  int width = source.getWidth();\n  int height = source.getHeight();\n  vector<int> histogram(LUMINANCE_BUCKETS_25, 0);\n\n  // Quickly calculates the histogram by sampling four rows from the image.\n  // This proved to be more robust on the blackbox tests than sampling a\n  // diagonal as we used to do.\n  ArrayRef<unsigned char> ref (width);\n  unsigned char* row = &ref[0];\n  for (int y = 1; y < 5; y++) {\n    int rownum = height * y / 5;\n    int right = (width << 2) / 5;\n    row = source.getRow(rownum, row);\n    for (int x = width / 5; x < right; x++) {\n      histogram[row[x] >> LUMINANCE_SHIFT_25]++;\n    }\n  }\n\n  int blackPoint = estimate(histogram);\n\n  Ref<BitMatrix> matrix_ref(new BitMatrix(width, height));\n  BitMatrix& matrix = *matrix_ref;\n  for (int y = 0; y < height; y++) {\n    row = source.getRow(y, row);\n    for (int x = 0; x < width; x++) {\n      if (row[x] < blackPoint)\n        matrix.set(x, y);\n    }\n  }\n\n  cached_matrix_ = matrix_ref;\n  // delete [] row;\n  return matrix_ref;\n}\n\nint GlobalHistogramBinarizer::estimate(vector<int> &histogram) {\n  int numBuckets = (int)histogram.size();\n  int maxBucketCount = 0;\n\n  // Find tallest peak in histogram\n  int firstPeak = 0;\n  int firstPeakSize = 0;\n  for (int i = 0; i < numBuckets; i++) {\n    if (histogram[i] > firstPeakSize) {\n      firstPeak = i;\n      firstPeakSize = histogram[i];\n    }\n    if (histogram[i] > maxBucketCount) {\n      maxBucketCount = histogram[i];\n    }\n  }\n\n  // Find second-tallest peak -- well, another peak that is tall and not\n  // so close to the first one\n  int secondPeak = 0;\n  int secondPeakScore = 0;\n  for (int i = 0; i < numBuckets; i++) {\n    int distanceToBiggest = i - firstPeak;\n    // Encourage more distant second peaks by multiplying by square of distance\n    int score = histogram[i] * distanceToBiggest * distanceToBiggest;\n    if (score > secondPeakScore) {\n      secondPeak = i;\n      secondPeakScore = score;\n    }\n  }\n\n  // Put firstPeak first\n  if (firstPeak > secondPeak) {\n    int temp = firstPeak;\n    firstPeak = secondPeak;\n    secondPeak = temp;\n  }\n\n  // Kind of arbitrary; if the two peaks are very close, then we figure there is\n  // so little dynamic range in the image, that discriminating black and white\n  // is too error-prone.\n  // Decoding the image/line is either pointless, or may in some cases lead to\n  // a false positive for 1D formats, which are relatively lenient.\n  // We arbitrarily say \"close\" is\n  // \"<= 1/16 of the total histogram buckets apart\"\n  if (secondPeak - firstPeak <= numBuckets >> 4) {\n    throw IllegalArgumentException(\"Too little dynamic range in luminance\");\n  }\n\n  // Find a valley between them that is low and closer to the white peak\n  int bestValley = secondPeak - 1;\n  int bestValleyScore = -1;\n  for (int i = secondPeak - 1; i > firstPeak; i--) {\n    int fromFirst = i - firstPeak;\n    // Favor a \"valley\" that is not too close to either peak -- especially not\n    // the black peak -- and that has a low value of course\n    int score = fromFirst * fromFirst * (secondPeak - i) *\n      (maxBucketCount - histogram[i]);\n    if (score > bestValleyScore) {\n      bestValley = i;\n      bestValleyScore = score;\n    }\n  }\n\n  return bestValley << LUMINANCE_SHIFT_25;\n}\n\nRef<Binarizer> GlobalHistogramBinarizer::createBinarizer(Ref<LuminanceSource> source) {\n  return Ref<Binarizer> (new GlobalHistogramBinarizer(source));\n}\n\n} // namespace zxing\n\n// file: zxing/common/GreyscaleLuminanceSource.cpp\n\n/*\n *  GreyscaleLuminanceSource.cpp\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/common/GreyscaleLuminanceSource.h>\n// #include <zxing/common/GreyscaleRotatedLuminanceSource.h>\n// #include <zxing/common/IllegalArgumentException.h>\n\nnamespace zxing {\n\nGreyscaleLuminanceSource::GreyscaleLuminanceSource(unsigned char* greyData, int dataWidth,\n    int dataHeight, int left, int top, int width, int height) : greyData_(greyData),\n    dataWidth_(dataWidth), dataHeight_(dataHeight), left_(left), top_(top), width_(width),\n    height_(height) {\n\n  if (left + width > dataWidth || top + height > dataHeight || top < 0 || left < 0) {\n    throw IllegalArgumentException(\"Crop rectangle does not fit within image data.\");\n  }\n}\n\nunsigned char* GreyscaleLuminanceSource::getRow(int y, unsigned char* row) {\n  if (y < 0 || y >= this->getHeight()) {\n    throw IllegalArgumentException(\"Requested row is outside the image.\");\n  }\n  int width = getWidth();\n  // TODO(flyashi): determine if row has enough size.\n  if (row == NULL) {\n    row = new unsigned char[width_];\n  }\n  int offset = (y + top_) * dataWidth_ + left_;\n  memcpy(row, &greyData_[offset], width);\n  return row;\n}\n\nunsigned char* GreyscaleLuminanceSource::getMatrix() {\n  int size = width_ * height_;\n  unsigned char* result = new unsigned char[size];\n  if (left_ == 0 && top_ == 0 && dataWidth_ == width_ && dataHeight_ == height_) {\n    memcpy(result, greyData_, size);\n  } else {\n    for (int row = 0; row < height_; row++) {\n      memcpy(result + row * width_, greyData_ + (top_ + row) * dataWidth_ + left_, width_);\n    }\n  }\n  return result;\n}\n\nRef<LuminanceSource> GreyscaleLuminanceSource::rotateCounterClockwise() {\n  // Intentionally flip the left, top, width, and height arguments as needed. dataWidth and\n  // dataHeight are always kept unrotated.\n  return Ref<LuminanceSource> (new GreyscaleRotatedLuminanceSource(greyData_, dataWidth_,\n      dataHeight_, top_, left_, height_, width_));\n}\n\n} /* namespace */\n\n// file: zxing/common/GreyscaleRotatedLuminanceSource.cpp\n\n/*\n *  GreyscaleRotatedLuminanceSource.cpp\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\n// #include <zxing/common/GreyscaleRotatedLuminanceSource.h>\n// #include <zxing/common/IllegalArgumentException.h>\n\nnamespace zxing {\n\n// Note that dataWidth and dataHeight are not reversed, as we need to be able to traverse the\n// greyData correctly, which does not get rotated.\nGreyscaleRotatedLuminanceSource::GreyscaleRotatedLuminanceSource(unsigned char* greyData,\n    int dataWidth, int dataHeight, int left, int top, int width, int height) : greyData_(greyData),\n    dataWidth_(dataWidth), dataHeight_(dataHeight), left_(left), top_(top), width_(width),\n    height_(height) {\n\n  // Intentionally comparing to the opposite dimension since we're rotated.\n  if (left + width > dataHeight || top + height > dataWidth) {\n    throw IllegalArgumentException(\"Crop rectangle does not fit within image data.\");\n  }\n}\n\n// The API asks for rows, but we're rotated, so we return columns.\nunsigned char* GreyscaleRotatedLuminanceSource::getRow(int y, unsigned char* row) {\n  if (y < 0 || y >= getHeight()) {\n    throw IllegalArgumentException(\"Requested row is outside the image\");\n  }\n  int width = getWidth();\n  if (row == NULL) {\n    row = new unsigned char[width];\n  }\n  int offset = (left_ * dataWidth_) + (dataWidth_ - (y + top_));\n  for (int x = 0; x < width; x++) {\n    row[x] = greyData_[offset];\n    offset += dataWidth_;\n  }\n  return row;\n}\n\nunsigned char* GreyscaleRotatedLuminanceSource::getMatrix() {\n  unsigned char* result = new unsigned char[width_ * height_];\n  // This depends on getRow() honoring its second parameter.\n  for (int y = 0; y < height_; y++) {\n    getRow(y, &result[y * width_]);\n  }\n  return result;\n}\n\n} // namespace\n\n// file: zxing/common/GridSampler.cpp\n\n/*\n *  GridSampler.cpp\n *  zxing\n *\n *  Created by Christian Brunschen on 18/05/2008.\n *  Copyright 2008 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/common/GridSampler.h>\n// #include <zxing/common/PerspectiveTransform.h>\n// #include <zxing/ReaderException.h>\n// #include <iostream>\n// #include <sstream>\n\nnamespace zxing {\nusing namespace std;\n\nGridSampler GridSampler::gridSampler;\n\nGridSampler::GridSampler() {\n}\n\nRef<BitMatrix> GridSampler::sampleGrid(Ref<BitMatrix> image, int dimension, Ref<PerspectiveTransform> transform) {\n  Ref<BitMatrix> bits(new BitMatrix(dimension));\n  vector<float> points(dimension << 1, (const float)0.0f);\n  for (int y = 0; y < dimension; y++) {\n    int max = (int)points.size();\n    float yValue = (float)y + 0.5f;\n    for (int x = 0; x < max; x += 2) {\n      points[x] = (float)(x >> 1) + 0.5f;\n      points[x + 1] = yValue;\n    }\n    transform->transformPoints(points);\n    checkAndNudgePoints(image, points);\n    for (int x = 0; x < max; x += 2) {\n      if (image->get((int)points[x], (int)points[x + 1])) {\n        bits->set(x >> 1, y);\n      }\n    }\n  }\n  return bits;\n}\n\nRef<BitMatrix> GridSampler::sampleGrid(Ref<BitMatrix> image, int dimensionX, int dimensionY, Ref<PerspectiveTransform> transform) {\n  Ref<BitMatrix> bits(new BitMatrix(dimensionX, dimensionY));\n  vector<float> points(dimensionX << 1, (const float)0.0f);\n  for (int y = 0; y < dimensionY; y++) {\n    int max = (int)points.size();\n    float yValue = (float)y + 0.5f;\n    for (int x = 0; x < max; x += 2) {\n      points[x] = (float)(x >> 1) + 0.5f;\n      points[x + 1] = yValue;\n    }\n    transform->transformPoints(points);\n    checkAndNudgePoints(image, points);\n    for (int x = 0; x < max; x += 2) {\n      if (image->get((int)points[x], (int)points[x + 1])) {\n        bits->set(x >> 1, y);\n      }\n    }\n  }\n  return bits;\n}\n\nRef<BitMatrix> GridSampler::sampleGrid(Ref<BitMatrix> image, int dimension, float p1ToX, float p1ToY, float p2ToX,\n                                       float p2ToY, float p3ToX, float p3ToY, float p4ToX, float p4ToY, float p1FromX, float p1FromY, float p2FromX,\n                                       float p2FromY, float p3FromX, float p3FromY, float p4FromX, float p4FromY) {\n  Ref<PerspectiveTransform> transform(PerspectiveTransform::quadrilateralToQuadrilateral(p1ToX, p1ToY, p2ToX, p2ToY,\n                                      p3ToX, p3ToY, p4ToX, p4ToY, p1FromX, p1FromY, p2FromX, p2FromY, p3FromX, p3FromY, p4FromX, p4FromY));\n\n  return sampleGrid(image, dimension, transform);\n\n}\n\nvoid GridSampler::checkAndNudgePoints(Ref<BitMatrix> image, vector<float> &points) {\n  int width = (int)image->getWidth();\n  int height = (int)image->getHeight();\n\n\n  // The Java code assumes that if the start and end points are in bounds, the rest will also be.\n  // However, in some unusual cases points in the middle may also be out of bounds.\n  // Since we can't rely on an ArrayIndexOutOfBoundsException like Java, we check every point.\n\n  for (size_t offset = 0; offset < points.size(); offset += 2) {\n    int x = (int)points[offset];\n    int y = (int)points[offset + 1];\n    if (x < -1 || x > width || y < -1 || y > height) {\n      ostringstream s;\n      s << \"Transformed point out of bounds at \" << x << \",\" << y;\n      throw ReaderException(s.str().c_str());\n    }\n\n    if (x == -1) {\n      points[offset] = 0.0f;\n    } else if (x == width) {\n      points[offset] = width - 1;\n    }\n    if (y == -1) {\n      points[offset + 1] = 0.0f;\n    } else if (y == height) {\n      points[offset + 1] = height - 1;\n    }\n  }\n\n}\n\nGridSampler &GridSampler::getInstance() {\n  return gridSampler;\n}\n}\n\n// file: zxing/common/HybridBinarizer.cpp\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n/*\n *  HybridBinarizer.cpp\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/common/HybridBinarizer.h>\n\n// #include <zxing/common/IllegalArgumentException.h>\n\nusing namespace std;\nusing namespace zxing;\n\nnamespace {\n  const int BLOCK_SIZE_POWER = 3;\n  const int BLOCK_SIZE = 1 << BLOCK_SIZE_POWER;\n  const int BLOCK_SIZE_MASK = BLOCK_SIZE - 1;\n  const int MINIMUM_DIMENSION = BLOCK_SIZE * 5;\n}\n\nHybridBinarizer::HybridBinarizer(Ref<LuminanceSource> source) :\n  GlobalHistogramBinarizer(source), matrix_(NULL), cached_row_(NULL), cached_row_num_(-1) {\n}\n\nHybridBinarizer::~HybridBinarizer() {\n}\n\n\nRef<Binarizer>\nHybridBinarizer::createBinarizer(Ref<LuminanceSource> source) {\n  return Ref<Binarizer> (new HybridBinarizer(source));\n}\n\nRef<BitMatrix> HybridBinarizer::getBlackMatrix() {\n  // Calculates the final BitMatrix once for all requests. This could\n  // be called once from the constructor instead, but there are some\n  // advantages to doing it lazily, such as making profiling easier,\n  // and not doing heavy lifting when callers don't expect it.\n  if (matrix_) {\n    return matrix_;\n  }\n  LuminanceSource& source = *getLuminanceSource();\n  if (source.getWidth() >= MINIMUM_DIMENSION &&\n      source.getHeight() >= MINIMUM_DIMENSION) {\n    unsigned char* luminances = source.getMatrix();\n    int width = source.getWidth();\n    int height = source.getHeight();\n    int subWidth = width >> BLOCK_SIZE_POWER;\n    if ((width & BLOCK_SIZE_MASK) != 0) {\n      subWidth++;\n    }\n    int subHeight = height >> BLOCK_SIZE_POWER;\n    if ((height & BLOCK_SIZE_MASK) != 0) {\n      subHeight++;\n    }\n    int* blackPoints =\n      calculateBlackPoints(luminances, subWidth, subHeight, width, height);\n\n    Ref<BitMatrix> newMatrix (new BitMatrix(width, height));\n    calculateThresholdForBlock(luminances,\n                               subWidth,\n                               subHeight,\n                               width,\n                               height,\n                               blackPoints,\n                               newMatrix);\n    matrix_ = newMatrix;\n\n    // N.B.: these deletes are inadequate if anything between the new\n    // and this point can throw.  As of this writing, it doesn't look\n    // like they do.\n\n    delete [] blackPoints;\n    delete [] luminances;\n  } else {\n    // If the image is too small, fall back to the global histogram approach.\n    matrix_ = GlobalHistogramBinarizer::getBlackMatrix();\n  }\n  return matrix_;\n}\n\nvoid\nHybridBinarizer::calculateThresholdForBlock(unsigned char* luminances,\n                                            int subWidth,\n                                            int subHeight,\n                                            int width,\n                                            int height,\n                                            int blackPoints[],\n                                            Ref<BitMatrix> const& matrix) {\n  for (int y = 0; y < subHeight; y++) {\n    int yoffset = y << BLOCK_SIZE_POWER;\n    if (yoffset + BLOCK_SIZE >= height) {\n      yoffset = height - BLOCK_SIZE;\n    }\n    for (int x = 0; x < subWidth; x++) {\n      int xoffset = x << BLOCK_SIZE_POWER;\n      if (xoffset + BLOCK_SIZE >= width) {\n        xoffset = width - BLOCK_SIZE;\n      }\n      int left = (x > 1) ? x : 2;\n      left = (left < subWidth - 2) ? left : subWidth - 3;\n      int top = (y > 1) ? y : 2;\n      top = (top < subHeight - 2) ? top : subHeight - 3;\n      int sum = 0;\n      for (int z = -2; z <= 2; z++) {\n        int *blackRow = &blackPoints[(top + z) * subWidth];\n        sum += blackRow[left - 2];\n        sum += blackRow[left - 1];\n        sum += blackRow[left];\n        sum += blackRow[left + 1];\n        sum += blackRow[left + 2];\n      }\n      int average = sum / 25;\n      threshold8x8Block(luminances, xoffset, yoffset, average, width, matrix);\n    }\n  }\n}\n\nvoid HybridBinarizer::threshold8x8Block(unsigned char* luminances,\n                                        int xoffset,\n                                        int yoffset,\n                                        int threshold,\n                                        int stride,\n                                        Ref<BitMatrix> const& matrix) {\n  for (int y = 0, offset = yoffset * stride + xoffset;\n       y < BLOCK_SIZE;\n       y++,  offset += stride) {\n    for (int x = 0; x < BLOCK_SIZE; x++) {\n      int pixel = luminances[offset + x] & 0xff;\n      if (pixel <= threshold) {\n        matrix->set(xoffset + x, yoffset + y);\n      }\n    }\n  }\n}\n\nnamespace {\n  inline int getBlackPointFromNeighbors(int* blackPoints, int subWidth, int x, int y) {\n    return (blackPoints[(y-1)*subWidth+x] +\n            2*blackPoints[y*subWidth+x-1] +\n            blackPoints[(y-1)*subWidth+x-1]) >> 2;\n  }\n}\n\nint* HybridBinarizer::calculateBlackPoints(unsigned char* luminances, int subWidth, int subHeight,\n    int width, int height) {\n  int *blackPoints = new int[subHeight * subWidth];\n  for (int y = 0; y < subHeight; y++) {\n    int yoffset = y << BLOCK_SIZE_POWER;\n    if (yoffset + BLOCK_SIZE >= height) {\n      yoffset = height - BLOCK_SIZE;\n    }\n    for (int x = 0; x < subWidth; x++) {\n      int xoffset = x << BLOCK_SIZE_POWER;\n      if (xoffset + BLOCK_SIZE >= width) {\n        xoffset = width - BLOCK_SIZE;\n      }\n      int sum = 0;\n      int min = 0xFF;\n      int max = 0;\n      for (int yy = 0, offset = yoffset * width + xoffset;\n           yy < BLOCK_SIZE;\n           yy++, offset += width) {\n        for (int xx = 0; xx < BLOCK_SIZE; xx++) {\n          int pixel = luminances[offset + xx] & 0xFF;\n          sum += pixel;\n          if (pixel < min) {\n            min = pixel;\n          }\n          if (pixel > max) {\n            max = pixel;\n          }\n        }\n      }\n\n      // See\n      // http://groups.google.com/group/zxing/browse_thread/thread/d06efa2c35a7ddc0\n      int average = sum >> 6;\n      if (max - min <= 24) {\n        average = min >> 1;\n        if (y > 0 && x > 0) {\n          int bp = getBlackPointFromNeighbors(blackPoints, subWidth, x, y);\n          if (min < bp) {\n            average = bp;\n          }\n        }\n      }\n      blackPoints[y * subWidth + x] = average;\n    }\n  }\n  return blackPoints;\n}\n\n\n// file: zxing/common/IllegalArgumentException.cpp\n\n/*\n *  IllegalArgumentException.cpp\n *  zxing\n *\n *  Created by Christian Brunschen on 06/05/2008.\n *  Copyright 2008 Google UK. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/common/IllegalArgumentException.h>\n\nnamespace zxing {\n\nIllegalArgumentException::IllegalArgumentException(const char *msg) :\n    Exception(msg) {\n}\nIllegalArgumentException::~IllegalArgumentException() throw() {\n\n}\n}\n\n// file: zxing/common/PerspectiveTransform.cpp\n\n/*\n *  PerspectiveTransform.cpp\n *  zxing\n *\n *  Created by Christian Brunschen on 12/05/2008.\n *  Copyright 2008 Google UK. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/common/PerspectiveTransform.h>\n\nnamespace zxing {\nusing namespace std;\n\nPerspectiveTransform::PerspectiveTransform(float inA11, float inA21,\n                                           float inA31, float inA12,\n                                           float inA22, float inA32,\n                                           float inA13, float inA23,\n                                           float inA33) :\n  a11(inA11), a12(inA12), a13(inA13), a21(inA21), a22(inA22), a23(inA23),\n  a31(inA31), a32(inA32), a33(inA33) {}\n\nRef<PerspectiveTransform> PerspectiveTransform::quadrilateralToQuadrilateral(float x0, float y0, float x1, float y1,\n    float x2, float y2, float x3, float y3, float x0p, float y0p, float x1p, float y1p, float x2p, float y2p,\n    float x3p, float y3p) {\n  Ref<PerspectiveTransform> qToS = PerspectiveTransform::quadrilateralToSquare(x0, y0, x1, y1, x2, y2, x3, y3);\n  Ref<PerspectiveTransform> sToQ =\n    PerspectiveTransform::squareToQuadrilateral(x0p, y0p, x1p, y1p, x2p, y2p, x3p, y3p);\n  return sToQ->times(qToS);\n}\n\nRef<PerspectiveTransform> PerspectiveTransform::squareToQuadrilateral(float x0, float y0, float x1, float y1, float x2,\n    float y2, float x3, float y3) {\n  float dy2 = y3 - y2;\n  float dy3 = y0 - y1 + y2 - y3;\n  if (dy2 == 0.0f && dy3 == 0.0f) {\n    Ref<PerspectiveTransform> result(new PerspectiveTransform(x1 - x0, x2 - x1, x0, y1 - y0, y2 - y1, y0, 0.0f,\n                                     0.0f, 1.0f));\n    return result;\n  } else {\n    float dx1 = x1 - x2;\n    float dx2 = x3 - x2;\n    float dx3 = x0 - x1 + x2 - x3;\n    float dy1 = y1 - y2;\n    float denominator = dx1 * dy2 - dx2 * dy1;\n    float a13 = (dx3 * dy2 - dx2 * dy3) / denominator;\n    float a23 = (dx1 * dy3 - dx3 * dy1) / denominator;\n    Ref<PerspectiveTransform> result(new PerspectiveTransform(x1 - x0 + a13 * x1, x3 - x0 + a23 * x3, x0, y1 - y0\n                                     + a13 * y1, y3 - y0 + a23 * y3, y0, a13, a23, 1.0f));\n    return result;\n  }\n}\n\nRef<PerspectiveTransform> PerspectiveTransform::quadrilateralToSquare(float x0, float y0, float x1, float y1, float x2,\n    float y2, float x3, float y3) {\n  // Here, the adjoint serves as the inverse:\n  return squareToQuadrilateral(x0, y0, x1, y1, x2, y2, x3, y3)->buildAdjoint();\n}\n\nRef<PerspectiveTransform> PerspectiveTransform::buildAdjoint() {\n  // Adjoint is the transpose of the cofactor matrix:\n  Ref<PerspectiveTransform> result(new PerspectiveTransform(a22 * a33 - a23 * a32, a23 * a31 - a21 * a33, a21 * a32\n                                   - a22 * a31, a13 * a32 - a12 * a33, a11 * a33 - a13 * a31, a12 * a31 - a11 * a32, a12 * a23 - a13 * a22,\n                                   a13 * a21 - a11 * a23, a11 * a22 - a12 * a21));\n  return result;\n}\n\nRef<PerspectiveTransform> PerspectiveTransform::times(Ref<PerspectiveTransform> other) {\n  Ref<PerspectiveTransform> result(new PerspectiveTransform(a11 * other->a11 + a21 * other->a12 + a31 * other->a13,\n                                   a11 * other->a21 + a21 * other->a22 + a31 * other->a23, a11 * other->a31 + a21 * other->a32 + a31\n                                   * other->a33, a12 * other->a11 + a22 * other->a12 + a32 * other->a13, a12 * other->a21 + a22\n                                   * other->a22 + a32 * other->a23, a12 * other->a31 + a22 * other->a32 + a32 * other->a33, a13\n                                   * other->a11 + a23 * other->a12 + a33 * other->a13, a13 * other->a21 + a23 * other->a22 + a33\n                                   * other->a23, a13 * other->a31 + a23 * other->a32 + a33 * other->a33));\n  return result;\n}\n\nvoid PerspectiveTransform::transformPoints(vector<float> &points) {\n  int max = (int)points.size();\n  for (int i = 0; i < max; i += 2) {\n    float x = points[i];\n    float y = points[i + 1];\n    float denominator = a13 * x + a23 * y + a33;\n    points[i] = (a11 * x + a21 * y + a31) / denominator;\n    points[i + 1] = (a12 * x + a22 * y + a32) / denominator;\n  }\n}\n\nostream& operator<<(ostream& out, const PerspectiveTransform &pt) {\n  out << pt.a11 << \", \" << pt.a12 << \", \" << pt.a13 << \", \\n\";\n  out << pt.a21 << \", \" << pt.a22 << \", \" << pt.a23 << \", \\n\";\n  out << pt.a31 << \", \" << pt.a32 << \", \" << pt.a33 << \"\\n\";\n  return out;\n}\n\n}\n\n// file: zxing/common/Str.cpp\n\n/*\n *  String.cpp\n *  zxing\n *\n *  Created by Christian Brunschen on 20/05/2008.\n *  Copyright 2008 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/common/Str.h>\n\nnamespace zxing {\nusing namespace std;\n\nString::String(const std::string &text) :\n    text_(text) {\n}\nconst std::string& String::getText() const {\n  return text_;\n}\n\nostream &operator<<(ostream &out, const String &s) {\n  out << s.text_;\n  return out;\n}\n\n}\n\n// file: zxing/common/StringUtils.cpp\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n\n/*\n * Copyright (C) 2010-2011 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/common/StringUtils.h>\n// #include <zxing/DecodeHints.h>\n\nusing namespace std;\nusing namespace zxing;\nusing namespace zxing::common;\n\n// N.B.: these are the iconv strings for at least some versions of iconv\n\nchar const* const StringUtils::PLATFORM_DEFAULT_ENCODING = \"UTF-8\";\nchar const* const StringUtils::ASCII = \"ASCII\";\nchar const* const StringUtils::SHIFT_JIS = \"SHIFT_JIS\";\nchar const* const StringUtils::GB2312 = \"GBK\";\nchar const* const StringUtils::EUC_JP = \"EUC-JP\";\nchar const* const StringUtils::UTF8 = \"UTF-8\";\nchar const* const StringUtils::ISO88591 = \"ISO8859-1\";\nconst bool StringUtils::ASSUME_SHIFT_JIS = false;\n\nstring\nStringUtils::guessEncoding(unsigned char* bytes, int length, Hashtable const& hints) {\n  Hashtable::const_iterator i = hints.find(DecodeHints::CHARACTER_SET);\n  if (i != hints.end()) {\n    return i->second;\n  }\n  // Does it start with the UTF-8 byte order mark? then guess it's UTF-8\n  if (length > 3 &&\n      bytes[0] == (unsigned char) 0xEF &&\n      bytes[1] == (unsigned char) 0xBB &&\n      bytes[2] == (unsigned char) 0xBF) {\n    return UTF8;\n  }\n  // For now, merely tries to distinguish ISO-8859-1, UTF-8 and Shift_JIS,\n  // which should be by far the most common encodings. ISO-8859-1\n  // should not have bytes in the 0x80 - 0x9F range, while Shift_JIS\n  // uses this as a first byte of a two-byte character. If we see this\n  // followed by a valid second byte in Shift_JIS, assume it is Shift_JIS.\n  // If we see something else in that second byte, we'll make the risky guess\n  // that it's UTF-8.\n  bool canBeISO88591 = true;\n  bool canBeShiftJIS = true;\n  bool canBeUTF8 = true;\n  int utf8BytesLeft = 0;\n  int maybeDoubleByteCount = 0;\n  int maybeSingleByteKatakanaCount = 0;\n  bool sawLatin1Supplement = false;\n  bool sawUTF8Start = false;\n  bool lastWasPossibleDoubleByteStart = false;\n\n  for (int i = 0;\n       i < length && (canBeISO88591 || canBeShiftJIS || canBeUTF8);\n       i++) {\n\n    int value = bytes[i] & 0xFF;\n\n    // UTF-8 stuff\n    if (value >= 0x80 && value <= 0xBF) {\n      if (utf8BytesLeft > 0) {\n        utf8BytesLeft--;\n      }\n    } else {\n      if (utf8BytesLeft > 0) {\n        canBeUTF8 = false;\n      }\n      if (value >= 0xC0 && value <= 0xFD) {\n        sawUTF8Start = true;\n        int valueCopy = value;\n        while ((valueCopy & 0x40) != 0) {\n          utf8BytesLeft++;\n          valueCopy <<= 1;\n        }\n      }\n    }\n\n    // ISO-8859-1 stuff\n\n    if ((value == 0xC2 || value == 0xC3) && i < length - 1) {\n      // This is really a poor hack. The slightly more exotic characters people might want to put in\n      // a QR Code, by which I mean the Latin-1 supplement characters (e.g. u-umlaut) have encodings\n      // that start with 0xC2 followed by [0xA0,0xBF], or start with 0xC3 followed by [0x80,0xBF].\n      int nextValue = bytes[i + 1] & 0xFF;\n      if (nextValue <= 0xBF &&\n          ((value == 0xC2 && nextValue >= 0xA0) || (value == 0xC3 && nextValue >= 0x80))) {\n        sawLatin1Supplement = true;\n      }\n    }\n    if (value >= 0x7F && value <= 0x9F) {\n      canBeISO88591 = false;\n    }\n\n    // Shift_JIS stuff\n\n    if (value >= 0xA1 && value <= 0xDF) {\n      // count the number of characters that might be a Shift_JIS single-byte Katakana character\n      if (!lastWasPossibleDoubleByteStart) {\n        maybeSingleByteKatakanaCount++;\n      }\n    }\n    if (!lastWasPossibleDoubleByteStart &&\n        ((value >= 0xF0 && value <= 0xFF) || value == 0x80 || value == 0xA0)) {\n      canBeShiftJIS = false;\n    }\n    if ((value >= 0x81 && value <= 0x9F) || (value >= 0xE0 && value <= 0xEF)) {\n      // These start double-byte characters in Shift_JIS. Let's see if it's followed by a valid\n      // second byte.\n      if (lastWasPossibleDoubleByteStart) {\n        // If we just checked this and the last byte for being a valid double-byte\n        // char, don't check starting on this byte. If this and the last byte\n        // formed a valid pair, then this shouldn't be checked to see if it starts\n        // a double byte pair of course.\n        lastWasPossibleDoubleByteStart = false;\n      } else {\n        // ... otherwise do check to see if this plus the next byte form a valid\n        // double byte pair encoding a character.\n        lastWasPossibleDoubleByteStart = true;\n        if (i >= length - 1) {\n          canBeShiftJIS = false;\n        } else {\n          int nextValue = bytes[i + 1] & 0xFF;\n          if (nextValue < 0x40 || nextValue > 0xFC) {\n            canBeShiftJIS = false;\n          } else {\n            maybeDoubleByteCount++;\n          }\n          // There is some conflicting information out there about which bytes can follow which in\n          // double-byte Shift_JIS characters. The rule above seems to be the one that matches practice.\n        }\n      }\n    } else {\n      lastWasPossibleDoubleByteStart = false;\n    }\n  }\n  if (utf8BytesLeft > 0) {\n    canBeUTF8 = false;\n  }\n\n  // Easy -- if assuming Shift_JIS and no evidence it can't be, done\n  if (canBeShiftJIS && ASSUME_SHIFT_JIS) {\n    return SHIFT_JIS;\n  }\n  if (canBeUTF8 && sawUTF8Start) {\n    return UTF8;\n  }\n  // Distinguishing Shift_JIS and ISO-8859-1 can be a little tough. The crude heuristic is:\n  // - If we saw\n  //   - at least 3 bytes that starts a double-byte value (bytes that are rare in ISO-8859-1), or\n  //   - over 5% of bytes could be single-byte Katakana (also rare in ISO-8859-1),\n  // - and, saw no sequences that are invalid in Shift_JIS, then we conclude Shift_JIS\n  if (canBeShiftJIS && (maybeDoubleByteCount >= 3 || 20 * maybeSingleByteKatakanaCount > length)) {\n    return SHIFT_JIS;\n  }\n  // Otherwise, we default to ISO-8859-1 unless we know it can't be\n  if (!sawLatin1Supplement && canBeISO88591) {\n    return ISO88591;\n  }\n  // Otherwise, we take a wild guess with platform encoding\n  return PLATFORM_DEFAULT_ENCODING;\n}\n\n// file: zxing/common/detector/MonochromeRectangleDetector.cpp\n\n/*\n *  MonochromeRectangleDetector.cpp\n *  y_wmk\n *\n *  Created by Luiz Silva on 09/02/2010.\n *  Copyright 2010 y_wmk authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/NotFoundException.h>\n// #include <zxing/common/detector/MonochromeRectangleDetector.h>\n// #include <sstream>\n\nnamespace zxing {\nusing namespace std;\n\nstd::vector<Ref<ResultPoint> > MonochromeRectangleDetector::detect() {\n    int height = (int)image_->getHeight();\n    int width = (int)image_->getWidth();\n    int halfHeight = height >> 1;\n    int halfWidth = width >> 1;\n    int deltaY = max(1, height / (MAX_MODULES << 3));\n    int deltaX = max(1, width / (MAX_MODULES << 3));\n\n    int top = 0;\n    int bottom = height;\n    int left = 0;\n    int right = width;\n    Ref<ResultPoint> pointA(findCornerFromCenter(halfWidth, 0, left, right,\n        halfHeight, -deltaY, top, bottom, halfWidth >> 1));\n    top = (int) pointA->getY() - 1;;\n    Ref<ResultPoint> pointB(findCornerFromCenter(halfWidth, -deltaX, left, right,\n        halfHeight, 0, top, bottom, halfHeight >> 1));\n    left = (int) pointB->getX() - 1;\n    Ref<ResultPoint> pointC(findCornerFromCenter(halfWidth, deltaX, left, right,\n        halfHeight, 0, top, bottom, halfHeight >> 1));\n    right = (int) pointC->getX() + 1;\n    Ref<ResultPoint> pointD(findCornerFromCenter(halfWidth, 0, left, right,\n        halfHeight, deltaY, top, bottom, halfWidth >> 1));\n    bottom = (int) pointD->getY() + 1;\n\n    // Go try to find point A again with better information -- might have been off at first.\n    pointA.reset(findCornerFromCenter(halfWidth, 0, left, right,\n        halfHeight, -deltaY, top, bottom, halfWidth >> 2));\n\n\t  std::vector<Ref<ResultPoint> > corners(4);\n  \tcorners[0].reset(pointA);\n  \tcorners[1].reset(pointB);\n  \tcorners[2].reset(pointC);\n  \tcorners[3].reset(pointD);\n    return corners;\n  }\n\nRef<ResultPoint> MonochromeRectangleDetector::findCornerFromCenter(int centerX, int deltaX, int left, int right,\n      int centerY, int deltaY, int top, int bottom, int maxWhiteRun) {\n\t  Ref<TwoInts> lastRange(NULL);\n    for (int y = centerY, x = centerX;\n         y < bottom && y >= top && x < right && x >= left;\n         y += deltaY, x += deltaX) {\n      Ref<TwoInts> range(NULL);\n      if (deltaX == 0) {\n        // horizontal slices, up and down\n        range = blackWhiteRange(y, maxWhiteRun, left, right, true);\n      } else {\n        // vertical slices, left and right\n        range = blackWhiteRange(x, maxWhiteRun, top, bottom, false);\n      }\n      if (range == NULL) {\n        if (lastRange == NULL) {\n\t\t\t    throw NotFoundException(\"Couldn't find corners (lastRange = NULL) \");\n        } else {\n        // lastRange was found\n        if (deltaX == 0) {\n          int lastY = y - deltaY;\n          if (lastRange->start < centerX) {\n            if (lastRange->end > centerX) {\n              // straddle, choose one or the other based on direction\n\t\t\t        Ref<ResultPoint> result(new ResultPoint(deltaY > 0 ? lastRange->start : lastRange->end, lastY));\n\t\t\t        return result;\n            }\n\t\t\t      Ref<ResultPoint> result(new ResultPoint(lastRange->start, lastY));\n\t\t\t      return result;\n          } else {\n\t\t\t      Ref<ResultPoint> result(new ResultPoint(lastRange->end, lastY));\n\t\t\t      return result;\n            }\n        } else {\n          int lastX = x - deltaX;\n          if (lastRange->start < centerY) {\n            if (lastRange->end > centerY) {\n\t\t\t        Ref<ResultPoint> result(new ResultPoint(lastX, deltaX < 0 ? lastRange->start : lastRange->end));\n\t\t\t        return result;\n            }\n\t\t\t      Ref<ResultPoint> result(new ResultPoint(lastX, lastRange->start));\n\t\t\t      return result;\n          } else {\n\t\t\t      Ref<ResultPoint> result(new ResultPoint(lastX, lastRange->end));\n\t\t\t      return result;\n            }\n          }\n        }\n      }\n      lastRange = range;\n    }\n    throw NotFoundException(\"Couldn't find corners\");\n  }\n\nRef<TwoInts> MonochromeRectangleDetector::blackWhiteRange(int fixedDimension, int maxWhiteRun, int minDim, int maxDim,\n      bool horizontal) {\n\n\t  int center = (minDim + maxDim) >> 1;\n\n    // Scan left/up first\n    int start = center;\n    while (start >= minDim) {\n      if (horizontal ? image_->get(start, fixedDimension) : image_->get(fixedDimension, start)) {\n        start--;\n      } else {\n        int whiteRunStart = start;\n        do {\n          start--;\n        } while (start >= minDim && !(horizontal ? image_->get(start, fixedDimension) :\n            image_->get(fixedDimension, start)));\n        int whiteRunSize = whiteRunStart - start;\n        if (start < minDim || whiteRunSize > maxWhiteRun) {\n          start = whiteRunStart;\n          break;\n        }\n      }\n    }\n    start++;\n\n    // Then try right/down\n    int end = center;\n    while (end < maxDim) {\n      if (horizontal ? image_->get(end, fixedDimension) : image_->get(fixedDimension, end)) {\n        end++;\n      } else {\n        int whiteRunStart = end;\n        do {\n          end++;\n        } while (end < maxDim && !(horizontal ? image_->get(end, fixedDimension) :\n            image_->get(fixedDimension, end)));\n        int whiteRunSize = end - whiteRunStart;\n        if (end >= maxDim || whiteRunSize > maxWhiteRun) {\n          end = whiteRunStart;\n          break;\n        }\n      }\n    }\n    end--;\n    Ref<TwoInts> result(NULL);\n    if (end > start) {\n\t\t  result = new TwoInts;\n      result->start = start;\n      result->end = end;\n    }\n    return result;\n  }\n}\n\n// file: zxing/common/detector/WhiteRectangleDetector.cpp\n\n/*\n *  WhiteRectangleDetector.cpp\n *  y_wmk\n *\n *  Created by Luiz Silva on 09/02/2010.\n *  Copyright 2010 y_wmk authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/NotFoundException.h>\n// #include <zxing/common/detector/WhiteRectangleDetector.h>\n// #include <math.h>\n// #include <sstream>\n\nnamespace zxing {\nusing namespace std;\n\nint WhiteRectangleDetector::INIT_SIZE = 30;\nint WhiteRectangleDetector::CORR = 1;\n\n\nWhiteRectangleDetector::WhiteRectangleDetector(Ref<BitMatrix> image) : image_(image) {\n  width_ = (int)image->getWidth();\n  height_ = (int)image->getHeight();\n}\n\n/**\n * <p>\n * Detects a candidate barcode-like rectangular region within an image. It\n * starts around the center of the image, increases the size of the candidate\n * region until it finds a white rectangular region.\n * </p>\n *\n * @return {@link vector<Ref<ResultPoint> >} describing the corners of the rectangular\n *         region. The first and last points are opposed on the diagonal, as\n *         are the second and third. The first point will be the topmost\n *         point and the last, the bottommost. The second point will be\n *         leftmost and the third, the rightmost\n * @throws NotFoundException if no Data Matrix Code can be found\n*/\nstd::vector<Ref<ResultPoint> > WhiteRectangleDetector::detect() {\n  int left = (width_ - INIT_SIZE) >> 1;\n  int right = (width_ + INIT_SIZE) >> 1;\n  int up = (height_ - INIT_SIZE) >> 1;\n  int down = (height_ + INIT_SIZE) >> 1;\n  if (up < 0 || left < 0 || down >= height_ || right >= width_) {\n    throw NotFoundException(\"Invalid dimensions WhiteRectangleDetector\");\n  }\n\n  bool sizeExceeded = false;\n  bool aBlackPointFoundOnBorder = true;\n  bool atLeastOneBlackPointFoundOnBorder = false;\n\n  while (aBlackPointFoundOnBorder) {\n    aBlackPointFoundOnBorder = false;\n\n    // .....\n    // .   |\n    // .....\n    bool rightBorderNotWhite = true;\n    while (rightBorderNotWhite && right < width_) {\n      rightBorderNotWhite = containsBlackPoint(up, down, right, false);\n      if (rightBorderNotWhite) {\n        right++;\n        aBlackPointFoundOnBorder = true;\n      }\n    }\n\n    if (right >= width_) {\n      sizeExceeded = true;\n      break;\n    }\n\n    // .....\n    // .   .\n    // .___.\n    bool bottomBorderNotWhite = true;\n    while (bottomBorderNotWhite && down < height_) {\n      bottomBorderNotWhite = containsBlackPoint(left, right, down, true);\n      if (bottomBorderNotWhite) {\n        down++;\n        aBlackPointFoundOnBorder = true;\n      }\n    }\n\n    if (down >= height_) {\n      sizeExceeded = true;\n      break;\n    }\n\n    // .....\n    // |   .\n    // .....\n    bool leftBorderNotWhite = true;\n    while (leftBorderNotWhite && left >= 0) {\n      leftBorderNotWhite = containsBlackPoint(up, down, left, false);\n      if (leftBorderNotWhite) {\n        left--;\n        aBlackPointFoundOnBorder = true;\n      }\n    }\n\n    if (left < 0) {\n      sizeExceeded = true;\n      break;\n    }\n\n    // .___.\n    // .   .\n    // .....\n    bool topBorderNotWhite = true;\n    while (topBorderNotWhite && up >= 0) {\n      topBorderNotWhite = containsBlackPoint(left, right, up, true);\n      if (topBorderNotWhite) {\n        up--;\n        aBlackPointFoundOnBorder = true;\n      }\n    }\n\n    if (up < 0) {\n      sizeExceeded = true;\n      break;\n    }\n\n    if (aBlackPointFoundOnBorder) {\n      atLeastOneBlackPointFoundOnBorder = true;\n    }\n\n  }\n  if (!sizeExceeded && atLeastOneBlackPointFoundOnBorder) {\n\n    int maxSize = right - left;\n\n    Ref<ResultPoint> z(NULL);\n    //go up right\n    for (int i = 1; i < maxSize; i++) {\n      z = getBlackPointOnSegment(left, down - i, left + i, down);\n      if (z != NULL) {\n        break;\n      }\n    }\n\n    if (z == NULL) {\n      throw NotFoundException(\"z == NULL\");\n    }\n\n    Ref<ResultPoint> t(NULL);\n    //go down right\n    for (int i = 1; i < maxSize; i++) {\n      t = getBlackPointOnSegment(left, up + i, left + i, up);\n      if (t != NULL) {\n        break;\n      }\n    }\n\n    if (t == NULL) {\n      throw NotFoundException(\"t == NULL\");\n    }\n\n    Ref<ResultPoint> x(NULL);\n    //go down left\n    for (int i = 1; i < maxSize; i++) {\n      x = getBlackPointOnSegment(right, up + i, right - i, up);\n      if (x != NULL) {\n        break;\n      }\n    }\n\n    if (x == NULL) {\n      throw NotFoundException(\"x == NULL\");\n    }\n\n    Ref<ResultPoint> y(NULL);\n    //go up left\n    for (int i = 1; i < maxSize; i++) {\n      y = getBlackPointOnSegment(right, down - i, right - i, down);\n      if (y != NULL) {\n        break;\n      }\n    }\n\n    if (y == NULL) {\n      throw NotFoundException(\"y == NULL\");\n    }\n\n    return centerEdges(y, z, x, t);\n\n  } else {\n    throw NotFoundException(\"No black point found on border\");\n  }\n}\n\n/**\n * Ends up being a bit faster than Math.round(). This merely rounds its\n * argument to the nearest int, where x.5 rounds up.\n */\nint WhiteRectangleDetector::round(float d) {\n  return (int) (d + 0.5f);\n}\n\nRef<ResultPoint> WhiteRectangleDetector::getBlackPointOnSegment(float aX, float aY, float bX, float bY) {\n  int dist = distanceL2(aX, aY, bX, bY);\n  float xStep = (bX - aX) / dist;\n  float yStep = (bY - aY) / dist;\n  for (int i = 0; i < dist; i++) {\n    int x = round(aX + i * xStep);\n    int y = round(aY + i * yStep);\n    if (image_->get(x, y)) {\n      Ref<ResultPoint> point(new ResultPoint(x, y));\n      return point;\n    }\n  }\n  Ref<ResultPoint> point(NULL);\n  return point;\n}\n\nint WhiteRectangleDetector::distanceL2(float aX, float aY, float bX, float bY) {\n  float xDiff = aX - bX;\n  float yDiff = aY - bY;\n  return round((float)sqrt(xDiff * xDiff + yDiff * yDiff));\n}\n\n/**\n * recenters the points of a constant distance towards the center\n *\n * @param y bottom most point\n * @param z left most point\n * @param x right most point\n * @param t top most point\n * @return {@link vector<Ref<ResultPoint> >} describing the corners of the rectangular\n *         region. The first and last points are opposed on the diagonal, as\n *         are the second and third. The first point will be the topmost\n *         point and the last, the bottommost. The second point will be\n *         leftmost and the third, the rightmost\n */\nvector<Ref<ResultPoint> > WhiteRectangleDetector::centerEdges(Ref<ResultPoint> y, Ref<ResultPoint> z,\n                                  Ref<ResultPoint> x, Ref<ResultPoint> t) {\n\n  //\n  //       t            t\n  //  z                      x\n  //        x    OR    z\n  //   y                    y\n  //\n\n  float yi = y->getX();\n  float yj = y->getY();\n  float zi = z->getX();\n  float zj = z->getY();\n  float xi = x->getX();\n  float xj = x->getY();\n  float ti = t->getX();\n  float tj = t->getY();\n\n  std::vector<Ref<ResultPoint> > corners(4);\n  if (yi < (float)width_/2) {\n    Ref<ResultPoint> pointA(new ResultPoint(ti - CORR, tj + CORR));\n    Ref<ResultPoint> pointB(new ResultPoint(zi + CORR, zj + CORR));\n    Ref<ResultPoint> pointC(new ResultPoint(xi - CORR, xj - CORR));\n    Ref<ResultPoint> pointD(new ResultPoint(yi + CORR, yj - CORR));\n\t  corners[0].reset(pointA);\n\t  corners[1].reset(pointB);\n\t  corners[2].reset(pointC);\n\t  corners[3].reset(pointD);\n  } else {\n    Ref<ResultPoint> pointA(new ResultPoint(ti + CORR, tj + CORR));\n    Ref<ResultPoint> pointB(new ResultPoint(zi + CORR, zj - CORR));\n    Ref<ResultPoint> pointC(new ResultPoint(xi - CORR, xj + CORR));\n    Ref<ResultPoint> pointD(new ResultPoint(yi - CORR, yj - CORR));\n\t  corners[0].reset(pointA);\n\t  corners[1].reset(pointB);\n\t  corners[2].reset(pointC);\n\t  corners[3].reset(pointD);\n  }\n  return corners;\n}\n\n/**\n * Determines whether a segment contains a black point\n *\n * @param a          min value of the scanned coordinate\n * @param b          max value of the scanned coordinate\n * @param fixed      value of fixed coordinate\n * @param horizontal set to true if scan must be horizontal, false if vertical\n * @return true if a black point has been found, else false.\n */\nbool WhiteRectangleDetector::containsBlackPoint(int a, int b, int fixed, bool horizontal) {\n  if (horizontal) {\n    for (int x = a; x <= b; x++) {\n      if (image_->get(x, fixed)) {\n        return true;\n      }\n    }\n  } else {\n    for (int y = a; y <= b; y++) {\n      if (image_->get(fixed, y)) {\n        return true;\n      }\n    }\n  }\n\n  return false;\n}\n}\n\n// file: zxing/common/reedsolomon/GF256.cpp\n\n/*\n *  GF256.cpp\n *  zxing\n *\n *  Created by Christian Brunschen on 05/05/2008.\n *  Copyright 2008 Google UK. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <vector>\n// #include <iostream>\n// #include <zxing/common/reedsolomon/GF256.h>\n// #include <zxing/common/reedsolomon/GF256Poly.h>\n// #include <zxing/common/IllegalArgumentException.h>\n// #include <zxing/common/Array.h>\n// #include <zxing/common/Counted.h>\n\nnamespace zxing {\nusing namespace std;\n\nstatic inline ArrayRef<int> makeArray(int value) {\n  ArrayRef<int> valuesRef(new Array<int> (value, 1));\n  return valuesRef;\n}\n\nstatic inline Ref<GF256Poly> refPoly(GF256 &field, int value) {\n  ArrayRef<int> values(makeArray(value));\n  Ref<GF256Poly> result(new GF256Poly(field, values));\n  return result;\n}\n\nGF256::GF256(int primitive) :\n    exp_(256, (const int)0), log_(256, (const int)0), zero_(refPoly(*this, 0)), one_(refPoly(*this, 1)) {\n  int x = 1;\n  for (int i = 0; i < 256; i++) {\n    exp_[i] = x;\n    x <<= 1;\n    if (x >= 0x100) {\n      x ^= primitive;\n    }\n  }\n\n  // log(0) == 0, but should never be used\n  log_[0] = 0;\n  for (int i = 0; i < 255; i++) {\n    log_[exp_[i]] = i;\n  }\n}\n\nRef<GF256Poly> GF256::getZero() {\n  return zero_;\n}\n\nRef<GF256Poly> GF256::getOne() {\n  return one_;\n}\n\nRef<GF256Poly> GF256::buildMonomial(int degree, int coefficient) {\n#ifdef DEBUG\n  cout << __FUNCTION__ << \"\\n\";\n#endif\n  if (degree < 0) {\n    throw IllegalArgumentException(\"Degree must be non-negative\");\n  }\n  if (coefficient == 0) {\n    return zero_;\n  }\n  int nCoefficients = degree + 1;\n  ArrayRef<int> coefficients(new Array<int> (nCoefficients));\n  coefficients[0] = coefficient;\n  Ref<GF256Poly> result(new GF256Poly(*this, coefficients));\n  return result;\n}\n\nint GF256::addOrSubtract(int a, int b) {\n  return a ^ b;\n}\n\nint GF256::exp(int a) {\n  return exp_[a];\n}\n\nint GF256::log(int a) {\n  if (a == 0) {\n    throw IllegalArgumentException(\"Cannot take the logarithm of 0\");\n  }\n  return log_[a];\n}\n\nint GF256::inverse(int a) {\n  if (a == 0) {\n    throw IllegalArgumentException(\"Cannot calculate the inverse of 0\");\n  }\n  return exp_[255 - log_[a]];\n}\n\nint GF256::multiply(int a, int b) {\n  if (a == 0 || b == 0) {\n    return 0;\n  }\n  int logSum = log_[a] + log_[b];\n  // index is a sped-up alternative to logSum % 255 since sum\n  // is in [0,510]. Thanks to jmsachs for the idea\n  return exp_[(logSum & 0xFF) + (logSum >> 8)];\n}\n\nGF256 GF256::QR_CODE_FIELD(0x011D); // x^8 + x^4 + x^3 + x^2 + 1\nGF256 GF256::DATA_MATRIX_FIELD(0x012D); // x^8 + x^5 + x^3 + x^2 + 1\n\nostream& operator<<(ostream& out, const GF256& field) {\n  out << \"Field[\\nexp=(\";\n  out << field.exp_[0];\n  for (int i = 1; i < 256; i++) {\n    out << \",\" << field.exp_[i];\n  }\n  out << \"),\\nlog=(\";\n  out << field.log_[0];\n  for (int i = 1; i < 256; i++) {\n    out << \",\" << field.log_[i];\n  }\n  out << \")\\n]\";\n  return out;\n}\n\n}\n\n// file: zxing/common/reedsolomon/GF256Poly.cpp\n\n/*\n *  GF256Poly.cpp\n *  zxing\n *\n *  Created by Christian Brunschen on 05/05/2008.\n *  Copyright 2008 Google UK. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <iostream>\n// #include <sstream>\n// #include <zxing/common/reedsolomon/GF256Poly.h>\n// #include <zxing/common/reedsolomon/GF256.h>\n// #include <zxing/common/IllegalArgumentException.h>\n\nnamespace zxing {\nusing namespace std;\n\nvoid GF256Poly::fixCoefficients() {\n  int coefficientsLength = (int)coefficients.size();\n  if (coefficientsLength > 1 && coefficients[0] == 0) {\n    // Leading term must be non-zero for anything except\n    // the constant polynomial \"0\"\n    int firstNonZero = 1;\n    while (firstNonZero < coefficientsLength && coefficients[firstNonZero] == 0) {\n      firstNonZero++;\n    }\n    if (firstNonZero == coefficientsLength) {\n      coefficientsLength = (int)(field.getZero()->coefficients.size());\n      coefficients.reset(new Array<int> (coefficientsLength));\n      *coefficients = *(field.getZero()->coefficients);\n    } else {\n      ArrayRef<int> c(coefficients);\n      coefficientsLength -= firstNonZero;\n      coefficients.reset(new Array<int> (coefficientsLength));\n      for (int i = 0; i < coefficientsLength; i++) {\n        coefficients[i] = c[i + firstNonZero];\n      }\n    }\n  }\n}\n\nGF256Poly::GF256Poly(GF256 &f, ArrayRef<int> c) :\n    Counted(), field(f), coefficients(c) {\n  fixCoefficients();\n}\n\nGF256Poly::~GF256Poly() {\n\n}\n\nint GF256Poly::getDegree() {\n  return (int)(coefficients.size() - 1);\n}\n\nbool GF256Poly::isZero() {\n  return coefficients[0] == 0;\n}\n\nint GF256Poly::getCoefficient(int degree) {\n  return coefficients[coefficients.size() - 1 - degree];\n}\n\nint GF256Poly::evaluateAt(int a) {\n  if (a == 0) {\n    return getCoefficient(0);\n  }\n  int size = (int)coefficients.size();\n  if (a == 1) {\n    // Just the sum of the coefficients\n    int result = 0;\n    for (int i = 0; i < size; i++) {\n      result = GF256::addOrSubtract(result, coefficients[i]);\n    }\n    return result;\n  }\n  int result = coefficients[0];\n  for (int i = 1; i < size; i++) {\n    result = GF256::addOrSubtract(field.multiply(a, result), coefficients[i]);\n  }\n  return result;\n}\n\nRef<GF256Poly> GF256Poly::addOrSubtract(Ref<GF256Poly> b) {\n  if (&field != &b->field) {\n    throw IllegalArgumentException(\"Fields must be the same\");\n  }\n  if (isZero()) {\n    return b;\n  }\n  if (b->isZero()) {\n    return Ref<GF256Poly>(this);\n  }\n\n  ArrayRef<int> largerCoefficients = coefficients;\n  ArrayRef<int> smallerCoefficients = b->coefficients;\n  if (smallerCoefficients.size() > largerCoefficients.size()) {\n    ArrayRef<int> tmp(smallerCoefficients);\n    smallerCoefficients = largerCoefficients;\n    largerCoefficients = tmp;\n  }\n\n  ArrayRef<int> sumDiff(new Array<int> (largerCoefficients.size()));\n\n  unsigned lengthDiff = (unsigned)(largerCoefficients.size() - smallerCoefficients.size());\n  for (unsigned i = 0; i < lengthDiff; i++) {\n    sumDiff[i] = largerCoefficients[i];\n  }\n  for (unsigned i = lengthDiff; i < largerCoefficients.size(); i++) {\n    sumDiff[i] = GF256::addOrSubtract(smallerCoefficients[i - lengthDiff], largerCoefficients[i]);\n  }\n  return Ref<GF256Poly>(new GF256Poly(field, sumDiff));\n}\n\nRef<GF256Poly> GF256Poly::multiply(Ref<GF256Poly> b) {\n  if (&field != &b->field) {\n    throw IllegalArgumentException(\"Fields must be the same\");\n  }\n  if (isZero() || b->isZero()) {\n    return field.getZero();\n  }\n  ArrayRef<int> aCoefficients = coefficients;\n  int aLength = (int)aCoefficients.size();\n  ArrayRef<int> bCoefficients = b->coefficients;\n  int bLength = (int)bCoefficients.size();\n  int productLength = aLength + bLength - 1;\n  ArrayRef<int> product(new Array<int> (productLength));\n  for (int i = 0; i < aLength; i++) {\n    int aCoeff = aCoefficients[i];\n    for (int j = 0; j < bLength; j++) {\n      product[i + j] = GF256::addOrSubtract(product[i + j], field.multiply(aCoeff, bCoefficients[j]));\n    }\n  }\n\n  return Ref<GF256Poly>(new GF256Poly(field, product));\n}\n\nRef<GF256Poly> GF256Poly::multiply(int scalar) {\n  if (scalar == 0) {\n    return field.getZero();\n  }\n  if (scalar == 1) {\n    return Ref<GF256Poly>(this);\n  }\n  int size = (int)coefficients.size();\n  ArrayRef<int> product(new Array<int> (size));\n  for (int i = 0; i < size; i++) {\n    product[i] = field.multiply(coefficients[i], scalar);\n  }\n  return Ref<GF256Poly>(new GF256Poly(field, product));\n}\n\nRef<GF256Poly> GF256Poly::multiplyByMonomial(int degree, int coefficient) {\n  if (degree < 0) {\n    throw IllegalArgumentException(\"Degree must be non-negative\");\n  }\n  if (coefficient == 0) {\n    return field.getZero();\n  }\n  int size = (int)coefficients.size();\n  ArrayRef<int> product(new Array<int> (size + degree));\n  for (int i = 0; i < size; i++) {\n    product[i] = field.multiply(coefficients[i], coefficient);\n  }\n  return Ref<GF256Poly>(new GF256Poly(field, product));\n}\n\nconst char *GF256Poly::description() const {\n  ostringstream result;\n  result << *this;\n  return result.str().c_str();\n}\n\nostream& operator<<(ostream& out, const GF256Poly& p) {\n  GF256Poly &poly = const_cast<GF256Poly&>(p);\n  out << \"Poly[\" << poly.coefficients.size() << \"]\";\n  if (poly.coefficients.size() > 0) {\n    out << \"(\" << poly.coefficients[0];\n    for (unsigned i = 1; i < poly.coefficients.size(); i++) {\n      out << \",\" << poly.coefficients[i];\n    }\n    out << \")\";\n  }\n  return out;\n}\n\n}\n\n// file: zxing/common/reedsolomon/ReedSolomonDecoder.cpp\n\n/*\n *  ReedSolomonDecoder.cpp\n *  zxing\n *\n *  Created by Christian Brunschen on 05/05/2008.\n *  Copyright 2008 Google UK. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <iostream>\n\n// #include <memory>\n// #include <zxing/common/reedsolomon/ReedSolomonDecoder.h>\n// #include <zxing/common/reedsolomon/GF256.h>\n// #include <zxing/common/reedsolomon/GF256Poly.h>\n// #include <zxing/common/reedsolomon/ReedSolomonException.h>\n// #include <zxing/common/IllegalArgumentException.h>\n\nusing namespace std;\n\nnamespace zxing {\n\nReedSolomonDecoder::ReedSolomonDecoder(GF256 &fld) :\n    field(fld) {\n}\n\nReedSolomonDecoder::~ReedSolomonDecoder() {\n}\n\nvoid ReedSolomonDecoder::decode(ArrayRef<int> received, int twoS) {\n\n  Ref<GF256Poly> poly(new GF256Poly(field, received));\n\n\n#ifdef DEBUG\n  cout << \"decoding with poly \" << *poly << \"\\n\";\n#endif\n\n  ArrayRef<int> syndromeCoefficients(new Array<int> (twoS));\n\n\n#ifdef DEBUG\n  cout << \"syndromeCoefficients array = \" <<\n       syndromeCoefficients.array_ << \"\\n\";\n#endif\n\n  bool dataMatrix = (&field == &GF256::DATA_MATRIX_FIELD);\n  bool noError = true;\n  for (int i = 0; i < twoS; i++) {\n    int eval = poly->evaluateAt(field.exp(dataMatrix ? i + 1 : i));\n    syndromeCoefficients[syndromeCoefficients->size() - 1 - i] = eval;\n    if (eval != 0) {\n      noError = false;\n    }\n  }\n  if (noError) {\n    return;\n  }\n\n  Ref<GF256Poly> syndrome(new GF256Poly(field, syndromeCoefficients));\n  Ref<GF256Poly> monomial(field.buildMonomial(twoS, 1));\n  vector<Ref<GF256Poly> > sigmaOmega(runEuclideanAlgorithm(monomial, syndrome, twoS));\n  ArrayRef<int> errorLocations = findErrorLocations(sigmaOmega[0]);\n  ArrayRef<int> errorMagitudes = findErrorMagnitudes(sigmaOmega[1], errorLocations, dataMatrix);\n  for (unsigned i = 0; i < errorLocations->size(); i++) {\n    int position = (int)(received->size() - 1 - field.log(errorLocations[i]));\n    //TODO: check why the position would be invalid\n    if (position < 0 || (size_t)position >= received.size())\n      throw IllegalArgumentException(\"Invalid position (ReedSolomonDecoder)\");\n    received[position] = GF256::addOrSubtract(received[position], errorMagitudes[i]);\n  }\n}\n\nvector<Ref<GF256Poly> > ReedSolomonDecoder::runEuclideanAlgorithm(Ref<GF256Poly> a, Ref<GF256Poly> b, int R) {\n  // Assume a's degree is >= b's\n  if (a->getDegree() < b->getDegree()) {\n    Ref<GF256Poly> tmp = a;\n    a = b;\n    b = tmp;\n  }\n\n  Ref<GF256Poly> rLast(a);\n  Ref<GF256Poly> r(b);\n  Ref<GF256Poly> sLast(field.getOne());\n  Ref<GF256Poly> s(field.getZero());\n  Ref<GF256Poly> tLast(field.getZero());\n  Ref<GF256Poly> t(field.getOne());\n\n\n  // Run Euclidean algorithm until r's degree is less than R/2\n  while (r->getDegree() >= R / 2) {\n    Ref<GF256Poly> rLastLast(rLast);\n    Ref<GF256Poly> sLastLast(sLast);\n    Ref<GF256Poly> tLastLast(tLast);\n    rLast = r;\n    sLast = s;\n    tLast = t;\n\n\n    // Divide rLastLast by rLast, with quotient q and remainder r\n    if (rLast->isZero()) {\n      // Oops, Euclidean algorithm already terminated?\n      throw ReedSolomonException(\"r_{i-1} was zero\");\n    }\n    r = rLastLast;\n    Ref<GF256Poly> q(field.getZero());\n    int denominatorLeadingTerm = rLast->getCoefficient(rLast->getDegree());\n    int dltInverse = field.inverse(denominatorLeadingTerm);\n    while (r->getDegree() >= rLast->getDegree() && !r->isZero()) {\n      int degreeDiff = r->getDegree() - rLast->getDegree();\n      int scale = field.multiply(r->getCoefficient(r->getDegree()), dltInverse);\n      q = q->addOrSubtract(field.buildMonomial(degreeDiff, scale));\n      r = r->addOrSubtract(rLast->multiplyByMonomial(degreeDiff, scale));\n    }\n\n    s = q->multiply(sLast)->addOrSubtract(sLastLast);\n    t = q->multiply(tLast)->addOrSubtract(tLastLast);\n  }\n\n  int sigmaTildeAtZero = t->getCoefficient(0);\n  if (sigmaTildeAtZero == 0) {\n    throw ReedSolomonException(\"sigmaTilde(0) was zero\");\n  }\n\n  int inverse = field.inverse(sigmaTildeAtZero);\n  Ref<GF256Poly> sigma(t->multiply(inverse));\n  Ref<GF256Poly> omega(r->multiply(inverse));\n\n\n#ifdef DEBUG\n  cout << \"t = \" << *t << \"\\n\";\n  cout << \"r = \" << *r << \"\\n\";\n  cout << \"sigma = \" << *sigma << \"\\n\";\n  cout << \"omega = \" << *omega << \"\\n\";\n#endif\n\n  vector<Ref<GF256Poly> > result(2);\n  result[0] = sigma;\n  result[1] = omega;\n  return result;\n}\n\nArrayRef<int> ReedSolomonDecoder::findErrorLocations(Ref<GF256Poly> errorLocator) {\n  // This is a direct application of Chien's search\n  int numErrors = errorLocator->getDegree();\n  if (numErrors == 1) { // shortcut\n    ArrayRef<int> result(1);\n    result[0] = errorLocator->getCoefficient(1);\n    return result;\n  }\n  ArrayRef<int> result(numErrors);\n  int e = 0;\n  for (int i = 1; i < 256 && e < numErrors; i++) {\n    // cout << \"errorLocator(\" << i << \") == \" << errorLocator->evaluateAt(i) << \"\\n\";\n    if (errorLocator->evaluateAt(i) == 0) {\n      result[e] = field.inverse(i);\n      e++;\n    }\n  }\n  if (e != numErrors) {\n    throw ReedSolomonException(\"Error locator degree does not match number of roots\");\n  }\n  return result;\n}\n\nArrayRef<int> ReedSolomonDecoder::findErrorMagnitudes(Ref<GF256Poly> errorEvaluator, ArrayRef<int> errorLocations, bool dataMatrix) {\n  // This is directly applying Forney's Formula\n  int s = (int)errorLocations.size();\n  ArrayRef<int> result(s);\n  for (int i = 0; i < s; i++) {\n    int xiInverse = field.inverse(errorLocations[i]);\n    int denominator = 1;\n    for (int j = 0; j < s; j++) {\n      if (i != j) {\n        denominator = field.multiply(denominator, GF256::addOrSubtract(1, field.multiply(errorLocations[j],\n                                     xiInverse)));\n      }\n    }\n    result[i] = field.multiply(errorEvaluator->evaluateAt(xiInverse), field.inverse(denominator));\n\n    if (dataMatrix) {\n      result[i] = field.multiply(result[i], xiInverse);\n\t}\n  }\n  return result;\n}\n}\n\n// file: zxing/common/reedsolomon/ReedSolomonException.cpp\n\n/*\n *  ReedSolomonException.cpp\n *  zxing\n *\n *  Created by Christian Brunschen on 06/05/2008.\n *  Copyright 2008 Google UK. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/common/reedsolomon/ReedSolomonException.h>\n\nnamespace zxing {\nReedSolomonException::ReedSolomonException(const char *msg) throw() :\n    Exception(msg) {\n}\nReedSolomonException::~ReedSolomonException() throw() {\n}\n\n}\n\n// file: zxing/datamatrix/DataMatrixReader.cpp\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n/*\n *  DataMatrixReader.cpp\n *  zxing\n *\n *  Created by Luiz Silva on 09/02/2010.\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/datamatrix/DataMatrixReader.h>\n// #include <zxing/datamatrix/detector/Detector.h>\n// #include <iostream>\n\nnamespace zxing {\nnamespace datamatrix {\n\nusing namespace std;\n\nDataMatrixReader::DataMatrixReader() :\n    decoder_() {\n}\n\nRef<Result> DataMatrixReader::decode(Ref<BinaryBitmap> image, DecodeHints hints) {\n  (void)hints;\n#ifdef DEBUG\n  cout << \"decoding image \" << image.object_ << \":\\n\" << flush;\n#endif\n\n  Detector detector(image->getBlackMatrix());\n\n\n#ifdef DEBUG\n  cout << \"(1) created detector \" << &detector << \"\\n\" << flush;\n#endif\n\n  Ref<DetectorResult> detectorResult(detector.detect());\n#ifdef DEBUG\n  cout << \"(2) detected, have detectorResult \" << detectorResult.object_ << \"\\n\" << flush;\n#endif\n\n  std::vector<Ref<ResultPoint> > points(detectorResult->getPoints());\n\n\n#ifdef DEBUG\n  cout << \"(3) extracted points \" << &points << \"\\n\" << flush;\n  cout << \"found \" << points.size() << \" points:\\n\";\n  for (size_t i = 0; i < points.size(); i++) {\n    cout << \"   \" << points[i]->getX() << \",\" << points[i]->getY() << \"\\n\";\n  }\n  cout << \"bits:\\n\";\n  cout << *(detectorResult->getBits()) << \"\\n\";\n#endif\n\n  Ref<DecoderResult> decoderResult(decoder_.decode(detectorResult->getBits()));\n#ifdef DEBUG\n  cout << \"(4) decoded, have decoderResult \" << decoderResult.object_ << \"\\n\" << flush;\n#endif\n\n  Ref<Result> result(\n    new Result(decoderResult->getText(), decoderResult->getRawBytes(), points, BarcodeFormat_DATA_MATRIX));\n#ifdef DEBUG\n  cout << \"(5) created result \" << result.object_ << \", returning\\n\" << flush;\n#endif\n\n  return result;\n}\n\nDataMatrixReader::~DataMatrixReader() {\n}\n\n}\n}\n\n// file: zxing/datamatrix/Version.cpp\n\n/*\n *  Version.cpp\n *  zxing\n *\n *  Created by Luiz Silva on 09/02/2010.\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/datamatrix/Version.h>\n// #include <limits>\n// #include <iostream>\n\nnamespace zxing {\nnamespace datamatrix {\nusing namespace std;\n\nECB::ECB(int count, int dataCodewords) :\n    count_(count), dataCodewords_(dataCodewords) {\n}\n\nint ECB::getCount() {\n  return count_;\n}\n\nint ECB::getDataCodewords() {\n  return dataCodewords_;\n}\n\nECBlocks::ECBlocks(int ecCodewords, ECB *ecBlocks) :\n    ecCodewords_(ecCodewords), ecBlocks_(1, ecBlocks) {\n}\n\nECBlocks::ECBlocks(int ecCodewords, ECB *ecBlocks1, ECB *ecBlocks2) :\n    ecCodewords_(ecCodewords), ecBlocks_(1, ecBlocks1) {\n  ecBlocks_.push_back(ecBlocks2);\n}\n\nint ECBlocks::getECCodewords() {\n  return ecCodewords_;\n}\n\nstd::vector<ECB*>& ECBlocks::getECBlocks() {\n  return ecBlocks_;\n}\n\nECBlocks::~ECBlocks() {\n  for (size_t i = 0; i < ecBlocks_.size(); i++) {\n    delete ecBlocks_[i];\n  }\n}\n\nvector<Ref<Version> > Version::VERSIONS;\nstatic int N_VERSIONS = Version::buildVersions();\n\nVersion::Version(int versionNumber, int symbolSizeRows, int symbolSizeColumns, int dataRegionSizeRows,\n\t\tint dataRegionSizeColumns, ECBlocks* ecBlocks) : versionNumber_(versionNumber),\n\t\tsymbolSizeRows_(symbolSizeRows), symbolSizeColumns_(symbolSizeColumns),\n\t\tdataRegionSizeRows_(dataRegionSizeRows), dataRegionSizeColumns_(dataRegionSizeColumns),\n\t\tecBlocks_(ecBlocks), totalCodewords_(0) {\n    // Calculate the total number of codewords\n    int total = 0;\n    int ecCodewords = ecBlocks_->getECCodewords();\n    vector<ECB*> &ecbArray = ecBlocks_->getECBlocks();\n    for (unsigned int i = 0; i < ecbArray.size(); i++) {\n      ECB *ecBlock = ecbArray[i];\n      total += ecBlock->getCount() * (ecBlock->getDataCodewords() + ecCodewords);\n    }\n    totalCodewords_ = total;\n}\n\nVersion::~Version() {\n    delete ecBlocks_;\n}\n\nint Version::getVersionNumber() {\n  return versionNumber_;\n}\n\nint Version::getSymbolSizeRows() {\n  return symbolSizeRows_;\n}\n\nint Version::getSymbolSizeColumns() {\n  return symbolSizeColumns_;\n}\n\nint Version::getDataRegionSizeRows() {\n  return dataRegionSizeRows_;\n}\n\nint Version::getDataRegionSizeColumns() {\n  return dataRegionSizeColumns_;\n}\n\nint Version::getTotalCodewords() {\n  return totalCodewords_;\n}\n\nECBlocks* Version::getECBlocks() {\n  return ecBlocks_;\n}\n\nRef<Version> Version::getVersionForDimensions(int numRows, int numColumns) {\n    if ((numRows & 0x01) != 0 || (numColumns & 0x01) != 0) {\n      throw ReaderException(\"Number of rows and columns must be even\");\n    }\n\n    // TODO(bbrown): This is doing a linear search through the array of versions.\n    // If we interleave the rectangular versions with the square versions we could\n    // do a binary search.\n    for (int i = 0; i < N_VERSIONS; ++i){\n      Ref<Version> version(VERSIONS[i]);\n      if (version->getSymbolSizeRows() == numRows && version->getSymbolSizeColumns() == numColumns) {\n        return version;\n      }\n    }\n    throw ReaderException(\"Error version not found\");\n  }\n\n/**\n * See ISO 16022:2006 5.5.1 Table 7\n */\nint Version::buildVersions() {\n  VERSIONS.push_back(Ref<Version>(new Version(1, 10, 10, 8, 8,\n            \t\t\t\t\t  new ECBlocks(5, new ECB(1, 3)))));\n  VERSIONS.push_back(Ref<Version>(new Version(2, 12, 12, 10, 10,\n            \t\t\t\t\t  new ECBlocks(7, new ECB(1, 5)))));\n  VERSIONS.push_back(Ref<Version>(new Version(3, 14, 14, 12, 12,\n            \t\t\t\t\t  new ECBlocks(10, new ECB(1, 8)))));\n  VERSIONS.push_back(Ref<Version>(new Version(4, 16, 16, 14, 14,\n            \t\t\t\t\t  new ECBlocks(12, new ECB(1, 12)))));\n  VERSIONS.push_back(Ref<Version>(new Version(5, 18, 18, 16, 16,\n            \t\t\t\t\t  new ECBlocks(14, new ECB(1, 18)))));\n  VERSIONS.push_back(Ref<Version>(new Version(6, 20, 20, 18, 18,\n            \t\t\t\t\t  new ECBlocks(18, new ECB(1, 22)))));\n  VERSIONS.push_back(Ref<Version>(new Version(7, 22, 22, 20, 20,\n            \t\t\t\t\t  new ECBlocks(20, new ECB(1, 30)))));\n  VERSIONS.push_back(Ref<Version>(new Version(8, 24, 24, 22, 22,\n            \t\t\t\t\t  new ECBlocks(24, new ECB(1, 36)))));\n  VERSIONS.push_back(Ref<Version>(new Version(9, 26, 26, 24, 24,\n            \t\t\t\t\t  new ECBlocks(28, new ECB(1, 44)))));\n  VERSIONS.push_back(Ref<Version>(new Version(10, 32, 32, 14, 14,\n            \t\t\t\t\t  new ECBlocks(36, new ECB(1, 62)))));\n  VERSIONS.push_back(Ref<Version>(new Version(11, 36, 36, 16, 16,\n            \t\t\t\t\t  new ECBlocks(42, new ECB(1, 86)))));\n  VERSIONS.push_back(Ref<Version>(new Version(12, 40, 40, 18, 18,\n            \t\t\t\t\t  new ECBlocks(48, new ECB(1, 114)))));\n  VERSIONS.push_back(Ref<Version>(new Version(13, 44, 44, 20, 20,\n            \t\t\t\t\t  new ECBlocks(56, new ECB(1, 144)))));\n  VERSIONS.push_back(Ref<Version>(new Version(14, 48, 48, 22, 22,\n            \t\t\t\t\t  new ECBlocks(68, new ECB(1, 174)))));\n  VERSIONS.push_back(Ref<Version>(new Version(15, 52, 52, 24, 24,\n            \t\t\t\t\t  new ECBlocks(42, new ECB(2, 102)))));\n  VERSIONS.push_back(Ref<Version>(new Version(16, 64, 64, 14, 14,\n            \t\t\t\t\t  new ECBlocks(56, new ECB(2, 140)))));\n  VERSIONS.push_back(Ref<Version>(new Version(17, 72, 72, 16, 16,\n            \t\t\t\t\t  new ECBlocks(36, new ECB(4, 92)))));\n  VERSIONS.push_back(Ref<Version>(new  Version(18, 80, 80, 18, 18,\n            \t\t\t\t\t  new ECBlocks(48, new ECB(4, 114)))));\n  VERSIONS.push_back(Ref<Version>(new Version(19, 88, 88, 20, 20,\n            \t\t\t\t\t  new ECBlocks(56, new ECB(4, 144)))));\n  VERSIONS.push_back(Ref<Version>(new Version(20, 96, 96, 22, 22,\n            \t\t\t\t\t  new ECBlocks(68, new ECB(4, 174)))));\n  VERSIONS.push_back(Ref<Version>(new Version(21, 104, 104, 24, 24,\n            \t\t\t\t\t  new ECBlocks(56, new ECB(6, 136)))));\n  VERSIONS.push_back(Ref<Version>(new Version(22, 120, 120, 18, 18,\n            \t\t\t\t\t  new ECBlocks(68, new ECB(6, 175)))));\n  VERSIONS.push_back(Ref<Version>(new Version(23, 132, 132, 20, 20,\n            \t\t\t\t\t  new ECBlocks(62, new ECB(8, 163)))));\n  VERSIONS.push_back(Ref<Version>(new Version(24, 144, 144, 22, 22,\n            \t\t\t\t\t  new ECBlocks(62, new ECB(8, 156), new ECB(2, 155)))));\n  VERSIONS.push_back(Ref<Version>(new Version(25, 8, 18, 6, 16,\n            \t\t\t\t\t  new ECBlocks(7, new ECB(1, 5)))));\n  VERSIONS.push_back(Ref<Version>(new Version(26, 8, 32, 6, 14,\n            \t\t\t\t\t  new ECBlocks(11, new ECB(1, 10)))));\n  VERSIONS.push_back(Ref<Version>(new Version(27, 12, 26, 10, 24,\n\t\t\t\t\t              new ECBlocks(14, new ECB(1, 16)))));\n  VERSIONS.push_back(Ref<Version>(new Version(28, 12, 36, 10, 16,\n\t\t\t\t\t              new ECBlocks(18, new ECB(1, 22)))));\n  VERSIONS.push_back(Ref<Version>(new Version(29, 16, 36, 14, 16,\n\t\t\t\t\t              new ECBlocks(24, new ECB(1, 32)))));\n  VERSIONS.push_back(Ref<Version>(new Version(30, 16, 48, 14, 22,\n\t\t\t\t\t              new ECBlocks(28, new ECB(1, 49)))));\n  return (int)VERSIONS.size();\n}\n}\n}\n\n// file: zxing/datamatrix/decoder/BitMatrixParser.cpp\n\n/*\n *  BitMatrixParser.cpp\n *  zxing\n *\n *  Created by Luiz Silva on 09/02/2010.\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/datamatrix/decoder/BitMatrixParser.h>\n// #include <zxing/common/IllegalArgumentException.h>\n\n// #include <iostream>\n\nnamespace zxing {\nnamespace datamatrix {\n\nint BitMatrixParser::copyBit(size_t x, size_t y, int versionBits) {\n  return bitMatrix_->get(x, y) ? (versionBits << 1) | 0x1 : versionBits << 1;\n}\n\nBitMatrixParser::BitMatrixParser(Ref<BitMatrix> bitMatrix) : bitMatrix_(NULL),\n                                                             parsedVersion_(NULL),\n                                                             readBitMatrix_(NULL) {\n  size_t dimension = bitMatrix->getDimension();\n  if (dimension < 8 || dimension > 144 || (dimension & 0x01) != 0)\n    throw ReaderException(\"Dimension must be even, > 8 < 144\");\n\n  parsedVersion_ = readVersion(bitMatrix);\n  bitMatrix_ = extractDataRegion(bitMatrix);\n  readBitMatrix_ = new BitMatrix(bitMatrix_->getWidth(), bitMatrix_->getHeight());\n}\n\nRef<Version> BitMatrixParser::readVersion(Ref<BitMatrix> bitMatrix) {\n  if (parsedVersion_ != 0) {\n    return parsedVersion_;\n  }\n\n  int numRows = (int)bitMatrix->getHeight();//getDimension();\n  int numColumns = (int)bitMatrix->getWidth();//numRows;\n\n  Ref<Version> version = parsedVersion_->getVersionForDimensions(numRows, numColumns);\n  if (version != 0) {\n    return version;\n  }\n  throw ReaderException(\"Couldn't decode version\");\n}\n\nArrayRef<unsigned char> BitMatrixParser::readCodewords() {\n  \tArrayRef<unsigned char> result(parsedVersion_->getTotalCodewords());\n  \tint resultOffset = 0;\n    int row = 4;\n    int column = 0;\n\n    int numRows = (int)bitMatrix_->getHeight();\n    int numColumns = (int)bitMatrix_->getWidth();\n\n    bool corner1Read = false;\n    bool corner2Read = false;\n    bool corner3Read = false;\n    bool corner4Read = false;\n\n    // Read all of the codewords\n    do {\n      // Check the four corner cases\n      if ((row == numRows) && (column == 0) && !corner1Read) {\n        result[resultOffset++] = (unsigned char) readCorner1(numRows, numColumns);\n        row -= 2;\n        column +=2;\n        corner1Read = true;\n      } else if ((row == numRows-2) && (column == 0) && ((numColumns & 0x03) != 0) && !corner2Read) {\n        result[resultOffset++] = (unsigned char) readCorner2(numRows, numColumns);\n        row -= 2;\n        column +=2;\n        corner2Read = true;\n      } else if ((row == numRows+4) && (column == 2) && ((numColumns & 0x07) == 0) && !corner3Read) {\n        result[resultOffset++] = (unsigned char) readCorner3(numRows, numColumns);\n        row -= 2;\n        column +=2;\n        corner3Read = true;\n      } else if ((row == numRows-2) && (column == 0) && ((numColumns & 0x07) == 4) && !corner4Read) {\n        result[resultOffset++] = (unsigned char) readCorner4(numRows, numColumns);\n        row -= 2;\n        column +=2;\n        corner4Read = true;\n      } else {\n        // Sweep upward diagonally to the right\n        do {\n          if ((row < numRows) && (column >= 0) && !readBitMatrix_->get(column, row)) {\n            result[resultOffset++] = (unsigned char) readUtah(row, column, numRows, numColumns);\n          }\n          row -= 2;\n          column +=2;\n        } while ((row >= 0) && (column < numColumns));\n        row += 1;\n        column +=3;\n\n        // Sweep downward diagonally to the left\n        do {\n          if ((row >= 0) && (column < numColumns) && !readBitMatrix_->get(column, row)) {\n             result[resultOffset++] = (unsigned char) readUtah(row, column, numRows, numColumns);\n          }\n          row += 2;\n          column -=2;\n        } while ((row < numRows) && (column >= 0));\n        row += 3;\n        column +=1;\n      }\n    } while ((row < numRows) || (column < numColumns));\n\n    if (resultOffset != parsedVersion_->getTotalCodewords()) {\n      throw ReaderException(\"Did not read all codewords\");\n    }\n    return result;\n}\n\nbool BitMatrixParser::readModule(int row, int column, int numRows, int numColumns) {\n    // Adjust the row and column indices based on boundary wrapping\n    if (row < 0) {\n      row += numRows;\n      column += 4 - ((numRows + 4) & 0x07);\n    }\n    if (column < 0) {\n      column += numColumns;\n      row += 4 - ((numColumns + 4) & 0x07);\n    }\n    readBitMatrix_->set(column, row);\n    return bitMatrix_->get(column, row);\n  }\n\nint BitMatrixParser::readUtah(int row, int column, int numRows, int numColumns) {\n    int currentByte = 0;\n    if (readModule(row - 2, column - 2, numRows, numColumns)) {\n      currentByte |= 1;\n    }\n    currentByte <<= 1;\n    if (readModule(row - 2, column - 1, numRows, numColumns)) {\n      currentByte |= 1;\n    }\n    currentByte <<= 1;\n    if (readModule(row - 1, column - 2, numRows, numColumns)) {\n      currentByte |= 1;\n    }\n    currentByte <<= 1;\n    if (readModule(row - 1, column - 1, numRows, numColumns)) {\n      currentByte |= 1;\n    }\n    currentByte <<= 1;\n    if (readModule(row - 1, column, numRows, numColumns)) {\n      currentByte |= 1;\n    }\n    currentByte <<= 1;\n    if (readModule(row, column - 2, numRows, numColumns)) {\n      currentByte |= 1;\n    }\n    currentByte <<= 1;\n    if (readModule(row, column - 1, numRows, numColumns)) {\n      currentByte |= 1;\n    }\n    currentByte <<= 1;\n    if (readModule(row, column, numRows, numColumns)) {\n      currentByte |= 1;\n    }\n    return currentByte;\n  }\n\nint BitMatrixParser::readCorner1(int numRows, int numColumns) {\n    int currentByte = 0;\n    if (readModule(numRows - 1, 0, numRows, numColumns)) {\n      currentByte |= 1;\n    }\n    currentByte <<= 1;\n    if (readModule(numRows - 1, 1, numRows, numColumns)) {\n      currentByte |= 1;\n    }\n    currentByte <<= 1;\n    if (readModule(numRows - 1, 2, numRows, numColumns)) {\n      currentByte |= 1;\n    }\n    currentByte <<= 1;\n    if (readModule(0, numColumns - 2, numRows, numColumns)) {\n      currentByte |= 1;\n    }\n    currentByte <<= 1;\n    if (readModule(0, numColumns - 1, numRows, numColumns)) {\n      currentByte |= 1;\n    }\n    currentByte <<= 1;\n    if (readModule(1, numColumns - 1, numRows, numColumns)) {\n      currentByte |= 1;\n    }\n    currentByte <<= 1;\n    if (readModule(2, numColumns - 1, numRows, numColumns)) {\n      currentByte |= 1;\n    }\n    currentByte <<= 1;\n    if (readModule(3, numColumns - 1, numRows, numColumns)) {\n      currentByte |= 1;\n    }\n    return currentByte;\n  }\n\nint BitMatrixParser::readCorner2(int numRows, int numColumns) {\n    int currentByte = 0;\n    if (readModule(numRows - 3, 0, numRows, numColumns)) {\n      currentByte |= 1;\n    }\n    currentByte <<= 1;\n    if (readModule(numRows - 2, 0, numRows, numColumns)) {\n      currentByte |= 1;\n    }\n    currentByte <<= 1;\n    if (readModule(numRows - 1, 0, numRows, numColumns)) {\n      currentByte |= 1;\n    }\n    currentByte <<= 1;\n    if (readModule(0, numColumns - 4, numRows, numColumns)) {\n      currentByte |= 1;\n    }\n    currentByte <<= 1;\n    if (readModule(0, numColumns - 3, numRows, numColumns)) {\n      currentByte |= 1;\n    }\n    currentByte <<= 1;\n    if (readModule(0, numColumns - 2, numRows, numColumns)) {\n      currentByte |= 1;\n    }\n    currentByte <<= 1;\n    if (readModule(0, numColumns - 1, numRows, numColumns)) {\n      currentByte |= 1;\n    }\n    currentByte <<= 1;\n    if (readModule(1, numColumns - 1, numRows, numColumns)) {\n      currentByte |= 1;\n    }\n    return currentByte;\n  }\n\nint BitMatrixParser::readCorner3(int numRows, int numColumns) {\n    int currentByte = 0;\n    if (readModule(numRows - 1, 0, numRows, numColumns)) {\n      currentByte |= 1;\n    }\n    currentByte <<= 1;\n    if (readModule(numRows - 1, numColumns - 1, numRows, numColumns)) {\n      currentByte |= 1;\n    }\n    currentByte <<= 1;\n    if (readModule(0, numColumns - 3, numRows, numColumns)) {\n      currentByte |= 1;\n    }\n    currentByte <<= 1;\n    if (readModule(0, numColumns - 2, numRows, numColumns)) {\n      currentByte |= 1;\n    }\n    currentByte <<= 1;\n    if (readModule(0, numColumns - 1, numRows, numColumns)) {\n      currentByte |= 1;\n    }\n    currentByte <<= 1;\n    if (readModule(1, numColumns - 3, numRows, numColumns)) {\n      currentByte |= 1;\n    }\n    currentByte <<= 1;\n    if (readModule(1, numColumns - 2, numRows, numColumns)) {\n      currentByte |= 1;\n    }\n    currentByte <<= 1;\n    if (readModule(1, numColumns - 1, numRows, numColumns)) {\n      currentByte |= 1;\n    }\n    return currentByte;\n  }\n\nint BitMatrixParser::readCorner4(int numRows, int numColumns) {\n    int currentByte = 0;\n    if (readModule(numRows - 3, 0, numRows, numColumns)) {\n      currentByte |= 1;\n    }\n    currentByte <<= 1;\n    if (readModule(numRows - 2, 0, numRows, numColumns)) {\n      currentByte |= 1;\n    }\n    currentByte <<= 1;\n    if (readModule(numRows - 1, 0, numRows, numColumns)) {\n      currentByte |= 1;\n    }\n    currentByte <<= 1;\n    if (readModule(0, numColumns - 2, numRows, numColumns)) {\n      currentByte |= 1;\n    }\n    currentByte <<= 1;\n    if (readModule(0, numColumns - 1, numRows, numColumns)) {\n      currentByte |= 1;\n    }\n    currentByte <<= 1;\n    if (readModule(1, numColumns - 1, numRows, numColumns)) {\n      currentByte |= 1;\n    }\n    currentByte <<= 1;\n    if (readModule(2, numColumns - 1, numRows, numColumns)) {\n      currentByte |= 1;\n    }\n    currentByte <<= 1;\n    if (readModule(3, numColumns - 1, numRows, numColumns)) {\n      currentByte |= 1;\n    }\n    return currentByte;\n  }\n\nRef<BitMatrix> BitMatrixParser::extractDataRegion(Ref<BitMatrix> bitMatrix) {\n    int symbolSizeRows = parsedVersion_->getSymbolSizeRows();\n    int symbolSizeColumns = parsedVersion_->getSymbolSizeColumns();\n\n    if ((int)bitMatrix->getHeight() != symbolSizeRows) {\n      throw IllegalArgumentException(\"Dimension of bitMatrix must match the version size\");\n    }\n\n    int dataRegionSizeRows = parsedVersion_->getDataRegionSizeRows();\n    int dataRegionSizeColumns = parsedVersion_->getDataRegionSizeColumns();\n\n    int numDataRegionsRow = symbolSizeRows / dataRegionSizeRows;\n    int numDataRegionsColumn = symbolSizeColumns / dataRegionSizeColumns;\n\n    int sizeDataRegionRow = numDataRegionsRow * dataRegionSizeRows;\n    int sizeDataRegionColumn = numDataRegionsColumn * dataRegionSizeColumns;\n\n    Ref<BitMatrix> bitMatrixWithoutAlignment(new BitMatrix(sizeDataRegionColumn, sizeDataRegionRow));\n    for (int dataRegionRow = 0; dataRegionRow < numDataRegionsRow; ++dataRegionRow) {\n      int dataRegionRowOffset = dataRegionRow * dataRegionSizeRows;\n      for (int dataRegionColumn = 0; dataRegionColumn < numDataRegionsColumn; ++dataRegionColumn) {\n        int dataRegionColumnOffset = dataRegionColumn * dataRegionSizeColumns;\n        for (int i = 0; i < dataRegionSizeRows; ++i) {\n          int readRowOffset = dataRegionRow * (dataRegionSizeRows + 2) + 1 + i;\n          int writeRowOffset = dataRegionRowOffset + i;\n          for (int j = 0; j < dataRegionSizeColumns; ++j) {\n            int readColumnOffset = dataRegionColumn * (dataRegionSizeColumns + 2) + 1 + j;\n            if (bitMatrix->get(readColumnOffset, readRowOffset)) {\n              int writeColumnOffset = dataRegionColumnOffset + j;\n              bitMatrixWithoutAlignment->set(writeColumnOffset, writeRowOffset);\n            }\n          }\n        }\n      }\n    }\n    return bitMatrixWithoutAlignment;\n}\n\n}\n}\n\n// file: zxing/datamatrix/decoder/DataBlock.cpp\n\n/*\n *  DataBlock.cpp\n *  zxing\n *\n *  Created by Luiz Silva on 09/02/2010.\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/datamatrix/decoder/DataBlock.h>\n// #include <zxing/common/IllegalArgumentException.h>\n\nnamespace zxing {\nnamespace datamatrix {\n\nusing namespace std;\n\nDataBlock::DataBlock(int numDataCodewords, ArrayRef<unsigned char> codewords) :\n    numDataCodewords_(numDataCodewords), codewords_(codewords) {\n}\n\nint DataBlock::getNumDataCodewords() {\n  return numDataCodewords_;\n}\n\nArrayRef<unsigned char> DataBlock::getCodewords() {\n  return codewords_;\n}\n\nstd::vector<Ref<DataBlock> > DataBlock::getDataBlocks(ArrayRef<unsigned char> rawCodewords, Version *version) {\n  // Figure out the number and size of data blocks used by this version and\n  // error correction level\n  ECBlocks* ecBlocks = version->getECBlocks();\n\n  // First count the total number of data blocks\n  int totalBlocks = 0;\n  vector<ECB*> ecBlockArray = ecBlocks->getECBlocks();\n  for (size_t i = 0; i < ecBlockArray.size(); i++) {\n    totalBlocks += ecBlockArray[i]->getCount();\n  }\n\n  // Now establish DataBlocks of the appropriate size and number of data codewords\n  std::vector<Ref<DataBlock> > result(totalBlocks);\n  int numResultBlocks = 0;\n  for (size_t j = 0; j < ecBlockArray.size(); j++) {\n    ECB *ecBlock = ecBlockArray[j];\n    for (int i = 0; i < ecBlock->getCount(); i++) {\n      int numDataCodewords = ecBlock->getDataCodewords();\n      int numBlockCodewords = ecBlocks->getECCodewords() + numDataCodewords;\n      ArrayRef<unsigned char> buffer(numBlockCodewords);\n      Ref<DataBlock> blockRef(new DataBlock(numDataCodewords, buffer));\n      result[numResultBlocks++] = blockRef;\n    }\n  }\n\n  // All blocks have the same amount of data, except that the last n\n  // (where n may be 0) have 1 more byte. Figure out where these start.\n  int shorterBlocksTotalCodewords = (int)result[0]->codewords_.size();\n  int longerBlocksStartAt = (int)(result.size() - 1);\n  while (longerBlocksStartAt >= 0) {\n    int numCodewords = (int)result[longerBlocksStartAt]->codewords_.size();\n    if (numCodewords == shorterBlocksTotalCodewords) {\n      break;\n    }\n    if (numCodewords != shorterBlocksTotalCodewords + 1) {\n      throw IllegalArgumentException(\"Data block sizes differ by more than 1\");\n    }\n    longerBlocksStartAt--;\n  }\n  longerBlocksStartAt++;\n\n  int shorterBlocksNumDataCodewords = shorterBlocksTotalCodewords - ecBlocks->getECCodewords();\n  // The last elements of result may be 1 element longer;\n  // first fill out as many elements as all of them have\n  int rawCodewordsOffset = 0;\n  for (int i = 0; i < shorterBlocksNumDataCodewords; i++) {\n    for (int j = 0; j < numResultBlocks; j++) {\n      result[j]->codewords_[i] = rawCodewords[rawCodewordsOffset++];\n    }\n  }\n  // Fill out the last data block in the longer ones\n  for (int j = longerBlocksStartAt; j < numResultBlocks; j++) {\n    result[j]->codewords_[shorterBlocksNumDataCodewords] = rawCodewords[rawCodewordsOffset++];\n  }\n  // Now add in error correction blocks\n  int max = (int)result[0]->codewords_.size();\n  for (int i = shorterBlocksNumDataCodewords; i < max; i++) {\n    for (int j = 0; j < numResultBlocks; j++) {\n      int iOffset = j < longerBlocksStartAt ? i : i + 1;\n      result[j]->codewords_[iOffset] = rawCodewords[rawCodewordsOffset++];\n    }\n  }\n\n  if ((size_t)rawCodewordsOffset != rawCodewords.size()) {\n    throw IllegalArgumentException(\"rawCodewordsOffset != rawCodewords.length\");\n  }\n\n  return result;\n}\n\n}\n}\n\n// file: zxing/datamatrix/decoder/DecodedBitStreamParser.cpp\n\n/*\n *  DecodedBitStreamParser.cpp\n *  zxing\n *\n *  Created by Luiz Silva on 09/02/2010.\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/FormatException.h>\n// #include <zxing/datamatrix/decoder/DecodedBitStreamParser.h>\n// #include <iostream>\n// #include <zxing/common/DecoderResult.h>\n\nnamespace zxing {\nnamespace datamatrix {\n\nusing namespace std;\n\nconst char DecodedBitStreamParser::C40_BASIC_SET_CHARS[] = {\n    '*', '*', '*', ' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',\n    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',\n    'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'\n};\n\nconst char DecodedBitStreamParser::C40_SHIFT2_SET_CHARS[] = {\n    '!', '\"', '#', '$', '%', '&', '\\'', '(', ')', '*', '+', ',', '-', '.',\n    '/', ':', ';', '<', '=', '>', '?', '@', '[', '\\\\', ']', '^', '_'\n};\n\nconst char DecodedBitStreamParser::TEXT_BASIC_SET_CHARS[] = {\n    '*', '*', '*', ' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',\n    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',\n    'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'\n};\n\nconst char DecodedBitStreamParser::TEXT_SHIFT3_SET_CHARS[] = {\n    '\\'', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',\n    'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '{', '|', '}', '~', (char) 127\n};\n\nRef<DecoderResult> DecodedBitStreamParser::decode(ArrayRef<unsigned char> bytes) {\n  Ref<BitSource> bits(new BitSource(bytes));\n  ostringstream result;\n  ostringstream resultTrailer;\n  vector<unsigned char> byteSegments;\n  int mode = ASCII_ENCODE;\n  do {\n    if (mode == ASCII_ENCODE) {\n      mode = decodeAsciiSegment(bits, result, resultTrailer);\n    } else {\n      switch (mode) {\n        case C40_ENCODE:\n          decodeC40Segment(bits, result);\n          break;\n        case TEXT_ENCODE:\n          decodeTextSegment(bits, result);\n          break;\n        case ANSIX12_ENCODE:\n          decodeAnsiX12Segment(bits, result);\n          break;\n        case EDIFACT_ENCODE:\n          decodeEdifactSegment(bits, result);\n          break;\n        case BASE256_ENCODE:\n          decodeBase256Segment(bits, result, byteSegments);\n          break;\n        default:\n          throw FormatException(\"Unsupported mode indicator\");\n      }\n      mode = ASCII_ENCODE;\n    }\n  } while (mode != PAD_ENCODE && bits->available() > 0);\n\n  if (resultTrailer.str().size() > 0) {\n    result << resultTrailer.str();\n  }\n  ArrayRef<unsigned char> rawBytes(bytes);\n  Ref<String> text(new String(result.str()));\n  return Ref<DecoderResult>(new DecoderResult(rawBytes, text));\n}\n\nint DecodedBitStreamParser::decodeAsciiSegment(Ref<BitSource> bits, ostringstream & result,\n  ostringstream & resultTrailer) {\n  bool upperShift = false;\n  do {\n    int oneByte = bits->readBits(8);\n    if (oneByte == 0) {\n      throw FormatException(\"Not enough bits to decode\");\n    } else if (oneByte <= 128) {  // ASCII data (ASCII value + 1)\n      oneByte = upperShift ? (oneByte + 128) : oneByte;\n      // upperShift = false;\n      result << (char) (oneByte - 1);\n      return ASCII_ENCODE;\n    } else if (oneByte == 129) {  // Pad\n      return PAD_ENCODE;\n    } else if (oneByte <= 229) {  // 2-digit data 00-99 (Numeric Value + 130)\n      int value = oneByte - 130;\n      if (value < 10) { // padd with '0' for single digit values\n        result << '0';\n      }\n      result << value;\n    } else if (oneByte == 230) {  // Latch to C40 encodation\n      return C40_ENCODE;\n    } else if (oneByte == 231) {  // Latch to Base 256 encodation\n      return BASE256_ENCODE;\n    } else if (oneByte == 232) {  // FNC1\n      result << ((char) 29); // translate as ASCII 29\n    } else if (oneByte == 233 || oneByte == 234) {\n      // Structured Append, Reader Programming\n      // Ignore these symbols for now\n      // throw FormatException.getInstance();\n    } else if (oneByte == 235) {  // Upper Shift (shift to Extended ASCII)\n      upperShift = true;\n    } else if (oneByte == 236) {  // 05 Macro\n        result << (\"[)>RS05GS\");\n        resultTrailer << (\"RSEOT\");\n    } else if (oneByte == 237) {  // 06 Macro\n      result << (\"[)>RS06GS\");\n      resultTrailer <<  (\"RSEOT\");\n    } else if (oneByte == 238) {  // Latch to ANSI X12 encodation\n      return ANSIX12_ENCODE;\n    } else if (oneByte == 239) {  // Latch to Text encodation\n      return TEXT_ENCODE;\n    } else if (oneByte == 240) {  // Latch to EDIFACT encodation\n      return EDIFACT_ENCODE;\n    } else if (oneByte == 241) {  // ECI Character\n      // TODO(bbrown): I think we need to support ECI\n      // throw FormatException.getInstance();\n      // Ignore this symbol for now\n    } else if (oneByte >= 242) { // Not to be used in ASCII encodation\n      // ... but work around encoders that end with 254, latch back to ASCII\n      if (oneByte == 254 && bits->available() == 0) {\n        // Ignore\n      } else {\n        throw FormatException(\"Not to be used in ASCII encodation\");\n      }\n    }\n  } while (bits->available() > 0);\n  return ASCII_ENCODE;\n}\n\nvoid DecodedBitStreamParser::decodeC40Segment(Ref<BitSource> bits, ostringstream & result) {\n  // Three C40 values are encoded in a 16-bit value as\n  // (1600 * C1) + (40 * C2) + C3 + 1\n  // TODO(bbrown): The Upper Shift with C40 doesn't work in the 4 value scenario all the time\n  bool upperShift = false;\n\n  int* cValues = new int[3];\n  int shift = 0;\n  do {\n    // If there is only one byte left then it will be encoded as ASCII\n    if (bits->available() == 8) {\n      return;\n    }\n    int firstByte = bits->readBits(8);\n    if (firstByte == 254) {  // Unlatch codeword\n      return;\n    }\n\n    parseTwoBytes(firstByte, bits->readBits(8), cValues);\n\n    for (int i = 0; i < 3; i++) {\n      int cValue = cValues[i];\n      switch (shift) {\n        case 0:\n          if (cValue < 3) {\n            shift = cValue + 1;\n          } else {\n            if (upperShift) {\n              result << (char) (C40_BASIC_SET_CHARS[cValue] + 128);\n              upperShift = false;\n            } else {\n              result << C40_BASIC_SET_CHARS[cValue];\n            }\n          }\n          break;\n        case 1:\n          if (upperShift) {\n            result << (char) (cValue + 128);\n            upperShift = false;\n          } else {\n            result << (char) cValue;\n          }\n          shift = 0;\n          break;\n        case 2:\n          if (cValue < 27) {\n            if (upperShift) {\n              result << (char) (C40_SHIFT2_SET_CHARS[cValue] + 128);\n              upperShift = false;\n            } else {\n              result << C40_SHIFT2_SET_CHARS[cValue];\n            }\n          } else if (cValue == 27) {  // FNC1\n            result << ((char) 29); // translate as ASCII 29\n          } else if (cValue == 30) {  // Upper Shift\n            upperShift = true;\n          } else {\n            throw FormatException(\"decodeC40Segment: Upper Shift\");\n          }\n          shift = 0;\n          break;\n        case 3:\n          if (upperShift) {\n            result << (char) (cValue + 224);\n            upperShift = false;\n          } else {\n            result << (char) (cValue + 96);\n          }\n          shift = 0;\n          break;\n        default:\n          throw FormatException(\"decodeC40Segment: no case\");\n      }\n    }\n  } while (bits->available() > 0);\n}\n\nvoid DecodedBitStreamParser::decodeTextSegment(Ref<BitSource> bits, ostringstream & result) {\n  // Three Text values are encoded in a 16-bit value as\n  // (1600 * C1) + (40 * C2) + C3 + 1\n  // TODO(bbrown): The Upper Shift with Text doesn't work in the 4 value scenario all the time\n  bool upperShift = false;\n\n  int* cValues = new int[3];\n  int shift = 0;\n  do {\n    // If there is only one byte left then it will be encoded as ASCII\n    if (bits->available() == 8) {\n      return;\n    }\n    int firstByte = bits->readBits(8);\n    if (firstByte == 254) {  // Unlatch codeword\n      return;\n    }\n\n    parseTwoBytes(firstByte, bits->readBits(8), cValues);\n\n    for (int i = 0; i < 3; i++) {\n      int cValue = cValues[i];\n      switch (shift) {\n        case 0:\n          if (cValue < 3) {\n            shift = cValue + 1;\n          } else {\n            if (upperShift) {\n              result << (char) (TEXT_BASIC_SET_CHARS[cValue] + 128);\n              upperShift = false;\n            } else {\n              result << (TEXT_BASIC_SET_CHARS[cValue]);\n            }\n          }\n          break;\n        case 1:\n          if (upperShift) {\n            result << (char) (cValue + 128);\n            upperShift = false;\n          } else {\n            result << (char) (cValue);\n          }\n          shift = 0;\n          break;\n        case 2:\n          // Shift 2 for Text is the same encoding as C40\n          if (cValue < 27) {\n            if (upperShift) {\n              result << (char) (C40_SHIFT2_SET_CHARS[cValue] + 128);\n              upperShift = false;\n            } else {\n              result << (C40_SHIFT2_SET_CHARS[cValue]);\n            }\n          } else if (cValue == 27) {  // FNC1\n            result << ((char) 29); // translate as ASCII 29\n          } else if (cValue == 30) {  // Upper Shift\n            upperShift = true;\n          } else {\n            throw FormatException(\"decodeTextSegment: Upper Shift\");\n          }\n          shift = 0;\n          break;\n        case 3:\n          if (upperShift) {\n            result << (char) (TEXT_SHIFT3_SET_CHARS[cValue] + 128);\n            upperShift = false;\n          } else {\n            result << (TEXT_SHIFT3_SET_CHARS[cValue]);\n          }\n          shift = 0;\n          break;\n        default:\n          throw FormatException(\"decodeTextSegment: no case\");\n      }\n    }\n  } while (bits->available() > 0);\n}\n\nvoid DecodedBitStreamParser::decodeAnsiX12Segment(Ref<BitSource> bits, ostringstream & result) {\n  // Three ANSI X12 values are encoded in a 16-bit value as\n  // (1600 * C1) + (40 * C2) + C3 + 1\n\n  int* cValues = new int[3];\n  do {\n    // If there is only one byte left then it will be encoded as ASCII\n    if (bits->available() == 8) {\n      return;\n    }\n    int firstByte = bits->readBits(8);\n    if (firstByte == 254) {  // Unlatch codeword\n      return;\n    }\n\n    parseTwoBytes(firstByte, bits->readBits(8), cValues);\n\n    for (int i = 0; i < 3; i++) {\n      int cValue = cValues[i];\n      if (cValue == 0) {  // X12 segment terminator <CR>\n        result << '\\r';\n      } else if (cValue == 1) {  // X12 segment separator *\n        result << '*';\n      } else if (cValue == 2) {  // X12 sub-element separator >\n        result << '>';\n      } else if (cValue == 3) {  // space\n        result << ' ';\n      } else if (cValue < 14) {  // 0 - 9\n        result << (char) (cValue + 44);\n      } else if (cValue < 40) {  // A - Z\n        result << (char) (cValue + 51);\n      } else {\n        throw FormatException(\"decodeAnsiX12Segment: no case\");\n      }\n    }\n  } while (bits->available() > 0);\n}\n\nvoid DecodedBitStreamParser::parseTwoBytes(int firstByte, int secondByte, int*& result) {\n  int fullBitValue = (firstByte << 8) + secondByte - 1;\n  int temp = fullBitValue / 1600;\n  result[0] = temp;\n  fullBitValue -= temp * 1600;\n  temp = fullBitValue / 40;\n  result[1] = temp;\n  result[2] = fullBitValue - temp * 40;\n}\n\nvoid DecodedBitStreamParser::decodeEdifactSegment(Ref<BitSource> bits, ostringstream & result) {\n  bool unlatch = false;\n  do {\n    // If there is only two or less bytes left then it will be encoded as ASCII\n    if (bits->available() <= 16) {\n      return;\n    }\n\n    for (int i = 0; i < 4; i++) {\n      int edifactValue = bits->readBits(6);\n\n      // Check for the unlatch character\n      if (edifactValue == 0x2B67) {  // 011111\n        unlatch = true;\n        // If we encounter the unlatch code then continue reading because the Codeword triple\n        // is padded with 0's\n      }\n\n      if (!unlatch) {\n        if ((edifactValue & 0x20) == 0) {  // no 1 in the leading (6th) bit\n          edifactValue |= 0x40;  // Add a leading 01 to the 6 bit binary value\n        }\n        result << (char)(edifactValue);\n      }\n    }\n  } while (!unlatch && bits->available() > 0);\n}\n\nvoid DecodedBitStreamParser::decodeBase256Segment(Ref<BitSource> bits, ostringstream& result, vector<unsigned char> byteSegments) {\n  // Figure out how long the Base 256 Segment is.\n  int codewordPosition = 1 + bits->getByteOffset(); // position is 1-indexed\n  int d1 = unrandomize255State(bits->readBits(8), codewordPosition++);\n  int count;\n  if (d1 == 0) {  // Read the remainder of the symbol\n    count = bits->available() / 8;\n  } else if (d1 < 250) {\n    count = d1;\n  } else {\n    count = 250 * (d1 - 249) + unrandomize255State(bits->readBits(8), codewordPosition++);\n  }\n\n  // We're seeing NegativeArraySizeException errors from users.\n  if (count < 0) {\n    throw FormatException(\"NegativeArraySizeException\");\n  }\n\n  unsigned char* bytes = new unsigned char[count];\n  for (int i = 0; i < count; i++) {\n    // Have seen this particular error in the wild, such as at\n    // http://www.bcgen.com/demo/IDAutomationStreamingDataMatrix.aspx?MODE=3&D=Fred&PFMT=3&PT=F&X=0.3&O=0&LM=0.2\n    if (bits->available() < 8) {\n      throw FormatException(\"byteSegments\");\n    }\n    bytes[i] = unrandomize255State(bits->readBits(8), codewordPosition++);\n    byteSegments.push_back(bytes[i]);\n    result << (char)bytes[i];\n  }\n}\n}\n}\n\n\n// file: zxing/datamatrix/decoder/Decoder.cpp\n\n/*\n *  Decoder.cpp\n *  zxing\n *\n *  Created by Luiz Silva on 09/02/2010.\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/datamatrix/decoder/Decoder.h>\n// #include <zxing/datamatrix/decoder/BitMatrixParser.h>\n// #include <zxing/datamatrix/decoder/DataBlock.h>\n// #include <zxing/datamatrix/decoder/DecodedBitStreamParser.h>\n// #include <zxing/datamatrix/Version.h>\n// #include <zxing/ReaderException.h>\n// #include <zxing/common/reedsolomon/ReedSolomonException.h>\n\nnamespace zxing {\nnamespace datamatrix {\n\nusing namespace std;\n\nDecoder::Decoder() :\n    rsDecoder_(GF256::DATA_MATRIX_FIELD) {\n}\n\n\nvoid Decoder::correctErrors(ArrayRef<unsigned char> codewordBytes, int numDataCodewords) {\n  int numCodewords = (int)codewordBytes->size();\n  ArrayRef<int> codewordInts(numCodewords);\n  for (int i = 0; i < numCodewords; i++) {\n    codewordInts[i] = codewordBytes[i] & 0xff;\n  }\n  int numECCodewords = numCodewords - numDataCodewords;\n  try {\n    rsDecoder_.decode(codewordInts, numECCodewords);\n  } catch (ReedSolomonException const& ex) {\n    ReaderException rex(ex.what());\n    throw rex;\n  }\n  // Copy back into array of bytes -- only need to worry about the bytes that were data\n  // We don't care about errors in the error-correction codewords\n  for (int i = 0; i < numDataCodewords; i++) {\n    codewordBytes[i] = (unsigned char)codewordInts[i];\n  }\n}\n\nRef<DecoderResult> Decoder::decode(Ref<BitMatrix> bits) {\n  // Construct a parser and read version, error-correction level\n  BitMatrixParser parser(bits);\n  Version *version = parser.readVersion(bits);\n\n  // Read codewords\n  ArrayRef<unsigned char> codewords(parser.readCodewords());\n  // Separate into data blocks\n  std::vector<Ref<DataBlock> > dataBlocks = DataBlock::getDataBlocks(codewords, version);\n\n  int dataBlocksCount = (int)dataBlocks.size();\n\n  // Count total number of data bytes\n  int totalBytes = 0;\n  for (int i = 0; i < dataBlocksCount; i++) {\n    totalBytes += dataBlocks[i]->getNumDataCodewords();\n  }\n  ArrayRef<unsigned char> resultBytes(totalBytes);\n\n  // Error-correct and copy data blocks together into a stream of bytes\n  for (int j = 0; j < dataBlocksCount; j++) {\n    Ref<DataBlock> dataBlock(dataBlocks[j]);\n    ArrayRef<unsigned char> codewordBytes = dataBlock->getCodewords();\n    int numDataCodewords = dataBlock->getNumDataCodewords();\n    correctErrors(codewordBytes, numDataCodewords);\n    for (int i = 0; i < numDataCodewords; i++) {\n      // De-interlace data blocks.\n      resultBytes[i * dataBlocksCount + j] = codewordBytes[i];\n    }\n  }\n  // Decode the contents of that stream of bytes\n  DecodedBitStreamParser decodedBSParser;\n  return Ref<DecoderResult> (decodedBSParser.decode(resultBytes));\n}\n}\n}\n\n// file: zxing/datamatrix/detector/CornerPoint.cpp\n\n/*\n *  CornerPoint.cpp\n *  zxing\n *\n *  Created by Luiz Silva on 09/02/2010.\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/datamatrix/detector/CornerPoint.h>\n\n\nnamespace zxing {\n\tnamespace datamatrix {\n\n\t\tusing namespace std;\n\n\t\tCornerPoint::CornerPoint(float posX, float posY) :\n\t\t  ResultPoint(posX,posY), counter_(0) {\n\t\t}\n\n\t\tint CornerPoint::getCount() const {\n\t\t\treturn counter_;\n\t\t}\n\n\t\tvoid CornerPoint::incrementCount() {\n\t\t\tcounter_++;\n\t\t}\n\n\t\tbool CornerPoint::equals(Ref<CornerPoint> other) const {\n\t\t\treturn posX_ == other->getX() && posY_ == other->getY();\n\t\t}\n\n\t}\n}\n\n// file: zxing/datamatrix/detector/Detector.cpp\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n/*\n *  Detector.cpp\n *  zxing\n *\n *  Created by Luiz Silva on 09/02/2010.\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/ResultPoint.h>\n// #include <zxing/common/GridSampler.h>\n// #include <zxing/datamatrix/detector/Detector.h>\n// #include <cmath>\n// #include <sstream>\n// #include <cstdlib>\n\nnamespace zxing {\nnamespace datamatrix {\n\nusing namespace std;\n\nResultPointsAndTransitions::ResultPointsAndTransitions() {\n  Ref<ResultPoint> ref(new ResultPoint(0, 0));\n  from_ = ref;\n  to_ = ref;\n  transitions_ = 0;\n}\n\nResultPointsAndTransitions::ResultPointsAndTransitions(Ref<ResultPoint> from, Ref<ResultPoint> to,\n    int transitions)\n    : to_(to), from_(from), transitions_(transitions) {\n}\n\nRef<ResultPoint> ResultPointsAndTransitions::getFrom() {\n  return from_;\n}\n\nRef<ResultPoint> ResultPointsAndTransitions::getTo() {\n  return to_;\n}\n\nint ResultPointsAndTransitions::getTransitions() {\n  return transitions_;\n}\n\nDetector::Detector(Ref<BitMatrix> image)\n    : image_(image) {\n}\n\nRef<BitMatrix> Detector::getImage() {\n  return image_;\n}\n\nRef<DetectorResult> Detector::detect() {\n  Ref<WhiteRectangleDetector> rectangleDetector_(new WhiteRectangleDetector(image_));\n  std::vector<Ref<ResultPoint> > ResultPoints = rectangleDetector_->detect();\n  Ref<ResultPoint> pointA = ResultPoints[0];\n  Ref<ResultPoint> pointB = ResultPoints[1];\n  Ref<ResultPoint> pointC = ResultPoints[2];\n  Ref<ResultPoint> pointD = ResultPoints[3];\n\n  // Point A and D are across the diagonal from one another,\n  // as are B and C. Figure out which are the solid black lines\n  // by counting transitions\n  std::vector<Ref<ResultPointsAndTransitions> > transitions(4);\n  transitions[0].reset(transitionsBetween(pointA, pointB));\n  transitions[1].reset(transitionsBetween(pointA, pointC));\n  transitions[2].reset(transitionsBetween(pointB, pointD));\n  transitions[3].reset(transitionsBetween(pointC, pointD));\n  insertionSort(transitions);\n\n  // Sort by number of transitions. First two will be the two solid sides; last two\n  // will be the two alternating black/white sides\n  Ref<ResultPointsAndTransitions> lSideOne(transitions[0]);\n  Ref<ResultPointsAndTransitions> lSideTwo(transitions[1]);\n\n  // Figure out which point is their intersection by tallying up the number of times we see the\n  // endpoints in the four endpoints. One will show up twice.\n  Ref<ResultPoint> maybeTopLeft;\n  Ref<ResultPoint> bottomLeft;\n  Ref<ResultPoint> maybeBottomRight;\n  if (lSideOne->getFrom()->equals(lSideOne->getTo())) {\n    bottomLeft = lSideOne->getFrom();\n    maybeTopLeft = lSideTwo->getFrom();\n    maybeBottomRight = lSideTwo->getTo();\n  } else if (lSideOne->getFrom()->equals(lSideTwo->getFrom())) {\n    bottomLeft = lSideOne->getFrom();\n    maybeTopLeft = lSideOne->getTo();\n    maybeBottomRight = lSideTwo->getTo();\n  } else if (lSideOne->getFrom()->equals(lSideTwo->getTo())) {\n    bottomLeft = lSideOne->getFrom();\n    maybeTopLeft = lSideOne->getTo();\n    maybeBottomRight = lSideTwo->getFrom();\n  } else if (lSideOne->getTo()->equals(lSideTwo->getFrom())) {\n    bottomLeft = lSideOne->getTo();\n    maybeTopLeft = lSideOne->getFrom();\n    maybeBottomRight = lSideTwo->getTo();\n  } else if (lSideOne->getTo()->equals(lSideTwo->getTo())) {\n    bottomLeft = lSideOne->getTo();\n    maybeTopLeft = lSideOne->getFrom();\n    maybeBottomRight = lSideTwo->getFrom();\n  } else {\n    bottomLeft = lSideTwo->getFrom();\n    maybeTopLeft = lSideOne->getTo();\n    maybeBottomRight = lSideOne->getFrom();\n  }\n\n  // Bottom left is correct but top left and bottom right might be switched\n  std::vector<Ref<ResultPoint> > corners(3);\n  corners[0].reset(maybeTopLeft);\n  corners[1].reset(bottomLeft);\n  corners[2].reset(maybeBottomRight);\n\n  // Use the dot product trick to sort them out\n  ResultPoint::orderBestPatterns(corners);\n\n  // Now we know which is which:\n  Ref<ResultPoint> bottomRight(corners[0]);\n  bottomLeft = corners[1];\n  Ref<ResultPoint> topLeft(corners[2]);\n\n  // Which point didn't we find in relation to the \"L\" sides? that's the top right corner\n  Ref<ResultPoint> topRight;\n  if (!(pointA->equals(bottomRight) || pointA->equals(bottomLeft) || pointA->equals(topLeft))) {\n    topRight = pointA;\n  } else if (!(pointB->equals(bottomRight) || pointB->equals(bottomLeft)\n      || pointB->equals(topLeft))) {\n    topRight = pointB;\n  } else if (!(pointC->equals(bottomRight) || pointC->equals(bottomLeft)\n      || pointC->equals(topLeft))) {\n    topRight = pointC;\n  } else {\n    topRight = pointD;\n  }\n\n  // Next determine the dimension by tracing along the top or right side and counting black/white\n  // transitions. Since we start inside a black module, we should see a number of transitions\n  // equal to 1 less than the code dimension. Well, actually 2 less, because we are going to\n  // end on a black module:\n\n  // The top right point is actually the corner of a module, which is one of the two black modules\n  // adjacent to the white module at the top right. Tracing to that corner from either the top left\n  // or bottom right should work here.\n\n  int dimensionTop = transitionsBetween(topLeft, topRight)->getTransitions();\n  int dimensionRight = transitionsBetween(bottomRight, topRight)->getTransitions();\n\n  //dimensionTop++;\n  if ((dimensionTop & 0x01) == 1) {\n    // it can't be odd, so, round... up?\n    dimensionTop++;\n  }\n  dimensionTop += 2;\n\n  //dimensionRight++;\n  if ((dimensionRight & 0x01) == 1) {\n    // it can't be odd, so, round... up?\n    dimensionRight++;\n  }\n  dimensionRight += 2;\n\n  Ref<BitMatrix> bits;\n  Ref<PerspectiveTransform> transform;\n  Ref<ResultPoint> correctedTopRight;\n\n\n  // Rectanguar symbols are 6x16, 6x28, 10x24, 10x32, 14x32, or 14x44. If one dimension is more\n  // than twice the other, it's certainly rectangular, but to cut a bit more slack we accept it as\n  // rectangular if the bigger side is at least 7/4 times the other:\n  if (4 * dimensionTop >= 7 * dimensionRight || 4 * dimensionRight >= 7 * dimensionTop) {\n    // The matrix is rectangular\n    correctedTopRight = correctTopRightRectangular(bottomLeft, bottomRight, topLeft, topRight,\n        dimensionTop, dimensionRight);\n    if (correctedTopRight == NULL) {\n      correctedTopRight = topRight;\n    }\n\n    dimensionTop = transitionsBetween(topLeft, correctedTopRight)->getTransitions();\n    dimensionRight = transitionsBetween(bottomRight, correctedTopRight)->getTransitions();\n\n    if ((dimensionTop & 0x01) == 1) {\n      // it can't be odd, so, round... up?\n      dimensionTop++;\n    }\n\n    if ((dimensionRight & 0x01) == 1) {\n      // it can't be odd, so, round... up?\n      dimensionRight++;\n    }\n\n    transform = createTransform(topLeft, correctedTopRight, bottomLeft, bottomRight, dimensionTop,\n        dimensionRight);\n    bits = sampleGrid(image_, dimensionTop, dimensionRight, transform);\n\n  } else {\n    // The matrix is square\n    int dimension = min(dimensionRight, dimensionTop);\n\n    // correct top right point to match the white module\n    correctedTopRight = correctTopRight(bottomLeft, bottomRight, topLeft, topRight, dimension);\n    if (correctedTopRight == NULL) {\n      correctedTopRight = topRight;\n    }\n\n    // Redetermine the dimension using the corrected top right point\n    int dimensionCorrected = max(transitionsBetween(topLeft, correctedTopRight)->getTransitions(),\n        transitionsBetween(bottomRight, correctedTopRight)->getTransitions());\n    dimensionCorrected++;\n    if ((dimensionCorrected & 0x01) == 1) {\n      dimensionCorrected++;\n    }\n\n    transform = createTransform(topLeft, correctedTopRight, bottomLeft, bottomRight,\n        dimensionCorrected, dimensionCorrected);\n    bits = sampleGrid(image_, dimensionCorrected, dimensionCorrected, transform);\n  }\n\n  std::vector<Ref<ResultPoint> > points(4);\n  points[0].reset(topLeft);\n  points[1].reset(bottomLeft);\n  points[2].reset(correctedTopRight);\n  points[3].reset(bottomRight);\n  Ref<DetectorResult> detectorResult(new DetectorResult(bits, points, transform));\n  return detectorResult;\n}\n\n/**\n * Calculates the position of the white top right module using the output of the rectangle detector\n * for a rectangular matrix\n */\nRef<ResultPoint> Detector::correctTopRightRectangular(Ref<ResultPoint> bottomLeft,\n    Ref<ResultPoint> bottomRight, Ref<ResultPoint> topLeft, Ref<ResultPoint> topRight,\n    int dimensionTop, int dimensionRight) {\n\n  float corr = distance(bottomLeft, bottomRight) / (float) dimensionTop;\n  int norm = distance(topLeft, topRight);\n  float cos = (topRight->getX() - topLeft->getX()) / norm;\n  float sin = (topRight->getY() - topLeft->getY()) / norm;\n\n  Ref<ResultPoint> c1(\n      new ResultPoint(topRight->getX() + corr * cos, topRight->getY() + corr * sin));\n\n  corr = distance(bottomLeft, topLeft) / (float) dimensionRight;\n  norm = distance(bottomRight, topRight);\n  cos = (topRight->getX() - bottomRight->getX()) / norm;\n  sin = (topRight->getY() - bottomRight->getY()) / norm;\n\n  Ref<ResultPoint> c2(\n      new ResultPoint(topRight->getX() + corr * cos, topRight->getY() + corr * sin));\n\n  if (!isValid(c1)) {\n    if (isValid(c2)) {\n      return c2;\n    }\n    return Ref<ResultPoint>(NULL);\n  }\n  if (!isValid(c2)) {\n    return c1;\n  }\n\n  int l1 = abs(dimensionTop - transitionsBetween(topLeft, c1)->getTransitions())\n      + abs(dimensionRight - transitionsBetween(bottomRight, c1)->getTransitions());\n  int l2 = abs(dimensionTop - transitionsBetween(topLeft, c2)->getTransitions())\n      + abs(dimensionRight - transitionsBetween(bottomRight, c2)->getTransitions());\n\n  return l1 <= l2 ? c1 : c2;\n}\n\n/**\n * Calculates the position of the white top right module using the output of the rectangle detector\n * for a square matrix\n */\nRef<ResultPoint> Detector::correctTopRight(Ref<ResultPoint> bottomLeft,\n    Ref<ResultPoint> bottomRight, Ref<ResultPoint> topLeft, Ref<ResultPoint> topRight,\n    int dimension) {\n\n  float corr = distance(bottomLeft, bottomRight) / (float) dimension;\n  int norm = distance(topLeft, topRight);\n  float cos = (topRight->getX() - topLeft->getX()) / norm;\n  float sin = (topRight->getY() - topLeft->getY()) / norm;\n\n  Ref<ResultPoint> c1(\n      new ResultPoint(topRight->getX() + corr * cos, topRight->getY() + corr * sin));\n\n  corr = distance(bottomLeft, bottomRight) / (float) dimension;\n  norm = distance(bottomRight, topRight);\n  cos = (topRight->getX() - bottomRight->getX()) / norm;\n  sin = (topRight->getY() - bottomRight->getY()) / norm;\n\n  Ref<ResultPoint> c2(\n      new ResultPoint(topRight->getX() + corr * cos, topRight->getY() + corr * sin));\n\n  if (!isValid(c1)) {\n    if (isValid(c2)) {\n      return c2;\n    }\n    return Ref<ResultPoint>(NULL);\n  }\n  if (!isValid(c2)) {\n    return c1;\n  }\n\n  int l1 = abs(\n      transitionsBetween(topLeft, c1)->getTransitions()\n          - transitionsBetween(bottomRight, c1)->getTransitions());\n  int l2 = abs(\n      transitionsBetween(topLeft, c2)->getTransitions()\n          - transitionsBetween(bottomRight, c2)->getTransitions());\n\n  return l1 <= l2 ? c1 : c2;\n}\n\nbool Detector::isValid(Ref<ResultPoint> p) {\n  return p->getX() >= 0 && p->getX() < image_->getWidth() && p->getY() > 0\n      && p->getY() < image_->getHeight();\n}\n\n// L2 distance\nint Detector::distance(Ref<ResultPoint> a, Ref<ResultPoint> b) {\n  return round(\n      (float) sqrt(\n          (double) (a->getX() - b->getX()) * (a->getX() - b->getX())\n              + (a->getY() - b->getY()) * (a->getY() - b->getY())));\n}\n\nRef<ResultPointsAndTransitions> Detector::transitionsBetween(Ref<ResultPoint> from,\n    Ref<ResultPoint> to) {\n  // See QR Code Detector, sizeOfBlackWhiteBlackRun()\n  int fromX = (int) from->getX();\n  int fromY = (int) from->getY();\n  int toX = (int) to->getX();\n  int toY = (int) to->getY();\n  bool steep = abs(toY - fromY) > abs(toX - fromX);\n  if (steep) {\n    int temp = fromX;\n    fromX = fromY;\n    fromY = temp;\n    temp = toX;\n    toX = toY;\n    toY = temp;\n  }\n\n  int dx = abs(toX - fromX);\n  int dy = abs(toY - fromY);\n  int error = -dx >> 1;\n  int ystep = fromY < toY ? 1 : -1;\n  int xstep = fromX < toX ? 1 : -1;\n  int transitions = 0;\n  bool inBlack = image_->get(steep ? fromY : fromX, steep ? fromX : fromY);\n  for (int x = fromX, y = fromY; x != toX; x += xstep) {\n    bool isBlack = image_->get(steep ? y : x, steep ? x : y);\n    if (isBlack != inBlack) {\n      transitions++;\n      inBlack = isBlack;\n    }\n    error += dy;\n    if (error > 0) {\n      if (y == toY) {\n        break;\n      }\n      y += ystep;\n      error -= dx;\n    }\n  }\n  Ref<ResultPointsAndTransitions> result(new ResultPointsAndTransitions(from, to, transitions));\n  return result;\n}\n\nRef<PerspectiveTransform> Detector::createTransform(Ref<ResultPoint> topLeft,\n    Ref<ResultPoint> topRight, Ref<ResultPoint> bottomLeft, Ref<ResultPoint> bottomRight,\n    int dimensionX, int dimensionY) {\n\n  Ref<PerspectiveTransform> transform(\n      PerspectiveTransform::quadrilateralToQuadrilateral(\n          0.5f,\n          0.5f,\n          dimensionX - 0.5f,\n          0.5f,\n          dimensionX - 0.5f,\n          dimensionY - 0.5f,\n          0.5f,\n          dimensionY - 0.5f,\n          topLeft->getX(),\n          topLeft->getY(),\n          topRight->getX(),\n          topRight->getY(),\n          bottomRight->getX(),\n          bottomRight->getY(),\n          bottomLeft->getX(),\n          bottomLeft->getY()));\n  return transform;\n}\n\nRef<BitMatrix> Detector::sampleGrid(Ref<BitMatrix> image, int dimensionX, int dimensionY,\n    Ref<PerspectiveTransform> transform) {\n  GridSampler &sampler = GridSampler::getInstance();\n  return sampler.sampleGrid(image, dimensionX, dimensionY, transform);\n}\n\nvoid Detector::insertionSort(std::vector<Ref<ResultPointsAndTransitions> > &vector) {\n  int max = (int)vector.size();\n  bool swapped = true;\n  Ref<ResultPointsAndTransitions> value;\n  Ref<ResultPointsAndTransitions> valueB;\n  do {\n    swapped = false;\n    for (int i = 1; i < max; i++) {\n      value = vector[i - 1];\n      if (compare(value, (valueB = vector[i])) > 0){\n        swapped = true;\n        vector[i - 1].reset(valueB);\n        vector[i].reset(value);\n      }\n    }\n  } while (swapped);\n}\n\nint Detector::compare(Ref<ResultPointsAndTransitions> a, Ref<ResultPointsAndTransitions> b) {\n  return a->getTransitions() - b->getTransitions();\n}\n}\n}\n\n// file: zxing/datamatrix/detector/DetectorException.cpp\n\n/*\n * DetectorException.cpp\n *\n *  Created on: Aug 26, 2011\n *      Author: luiz\n */\n\n// #include \"DetectorException.h\"\n\nnamespace zxing {\nnamespace datamatrix {\n\nDetectorException::DetectorException(const char *msg) :\n    Exception(msg) {\n\n}\n\nDetectorException::~DetectorException() throw () {\n  // TODO Auto-generated destructor stub\n}\n\n}\n} /* namespace zxing */\n\n// file: zxing/datamatrix/detector/MonochromeRectangleDetector.cpp\n\n/*\n *  MonochromeRectangleDetector.cpp\n *  zxing\n *\n *  Created by Luiz Silva on 09/02/2010.\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/ReaderException.h>\n// #include <zxing/datamatrix/detector/MonochromeRectangleDetector.h>\n// #include <sstream>\n\nnamespace zxing {\nnamespace datamatrix {\n\nstd::vector<Ref<CornerPoint> > MonochromeRectangleDetector::detect() {\n    int height = (int)image_->getHeight();\n    int width = (int)image_->getWidth();\n    int halfHeight = height >> 1;\n    int halfWidth = width >> 1;\n    int deltaY = max(1, height / (MAX_MODULES << 3));\n    int deltaX = max(1, width / (MAX_MODULES << 3));\n\n    int top = 0;\n    int bottom = height;\n    int left = 0;\n    int right = width;\n    Ref<CornerPoint> pointA(findCornerFromCenter(halfWidth, 0, left, right,\n        halfHeight, -deltaY, top, bottom, halfWidth >> 1));\n    top = (int) pointA->getY() - 1;\n    Ref<CornerPoint> pointB(findCornerFromCenter(halfWidth, -deltaX, left, right,\n        halfHeight, 0, top, bottom, halfHeight >> 1));\n    left = (int) pointB->getX() - 1;\n    Ref<CornerPoint> pointC(findCornerFromCenter(halfWidth, deltaX, left, right,\n        halfHeight, 0, top, bottom, halfHeight >> 1));\n    right = (int) pointC->getX() + 1;\n    Ref<CornerPoint> pointD(findCornerFromCenter(halfWidth, 0, left, right,\n        halfHeight, deltaY, top, bottom, halfWidth >> 1));\n    bottom = (int) pointD->getY() + 1;\n\n    // Go try to find point A again with better information -- might have been off at first.\n    pointA.reset(findCornerFromCenter(halfWidth, 0, left, right,\n        halfHeight, -deltaY, top, bottom, halfWidth >> 2));\n\t  std::vector<Ref<CornerPoint> > corners(4);\n\n  \tcorners[0].reset(pointA);\n  \tcorners[1].reset(pointB);\n  \tcorners[2].reset(pointC);\n  \tcorners[3].reset(pointD);\n    return corners;\n  }\n\nRef<CornerPoint> MonochromeRectangleDetector::findCornerFromCenter(int centerX, int deltaX, int left, int right,\n      int centerY, int deltaY, int top, int bottom, int maxWhiteRun) {\n\tRef<TwoInts> lastRange(NULL);\n    for (int y = centerY, x = centerX;\n         y < bottom && y >= top && x < right && x >= left;\n         y += deltaY, x += deltaX) {\n    Ref<TwoInts> range(NULL);\n      if (deltaX == 0) {\n        // horizontal slices, up and down\n        range = blackWhiteRange(y, maxWhiteRun, left, right, true);\n      } else {\n        // vertical slices, left and right\n        range = blackWhiteRange(x, maxWhiteRun, top, bottom, false);\n      }\n      if (range == NULL) {\n        if (lastRange == NULL) {\n\t\t\t    throw ReaderException(\"Couldn't find corners (lastRange = NULL) \");\n        } else {\n        // lastRange was found\n        if (deltaX == 0) {\n          int lastY = y - deltaY;\n          if (lastRange->start < centerX) {\n            if (lastRange->end > centerX) {\n              // straddle, choose one or the other based on direction\n\t\t\t        Ref<CornerPoint> result(new CornerPoint(deltaY > 0 ? lastRange->start : lastRange->end, lastY));\n\t\t\t        return result;\n            }\n\t\t\t      Ref<CornerPoint> result(new CornerPoint(lastRange->start, lastY));\n\t\t\t      return result;\n          } else {\n\t\t\t      Ref<CornerPoint> result(new CornerPoint(lastRange->end, lastY));\n\t\t\t      return result;\n            }\n        } else {\n          int lastX = x - deltaX;\n          if (lastRange->start < centerY) {\n            if (lastRange->end > centerY) {\n\t\t\t        Ref<CornerPoint> result(new CornerPoint(lastX, deltaX < 0 ? lastRange->start : lastRange->end));\n\t\t\t        return result;\n            }\n\t\t\t      Ref<CornerPoint> result(new CornerPoint(lastX, lastRange->start));\n\t\t\t      return result;\n          } else {\n\t\t\t      Ref<CornerPoint> result(new CornerPoint(lastX, lastRange->end));\n\t\t\t      return result;\n            }\n          }\n        }\n      }\n      lastRange = range;\n    }\n    throw ReaderException(\"Couldn't find corners\");\n  }\n\nRef<TwoInts> MonochromeRectangleDetector::blackWhiteRange(int fixedDimension, int maxWhiteRun, int minDim, int maxDim,\n      bool horizontal) {\n\n\t  int center = (minDim + maxDim) >> 1;\n\n    // Scan left/up first\n    int start = center;\n    while (start >= minDim) {\n      if (horizontal ? image_->get(start, fixedDimension) : image_->get(fixedDimension, start)) {\n        start--;\n      } else {\n        int whiteRunStart = start;\n        do {\n          start--;\n        } while (start >= minDim && !(horizontal ? image_->get(start, fixedDimension) :\n            image_->get(fixedDimension, start)));\n        int whiteRunSize = whiteRunStart - start;\n        if (start < minDim || whiteRunSize > maxWhiteRun) {\n          start = whiteRunStart;\n          break;\n        }\n      }\n    }\n    start++;\n\n    // Then try right/down\n    int end = center;\n    while (end < maxDim) {\n      if (horizontal ? image_->get(end, fixedDimension) : image_->get(fixedDimension, end)) {\n        end++;\n      } else {\n        int whiteRunStart = end;\n        do {\n          end++;\n        } while (end < maxDim && !(horizontal ? image_->get(end, fixedDimension) :\n            image_->get(fixedDimension, end)));\n        int whiteRunSize = end - whiteRunStart;\n        if (end >= maxDim || whiteRunSize > maxWhiteRun) {\n          end = whiteRunStart;\n          break;\n        }\n      }\n    }\n    end--;\n    Ref<TwoInts> result(NULL);\n    if (end > start) {\n\t\tresult = new TwoInts;\n      result->start = start;\n      result->end = end;\n    }\n    return result;\n  }\n}\n}\n\n// file: zxing/multi/ByQuadrantReader.cpp\n\n/*\n *  Copyright 2011 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/multi/ByQuadrantReader.h>\n// #include <zxing/ReaderException.h>\n\nnamespace zxing {\nnamespace multi {\n\nByQuadrantReader::ByQuadrantReader(Reader& delegate) : delegate_(delegate) {}\n\nByQuadrantReader::~ByQuadrantReader(){}\n\nRef<Result> ByQuadrantReader::decode(Ref<BinaryBitmap> image){\n  return decode(image, DecodeHints::DEFAULT_HINT);\n}\n\nRef<Result> ByQuadrantReader::decode(Ref<BinaryBitmap> image, DecodeHints hints){\n  int width = image->getWidth();\n  int height = image->getHeight();\n  int halfWidth = width / 2;\n  int halfHeight = height / 2;\n  Ref<BinaryBitmap> topLeft = image->crop(0, 0, halfWidth, halfHeight);\n  try {\n    return delegate_.decode(topLeft, hints);\n  } catch (ReaderException re) {\n    // continue\n  }\n\n  Ref<BinaryBitmap> topRight = image->crop(halfWidth, 0, halfWidth, halfHeight);\n  try {\n    return delegate_.decode(topRight, hints);\n  } catch (ReaderException re) {\n    // continue\n  }\n\n  Ref<BinaryBitmap> bottomLeft = image->crop(0, halfHeight, halfWidth, halfHeight);\n  try {\n    return delegate_.decode(bottomLeft, hints);\n  } catch (ReaderException re) {\n    // continue\n  }\n\n  Ref<BinaryBitmap> bottomRight = image->crop(halfWidth, halfHeight, halfWidth, halfHeight);\n  try {\n    return delegate_.decode(bottomRight, hints);\n  } catch (ReaderException re) {\n    // continue\n  }\n\n  int quarterWidth = halfWidth / 2;\n  int quarterHeight = halfHeight / 2;\n  Ref<BinaryBitmap> center = image->crop(quarterWidth, quarterHeight, halfWidth, halfHeight);\n  return delegate_.decode(center, hints);\n}\n\n} // End zxing::multi namespace\n} // End zxing namespace\n\n// file: zxing/multi/GenericMultipleBarcodeReader.cpp\n\n/*\n *  Copyright 2011 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/multi/GenericMultipleBarcodeReader.h>\n// #include <zxing/ReaderException.h>\n// #include <zxing/ResultPoint.h>\n\nnamespace zxing {\nnamespace multi {\nGenericMultipleBarcodeReader::GenericMultipleBarcodeReader(Reader& delegate) :\n  delegate_(delegate)\n{\n}\n\nGenericMultipleBarcodeReader::~GenericMultipleBarcodeReader(){}\n\nstd::vector<Ref<Result> > GenericMultipleBarcodeReader::decodeMultiple(\n  Ref<BinaryBitmap> image, DecodeHints hints)\n{\n  std::vector<Ref<Result> > results;\n  doDecodeMultiple(image, hints, results, 0, 0);\n  if (results.empty()){\n    throw ReaderException(\"No code detected\");\n  }\n  return results;\n}\n\nvoid GenericMultipleBarcodeReader::doDecodeMultiple(Ref<BinaryBitmap> image,\n  DecodeHints hints, std::vector<Ref<Result> >& results, int xOffset, int yOffset)\n{\n  Ref<Result> result;\n  try {\n    result = delegate_.decode(image, hints);\n  } catch (ReaderException re) {\n    return;\n  }\n  bool alreadyFound = false;\n  for (unsigned int i = 0; i < results.size(); i++) {\n    Ref<Result> existingResult = results[i];\n    if (existingResult->getText()->getText() == result->getText()->getText()) {\n      alreadyFound = true;\n      break;\n    }\n  }\n  if (alreadyFound) {\n    return;\n  }\n\n  results.push_back(translateResultPoints(result, xOffset, yOffset));\n  const std::vector<Ref<ResultPoint> > resultPoints = result->getResultPoints();\n  if (resultPoints.empty()) {\n    return;\n  }\n\n  int width = image->getWidth();\n  int height = image->getHeight();\n  float minX = width;\n  float minY = height;\n  float maxX = 0.0f;\n  float maxY = 0.0f;\n  for (unsigned int i = 0; i < resultPoints.size(); i++) {\n    Ref<ResultPoint> point = resultPoints[i];\n    float x = point->getX();\n    float y = point->getY();\n    if (x < minX) {\n      minX = x;\n    }\n    if (y < minY) {\n      minY = y;\n    }\n    if (x > maxX) {\n      maxX = x;\n    }\n    if (y > maxY) {\n      maxY = y;\n    }\n  }\n\n  // Decode left of barcode\n  if (minX > MIN_DIMENSION_TO_RECUR) {\n    doDecodeMultiple(image->crop(0, 0, (int) minX, height),\n                     hints, results, xOffset, yOffset);\n  }\n  // Decode above barcode\n  if (minY > MIN_DIMENSION_TO_RECUR) {\n    doDecodeMultiple(image->crop(0, 0, width, (int) minY),\n                     hints, results, xOffset, yOffset);\n  }\n  // Decode right of barcode\n  if (maxX < width - MIN_DIMENSION_TO_RECUR) {\n    doDecodeMultiple(image->crop((int) maxX, 0, width - (int) maxX, height),\n                     hints, results, xOffset + (int) maxX, yOffset);\n  }\n  // Decode below barcode\n  if (maxY < height - MIN_DIMENSION_TO_RECUR) {\n    doDecodeMultiple(image->crop(0, (int) maxY, width, height - (int) maxY),\n                     hints, results, xOffset, yOffset + (int) maxY);\n  }\n}\n\nRef<Result> GenericMultipleBarcodeReader::translateResultPoints(Ref<Result> result, int xOffset, int yOffset){\n  const std::vector<Ref<ResultPoint> > oldResultPoints = result->getResultPoints();\n  if (oldResultPoints.empty()) {\n    return result;\n  }\n  std::vector<Ref<ResultPoint> > newResultPoints;\n  for (unsigned int i = 0; i < oldResultPoints.size(); i++) {\n    Ref<ResultPoint> oldPoint = oldResultPoints[i];\n    newResultPoints.push_back(Ref<ResultPoint>(new ResultPoint(oldPoint->getX() + xOffset, oldPoint->getY() + yOffset)));\n  }\n  return Ref<Result>(new Result(result->getText(), result->getRawBytes(), newResultPoints, result->getBarcodeFormat()));\n}\n\n} // End zxing::multi namespace\n} // End zxing namespace\n\n// file: zxing/multi/MultipleBarcodeReader.cpp\n\n/*\n *  Copyright 2011 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/multi/MultipleBarcodeReader.h>\n\nnamespace zxing {\nnamespace multi {\n\nMultipleBarcodeReader::~MultipleBarcodeReader() { }\n\nstd::vector<Ref<Result> > MultipleBarcodeReader::decodeMultiple(Ref<BinaryBitmap> image) {\n  return decodeMultiple(image, DecodeHints::DEFAULT_HINT);\n}\n\n} // End zxing::multi namespace\n} // End zxing namespace\n\n// file: zxing/multi/qrcode/QRCodeMultiReader.cpp\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n/*\n *  Copyright 2011 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/multi/qrcode/QRCodeMultiReader.h>\n// #include <zxing/ReaderException.h>\n// #include <zxing/multi/qrcode/detector/MultiDetector.h>\n// #include <zxing/BarcodeFormat.h>\n\nnamespace zxing {\nnamespace multi {\nQRCodeMultiReader::QRCodeMultiReader(){}\n\nQRCodeMultiReader::~QRCodeMultiReader(){}\n\nstd::vector<Ref<Result> > QRCodeMultiReader::decodeMultiple(Ref<BinaryBitmap> image,\n  DecodeHints hints)\n{\n  std::vector<Ref<Result> > results;\n  MultiDetector detector(image->getBlackMatrix());\n\n  std::vector<Ref<DetectorResult> > detectorResult =  detector.detectMulti(hints);\n  for (unsigned int i = 0; i < detectorResult.size(); i++) {\n    try {\n      Ref<DecoderResult> decoderResult = getDecoder().decode(detectorResult[i]->getBits());\n      std::vector<Ref<ResultPoint> > points = detectorResult[i]->getPoints();\n      Ref<Result> result = Ref<Result>(new Result(decoderResult->getText(),\n      decoderResult->getRawBytes(),\n      points, BarcodeFormat_QR_CODE));\n      // result->putMetadata(ResultMetadataType.BYTE_SEGMENTS, decoderResult->getByteSegments());\n      // result->putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, decoderResult->getECLevel().toString());\n      results.push_back(result);\n    } catch (ReaderException re) {\n    // ignore and continue\n    }\n  }\n  if (results.empty()){\n    throw ReaderException(\"No code detected\");\n  }\n  return results;\n}\n\n} // End zxing::multi namespace\n} // End zxing namespace\n\n// file: zxing/multi/qrcode/detector/MultiDetector.cpp\n\n/*\n *  Copyright 2011 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/multi/qrcode/detector/MultiDetector.h>\n// #include <zxing/multi/qrcode/detector/MultiFinderPatternFinder.h>\n// #include <zxing/ReaderException.h>\n\nnamespace zxing {\nnamespace multi {\nusing namespace zxing::qrcode;\n\nMultiDetector::MultiDetector(Ref<BitMatrix> image) : Detector(image) {}\n\nMultiDetector::~MultiDetector(){}\n\nstd::vector<Ref<DetectorResult> > MultiDetector::detectMulti(DecodeHints hints){\n  Ref<BitMatrix> image = getImage();\n  MultiFinderPatternFinder finder = MultiFinderPatternFinder(image, hints.getResultPointCallback());\n  std::vector<Ref<FinderPatternInfo> > info = finder.findMulti(hints);\n  std::vector<Ref<DetectorResult> > result;\n  for(unsigned int i = 0; i < info.size(); i++){\n    try{\n      result.push_back(processFinderPatternInfo(info[i]));\n    } catch (ReaderException e){\n      // ignore\n    }\n  }\n\n  return result;\n}\n\n} // End zxing::multi namespace\n} // End zxing namespace\n\n// file: zxing/multi/qrcode/detector/MultiFinderPatternFinder.cpp\n\n/*\n *  Copyright 2011 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <algorithm>\n// #include <math.h>\n// #include <stdlib.h>\n// #include <zxing/multi/qrcode/detector/MultiFinderPatternFinder.h>\n// #include <zxing/DecodeHints.h>\n// #include <zxing/ReaderException.h>\n\nnamespace zxing{\nnamespace multi {\nusing namespace zxing::qrcode;\n\nconst float MultiFinderPatternFinder::MAX_MODULE_COUNT_PER_EDGE = 180;\nconst float MultiFinderPatternFinder::MIN_MODULE_COUNT_PER_EDGE = 9;\nconst float MultiFinderPatternFinder::DIFF_MODSIZE_CUTOFF_PERCENT = 0.05f;\nconst float MultiFinderPatternFinder::DIFF_MODSIZE_CUTOFF = 0.5f;\n\nbool compareModuleSize(Ref<FinderPattern> a, Ref<FinderPattern> b){\n    float value = a->getEstimatedModuleSize() - b->getEstimatedModuleSize();\n    return value < 0.0;\n}\n\n\nMultiFinderPatternFinder::MultiFinderPatternFinder(Ref<BitMatrix> image,\n  Ref<ResultPointCallback> resultPointCallback) :\n    FinderPatternFinder(image, resultPointCallback)\n{\n}\n\nMultiFinderPatternFinder::~MultiFinderPatternFinder(){}\n\nstd::vector<Ref<FinderPatternInfo> > MultiFinderPatternFinder::findMulti(DecodeHints const& hints){\n  bool tryHarder = hints.getTryHarder();\n  Ref<BitMatrix> image = image_; // Protected member\n  int maxI = (int)image->getHeight();\n  int maxJ = (int)image->getWidth();\n  // We are looking for black/white/black/white/black modules in\n  // 1:1:3:1:1 ratio; this tracks the number of such modules seen so far\n\n  // Let's assume that the maximum version QR Code we support takes up 1/4 the height of the\n  // image, and then account for the center being 3 modules in size. This gives the smallest\n  // number of pixels the center could be, so skip this often. When trying harder, look for all\n  // QR versions regardless of how dense they are.\n  int iSkip = (int) (maxI / (MAX_MODULES * 4.0f) * 3);\n  if (iSkip < MIN_SKIP || tryHarder) {\n    iSkip = MIN_SKIP;\n  }\n\n  int stateCount[5];\n  for (int i = iSkip - 1; i < maxI; i += iSkip) {\n    // Get a row of black/white values\n    stateCount[0] = 0;\n    stateCount[1] = 0;\n    stateCount[2] = 0;\n    stateCount[3] = 0;\n    stateCount[4] = 0;\n    int currentState = 0;\n    for (int j = 0; j < maxJ; j++) {\n      if (image->get(j, i)) {\n        // Black pixel\n        if ((currentState & 1) == 1) { // Counting white pixels\n          currentState++;\n        }\n        stateCount[currentState]++;\n      } else { // White pixel\n        if ((currentState & 1) == 0) { // Counting black pixels\n          if (currentState == 4) { // A winner?\n            if (foundPatternCross(stateCount)) { // Yes\n              bool confirmed = handlePossibleCenter(stateCount, i, j);\n              if (!confirmed) {\n                do { // Advance to next black pixel\n                  j++;\n                } while (j < maxJ && !image->get(j, i));\n                  j--; // back up to that last white pixel\n              }\n              // Clear state to start looking again\n              currentState = 0;\n              stateCount[0] = 0;\n              stateCount[1] = 0;\n              stateCount[2] = 0;\n              stateCount[3] = 0;\n              stateCount[4] = 0;\n            } else { // No, shift counts back by two\n              stateCount[0] = stateCount[2];\n              stateCount[1] = stateCount[3];\n              stateCount[2] = stateCount[4];\n              stateCount[3] = 1;\n              stateCount[4] = 0;\n              currentState = 3;\n            }\n          } else {\n            stateCount[++currentState]++;\n          }\n        } else { // Counting white pixels\n            stateCount[currentState]++;\n        }\n      }\n    } // for j=...\n\n    if (foundPatternCross(stateCount)) {\n      handlePossibleCenter(stateCount, i, maxJ);\n    } // end if foundPatternCross\n  } // for i=iSkip-1 ...\n  std::vector<std::vector<Ref<FinderPattern> > > patternInfo = selectBestPatterns();\n  std::vector<Ref<FinderPatternInfo> > result;\n  for (unsigned int i = 0; i < patternInfo.size(); i++) {\n    std::vector<Ref<FinderPattern> > pattern = patternInfo[i];\n    FinderPatternFinder::orderBestPatterns(pattern);\n    result.push_back(Ref<FinderPatternInfo>(new FinderPatternInfo(pattern)));\n  }\n  return result;\n}\n\nstd::vector<std::vector<Ref<FinderPattern> > > MultiFinderPatternFinder::selectBestPatterns(){\n  std::vector<Ref<FinderPattern> > possibleCenters = possibleCenters_;\n\n  int size = (int)possibleCenters.size();\n\n  if (size < 3) {\n    // Couldn't find enough finder patterns\n    throw ReaderException(\"No code detected\");\n  }\n\n  std::vector<std::vector<Ref<FinderPattern> > > results;\n\n  /*\n  * Begin HE modifications to safely detect multiple codes of equal size\n  */\n  if (size == 3) {\n    results.push_back(possibleCenters_);\n    return results;\n  }\n\n  // Sort by estimated module size to speed up the upcoming checks\n  //TODO do a sort based on module size\n  std::sort(possibleCenters.begin(), possibleCenters.end(), compareModuleSize);\n\n  /*\n  * Now lets start: build a list of tuples of three finder locations that\n  *  - feature similar module sizes\n  *  - are placed in a distance so the estimated module count is within the QR specification\n  *  - have similar distance between upper left/right and left top/bottom finder patterns\n  *  - form a triangle with 90° angle (checked by comparing top right/bottom left distance\n  *    with pythagoras)\n  *\n  * Note: we allow each point to be used for more than one code region: this might seem\n  * counterintuitive at first, but the performance penalty is not that big. At this point,\n  * we cannot make a good quality decision whether the three finders actually represent\n  * a QR code, or are just by chance layouted so it looks like there might be a QR code there.\n  * So, if the layout seems right, lets have the decoder try to decode.\n  */\n\n  for (int i1 = 0; i1 < (size - 2); i1++) {\n    Ref<FinderPattern> p1 = possibleCenters[i1];\n    for (int i2 = i1 + 1; i2 < (size - 1); i2++) {\n      Ref<FinderPattern> p2 = possibleCenters[i2];\n      // Compare the expected module sizes; if they are really off, skip\n      float vModSize12 = (p1->getEstimatedModuleSize() - p2->getEstimatedModuleSize()) / std::min(p1->getEstimatedModuleSize(), p2->getEstimatedModuleSize());\n      float vModSize12A = abs(p1->getEstimatedModuleSize() - p2->getEstimatedModuleSize());\n      if (vModSize12A > DIFF_MODSIZE_CUTOFF && vModSize12 >= DIFF_MODSIZE_CUTOFF_PERCENT) {\n        // break, since elements are ordered by the module size deviation there cannot be\n        // any more interesting elements for the given p1.\n        break;\n      }\n      for (int i3 = i2 + 1; i3 < size; i3++) {\n        Ref<FinderPattern> p3 = possibleCenters[i3];\n        // Compare the expected module sizes; if they are really off, skip\n        float vModSize23 = (p2->getEstimatedModuleSize() - p3->getEstimatedModuleSize()) / std::min(p2->getEstimatedModuleSize(), p3->getEstimatedModuleSize());\n        float vModSize23A = abs(p2->getEstimatedModuleSize() - p3->getEstimatedModuleSize());\n        if (vModSize23A > DIFF_MODSIZE_CUTOFF && vModSize23 >= DIFF_MODSIZE_CUTOFF_PERCENT) {\n          // break, since elements are ordered by the module size deviation there cannot be\n          // any more interesting elements for the given p1.\n          break;\n        }\n        std::vector<Ref<FinderPattern> > test;\n        test.push_back(p1);\n        test.push_back(p2);\n        test.push_back(p3);\n        FinderPatternFinder::orderBestPatterns(test);\n        // Calculate the distances: a = topleft-bottomleft, b=topleft-topright, c = diagonal\n        Ref<FinderPatternInfo> info = Ref<FinderPatternInfo>(new FinderPatternInfo(test));\n        float dA = FinderPatternFinder::distance(info->getTopLeft(), info->getBottomLeft());\n        float dC = FinderPatternFinder::distance(info->getTopRight(), info->getBottomLeft());\n        float dB = FinderPatternFinder::distance(info->getTopLeft(), info->getTopRight());\n        // Check the sizes\n        float estimatedModuleCount = (dA + dB) / (p1->getEstimatedModuleSize() * 2.0f);\n        if (estimatedModuleCount > MAX_MODULE_COUNT_PER_EDGE || estimatedModuleCount < MIN_MODULE_COUNT_PER_EDGE) {\n          continue;\n        }\n        // Calculate the difference of the edge lengths in percent\n        float vABBC = abs((dA - dB) / std::min(dA, dB));\n        if (vABBC >= 0.1f) {\n          continue;\n        }\n        // Calculate the diagonal length by assuming a 90° angle at topleft\n        float dCpy = (float) sqrt(dA * dA + dB * dB);\n        // Compare to the real distance in %\n        float vPyC = abs((dC - dCpy) / std::min(dC, dCpy));\n        if (vPyC >= 0.1f) {\n          continue;\n        }\n        // All tests passed!\n        results.push_back(test);\n      } // end iterate p3\n    } // end iterate p2\n  } // end iterate p1\n  if (results.empty()){\n    // Nothing found!\n    throw ReaderException(\"No code detected\");\n  }\n  return results;\n}\n\n} // End zxing::multi namespace\n} // End zxing namespace\n\n// file: zxing/oned/Code128Reader.cpp\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n/*\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include \"Code128Reader.h\"\n// #include <zxing/oned/OneDResultPoint.h>\n// #include <zxing/common/Array.h>\n// #include <zxing/ReaderException.h>\n// #include <math.h>\n// #include <string.h>\n// #include <sstream>\n\nnamespace zxing {\n\tnamespace oned {\n\n\t\tconst int CODE_PATTERNS_LENGTH = 107;\n\t\tconst int countersLength = 6;\n\t\tstatic const int CODE_PATTERNS[CODE_PATTERNS_LENGTH][countersLength] = {\n\t\t\t{2, 1, 2, 2, 2, 2}, /* 0 */\n\t\t\t{2, 2, 2, 1, 2, 2},\n\t\t\t{2, 2, 2, 2, 2, 1},\n\t\t\t{1, 2, 1, 2, 2, 3},\n\t\t\t{1, 2, 1, 3, 2, 2},\n\t\t\t{1, 3, 1, 2, 2, 2}, /* 5 */\n\t\t\t{1, 2, 2, 2, 1, 3},\n\t\t\t{1, 2, 2, 3, 1, 2},\n\t\t\t{1, 3, 2, 2, 1, 2},\n\t\t\t{2, 2, 1, 2, 1, 3},\n\t\t\t{2, 2, 1, 3, 1, 2}, /* 10 */\n\t\t\t{2, 3, 1, 2, 1, 2},\n\t\t\t{1, 1, 2, 2, 3, 2},\n\t\t\t{1, 2, 2, 1, 3, 2},\n\t\t\t{1, 2, 2, 2, 3, 1},\n\t\t\t{1, 1, 3, 2, 2, 2}, /* 15 */\n\t\t\t{1, 2, 3, 1, 2, 2},\n\t\t\t{1, 2, 3, 2, 2, 1},\n\t\t\t{2, 2, 3, 2, 1, 1},\n\t\t\t{2, 2, 1, 1, 3, 2},\n\t\t\t{2, 2, 1, 2, 3, 1}, /* 20 */\n\t\t\t{2, 1, 3, 2, 1, 2},\n\t\t\t{2, 2, 3, 1, 1, 2},\n\t\t\t{3, 1, 2, 1, 3, 1},\n\t\t\t{3, 1, 1, 2, 2, 2},\n\t\t\t{3, 2, 1, 1, 2, 2}, /* 25 */\n\t\t\t{3, 2, 1, 2, 2, 1},\n\t\t\t{3, 1, 2, 2, 1, 2},\n\t\t\t{3, 2, 2, 1, 1, 2},\n\t\t\t{3, 2, 2, 2, 1, 1},\n\t\t\t{2, 1, 2, 1, 2, 3}, /* 30 */\n\t\t\t{2, 1, 2, 3, 2, 1},\n\t\t\t{2, 3, 2, 1, 2, 1},\n\t\t\t{1, 1, 1, 3, 2, 3},\n\t\t\t{1, 3, 1, 1, 2, 3},\n\t\t\t{1, 3, 1, 3, 2, 1}, /* 35 */\n\t\t\t{1, 1, 2, 3, 1, 3},\n\t\t\t{1, 3, 2, 1, 1, 3},\n\t\t\t{1, 3, 2, 3, 1, 1},\n\t\t\t{2, 1, 1, 3, 1, 3},\n\t\t\t{2, 3, 1, 1, 1, 3}, /* 40 */\n\t\t\t{2, 3, 1, 3, 1, 1},\n\t\t\t{1, 1, 2, 1, 3, 3},\n\t\t\t{1, 1, 2, 3, 3, 1},\n\t\t\t{1, 3, 2, 1, 3, 1},\n\t\t\t{1, 1, 3, 1, 2, 3}, /* 45 */\n\t\t\t{1, 1, 3, 3, 2, 1},\n\t\t\t{1, 3, 3, 1, 2, 1},\n\t\t\t{3, 1, 3, 1, 2, 1},\n\t\t\t{2, 1, 1, 3, 3, 1},\n\t\t\t{2, 3, 1, 1, 3, 1}, /* 50 */\n\t\t\t{2, 1, 3, 1, 1, 3},\n\t\t\t{2, 1, 3, 3, 1, 1},\n\t\t\t{2, 1, 3, 1, 3, 1},\n\t\t\t{3, 1, 1, 1, 2, 3},\n\t\t\t{3, 1, 1, 3, 2, 1}, /* 55 */\n\t\t\t{3, 3, 1, 1, 2, 1},\n\t\t\t{3, 1, 2, 1, 1, 3},\n\t\t\t{3, 1, 2, 3, 1, 1},\n\t\t\t{3, 3, 2, 1, 1, 1},\n\t\t\t{3, 1, 4, 1, 1, 1}, /* 60 */\n\t\t\t{2, 2, 1, 4, 1, 1},\n\t\t\t{4, 3, 1, 1, 1, 1},\n\t\t\t{1, 1, 1, 2, 2, 4},\n\t\t\t{1, 1, 1, 4, 2, 2},\n\t\t\t{1, 2, 1, 1, 2, 4}, /* 65 */\n\t\t\t{1, 2, 1, 4, 2, 1},\n\t\t\t{1, 4, 1, 1, 2, 2},\n\t\t\t{1, 4, 1, 2, 2, 1},\n\t\t\t{1, 1, 2, 2, 1, 4},\n\t\t\t{1, 1, 2, 4, 1, 2}, /* 70 */\n\t\t\t{1, 2, 2, 1, 1, 4},\n\t\t\t{1, 2, 2, 4, 1, 1},\n\t\t\t{1, 4, 2, 1, 1, 2},\n\t\t\t{1, 4, 2, 2, 1, 1},\n\t\t\t{2, 4, 1, 2, 1, 1}, /* 75 */\n\t\t\t{2, 2, 1, 1, 1, 4},\n\t\t\t{4, 1, 3, 1, 1, 1},\n\t\t\t{2, 4, 1, 1, 1, 2},\n\t\t\t{1, 3, 4, 1, 1, 1},\n\t\t\t{1, 1, 1, 2, 4, 2}, /* 80 */\n\t\t\t{1, 2, 1, 1, 4, 2},\n\t\t\t{1, 2, 1, 2, 4, 1},\n\t\t\t{1, 1, 4, 2, 1, 2},\n\t\t\t{1, 2, 4, 1, 1, 2},\n\t\t\t{1, 2, 4, 2, 1, 1}, /* 85 */\n\t\t\t{4, 1, 1, 2, 1, 2},\n\t\t\t{4, 2, 1, 1, 1, 2},\n\t\t\t{4, 2, 1, 2, 1, 1},\n\t\t\t{2, 1, 2, 1, 4, 1},\n\t\t\t{2, 1, 4, 1, 2, 1}, /* 90 */\n\t\t\t{4, 1, 2, 1, 2, 1},\n\t\t\t{1, 1, 1, 1, 4, 3},\n\t\t\t{1, 1, 1, 3, 4, 1},\n\t\t\t{1, 3, 1, 1, 4, 1},\n\t\t\t{1, 1, 4, 1, 1, 3}, /* 95 */\n\t\t\t{1, 1, 4, 3, 1, 1},\n\t\t\t{4, 1, 1, 1, 1, 3},\n\t\t\t{4, 1, 1, 3, 1, 1},\n\t\t\t{1, 1, 3, 1, 4, 1},\n\t\t\t{1, 1, 4, 1, 3, 1}, /* 100 */\n\t\t\t{3, 1, 1, 1, 4, 1},\n\t\t\t{4, 1, 1, 1, 3, 1},\n\t\t\t{2, 1, 1, 4, 1, 2},\n\t\t\t{2, 1, 1, 2, 1, 4},\n\t\t\t{2, 1, 1, 2, 3, 2}, /* 105 */\n\t\t\t{2, 3, 3, 1, 1, 1}\n\t\t};\n\n\n\t\tCode128Reader::Code128Reader(){\n\t\t}\n\n\t\tint* Code128Reader::findStartPattern(Ref<BitArray> row){\n\t\t\tint width = (int)row->getSize();\n\t\t\tint rowOffset = 0;\n\t\t\twhile (rowOffset < width) {\n\t\t\t\tif (row->get(rowOffset)) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\trowOffset++;\n\t\t\t}\n\n\t\t\tint counterPosition = 0;\n\t\t\tint counters[countersLength] = {0,0,0,0,0,0};\n\t\t\tint patternStart = rowOffset;\n\t\t\tbool isWhite = false;\n\t\t\tint patternLength =  sizeof(counters) / sizeof(int);\n\n\t\t\tfor (int i = rowOffset; i < width; i++) {\n\t\t\t\tbool pixel = row->get(i);\n\t\t\t\tif (pixel ^ isWhite) {\n\t\t\t\t\tcounters[counterPosition]++;\n\t\t\t\t} else {\n\t\t\t\t\tif (counterPosition == patternLength - 1) {\n\t\t\t\t\t\tunsigned int bestVariance = MAX_AVG_VARIANCE;\n\t\t\t\t\t\tint bestMatch = -1;\n\t\t\t\t\t\tfor (int startCode = CODE_START_A; startCode <= CODE_START_C; startCode++) {\n\t\t\t\t\t\t\tunsigned int variance = patternMatchVariance(counters, sizeof(counters) / sizeof(int),\n\t\t\t\t\t\t\t    CODE_PATTERNS[startCode], MAX_INDIVIDUAL_VARIANCE);\n\t\t\t\t\t\t\tif (variance < bestVariance) {\n\t\t\t\t\t\t\t\tbestVariance = variance;\n\t\t\t\t\t\t\t\tbestMatch = startCode;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (bestMatch >= 0) {\n\t\t\t\t\t\t\t// Look for whitespace before start pattern, >= 50% of width of start pattern\n              if (row->isRange(std::max(0, patternStart - (i - patternStart) / 2), patternStart,\n\t\t\t\t\t\t\t    false)) {\n\t\t\t\t\t\t\t\tint* resultValue = new int[3];\n\t\t\t\t\t\t\t\tresultValue[0] = patternStart;\n\t\t\t\t\t\t\t\tresultValue[1] = i;\n\t\t\t\t\t\t\t\tresultValue[2] = bestMatch;\n\t\t\t\t\t\t\t\treturn resultValue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tpatternStart += counters[0] + counters[1];\n\t\t\t\t\t\tfor (int y = 2; y < patternLength; y++) {\n\t\t\t\t\t\t\tcounters[y - 2] = counters[y];\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcounters[patternLength - 2] = 0;\n\t\t\t\t\t\tcounters[patternLength - 1] = 0;\n\t\t\t\t\t\tcounterPosition--;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcounterPosition++;\n\t\t\t\t\t}\n\t\t\t\t\tcounters[counterPosition] = 1;\n\t\t\t\t\tisWhite = !isWhite;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow ReaderException(\"\");\n\t\t}\n\n\t\tint Code128Reader::decodeCode(Ref<BitArray> row, int counters[], int countersCount,\n\t\t    int rowOffset) {\n\t\t  if (!recordPattern(row, rowOffset, counters, countersCount)) {\n\t\t    throw ReaderException(\"\");\n\t\t  }\n\t\t\tunsigned int bestVariance = MAX_AVG_VARIANCE; // worst variance we'll accept\n\t\t\tint bestMatch = -1;\n\t\t\tfor (int d = 0; d < CODE_PATTERNS_LENGTH; d++) {\n\t\t\t\tint pattern[countersLength];\n\n\t\t\t\tfor(int ind = 0; ind< countersLength; ind++){\n\t\t\t\t\tpattern[ind] = CODE_PATTERNS[d][ind];\n\t\t\t\t}\n//\t\t\t\tmemcpy(pattern, CODE_PATTERNS[d], countersLength);\n\t\t\t\tunsigned int variance = patternMatchVariance(counters, countersCount, pattern,\n\t\t\t\t    MAX_INDIVIDUAL_VARIANCE);\n\t\t\t\tif (variance < bestVariance) {\n\t\t\t\t\tbestVariance = variance;\n\t\t\t\t\tbestMatch = d;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// TODO We're overlooking the fact that the STOP pattern has 7 values, not 6.\n\t\t\tif (bestMatch >= 0) {\n\t\t\t\treturn bestMatch;\n\t\t\t} else {\n\t\t\t\tthrow ReaderException(\"\");\n\t\t\t}\n\t\t}\n\n\t\tRef<Result> Code128Reader::decodeRow(int rowNumber, Ref<BitArray> row) {\n\t\t  int* startPatternInfo = NULL;\n\t\t  try {\n        startPatternInfo = findStartPattern(row);\n        int startCode = startPatternInfo[2];\n        int codeSet;\n        switch (startCode) {\n          case CODE_START_A:\n            codeSet = CODE_CODE_A;\n            break;\n          case CODE_START_B:\n            codeSet = CODE_CODE_B;\n            break;\n          case CODE_START_C:\n            codeSet = CODE_CODE_C;\n            break;\n          default:\n            throw ReaderException(\"\");\n        }\n\n        bool done = false;\n        bool isNextShifted = false;\n\n        std::string tmpResultString;\n        std::stringstream tmpResultSStr; // used if its Code 128C\n\n        int lastStart = startPatternInfo[0];\n        int nextStart = startPatternInfo[1];\n        int counters[countersLength] = {0,0,0,0,0,0};\n\n        int lastCode = 0;\n        int code = 0;\n        int checksumTotal = startCode;\n        int multiplier = 0;\n        bool lastCharacterWasPrintable = true;\n\n        while (!done) {\n          bool unshift = isNextShifted;\n          isNextShifted = false;\n\n          // Save off last code\n          lastCode = code;\n\n          // Decode another code from image\n          try {\n            code = decodeCode(row, counters, sizeof(counters)/sizeof(int), nextStart);\n          } catch (ReaderException const& re) {\n            throw re;\n          }\n\n          // Remember whether the last code was printable or not (excluding CODE_STOP)\n          if (code != CODE_STOP) {\n            lastCharacterWasPrintable = true;\n          }\n\n          // Add to checksum computation (if not CODE_STOP of course)\n          if (code != CODE_STOP) {\n            multiplier++;\n            checksumTotal += multiplier * code;\n          }\n\n          // Advance to where the next code will to start\n          lastStart = nextStart;\n          int _countersLength = sizeof(counters) / sizeof(int);\n          for (int i = 0; i < _countersLength; i++) {\n            nextStart += counters[i];\n          }\n\n          // Take care of illegal start codes\n          switch (code) {\n            case CODE_START_A:\n            case CODE_START_B:\n            case CODE_START_C:\n              throw ReaderException(\"\");\n          }\n\n          switch (codeSet) {\n\n            case CODE_CODE_A:\n              if (code < 64) {\n                tmpResultString.append(1, (char) (' ' + code));\n              } else if (code < 96) {\n                tmpResultString.append(1, (char) (code - 64));\n              } else {\n                // Don't let CODE_STOP, which always appears, affect whether whether we think the\n                // last code was printable or not.\n                if (code != CODE_STOP) {\n                  lastCharacterWasPrintable = false;\n                }\n                switch (code) {\n                  case CODE_FNC_1:\n                  case CODE_FNC_2:\n                  case CODE_FNC_3:\n                  case CODE_FNC_4_A:\n                    // do nothing?\n                    break;\n                  case CODE_SHIFT:\n                    isNextShifted = true;\n                    codeSet = CODE_CODE_B;\n                    break;\n                  case CODE_CODE_B:\n                    codeSet = CODE_CODE_B;\n                    break;\n                  case CODE_CODE_C:\n                    codeSet = CODE_CODE_C;\n                    break;\n                  case CODE_STOP:\n                    done = true;\n                    break;\n                }\n              }\n              break;\n            case CODE_CODE_B:\n              if (code < 96) {\n                tmpResultString.append(1, (char) (' ' + code));\n              } else {\n                if (code != CODE_STOP) {\n                  lastCharacterWasPrintable = false;\n                }\n                switch (code) {\n                  case CODE_FNC_1:\n                  case CODE_FNC_2:\n                  case CODE_FNC_3:\n                  case CODE_FNC_4_B:\n                    // do nothing?\n                    break;\n                  case CODE_SHIFT:\n                    isNextShifted = true;\n                    codeSet = CODE_CODE_C;\n                    break;\n                  case CODE_CODE_A:\n                    codeSet = CODE_CODE_A;\n                    break;\n                  case CODE_CODE_C:\n                    codeSet = CODE_CODE_C;\n                    break;\n                  case CODE_STOP:\n                    done = true;\n                    break;\n                }\n              }\n              break;\n            case CODE_CODE_C:\n              tmpResultSStr.str(std::string());\n              // the code read in this case is the number encoded directly\n              if (code < 100) {\n                if (code < 10) {\n \t\t\t\t\t        tmpResultSStr << '0';\n \t\t\t\t        }\n                tmpResultSStr << code;\n \t\t\t\t        tmpResultString.append(tmpResultSStr.str());\n              } else {\n                if (code != CODE_STOP) {\n                  lastCharacterWasPrintable = false;\n                }\n                switch (code) {\n                  case CODE_FNC_1:\n                    // do nothing?\n                    break;\n                  case CODE_CODE_A:\n                    codeSet = CODE_CODE_A;\n                    break;\n                  case CODE_CODE_B:\n                    codeSet = CODE_CODE_B;\n                    break;\n                  case CODE_STOP:\n                    done = true;\n                    break;\n                }\n              }\n              break;\n          }\n\n          // Unshift back to another code set if we were shifted\n          if (unshift) {\n            switch (codeSet) {\n              case CODE_CODE_A:\n                codeSet = CODE_CODE_C;\n                break;\n              case CODE_CODE_B:\n                codeSet = CODE_CODE_A;\n                break;\n              case CODE_CODE_C:\n                codeSet = CODE_CODE_B;\n                break;\n            }\n          }\n\n        }\n\n        // Check for ample whitespace following pattern, but, to do this we first need to remember that\n        // we fudged decoding CODE_STOP since it actually has 7 bars, not 6. There is a black bar left\n        // to read off. Would be slightly better to properly read. Here we just skip it:\n        int width = (int)row->getSize();\n        while (nextStart < width && row->get(nextStart)) {\n          nextStart++;\n        }\n        if (!row->isRange(nextStart,\n                          std::min(width, nextStart + (nextStart - lastStart) / 2),\n                          false)) {\n          throw ReaderException(\"\");\n        }\n\n        // Pull out from sum the value of the penultimate check code\n        checksumTotal -= multiplier * lastCode;\n        // lastCode is the checksum then:\n        if (checksumTotal % 103 != lastCode) {\n          throw ReaderException(\"\");\n        }\n\n        // Need to pull out the check digits from string\n        int resultLength = (int)tmpResultString.length();\n        // Only bother if the result had at least one character, and if the checksum digit happened to\n        // be a printable character. If it was just interpreted as a control code, nothing to remove.\n        if (resultLength > 0 && lastCharacterWasPrintable) {\n          if (codeSet == CODE_CODE_C) {\n            tmpResultString.erase(resultLength - 2, resultLength);\n          } else {\n            tmpResultString.erase(resultLength - 1, resultLength);\n          }\n        }\n\n        Ref<String> resultString(new String(tmpResultString));\n        if (tmpResultString.length() == 0) {\n          // Almost surely a false positive\n          throw ReaderException(\"\");\n        }\n\n        float left = (float) (startPatternInfo[1] + startPatternInfo[0]) / 2.0f;\n        float right = (float) (nextStart + lastStart) / 2.0f;\n\n        std::vector< Ref<ResultPoint> > resultPoints(2);\n        Ref<OneDResultPoint> resultPoint1(new OneDResultPoint(left, (float) rowNumber));\n        Ref<OneDResultPoint> resultPoint2(new OneDResultPoint(right, (float) rowNumber));\n        resultPoints[0] = resultPoint1;\n        resultPoints[1] = resultPoint2;\n\n        delete [] startPatternInfo;\n        ArrayRef<unsigned char> resultBytes(1);\n        return Ref<Result>(new Result(resultString, resultBytes, resultPoints,\n            BarcodeFormat_CODE_128));\n\t\t\t} catch (ReaderException const& re) {\n\t\t\t  delete [] startPatternInfo;\n\t\t\t  return Ref<Result>();\n\t\t\t}\n\t\t}\n\n\t\tvoid Code128Reader::append(char* s, char c){\n\t\t\tint len = (int)strlen(s);\n\t\t\ts[len] = c;\n\t\t\ts[len + 1] = '\\0';\n\t\t}\n\n\t\tCode128Reader::~Code128Reader(){\n\t\t}\n\t}\n}\n\n// file: zxing/oned/Code39Reader.cpp\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n/*\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include \"Code39Reader.h\"\n// #include <zxing/oned/OneDResultPoint.h>\n// #include <zxing/common/Array.h>\n// #include <zxing/ReaderException.h>\n// #include <math.h>\n// #include <limits.h>\n\nnamespace zxing {\nnamespace oned {\n\n  static const char* ALPHABET = \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. *$/+%\";\n\n\n  /**\n   * These represent the encodings of characters, as patterns of wide and narrow\n   * bars.\n   * The 9 least-significant bits of each int correspond to the pattern of wide\n   * and narrow, with 1s representing \"wide\" and 0s representing narrow.\n   */\n  const int CHARACTER_ENCODINGS_LEN = 44;\n  static int CHARACTER_ENCODINGS[CHARACTER_ENCODINGS_LEN] = {\n    0x034, 0x121, 0x061, 0x160, 0x031, 0x130, 0x070, 0x025, 0x124, 0x064, // 0-9\n    0x109, 0x049, 0x148, 0x019, 0x118, 0x058, 0x00D, 0x10C, 0x04C, 0x01C, // A-J\n    0x103, 0x043, 0x142, 0x013, 0x112, 0x052, 0x007, 0x106, 0x046, 0x016, // K-T\n    0x181, 0x0C1, 0x1C0, 0x091, 0x190, 0x0D0, 0x085, 0x184, 0x0C4, 0x094, // U-*\n    0x0A8, 0x0A2, 0x08A, 0x02A // $-%\n  };\n\n  static int ASTERISK_ENCODING = 0x094;\n  static const char* ALPHABET_STRING =\n    \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. *$/+%\";\n\n\n  /**\n   * Creates a reader that assumes all encoded data is data, and does not treat\n   * the final character as a check digit. It will not decoded \"extended\n   * Code 39\" sequences.\n   */\n  Code39Reader::Code39Reader() : alphabet_string(ALPHABET_STRING),\n                                 usingCheckDigit(false),\n                                 extendedMode(false) {\n  }\n\n  /**\n   * Creates a reader that can be configured to check the last character as a\n   * check digit. It will not decoded \"extended Code 39\" sequences.\n   *\n   * @param usingCheckDigit if true, treat the last data character as a check\n   * digit, not data, and verify that the checksum passes.\n   */\n  Code39Reader::Code39Reader(bool usingCheckDigit_) :\n    alphabet_string(ALPHABET_STRING),\n    usingCheckDigit(usingCheckDigit_),\n    extendedMode(false) {\n  }\n\n\n  Code39Reader::Code39Reader(bool usingCheckDigit_, bool extendedMode_) :\n    alphabet_string(ALPHABET_STRING),\n    usingCheckDigit(usingCheckDigit_),\n    extendedMode(extendedMode_) {\n  }\n\n  Ref<Result> Code39Reader::decodeRow(int rowNumber, Ref<BitArray> row) {\n    int* start = NULL;\n    try {\n      start = findAsteriskPattern(row);\n      int nextStart = start[1];\n      int end = (int)row->getSize();\n\n      // Read off white space\n      while (nextStart < end && !row->get(nextStart)) {\n        nextStart++;\n      }\n\n      std::string tmpResultString;\n\n      const int countersLen = 9;\n      int counters[countersLen];\n      for (int i = 0; i < countersLen; i++) {\n        counters[i] = 0;\n      }\n      char decodedChar;\n      int lastStart;\n      do {\n        if (!recordPattern(row, nextStart, counters, countersLen)) {\n          throw ReaderException(\"\");\n        }\n        int pattern = toNarrowWidePattern(counters, countersLen);\n        if (pattern < 0) {\n          throw ReaderException(\"pattern < 0\");\n        }\n        decodedChar = patternToChar(pattern);\n        tmpResultString.append(1, decodedChar);\n        lastStart = nextStart;\n        for (int i = 0; i < countersLen; i++) {\n          nextStart += counters[i];\n        }\n        // Read off white space\n        while (nextStart < end && !row->get(nextStart)) {\n          nextStart++;\n        }\n      } while (decodedChar != '*');\n      tmpResultString.erase(tmpResultString.length()-1, 1);// remove asterisk\n\n      // Look for whitespace after pattern:\n      int lastPatternSize = 0;\n      for (int i = 0; i < countersLen; i++) {\n        lastPatternSize += counters[i];\n      }\n      int whiteSpaceAfterEnd = nextStart - lastStart - lastPatternSize;\n      // If 50% of last pattern size, following last pattern, is not whitespace,\n      // fail (but if it's whitespace to the very end of the image, that's OK)\n      if (nextStart != end && whiteSpaceAfterEnd / 2 < lastPatternSize) {\n        throw ReaderException(\"too short end white space\");\n      }\n\n      if (usingCheckDigit) {\n        int max = (int)tmpResultString.length() - 1;\n        unsigned int total = 0;\n        for (int i = 0; i < max; i++) {\n          total += alphabet_string.find_first_of(tmpResultString[i], 0);\n        }\n        if (total % 43 != alphabet_string.find_first_of(tmpResultString[max], 0)) {\n          throw ReaderException(\"\");\n        }\n        tmpResultString.erase(max, 1);\n      }\n\n      Ref<String> resultString(new String(tmpResultString));\n      if (extendedMode) {\n        resultString = decodeExtended(tmpResultString);\n      }\n\n      if (tmpResultString.length() == 0) {\n        // Almost surely a false positive\n        throw ReaderException(\"\");\n      }\n\n      float left = (float) (start[1] + start[0]) / 2.0f;\n      float right = (float) (nextStart + lastStart) / 2.0f;\n\n      std::vector< Ref<ResultPoint> > resultPoints(2);\n      Ref<OneDResultPoint> resultPoint1(\n        new OneDResultPoint(left, (float) rowNumber));\n      Ref<OneDResultPoint> resultPoint2(\n        new OneDResultPoint(right, (float) rowNumber));\n      resultPoints[0] = resultPoint1;\n      resultPoints[1] = resultPoint2;\n\n      ArrayRef<unsigned char> resultBytes(1);\n\n      Ref<Result> res(new Result(\n                        resultString, resultBytes, resultPoints, BarcodeFormat_CODE_39));\n\n      delete [] start;\n      return res;\n    } catch (ReaderException const& re) {\n      delete [] start;\n      return Ref<Result>();\n    }\n  }\n\n  int* Code39Reader::findAsteriskPattern(Ref<BitArray> row){\n    int width = (int)row->getSize();\n    int rowOffset = 0;\n    while (rowOffset < width) {\n      if (row->get(rowOffset)) {\n        break;\n      }\n      rowOffset++;\n    }\n\n    int counterPosition = 0;\n    const int countersLen = 9;\n    int counters[countersLen];\n    for (int i = 0; i < countersLen; i++) {\n      counters[i] = 0;\n    }\n    int patternStart = rowOffset;\n    bool isWhite = false;\n    int patternLength = countersLen;\n\n    for (int i = rowOffset; i < width; i++) {\n      bool pixel = row->get(i);\n      if (pixel ^ isWhite) {\n        counters[counterPosition]++;\n      } else {\n        if (counterPosition == patternLength - 1) {\n          if (toNarrowWidePattern(counters, countersLen) == ASTERISK_ENCODING) {\n            // Look for whitespace before start pattern, >= 50% of width of\n            // start pattern.\n            if (row->isRange(std::max(0, patternStart - ((i - patternStart) >> 1)), patternStart, false)) {\n              int* resultValue = new int[2];\n              resultValue[0] = patternStart;\n              resultValue[1] = i;\n              return resultValue;\n            }\n          }\n          patternStart += counters[0] + counters[1];\n          for (int y = 2; y < patternLength; y++) {\n            counters[y - 2] = counters[y];\n          }\n          counters[patternLength - 2] = 0;\n          counters[patternLength - 1] = 0;\n          counterPosition--;\n        } else {\n          counterPosition++;\n        }\n        counters[counterPosition] = 1;\n        isWhite = !isWhite;\n      }\n    }\n    throw ReaderException(\"\");\n  }\n\n  // For efficiency, returns -1 on failure. Not throwing here saved as many as\n  // 700 exceptions per image when using some of our blackbox images.\n  int Code39Reader::toNarrowWidePattern(int counters[], int countersLen){\n    int numCounters = countersLen;\n    int maxNarrowCounter = 0;\n    int wideCounters;\n    do {\n      int minCounter = INT_MAX;\n      for (int i = 0; i < numCounters; i++) {\n        int counter = counters[i];\n        if (counter < minCounter && counter > maxNarrowCounter) {\n          minCounter = counter;\n        }\n      }\n      maxNarrowCounter = minCounter;\n      wideCounters = 0;\n      int totalWideCountersWidth = 0;\n      int pattern = 0;\n      for (int i = 0; i < numCounters; i++) {\n        int counter = counters[i];\n        if (counters[i] > maxNarrowCounter) {\n          pattern |= 1 << (numCounters - 1 - i);\n          wideCounters++;\n          totalWideCountersWidth += counter;\n        }\n      }\n      if (wideCounters == 3) {\n        // Found 3 wide counters, but are they close enough in width?\n        // We can perform a cheap, conservative check to see if any individual\n        // counter is more than 1.5 times the average:\n        for (int i = 0; i < numCounters && wideCounters > 0; i++) {\n          int counter = counters[i];\n          if (counters[i] > maxNarrowCounter) {\n            wideCounters--;\n            // totalWideCountersWidth = 3 * average, so this checks if\n            // counter >= 3/2 * average.\n            if ((counter << 1) >= totalWideCountersWidth) {\n              return -1;\n            }\n          }\n        }\n        return pattern;\n      }\n    } while (wideCounters > 3);\n    return -1;\n  }\n\n  char Code39Reader::patternToChar(int pattern){\n    for (int i = 0; i < CHARACTER_ENCODINGS_LEN; i++) {\n      if (CHARACTER_ENCODINGS[i] == pattern) {\n        return ALPHABET[i];\n      }\n    }\n    throw ReaderException(\"\");\n  }\n\n  Ref<String> Code39Reader::decodeExtended(std::string encoded){\n    int length = (int)encoded.length();\n    std::string tmpDecoded;\n    for (int i = 0; i < length; i++) {\n      char c = encoded[i];\n      if (c == '+' || c == '$' || c == '%' || c == '/') {\n        char next = encoded[i + 1];\n        char decodedChar = '\\0';\n        switch (c) {\n          case '+':\n            // +A to +Z map to a to z\n            if (next >= 'A' && next <= 'Z') {\n              decodedChar = (char) (next + 32);\n            } else {\n              throw ReaderException(\"\");\n            }\n            break;\n          case '$':\n            // $A to $Z map to control codes SH to SB\n            if (next >= 'A' && next <= 'Z') {\n              decodedChar = (char) (next - 64);\n            } else {\n              throw ReaderException(\"\");\n            }\n            break;\n          case '%':\n            // %A to %E map to control codes ESC to US\n            if (next >= 'A' && next <= 'E') {\n              decodedChar = (char) (next - 38);\n            } else if (next >= 'F' && next <= 'W') {\n              decodedChar = (char) (next - 11);\n            } else {\n              throw ReaderException(\"\");\n            }\n            break;\n          case '/':\n            // /A to /O map to ! to , and /Z maps to :\n            if (next >= 'A' && next <= 'O') {\n              decodedChar = (char) (next - 32);\n            } else if (next == 'Z') {\n              decodedChar = ':';\n            } else {\n              throw ReaderException(\"\");\n            }\n            break;\n        }\n        tmpDecoded.append(1, decodedChar);\n        // bump up i again since we read two characters\n        i++;\n      } else {\n        tmpDecoded.append(1, c);\n      }\n    }\n    Ref<String> decoded(new String(tmpDecoded));\n    return decoded;\n  }\n} // namespace oned\n} // namespace zxing\n\n\n// file: zxing/oned/EAN13Reader.cpp\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n/*\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include \"EAN13Reader.h\"\n// #include <zxing/ReaderException.h>\n\nnamespace zxing {\n  namespace oned {\n\n    static const int FIRST_DIGIT_ENCODINGS[10] = {\n      0x00, 0x0B, 0x0D, 0xE, 0x13, 0x19, 0x1C, 0x15, 0x16, 0x1A\n    };\n\n    EAN13Reader::EAN13Reader() { }\n\n    int EAN13Reader::decodeMiddle(Ref<BitArray> row, int startGuardBegin, int startGuardEnd,\n        std::string& resultString) {\n      (void)startGuardBegin;\n      const int countersLen = 4;\n      int counters[countersLen] = { 0, 0, 0, 0 };\n\n      int end = (int)row->getSize();\n      int rowOffset = startGuardEnd;\n      int lgPatternFound = 0;\n\n      for (int x = 0; x < 6 && rowOffset < end; x++) {\n        int bestMatch = decodeDigit(row, counters, countersLen, rowOffset,\n            UPC_EAN_PATTERNS_L_AND_G_PATTERNS);\n        if (bestMatch < 0) {\n          return -1;\n        }\n        resultString.append(1, (char) ('0' + bestMatch % 10));\n        for (int i = 0; i < countersLen; i++) {\n          rowOffset += counters[i];\n        }\n        if (bestMatch >= 10) {\n          lgPatternFound |= 1 << (5 - x);\n        }\n      }\n\n      if (!determineFirstDigit(resultString, lgPatternFound)) {\n        return -1;\n      }\n\n      int middleRangeStart;\n      int middleRangeEnd;\n      if (findGuardPattern(row, rowOffset, true, (int*)getMIDDLE_PATTERN(),\n            getMIDDLE_PATTERN_LEN(), &middleRangeStart, &middleRangeEnd)) {\n        rowOffset = middleRangeEnd;\n        for (int x = 0; x < 6 && rowOffset < end; x++) {\n          int bestMatch = decodeDigit(row, counters, countersLen, rowOffset,\n              UPC_EAN_PATTERNS_L_PATTERNS);\n          if (bestMatch < 0) {\n            return -1;\n          }\n          resultString.append(1, (char) ('0' + bestMatch));\n          for (int i = 0; i < countersLen; i++) {\n            rowOffset += counters[i];\n          }\n        }\n        return rowOffset;\n      }\n      return -1;\n    }\n\n    bool EAN13Reader::determineFirstDigit(std::string& resultString, int lgPatternFound) {\n      for (int d = 0; d < 10; d++) {\n        if (lgPatternFound == FIRST_DIGIT_ENCODINGS[d]) {\n          resultString.insert(0, 1, (char) ('0' + d));\n          return true;\n        }\n      }\n      return false;\n    }\n\n    BarcodeFormat EAN13Reader::getBarcodeFormat(){\n      return BarcodeFormat_EAN_13;\n    }\n  }\n}\n\n// file: zxing/oned/EAN8Reader.cpp\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n/*\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include \"EAN8Reader.h\"\n// #include <zxing/ReaderException.h>\n\nnamespace zxing {\n  namespace oned {\n\n    EAN8Reader::EAN8Reader(){ }\n\n    int EAN8Reader::decodeMiddle(Ref<BitArray> row, int startGuardBegin, int startGuardEnd,\n        std::string& resultString){\n      (void)startGuardBegin;\n      const int countersLen = 4;\n      int counters[countersLen] = { 0, 0, 0, 0 };\n\n      int end = (int)row->getSize();\n      int rowOffset = startGuardEnd;\n\n      for (int x = 0; x < 4 && rowOffset < end; x++) {\n        int bestMatch = decodeDigit(row, counters, countersLen, rowOffset,\n            UPC_EAN_PATTERNS_L_PATTERNS);\n        if (bestMatch < 0) {\n          return -1;\n        }\n        resultString.append(1, (char) ('0' + bestMatch));\n        for (int i = 0; i < countersLen; i++) {\n          rowOffset += counters[i];\n        }\n      }\n\n      int middleRangeStart;\n      int middleRangeEnd;\n      if (findGuardPattern(row, rowOffset, true, (int*)getMIDDLE_PATTERN(),\n            getMIDDLE_PATTERN_LEN(), &middleRangeStart, &middleRangeEnd)) {\n        rowOffset = middleRangeEnd;\n        for (int x = 0; x < 4 && rowOffset < end; x++) {\n          int bestMatch = decodeDigit(row, counters, countersLen, rowOffset,\n              UPC_EAN_PATTERNS_L_PATTERNS);\n          if (bestMatch < 0) {\n            return -1;\n          }\n          resultString.append(1, (char) ('0' + bestMatch));\n          for (int i = 0; i < countersLen; i++) {\n            rowOffset += counters[i];\n          }\n        }\n        return rowOffset;\n      }\n      return -1;\n    }\n\n    BarcodeFormat EAN8Reader::getBarcodeFormat(){\n      return BarcodeFormat_EAN_8;\n    }\n  }\n}\n\n// file: zxing/oned/ITFReader.cpp\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n/*\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include \"ITFReader.h\"\n// #include <zxing/oned/OneDResultPoint.h>\n// #include <zxing/common/Array.h>\n// #include <zxing/ReaderException.h>\n// #include <math.h>\n\nnamespace zxing {\n  namespace oned {\n\n    static const int W = 3; // Pixel width of a wide line\n    static const int N = 1; // Pixed width of a narrow line\n\n    const int DEFAULT_ALLOWED_LENGTHS_LEN = 10;\n    const int DEFAULT_ALLOWED_LENGTHS[DEFAULT_ALLOWED_LENGTHS_LEN] = { 44, 24, 20, 18, 16, 14, 12, 10, 8, 6 };\n\n    /**\n     * Start/end guard pattern.\n     *\n     * Note: The end pattern is reversed because the row is reversed before\n     * searching for the END_PATTERN\n     */\n    static const int START_PATTERN_LEN = 4;\n    static const int START_PATTERN[START_PATTERN_LEN] = {N, N, N, N};\n\n    static const int END_PATTERN_REVERSED_LEN = 3;\n    static const int END_PATTERN_REVERSED[END_PATTERN_REVERSED_LEN] = {N, N, W};\n\n    /**\n     * Patterns of Wide / Narrow lines to indicate each digit\n     */\n    static const int PATTERNS_LEN = 10;\n    static const int PATTERNS[PATTERNS_LEN][5] = {\n      {N, N, W, W, N}, // 0\n      {W, N, N, N, W}, // 1\n      {N, W, N, N, W}, // 2\n      {W, W, N, N, N}, // 3\n      {N, N, W, N, W}, // 4\n      {W, N, W, N, N}, // 5\n      {N, W, W, N, N}, // 6\n      {N, N, N, W, W}, // 7\n      {W, N, N, W, N}, // 8\n      {N, W, N, W, N}  // 9\n    };\n\n\n    ITFReader::ITFReader() : narrowLineWidth(-1) {\n    }\n\n\n    Ref<Result> ITFReader::decodeRow(int rowNumber, Ref<BitArray> row) {\n      int* startRange = 0;\n      int* endRange = 0;\n      try {\n        // Find out where the Middle section (payload) starts & ends\n        startRange = decodeStart(row);\n        endRange = decodeEnd(row);\n\n        std::string tmpResult;\n        decodeMiddle(row, startRange[1], endRange[0], tmpResult);\n\n        // To avoid false positives with 2D barcodes (and other patterns), make\n        // an assumption that the decoded string must be a known length\n        int length = (int)tmpResult.length();\n        bool lengthOK = false;\n        for (int i = 0; i < DEFAULT_ALLOWED_LENGTHS_LEN; i++) {\n          if (length == DEFAULT_ALLOWED_LENGTHS[i]) {\n            lengthOK = true;\n            break;\n          }\n        }\n        if (!lengthOK) {\n          throw ReaderException(\"not enough characters count\");\n        }\n\n        Ref<String> resultString(new String(tmpResult));\n\n        std::vector< Ref<ResultPoint> > resultPoints(2);\n        Ref<OneDResultPoint> resultPoint1(new OneDResultPoint(startRange[1], (float) rowNumber));\n        Ref<OneDResultPoint> resultPoint2(new OneDResultPoint(endRange[0], (float) rowNumber));\n        resultPoints[0] = resultPoint1;\n        resultPoints[1] = resultPoint2;\n\n        delete [] startRange;\n        delete [] endRange;\n        ArrayRef<unsigned char> resultBytes(1);\n        return Ref<Result>(new Result(resultString, resultBytes, resultPoints, BarcodeFormat_ITF));\n      } catch (ReaderException const& re) {\n        delete [] startRange;\n        delete [] endRange;\n        return Ref<Result>();\n      }\n    }\n\n    /**\n     * @param row          row of black/white values to search\n     * @param payloadStart offset of start pattern\n     * @param resultString {@link StringBuffer} to append decoded chars to\n     * @throws ReaderException if decoding could not complete successfully\n     */\n    void ITFReader::decodeMiddle(Ref<BitArray> row, int payloadStart, int payloadEnd,\n        std::string& resultString) {\n      // Digits are interleaved in pairs - 5 black lines for one digit, and the\n      // 5\n      // interleaved white lines for the second digit.\n      // Therefore, need to scan 10 lines and then\n      // split these into two arrays\n      int counterDigitPairLen = 10;\n      int counterDigitPair[counterDigitPairLen];\n      for (int i=0; i<counterDigitPairLen; i++) {\n        counterDigitPair[i] = 0;\n      }\n\n      int counterBlack[5];\n      int counterWhite[5];\n      for (int i=0; i<5; i++) {\n        counterBlack[i] = 0;\n        counterWhite[i] = 0;\n      }\n\n      while (payloadStart < payloadEnd) {\n        // Get 10 runs of black/white.\n        if (!recordPattern(row, payloadStart, counterDigitPair, counterDigitPairLen)) {\n          throw ReaderException(\"\");\n        }\n        // Split them into each array\n        for (int k = 0; k < 5; k++) {\n          int twoK = k << 1;\n          counterBlack[k] = counterDigitPair[twoK];\n          counterWhite[k] = counterDigitPair[twoK + 1];\n        }\n\n        int bestMatch = decodeDigit(counterBlack, 5);\n        resultString.append(1, (char) ('0' + bestMatch));\n        bestMatch = decodeDigit(counterWhite, 5);\n        resultString.append(1, (char) ('0' + bestMatch));\n\n        for (int i = 0; i < counterDigitPairLen; i++) {\n          payloadStart += counterDigitPair[i];\n        }\n      }\n    }\n\n    /**\n     * Identify where the start of the middle / payload section starts.\n     *\n     * @param row row of black/white values to search\n     * @return Array, containing index of start of 'start block' and end of\n     *         'start block'\n     * @throws ReaderException\n     */\n    int* ITFReader::decodeStart(Ref<BitArray> row) {\n      int endStart = skipWhiteSpace(row);\n      int* startPattern = 0;\n      try {\n          startPattern = findGuardPattern(row, endStart, START_PATTERN, START_PATTERN_LEN);\n\n          // Determine the width of a narrow line in pixels. We can do this by\n          // getting the width of the start pattern and dividing by 4 because its\n          // made up of 4 narrow lines.\n          narrowLineWidth = (startPattern[1] - startPattern[0]) >> 2;\n          validateQuietZone(row, startPattern[0]);\n          return startPattern;\n      } catch (ReaderException const& re) {\n          delete [] startPattern;\n        throw re;\n      }\n    }\n\n    /**\n     * Identify where the end of the middle / payload section ends.\n     *\n     * @param row row of black/white values to search\n     * @return Array, containing index of start of 'end block' and end of 'end\n     *         block'\n     * @throws ReaderException\n     */\n\n    int* ITFReader::decodeEnd(Ref<BitArray> row) {\n      // For convenience, reverse the row and then\n      // search from 'the start' for the end block\n      row->reverse();\n                        int* endPattern = 0;\n      try {\n        int endStart = skipWhiteSpace(row);\n        endPattern = findGuardPattern(row, endStart, END_PATTERN_REVERSED, END_PATTERN_REVERSED_LEN);\n\n        // The start & end patterns must be pre/post fixed by a quiet zone. This\n        // zone must be at least 10 times the width of a narrow line.\n        // ref: http://www.barcode-1.net/i25code.html\n        validateQuietZone(row, endPattern[0]);\n\n        // Now recalculate the indices of where the 'endblock' starts & stops to\n        // accommodate\n        // the reversed nature of the search\n        int temp = endPattern[0];\n        endPattern[0] = (int)(row->getSize() - endPattern[1]);\n        endPattern[1] = (int)(row->getSize() - temp);\n\n        row->reverse();\n        return endPattern;\n      } catch (ReaderException const& re) {\n                                delete [] endPattern;\n        row->reverse();\n        throw re;\n      }\n    }\n\n    /**\n     * The start & end patterns must be pre/post fixed by a quiet zone. This\n     * zone must be at least 10 times the width of a narrow line.  Scan back until\n     * we either get to the start of the barcode or match the necessary number of\n     * quiet zone pixels.\n     *\n     * Note: Its assumed the row is reversed when using this method to find\n     * quiet zone after the end pattern.\n     *\n     * ref: http://www.barcode-1.net/i25code.html\n     *\n     * @param row bit array representing the scanned barcode.\n     * @param startPattern index into row of the start or end pattern.\n     * @throws ReaderException if the quiet zone cannot be found, a ReaderException is thrown.\n     */\n    void ITFReader::validateQuietZone(Ref<BitArray> row, int startPattern) {\n      (void)row;\n      (void)startPattern;\n//#pragma mark needs some corrections\n//      int quietCount = narrowLineWidth * 10;  // expect to find this many pixels of quiet zone\n//\n//      for (int i = startPattern - 1; quietCount > 0 && i >= 0; i--) {\n//        if (row->get(i)) {\n//          break;\n//        }\n//        quietCount--;\n//      }\n//      if (quietCount != 0) {\n//        // Unable to find the necessary number of quiet zone pixels.\n//        throw ReaderException(\"Unable to find the necessary number of quiet zone pixels\");\n//      }\n    }\n\n    /**\n     * Skip all whitespace until we get to the first black line.\n     *\n     * @param row row of black/white values to search\n     * @return index of the first black line.\n     * @throws ReaderException Throws exception if no black lines are found in the row\n     */\n    int ITFReader::skipWhiteSpace(Ref<BitArray> row) {\n      int width = (int)row->getSize();\n      int endStart = 0;\n      while (endStart < width) {\n        if (row->get(endStart)) {\n          break;\n        }\n        endStart++;\n      }\n      if (endStart == width) {\n        throw ReaderException(\"\");\n      }\n      return endStart;\n    }\n\n    /**\n     * @param row       row of black/white values to search\n     * @param rowOffset position to start search\n     * @param pattern   pattern of counts of number of black and white pixels that are\n     *                  being searched for as a pattern\n     * @return start/end horizontal offset of guard pattern, as an array of two\n     *         ints\n     * @throws ReaderException if pattern is not found\n     */\n    int* ITFReader::findGuardPattern(Ref<BitArray> row, int rowOffset, const int pattern[],\n        int patternLen) {\n      // TODO: This is very similar to implementation in UPCEANReader. Consider if they can be\n      // merged to a single method.\n      int patternLength = patternLen;\n      int counters[patternLength];\n      for (int i=0; i<patternLength; i++) {\n        counters[i] = 0;\n      }\n      int width = (int)row->getSize();\n      bool isWhite = false;\n\n      int counterPosition = 0;\n      int patternStart = rowOffset;\n      for (int x = rowOffset; x < width; x++) {\n        bool pixel = row->get(x);\n        if (pixel ^ isWhite) {\n          counters[counterPosition]++;\n        } else {\n          if (counterPosition == patternLength - 1) {\n            if (patternMatchVariance(counters, patternLength, pattern,\n                MAX_INDIVIDUAL_VARIANCE) < MAX_AVG_VARIANCE) {\n              int* resultValue = new int[2];\n              resultValue[0] = patternStart;\n              resultValue[1] = x;\n              return resultValue;\n            }\n            patternStart += counters[0] + counters[1];\n            for (int y = 2; y < patternLength; y++) {\n              counters[y - 2] = counters[y];\n            }\n            counters[patternLength - 2] = 0;\n            counters[patternLength - 1] = 0;\n            counterPosition--;\n          } else {\n            counterPosition++;\n          }\n          counters[counterPosition] = 1;\n          isWhite = !isWhite;\n        }\n      }\n      throw ReaderException(\"\");\n    }\n\n    /**\n     * Attempts to decode a sequence of ITF black/white lines into single\n     * digit.\n     *\n     * @param counters the counts of runs of observed black/white/black/... values\n     * @return The decoded digit\n     * @throws ReaderException if digit cannot be decoded\n     */\n    int ITFReader::decodeDigit(int counters[], int countersLen){\n      unsigned int bestVariance = MAX_AVG_VARIANCE; // worst variance we'll accept\n      int bestMatch = -1;\n      int max = PATTERNS_LEN;\n      for (int i = 0; i < max; i++) {\n        int pattern[countersLen];\n        for(int ind = 0; ind<countersLen; ind++){\n          pattern[ind] = PATTERNS[i][ind];\n        }\n        unsigned int variance = patternMatchVariance(counters, countersLen, pattern,\n            MAX_INDIVIDUAL_VARIANCE);\n        if (variance < bestVariance) {\n          bestVariance = variance;\n          bestMatch = i;\n        }\n      }\n      if (bestMatch >= 0) {\n        return bestMatch;\n      } else {\n        throw ReaderException(\"digit didint found\");\n      }\n    }\n\n    ITFReader::~ITFReader(){\n    }\n  }\n}\n\n// file: zxing/oned/MultiFormatOneDReader.cpp\n\n/*\n *  MultiFormatOneDReader.cpp\n *  ZXing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include \"MultiFormatOneDReader.h\"\n\n// #include <zxing/oned/MultiFormatUPCEANReader.h>\n// #include <zxing/oned/Code39Reader.h>\n// #include <zxing/oned/Code128Reader.h>\n// #include <zxing/oned/ITFReader.h>\n// #include <zxing/ReaderException.h>\n\nnamespace zxing {\n  namespace oned {\n    MultiFormatOneDReader::MultiFormatOneDReader(DecodeHints hints) : readers() {\n      if (hints.containsFormat(BarcodeFormat_EAN_13) ||\n          hints.containsFormat(BarcodeFormat_EAN_8) ||\n          hints.containsFormat(BarcodeFormat_UPC_A) ||\n          hints.containsFormat(BarcodeFormat_UPC_E)) {\n        readers.push_back(Ref<OneDReader>(new MultiFormatUPCEANReader(hints)));\n      }\n      if (hints.containsFormat(BarcodeFormat_CODE_39)) {\n        readers.push_back(Ref<OneDReader>(new Code39Reader()));\n      }\n      if (hints.containsFormat(BarcodeFormat_CODE_128)) {\n        readers.push_back(Ref<OneDReader>(new Code128Reader()));\n      }\n      if (hints.containsFormat(BarcodeFormat_ITF)) {\n        readers.push_back(Ref<OneDReader>(new ITFReader()));\n      }\n      if (readers.size() == 0) {\n        readers.push_back(Ref<OneDReader>(new MultiFormatUPCEANReader(hints)));\n        readers.push_back(Ref<OneDReader>(new Code39Reader()));\n        readers.push_back(Ref<OneDReader>(new Code128Reader()));\n        readers.push_back(Ref<OneDReader>(new ITFReader()));\n      }\n    }\n\n    Ref<Result> MultiFormatOneDReader::decodeRow(int rowNumber, Ref<BitArray> row) {\n      int size = (int)readers.size();\n      for (int i = 0; i < size; i++) {\n        OneDReader* reader = readers[i];\n        Ref<Result> result = reader->decodeRow(rowNumber, row);\n        if (!result.empty()) {\n          return result;\n        }\n      }\n      return Ref<Result>();\n    }\n  }\n}\n\n// file: zxing/oned/MultiFormatUPCEANReader.cpp\n\n/*\n *  MultiFormatUPCEANReader.cpp\n *  ZXing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n// #include \"MultiFormatUPCEANReader.h\"\n\n// #include <zxing/oned/EAN13Reader.h>\n// #include <zxing/oned/EAN8Reader.h>\n// #include <zxing/oned/UPCEReader.h>\n// #include <zxing/oned/UPCAReader.h>\n// #include <zxing/oned/OneDResultPoint.h>\n// #include <zxing/common/Array.h>\n// #include <zxing/ReaderException.h>\n// #include <math.h>\n\nnamespace zxing {\n  namespace oned {\n\n    MultiFormatUPCEANReader::MultiFormatUPCEANReader(DecodeHints hints) : readers() {\n      if (hints.containsFormat(BarcodeFormat_EAN_13)) {\n        readers.push_back(Ref<OneDReader>(new EAN13Reader()));\n      } else if (hints.containsFormat(BarcodeFormat_UPC_A)) {\n        readers.push_back(Ref<OneDReader>(new UPCAReader()));\n      }\n      if (hints.containsFormat(BarcodeFormat_EAN_8)) {\n        readers.push_back(Ref<OneDReader>(new EAN8Reader()));\n      }\n      if (hints.containsFormat(BarcodeFormat_UPC_E)) {\n        readers.push_back(Ref<OneDReader>(new UPCEReader()));\n      }\n      if (readers.size() == 0) {\n        readers.push_back(Ref<OneDReader>(new EAN13Reader()));\n        // UPC-A is covered by EAN-13\n        readers.push_back(Ref<OneDReader>(new EAN8Reader()));\n        readers.push_back(Ref<OneDReader>(new UPCEReader()));\n      }\n    }\n\n    Ref<Result> MultiFormatUPCEANReader::decodeRow(int rowNumber, Ref<BitArray> row) {\n      // Compute this location once and reuse it on multiple implementations\n      int size = (int)readers.size();\n      for (int i = 0; i < size; i++) {\n        Ref<OneDReader> reader = readers[i];\n        Ref<Result> result = reader->decodeRow(rowNumber, row);\n        if (result.empty()) {\n          continue;\n        }\n\n        // Special case: a 12-digit code encoded in UPC-A is identical to a \"0\"\n        // followed by those 12 digits encoded as EAN-13. Each will recognize such a code,\n        // UPC-A as a 12-digit string and EAN-13 as a 13-digit string starting with \"0\".\n        // Individually these are correct and their readers will both read such a code\n        // and correctly call it EAN-13, or UPC-A, respectively.\n        //\n        // In this case, if we've been looking for both types, we'd like to call it\n        // a UPC-A code. But for efficiency we only run the EAN-13 decoder to also read\n        // UPC-A. So we special case it here, and convert an EAN-13 result to a UPC-A\n        // result if appropriate.\n        if (result->getBarcodeFormat() == BarcodeFormat_EAN_13) {\n          const std::string& text = (result->getText())->getText();\n          if (text[0] == '0') {\n            Ref<String> resultString(new String(text.substr(1)));\n            Ref<Result> res(new Result(resultString, result->getRawBytes(),\n                result->getResultPoints(), BarcodeFormat_UPC_A));\n            return res;\n          }\n        }\n        return result;\n      }\n      return Ref<Result>();\n    }\n  }\n}\n\n// file: zxing/oned/OneDReader.cpp\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n/*\n *  OneDReader.cpp\n *  ZXing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include \"OneDReader.h\"\n// #include <zxing/ReaderException.h>\n// #include <zxing/oned/OneDResultPoint.h>\n// #include <math.h>\n// #include <limits.h>\n\nnamespace zxing {\n  namespace oned {\n    using namespace std;\n\n    OneDReader::OneDReader() {\n    }\n\n    Ref<Result> OneDReader::decode(Ref<BinaryBitmap> image, DecodeHints hints) {\n      Ref<Result> result = doDecode(image, hints);\n      if (result.empty() && hints.getTryHarder() && image->isRotateSupported()) {\n        Ref<BinaryBitmap> rotatedImage(image->rotateCounterClockwise());\n        result = doDecode(rotatedImage, hints);\n        if (!result.empty()) {\n          /*\n          // Record that we found it rotated 90 degrees CCW / 270 degrees CW\n          Hashtable metadata = result.getResultMetadata();\n          int orientation = 270;\n          if (metadata != null && metadata.containsKey(ResultMetadataType.ORIENTATION)) {\n            // But if we found it reversed in doDecode(), add in that result here:\n            orientation = (orientation +\n                     ((Integer) metadata.get(ResultMetadataType.ORIENTATION)).intValue()) % 360;\n          }\n          result.putMetadata(ResultMetadataType.ORIENTATION, new Integer(orientation));\n          */\n          // Update result points\n          std::vector<Ref<ResultPoint> >& points (result->getResultPoints());\n          int height = rotatedImage->getHeight();\n          for (size_t i = 0; i < points.size(); i++) {\n            points[i].reset(new OneDResultPoint(height - points[i]->getY() - 1, points[i]->getX()));\n          }\n        }\n      }\n      if (result.empty()) {\n        throw ReaderException(\"\");\n      }\n      return result;\n    }\n\n    Ref<Result> OneDReader::doDecode(Ref<BinaryBitmap> image, DecodeHints hints) {\n      int width = image->getWidth();\n      int height = image->getHeight();\n      Ref<BitArray> row(new BitArray(width));\n      int middle = height >> 1;\n      bool tryHarder = hints.getTryHarder();\n      int rowStep = (int)fmax(1, height >> (tryHarder ? 8 : 5));\n      int maxLines;\n      if (tryHarder) {\n        maxLines = height; // Look at the whole image, not just the center\n      } else {\n        maxLines = 15; // 15 rows spaced 1/32 apart is roughly the middle half of the image\n      }\n\n      for (int x = 0; x < maxLines; x++) {\n        // Scanning from the middle out. Determine which row we're looking at next:\n        int rowStepsAboveOrBelow = (x + 1) >> 1;\n        bool isAbove = (x & 0x01) == 0; // i.e. is x even?\n        int rowNumber = middle + rowStep * (isAbove ? rowStepsAboveOrBelow : -rowStepsAboveOrBelow);\n        if (rowNumber < 0 || rowNumber >= height) {\n          // Oops, if we run off the top or bottom, stop\n          break;\n        }\n\n        // Estimate black point for this row and load it:\n        try {\n          row = image->getBlackRow(rowNumber, row);\n        } catch (ReaderException const& re) {\n          continue;\n        } catch (IllegalArgumentException const& re) {\n          continue;\n        }\n\n        // While we have the image data in a BitArray, it's fairly cheap to reverse it in place to\n        // handle decoding upside down barcodes.\n        for (int attempt = 0; attempt < 2; attempt++) {\n          if (attempt == 1) {\n            row->reverse(); // reverse the row and continue\n          }\n\n          // Look for a barcode\n          Ref<Result> result = decodeRow(rowNumber, row);\n          // We found our barcode\n          if (!result.empty()) {\n            if (attempt == 1) {\n              // But it was upside down, so note that\n              // result.putMetadata(ResultMetadataType.ORIENTATION, new Integer(180));\n              // And remember to flip the result points horizontally.\n              std::vector<Ref<ResultPoint> > points(result->getResultPoints());\n              // if there's exactly two points (which there should be), flip the x coordinate\n              // if there's not exactly 2, I don't know what do do with it\n              if (points.size() == 2) {\n                Ref<ResultPoint> pointZero(new OneDResultPoint(width - points[0]->getX() - 1,\n                    points[0]->getY()));\n                points[0] = pointZero;\n\n                Ref<ResultPoint> pointOne(new OneDResultPoint(width - points[1]->getX() - 1,\n                    points[1]->getY()));\n                points[1] = pointOne;\n\n                result.reset(new Result(result->getText(), result->getRawBytes(), points,\n                    result->getBarcodeFormat()));\n              }\n            }\n            return result;\n          }\n        }\n      }\n      return Ref<Result>();\n    }\n\n    unsigned int OneDReader::patternMatchVariance(int counters[], int countersSize,\n        const int pattern[], int maxIndividualVariance) {\n      int numCounters = countersSize;\n      unsigned int total = 0;\n      unsigned int patternLength = 0;\n      for (int i = 0; i < numCounters; i++) {\n        total += counters[i];\n        patternLength += pattern[i];\n      }\n      if (total < patternLength) {\n        // If we don't even have one pixel per unit of bar width, assume this is too small\n        // to reliably match, so fail:\n        return INT_MAX;\n      }\n      // We're going to fake floating-point math in integers. We just need to use more bits.\n      // Scale up patternLength so that intermediate values below like scaledCounter will have\n      // more \"significant digits\"\n      unsigned int unitBarWidth = (total << INTEGER_MATH_SHIFT) / patternLength;\n      maxIndividualVariance = (maxIndividualVariance * unitBarWidth) >> INTEGER_MATH_SHIFT;\n\n      unsigned int totalVariance = 0;\n      for (int x = 0; x < numCounters; x++) {\n        int counter = counters[x] << INTEGER_MATH_SHIFT;\n        int scaledPattern = pattern[x] * unitBarWidth;\n        int variance = counter > scaledPattern ? counter - scaledPattern : scaledPattern - counter;\n        if (variance > maxIndividualVariance) {\n          return INT_MAX;\n        }\n        totalVariance += variance;\n      }\n      return totalVariance / total;\n    }\n\n    bool OneDReader::recordPattern(Ref<BitArray> row, int start, int counters[], int countersCount) {\n      int numCounters = countersCount;//sizeof(counters) / sizeof(int);\n      for (int i = 0; i < numCounters; i++) {\n        counters[i] = 0;\n      }\n      int end = (int)row->getSize();\n      if (start >= end) {\n        return false;\n      }\n      bool isWhite = !row->get(start);\n      int counterPosition = 0;\n      int i = start;\n      while (i < end) {\n        bool pixel = row->get(i);\n        if (pixel ^ isWhite) { // that is, exactly one is true\n          counters[counterPosition]++;\n        } else {\n          counterPosition++;\n          if (counterPosition == numCounters) {\n            break;\n          } else {\n            counters[counterPosition] = 1;\n            isWhite ^= true; // isWhite = !isWhite;\n          }\n        }\n        i++;\n      }\n      // If we read fully the last section of pixels and filled up our counters -- or filled\n      // the last counter but ran off the side of the image, OK. Otherwise, a problem.\n      if (!(counterPosition == numCounters || (counterPosition == numCounters - 1 && i == end))) {\n        return false;\n      }\n      return true;\n    }\n\n    OneDReader::~OneDReader() {\n    }\n  }\n}\n\n// file: zxing/oned/OneDResultPoint.cpp\n\n/*\n *  OneDResultPoint.cpp\n *  ZXing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include \"OneDResultPoint.h\"\n\nnamespace zxing {\n\tnamespace oned {\n\n\t\tOneDResultPoint::OneDResultPoint(float posX, float posY) : ResultPoint(posX,posY) {\n\t\t}\n\t}\n}\n\n// file: zxing/oned/UPCAReader.cpp\n\n/*\n *  UPCAReader.cpp\n *  ZXing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include \"UPCAReader.h\"\n// #include <zxing/ReaderException.h>\n\nnamespace zxing {\n  namespace oned {\n    UPCAReader::UPCAReader() : ean13Reader() {\n    }\n\n    Ref<Result> UPCAReader::decodeRow(int rowNumber, Ref<BitArray> row) {\n      return maybeReturnResult(ean13Reader.decodeRow(rowNumber, row));\n    }\n\n    Ref<Result> UPCAReader::decodeRow(int rowNumber, Ref<BitArray> row, int startGuardBegin,\n        int startGuardEnd) {\n      return maybeReturnResult(ean13Reader.decodeRow(rowNumber, row, startGuardBegin,\n          startGuardEnd));\n    }\n\n    Ref<Result> UPCAReader::decode(Ref<BinaryBitmap> image, DecodeHints hints) {\n      return maybeReturnResult(ean13Reader.decode(image, hints));\n    }\n\n    int UPCAReader::decodeMiddle(Ref<BitArray> row, int startGuardBegin, int startGuardEnd,\n        std::string& resultString) {\n      return ean13Reader.decodeMiddle(row, startGuardBegin, startGuardEnd, resultString);\n    }\n\n    Ref<Result> UPCAReader::maybeReturnResult(Ref<Result> result) {\n      if (result.empty()) {\n        return result;\n      }\n      const std::string& text = (result->getText())->getText();\n      if (text[0] == '0') {\n        Ref<String> resultString(new String(text.substr(1)));\n        Ref<Result> res(new Result(resultString, result->getRawBytes(), result->getResultPoints(),\n            BarcodeFormat_UPC_A));\n        return res;\n      }\n      return Ref<Result>();\n    }\n\n    BarcodeFormat UPCAReader::getBarcodeFormat(){\n      return BarcodeFormat_UPC_A;\n    }\n  }\n}\n\n// file: zxing/oned/UPCEANReader.cpp\n\n/*\n *  UPCEANReader.cpp\n *  ZXing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include \"UPCEANReader.h\"\n// #include <zxing/oned/OneDResultPoint.h>\n// #include <zxing/ReaderException.h>\n\nnamespace zxing {\n  namespace oned {\n\n    /**\n     * Start/end guard pattern.\n     */\n    static const int START_END_PATTERN[3] = {1, 1, 1};\n\n    /**\n     * Pattern marking the middle of a UPC/EAN pattern, separating the two halves.\n     */\n    static const int MIDDLE_PATTERN_LEN = 5;\n    static const int MIDDLE_PATTERN[MIDDLE_PATTERN_LEN] = {1, 1, 1, 1, 1};\n\n    /**\n     * \"Odd\", or \"L\" patterns used to encode UPC/EAN digits.\n     */\n    const int L_PATTERNS_LEN = 10;\n    const int L_PATTERNS_SUB_LEN = 4;\n    const int L_PATTERNS[L_PATTERNS_LEN][L_PATTERNS_SUB_LEN] = {\n      {3, 2, 1, 1}, // 0\n      {2, 2, 2, 1}, // 1\n      {2, 1, 2, 2}, // 2\n      {1, 4, 1, 1}, // 3\n      {1, 1, 3, 2}, // 4\n      {1, 2, 3, 1}, // 5\n      {1, 1, 1, 4}, // 6\n      {1, 3, 1, 2}, // 7\n      {1, 2, 1, 3}, // 8\n      {3, 1, 1, 2}  // 9\n    };\n\n    /**\n     * As above but also including the \"even\", or \"G\" patterns used to encode UPC/EAN digits.\n     */\n    const int L_AND_G_PATTERNS_LEN = 20;\n    const int L_AND_G_PATTERNS_SUB_LEN = 4;\n    const int L_AND_G_PATTERNS[L_AND_G_PATTERNS_LEN][L_AND_G_PATTERNS_SUB_LEN] = {\n      {3, 2, 1, 1}, // 0\n      {2, 2, 2, 1}, // 1\n      {2, 1, 2, 2}, // 2\n      {1, 4, 1, 1}, // 3\n      {1, 1, 3, 2}, // 4\n      {1, 2, 3, 1}, // 5\n      {1, 1, 1, 4}, // 6\n      {1, 3, 1, 2}, // 7\n      {1, 2, 1, 3}, // 8\n      {3, 1, 1, 2}, // 9\n      {1, 1, 2, 3}, // 10 reversed 0\n      {1, 2, 2, 2}, // 11 reversed 1\n      {2, 2, 1, 2}, // 12 reversed 2\n      {1, 1, 4, 1}, // 13 reversed 3\n      {2, 3, 1, 1}, // 14 reversed 4\n      {1, 3, 2, 1}, // 15 reversed 5\n      {4, 1, 1, 1}, // 16 reversed 6\n      {2, 1, 3, 1}, // 17 reversed 7\n      {3, 1, 2, 1}, // 18 reversed 8\n      {2, 1, 1, 3}  // 19 reversed 9\n    };\n\n\n    int UPCEANReader::getMIDDLE_PATTERN_LEN() {\n      return MIDDLE_PATTERN_LEN;\n    }\n\n    const int* UPCEANReader::getMIDDLE_PATTERN() {\n      return MIDDLE_PATTERN;\n    }\n\n    UPCEANReader::UPCEANReader() {\n    }\n\n\n    Ref<Result> UPCEANReader::decodeRow(int rowNumber, Ref<BitArray> row) {\n      int rangeStart;\n      int rangeEnd;\n\t\t\tif (findStartGuardPattern(row, &rangeStart, &rangeEnd)) {\n        try {\n          return decodeRow(rowNumber, row, rangeStart, rangeEnd);\n        } catch (ReaderException const& re) {\n        }\n\t\t\t}\n\t\t\treturn Ref<Result>();\n    }\n\n    Ref<Result> UPCEANReader::decodeRow(int rowNumber, Ref<BitArray> row, int startGuardBegin,\n        int startGuardEnd) {\n      std::string tmpResultString;\n      std::string& tmpResultStringRef = tmpResultString;\n      int endStart = decodeMiddle(row, startGuardBegin, startGuardEnd, tmpResultStringRef);\n      if (endStart < 0) {\n        return Ref<Result>();\n      }\n\n      int endGuardBegin;\n      int endGuardEnd;\n      if (!decodeEnd(row, endStart, &endGuardBegin, &endGuardEnd)) {\n        return Ref<Result>();\n      }\n\n      // Make sure there is a quiet zone at least as big as the end pattern after the barcode.\n      // The spec might want more whitespace, but in practice this is the maximum we can count on.\n      size_t quietEnd = endGuardEnd + (endGuardEnd - endGuardBegin);\n      if (quietEnd >= row->getSize() || !row->isRange(endGuardEnd, quietEnd, false)) {\n        return Ref<Result>();\n      }\n\n      if (!checkChecksum(tmpResultString)) {\n        return Ref<Result>();\n      }\n\n      Ref<String> resultString(new String(tmpResultString));\n      float left = (float) (startGuardBegin + startGuardEnd) / 2.0f;\n      float right = (float) (endGuardBegin + endGuardEnd) / 2.0f;\n\n      std::vector< Ref<ResultPoint> > resultPoints(2);\n      Ref<OneDResultPoint> resultPoint1(new OneDResultPoint(left, (float) rowNumber));\n      Ref<OneDResultPoint> resultPoint2(new OneDResultPoint(right, (float) rowNumber));\n      resultPoints[0] = resultPoint1;\n      resultPoints[1] = resultPoint2;\n\n      ArrayRef<unsigned char> resultBytes(1);\n      return Ref<Result>(new Result(resultString, resultBytes, resultPoints, getBarcodeFormat()));\n    }\n\n    bool UPCEANReader::findStartGuardPattern(Ref<BitArray> row, int* rangeStart, int* rangeEnd) {\n      int nextStart = 0;\n      while (findGuardPattern(row, nextStart, false, START_END_PATTERN,\n          sizeof(START_END_PATTERN) / sizeof(int), rangeStart, rangeEnd)) {\n        int start = *rangeStart;\n        nextStart = *rangeEnd;\n        // Make sure there is a quiet zone at least as big as the start pattern before the barcode.\n        // If this check would run off the left edge of the image, do not accept this barcode,\n        // as it is very likely to be a false positive.\n        int quietStart = start - (nextStart - start);\n        if (quietStart >= 0 && row->isRange(quietStart, start, false)) {\n          return true;\n        }\n      }\n      return false;\n    }\n\n    bool UPCEANReader::findGuardPattern(Ref<BitArray> row, int rowOffset, bool whiteFirst,\n        const int pattern[], int patternLen, int* start, int* end) {\n      int patternLength = patternLen;\n      int counters[patternLength];\n      int countersCount = (int)(sizeof(counters) / sizeof(int));\n      for (int i = 0; i < countersCount; i++) {\n        counters[i] = 0;\n      }\n      int width = (int)row->getSize();\n      bool isWhite = false;\n      while (rowOffset < width) {\n        isWhite = !row->get(rowOffset);\n        if (whiteFirst == isWhite) {\n          break;\n        }\n        rowOffset++;\n      }\n\n      int counterPosition = 0;\n      int patternStart = rowOffset;\n      for (int x = rowOffset; x < width; x++) {\n        bool pixel = row->get(x);\n        if (pixel ^ isWhite) {\n          counters[counterPosition]++;\n        } else {\n          if (counterPosition == patternLength - 1) {\n            if (patternMatchVariance(counters, countersCount, pattern,\n                MAX_INDIVIDUAL_VARIANCE) < MAX_AVG_VARIANCE) {\n              *start = patternStart;\n              *end = x;\n              return true;\n            }\n            patternStart += counters[0] + counters[1];\n            for (int y = 2; y < patternLength; y++) {\n              counters[y - 2] = counters[y];\n            }\n            counters[patternLength - 2] = 0;\n            counters[patternLength - 1] = 0;\n            counterPosition--;\n          } else {\n            counterPosition++;\n          }\n          counters[counterPosition] = 1;\n          isWhite = !isWhite;\n        }\n      }\n      return false;\n    }\n\n    bool UPCEANReader::decodeEnd(Ref<BitArray> row, int endStart, int* endGuardBegin,\n        int* endGuardEnd) {\n      return findGuardPattern(row, endStart, false, START_END_PATTERN,\n          sizeof(START_END_PATTERN) / sizeof(int), endGuardBegin, endGuardEnd);\n    }\n\n    int UPCEANReader::decodeDigit(Ref<BitArray> row, int counters[], int countersLen, int rowOffset,\n        UPC_EAN_PATTERNS patternType) {\n      if (!recordPattern(row, rowOffset, counters, countersLen)) {\n        return -1;\n      }\n      unsigned int bestVariance = MAX_AVG_VARIANCE; // worst variance we'll accept\n      int bestMatch = -1;\n\n      int max = 0;\n      switch (patternType) {\n        case UPC_EAN_PATTERNS_L_PATTERNS:\n          max = L_PATTERNS_LEN;\n          for (int i = 0; i < max; i++) {\n            int pattern[countersLen];\n            for(int j = 0; j< countersLen; j++){\n              pattern[j] = L_PATTERNS[i][j];\n            }\n\n            unsigned int variance = patternMatchVariance(counters, countersLen, pattern,\n                MAX_INDIVIDUAL_VARIANCE);\n            if (variance < bestVariance) {\n              bestVariance = variance;\n              bestMatch = i;\n            }\n          }\n          break;\n        case UPC_EAN_PATTERNS_L_AND_G_PATTERNS:\n          max = L_AND_G_PATTERNS_LEN;\n          for (int i = 0; i < max; i++) {\n            int pattern[countersLen];\n            for(int j = 0; j< countersLen; j++){\n              pattern[j] = L_AND_G_PATTERNS[i][j];\n            }\n\n            unsigned int variance = patternMatchVariance(counters, countersLen, pattern,\n                MAX_INDIVIDUAL_VARIANCE);\n            if (variance < bestVariance) {\n              bestVariance = variance;\n              bestMatch = i;\n            }\n          }\n          break;\n        default:\n          break;\n      }\n      return bestMatch;\n    }\n\n    /**\n     * @return {@link #checkStandardUPCEANChecksum(String)}\n     */\n    bool UPCEANReader::checkChecksum(std::string s) {\n      return checkStandardUPCEANChecksum(s);\n    }\n\n    /**\n     * Computes the UPC/EAN checksum on a string of digits, and reports\n     * whether the checksum is correct or not.\n     *\n     * @param s string of digits to check\n     * @return true iff string of digits passes the UPC/EAN checksum algorithm\n     */\n    bool UPCEANReader::checkStandardUPCEANChecksum(std::string s) {\n      int length = (int)s.length();\n      if (length == 0) {\n        return false;\n      }\n\n      int sum = 0;\n      for (int i = length - 2; i >= 0; i -= 2) {\n        int digit = (int) s[i] - (int) '0';\n        if (digit < 0 || digit > 9) {\n          return false;\n        }\n        sum += digit;\n      }\n      sum *= 3;\n      for (int i = length - 1; i >= 0; i -= 2) {\n        int digit = (int) s[i] - (int) '0';\n        if (digit < 0 || digit > 9) {\n          return false;\n        }\n        sum += digit;\n      }\n      return sum % 10 == 0;\n    }\n\n    UPCEANReader::~UPCEANReader() {\n    }\n  }\n}\n\n// file: zxing/oned/UPCEReader.cpp\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n/*\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include \"UPCEReader.h\"\n// #include <zxing/ReaderException.h>\n\nnamespace zxing {\n  namespace oned {\n\n    /**\n     * The pattern that marks the middle, and end, of a UPC-E pattern.\n     * There is no \"second half\" to a UPC-E barcode.\n     */\n    static const int MIDDLE_END_PATTERN[6] = {1, 1, 1, 1, 1, 1};\n\n    /**\n     * See {@link #L_AND_G_PATTERNS}; these values similarly represent patterns of\n     * even-odd parity encodings of digits that imply both the number system (0 or 1)\n     * used, and the check digit.\n     */\n    static const int NUMSYS_AND_CHECK_DIGIT_PATTERNS[2][10] = {\n      {0x38, 0x34, 0x32, 0x31, 0x2C, 0x26, 0x23, 0x2A, 0x29, 0x25},\n      {0x07, 0x0B, 0x0D, 0x0E, 0x13, 0x19, 0x1C, 0x15, 0x16, 0x1A}\n    };\n\n    UPCEReader::UPCEReader() {\n    }\n\n    int UPCEReader::decodeMiddle(Ref<BitArray> row, int startGuardBegin, int startGuardEnd,\n        std::string& resultString) {\n      (void)startGuardBegin;\n      const int countersLen = 4;\n      int counters[countersLen] = { 0, 0, 0, 0 };\n\n      int end = (int)row->getSize();\n      int rowOffset = startGuardEnd;\n      int lgPatternFound = 0;\n\n      for (int x = 0; x < 6 && rowOffset < end; x++) {\n        int bestMatch = decodeDigit(row, counters, countersLen, rowOffset,\n            UPC_EAN_PATTERNS_L_AND_G_PATTERNS);\n        if (bestMatch < 0) {\n          return -1;\n        }\n        resultString.append(1, (char) ('0' + bestMatch % 10));\n        for (int i = 0; i < countersLen; i++) {\n          rowOffset += counters[i];\n        }\n        if (bestMatch >= 10) {\n          lgPatternFound |= 1 << (5 - x);\n        }\n      }\n\n      if (!determineNumSysAndCheckDigit(resultString, lgPatternFound)) {\n        return -1;\n      }\n      return rowOffset;\n    }\n\n    bool UPCEReader::decodeEnd(Ref<BitArray> row, int endStart, int* endGuardBegin,\n        int* endGuardEnd) {\n      return findGuardPattern(row, endStart, true, MIDDLE_END_PATTERN,\n          sizeof(MIDDLE_END_PATTERN) / sizeof(int), endGuardBegin, endGuardEnd);\n    }\n\n    bool UPCEReader::checkChecksum(std::string s){\n      return UPCEANReader::checkChecksum(convertUPCEtoUPCA(s));\n    }\n\n\n    bool UPCEReader::determineNumSysAndCheckDigit(std::string& resultString, int lgPatternFound) {\n      for (int numSys = 0; numSys <= 1; numSys++) {\n        for (int d = 0; d < 10; d++) {\n          if (lgPatternFound == NUMSYS_AND_CHECK_DIGIT_PATTERNS[numSys][d]) {\n            resultString.insert(0, 1, (char) ('0' + numSys));\n            resultString.append(1, (char) ('0' + d));\n            return true;\n          }\n        }\n      }\n      return false;\n    }\n\n    /**\n     * Expands a UPC-E value back into its full, equivalent UPC-A code value.\n     *\n     * @param upce UPC-E code as string of digits\n     * @return equivalent UPC-A code as string of digits\n     */\n    std::string UPCEReader::convertUPCEtoUPCA(std::string upce) {\n      std::string result;\n      result.append(1, upce[0]);\n      char lastChar = upce[6];\n      switch (lastChar) {\n        case '0':\n        case '1':\n        case '2':\n          result.append(upce.substr(1,2));\n          result.append(1, lastChar);\n          result.append(\"0000\");\n          result.append(upce.substr(3,3));\n          break;\n        case '3':\n          result.append(upce.substr(1,3));\n          result.append(\"00000\");\n          result.append(upce.substr(4,2));\n          break;\n        case '4':\n          result.append(upce.substr(1,4));\n          result.append(\"00000\");\n          result.append(1, upce[5]);\n          break;\n        default:\n          result.append(upce.substr(1,5));\n          result.append(\"0000\");\n          result.append(1, lastChar);\n          break;\n      }\n      result.append(1, upce[7]);\n      return result;\n    }\n\n\n    BarcodeFormat UPCEReader::getBarcodeFormat() {\n      return BarcodeFormat_UPC_E;\n    }\n  }\n}\n\n// file: zxing/qrcode/ErrorCorrectionLevel.cpp\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n/*\n *  ErrorCorrectionLevel.cpp\n *  zxing\n *\n *  Created by Christian Brunschen on 15/05/2008.\n *  Copyright 2008-2011 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/qrcode/ErrorCorrectionLevel.h>\n\nusing std::string;\n\nnamespace zxing {\nnamespace qrcode {\n\nErrorCorrectionLevel::ErrorCorrectionLevel(int inOrdinal,\n                                           int bits,\n                                           char const* name) :\n  ordinal_(inOrdinal), bits_(bits), name_(name) {}\n\nint ErrorCorrectionLevel::ordinal() const {\n  return ordinal_;\n}\n\nint ErrorCorrectionLevel::bits() const {\n  return bits_;\n}\n\nstring const& ErrorCorrectionLevel::name() const {\n  return name_;\n}\n\nErrorCorrectionLevel::operator string const& () const {\n  return name_;\n}\n\nErrorCorrectionLevel& ErrorCorrectionLevel::forBits(int bits) {\n  if (bits < 0 || bits >= N_LEVELS) {\n    throw ReaderException(\"Ellegal error correction level bits\");\n  }\n  return *FOR_BITS[bits];\n}\n\n  ErrorCorrectionLevel ErrorCorrectionLevel::L(0, 0x01, \"L\");\n  ErrorCorrectionLevel ErrorCorrectionLevel::M(1, 0x00, \"M\");\n  ErrorCorrectionLevel ErrorCorrectionLevel::Q(2, 0x03, \"Q\");\n  ErrorCorrectionLevel ErrorCorrectionLevel::H(3, 0x02, \"H\");\nErrorCorrectionLevel *ErrorCorrectionLevel::FOR_BITS[] = { &M, &L, &H, &Q };\nint ErrorCorrectionLevel::N_LEVELS = 4;\n\n}\n}\n\n// file: zxing/qrcode/FormatInformation.cpp\n\n/*\n *  FormatInformation.cpp\n *  zxing\n *\n *  Created by Christian Brunschen on 18/05/2008.\n *  Copyright 2008 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/qrcode/FormatInformation.h>\n// #include <limits>\n\nnamespace zxing {\nnamespace qrcode {\n\nusing namespace std;\n\nint FormatInformation::FORMAT_INFO_MASK_QR = 0x5412;\nint FormatInformation::FORMAT_INFO_DECODE_LOOKUP[][2] = { { 0x5412, 0x00 }, { 0x5125, 0x01 }, { 0x5E7C, 0x02 }, {\n    0x5B4B, 0x03 }, { 0x45F9, 0x04 }, { 0x40CE, 0x05 }, { 0x4F97, 0x06 }, { 0x4AA0, 0x07 }, { 0x77C4, 0x08 }, {\n    0x72F3, 0x09 }, { 0x7DAA, 0x0A }, { 0x789D, 0x0B }, { 0x662F, 0x0C }, { 0x6318, 0x0D }, { 0x6C41, 0x0E }, {\n    0x6976, 0x0F }, { 0x1689, 0x10 }, { 0x13BE, 0x11 }, { 0x1CE7, 0x12 }, { 0x19D0, 0x13 }, { 0x0762, 0x14 }, {\n    0x0255, 0x15 }, { 0x0D0C, 0x16 }, { 0x083B, 0x17 }, { 0x355F, 0x18 }, { 0x3068, 0x19 }, { 0x3F31, 0x1A }, {\n    0x3A06, 0x1B }, { 0x24B4, 0x1C }, { 0x2183, 0x1D }, { 0x2EDA, 0x1E }, { 0x2BED, 0x1F },\n};\nint FormatInformation::N_FORMAT_INFO_DECODE_LOOKUPS = 32;\n\nint FormatInformation::BITS_SET_IN_HALF_BYTE[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };\n\nFormatInformation::FormatInformation(int formatInfo) :\n    errorCorrectionLevel_(ErrorCorrectionLevel::forBits((formatInfo >> 3) & 0x03)), dataMask_(\n      (unsigned char)(formatInfo & 0x07)) {\n}\n\nErrorCorrectionLevel& FormatInformation::getErrorCorrectionLevel() {\n  return errorCorrectionLevel_;\n}\n\nunsigned char FormatInformation::getDataMask() {\n  return dataMask_;\n}\n\nint FormatInformation::numBitsDiffering(unsigned int a, unsigned int b) {\n  a ^= b;\n  return BITS_SET_IN_HALF_BYTE[a & 0x0F] + BITS_SET_IN_HALF_BYTE[(a >> 4 & 0x0F)] + BITS_SET_IN_HALF_BYTE[(a >> 8\n         & 0x0F)] + BITS_SET_IN_HALF_BYTE[(a >> 12 & 0x0F)] + BITS_SET_IN_HALF_BYTE[(a >> 16 & 0x0F)]\n         + BITS_SET_IN_HALF_BYTE[(a >> 20 & 0x0F)] + BITS_SET_IN_HALF_BYTE[(a >> 24 & 0x0F)]\n         + BITS_SET_IN_HALF_BYTE[(a >> 28 & 0x0F)];\n}\n\nRef<FormatInformation> FormatInformation::decodeFormatInformation(int maskedFormatInfo1, int maskedFormatInfo2) {\n  Ref<FormatInformation> result(doDecodeFormatInformation(maskedFormatInfo1, maskedFormatInfo2));\n  if (result != 0) {\n    return result;\n  }\n  // Should return null, but, some QR codes apparently\n  // do not mask this info. Try again by actually masking the pattern\n  // first\n  return doDecodeFormatInformation(maskedFormatInfo1 ^ FORMAT_INFO_MASK_QR,\n                                   maskedFormatInfo2  ^ FORMAT_INFO_MASK_QR);\n}\nRef<FormatInformation> FormatInformation::doDecodeFormatInformation(int maskedFormatInfo1, int maskedFormatInfo2) {\n  // Find the int in FORMAT_INFO_DECODE_LOOKUP with fewest bits differing\n  int bestDifference = numeric_limits<int>::max();\n  int bestFormatInfo = 0;\n  for (int i = 0; i < N_FORMAT_INFO_DECODE_LOOKUPS; i++) {\n    int* decodeInfo = FORMAT_INFO_DECODE_LOOKUP[i];\n    int targetInfo = decodeInfo[0];\n    if (targetInfo == maskedFormatInfo1 || targetInfo == maskedFormatInfo2) {\n      // Found an exact match\n      Ref<FormatInformation> result(new FormatInformation(decodeInfo[1]));\n      return result;\n    }\n    int bitsDifference = numBitsDiffering(maskedFormatInfo1, targetInfo);\n    if (bitsDifference < bestDifference) {\n      bestFormatInfo = decodeInfo[1];\n      bestDifference = bitsDifference;\n    }\n    if (maskedFormatInfo1 != maskedFormatInfo2) {\n        // also try the other option\n        bitsDifference = numBitsDiffering(maskedFormatInfo2, targetInfo);\n        if (bitsDifference < bestDifference) {\n            bestFormatInfo = decodeInfo[1];\n          bestDifference = bitsDifference;\n        }\n      }\n  }\n  if (bestDifference <= 3) {\n    Ref<FormatInformation> result(new FormatInformation(bestFormatInfo));\n    return result;\n  }\n  Ref<FormatInformation> result;\n  return result;\n}\n\nbool operator==(const FormatInformation &a, const FormatInformation &b) {\n  return &(a.errorCorrectionLevel_) == &(b.errorCorrectionLevel_) && a.dataMask_ == b.dataMask_;\n}\n\nostream& operator<<(ostream& out, const FormatInformation& fi) {\n  const FormatInformation *fip = &fi;\n  out << \"FormatInformation @ \" << fip;\n  return out;\n}\n\n}\n}\n\n// file: zxing/qrcode/QRCodeReader.cpp\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n/*\n *  QRCodeReader.cpp\n *  zxing\n *\n *  Created by Christian Brunschen on 20/05/2008.\n *  Copyright 2008 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/qrcode/QRCodeReader.h>\n// #include <zxing/qrcode/detector/Detector.h>\n\n// #include <iostream>\n\nnamespace zxing {\n\tnamespace qrcode {\n\n\t\tusing namespace std;\n\n\t\tQRCodeReader::QRCodeReader() :decoder_() {\n\t\t}\n\t\t//TODO: see if any of the other files in the qrcode tree need tryHarder\n\t\tRef<Result> QRCodeReader::decode(Ref<BinaryBitmap> image, DecodeHints hints) {\n#ifdef DEBUG\n\t\t\tcout << \"decoding image \" << image.object_ << \":\\n\" << flush;\n#endif\n\n\t\t\tDetector detector(image->getBlackMatrix());\n\n\n#ifdef DEBUG\n\t\t\tcout << \"(1) created detector \" << &detector << \"\\n\" << flush;\n#endif\n\n\t\t\tRef<DetectorResult> detectorResult(detector.detect(hints));\n#ifdef DEBUG\n\t\t\tcout << \"(2) detected, have detectorResult \" << detectorResult.object_ << \"\\n\" << flush;\n#endif\n\n\t\t\tstd::vector<Ref<ResultPoint> > points(detectorResult->getPoints());\n\n\n#ifdef DEBUG\n\t\t\tcout << \"(3) extracted points \" << &points << \"\\n\" << flush;\n\t\t\tcout << \"found \" << points.size() << \" points:\\n\";\n\t\t\tfor (size_t i = 0; i < points.size(); i++) {\n\t\t\t\tcout << \"   \" << points[i]->getX() << \",\" << points[i]->getY() << \"\\n\";\n\t\t\t}\n\t\t\tcout << \"bits:\\n\";\n\t\t\tcout << *(detectorResult->getBits()) << \"\\n\";\n#endif\n\n\t\t\tRef<DecoderResult> decoderResult(decoder_.decode(detectorResult->getBits()));\n#ifdef DEBUG\n\t\t\tcout << \"(4) decoded, have decoderResult \" << decoderResult.object_ << \"\\n\" << flush;\n#endif\n\n\t\t\tRef<Result> result(\n\t\t\t\t\t\t\t   new Result(decoderResult->getText(), decoderResult->getRawBytes(), points, BarcodeFormat_QR_CODE));\n#ifdef DEBUG\n\t\t\tcout << \"(5) created result \" << result.object_ << \", returning\\n\" << flush;\n#endif\n\n\t\t\treturn result;\n\t\t}\n\n\t\tQRCodeReader::~QRCodeReader() {\n\t\t}\n\n    Decoder& QRCodeReader::getDecoder() {\n        return decoder_;\n    }\n\t}\n}\n\n// file: zxing/qrcode/Version.cpp\n\n/*\n *  Version.cpp\n *  zxing\n *\n *  Created by Christian Brunschen on 14/05/2008.\n *  Copyright 2008 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/qrcode/Version.h>\n// #include <zxing/qrcode/FormatInformation.h>\n// #include <limits>\n// #include <iostream>\n// #include <cstdarg>\n\nnamespace zxing {\nnamespace qrcode {\nusing namespace std;\n\nECB::ECB(int count, int dataCodewords) :\n    count_(count), dataCodewords_(dataCodewords) {\n}\n\nint ECB::getCount() {\n  return count_;\n}\n\nint ECB::getDataCodewords() {\n  return dataCodewords_;\n}\n\nECBlocks::ECBlocks(int ecCodewords, ECB *ecBlocks) :\n    ecCodewords_(ecCodewords), ecBlocks_(1, ecBlocks) {\n}\n\nECBlocks::ECBlocks(int ecCodewords, ECB *ecBlocks1, ECB *ecBlocks2) :\n    ecCodewords_(ecCodewords), ecBlocks_(1, ecBlocks1) {\n  ecBlocks_.push_back(ecBlocks2);\n}\n\nint ECBlocks::getECCodewords() {\n  return ecCodewords_;\n}\n\nstd::vector<ECB*>& ECBlocks::getECBlocks() {\n  return ecBlocks_;\n}\n\nECBlocks::~ECBlocks() {\n  for (size_t i = 0; i < ecBlocks_.size(); i++) {\n    delete ecBlocks_[i];\n  }\n}\n\nunsigned int Version::VERSION_DECODE_INFO[] = { 0x07C94, 0x085BC, 0x09A99, 0x0A4D3, 0x0BBF6, 0x0C762, 0x0D847, 0x0E60D,\n    0x0F928, 0x10B78, 0x1145D, 0x12A17, 0x13532, 0x149A6, 0x15683, 0x168C9, 0x177EC, 0x18EC4, 0x191E1, 0x1AFAB,\n    0x1B08E, 0x1CC1A, 0x1D33F, 0x1ED75, 0x1F250, 0x209D5, 0x216F0, 0x228BA, 0x2379F, 0x24B0B, 0x2542E, 0x26A64,\n    0x27541, 0x28C69\n                                              };\nint Version::N_VERSION_DECODE_INFOS = 34;\nvector<Ref<Version> > Version::VERSIONS;\nstatic int N_VERSIONS = Version::buildVersions();\n\nint Version::getVersionNumber() {\n  return versionNumber_;\n}\n\nvector<int> &Version::getAlignmentPatternCenters() {\n  return alignmentPatternCenters_;\n}\n\nint Version::getTotalCodewords() {\n  return totalCodewords_;\n}\n\nint Version::getDimensionForVersion() {\n  return 17 + 4 * versionNumber_;\n}\n\nECBlocks& Version::getECBlocksForLevel(ErrorCorrectionLevel &ecLevel) {\n  return *ecBlocks_[ecLevel.ordinal()];\n}\n\nVersion *Version::getProvisionalVersionForDimension(int dimension) {\n  if (dimension % 4 != 1) {\n    throw ReaderException(\"Dimension must be 1 mod 4\");\n  }\n  return Version::getVersionForNumber((dimension - 17) >> 2);\n}\n\nVersion *Version::getVersionForNumber(int versionNumber) {\n  if (versionNumber < 1 || versionNumber > N_VERSIONS) {\n    throw ReaderException(\"versionNumber must be between 1 and 40\");\n  }\n\n  return VERSIONS[versionNumber - 1];\n}\n\nVersion::Version(int versionNumber, vector<int> *alignmentPatternCenters, ECBlocks *ecBlocks1, ECBlocks *ecBlocks2,\n                 ECBlocks *ecBlocks3, ECBlocks *ecBlocks4) :\n    versionNumber_(versionNumber), alignmentPatternCenters_(*alignmentPatternCenters), ecBlocks_(4), totalCodewords_(0) {\n  ecBlocks_[0] = ecBlocks1;\n  ecBlocks_[1] = ecBlocks2;\n  ecBlocks_[2] = ecBlocks3;\n  ecBlocks_[3] = ecBlocks4;\n\n  int total = 0;\n  int ecCodewords = ecBlocks1->getECCodewords();\n  vector<ECB*> &ecbArray = ecBlocks1->getECBlocks();\n  for (size_t i = 0; i < ecbArray.size(); i++) {\n    ECB *ecBlock = ecbArray[i];\n    total += ecBlock->getCount() * (ecBlock->getDataCodewords() + ecCodewords);\n  }\n  totalCodewords_ = total;\n}\n\nVersion::~Version() {\n  delete &alignmentPatternCenters_;\n  for (size_t i = 0; i < ecBlocks_.size(); i++) {\n    delete ecBlocks_[i];\n  }\n}\n\nVersion *Version::decodeVersionInformation(unsigned int versionBits) {\n  int bestDifference = numeric_limits<int>::max();\n  size_t bestVersion = 0;\n  for (int i = 0; i < N_VERSION_DECODE_INFOS; i++) {\n    unsigned targetVersion = VERSION_DECODE_INFO[i];\n    // Do the version info bits match exactly? done.\n    if (targetVersion == versionBits) {\n      return getVersionForNumber(i + 7);\n    }\n    // Otherwise see if this is the closest to a real version info bit\n    // string we have seen so far\n    int bitsDifference = FormatInformation::numBitsDiffering(versionBits, targetVersion);\n    if (bitsDifference < bestDifference) {\n      bestVersion = i + 7;\n      bestDifference = bitsDifference;\n    }\n  }\n  // We can tolerate up to 3 bits of error since no two version info codewords will\n  // differ in less than 4 bits.\n  if (bestDifference <= 3) {\n    return getVersionForNumber((int)bestVersion);\n  }\n  // If we didn't find a close enough match, fail\n  return 0;\n}\n\nRef<BitMatrix> Version::buildFunctionPattern() {\n  int dimension = getDimensionForVersion();\n  Ref<BitMatrix> functionPattern(new BitMatrix(dimension));\n\n\n  // Top left finder pattern + separator + format\n  functionPattern->setRegion(0, 0, 9, 9);\n  // Top right finder pattern + separator + format\n  functionPattern->setRegion(dimension - 8, 0, 8, 9);\n  // Bottom left finder pattern + separator + format\n  functionPattern->setRegion(0, dimension - 8, 9, 8);\n\n\n  // Alignment patterns\n  size_t max = alignmentPatternCenters_.size();\n  for (size_t x = 0; x < max; x++) {\n    int i = alignmentPatternCenters_[x] - 2;\n    for (size_t y = 0; y < max; y++) {\n      if ((x == 0 && (y == 0 || y == max - 1)) || (x == max - 1 && y == 0)) {\n        // No alignment patterns near the three finder patterns\n        continue;\n      }\n      functionPattern->setRegion(alignmentPatternCenters_[y] - 2, i, 5, 5);\n    }\n  }\n\n  // Vertical timing pattern\n  functionPattern->setRegion(6, 9, 1, dimension - 17);\n  // Horizontal timing pattern\n  functionPattern->setRegion(9, 6, dimension - 17, 1);\n\n  if (versionNumber_ > 6) {\n    // Version info, top right\n    functionPattern->setRegion(dimension - 11, 0, 3, 6);\n    // Version info, bottom left\n    functionPattern->setRegion(0, dimension - 11, 6, 3);\n  }\n\n\n  //#ifdef DEBUG\n  //\tcout << \"version \" << versionNumber_ << \" built function pattern:\\n\";\n  //\tcout << *functionPattern;\n  //#endif\n\n  return functionPattern;\n}\n\nstatic vector<int> *intArray(size_t n...) {\n  va_list ap;\n  va_start(ap, n);\n  vector<int> *result = new vector<int>(n);\n  for (size_t i = 0; i < n; i++) {\n    (*result)[i] = va_arg(ap, int);\n  }\n  va_end(ap);\n  return result;\n}\n\nint Version::buildVersions() {\n  VERSIONS.push_back(Ref<Version>(new Version(1, intArray(0),\n                                  new ECBlocks(7, new ECB(1, 19)),\n                                  new ECBlocks(10, new ECB(1, 16)),\n                                  new ECBlocks(13, new ECB(1, 13)),\n                                  new ECBlocks(17, new ECB(1, 9)))));\n  VERSIONS.push_back(Ref<Version>(new Version(2, intArray(2, 6, 18),\n                                  new ECBlocks(10, new ECB(1, 34)),\n                                  new ECBlocks(16, new ECB(1, 28)),\n                                  new ECBlocks(22, new ECB(1, 22)),\n                                  new ECBlocks(28, new ECB(1, 16)))));\n  VERSIONS.push_back(Ref<Version>(new Version(3, intArray(2, 6, 22),\n                                  new ECBlocks(15, new ECB(1, 55)),\n                                  new ECBlocks(26, new ECB(1, 44)),\n                                  new ECBlocks(18, new ECB(2, 17)),\n                                  new ECBlocks(22, new ECB(2, 13)))));\n  VERSIONS.push_back(Ref<Version>(new Version(4, intArray(2, 6, 26),\n                                  new ECBlocks(20, new ECB(1, 80)),\n                                  new ECBlocks(18, new ECB(2, 32)),\n                                  new ECBlocks(26, new ECB(2, 24)),\n                                  new ECBlocks(16, new ECB(4, 9)))));\n  VERSIONS.push_back(Ref<Version>(new Version(5, intArray(2, 6, 30),\n                                  new ECBlocks(26, new ECB(1, 108)),\n                                  new ECBlocks(24, new ECB(2, 43)),\n                                  new ECBlocks(18, new ECB(2, 15),\n                                               new ECB(2, 16)),\n                                  new ECBlocks(22, new ECB(2, 11),\n                                               new ECB(2, 12)))));\n  VERSIONS.push_back(Ref<Version>(new Version(6, intArray(2, 6, 34),\n                                  new ECBlocks(18, new ECB(2, 68)),\n                                  new ECBlocks(16, new ECB(4, 27)),\n                                  new ECBlocks(24, new ECB(4, 19)),\n                                  new ECBlocks(28, new ECB(4, 15)))));\n  VERSIONS.push_back(Ref<Version>(new Version(7, intArray(3, 6, 22, 38),\n                                  new ECBlocks(20, new ECB(2, 78)),\n                                  new ECBlocks(18, new ECB(4, 31)),\n                                  new ECBlocks(18, new ECB(2, 14),\n                                               new ECB(4, 15)),\n                                  new ECBlocks(26, new ECB(4, 13),\n                                               new ECB(1, 14)))));\n  VERSIONS.push_back(Ref<Version>(new Version(8, intArray(3, 6, 24, 42),\n                                  new ECBlocks(24, new ECB(2, 97)),\n                                  new ECBlocks(22, new ECB(2, 38),\n                                               new ECB(2, 39)),\n                                  new ECBlocks(22, new ECB(4, 18),\n                                               new ECB(2, 19)),\n                                  new ECBlocks(26, new ECB(4, 14),\n                                               new ECB(2, 15)))));\n  VERSIONS.push_back(Ref<Version>(new Version(9, intArray(3, 6, 26, 46),\n                                  new ECBlocks(30, new ECB(2, 116)),\n                                  new ECBlocks(22, new ECB(3, 36),\n                                               new ECB(2, 37)),\n                                  new ECBlocks(20, new ECB(4, 16),\n                                               new ECB(4, 17)),\n                                  new ECBlocks(24, new ECB(4, 12),\n                                               new ECB(4, 13)))));\n  VERSIONS.push_back(Ref<Version>(new Version(10, intArray(3, 6, 28, 50),\n                                  new ECBlocks(18, new ECB(2, 68),\n                                               new ECB(2, 69)),\n                                  new ECBlocks(26, new ECB(4, 43),\n                                               new ECB(1, 44)),\n                                  new ECBlocks(24, new ECB(6, 19),\n                                               new ECB(2, 20)),\n                                  new ECBlocks(28, new ECB(6, 15),\n                                               new ECB(2, 16)))));\n  VERSIONS.push_back(Ref<Version>(new Version(11, intArray(3, 6, 30, 54),\n                                  new ECBlocks(20, new ECB(4, 81)),\n                                  new ECBlocks(30, new ECB(1, 50),\n                                               new ECB(4, 51)),\n                                  new ECBlocks(28, new ECB(4, 22),\n                                               new ECB(4, 23)),\n                                  new ECBlocks(24, new ECB(3, 12),\n                                               new ECB(8, 13)))));\n  VERSIONS.push_back(Ref<Version>(new Version(12, intArray(3, 6, 32, 58),\n                                  new ECBlocks(24, new ECB(2, 92),\n                                               new ECB(2, 93)),\n                                  new ECBlocks(22, new ECB(6, 36),\n                                               new ECB(2, 37)),\n                                  new ECBlocks(26, new ECB(4, 20),\n                                               new ECB(6, 21)),\n                                  new ECBlocks(28, new ECB(7, 14),\n                                               new ECB(4, 15)))));\n  VERSIONS.push_back(Ref<Version>(new Version(13, intArray(3, 6, 34, 62),\n                                  new ECBlocks(26, new ECB(4, 107)),\n                                  new ECBlocks(22, new ECB(8, 37),\n                                               new ECB(1, 38)),\n                                  new ECBlocks(24, new ECB(8, 20),\n                                               new ECB(4, 21)),\n                                  new ECBlocks(22, new ECB(12, 11),\n                                               new ECB(4, 12)))));\n  VERSIONS.push_back(Ref<Version>(new Version(14, intArray(4, 6, 26, 46, 66),\n                                  new ECBlocks(30, new ECB(3, 115),\n                                               new ECB(1, 116)),\n                                  new ECBlocks(24, new ECB(4, 40),\n                                               new ECB(5, 41)),\n                                  new ECBlocks(20, new ECB(11, 16),\n                                               new ECB(5, 17)),\n                                  new ECBlocks(24, new ECB(11, 12),\n                                               new ECB(5, 13)))));\n  VERSIONS.push_back(Ref<Version>(new Version(15, intArray(4, 6, 26, 48, 70),\n                                  new ECBlocks(22, new ECB(5, 87),\n                                               new ECB(1, 88)),\n                                  new ECBlocks(24, new ECB(5, 41),\n                                               new ECB(5, 42)),\n                                  new ECBlocks(30, new ECB(5, 24),\n                                               new ECB(7, 25)),\n                                  new ECBlocks(24, new ECB(11, 12),\n                                               new ECB(7, 13)))));\n  VERSIONS.push_back(Ref<Version>(new Version(16, intArray(4, 6, 26, 50, 74),\n                                  new ECBlocks(24, new ECB(5, 98),\n                                               new ECB(1, 99)),\n                                  new ECBlocks(28, new ECB(7, 45),\n                                               new ECB(3, 46)),\n                                  new ECBlocks(24, new ECB(15, 19),\n                                               new ECB(2, 20)),\n                                  new ECBlocks(30, new ECB(3, 15),\n                                               new ECB(13, 16)))));\n  VERSIONS.push_back(Ref<Version>(new Version(17, intArray(4, 6, 30, 54, 78),\n                                  new ECBlocks(28, new ECB(1, 107),\n                                               new ECB(5, 108)),\n                                  new ECBlocks(28, new ECB(10, 46),\n                                               new ECB(1, 47)),\n                                  new ECBlocks(28, new ECB(1, 22),\n                                               new ECB(15, 23)),\n                                  new ECBlocks(28, new ECB(2, 14),\n                                               new ECB(17, 15)))));\n  VERSIONS.push_back(Ref<Version>(new Version(18, intArray(4, 6, 30, 56, 82),\n                                  new ECBlocks(30, new ECB(5, 120),\n                                               new ECB(1, 121)),\n                                  new ECBlocks(26, new ECB(9, 43),\n                                               new ECB(4, 44)),\n                                  new ECBlocks(28, new ECB(17, 22),\n                                               new ECB(1, 23)),\n                                  new ECBlocks(28, new ECB(2, 14),\n                                               new ECB(19, 15)))));\n  VERSIONS.push_back(Ref<Version>(new Version(19, intArray(4, 6, 30, 58, 86),\n                                  new ECBlocks(28, new ECB(3, 113),\n                                               new ECB(4, 114)),\n                                  new ECBlocks(26, new ECB(3, 44),\n                                               new ECB(11, 45)),\n                                  new ECBlocks(26, new ECB(17, 21),\n                                               new ECB(4, 22)),\n                                  new ECBlocks(26, new ECB(9, 13),\n                                               new ECB(16, 14)))));\n  VERSIONS.push_back(Ref<Version>(new Version(20, intArray(4, 6, 34, 62, 90),\n                                  new ECBlocks(28, new ECB(3, 107),\n                                               new ECB(5, 108)),\n                                  new ECBlocks(26, new ECB(3, 41),\n                                               new ECB(13, 42)),\n                                  new ECBlocks(30, new ECB(15, 24),\n                                               new ECB(5, 25)),\n                                  new ECBlocks(28, new ECB(15, 15),\n                                               new ECB(10, 16)))));\n  VERSIONS.push_back(Ref<Version>(new Version(21, intArray(5, 6, 28, 50, 72, 94),\n                                  new ECBlocks(28, new ECB(4, 116),\n                                               new ECB(4, 117)),\n                                  new ECBlocks(26, new ECB(17, 42)),\n                                  new ECBlocks(28, new ECB(17, 22),\n                                               new ECB(6, 23)),\n                                  new ECBlocks(30, new ECB(19, 16),\n                                               new ECB(6, 17)))));\n  VERSIONS.push_back(Ref<Version>(new Version(22, intArray(5, 6, 26, 50, 74, 98),\n                                  new ECBlocks(28, new ECB(2, 111),\n                                               new ECB(7, 112)),\n                                  new ECBlocks(28, new ECB(17, 46)),\n                                  new ECBlocks(30, new ECB(7, 24),\n                                               new ECB(16, 25)),\n                                  new ECBlocks(24, new ECB(34, 13)))));\n  VERSIONS.push_back(Ref<Version>(new Version(23, intArray(5, 6, 30, 54, 78, 102),\n                                  new ECBlocks(30, new ECB(4, 121),\n                                               new ECB(5, 122)),\n                                  new ECBlocks(28, new ECB(4, 47),\n                                               new ECB(14, 48)),\n                                  new ECBlocks(30, new ECB(11, 24),\n                                               new ECB(14, 25)),\n                                  new ECBlocks(30, new ECB(16, 15),\n                                               new ECB(14, 16)))));\n  VERSIONS.push_back(Ref<Version>(new Version(24, intArray(5, 6, 28, 54, 80, 106),\n                                  new ECBlocks(30, new ECB(6, 117),\n                                               new ECB(4, 118)),\n                                  new ECBlocks(28, new ECB(6, 45),\n                                               new ECB(14, 46)),\n                                  new ECBlocks(30, new ECB(11, 24),\n                                               new ECB(16, 25)),\n                                  new ECBlocks(30, new ECB(30, 16),\n                                               new ECB(2, 17)))));\n  VERSIONS.push_back(Ref<Version>(new Version(25, intArray(5, 6, 32, 58, 84, 110),\n                                  new ECBlocks(26, new ECB(8, 106),\n                                               new ECB(4, 107)),\n                                  new ECBlocks(28, new ECB(8, 47),\n                                               new ECB(13, 48)),\n                                  new ECBlocks(30, new ECB(7, 24),\n                                               new ECB(22, 25)),\n                                  new ECBlocks(30, new ECB(22, 15),\n                                               new ECB(13, 16)))));\n  VERSIONS.push_back(Ref<Version>(new Version(26, intArray(5, 6, 30, 58, 86, 114),\n                                  new ECBlocks(28, new ECB(10, 114),\n                                               new ECB(2, 115)),\n                                  new ECBlocks(28, new ECB(19, 46),\n                                               new ECB(4, 47)),\n                                  new ECBlocks(28, new ECB(28, 22),\n                                               new ECB(6, 23)),\n                                  new ECBlocks(30, new ECB(33, 16),\n                                               new ECB(4, 17)))));\n  VERSIONS.push_back(Ref<Version>(new Version(27, intArray(5, 6, 34, 62, 90, 118),\n                                  new ECBlocks(30, new ECB(8, 122),\n                                               new ECB(4, 123)),\n                                  new ECBlocks(28, new ECB(22, 45),\n                                               new ECB(3, 46)),\n                                  new ECBlocks(30, new ECB(8, 23),\n                                               new ECB(26, 24)),\n                                  new ECBlocks(30, new ECB(12, 15),\n                                               new ECB(28, 16)))));\n  VERSIONS.push_back(Ref<Version>(new Version(28, intArray(6, 6, 26, 50, 74, 98, 122),\n                                  new ECBlocks(30, new ECB(3, 117),\n                                               new ECB(10, 118)),\n                                  new ECBlocks(28, new ECB(3, 45),\n                                               new ECB(23, 46)),\n                                  new ECBlocks(30, new ECB(4, 24),\n                                               new ECB(31, 25)),\n                                  new ECBlocks(30, new ECB(11, 15),\n                                               new ECB(31, 16)))));\n  VERSIONS.push_back(Ref<Version>(new Version(29, intArray(6, 6, 30, 54, 78, 102, 126),\n                                  new ECBlocks(30, new ECB(7, 116),\n                                               new ECB(7, 117)),\n                                  new ECBlocks(28, new ECB(21, 45),\n                                               new ECB(7, 46)),\n                                  new ECBlocks(30, new ECB(1, 23),\n                                               new ECB(37, 24)),\n                                  new ECBlocks(30, new ECB(19, 15),\n                                               new ECB(26, 16)))));\n  VERSIONS.push_back(Ref<Version>(new Version(30, intArray(6, 6, 26, 52, 78, 104, 130),\n                                  new ECBlocks(30, new ECB(5, 115),\n                                               new ECB(10, 116)),\n                                  new ECBlocks(28, new ECB(19, 47),\n                                               new ECB(10, 48)),\n                                  new ECBlocks(30, new ECB(15, 24),\n                                               new ECB(25, 25)),\n                                  new ECBlocks(30, new ECB(23, 15),\n                                               new ECB(25, 16)))));\n  VERSIONS.push_back(Ref<Version>(new Version(31, intArray(6, 6, 30, 56, 82, 108, 134),\n                                  new ECBlocks(30, new ECB(13, 115),\n                                               new ECB(3, 116)),\n                                  new ECBlocks(28, new ECB(2, 46),\n                                               new ECB(29, 47)),\n                                  new ECBlocks(30, new ECB(42, 24),\n                                               new ECB(1, 25)),\n                                  new ECBlocks(30, new ECB(23, 15),\n                                               new ECB(28, 16)))));\n  VERSIONS.push_back(Ref<Version>(new Version(32, intArray(6, 6, 34, 60, 86, 112, 138),\n                                  new ECBlocks(30, new ECB(17, 115)),\n                                  new ECBlocks(28, new ECB(10, 46),\n                                               new ECB(23, 47)),\n                                  new ECBlocks(30, new ECB(10, 24),\n                                               new ECB(35, 25)),\n                                  new ECBlocks(30, new ECB(19, 15),\n                                               new ECB(35, 16)))));\n  VERSIONS.push_back(Ref<Version>(new Version(33, intArray(6, 6, 30, 58, 86, 114, 142),\n                                  new ECBlocks(30, new ECB(17, 115),\n                                               new ECB(1, 116)),\n                                  new ECBlocks(28, new ECB(14, 46),\n                                               new ECB(21, 47)),\n                                  new ECBlocks(30, new ECB(29, 24),\n                                               new ECB(19, 25)),\n                                  new ECBlocks(30, new ECB(11, 15),\n                                               new ECB(46, 16)))));\n  VERSIONS.push_back(Ref<Version>(new Version(34, intArray(6, 6, 34, 62, 90, 118, 146),\n                                  new ECBlocks(30, new ECB(13, 115),\n                                               new ECB(6, 116)),\n                                  new ECBlocks(28, new ECB(14, 46),\n                                               new ECB(23, 47)),\n                                  new ECBlocks(30, new ECB(44, 24),\n                                               new ECB(7, 25)),\n                                  new ECBlocks(30, new ECB(59, 16),\n                                               new ECB(1, 17)))));\n  VERSIONS.push_back(Ref<Version>(new Version(35, intArray(7, 6, 30, 54, 78,\n                                  102, 126, 150),\n                                  new ECBlocks(30, new ECB(12, 121),\n                                               new ECB(7, 122)),\n                                  new ECBlocks(28, new ECB(12, 47),\n                                               new ECB(26, 48)),\n                                  new ECBlocks(30, new ECB(39, 24),\n                                               new ECB(14, 25)),\n                                  new ECBlocks(30, new ECB(22, 15),\n                                               new ECB(41, 16)))));\n  VERSIONS.push_back(Ref<Version>(new Version(36, intArray(7, 6, 24, 50, 76,\n                                  102, 128, 154),\n                                  new ECBlocks(30, new ECB(6, 121),\n                                               new ECB(14, 122)),\n                                  new ECBlocks(28, new ECB(6, 47),\n                                               new ECB(34, 48)),\n                                  new ECBlocks(30, new ECB(46, 24),\n                                               new ECB(10, 25)),\n                                  new ECBlocks(30, new ECB(2, 15),\n                                               new ECB(64, 16)))));\n  VERSIONS.push_back(Ref<Version>(new Version(37, intArray(7, 6, 28, 54, 80,\n                                  106, 132, 158),\n                                  new ECBlocks(30, new ECB(17, 122),\n                                               new ECB(4, 123)),\n                                  new ECBlocks(28, new ECB(29, 46),\n                                               new ECB(14, 47)),\n                                  new ECBlocks(30, new ECB(49, 24),\n                                               new ECB(10, 25)),\n                                  new ECBlocks(30, new ECB(24, 15),\n                                               new ECB(46, 16)))));\n  VERSIONS.push_back(Ref<Version>(new Version(38, intArray(7, 6, 32, 58, 84,\n                                  110, 136, 162),\n                                  new ECBlocks(30, new ECB(4, 122),\n                                               new ECB(18, 123)),\n                                  new ECBlocks(28, new ECB(13, 46),\n                                               new ECB(32, 47)),\n                                  new ECBlocks(30, new ECB(48, 24),\n                                               new ECB(14, 25)),\n                                  new ECBlocks(30, new ECB(42, 15),\n                                               new ECB(32, 16)))));\n  VERSIONS.push_back(Ref<Version>(new Version(39, intArray(7, 6, 26, 54, 82,\n                                  110, 138, 166),\n                                  new ECBlocks(30, new ECB(20, 117),\n                                               new ECB(4, 118)),\n                                  new ECBlocks(28, new ECB(40, 47),\n                                               new ECB(7, 48)),\n                                  new ECBlocks(30, new ECB(43, 24),\n                                               new ECB(22, 25)),\n                                  new ECBlocks(30, new ECB(10, 15),\n                                               new ECB(67, 16)))));\n  VERSIONS.push_back(Ref<Version>(new Version(40, intArray(7, 6, 30, 58, 86,\n                                  114, 142, 170),\n                                  new ECBlocks(30, new ECB(19, 118),\n                                               new ECB(6, 119)),\n                                  new ECBlocks(28, new ECB(18, 47),\n                                               new ECB(31, 48)),\n                                  new ECBlocks(30, new ECB(34, 24),\n                                               new ECB(34, 25)),\n                                  new ECBlocks(30, new ECB(20, 15),\n                                               new ECB(61, 16)))));\n  return (int)VERSIONS.size();\n}\n}\n}\n\n// file: zxing/qrcode/decoder/BitMatrixParser.cpp\n\n/*\n *  BitMatrixParser.cpp\n *  zxing\n *\n *  Created by Christian Brunschen on 20/05/2008.\n *  Copyright 2008 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/qrcode/decoder/BitMatrixParser.h>\n// #include <zxing/qrcode/decoder/DataMask.h>\n\n\nnamespace zxing {\nnamespace qrcode {\n\nint BitMatrixParser::copyBit(size_t x, size_t y, int versionBits) {\n  return bitMatrix_->get(x, y) ? (versionBits << 1) | 0x1 : versionBits << 1;\n}\n\nBitMatrixParser::BitMatrixParser(Ref<BitMatrix> bitMatrix) :\n    bitMatrix_(bitMatrix), parsedVersion_(0), parsedFormatInfo_() {\n  size_t dimension = bitMatrix->getDimension();\n  if ((dimension < 21) || (dimension & 0x03) != 1) {\n    throw ReaderException(\"Dimension must be 1 mod 4 and >= 21\");\n  }\n}\n\nRef<FormatInformation> BitMatrixParser::readFormatInformation() {\n  if (parsedFormatInfo_ != 0) {\n    return parsedFormatInfo_;\n  }\n\n  // Read top-left format info bits\n  int formatInfoBits1 = 0;\n  for (int i = 0; i < 6; i++) {\n    formatInfoBits1 = copyBit(i, 8, formatInfoBits1);\n  }\n  // .. and skip a bit in the timing pattern ...\n  formatInfoBits1 = copyBit(7, 8, formatInfoBits1);\n  formatInfoBits1 = copyBit(8, 8, formatInfoBits1);\n  formatInfoBits1 = copyBit(8, 7, formatInfoBits1);\n  // .. and skip a bit in the timing pattern ...\n  for (int j = 5; j >= 0; j--) {\n    formatInfoBits1 = copyBit(8, j, formatInfoBits1);\n  }\n\n  // Read the top-right/bottom-left pattern\n  int dimension = (int)bitMatrix_->getDimension();\n  int formatInfoBits2 = 0;\n  int jMin = dimension - 7;\n  for (int j = dimension - 1; j >= jMin; j--) {\n    formatInfoBits2 = copyBit(8, j, formatInfoBits2);\n  }\n  for (int i = dimension - 8; i < dimension; i++) {\n    formatInfoBits2 = copyBit(i, 8, formatInfoBits2);\n  }\n\n  parsedFormatInfo_ = FormatInformation::decodeFormatInformation(formatInfoBits1,formatInfoBits2);\n  if (parsedFormatInfo_ != 0) {\n    return parsedFormatInfo_;\n  }\n  throw ReaderException(\"Could not decode format information\");\n}\n\nVersion *BitMatrixParser::readVersion() {\n  if (parsedVersion_ != 0) {\n    return parsedVersion_;\n  }\n\n  int dimension = (int)bitMatrix_->getDimension();\n\n  int provisionalVersion = (dimension - 17) >> 2;\n  if (provisionalVersion <= 6) {\n    return Version::getVersionForNumber(provisionalVersion);\n  }\n\n  // Read top-right version info: 3 wide by 6 tall\n  int versionBits = 0;\n  for (int y = 5; y >= 0; y--) {\n    int xMin = dimension - 11;\n    for (int x = dimension - 9; x >= xMin; x--) {\n      versionBits = copyBit(x, y, versionBits);\n    }\n  }\n\n  parsedVersion_ = Version::decodeVersionInformation(versionBits);\n  if (parsedVersion_ != 0 && parsedVersion_->getDimensionForVersion() == dimension) {\n    return parsedVersion_;\n  }\n\n  // Hmm, failed. Try bottom left: 6 wide by 3 tall\n  versionBits = 0;\n  for (int x = 5; x >= 0; x--) {\n    int yMin = dimension - 11;\n    for (int y = dimension - 9; y >= yMin; y--) {\n      versionBits = copyBit(x, y, versionBits);\n    }\n  }\n\n  parsedVersion_ = Version::decodeVersionInformation(versionBits);\n  if (parsedVersion_ != 0 && parsedVersion_->getDimensionForVersion() == dimension) {\n    return parsedVersion_;\n  }\n  throw ReaderException(\"Could not decode version\");\n}\n\nArrayRef<unsigned char> BitMatrixParser::readCodewords() {\n  Ref<FormatInformation> formatInfo = readFormatInformation();\n  Version *version = readVersion();\n\n\n  //\tcerr << *bitMatrix_ << endl;\n  //\tcerr << bitMatrix_->getDimension() << endl;\n\n  // Get the data mask for the format used in this QR Code. This will exclude\n  // some bits from reading as we wind through the bit matrix.\n  DataMask &dataMask = DataMask::forReference((int)formatInfo->getDataMask());\n  //\tcout << (int)formatInfo->getDataMask() << endl;\n  int dimension = (int)bitMatrix_->getDimension();\n  dataMask.unmaskBitMatrix(*bitMatrix_, dimension);\n\n\n  //\t\tcerr << *bitMatrix_ << endl;\n  //\tcerr << version->getTotalCodewords() << endl;\n\n  Ref<BitMatrix> functionPattern = version->buildFunctionPattern();\n\n\n  //\tcout << *functionPattern << endl;\n\n  bool readingUp = true;\n  ArrayRef<unsigned char> result(version->getTotalCodewords());\n  int resultOffset = 0;\n  int currentByte = 0;\n  int bitsRead = 0;\n  // Read columns in pairs, from right to left\n  for (int x = dimension - 1; x > 0; x -= 2) {\n    if (x == 6) {\n      // Skip whole column with vertical alignment pattern;\n      // saves time and makes the other code proceed more cleanly\n      x--;\n    }\n    // Read alternatingly from bottom to top then top to bottom\n    for (int counter = 0; counter < dimension; counter++) {\n      int y = readingUp ? dimension - 1 - counter : counter;\n      for (int col = 0; col < 2; col++) {\n        // Ignore bits covered by the function pattern\n        if (!functionPattern->get(x - col, y)) {\n          // Read a bit\n          bitsRead++;\n          currentByte <<= 1;\n          if (bitMatrix_->get(x - col, y)) {\n            currentByte |= 1;\n          }\n          // If we've made a whole byte, save it off\n          if (bitsRead == 8) {\n            result[resultOffset++] = (unsigned char)currentByte;\n            bitsRead = 0;\n            currentByte = 0;\n          }\n        }\n      }\n    }\n    readingUp = !readingUp; // switch directions\n  }\n\n  if (resultOffset != version->getTotalCodewords()) {\n    throw ReaderException(\"Did not read all codewords\");\n  }\n  return result;\n}\n\n}\n}\n\n// file: zxing/qrcode/decoder/DataBlock.cpp\n\n/*\n *  DataBlock.cpp\n *  zxing\n *\n *  Created by Christian Brunschen on 19/05/2008.\n *  Copyright 2008 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/qrcode/decoder/DataBlock.h>\n// #include <zxing/common/IllegalArgumentException.h>\n\nnamespace zxing {\nnamespace qrcode {\n\nusing namespace std;\n\nDataBlock::DataBlock(int numDataCodewords, ArrayRef<unsigned char> codewords) :\n    numDataCodewords_(numDataCodewords), codewords_(codewords) {\n}\n\nint DataBlock::getNumDataCodewords() {\n  return numDataCodewords_;\n}\n\nArrayRef<unsigned char> DataBlock::getCodewords() {\n  return codewords_;\n}\n\n\nstd::vector<Ref<DataBlock> > DataBlock::getDataBlocks(ArrayRef<unsigned char> rawCodewords, Version *version,\n    ErrorCorrectionLevel &ecLevel) {\n\n\n  // Figure out the number and size of data blocks used by this version and\n  // error correction level\n  ECBlocks &ecBlocks = version->getECBlocksForLevel(ecLevel);\n\n\n  // First count the total number of data blocks\n  int totalBlocks = 0;\n  vector<ECB*> ecBlockArray = ecBlocks.getECBlocks();\n  for (size_t i = 0; i < ecBlockArray.size(); i++) {\n    totalBlocks += ecBlockArray[i]->getCount();\n  }\n\n  // Now establish DataBlocks of the appropriate size and number of data codewords\n  std::vector<Ref<DataBlock> > result(totalBlocks);\n  int numResultBlocks = 0;\n  for (size_t j = 0; j < ecBlockArray.size(); j++) {\n    ECB *ecBlock = ecBlockArray[j];\n    for (int i = 0; i < ecBlock->getCount(); i++) {\n      int numDataCodewords = ecBlock->getDataCodewords();\n      int numBlockCodewords = ecBlocks.getECCodewords() + numDataCodewords;\n      ArrayRef<unsigned char> buffer(numBlockCodewords);\n      Ref<DataBlock> blockRef(new DataBlock(numDataCodewords, buffer));\n      result[numResultBlocks++] = blockRef;\n    }\n  }\n\n  // All blocks have the same amount of data, except that the last n\n  // (where n may be 0) have 1 more byte. Figure out where these start.\n  int shorterBlocksTotalCodewords = (int)result[0]->codewords_.size();\n  int longerBlocksStartAt = (int)(result.size() - 1);\n  while (longerBlocksStartAt >= 0) {\n    int numCodewords = (int)result[longerBlocksStartAt]->codewords_.size();\n    if (numCodewords == shorterBlocksTotalCodewords) {\n      break;\n    }\n    if (numCodewords != shorterBlocksTotalCodewords + 1) {\n      throw IllegalArgumentException(\"Data block sizes differ by more than 1\");\n    }\n    longerBlocksStartAt--;\n  }\n  longerBlocksStartAt++;\n\n  int shorterBlocksNumDataCodewords = shorterBlocksTotalCodewords - ecBlocks.getECCodewords();\n  // The last elements of result may be 1 element longer;\n  // first fill out as many elements as all of them have\n  int rawCodewordsOffset = 0;\n  for (int i = 0; i < shorterBlocksNumDataCodewords; i++) {\n    for (int j = 0; j < numResultBlocks; j++) {\n      result[j]->codewords_[i] = rawCodewords[rawCodewordsOffset++];\n    }\n  }\n  // Fill out the last data block in the longer ones\n  for (int j = longerBlocksStartAt; j < numResultBlocks; j++) {\n    result[j]->codewords_[shorterBlocksNumDataCodewords] = rawCodewords[rawCodewordsOffset++];\n  }\n  // Now add in error correction blocks\n  int max = (int)result[0]->codewords_.size();\n  for (int i = shorterBlocksNumDataCodewords; i < max; i++) {\n    for (int j = 0; j < numResultBlocks; j++) {\n      int iOffset = j < longerBlocksStartAt ? i : i + 1;\n      result[j]->codewords_[iOffset] = rawCodewords[rawCodewordsOffset++];\n    }\n  }\n\n  if ((size_t)rawCodewordsOffset != rawCodewords.size()) {\n    throw IllegalArgumentException(\"rawCodewordsOffset != rawCodewords.length\");\n  }\n\n  return result;\n}\n\n}\n}\n\n// file: zxing/qrcode/decoder/DataMask.cpp\n\n/*\n *  DataMask.cpp\n *  zxing\n *\n *  Created by Christian Brunschen on 19/05/2008.\n *  Copyright 2008 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/qrcode/decoder/DataMask.h>\n\n// #include <zxing/common/IllegalArgumentException.h>\n\nnamespace zxing {\nnamespace qrcode {\n\nusing namespace std;\n\nDataMask::DataMask() {\n}\n\nDataMask::~DataMask() {\n}\n\nvector<Ref<DataMask> > DataMask::DATA_MASKS;\nstatic int N_DATA_MASKS = DataMask::buildDataMasks();\n\nDataMask &DataMask::forReference(int reference) {\n  if (reference < 0 || reference > 7) {\n    throw IllegalArgumentException(\"reference must be between 0 and 7\");\n  }\n  return *DATA_MASKS[reference];\n}\n\nvoid DataMask::unmaskBitMatrix(BitMatrix& bits, size_t dimension) {\n  for (size_t y = 0; y < dimension; y++) {\n    for (size_t x = 0; x < dimension; x++) {\n      // TODO: check why the coordinates have to be swapped\n      if (isMasked(y, x)) {\n        bits.flip(x, y);\n      }\n    }\n  }\n}\n\n/**\n * 000: mask bits for which (x + y) mod 2 == 0\n */\nclass DataMask000 : public DataMask {\npublic:\n  bool isMasked(size_t x, size_t y) {\n    //\t\treturn ((x + y) & 0x01) == 0;\n    return ((x + y) % 2) == 0;\n  }\n};\n\n/**\n * 001: mask bits for which x mod 2 == 0\n */\nclass DataMask001 : public DataMask {\npublic:\n  bool isMasked(size_t x, size_t) {\n    //\t\treturn (x & 0x01) == 0;\n    return (x % 2) == 0;\n  }\n};\n\n/**\n * 010: mask bits for which y mod 3 == 0\n */\nclass DataMask010 : public DataMask {\npublic:\n  bool isMasked(size_t, size_t y) {\n    return y % 3 == 0;\n  }\n};\n\n/**\n * 011: mask bits for which (x + y) mod 3 == 0\n */\nclass DataMask011 : public DataMask {\npublic:\n  bool isMasked(size_t x, size_t y) {\n    return (x + y) % 3 == 0;\n  }\n};\n\n/**\n * 100: mask bits for which (x/2 + y/3) mod 2 == 0\n */\nclass DataMask100 : public DataMask {\npublic:\n  bool isMasked(size_t x, size_t y) {\n    //\t\treturn (((x >> 1) + (y / 3)) & 0x01) == 0;\n    return (((x >> 1) + (y / 3)) % 2) == 0;\n  }\n};\n\n/**\n * 101: mask bits for which xy mod 2 + xy mod 3 == 0\n */\nclass DataMask101 : public DataMask {\npublic:\n  bool isMasked(size_t x, size_t y) {\n    size_t temp = x * y;\n    //\t\treturn (temp & 0x01) + (temp % 3) == 0;\n    return (temp % 2) + (temp % 3) == 0;\n\n  }\n};\n\n/**\n * 110: mask bits for which (xy mod 2 + xy mod 3) mod 2 == 0\n */\nclass DataMask110 : public DataMask {\npublic:\n  bool isMasked(size_t x, size_t y) {\n    size_t temp = x * y;\n    //\t\treturn (((temp & 0x01) + (temp % 3)) & 0x01) == 0;\n    return (((temp % 2) + (temp % 3)) % 2) == 0;\n  }\n};\n\n/**\n * 111: mask bits for which ((x+y)mod 2 + xy mod 3) mod 2 == 0\n */\nclass DataMask111 : public DataMask {\npublic:\n  bool isMasked(size_t x, size_t y) {\n    //\t\treturn ((((x + y) & 0x01) + ((x * y) % 3)) & 0x01) == 0;\n    return ((((x + y) % 2) + ((x * y) % 3)) % 2) == 0;\n  }\n};\n\nint DataMask::buildDataMasks() {\n  DATA_MASKS.push_back(Ref<DataMask> (new DataMask000()));\n  DATA_MASKS.push_back(Ref<DataMask> (new DataMask001()));\n  DATA_MASKS.push_back(Ref<DataMask> (new DataMask010()));\n  DATA_MASKS.push_back(Ref<DataMask> (new DataMask011()));\n  DATA_MASKS.push_back(Ref<DataMask> (new DataMask100()));\n  DATA_MASKS.push_back(Ref<DataMask> (new DataMask101()));\n  DATA_MASKS.push_back(Ref<DataMask> (new DataMask110()));\n  DATA_MASKS.push_back(Ref<DataMask> (new DataMask111()));\n  return (int)DATA_MASKS.size();\n}\n\n}\n}\n\n// file: zxing/qrcode/decoder/DecodedBitStreamParser.cpp\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n/*\n *  DecodedBitStreamParser.cpp\n *  zxing\n *\n *  Created by Christian Brunschen on 20/05/2008.\n *  Copyright 2008 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/qrcode/decoder/DecodedBitStreamParser.h>\n// #include <zxing/common/CharacterSetECI.h>\n// #include <zxing/FormatException.h>\n// #include <zxing/common/StringUtils.h>\n// #include <iostream>\n#ifndef NO_ICONV\n// #include <iconv.h>\n#endif\n\n// Required for compatibility. TODO: test on Symbian\n#ifdef ZXING_ICONV_CONST\n#undef ICONV_CONST\n#define ICONV_CONST const\n#endif\n\n#ifndef ICONV_CONST\n#define ICONV_CONST /**/\n#endif\n\nusing namespace std;\nusing namespace zxing;\nusing namespace zxing::qrcode;\nusing namespace zxing::common;\n\nconst char DecodedBitStreamParser::ALPHANUMERIC_CHARS[] =\n{ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B',\n  'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',\n  'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',\n  'Y', 'Z', ' ', '$', '%', '*', '+', '-', '.', '/', ':'\n};\n\nnamespace {int GB2312_SUBSET = 1;}\n\nvoid DecodedBitStreamParser::append(std::string &result,\n                                    string const& in,\n                                    const char *src) {\n  append(result, (unsigned char const*)in.c_str(), in.length(), src);\n}\n\nvoid DecodedBitStreamParser::append(std::string &result,\n                                    const unsigned char *bufIn,\n                                    size_t nIn,\n                                    const char *src) {\n#ifndef NO_ICONV\n  if (nIn == 0) {\n    return;\n  }\n\n  iconv_t cd = iconv_open(StringUtils::UTF8, src);\n  if (cd == (iconv_t)-1) {\n    result.append((const char *)bufIn, nIn);\n    return;\n  }\n\n  const int maxOut = (int)(4 * nIn + 1);\n  unsigned char* bufOut = new unsigned char[maxOut];\n\n  ICONV_CONST char *fromPtr = (ICONV_CONST char *)bufIn;\n  size_t nFrom = nIn;\n  char *toPtr = (char *)bufOut;\n  size_t nTo = maxOut;\n\n  while (nFrom > 0) {\n    size_t oneway = iconv(cd, &fromPtr, &nFrom, &toPtr, &nTo);\n    if (oneway == (size_t)(-1)) {\n      iconv_close(cd);\n      delete[] bufOut;\n      throw ReaderException(\"error converting characters\");\n    }\n  }\n  iconv_close(cd);\n\n  int nResult = (int)(maxOut - nTo);\n  bufOut[nResult] = '\\0';\n  result.append((const char *)bufOut);\n  delete[] bufOut;\n#else\n  result.append((const char *)bufIn, nIn);\n#endif\n}\n\nvoid DecodedBitStreamParser::decodeHanziSegment(Ref<BitSource> bits_,\n                                                string& result,\n                                                int count) {\n    BitSource& bits (*bits_);\n    // Don't crash trying to read more bits than we have available.\n    if (count * 13 > bits.available()) {\n      throw FormatException();\n    }\n\n    // Each character will require 2 bytes. Read the characters as 2-byte pairs\n    // and decode as GB2312 afterwards\n    size_t nBytes = 2 * count;\n    unsigned char* buffer = new unsigned char[nBytes];\n    int offset = 0;\n    while (count > 0) {\n      // Each 13 bits encodes a 2-byte character\n      int twoBytes = bits.readBits(13);\n      int assembledTwoBytes = ((twoBytes / 0x060) << 8) | (twoBytes % 0x060);\n      if (assembledTwoBytes < 0x003BF) {\n        // In the 0xA1A1 to 0xAAFE range\n        assembledTwoBytes += 0x0A1A1;\n      } else {\n        // In the 0xB0A1 to 0xFAFE range\n        assembledTwoBytes += 0x0A6A1;\n      }\n      buffer[offset] = (unsigned char) ((assembledTwoBytes >> 8) & 0xFF);\n      buffer[offset + 1] = (unsigned char) (assembledTwoBytes & 0xFF);\n      offset += 2;\n      count--;\n    }\n\n    try {\n      append(result, buffer, nBytes, StringUtils::GB2312);\n    } catch (ReaderException const& re) {\n      delete [] buffer;\n      throw FormatException();\n    }\n\n    delete [] buffer;\n  }\n\nvoid DecodedBitStreamParser::decodeKanjiSegment(Ref<BitSource> bits, std::string &result, int count) {\n  // Each character will require 2 bytes. Read the characters as 2-byte pairs\n  // and decode as Shift_JIS afterwards\n  size_t nBytes = 2 * count;\n  unsigned char* buffer = new unsigned char[nBytes];\n  int offset = 0;\n  while (count > 0) {\n    // Each 13 bits encodes a 2-byte character\n\n    int twoBytes = bits->readBits(13);\n    int assembledTwoBytes = ((twoBytes / 0x0C0) << 8) | (twoBytes % 0x0C0);\n    if (assembledTwoBytes < 0x01F00) {\n      // In the 0x8140 to 0x9FFC range\n      assembledTwoBytes += 0x08140;\n    } else {\n      // In the 0xE040 to 0xEBBF range\n      assembledTwoBytes += 0x0C140;\n    }\n    buffer[offset] = (unsigned char)(assembledTwoBytes >> 8);\n    buffer[offset + 1] = (unsigned char)assembledTwoBytes;\n    offset += 2;\n    count--;\n  }\n\n  append(result, buffer, nBytes, StringUtils::SHIFT_JIS);\n  delete[] buffer;\n}\n\nvoid DecodedBitStreamParser::decodeByteSegment(Ref<BitSource> bits_,\n                                               string& result,\n                                               int count,\n                                               CharacterSetECI* currentCharacterSetECI,\n                                               ArrayRef< ArrayRef<unsigned char> >& byteSegments,\n                                               Hashtable const& hints) {\n  int nBytes = count;\n  BitSource& bits (*bits_);\n  // Don't crash trying to read more bits than we have available.\n  if (count << 3 > bits.available()) {\n    throw FormatException();\n  }\n\n  ArrayRef<unsigned char> bytes_ (count);\n  unsigned char* readBytes = &(*bytes_)[0];\n  for (int i = 0; i < count; i++) {\n    readBytes[i] = (unsigned char) bits.readBits(8);\n  }\n  string encoding;\n  if (currentCharacterSetECI == 0) {\n    // The spec isn't clear on this mode; see\n    // section 6.4.5: t does not say which encoding to assuming\n    // upon decoding. I have seen ISO-8859-1 used as well as\n    // Shift_JIS -- without anything like an ECI designator to\n    // give a hint.\n    encoding = StringUtils::guessEncoding(readBytes, count, hints);\n  } else {\n    encoding = currentCharacterSetECI->getEncodingName();\n  }\n  try {\n    append(result, readBytes, nBytes, encoding.c_str());\n  } catch (ReaderException const& re) {\n    throw FormatException();\n  }\n  byteSegments->values().push_back(bytes_);\n}\n\nvoid DecodedBitStreamParser::decodeNumericSegment(Ref<BitSource> bits, std::string &result, int count) {\n  int nBytes = count;\n  unsigned char* bytes = new unsigned char[nBytes];\n  int i = 0;\n  // Read three digits at a time\n  while (count >= 3) {\n    // Each 10 bits encodes three digits\n    if (bits->available() < 10) {\n      throw ReaderException(\"format exception\");\n    }\n    int threeDigitsBits = bits->readBits(10);\n    if (threeDigitsBits >= 1000) {\n      ostringstream s;\n      s << \"Illegal value for 3-digit unit: \" << threeDigitsBits;\n      delete[] bytes;\n      throw ReaderException(s.str().c_str());\n    }\n    bytes[i++] = ALPHANUMERIC_CHARS[threeDigitsBits / 100];\n    bytes[i++] = ALPHANUMERIC_CHARS[(threeDigitsBits / 10) % 10];\n    bytes[i++] = ALPHANUMERIC_CHARS[threeDigitsBits % 10];\n    count -= 3;\n  }\n  if (count == 2) {\n    if (bits->available() < 7) {\n      throw ReaderException(\"format exception\");\n    }\n    // Two digits left over to read, encoded in 7 bits\n    int twoDigitsBits = bits->readBits(7);\n    if (twoDigitsBits >= 100) {\n      ostringstream s;\n      s << \"Illegal value for 2-digit unit: \" << twoDigitsBits;\n      delete[] bytes;\n      throw ReaderException(s.str().c_str());\n    }\n    bytes[i++] = ALPHANUMERIC_CHARS[twoDigitsBits / 10];\n    bytes[i++] = ALPHANUMERIC_CHARS[twoDigitsBits % 10];\n  } else if (count == 1) {\n    if (bits->available() < 4) {\n      throw ReaderException(\"format exception\");\n    }\n    // One digit left over to read\n    int digitBits = bits->readBits(4);\n    if (digitBits >= 10) {\n      ostringstream s;\n      s << \"Illegal value for digit unit: \" << digitBits;\n      delete[] bytes;\n      throw ReaderException(s.str().c_str());\n    }\n    bytes[i++] = ALPHANUMERIC_CHARS[digitBits];\n  }\n  append(result, bytes, nBytes, StringUtils::ASCII);\n  delete[] bytes;\n}\n\nchar DecodedBitStreamParser::toAlphaNumericChar(size_t value) {\n  if (value >= sizeof(DecodedBitStreamParser::ALPHANUMERIC_CHARS)) {\n    throw FormatException();\n  }\n  return ALPHANUMERIC_CHARS[value];\n}\n\nvoid DecodedBitStreamParser::decodeAlphanumericSegment(Ref<BitSource> bits_,\n                                                       string& result,\n                                                       int count,\n                                                       bool fc1InEffect) {\n  BitSource& bits (*bits_);\n  ostringstream bytes;\n  // Read two characters at a time\n  while (count > 1) {\n    int nextTwoCharsBits = bits.readBits(11);\n    bytes << toAlphaNumericChar(nextTwoCharsBits / 45);\n    bytes << toAlphaNumericChar(nextTwoCharsBits % 45);\n    count -= 2;\n  }\n  if (count == 1) {\n    // special case: one character left\n    bytes << toAlphaNumericChar(bits.readBits(6));\n  }\n  // See section 6.4.8.1, 6.4.8.2\n  string s = bytes.str();\n  if (fc1InEffect) {\n    // We need to massage the result a bit if in an FNC1 mode:\n    ostringstream r;\n    for (size_t i = 0; i < s.length(); i++) {\n      if (s[i] != '%') {\n        r << s[i];\n      } else {\n        if (i < s.length() - 1 && s[i + 1] == '%') {\n          // %% is rendered as %\n          r << s[i++];\n        } else {\n          // In alpha mode, % should be converted to FNC1 separator 0x1D\n          r << (char)0x1D;\n        }\n      }\n    }\n    s = r.str();\n  }\n  append(result, s, StringUtils::ASCII);\n}\n\nnamespace {\n  int parseECIValue(BitSource bits) {\n    int firstByte = bits.readBits(8);\n    if ((firstByte & 0x80) == 0) {\n      // just one byte\n      return firstByte & 0x7F;\n    }\n    if ((firstByte & 0xC0) == 0x80) {\n      // two bytes\n      int secondByte = bits.readBits(8);\n      return ((firstByte & 0x3F) << 8) | secondByte;\n    }\n    if ((firstByte & 0xE0) == 0xC0) {\n      // three bytes\n      int secondThirdBytes = bits.readBits(16);\n      return ((firstByte & 0x1F) << 16) | secondThirdBytes;\n    }\n    throw IllegalArgumentException(\"Bad ECI bits starting with byte \");\n  }\n}\n\nRef<DecoderResult>\nDecodedBitStreamParser::decode(ArrayRef<unsigned char> bytes,\n                               Version* version,\n                               ErrorCorrectionLevel const& ecLevel,\n                               Hashtable const& hints) {\n  Ref<BitSource> bits_ (new BitSource(bytes));\n  BitSource& bits (*bits_);\n  string result;\n  CharacterSetECI* currentCharacterSetECI = 0;\n  bool fc1InEffect = false;\n  ArrayRef< ArrayRef<unsigned char> > byteSegments (size_t(0));\n  Mode* mode = 0;\n  do {\n    // While still another segment to read...\n    if (bits.available() < 4) {\n      // OK, assume we're done. Really, a TERMINATOR mode should have been recorded here\n      mode = &Mode::TERMINATOR;\n    } else {\n      try {\n        mode = &Mode::forBits(bits.readBits(4)); // mode is encoded by 4 bits\n      } catch (IllegalArgumentException const& iae) {\n        throw iae;\n        // throw FormatException.getFormatInstance();\n      }\n    }\n    if (mode != &Mode::TERMINATOR) {\n      if ((mode == &Mode::FNC1_FIRST_POSITION) || (mode == &Mode::FNC1_SECOND_POSITION)) {\n        // We do little with FNC1 except alter the parsed result a bit according to the spec\n        fc1InEffect = true;\n      } else if (mode == &Mode::STRUCTURED_APPEND) {\n        // not really supported; all we do is ignore it\n        // Read next 8 bits (symbol sequence #) and 8 bits (parity data), then continue\n        bits.readBits(16);\n      } else if (mode == &Mode::ECI) {\n        // Count doesn't apply to ECI\n        int value = parseECIValue(bits);\n        currentCharacterSetECI = CharacterSetECI::getCharacterSetECIByValue(value);\n        if (currentCharacterSetECI == 0) {\n          throw FormatException();\n        }\n      } else {\n        // First handle Hanzi mode which does not start with character count\n        if (mode == &Mode::HANZI) {\n          //chinese mode contains a sub set indicator right after mode indicator\n          int subset = bits.readBits(4);\n          int countHanzi = bits.readBits(mode->getCharacterCountBits(version));\n          if (subset == GB2312_SUBSET) {\n            decodeHanziSegment(bits_, result, countHanzi);\n          }\n        } else {\n          // \"Normal\" QR code modes:\n          // How many characters will follow, encoded in this mode?\n          int count = bits.readBits(mode->getCharacterCountBits(version));\n          if (mode == &Mode::NUMERIC) {\n            decodeNumericSegment(bits_, result, count);\n          } else if (mode == &Mode::ALPHANUMERIC) {\n            decodeAlphanumericSegment(bits_, result, count, fc1InEffect);\n          } else if (mode == &Mode::BYTE) {\n            decodeByteSegment(bits_, result, count, currentCharacterSetECI, byteSegments, hints);\n          } else if (mode == &Mode::KANJI) {\n            decodeKanjiSegment(bits_, result, count);\n          } else {\n            throw FormatException();\n          }\n        }\n      }\n    }\n  } while (mode != &Mode::TERMINATOR);\n\n  return Ref<DecoderResult>(new DecoderResult(bytes, Ref<String>(new String(result)), byteSegments, (string)ecLevel));\n}\n\n\n// file: zxing/qrcode/decoder/Decoder.cpp\n\n/*\n *  Decoder.cpp\n *  zxing\n *\n *  Created by Christian Brunschen on 20/05/2008.\n *  Copyright 2008 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/qrcode/decoder/Decoder.h>\n// #include <zxing/qrcode/decoder/BitMatrixParser.h>\n// #include <zxing/qrcode/ErrorCorrectionLevel.h>\n// #include <zxing/qrcode/Version.h>\n// #include <zxing/qrcode/decoder/DataBlock.h>\n// #include <zxing/qrcode/decoder/DecodedBitStreamParser.h>\n// #include <zxing/ReaderException.h>\n// #include <zxing/common/reedsolomon/ReedSolomonException.h>\n\nnamespace zxing {\nnamespace qrcode {\n\nusing namespace std;\n\nDecoder::Decoder() :\n    rsDecoder_(GF256::QR_CODE_FIELD) {\n}\n\nvoid Decoder::correctErrors(ArrayRef<unsigned char> codewordBytes, int numDataCodewords) {\n  int numCodewords = (int)codewordBytes->size();\n  ArrayRef<int> codewordInts(numCodewords);\n  for (int i = 0; i < numCodewords; i++) {\n    codewordInts[i] = codewordBytes[i] & 0xff;\n  }\n  int numECCodewords = numCodewords - numDataCodewords;\n\n  try {\n    rsDecoder_.decode(codewordInts, numECCodewords);\n  } catch (ReedSolomonException const& ex) {\n    ReaderException rex(ex.what());\n    throw rex;\n  }\n\n  for (int i = 0; i < numDataCodewords; i++) {\n    codewordBytes[i] = (unsigned char)codewordInts[i];\n  }\n}\n\nRef<DecoderResult> Decoder::decode(Ref<BitMatrix> bits) {\n  // Construct a parser and read version, error-correction level\n  BitMatrixParser parser(bits);\n\n  Version *version = parser.readVersion();\n  ErrorCorrectionLevel &ecLevel = parser.readFormatInformation()->getErrorCorrectionLevel();\n\n\n  // Read codewords\n  ArrayRef<unsigned char> codewords(parser.readCodewords());\n\n\n  // Separate into data blocks\n  std::vector<Ref<DataBlock> > dataBlocks(DataBlock::getDataBlocks(codewords, version, ecLevel));\n\n\n  // Count total number of data bytes\n  int totalBytes = 0;\n  for (size_t i = 0; i < dataBlocks.size(); i++) {\n    totalBytes += dataBlocks[i]->getNumDataCodewords();\n  }\n  ArrayRef<unsigned char> resultBytes(totalBytes);\n  int resultOffset = 0;\n\n\n  // Error-correct and copy data blocks together into a stream of bytes\n  for (size_t j = 0; j < dataBlocks.size(); j++) {\n    Ref<DataBlock> dataBlock(dataBlocks[j]);\n    ArrayRef<unsigned char> codewordBytes = dataBlock->getCodewords();\n    int numDataCodewords = dataBlock->getNumDataCodewords();\n    correctErrors(codewordBytes, numDataCodewords);\n    for (int i = 0; i < numDataCodewords; i++) {\n      resultBytes[resultOffset++] = codewordBytes[i];\n    }\n  }\n\n  return DecodedBitStreamParser::decode(resultBytes,\n                                        version,\n                                        ecLevel,\n                                        DecodedBitStreamParser::Hashtable());\n}\n\n}\n}\n\n// file: zxing/qrcode/decoder/Mode.cpp\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n/*\n *  Mode.cpp\n *  zxing\n *\n *  Created by Christian Brunschen on 19/05/2008.\n *  Copyright 2008 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/qrcode/decoder/Mode.h>\n// #include <zxing/common/Counted.h>\n// #include <zxing/ReaderException.h>\n// #include <zxing/qrcode/Version.h>\n// #include <sstream>\n\nusing zxing::qrcode::Mode;\nusing std::ostringstream;\n\nMode Mode::TERMINATOR(0, 0, 0, 0x00, \"TERMINATOR\");\nMode Mode::NUMERIC(10, 12, 14, 0x01, \"NUMERIC\");\nMode Mode::ALPHANUMERIC(9, 11, 13, 0x02, \"ALPHANUMERIC\");\nMode Mode::STRUCTURED_APPEND(0, 0, 0, 0x03, \"STRUCTURED_APPEND\");\nMode Mode::BYTE(8, 16, 16, 0x04, \"BYTE\");\nMode Mode::ECI(0, 0, 0, 0x07, \"ECI\");\nMode Mode::KANJI(8, 10, 12, 0x08, \"KANJI\");\nMode Mode::FNC1_FIRST_POSITION(0, 0, 0, 0x05, \"FNC1_FIRST_POSITION\");\nMode Mode::FNC1_SECOND_POSITION(0, 0, 0, 0x09, \"FNC1_SECOND_POSITION\");\nMode Mode::HANZI(8, 10, 12, 0x0D, \"HANZI\");\n\nMode::Mode(int cbv0_9, int cbv10_26, int cbv27, int bits, char const* name) :\n    characterCountBitsForVersions0To9_(cbv0_9), characterCountBitsForVersions10To26_(cbv10_26),\n    characterCountBitsForVersions27AndHigher_(cbv27), bits_(bits), name_(name) {\n}\n\nMode& Mode::forBits(int bits) {\n    switch (bits) {\n    case 0x0:\n        return TERMINATOR;\n    case 0x1:\n        return NUMERIC;\n    case 0x2:\n        return ALPHANUMERIC;\n    case 0x3:\n        return STRUCTURED_APPEND;\n    case 0x4:\n        return BYTE;\n    case 0x5:\n        return FNC1_FIRST_POSITION;\n    case 0x7:\n        return ECI;\n    case 0x8:\n        return KANJI;\n    case 0x9:\n        return FNC1_SECOND_POSITION;\n    case 0xD:\n        // 0xD is defined in GBT 18284-2000, may not be supported in foreign country\n        return HANZI;\n    default:\n        ostringstream s;\n        s << \"Illegal mode bits: \" << bits;\n        throw ReaderException(s.str().c_str());\n    }\n}\n\nint Mode::getCharacterCountBits(Version *version) {\n  int number = version->getVersionNumber();\n  if (number <= 9) {\n    return characterCountBitsForVersions0To9_;\n  } else if (number <= 26) {\n    return characterCountBitsForVersions10To26_;\n  } else {\n    return characterCountBitsForVersions27AndHigher_;\n  }\n}\n\n// file: zxing/qrcode/detector/AlignmentPattern.cpp\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n/*\n *  AlignmentPattern.cpp\n *  zxing\n *\n *  Created by Christian Brunschen on 13/05/2008.\n *  Copyright 2008 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/qrcode/detector/AlignmentPattern.h>\n\nnamespace zxing {\nnamespace qrcode {\n\nusing namespace std;\n\nAlignmentPattern::AlignmentPattern(float posX, float posY, float estimatedModuleSize) :\n    ResultPoint(posX,posY), estimatedModuleSize_(estimatedModuleSize) {\n}\n\nbool AlignmentPattern::aboutEquals(float moduleSize, float i, float j) const {\n  if (abs(i - getY()) <= moduleSize && abs(j - getX()) <= moduleSize) {\n    float moduleSizeDiff = abs(moduleSize - estimatedModuleSize_);\n    return moduleSizeDiff <= 1.0f || moduleSizeDiff <= estimatedModuleSize_;\n  }\n  return false;\n}\n\nRef<AlignmentPattern> AlignmentPattern::combineEstimate(float i, float j, float newModuleSize) const {\n  float combinedX = (getX() + j) / 2.0f;\n  float combinedY = (getY() + i) / 2.0f;\n  float combinedModuleSize = (estimatedModuleSize_ + newModuleSize) / 2.0f;\n  Ref<AlignmentPattern> result\n    (new AlignmentPattern(combinedX, combinedY, combinedModuleSize));\n  return result;\n}\n\n}\n}\n\n// file: zxing/qrcode/detector/AlignmentPatternFinder.cpp\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n/*\n *  AlignmentPatternFinder.cpp\n *  zxing\n *\n *  Created by Christian Brunschen on 14/05/2008.\n *  Copyright 2008 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include \"AlignmentPatternFinder.h\"\n// #include <zxing/ReaderException.h>\n// #include <zxing/common/BitArray.h>\n// #include <vector>\n// #include <cmath>\n// #include <cstdlib>\n\nnamespace zxing {\nnamespace qrcode {\n\nusing namespace std;\n\nfloat AlignmentPatternFinder::centerFromEnd(vector<int> &stateCount, int end) {\n  return (float)(end - stateCount[2]) - stateCount[1] / 2.0f;\n}\n\nbool AlignmentPatternFinder::foundPatternCross(vector<int> &stateCount) {\n  float maxVariance = moduleSize_ / 2.0f;\n  for (size_t i = 0; i < 3; i++) {\n    if (abs(moduleSize_ - stateCount[i]) >= maxVariance) {\n      return false;\n    }\n  }\n  return true;\n}\n\nfloat AlignmentPatternFinder::crossCheckVertical(size_t startI, size_t centerJ, int maxCount,\n    int originalStateCountTotal) {\n  int maxI = (int)image_->getHeight();\n  vector<int> stateCount(3, 0);\n\n\n  // Start counting up from center\n  int i = (int)startI;\n  while (i >= 0 && image_->get(centerJ, i) && stateCount[1] <= maxCount) {\n    stateCount[1]++;\n    i--;\n  }\n  // If already too many modules in this state or ran off the edge:\n  if (i < 0 || stateCount[1] > maxCount) {\n    return NAN;\n  }\n  while (i >= 0 && !image_->get(centerJ, i) && stateCount[0] <= maxCount) {\n    stateCount[0]++;\n    i--;\n  }\n  if (stateCount[0] > maxCount) {\n    return NAN;\n  }\n\n  // Now also count down from center\n  i = (int)(startI + 1);\n  while (i < maxI && image_->get(centerJ, i) && stateCount[1] <= maxCount) {\n    stateCount[1]++;\n    i++;\n  }\n  if (i == maxI || stateCount[1] > maxCount) {\n    return NAN;\n  }\n  while (i < maxI && !image_->get(centerJ, i) && stateCount[2] <= maxCount) {\n    stateCount[2]++;\n    i++;\n  }\n  if (stateCount[2] > maxCount) {\n    return NAN;\n  }\n\n  int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2];\n  if (5 * abs(stateCountTotal - originalStateCountTotal) >= 2 * originalStateCountTotal) {\n    return NAN;\n  }\n\n  return foundPatternCross(stateCount) ? centerFromEnd(stateCount, i) : NAN;\n}\n\nRef<AlignmentPattern> AlignmentPatternFinder::handlePossibleCenter(vector<int> &stateCount, size_t i, size_t j) {\n  int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2];\n  float centerJ = centerFromEnd(stateCount, (int)j);\n  float centerI = crossCheckVertical(i, (int)centerJ, 2 * stateCount[1], stateCountTotal);\n  if (!isnan(centerI)) {\n    float estimatedModuleSize = (float)(stateCount[0] + stateCount[1] + stateCount[2]) / 3.0f;\n    int max = (int)possibleCenters_->size();\n    for (int index = 0; index < max; index++) {\n      Ref<AlignmentPattern> center((*possibleCenters_)[index]);\n      // Look for about the same center and module size:\n      if (center->aboutEquals(estimatedModuleSize, centerI, centerJ)) {\n        return center->combineEstimate(centerI, centerJ, estimatedModuleSize);\n      }\n    }\n    AlignmentPattern *tmp = new AlignmentPattern(centerJ, centerI, estimatedModuleSize);\n    // Hadn't found this before; save it\n    tmp->retain();\n    possibleCenters_->push_back(tmp);\n    if (callback_ != 0) {\n      callback_->foundPossibleResultPoint(*tmp);\n    }\n  }\n  Ref<AlignmentPattern> result;\n  return result;\n}\n\nAlignmentPatternFinder::AlignmentPatternFinder(Ref<BitMatrix> image, size_t startX, size_t startY, size_t width,\n                                               size_t height, float moduleSize,\n                                               Ref<ResultPointCallback>const& callback) :\n    image_(image), possibleCenters_(new vector<AlignmentPattern *> ()), startX_(startX), startY_(startY),\n    width_(width), height_(height), moduleSize_(moduleSize), callback_(callback) {\n}\n\nAlignmentPatternFinder::~AlignmentPatternFinder() {\n  for (size_t i = 0; i < possibleCenters_->size(); i++) {\n    (*possibleCenters_)[i]->release();\n    (*possibleCenters_)[i] = 0;\n  }\n  delete possibleCenters_;\n}\n\nRef<AlignmentPattern> AlignmentPatternFinder::find() {\n  size_t maxJ = startX_ + width_;\n  size_t middleI = startY_ + (height_ >> 1);\n  //      Ref<BitArray> luminanceRow(new BitArray(width_));\n  // We are looking for black/white/black modules in 1:1:1 ratio;\n  // this tracks the number of black/white/black modules seen so far\n  vector<int> stateCount(3, 0);\n  for (size_t iGen = 0; iGen < height_; iGen++) {\n    // Search from middle outwards\n    size_t i = middleI + ((iGen & 0x01) == 0 ? ((iGen + 1) >> 1) : -((iGen + 1) >> 1));\n    //        image_->getBlackRow(i, luminanceRow, startX_, width_);\n    stateCount[0] = 0;\n    stateCount[1] = 0;\n    stateCount[2] = 0;\n    size_t j = startX_;\n    // Burn off leading white pixels before anything else; if we start in the middle of\n    // a white run, it doesn't make sense to count its length, since we don't know if the\n    // white run continued to the left of the start point\n    while (j < maxJ && !image_->get(j, i)) {\n      j++;\n    }\n    int currentState = 0;\n    while (j < maxJ) {\n      if (image_->get(j, i)) {\n        // Black pixel\n        if (currentState == 1) { // Counting black pixels\n          stateCount[currentState]++;\n        } else { // Counting white pixels\n          if (currentState == 2) { // A winner?\n            if (foundPatternCross(stateCount)) { // Yes\n              Ref<AlignmentPattern> confirmed(handlePossibleCenter(stateCount, i, j));\n              if (confirmed != 0) {\n                return confirmed;\n              }\n            }\n            stateCount[0] = stateCount[2];\n            stateCount[1] = 1;\n            stateCount[2] = 0;\n            currentState = 1;\n          } else {\n            stateCount[++currentState]++;\n          }\n        }\n      } else { // White pixel\n        if (currentState == 1) { // Counting black pixels\n          currentState++;\n        }\n        stateCount[currentState]++;\n      }\n      j++;\n    }\n    if (foundPatternCross(stateCount)) {\n      Ref<AlignmentPattern> confirmed(handlePossibleCenter(stateCount, i, maxJ));\n      if (confirmed != 0) {\n        return confirmed;\n      }\n    }\n\n  }\n\n  // Hmm, nothing we saw was observed and confirmed twice. If we had\n  // any guess at all, return it.\n  if (possibleCenters_->size() > 0) {\n    Ref<AlignmentPattern> center((*possibleCenters_)[0]);\n    return center;\n  }\n\n  throw zxing::ReaderException(\"Could not find alignment pattern\");\n}\n\n}\n}\n\n// file: zxing/qrcode/detector/Detector.cpp\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n/*\n *  Detector.cpp\n *  zxing\n *\n *  Created by Christian Brunschen on 14/05/2008.\n *  Copyright 2008 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/qrcode/detector/Detector.h>\n// #include <zxing/qrcode/detector/FinderPatternFinder.h>\n// #include <zxing/qrcode/detector/FinderPattern.h>\n// #include <zxing/qrcode/detector/AlignmentPattern.h>\n// #include <zxing/qrcode/detector/AlignmentPatternFinder.h>\n// #include <zxing/qrcode/Version.h>\n// #include <zxing/common/GridSampler.h>\n// #include <zxing/DecodeHints.h>\n// #include <cmath>\n// #include <sstream>\n// #include <cstdlib>\n\nnamespace zxing {\nnamespace qrcode {\n\nusing namespace std;\n\nDetector::Detector(Ref<BitMatrix> image) :\n    image_(image) {\n}\n\nRef<BitMatrix> Detector::getImage() {\n   return image_;\n}\n\nRef<DetectorResult> Detector::detect(DecodeHints const& hints) {\n  callback_ = hints.getResultPointCallback();\n  FinderPatternFinder finder(image_, hints.getResultPointCallback());\n  Ref<FinderPatternInfo> info(finder.find(hints));\n  return processFinderPatternInfo(info);\n}\n\nRef<DetectorResult> Detector::processFinderPatternInfo(Ref<FinderPatternInfo> info){\n  Ref<FinderPattern> topLeft(info->getTopLeft());\n  Ref<FinderPattern> topRight(info->getTopRight());\n  Ref<FinderPattern> bottomLeft(info->getBottomLeft());\n\n  float moduleSize = calculateModuleSize(topLeft, topRight, bottomLeft);\n  if (moduleSize < 1.0f) {\n    throw zxing::ReaderException(\"bad module size\");\n  }\n  int dimension = computeDimension(topLeft, topRight, bottomLeft, moduleSize);\n  Version *provisionalVersion = Version::getProvisionalVersionForDimension(dimension);\n  int modulesBetweenFPCenters = provisionalVersion->getDimensionForVersion() - 7;\n\n  Ref<AlignmentPattern> alignmentPattern;\n  // Anything above version 1 has an alignment pattern\n  if (provisionalVersion->getAlignmentPatternCenters().size() > 0) {\n\n\n    // Guess where a \"bottom right\" finder pattern would have been\n    float bottomRightX = topRight->getX() - topLeft->getX() + bottomLeft->getX();\n    float bottomRightY = topRight->getY() - topLeft->getY() + bottomLeft->getY();\n\n\n    // Estimate that alignment pattern is closer by 3 modules\n    // from \"bottom right\" to known top left location\n    float correctionToTopLeft = 1.0f - 3.0f / (float)modulesBetweenFPCenters;\n    int estAlignmentX = (int)(topLeft->getX() + correctionToTopLeft * (bottomRightX - topLeft->getX()));\n    int estAlignmentY = (int)(topLeft->getY() + correctionToTopLeft * (bottomRightY - topLeft->getY()));\n\n\n    // Kind of arbitrary -- expand search radius before giving up\n    for (int i = 4; i <= 16; i <<= 1) {\n      try {\n        alignmentPattern = findAlignmentInRegion(moduleSize, estAlignmentX, estAlignmentY, (float)i);\n        break;\n      } catch (zxing::ReaderException const& re) {\n        // try next round\n      }\n    }\n    if (alignmentPattern == 0) {\n      // Try anyway\n    }\n\n  }\n\n  Ref<PerspectiveTransform> transform = createTransform(topLeft, topRight, bottomLeft, alignmentPattern, dimension);\n  Ref<BitMatrix> bits(sampleGrid(image_, dimension, transform));\n  std::vector<Ref<ResultPoint> > points(alignmentPattern == 0 ? 3 : 4);\n  points[0].reset(bottomLeft);\n  points[1].reset(topLeft);\n  points[2].reset(topRight);\n  if (alignmentPattern != 0) {\n    points[3].reset(alignmentPattern);\n  }\n\n  Ref<DetectorResult> result(new DetectorResult(bits, points, transform));\n  return result;\n}\n\nRef<PerspectiveTransform> Detector::createTransform(Ref<ResultPoint> topLeft, Ref<ResultPoint> topRight, Ref <\n    ResultPoint > bottomLeft, Ref<ResultPoint> alignmentPattern, int dimension) {\n\n  float dimMinusThree = (float)dimension - 3.5f;\n  float bottomRightX;\n  float bottomRightY;\n  float sourceBottomRightX;\n  float sourceBottomRightY;\n  if (alignmentPattern != 0) {\n    bottomRightX = alignmentPattern->getX();\n    bottomRightY = alignmentPattern->getY();\n    sourceBottomRightX = sourceBottomRightY = dimMinusThree - 3.0f;\n  } else {\n    // Don't have an alignment pattern, just make up the bottom-right point\n    bottomRightX = (topRight->getX() - topLeft->getX()) + bottomLeft->getX();\n    bottomRightY = (topRight->getY() - topLeft->getY()) + bottomLeft->getY();\n    sourceBottomRightX = sourceBottomRightY = dimMinusThree;\n  }\n\n  Ref<PerspectiveTransform> transform(PerspectiveTransform::quadrilateralToQuadrilateral(3.5f, 3.5f, dimMinusThree, 3.5f, sourceBottomRightX,\n                                      sourceBottomRightY, 3.5f, dimMinusThree, topLeft->getX(), topLeft->getY(), topRight->getX(),\n                                      topRight->getY(), bottomRightX, bottomRightY, bottomLeft->getX(), bottomLeft->getY()));\n\n  return transform;\n}\n\nRef<BitMatrix> Detector::sampleGrid(Ref<BitMatrix> image, int dimension, Ref<PerspectiveTransform> transform) {\n  GridSampler &sampler = GridSampler::getInstance();\n  return sampler.sampleGrid(image, dimension, transform);\n}\n\nint Detector::computeDimension(Ref<ResultPoint> topLeft, Ref<ResultPoint> topRight, Ref<ResultPoint> bottomLeft,\n                               float moduleSize) {\n  int tltrCentersDimension = int(FinderPatternFinder::distance(topLeft, topRight) / moduleSize + 0.5f);\n  int tlblCentersDimension = int(FinderPatternFinder::distance(topLeft, bottomLeft) / moduleSize + 0.5f);\n  int dimension = ((tltrCentersDimension + tlblCentersDimension) >> 1) + 7;\n  switch (dimension & 0x03) { // mod 4\n  case 0:\n    dimension++;\n    break;\n    // 1? do nothing\n  case 2:\n    dimension--;\n    break;\n  case 3:\n    ostringstream s;\n    s << \"Bad dimension: \" << dimension;\n    throw zxing::ReaderException(s.str().c_str());\n  }\n  return dimension;\n}\n\nfloat Detector::calculateModuleSize(Ref<ResultPoint> topLeft, Ref<ResultPoint> topRight, Ref<ResultPoint> bottomLeft) {\n  // Take the average\n  return (calculateModuleSizeOneWay(topLeft, topRight) + calculateModuleSizeOneWay(topLeft, bottomLeft)) / 2.0f;\n}\n\nfloat Detector::calculateModuleSizeOneWay(Ref<ResultPoint> pattern, Ref<ResultPoint> otherPattern) {\n  float moduleSizeEst1 = sizeOfBlackWhiteBlackRunBothWays((int)pattern->getX(), (int)pattern->getY(),\n                         (int)otherPattern->getX(), (int)otherPattern->getY());\n  float moduleSizeEst2 = sizeOfBlackWhiteBlackRunBothWays((int)otherPattern->getX(), (int)otherPattern->getY(),\n                         (int)pattern->getX(), (int)pattern->getY());\n  if (isnan(moduleSizeEst1)) {\n    return moduleSizeEst2;\n  }\n  if (isnan(moduleSizeEst2)) {\n    return moduleSizeEst1;\n  }\n  // Average them, and divide by 7 since we've counted the width of 3 black modules,\n  // and 1 white and 1 black module on either side. Ergo, divide sum by 14.\n  return (moduleSizeEst1 + moduleSizeEst2) / 14.0f;\n}\n\nfloat Detector::sizeOfBlackWhiteBlackRunBothWays(int fromX, int fromY, int toX, int toY) {\n\n    float result = sizeOfBlackWhiteBlackRun(fromX, fromY, toX, toY);\n\n    // Now count other way -- don't run off image though of course\n    float scale = 1.0f;\n    int otherToX = fromX - (toX - fromX);\n    if (otherToX < 0) {\n      scale = (float) fromX / (float) (fromX - otherToX);\n      otherToX = 0;\n    } else if (otherToX >= (int)image_->getWidth()) {\n      scale = (float) (image_->getWidth() - 1 - fromX) / (float) (otherToX - fromX);\n      otherToX = (int)(image_->getWidth() - 1);\n    }\n    int otherToY = (int) (fromY - (toY - fromY) * scale);\n\n    scale = 1.0f;\n    if (otherToY < 0) {\n      scale = (float) fromY / (float) (fromY - otherToY);\n      otherToY = 0;\n    } else if (otherToY >= (int)image_->getHeight()) {\n      scale = (float) (image_->getHeight() - 1 - fromY) / (float) (otherToY - fromY);\n      otherToY = (int)(image_->getHeight() - 1);\n    }\n    otherToX = (int) (fromX + (otherToX - fromX) * scale);\n\n    result += sizeOfBlackWhiteBlackRun(fromX, fromY, otherToX, otherToY);\n\n    // Middle pixel is double-counted this way; subtract 1\n    return result - 1.0f;\n}\n\nfloat Detector::sizeOfBlackWhiteBlackRun(int fromX, int fromY, int toX, int toY) {\n    // Mild variant of Bresenham's algorithm;\n    // see http://en.wikipedia.org/wiki/Bresenham's_line_algorithm\n    bool steep = abs(toY - fromY) > abs(toX - fromX);\n    if (steep) {\n      int temp = fromX;\n      fromX = fromY;\n      fromY = temp;\n      temp = toX;\n      toX = toY;\n      toY = temp;\n    }\n\n    int dx = abs(toX - fromX);\n    int dy = abs(toY - fromY);\n    int error = -dx >> 1;\n    int xstep = fromX < toX ? 1 : -1;\n    int ystep = fromY < toY ? 1 : -1;\n\n    // In black pixels, looking for white, first or second time.\n    int state = 0;\n    // Loop up until x == toX, but not beyond\n    int xLimit = toX + xstep;\n    for (int x = fromX, y = fromY; x != xLimit; x += xstep) {\n      int realX = steep ? y : x;\n      int realY = steep ? x : y;\n\n      // Does current pixel mean we have moved white to black or vice versa?\n      if (!((state == 1) ^ image_->get(realX, realY))) {\n        if (state == 2) {\n          int diffX = x - fromX;\n          int diffY = y - fromY;\n          return (float) sqrt((double) (diffX * diffX + diffY * diffY));\n        }\n        state++;\n      }\n\n      error += dy;\n      if (error > 0) {\n        if (y == toY) {\n          break;\n        }\n        y += ystep;\n        error -= dx;\n      }\n    }\n    // Found black-white-black; give the benefit of the doubt that the next pixel outside the image\n    // is \"white\" so this last point at (toX+xStep,toY) is the right ending. This is really a\n    // small approximation; (toX+xStep,toY+yStep) might be really correct. Ignore this.\n    if (state == 2) {\n      int diffX = toX + xstep - fromX;\n      int diffY = toY - fromY;\n      return (float) sqrt((double) (diffX * diffX + diffY * diffY));\n    }\n    // else we didn't find even black-white-black; no estimate is really possible\n    return NAN;\n}\n\nRef<AlignmentPattern> Detector::findAlignmentInRegion(float overallEstModuleSize, int estAlignmentX, int estAlignmentY,\n    float allowanceFactor) {\n  // Look for an alignment pattern (3 modules in size) around where it\n  // should be\n  int allowance = (int)(allowanceFactor * overallEstModuleSize);\n  int alignmentAreaLeftX = max(0, estAlignmentX - allowance);\n  int alignmentAreaRightX = min((int)(image_->getWidth() - 1), estAlignmentX + allowance);\n  if (alignmentAreaRightX - alignmentAreaLeftX < overallEstModuleSize * 3) {\n      throw zxing::ReaderException(\"region too small to hold alignment pattern\");\n  }\n  int alignmentAreaTopY = max(0, estAlignmentY - allowance);\n  int alignmentAreaBottomY = min((int)(image_->getHeight() - 1), estAlignmentY + allowance);\n  if (alignmentAreaBottomY - alignmentAreaTopY < overallEstModuleSize * 3) {\n      throw zxing::ReaderException(\"region too small to hold alignment pattern\");\n  }\n\n  AlignmentPatternFinder alignmentFinder(image_, alignmentAreaLeftX, alignmentAreaTopY, alignmentAreaRightX\n                                         - alignmentAreaLeftX, alignmentAreaBottomY - alignmentAreaTopY, overallEstModuleSize, callback_);\n  return alignmentFinder.find();\n}\n\n}\n}\n\n// file: zxing/qrcode/detector/FinderPattern.cpp\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n/*\n *  FinderPattern.cpp\n *  zxing\n *\n *  Created by Christian Brunschen on 13/05/2008.\n *  Copyright 2008 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/qrcode/detector/FinderPattern.h>\n\nnamespace zxing {\n\tnamespace qrcode {\n\n\t\tusing namespace std;\n\n\t\tFinderPattern::FinderPattern(float posX, float posY, float estimatedModuleSize) :\n\t\tResultPoint(posX,posY), estimatedModuleSize_(estimatedModuleSize), count_(1) {\n\t\t}\n\n\t\tFinderPattern::FinderPattern(float posX, float posY, float estimatedModuleSize, int count) :\n\t\tResultPoint(posX,posY), estimatedModuleSize_(estimatedModuleSize), count_(count) {\n\t\t}\n\n\t\tint FinderPattern::getCount() const {\n\t\t\treturn count_;\n\t\t}\n\n\t\tfloat FinderPattern::getEstimatedModuleSize() const {\n\t\t\treturn estimatedModuleSize_;\n\t\t}\n\n\t\tvoid FinderPattern::incrementCount() {\n\t\t\tcount_++;\n\t\t}\n\n/*\n\t\tbool FinderPattern::aboutEquals(float moduleSize, float i, float j) const {\n\t\t\treturn abs(i - posY_) <= moduleSize && abs(j - posX_) <= moduleSize && (abs(moduleSize - estimatedModuleSize_)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<= 1.0f || abs(moduleSize - estimatedModuleSize_) / estimatedModuleSize_ <= 0.1f);\n\t\t}\n*/\n    bool FinderPattern::aboutEquals(float moduleSize, float i, float j) const {\n      if (abs(i - getY()) <= moduleSize && abs(j - getX()) <= moduleSize) {\n        float moduleSizeDiff = abs(moduleSize - estimatedModuleSize_);\n        return moduleSizeDiff <= 1.0f || moduleSizeDiff <= estimatedModuleSize_;\n      }\n      return false;\n    }\n\n    Ref<FinderPattern> FinderPattern::combineEstimate(float i, float j, float newModuleSize) const {\n      int combinedCount = count_ + 1;\n      float combinedX = (count_ * getX() + j) / combinedCount;\n      float combinedY = (count_ * getY() + i) / combinedCount;\n      float combinedModuleSize = (count_ * getEstimatedModuleSize() + newModuleSize) / combinedCount;\n      return Ref<FinderPattern>(new FinderPattern(combinedX, combinedY, combinedModuleSize, combinedCount));\n    }\n\t}\n}\n\n// file: zxing/qrcode/detector/FinderPatternFinder.cpp\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n/*\n *  FinderPatternFinder.cpp\n *  zxing\n *\n *  Created by Christian Brunschen on 13/05/2008.\n *  Copyright 2008 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/qrcode/detector/FinderPatternFinder.h>\n// #include <zxing/ReaderException.h>\n// #include <zxing/DecodeHints.h>\n// #include <vector>\n// #include <cmath>\n// #include <cstdlib>\n// #include <algorithm>\n\nnamespace zxing {\nnamespace qrcode {\n\nusing namespace std;\n\nclass FurthestFromAverageComparator {\nprivate:\n  const float averageModuleSize_;\npublic:\n  FurthestFromAverageComparator(float averageModuleSize) :\n    averageModuleSize_(averageModuleSize) {\n  }\n  bool operator()(Ref<FinderPattern> a, Ref<FinderPattern> b) {\n    float dA = abs(a->getEstimatedModuleSize() - averageModuleSize_);\n    float dB = abs(b->getEstimatedModuleSize() - averageModuleSize_);\n    return dA > dB;\n  }\n};\n\nclass CenterComparator {\n  const float averageModuleSize_;\npublic:\n  CenterComparator(float averageModuleSize) :\n    averageModuleSize_(averageModuleSize) {\n  }\n  bool operator()(Ref<FinderPattern> a, Ref<FinderPattern> b) {\n    // N.B.: we want the result in descending order ...\n    if (a->getCount() != b->getCount()) {\n      return a->getCount() > b->getCount();\n    } else {\n      float dA = abs(a->getEstimatedModuleSize() - averageModuleSize_);\n      float dB = abs(b->getEstimatedModuleSize() - averageModuleSize_);\n      return dA < dB;\n    }\n  }\n};\n\nint FinderPatternFinder::CENTER_QUORUM = 2;\nint FinderPatternFinder::MIN_SKIP = 3;\nint FinderPatternFinder::MAX_MODULES = 57;\n\nfloat FinderPatternFinder::centerFromEnd(int* stateCount, int end) {\n  return (float)(end - stateCount[4] - stateCount[3]) - stateCount[2] / 2.0f;\n}\n\nbool FinderPatternFinder::foundPatternCross(int* stateCount) {\n  int totalModuleSize = 0;\n  for (int i = 0; i < 5; i++) {\n    if (stateCount[i] == 0) {\n      return false;\n    }\n    totalModuleSize += stateCount[i];\n  }\n  if (totalModuleSize < 7) {\n    return false;\n  }\n  float moduleSize = (float)totalModuleSize / 7.0f;\n  float maxVariance = moduleSize / 2.0f;\n  // Allow less than 50% variance from 1-1-3-1-1 proportions\n  return abs(moduleSize - stateCount[0]) < maxVariance && abs(moduleSize - stateCount[1]) < maxVariance && abs(3.0f\n         * moduleSize - stateCount[2]) < 3.0f * maxVariance && abs(moduleSize - stateCount[3]) < maxVariance && abs(\n           moduleSize - stateCount[4]) < maxVariance;\n}\n\nfloat FinderPatternFinder::crossCheckVertical(size_t startI, size_t centerJ, int maxCount, int originalStateCountTotal) {\n\n  int maxI = (int)image_->getHeight();\n  int stateCount[5];\n  for (int i = 0; i < 5; i++)\n    stateCount[i] = 0;\n\n\n  // Start counting up from center\n  int i = (int)startI;\n  while (i >= 0 && image_->get(centerJ, i)) {\n    stateCount[2]++;\n    i--;\n  }\n  if (i < 0) {\n    return NAN;\n  }\n  while (i >= 0 && !image_->get(centerJ, i) && stateCount[1] <= maxCount) {\n    stateCount[1]++;\n    i--;\n  }\n  // If already too many modules in this state or ran off the edge:\n  if (i < 0 || stateCount[1] > maxCount) {\n    return NAN;\n  }\n  while (i >= 0 && image_->get(centerJ, i) && stateCount[0] <= maxCount) {\n    stateCount[0]++;\n    i--;\n  }\n  if (stateCount[0] > maxCount) {\n    return NAN;\n  }\n\n  // Now also count down from center\n  i = (int)(startI + 1);\n  while (i < maxI && image_->get(centerJ, i)) {\n    stateCount[2]++;\n    i++;\n  }\n  if (i == maxI) {\n    return NAN;\n  }\n  while (i < maxI && !image_->get(centerJ, i) && stateCount[3] < maxCount) {\n    stateCount[3]++;\n    i++;\n  }\n  if (i == maxI || stateCount[3] >= maxCount) {\n    return NAN;\n  }\n  while (i < maxI && image_->get(centerJ, i) && stateCount[4] < maxCount) {\n    stateCount[4]++;\n    i++;\n  }\n  if (stateCount[4] >= maxCount) {\n    return NAN;\n  }\n\n  // If we found a finder-pattern-like section, but its size is more than 40% different than\n  // the original, assume it's a false positive\n  int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] + stateCount[4];\n  if (5 * abs(stateCountTotal - originalStateCountTotal) >= 2 * originalStateCountTotal) {\n    return NAN;\n  }\n\n  return foundPatternCross(stateCount) ? centerFromEnd(stateCount, i) : NAN;\n}\n\nfloat FinderPatternFinder::crossCheckHorizontal(size_t startJ, size_t centerI, int maxCount,\n    int originalStateCountTotal) {\n\n  int maxJ = (int)image_->getWidth();\n  int stateCount[5];\n  for (int i = 0; i < 5; i++)\n    stateCount[i] = 0;\n\n  int j = (int)startJ;\n  while (j >= 0 && image_->get(j, centerI)) {\n    stateCount[2]++;\n    j--;\n  }\n  if (j < 0) {\n    return NAN;\n  }\n  while (j >= 0 && !image_->get(j, centerI) && stateCount[1] <= maxCount) {\n    stateCount[1]++;\n    j--;\n  }\n  if (j < 0 || stateCount[1] > maxCount) {\n    return NAN;\n  }\n  while (j >= 0 && image_->get(j, centerI) && stateCount[0] <= maxCount) {\n    stateCount[0]++;\n    j--;\n  }\n  if (stateCount[0] > maxCount) {\n    return NAN;\n  }\n\n  j = (int)(startJ + 1);\n  while (j < maxJ && image_->get(j, centerI)) {\n    stateCount[2]++;\n    j++;\n  }\n  if (j == maxJ) {\n    return NAN;\n  }\n  while (j < maxJ && !image_->get(j, centerI) && stateCount[3] < maxCount) {\n    stateCount[3]++;\n    j++;\n  }\n  if (j == maxJ || stateCount[3] >= maxCount) {\n    return NAN;\n  }\n  while (j < maxJ && image_->get(j, centerI) && stateCount[4] < maxCount) {\n    stateCount[4]++;\n    j++;\n  }\n  if (stateCount[4] >= maxCount) {\n    return NAN;\n  }\n\n  // If we found a finder-pattern-like section, but its size is significantly different than\n  // the original, assume it's a false positive\n  int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] + stateCount[4];\n  if (5 * abs(stateCountTotal - originalStateCountTotal) >= originalStateCountTotal) {\n    return NAN;\n  }\n\n  return foundPatternCross(stateCount) ? centerFromEnd(stateCount, j) : NAN;\n}\n\nbool FinderPatternFinder::handlePossibleCenter(int* stateCount, size_t i, size_t j) {\n  int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] + stateCount[4];\n  float centerJ = centerFromEnd(stateCount, (int)j);\n  float centerI = crossCheckVertical(i, (size_t)centerJ, stateCount[2], stateCountTotal);\n  if (!isnan(centerI)) {\n    // Re-cross check\n    centerJ = crossCheckHorizontal((size_t)centerJ, (size_t)centerI, stateCount[2], stateCountTotal);\n    if (!isnan(centerJ)) {\n      float estimatedModuleSize = (float)stateCountTotal / 7.0f;\n      bool found = false;\n      size_t max = possibleCenters_.size();\n      for (size_t index = 0; index < max; index++) {\n        Ref<FinderPattern> center = possibleCenters_[index];\n        // Look for about the same center and module size:\n        if (center->aboutEquals(estimatedModuleSize, centerI, centerJ)) {\n          possibleCenters_[index] = center->combineEstimate(centerI, centerJ, estimatedModuleSize);\n          found = true;\n          break;\n        }\n      }\n      if (!found) {\n        Ref<FinderPattern> newPattern(new FinderPattern(centerJ, centerI, estimatedModuleSize));\n        possibleCenters_.push_back(newPattern);\n        if (callback_ != 0) {\n          callback_->foundPossibleResultPoint(*newPattern);\n        }\n      }\n      return true;\n    }\n  }\n  return false;\n}\n\nint FinderPatternFinder::findRowSkip() {\n  size_t max = possibleCenters_.size();\n  if (max <= 1) {\n    return 0;\n  }\n  Ref<FinderPattern> firstConfirmedCenter;\n  for (size_t i = 0; i < max; i++) {\n    Ref<FinderPattern> center = possibleCenters_[i];\n    if (center->getCount() >= CENTER_QUORUM) {\n      if (firstConfirmedCenter == 0) {\n        firstConfirmedCenter = center;\n      } else {\n        // We have two confirmed centers\n        // How far down can we skip before resuming looking for the next\n        // pattern? In the worst case, only the difference between the\n        // difference in the x / y coordinates of the two centers.\n        // This is the case where you find top left first. Draw it out.\n        hasSkipped_ = true;\n        return (int)(abs(firstConfirmedCenter->getX() - center->getX()) - abs(firstConfirmedCenter->getY()\n                     - center->getY()))/2;\n      }\n    }\n  }\n  return 0;\n}\n\nbool FinderPatternFinder::haveMultiplyConfirmedCenters() {\n  int confirmedCount = 0;\n  float totalModuleSize = 0.0f;\n  size_t max = possibleCenters_.size();\n  for (size_t i = 0; i < max; i++) {\n    Ref<FinderPattern> pattern = possibleCenters_[i];\n    if (pattern->getCount() >= CENTER_QUORUM) {\n      confirmedCount++;\n      totalModuleSize += pattern->getEstimatedModuleSize();\n    }\n  }\n  if (confirmedCount < 3) {\n    return false;\n  }\n  // OK, we have at least 3 confirmed centers, but, it's possible that one is a \"false positive\"\n  // and that we need to keep looking. We detect this by asking if the estimated module sizes\n  // vary too much. We arbitrarily say that when the total deviation from average exceeds\n  // 5% of the total module size estimates, it's too much.\n  float average = totalModuleSize / max;\n  float totalDeviation = 0.0f;\n  for (size_t i = 0; i < max; i++) {\n    Ref<FinderPattern> pattern = possibleCenters_[i];\n    totalDeviation += abs(pattern->getEstimatedModuleSize() - average);\n  }\n  return totalDeviation <= 0.05f * totalModuleSize;\n}\n\nvector<Ref<FinderPattern> > FinderPatternFinder::selectBestPatterns() {\n  size_t startSize = possibleCenters_.size();\n\n  if (startSize < 3) {\n    // Couldn't find enough finder patterns\n    throw zxing::ReaderException(\"Could not find three finder patterns\");\n  }\n\n  // Filter outlier possibilities whose module size is too different\n  if (startSize > 3) {\n    // But we can only afford to do so if we have at least 4 possibilities to choose from\n    float totalModuleSize = 0.0f;\n    float square = 0.0f;\n    for (size_t i = 0; i < startSize; i++) {\n      float size = possibleCenters_[i]->getEstimatedModuleSize();\n      totalModuleSize += size;\n      square += size * size;\n    }\n    float average = totalModuleSize / (float) startSize;\n    float stdDev = (float)sqrt(square / startSize - average * average);\n\n    sort(possibleCenters_.begin(), possibleCenters_.end(), FurthestFromAverageComparator(average));\n\n    float limit = max(0.2f * average, stdDev);\n\n    for (size_t i = 0; i < possibleCenters_.size() && possibleCenters_.size() > 3; i++) {\n      if (abs(possibleCenters_[i]->getEstimatedModuleSize() - average) > limit) {\n        possibleCenters_.erase(possibleCenters_.begin()+i);\n        i--;\n      }\n    }\n  }\n\n  if (possibleCenters_.size() > 3) {\n    // Throw away all but those first size candidate points we found.\n    float totalModuleSize = 0.0f;\n    for (size_t i = 0; i < possibleCenters_.size(); i++) {\n      float size = possibleCenters_[i]->getEstimatedModuleSize();\n      totalModuleSize += size;\n    }\n    float average = totalModuleSize / (float) possibleCenters_.size();\n    sort(possibleCenters_.begin(), possibleCenters_.end(), CenterComparator(average));\n  }\n\n  if (possibleCenters_.size() > 3) {\n    possibleCenters_.erase(possibleCenters_.begin()+3,possibleCenters_.end());\n  }\n\n  vector<Ref<FinderPattern> > result(3);\n  result[0] = possibleCenters_[0];\n  result[1] = possibleCenters_[1];\n  result[2] = possibleCenters_[2];\n  return result;\n}\n\nvector<Ref<FinderPattern> > FinderPatternFinder::orderBestPatterns(vector<Ref<FinderPattern> > patterns) {\n  // Find distances between pattern centers\n  float abDistance = distance(patterns[0], patterns[1]);\n  float bcDistance = distance(patterns[1], patterns[2]);\n  float acDistance = distance(patterns[0], patterns[2]);\n\n  Ref<FinderPattern> topLeft;\n  Ref<FinderPattern> topRight;\n  Ref<FinderPattern> bottomLeft;\n  // Assume one closest to other two is top left;\n  // topRight and bottomLeft will just be guesses below at first\n  if (bcDistance >= abDistance && bcDistance >= acDistance) {\n    topLeft = patterns[0];\n    topRight = patterns[1];\n    bottomLeft = patterns[2];\n  } else if (acDistance >= bcDistance && acDistance >= abDistance) {\n    topLeft = patterns[1];\n    topRight = patterns[0];\n    bottomLeft = patterns[2];\n  } else {\n    topLeft = patterns[2];\n    topRight = patterns[0];\n    bottomLeft = patterns[1];\n  }\n\n  // Use cross product to figure out which of other1/2 is the bottom left\n  // pattern. The vector \"top-left -> bottom-left\" x \"top-left -> top-right\"\n  // should yield a vector with positive z component\n  if ((bottomLeft->getY() - topLeft->getY()) * (topRight->getX() - topLeft->getX()) < (bottomLeft->getX()\n      - topLeft->getX()) * (topRight->getY() - topLeft->getY())) {\n    Ref<FinderPattern> temp = topRight;\n    topRight = bottomLeft;\n    bottomLeft = temp;\n  }\n\n  vector<Ref<FinderPattern> > results(3);\n  results[0] = bottomLeft;\n  results[1] = topLeft;\n  results[2] = topRight;\n  return results;\n}\n\nfloat FinderPatternFinder::distance(Ref<ResultPoint> p1, Ref<ResultPoint> p2) {\n  float dx = p1->getX() - p2->getX();\n  float dy = p1->getY() - p2->getY();\n  return (float)sqrt(dx * dx + dy * dy);\n}\n\nFinderPatternFinder::FinderPatternFinder(Ref<BitMatrix> image,\n                                           Ref<ResultPointCallback>const& callback) :\n    image_(image), possibleCenters_(), hasSkipped_(false), callback_(callback) {\n}\n\nRef<FinderPatternInfo> FinderPatternFinder::find(DecodeHints const& hints) {\n  bool tryHarder = hints.getTryHarder();\n\n  size_t maxI = image_->getHeight();\n  size_t maxJ = image_->getWidth();\n\n\n  // We are looking for black/white/black/white/black modules in\n  // 1:1:3:1:1 ratio; this tracks the number of such modules seen so far\n\n  // As this is used often, we use an integer array instead of vector\n  int stateCount[5];\n  bool done = false;\n\n\n  // Let's assume that the maximum version QR Code we support takes up 1/4\n  // the height of the image, and then account for the center being 3\n  // modules in size. This gives the smallest number of pixels the center\n  // could be, so skip this often. When trying harder, look for all\n  // QR versions regardless of how dense they are.\n  int iSkip = (int)((3 * maxI) / (4 * MAX_MODULES));\n  if (iSkip < MIN_SKIP || tryHarder) {\n      iSkip = MIN_SKIP;\n  }\n\n  // This is slightly faster than using the Ref. Efficiency is important here\n  BitMatrix& matrix = *image_;\n\n  for (size_t i = iSkip - 1; i < maxI && !done; i += iSkip) {\n    // Get a row of black/white values\n\n    stateCount[0] = 0;\n    stateCount[1] = 0;\n    stateCount[2] = 0;\n    stateCount[3] = 0;\n    stateCount[4] = 0;\n    int currentState = 0;\n    for (size_t j = 0; j < maxJ; j++) {\n      if (matrix.get(j, i)) {\n        // Black pixel\n        if ((currentState & 1) == 1) { // Counting white pixels\n          currentState++;\n        }\n        stateCount[currentState]++;\n      } else { // White pixel\n        if ((currentState & 1) == 0) { // Counting black pixels\n          if (currentState == 4) { // A winner?\n            if (foundPatternCross(stateCount)) { // Yes\n              bool confirmed = handlePossibleCenter(stateCount, i, j);\n              if (confirmed) {\n                // Start examining every other line. Checking each line turned out to be too\n                // expensive and didn't improve performance.\n                iSkip = 2;\n                if (hasSkipped_) {\n                  done = haveMultiplyConfirmedCenters();\n                } else {\n                  int rowSkip = findRowSkip();\n                  if (rowSkip > stateCount[2]) {\n                    // Skip rows between row of lower confirmed center\n                    // and top of presumed third confirmed center\n                    // but back up a bit to get a full chance of detecting\n                    // it, entire width of center of finder pattern\n\n                    // Skip by rowSkip, but back off by stateCount[2] (size\n                    // of last center of pattern we saw) to be conservative,\n                    // and also back off by iSkip which is about to be\n                    // re-added\n                    i += rowSkip - stateCount[2] - iSkip;\n                    j = maxJ - 1;\n                  }\n                }\n              } else {\n                stateCount[0] = stateCount[2];\n                stateCount[1] = stateCount[3];\n                stateCount[2] = stateCount[4];\n                stateCount[3] = 1;\n                stateCount[4] = 0;\n                currentState = 3;\n                continue;\n              }\n              // Clear state to start looking again\n              currentState = 0;\n              stateCount[0] = 0;\n              stateCount[1] = 0;\n              stateCount[2] = 0;\n              stateCount[3] = 0;\n              stateCount[4] = 0;\n            } else { // No, shift counts back by two\n              stateCount[0] = stateCount[2];\n              stateCount[1] = stateCount[3];\n              stateCount[2] = stateCount[4];\n              stateCount[3] = 1;\n              stateCount[4] = 0;\n              currentState = 3;\n            }\n          } else {\n            stateCount[++currentState]++;\n          }\n        } else { // Counting white pixels\n          stateCount[currentState]++;\n        }\n      }\n    }\n    if (foundPatternCross(stateCount)) {\n      bool confirmed = handlePossibleCenter(stateCount, i, maxJ);\n      if (confirmed) {\n        iSkip = stateCount[0];\n        if (hasSkipped_) {\n          // Found a third one\n          done = haveMultiplyConfirmedCenters();\n        }\n      }\n    }\n  }\n\n  vector<Ref<FinderPattern> > patternInfo = selectBestPatterns();\n  patternInfo = orderBestPatterns(patternInfo);\n\n  Ref<FinderPatternInfo> result(new FinderPatternInfo(patternInfo));\n  return result;\n}\n}\n}\n\n// file: zxing/qrcode/detector/FinderPatternInfo.cpp\n\n/*\n *  FinderPatternInfo.cpp\n *  zxing\n *\n *  Created by Christian Brunschen on 13/05/2008.\n *  Copyright 2008 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/qrcode/detector/FinderPatternInfo.h>\n\nnamespace zxing {\nnamespace qrcode {\n\nFinderPatternInfo::FinderPatternInfo(std::vector<Ref<FinderPattern> > patternCenters) :\n    bottomLeft_(patternCenters[0]), topLeft_(patternCenters[1]), topRight_(patternCenters[2]) {\n}\n\nRef<FinderPattern> FinderPatternInfo::getBottomLeft() {\n  return bottomLeft_;\n}\nRef<FinderPattern> FinderPatternInfo::getTopLeft() {\n  return topLeft_;\n}\nRef<FinderPattern> FinderPatternInfo::getTopRight() {\n  return topRight_;\n}\n\n}\n}\n\n// file: zxing/qrcode/detector/QREdgeDetector.cpp\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n/*\n *  Created by Ralf Kistner on 7/12/2009.\n *  Copyright 2008 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/qrcode/detector/QREdgeDetector.h>\n// #include <zxing/common/EdgeDetector.h>\n// #include <cstdlib>\n\nusing namespace std;\n\nnamespace zxing {\nnamespace qrcode {\n\nstatic const float patternEdgeThreshold = 2;\nstatic const int patternEdgeWidth = 3;\nstatic const float patternEdgeSearchRatio = 1.1;\nstatic const int patternEdgeSkip = 2;\n\nstatic const float accurateEdgeThreshold = 3.3;\nstatic const int accurateEdgeWidth = 7;\nstatic const int accurateEdgeSkip = 2;\n\nstatic Point guessLastPattern(Point topLeft, Point topRight, Point bottomLeft) {\n  return Point(topRight.x - topLeft.x + bottomLeft.x, topRight.y - topLeft.y + bottomLeft.y);\n}\n\nstatic Point rp(Ref<ResultPoint> rp) {\n  return Point(rp->getX(), rp->getY());\n}\n\nQREdgeDetector::QREdgeDetector(Ref<BitMatrix> image) : Detector(image) { }\n\nRef<PerspectiveTransform> QREdgeDetector::createTransform(Ref<ResultPoint> topLeft, Ref<ResultPoint> topRight, Ref <\n      ResultPoint > bottomLeft, Ref<ResultPoint> alignmentPattern, int dimension) {\n\n  if(alignmentPattern == NULL) {\n    Point corner = findCorner(*Detector::getImage(), rp(topLeft), rp(topRight), rp(bottomLeft), dimension);\n    return get1CornerTransform(rp(topLeft), rp(topRight), rp(bottomLeft), corner, dimension);\n  } else {\n    return Detector::createTransform(topLeft, topRight, bottomLeft, alignmentPattern, dimension);\n  }\n}\n\n\n\n\nPoint QREdgeDetector::findCorner(const BitMatrix& image, Point topLeft, Point topRight, Point bottomLeft, int dimension) {\n  (void)dimension;\n  Point bottomRight = guessLastPattern(topLeft, topRight, bottomLeft);\n\n  Line bottomEst = findPatternEdge(image, bottomLeft, topLeft, bottomRight, false);\n  Line rightEst = findPatternEdge(image, topRight, topLeft, bottomRight, true);\n\n  //return EdgeDetector::intersection(bottomEst, rightEst);\n\n  Line bottom = EdgeDetector::findLine(image, bottomEst, false, accurateEdgeWidth, accurateEdgeThreshold, accurateEdgeSkip);\n  Line right = EdgeDetector::findLine(image, rightEst, true, accurateEdgeWidth, accurateEdgeThreshold, accurateEdgeSkip);\n\n\n  return EdgeDetector::intersection(bottom, right);\n}\n\nLine QREdgeDetector::findPatternEdge(const BitMatrix& image, Point pattern, Point opposite, Point direction, bool invert) {\n  Point start = endOfReverseBlackWhiteBlackRun(image, pattern, opposite);\n\n  float dx = pattern.x - start.x;\n  float dy = pattern.y - start.y;\n  float dist = sqrt(dx*dx + dy*dy);\n\n  float dirX = direction.x - pattern.x;\n  float dirY = direction.y - pattern.y;\n  float dirSize = sqrt(dirX*dirX + dirY*dirY);\n\n  float nx = dirX/dirSize;\n  float ny = dirY/dirSize;\n\n  float search = dist * patternEdgeSearchRatio;\n  Point a(start.x + nx*search, start.y + ny*search);\n  Point b(start.x - nx*search, start.y - ny*search);\n\n  return EdgeDetector::findLine(image, Line(a, b), invert, patternEdgeWidth, patternEdgeThreshold, patternEdgeSkip);\n}\n\n\nRef<PerspectiveTransform> QREdgeDetector::get1CornerTransform(Point topLeft, Point topRight, Point bottomLeft, Point corner, int dimension) {\n  float dimMinusThree = (float) dimension - 3.5f;\n\n  Ref<PerspectiveTransform> transform(PerspectiveTransform::quadrilateralToQuadrilateral(3.5f, 3.5f, dimMinusThree, 3.5f, dimension,\n                                      dimension, 3.5f, dimMinusThree, topLeft.x, topLeft.y, topRight.x,\n                                      topRight.y, corner.x, corner.y, bottomLeft.x, bottomLeft.y));\n\n  return transform;\n}\n\n// Adapted from \"sizeOfBlackWhiteBlackRun\" in zxing::qrcode::Detector\nPoint QREdgeDetector::endOfReverseBlackWhiteBlackRun(const BitMatrix& image, Point from, Point to) {\n  int fromX = (int)from.x;\n  int fromY = (int)from.y;\n  int toX = (int)to.x;\n  int toY = (int)to.y;\n\n  bool steep = abs(toY - fromY) > abs(toX - fromX);\n  if (steep) {\n    int temp = fromX;\n    fromX = fromY;\n    fromY = temp;\n    temp = toX;\n    toX = toY;\n    toY = temp;\n  }\n\n  int dx = abs(toX - fromX);\n  int dy = abs(toY - fromY);\n  int error = -dx >> 1;\n  int ystep = fromY < toY ? -1 : 1;\n  int xstep = fromX < toX ? -1 : 1;\n  int state = 0; // In black pixels, looking for white, first or second time\n\n  // In case there are no points, prepopulate to from\n  int realX = fromX;\n  int realY = fromY;\n  for (int x = fromX, y = fromY; x != toX; x += xstep) {\n    realX = steep ? y : x;\n    realY = steep ? x : y;\n\n    if(realX < 0 || realY < 0 || realX >= (int)image.getWidth() || realY >= (int)image.getHeight())\n      break;\n\n    if (state == 1) { // In white pixels, looking for black\n      if (image.get(realX, realY)) {\n        state++;\n      }\n    } else {\n      if (!image.get(realX, realY)) {\n        state++;\n      }\n    }\n\n    if (state == 3) { // Found black, white, black, and stumbled back onto white; done\n      return Point(realX, realY);\n    }\n    error += dy;\n    if (error > 0) {\n      y += ystep;\n      error -= dx;\n    }\n  }\n\n  // B-W-B run not found, return the last point visited.\n  return Point(realX, realY);\n}\n\n} // namespace qrcode\n} // namespace zxing\n\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/ios/zxing-all-in-one.h",
    "content": "#include <map>\n#include <exception>\n#include <algorithm>\n#include <typeinfo>\n#include <string>\n#include <limits>\n#include <limits.h>\n#include <sstream>\n#include <cstdarg>\n#include <math.h>\n#include <vector>\n#include <cmath>\n#include <string.h>\n#include <memory>\n#include <cstdlib>\n#include <iostream>\n#include <stdlib.h>\n#include <iconv.h>\n\n// file: zxing/Exception.h\n\n#ifndef __EXCEPTION_H__\n// #define __EXCEPTION_H__\n\n/*\n *  Exception.h\n *  ZXing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <string>\n// #include <exception>\n\nnamespace zxing {\n\nclass Exception : public std::exception {\nprivate:\n  std::string message;\n\npublic:\n  Exception();\n  Exception(const char *msg);\n  virtual const char* what() const throw();\n  virtual ~Exception() throw();\n};\n\n}\n#endif // __EXCEPTION_H__\n\n// file: zxing/common/IllegalArgumentException.h\n\n#ifndef __ILLEGAL_ARGUMENT_EXCEPTION_H__\n// #define __ILLEGAL_ARGUMENT_EXCEPTION_H__\n\n/*\n *  IllegalArgumentException.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/Exception.h>\n\nnamespace zxing {\nclass IllegalArgumentException : public zxing::Exception {\npublic:\n  IllegalArgumentException(const char *msg);\n  ~IllegalArgumentException() throw();\n};\n}\n\n#endif // __ILLEGAL_ARGUMENT_EXCEPTION_H__\n\n// file: zxing/common/Counted.h\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n#ifndef __COUNTED_H__\n// #define __COUNTED_H__\n\n/*\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n//#define DEBUG_COUNTING\n\n// #include <iostream>\n\n#ifdef DEBUG_COUNTING\n// #include <typeinfo>\n#endif\n\nnamespace zxing {\n\n/* base class for reference-counted objects */\nclass Counted {\nprivate:\n  unsigned int count_;\npublic:\n  Counted() :\n      count_(0) {\n#ifdef DEBUG_COUNTING\n    cout << \"instantiating \" << typeid(*this).name() << \" \" << this <<\n         \" @ \" << count_ << \"\\n\";\n#endif\n  }\n  virtual ~Counted() {\n  }\n  Counted *retain() {\n#ifdef DEBUG_COUNTING\n    cout << \"retaining \" << typeid(*this).name() << \" \" << this <<\n         \" @ \" << count_;\n#endif\n    count_++;\n#ifdef DEBUG_COUNTING\n    cout << \"->\" << count_ << \"\\n\";\n#endif\n    return this;\n  }\n  void release() {\n#ifdef DEBUG_COUNTING\n    cout << \"releasing \" << typeid(*this).name() << \" \" << this <<\n         \" @ \" << count_;\n#endif\n    if (count_ == 0 || count_ == 54321) {\n#ifdef DEBUG_COUNTING\n      cout << \"\\nOverreleasing already-deleted object \" << this << \"!!!\\n\";\n#endif\n      throw 4711;\n    }\n    count_--;\n#ifdef DEBUG_COUNTING\n    cout << \"->\" << count_ << \"\\n\";\n#endif\n    if (count_ == 0) {\n#ifdef DEBUG_COUNTING\n      cout << \"deleting \" << typeid(*this).name() << \" \" << this << \"\\n\";\n#endif\n      count_ = 0xDEADF001;\n      delete this;\n    }\n  }\n\n\n  /* return the current count for denugging purposes or similar */\n  int count() const {\n    return count_;\n  }\n};\n\n/* counting reference to reference-counted objects */\ntemplate<typename T> class Ref {\nprivate:\npublic:\n  T *object_;\n  explicit Ref(T *o = 0) :\n      object_(0) {\n#ifdef DEBUG_COUNTING\n    cout << \"instantiating Ref \" << this << \" from pointer\" << o << \"\\n\";\n#endif\n    reset(o);\n  }\n\n  explicit Ref(const T &o) :\n      object_(0) {\n#ifdef DEBUG_COUNTING\n    cout << \"instantiating Ref \" << this << \" from reference\\n\";\n#endif\n    reset(const_cast<T *>(&o));\n  }\n\n  Ref(const Ref &other) :\n      object_(0) {\n#ifdef DEBUG_COUNTING\n    cout << \"instantiating Ref \" << this << \" from Ref \" << &other << \"\\n\";\n#endif\n    reset(other.object_);\n  }\n\n  template<class Y>\n  Ref(const Ref<Y> &other) :\n      object_(0) {\n#ifdef DEBUG_COUNTING\n    cout << \"instantiating Ref \" << this << \" from reference\\n\";\n#endif\n    reset(other.object_);\n  }\n\n  ~Ref() {\n#ifdef DEBUG_COUNTING\n    cout << \"destroying Ref \" << this << \" with \" <<\n         (object_ ? typeid(*object_).name() : \"NULL\") << \" \" << object_ << \"\\n\";\n#endif\n    if (object_) {\n      object_->release();\n    }\n  }\n\n  void reset(T *o) {\n#ifdef DEBUG_COUNTING\n    cout << \"resetting Ref \" << this << \" from \" <<\n         (object_ ? typeid(*object_).name() : \"NULL\") << \" \" << object_ <<\n         \" to \" << (o ? typeid(*o).name() : \"NULL\") << \" \" << o << \"\\n\";\n#endif\n    if (o) {\n      o->retain();\n    }\n    if (object_ != 0) {\n      object_->release();\n    }\n    object_ = o;\n  }\n  Ref& operator=(const Ref &other) {\n    reset(other.object_);\n    return *this;\n  }\n  template<class Y>\n  Ref& operator=(const Ref<Y> &other) {\n    reset(other.object_);\n    return *this;\n  }\n  Ref& operator=(T* o) {\n    reset(o);\n    return *this;\n  }\n  template<class Y>\n  Ref& operator=(Y* o) {\n    reset(o);\n    return *this;\n  }\n\n  T& operator*() {\n    return *object_;\n  }\n  T* operator->() const {\n    return object_;\n  }\n  operator T*() const {\n    return object_;\n  }\n\n  bool operator==(const T* that) {\n    return object_ == that;\n  }\n  bool operator==(const Ref &other) const {\n    return object_ == other.object_ || *object_ == *(other.object_);\n  }\n  template<class Y>\n  bool operator==(const Ref<Y> &other) const {\n    return object_ == other.object_ || *object_ == *(other.object_);\n  }\n\n  bool operator!=(const T* that) {\n    return !(*this == that);\n  }\n\n  bool empty() const {\n    return object_ == 0;\n  }\n\n  template<class Y>\n  friend std::ostream& operator<<(std::ostream &out, Ref<Y>& ref);\n};\n}\n\n#endif // __COUNTED_H__\n\n// file: zxing/common/BitArray.h\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n#ifndef __BIT_ARRAY_H__\n// #define __BIT_ARRAY_H__\n\n/*\n *  Copyright 2010 ZXing authors. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/common/Counted.h>\n// #include <zxing/common/IllegalArgumentException.h>\n// #include <vector>\n// #include <limits>\n\nnamespace zxing {\n\n#define ZX_LOG_DIGITS(digits) \\\n    ((digits == 8) ? 3 : \\\n     ((digits == 16) ? 4 : \\\n      ((digits == 32) ? 5 : \\\n       ((digits == 64) ? 6 : \\\n        ((digits == 128) ? 7 : \\\n         (-1))))))\n\nclass BitArray : public Counted {\nprivate:\n  size_t size_;\n  std::vector<unsigned int> bits_;\n  static const unsigned int bitsPerWord_ =\n    std::numeric_limits<unsigned int>::digits;\n  static const unsigned int logBits_ = ZX_LOG_DIGITS(bitsPerWord_);\n  static const unsigned int bitsMask_ = (1 << logBits_) - 1;\n  static size_t wordsForBits(size_t bits);\n  explicit BitArray();\n\npublic:\n  BitArray(size_t size);\n  ~BitArray();\n  size_t getSize();\n\n  bool get(size_t i) {\n    return (bits_[i >> logBits_] & (1 << (i & bitsMask_))) != 0;\n  }\n\n  void set(size_t i) {\n    bits_[i >> logBits_] |= 1 << (i & bitsMask_);\n  }\n\n  void setBulk(size_t i, unsigned int newBits);\n  void setRange(int start, int end);\n  void clear();\n  bool isRange(size_t start, size_t end, bool value);\n  std::vector<unsigned int>& getBitArray();\n  void reverse();\n};\n\n}\n\n#endif // __BIT_ARRAY_H__\n\n// file: zxing/common/BitMatrix.h\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n#ifndef __BIT_MATRIX_H__\n// #define __BIT_MATRIX_H__\n\n/*\n *  BitMatrix.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/common/Counted.h>\n// #include <zxing/common/BitArray.h>\n// #include <limits>\n\nnamespace zxing {\n\nclass BitMatrix : public Counted {\nprivate:\n  size_t width_;\n  size_t height_;\n  size_t words_;\n  unsigned int* bits_;\n\n#define ZX_LOG_DIGITS(digits) \\\n    ((digits == 8) ? 3 : \\\n     ((digits == 16) ? 4 : \\\n      ((digits == 32) ? 5 : \\\n       ((digits == 64) ? 6 : \\\n        ((digits == 128) ? 7 : \\\n         (-1))))))\n\n  static const unsigned int bitsPerWord =\n    std::numeric_limits<unsigned int>::digits;\n  static const unsigned int logBits = ZX_LOG_DIGITS(bitsPerWord);\n  static const unsigned int bitsMask = (1 << logBits) - 1;\n\npublic:\n  BitMatrix(size_t dimension);\n  BitMatrix(size_t width, size_t height);\n\n  ~BitMatrix();\n\n  bool get(size_t x, size_t y) const {\n    size_t offset = x + width_ * y;\n    return ((bits_[offset >> logBits] >> (offset & bitsMask)) & 0x01) != 0;\n  }\n\n  void set(size_t x, size_t y) {\n    size_t offset = x + width_ * y;\n    bits_[offset >> logBits] |= 1 << (offset & bitsMask);\n  }\n\n  void flip(size_t x, size_t y);\n  void clear();\n  void setRegion(size_t left, size_t top, size_t width, size_t height);\n  Ref<BitArray> getRow(int y, Ref<BitArray> row);\n\n  size_t getDimension() const;\n  size_t getWidth() const;\n  size_t getHeight() const;\n\n  unsigned int* getBits() const;\n\n  friend std::ostream& operator<<(std::ostream &out, const BitMatrix &bm);\n  const char *description();\n\nprivate:\n  BitMatrix(const BitMatrix&);\n  BitMatrix& operator =(const BitMatrix&);\n};\n\n}\n\n#endif // __BIT_MATRIX_H__\n\n// file: zxing/common/Array.h\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n#ifndef __ARRAY_H__\n// #define __ARRAY_H__\n\n/*\n *  Array.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <vector>\n\n#ifdef DEBUG_COUNTING\n// #include <iostream>\n// #include <typeinfo>\n#endif\n\n// #include <zxing/common/Counted.h>\n\n\nnamespace zxing {\n\ntemplate<typename T> class Array : public Counted {\nprotected:\npublic:\n  std::vector<T> values_;\n  Array(size_t n) :\n      Counted(), values_(n, T()) {\n  }\n  Array(T *ts, size_t n) :\n      Counted(), values_(ts, ts+n) {\n  }\n  Array(T v, size_t n) :\n      Counted(), values_(n, v) {\n  }\n  Array(std::vector<T> &v) :\n      Counted(), values_(v) {\n  }\n  Array(Array<T> &other) :\n      Counted(), values_(other.values_) {\n  }\n  Array(Array<T> *other) :\n      Counted(), values_(other->values_) {\n  }\n  virtual ~Array() {\n  }\n  Array<T>& operator=(const Array<T> &other) {\n#ifdef DEBUG_COUNTING\n    cout << \"assigning values from Array \" << &other << \" to this Array \" << this << \", \";\n#endif\n    values_ = other.values_;\n#ifdef DEBUG_COUNTING\n    cout << \"new size = \" << values_.size() << \"\\n\";\n#endif\n    return *this;\n  }\n  Array<T>& operator=(const std::vector<T> &array) {\n#ifdef DEBUG_COUNTING\n    cout << \"assigning values from Array \" << &array << \" to this Array \" << this << \", \";\n#endif\n    values_ = array;\n#ifdef DEBUG_COUNTING\n    cout << \"new size = \" << values_.size() << \"\\n\";\n#endif\n    return *this;\n  }\n  T operator[](size_t i) const {\n    return values_[i];\n  }\n  T& operator[](size_t i) {\n    return values_[i];\n  }\n  size_t size() const {\n    return values_.size();\n  }\n  std::vector<T> values() const {\n    return values_;\n  }\n  std::vector<T>& values() {\n    return values_;\n  }\n};\n\ntemplate<typename T> class ArrayRef : public Counted {\nprivate:\npublic:\n  Array<T> *array_;\n  ArrayRef() :\n      array_(0) {\n#ifdef DEBUG_COUNTING\n    cout << \"instantiating empty ArrayRef \" << this << \"\\n\";\n#endif\n  }\n  ArrayRef(size_t n) :\n      array_(0) {\n#ifdef DEBUG_COUNTING\n    cout << \"instantiating ArrayRef \" << this << \"with size \" << n << \"\\n\";\n#endif\n    reset(new Array<T> (n));\n  }\n  ArrayRef(T *ts, size_t n) :\n      array_(0) {\n#ifdef DEBUG_COUNTING\n    cout << \"instantiating ArrayRef \" << this << \"with \" << n << \" elements at \" << (void *)ts << \"\\n\";\n#endif\n    reset(new Array<T> (ts, n));\n  }\n  ArrayRef(Array<T> *a) :\n      array_(0) {\n#ifdef DEBUG_COUNTING\n    cout << \"instantiating ArrayRef \" << this << \" from pointer:\\n\";\n#endif\n    reset(a);\n  }\n  ArrayRef(const Array<T> &a) :\n      array_(0) {\n#ifdef DEBUG_COUNTING\n    cout << \"instantiating ArrayRef \" << this << \" from reference to Array \" << (void *)&a << \":\\n\";\n#endif\n    reset(const_cast<Array<T> *>(&a));\n  }\n  ArrayRef(const ArrayRef &other) :\n      Counted(), array_(0) {\n#ifdef DEBUG_COUNTING\n    cout << \"instantiating ArrayRef \" << this << \" from ArrayRef \" << &other << \":\\n\";\n#endif\n    reset(other.array_);\n  }\n\n  template<class Y>\n  ArrayRef(const ArrayRef<Y> &other) :\n      array_(0) {\n#ifdef DEBUG_COUNTING\n    cout << \"instantiating ArrayRef \" << this << \" from ArrayRef \" << &other << \":\\n\";\n#endif\n    reset(static_cast<const Array<T> *>(other.array_));\n  }\n\n  ~ArrayRef() {\n#ifdef DEBUG_COUNTING\n    cout << \"destroying ArrayRef \" << this << \" with \" << (array_ ? typeid(*array_).name() : \"NULL\") << \" \"\n         << array_ << \"\\n\";\n#endif\n    if (array_) {\n      array_->release();\n    }\n    array_ = 0;\n  }\n\n  T operator[](size_t i) const {\n    return (*array_)[i];\n  }\n  T& operator[](size_t i) {\n    return (*array_)[i];\n  }\n  size_t size() const {\n    return array_->size();\n  }\n\n  void reset(Array<T> *a) {\n#ifdef DEBUG_COUNTING\n    cout << \"resetting ArrayRef \" << this << \" from \" << (array_ ? typeid(*array_).name() : \"NULL\") << \" \"\n         << array_ << \" to \" << (a ? typeid(*a).name() : \"NULL\") << \" \" << a << \"\\n\";\n#endif\n    if (a) {\n      a->retain();\n    }\n    if (array_) {\n      array_->release();\n    }\n    array_ = a;\n  }\n  void reset(const ArrayRef<T> &other) {\n    reset(other.array_);\n  }\n  ArrayRef<T>& operator=(const ArrayRef<T> &other) {\n    reset(other);\n    return *this;\n  }\n  ArrayRef<T>& operator=(Array<T> *a) {\n    reset(a);\n    return *this;\n  }\n\n  Array<T>& operator*() {\n    return *array_;\n  }\n  Array<T>* operator->() {\n    return array_;\n  }\n};\n\n} // namespace zxing\n\n#endif // __ARRAY_H__\n\n// file: zxing/common/Str.h\n\n#ifndef __STR_H__\n// #define __STR_H__\n\n/*\n *  Str.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <string>\n// #include <iostream>\n// #include <zxing/common/Counted.h>\n\nnamespace zxing {\n\nclass String : public Counted {\nprivate:\n  std::string text_;\npublic:\n  String(const std::string &text);\n  const std::string &getText() const;\n  friend std::ostream &operator<<(std::ostream &out, const String &s);\n};\n\n}\n\n#endif // __COMMON__STRING_H__\n\n// file: zxing/common/BitSource.h\n\n#ifndef __BIT_SOURCE_H__\n// #define __BIT_SOURCE_H__\n\n/*\n *  BitSource.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/common/Array.h>\n\nnamespace zxing {\n/**\n * <p>This provides an easy abstraction to read bits at a time from a sequence of bytes, where the\n * number of bits read is not often a multiple of 8.</p>\n *\n * <p>This class is not thread-safe.</p>\n *\n * @author srowen@google.com (Sean Owen)\n * @author christian.brunschen@gmail.com (Christian Brunschen)\n */\nclass BitSource : public Counted {\n  typedef unsigned char byte;\nprivate:\n  ArrayRef<byte> bytes_;\n  int byteOffset_;\n  int bitOffset_;\npublic:\n  /**\n   * @param bytes bytes from which this will read bits. Bits will be read from the first byte first.\n   * Bits are read within a byte from most-significant to least-significant bit.\n   */\n  BitSource(ArrayRef<byte> &bytes) :\n      bytes_(bytes), byteOffset_(0), bitOffset_(0) {\n  }\n\n  int getByteOffset() {\n    return byteOffset_;\n  }\n\n  /**\n   * @param numBits number of bits to read\n   * @return int representing the bits read. The bits will appear as the least-significant\n   *         bits of the int\n   * @throws IllegalArgumentException if numBits isn't in [1,32]\n   */\n  int readBits(int numBits);\n\n  /**\n   * @return number of bits that can be read successfully\n   */\n  int available();\n};\n\n}\n\n#endif // __BIT_SOURCE_H__\n\n// file: zxing/common/DecoderResult.h\n\n#ifndef __DECODER_RESULT_H__\n// #define __DECODER_RESULT_H__\n\n/*\n *  DecoderResult.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/common/Counted.h>\n// #include <zxing/common/Array.h>\n// #include <string>\n// #include <zxing/common/Str.h>\n\nnamespace zxing {\n\nclass DecoderResult : public Counted {\nprivate:\n  ArrayRef<unsigned char> rawBytes_;\n  Ref<String> text_;\n  ArrayRef< ArrayRef<unsigned char> > byteSegments_;\n  std::string ecLevel_;\n\npublic:\n  DecoderResult(ArrayRef<unsigned char> rawBytes,\n                Ref<String> text,\n                ArrayRef< ArrayRef<unsigned char> >& byteSegments,\n                std::string const& ecLevel);\n\n  DecoderResult(ArrayRef<unsigned char> rawBytes, Ref<String> text);\n\n  ArrayRef<unsigned char> getRawBytes();\n  Ref<String> getText();\n};\n\n}\n\n#endif // __DECODER_RESULT_H__\n\n// file: zxing/common/PerspectiveTransform.h\n\n#ifndef __PERSPECTIVE_TANSFORM_H__\n// #define __PERSPECTIVE_TANSFORM_H__\n\n/*\n *  PerspectiveTransform.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/common/Counted.h>\n// #include <vector>\n\nnamespace zxing {\nclass PerspectiveTransform : public Counted {\nprivate:\n  float a11, a12, a13, a21, a22, a23, a31, a32, a33;\n  PerspectiveTransform(float a11, float a21, float a31, float a12, float a22, float a32, float a13, float a23,\n                       float a33);\n\npublic:\n  static Ref<PerspectiveTransform>\n  quadrilateralToQuadrilateral(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3,\n                               float x0p, float y0p, float x1p, float y1p, float x2p, float y2p, float x3p, float y3p);\n  static Ref<PerspectiveTransform> squareToQuadrilateral(float x0, float y0, float x1, float y1, float x2, float y2,\n      float x3, float y3);\n  static Ref<PerspectiveTransform> quadrilateralToSquare(float x0, float y0, float x1, float y1, float x2, float y2,\n      float x3, float y3);\n  Ref<PerspectiveTransform> buildAdjoint();\n  Ref<PerspectiveTransform> times(Ref<PerspectiveTransform> other);\n  void transformPoints(std::vector<float> &points);\n\n  friend std::ostream& operator<<(std::ostream& out, const PerspectiveTransform &pt);\n};\n}\n\n#endif // __PERSPECTIVE_TANSFORM_H__\n\n// file: zxing/ResultPoint.h\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n#ifndef __RESULT_POINT_H__\n// #define __RESULT_POINT_H__\n\n/*\n *  ResultPoint.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/common/Counted.h>\n// #include <vector>\n\nnamespace zxing {\n\nclass ResultPoint : public Counted {\nprotected:\n  float posX_;\n  float posY_;\n\npublic:\n  ResultPoint();\n  ResultPoint(float x, float y);\n  virtual ~ResultPoint();\n\n  virtual float getX() const;\n  virtual float getY() const;\n\n  bool equals(Ref<ResultPoint> other);\n\n  static void orderBestPatterns(std::vector<Ref<ResultPoint> > &patterns);\n  static float distance(Ref<ResultPoint> point1, Ref<ResultPoint> point2);\n  static float distance(float x1, float x2, float y1, float y2);\n\nprivate:\n  static float crossProductZ(Ref<ResultPoint> pointA, Ref<ResultPoint> pointB, Ref<ResultPoint> pointC);\n};\n\n}\n\n#endif // __RESULT_POINT_H__\n\n// file: zxing/common/DetectorResult.h\n\n#ifndef __DETECTOR_RESULT_H__\n// #define __DETECTOR_RESULT_H__\n\n/*\n *  DetectorResult.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <vector>\n// #include <zxing/common/Counted.h>\n// #include <zxing/common/Array.h>\n// #include <zxing/common/BitMatrix.h>\n// #include <zxing/ResultPoint.h>\n// #include <zxing/common/PerspectiveTransform.h>\n\nnamespace zxing {\n\nclass DetectorResult : public Counted {\nprivate:\n  Ref<BitMatrix> bits_;\n  std::vector<Ref<ResultPoint> > points_;\n  Ref<PerspectiveTransform> transform_;\n\npublic:\n  DetectorResult(Ref<BitMatrix> bits, std::vector<Ref<ResultPoint> > points, Ref<PerspectiveTransform> transform);\n  Ref<BitMatrix> getBits();\n  std::vector<Ref<ResultPoint> > getPoints();\n  Ref<PerspectiveTransform> getTransform();\n};\n}\n\n#endif // __DETECTOR_RESULT_H__\n\n// file: zxing/common/Point.h\n\n#ifndef __POINT_H__\n// #define __POINT_H__\n\n/*\n *  Point.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nnamespace zxing {\nclass PointI {\npublic:\n  int x;\n  int y;\n};\n\nclass Point {\npublic:\n  Point() : x(0.0f), y(0.0f) {};\n  Point(float x_, float y_) : x(x_), y(y_) {};\n\n  float x;\n  float y;\n};\n\nclass Line {\npublic:\n  Line(Point start_, Point end_) : start(start_), end(end_) {};\n\n  Point start;\n  Point end;\n};\n}\n#endif // POINT_H_\n\n// file: zxing/common/EdgeDetector.h\n\n#ifndef __EDGEDETECTOR_H__\n// #define __EDGEDETECTOR_H__\n/*\n *  EdgeDetector.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\n\n// #include <vector>\n// #include <zxing/common/BitMatrix.h>\n// #include <zxing/common/Point.h>\n\nnamespace zxing {\nnamespace EdgeDetector {\n\nvoid findEdgePoints(std::vector<Point>& points, const BitMatrix& image, Point start, Point end, bool invert, int skip, float deviation);\nLine findLine(const BitMatrix& image, Line estimate, bool invert, int deviation, float threshold, int skip);\n\nPoint intersection(Line a, Line b);\n\n}\n}\n#endif /* EDGEDETECTOR_H_ */\n\n// file: zxing/LuminanceSource.h\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n#ifndef __LUMINANCESOURCE_H__\n// #define __LUMINANCESOURCE_H__\n/*\n *  LuminanceSource.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/common/Counted.h>\n// #include <string.h>\n\nnamespace zxing {\n\nclass LuminanceSource : public Counted {\npublic:\n  LuminanceSource();\n  virtual ~LuminanceSource();\n\n  virtual int getWidth() const = 0;\n  virtual int getHeight() const = 0;\n\n  // Callers take ownership of the returned memory and must call delete [] on it themselves.\n  virtual unsigned char* getRow(int y, unsigned char* row) = 0;\n  virtual unsigned char* getMatrix() = 0;\n\n  virtual bool isCropSupported() const;\n  virtual Ref<LuminanceSource> crop(int left, int top, int width, int height);\n\n  virtual bool isRotateSupported() const;\n  virtual Ref<LuminanceSource> rotateCounterClockwise();\n\n  operator std::string (); // should be const but don't want to make sure a\n                           // large breaking change right now\n};\n\n}\n\n#endif /* LUMINANCESOURCE_H_ */\n\n// file: zxing/Binarizer.h\n\n#ifndef BINARIZER_H_\n#define BINARIZER_H_\n\n/*\n *  Binarizer.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/LuminanceSource.h>\n// #include <zxing/common/BitArray.h>\n// #include <zxing/common/BitMatrix.h>\n// #include <zxing/common/Counted.h>\n\nnamespace zxing {\n\nclass Binarizer : public Counted {\n private:\n  Ref<LuminanceSource> source_;\n\n public:\n  Binarizer(Ref<LuminanceSource> source);\n  virtual ~Binarizer();\n\n  virtual Ref<BitArray> getBlackRow(int y, Ref<BitArray> row) = 0;\n  virtual Ref<BitMatrix> getBlackMatrix() = 0;\n\n  Ref<LuminanceSource> getLuminanceSource() const ;\n  virtual Ref<Binarizer> createBinarizer(Ref<LuminanceSource> source) = 0;\n};\n\n}\n#endif /* BINARIZER_H_ */\n\n// file: zxing/common/GlobalHistogramBinarizer.h\n\n#ifndef __GLOBALHISTOGRAMBINARIZER_H__\n// #define __GLOBALHISTOGRAMBINARIZER_H__\n/*\n *  GlobalHistogramBinarizer.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <vector>\n// #include <zxing/Binarizer.h>\n// #include <zxing/common/BitArray.h>\n// #include <zxing/common/BitMatrix.h>\n\nnamespace zxing {\n\n\tclass GlobalHistogramBinarizer : public Binarizer {\n\t private:\n    Ref<BitMatrix> cached_matrix_;\n\t  Ref<BitArray> cached_row_;\n\t  int cached_row_num_;\n\n\tpublic:\n\t\tGlobalHistogramBinarizer(Ref<LuminanceSource> source);\n\t\tvirtual ~GlobalHistogramBinarizer();\n\n\t\tvirtual Ref<BitArray> getBlackRow(int y, Ref<BitArray> row);\n\t\tvirtual Ref<BitMatrix> getBlackMatrix();\n\t\tstatic int estimate(std::vector<int> &histogram);\n\t\tRef<Binarizer> createBinarizer(Ref<LuminanceSource> source);\n\t};\n\n}\n\n#endif /* GLOBALHISTOGRAMBINARIZER_H_ */\n\n// file: zxing/common/GreyscaleLuminanceSource.h\n\n#ifndef __GREYSCALE_LUMINANCE_SOURCE__\n#define __GREYSCALE_LUMINANCE_SOURCE__\n/*\n *  GreyscaleLuminanceSource.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/LuminanceSource.h>\n\nnamespace zxing {\n\nclass GreyscaleLuminanceSource : public LuminanceSource {\n\n private:\n  unsigned char* greyData_;\n  int dataWidth_;\n  int dataHeight_;\n  int left_;\n  int top_;\n  int width_;\n  int height_;\n\n public:\n  GreyscaleLuminanceSource(unsigned char* greyData, int dataWidth, int dataHeight, int left,\n      int top, int width, int height);\n\n  unsigned char* getRow(int y, unsigned char* row);\n  unsigned char* getMatrix();\n\n  bool isRotateSupported() const {\n    return true;\n  }\n\n  int getWidth() const {\n    return width_;\n  }\n\n  int getHeight() const {\n    return height_;\n  }\n\n  Ref<LuminanceSource> rotateCounterClockwise();\n\n};\n\n} /* namespace */\n\n#endif\n\n// file: zxing/common/GreyscaleRotatedLuminanceSource.h\n\n#ifndef __GREYSCALE_ROTATED_LUMINANCE_SOURCE__\n#define __GREYSCALE_ROTATED_LUMINANCE_SOURCE__\n/*\n *  GreyscaleRotatedLuminanceSource.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\n// #include <zxing/LuminanceSource.h>\n\nnamespace zxing {\n\nclass GreyscaleRotatedLuminanceSource : public LuminanceSource {\n private:\n  unsigned char* greyData_;\n  int dataWidth_;\n  int dataHeight_;\n  int left_;\n  int top_;\n  int width_;\n  int height_;\n\npublic:\n  GreyscaleRotatedLuminanceSource(unsigned char* greyData, int dataWidth, int dataHeight,\n      int left, int top, int width, int height);\n\n  unsigned char* getRow(int y, unsigned char* row);\n  unsigned char* getMatrix();\n\n  bool isRotateSupported() const {\n    return false;\n  }\n\n  int getWidth() const {\n    return width_;\n  }\n\n  int getHeight() const {\n    return height_;\n  }\n\n};\n\n} /* namespace */\n\n#endif\n\n// file: zxing/common/GridSampler.h\n\n#ifndef __GRID_SAMPLER_H__\n// #define __GRID_SAMPLER_H__\n\n/*\n *  GridSampler.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/common/Counted.h>\n// #include <zxing/common/BitMatrix.h>\n// #include <zxing/common/PerspectiveTransform.h>\n\nnamespace zxing {\nclass GridSampler {\nprivate:\n  static GridSampler gridSampler;\n  GridSampler();\n\npublic:\n  Ref<BitMatrix> sampleGrid(Ref<BitMatrix> image, int dimension, Ref<PerspectiveTransform> transform);\n  Ref<BitMatrix> sampleGrid(Ref<BitMatrix> image, int dimensionX, int dimensionY, Ref<PerspectiveTransform> transform);\n\n  Ref<BitMatrix> sampleGrid(Ref<BitMatrix> image, int dimension, float p1ToX, float p1ToY, float p2ToX, float p2ToY,\n                            float p3ToX, float p3ToY, float p4ToX, float p4ToY, float p1FromX, float p1FromY, float p2FromX,\n                            float p2FromY, float p3FromX, float p3FromY, float p4FromX, float p4FromY);\n  static void checkAndNudgePoints(Ref<BitMatrix> image, std::vector<float> &points);\n  static GridSampler &getInstance();\n};\n}\n\n#endif // __GRID_SAMPLER_H__\n\n// file: zxing/common/HybridBinarizer.h\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n#ifndef __HYBRIDBINARIZER_H__\n// #define __HYBRIDBINARIZER_H__\n/*\n *  HybridBinarizer.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <vector>\n// #include <zxing/Binarizer.h>\n// #include <zxing/common/GlobalHistogramBinarizer.h>\n// #include <zxing/common/BitArray.h>\n// #include <zxing/common/BitMatrix.h>\n\nnamespace zxing {\n\n\tclass HybridBinarizer : public GlobalHistogramBinarizer {\n\t private:\n    Ref<BitMatrix> matrix_;\n\t  Ref<BitArray> cached_row_;\n\t  int cached_row_num_;\n\n\tpublic:\n\t\tHybridBinarizer(Ref<LuminanceSource> source);\n\t\tvirtual ~HybridBinarizer();\n\n\t\tvirtual Ref<BitMatrix> getBlackMatrix();\n\t\tRef<Binarizer> createBinarizer(Ref<LuminanceSource> source);\n  private:\n    // We'll be using one-D arrays because C++ can't dynamically allocate 2D\n    // arrays\n    int* calculateBlackPoints(unsigned char* luminances,\n                              int subWidth,\n                              int subHeight,\n                              int width,\n                              int height);\n    void calculateThresholdForBlock(unsigned char* luminances,\n                                    int subWidth,\n                                    int subHeight,\n                                    int width,\n                                    int height,\n                                    int blackPoints[],\n                                    Ref<BitMatrix> const& matrix);\n    void threshold8x8Block(unsigned char* luminances,\n                           int xoffset,\n                           int yoffset,\n                           int threshold,\n                           int stride,\n                           Ref<BitMatrix> const& matrix);\n\t};\n\n}\n\n#endif\n\n// file: zxing/common/reedsolomon/GF256.h\n\n#ifndef __GF256_H__\n// #define __GF256_H__\n\n/*\n *  GF256.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <memory>\n// #include <vector>\n// #include <zxing/common/Counted.h>\n\nnamespace zxing {\nclass GF256Poly;\n\nclass GF256 {\n  /**\n   * <p>This class contains utility methods for performing mathematical\n   * operations over the Galois Field GF(256). Operations use a given\n   * primitive polynomial in calculations.</p>\n   *\n   * <p>Throughout this package, elements of GF(256) are represented as an\n   * <code>int</code> for convenience and speed (but at the cost of memory).\n   * Only the bottom 8 bits are really used.</p>\n   *\n   * @author srowen@google.com (Sean Owen)\n   * @author christian.brunschen@gmail.com (Christian Brunschen)\n   */\nprivate:\n  std::vector<int> exp_;\n  std::vector<int> log_;\n  Ref<GF256Poly> zero_;\n  Ref<GF256Poly> one_;\n\n  GF256(int primitive);\n\npublic:\n  Ref<GF256Poly> getZero();\n  Ref<GF256Poly> getOne();\n  Ref<GF256Poly> buildMonomial(int degree, int coefficient);\n  static int addOrSubtract(int a, int b);\n  int exp(int a);\n  int log(int a);\n  int inverse(int a);\n  int multiply(int a, int b);\n\n  static GF256 QR_CODE_FIELD;\n  static GF256 DATA_MATRIX_FIELD;\n\n  friend std::ostream& operator<<(std::ostream& out, const GF256& field);\n};\n}\n\n#endif // __GF256_H__\n\n// file: zxing/common/reedsolomon/GF256Poly.h\n\n#ifndef __GF256_POLY_H__\n// #define __GF256_POLY_H__\n\n/*\n *  GF256Poly.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <memory>\n// #include <zxing/common/Counted.h>\n// #include <zxing/common/Array.h>\n\nnamespace zxing {\nclass GF256;\n\nclass GF256Poly : public Counted {\nprivate:\n  GF256 &field;\n  ArrayRef<int> coefficients;\n  void fixCoefficients();\npublic:\n  GF256Poly(GF256 &field, ArrayRef<int> c);\n  ~GF256Poly();\n\n  int getDegree();\n  bool isZero();\n  int getCoefficient(int degree);\n  int evaluateAt(int a);\n  Ref<GF256Poly> addOrSubtract(Ref<GF256Poly> other);\n  Ref<GF256Poly> multiply(Ref<GF256Poly> other);\n  Ref<GF256Poly> multiply(int scalar);\n  Ref<GF256Poly> multiplyByMonomial(int degree, int coefficient);\n  const char *description() const;\n  friend std::ostream& operator<<(std::ostream& out, const GF256Poly& poly);\n\n};\n}\n\n#endif // __GF256_POLY_H__\n\n// file: zxing/common/reedsolomon/ReedSolomonDecoder.h\n\n#ifndef __REED_SOLOMON_DECODER_H__\n// #define __REED_SOLOMON_DECODER_H__\n\n/*\n *  ReedSolomonDecoder.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <memory>\n// #include <vector>\n// #include <zxing/common/Counted.h>\n// #include <zxing/common/Array.h>\n\nnamespace zxing {\nclass GF256;\nclass GF256Poly;\n\nclass ReedSolomonDecoder {\nprivate:\n  GF256 &field;\npublic:\n  ReedSolomonDecoder(GF256 &fld);\n  ~ReedSolomonDecoder();\n  void decode(ArrayRef<int> received, int twoS);\nprivate:\n  std::vector<Ref<GF256Poly> > runEuclideanAlgorithm(Ref<GF256Poly> a, Ref<GF256Poly> b, int R);\n  ArrayRef<int> findErrorLocations(Ref<GF256Poly> errorLocator);\n  ArrayRef<int> findErrorMagnitudes(Ref<GF256Poly> errorEvaluator, ArrayRef<int> errorLocations, bool dataMatrix);\n};\n}\n\n#endif // __REED_SOLOMON_DECODER_H__\n\n// file: zxing/common/reedsolomon/ReedSolomonException.h\n\n#ifndef __REED_SOLOMON_EXCEPTION_H__\n// #define __REED_SOLOMON_EXCEPTION_H__\n\n/*\n *  ReedSolomonException.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/Exception.h>\n\nnamespace zxing {\nclass ReedSolomonException : public Exception {\npublic:\n  ReedSolomonException(const char *msg) throw();\n  ~ReedSolomonException() throw();\n};\n}\n\n#endif // __REED_SOLOMON_EXCEPTION_H__\n\n// file: zxing/BarcodeFormat.h\n\n#ifndef __BARCODE_FORMAT_H__\n// #define __BARCODE_FORMAT_H__\n\n/*\n *  BarcodeFormat.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nnamespace zxing {\n\n\ttypedef enum BarcodeFormat {\n\t\tBarcodeFormat_None = 0,\n\t\tBarcodeFormat_QR_CODE,\n\t\tBarcodeFormat_DATA_MATRIX,\n\t\tBarcodeFormat_UPC_E,\n\t\tBarcodeFormat_UPC_A,\n\t\tBarcodeFormat_EAN_8,\n\t\tBarcodeFormat_EAN_13,\n\t\tBarcodeFormat_CODE_128,\n\t\tBarcodeFormat_CODE_39,\n\t\tBarcodeFormat_ITF\n\t} BarcodeFormat;\n\n\t/* if you update the enum, please update the name in BarcodeFormat.cpp */\n\textern const char *barcodeFormatNames[];\n}\n\n#endif // __BARCODE_FORMAT_H__\n\n// file: zxing/BinaryBitmap.h\n\n#ifndef __BINARYBITMAP_H__\n// #define __BINARYBITMAP_H__\n\n/*\n *  BinaryBitmap.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/common/Counted.h>\n// #include <zxing/common/BitMatrix.h>\n// #include <zxing/common/BitArray.h>\n// #include <zxing/Binarizer.h>\n\nnamespace zxing {\n\n\tclass BinaryBitmap : public Counted {\n\tprivate:\n\t\tRef<Binarizer> binarizer_;\n\t\tint cached_y_;\n\n\tpublic:\n\t\tBinaryBitmap(Ref<Binarizer> binarizer);\n\t\tvirtual ~BinaryBitmap();\n\n\t\tRef<BitArray> getBlackRow(int y, Ref<BitArray> row);\n\t\tRef<BitMatrix> getBlackMatrix();\n\n\t\tRef<LuminanceSource> getLuminanceSource() const;\n\n\t\tint getWidth() const;\n\t\tint getHeight() const;\n\n\t\tbool isRotateSupported() const;\n\t\tRef<BinaryBitmap> rotateCounterClockwise();\n\n\t\tbool isCropSupported() const;\n\t\tRef<BinaryBitmap> crop(int left, int top, int width, int height);\n\n\t};\n\n}\n\n#endif /* BINARYBITMAP_H_ */\n\n// file: zxing/ResultPointCallback.h\n\n#ifndef __RESULT_POINT_CALLBACK_H__\n// #define __RESULT_POINT_CALLBACK_H__\n\n/*\n *  ResultPointCallback.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/common/Counted.h>\n\nnamespace zxing {\n\nclass ResultPoint;\n\nclass ResultPointCallback : public Counted {\nprotected:\n  ResultPointCallback() {}\npublic:\n  virtual void foundPossibleResultPoint(ResultPoint const& point) = 0;\n  virtual ~ResultPointCallback();\n};\n\n}\n\n#endif // __RESULT_POINT_CALLBACK_H__\n\n// file: zxing/DecodeHints.h\n\n#ifndef __DECODEHINTS_H_\n#define __DECODEHINTS_H_\n/*\n *  DecodeHintType.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/BarcodeFormat.h>\n// #include <zxing/ResultPointCallback.h>\n\nnamespace zxing {\n\ntypedef unsigned int DecodeHintType;\n\nclass DecodeHints {\n\n private:\n\n  DecodeHintType hints;\n\n  Ref<ResultPointCallback> callback;\n\n public:\n\n  static const DecodeHintType BARCODEFORMAT_QR_CODE_HINT = 1 << BarcodeFormat_QR_CODE;\n  static const DecodeHintType BARCODEFORMAT_DATA_MATRIX_HINT = 1 << BarcodeFormat_DATA_MATRIX;\n  static const DecodeHintType BARCODEFORMAT_UPC_E_HINT = 1 << BarcodeFormat_UPC_E;\n  static const DecodeHintType BARCODEFORMAT_UPC_A_HINT = 1 << BarcodeFormat_UPC_A;\n  static const DecodeHintType BARCODEFORMAT_EAN_8_HINT = 1 << BarcodeFormat_EAN_8;\n  static const DecodeHintType BARCODEFORMAT_EAN_13_HINT = 1 << BarcodeFormat_EAN_13;\n  static const DecodeHintType BARCODEFORMAT_CODE_128_HINT = 1 << BarcodeFormat_CODE_128;\n  static const DecodeHintType BARCODEFORMAT_CODE_39_HINT = 1 << BarcodeFormat_CODE_39;\n  static const DecodeHintType BARCODEFORMAT_ITF_HINT = 1 << BarcodeFormat_ITF;\n  static const DecodeHintType CHARACTER_SET = 1 << 30;\n  static const DecodeHintType TRYHARDER_HINT = 1 << 31;\n\n  static const DecodeHints PRODUCT_HINT;\n  static const DecodeHints ONED_HINT;\n  static const DecodeHints DEFAULT_HINT;\n\n  DecodeHints();\n  DecodeHints(DecodeHintType init);\n\n  void addFormat(BarcodeFormat toadd);\n  bool containsFormat(BarcodeFormat tocheck) const;\n  void setTryHarder(bool toset);\n  bool getTryHarder() const;\n\n  void setResultPointCallback(Ref<ResultPointCallback> const&);\n  Ref<ResultPointCallback> getResultPointCallback() const;\n\n};\n\n}\n\n#endif\n\n// file: zxing/Result.h\n\n#ifndef __RESULT_H__\n// #define __RESULT_H__\n\n/*\n *  Result.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <string>\n// #include <vector>\n// #include <zxing/common/Array.h>\n// #include <zxing/common/Counted.h>\n// #include <zxing/common/Str.h>\n// #include <zxing/ResultPoint.h>\n// #include <zxing/BarcodeFormat.h>\n\nnamespace zxing {\n\nclass Result : public Counted {\nprivate:\n  Ref<String> text_;\n  ArrayRef<unsigned char> rawBytes_;\n  std::vector<Ref<ResultPoint> > resultPoints_;\n  BarcodeFormat format_;\n\npublic:\n  Result(Ref<String> text, ArrayRef<unsigned char> rawBytes, std::vector<Ref<ResultPoint> > resultPoints,\n         BarcodeFormat format);\n  ~Result();\n  Ref<String> getText();\n  ArrayRef<unsigned char> getRawBytes();\n  const std::vector<Ref<ResultPoint> >& getResultPoints() const;\n  std::vector<Ref<ResultPoint> >& getResultPoints();\n  BarcodeFormat getBarcodeFormat() const;\n\n  friend std::ostream& operator<<(std::ostream &out, Result& result);\n};\n\n}\n#endif // __RESULT_H__\n\n// file: zxing/Reader.h\n\n#ifndef __READER_H__\n// #define __READER_H__\n\n/*\n *  Reader.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/BinaryBitmap.h>\n// #include <zxing/Result.h>\n// #include <zxing/DecodeHints.h>\n\nnamespace zxing {\n\n class Reader : public Counted {\n  protected:\n   Reader() {}\n  public:\n   virtual Ref<Result> decode(Ref<BinaryBitmap> image);\n   virtual Ref<Result> decode(Ref<BinaryBitmap> image, DecodeHints hints) = 0;\n   virtual ~Reader();\n};\n\n}\n\n#endif // __READER_H__\n\n// file: zxing/MultiFormatReader.h\n\n#ifndef __MULTI_FORMAT_READER_H__\n// #define __MULTI_FORMAT_READER_H__\n\n/*\n *  MultiFormatBarcodeReader.h\n *  ZXing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\n// #include <zxing/Reader.h>\n// #include <zxing/common/BitArray.h>\n// #include <zxing/Result.h>\n// #include <zxing/DecodeHints.h>\n\nnamespace zxing {\n  class MultiFormatReader : public Reader {\n\n  private:\n    Ref<Result> decodeInternal(Ref<BinaryBitmap> image);\n\n    std::vector<Ref<Reader> > readers_;\n    DecodeHints hints_;\n\n  public:\n    MultiFormatReader();\n\n    Ref<Result> decode(Ref<BinaryBitmap> image);\n    Ref<Result> decode(Ref<BinaryBitmap> image, DecodeHints hints);\n    Ref<Result> decodeWithState(Ref<BinaryBitmap> image);\n    void setHints(DecodeHints hints);\n    ~MultiFormatReader();\n  };\n}\n\n#endif\n\n// file: zxing/ReaderException.h\n\n#ifndef __READER_EXCEPTION_H__\n// #define __READER_EXCEPTION_H__\n\n/*\n *  ReaderException.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/Exception.h>\n\nnamespace zxing {\n\nclass ReaderException : public Exception {\npublic:\n  ReaderException();\n  ReaderException(const char *msg);\n  ~ReaderException() throw();\n};\n\n}\n#endif // __READER_EXCEPTION_H__\n\n// file: zxing/datamatrix/decoder/Decoder.h\n\n#ifndef __DECODER_DM_H__\n// #define __DECODER_DM_H__\n\n/*\n *  Decoder.h\n *  zxing\n *\n *  Created by Luiz Silva on 09/02/2010.\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/common/reedsolomon/ReedSolomonDecoder.h>\n// #include <zxing/common/reedsolomon/GF256.h>\n// #include <zxing/common/Counted.h>\n// #include <zxing/common/Array.h>\n// #include <zxing/common/DecoderResult.h>\n// #include <zxing/common/BitMatrix.h>\n\n\nnamespace zxing {\nnamespace datamatrix {\n\nclass Decoder {\nprivate:\n  ReedSolomonDecoder rsDecoder_;\n\n  void correctErrors(ArrayRef<unsigned char> bytes, int numDataCodewords);\n\npublic:\n  Decoder();\n\n  Ref<DecoderResult> decode(Ref<BitMatrix> bits);\n};\n\n}\n}\n\n#endif // __DECODER_DM_H__\n\n// file: zxing/datamatrix/DataMatrixReader.h\n\n#ifndef __DATA_MATRIX_READER_H__\n// #define __DATA_MATRIX_READER_H__\n\n/*\n *  DataMatrixReader.h\n *  zxing\n *\n *  Created by Luiz Silva on 09/02/2010.\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/Reader.h>\n// #include <zxing/DecodeHints.h>\n// #include <zxing/datamatrix/decoder/Decoder.h>\n\nnamespace zxing {\nnamespace datamatrix {\n\nclass DataMatrixReader : public Reader {\nprivate:\n  Decoder decoder_;\n\npublic:\n  DataMatrixReader();\n  virtual Ref<Result> decode(Ref<BinaryBitmap> image, DecodeHints hints);\n  virtual ~DataMatrixReader();\n\n};\n\n}\n}\n\n#endif // __DATA_MATRIX_READER_H__\n\n// file: zxing/datamatrix/Version.h\n\n#ifndef __VERSION_H__\n// #define __VERSION_H__\n\n/*\n *  Version.h\n *  zxing\n *\n *  Created by Luiz Silva on 09/02/2010.\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/ReaderException.h>\n// #include <zxing/common/BitMatrix.h>\n// #include <zxing/common/Counted.h>\n// #include <vector>\n\nnamespace zxing {\nnamespace datamatrix {\n\nclass ECB {\nprivate:\n  int count_;\n  int dataCodewords_;\npublic:\n  ECB(int count, int dataCodewords);\n  int getCount();\n  int getDataCodewords();\n};\n\nclass ECBlocks {\nprivate:\n  int ecCodewords_;\n  std::vector<ECB*> ecBlocks_;\npublic:\n  ECBlocks(int ecCodewords, ECB *ecBlocks);\n  ECBlocks(int ecCodewords, ECB *ecBlocks1, ECB *ecBlocks2);\n  int getECCodewords();\n  std::vector<ECB*>& getECBlocks();\n  ~ECBlocks();\n};\n\nclass Version : public Counted {\nprivate:\n  int versionNumber_;\n  int symbolSizeRows_;\n  int symbolSizeColumns_;\n  int dataRegionSizeRows_;\n  int dataRegionSizeColumns_;\n  ECBlocks* ecBlocks_;\n  int totalCodewords_;\n  Version(int versionNumber, int symbolSizeRows, int symbolSizeColumns, int dataRegionSizeRows,\n\t\t  int dataRegionSizeColumns, ECBlocks *ecBlocks);\n\npublic:\n  static std::vector<Ref<Version> > VERSIONS;\n\n  ~Version();\n  int getVersionNumber();\n  int getSymbolSizeRows();\n  int getSymbolSizeColumns();\n  int getDataRegionSizeRows();\n  int getDataRegionSizeColumns();\n  int getTotalCodewords();\n  ECBlocks* getECBlocks();\n  static int  buildVersions();\n  Ref<Version> getVersionForDimensions(int numRows, int numColumns);\n\nprivate:\n  Version(const Version&);\n  Version & operator=(const Version&);\n};\n}\n}\n\n#endif // __VERSION_H__\n\n// file: zxing/datamatrix/decoder/BitMatrixParser.h\n\n#ifndef __BIT_MATRIX_PARSER_DM_H__\n// #define __BIT_MATRIX_PARSER_DM_H__\n\n/*\n *  BitMatrixParser.h\n *  zxing\n *\n *  Created by Luiz Silva on 09/02/2010.\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/ReaderException.h>\n// #include <zxing/common/BitMatrix.h>\n// #include <zxing/common/Counted.h>\n// #include <zxing/common/Array.h>\n// #include <zxing/datamatrix/Version.h>\n\nnamespace zxing {\nnamespace datamatrix {\n\nclass BitMatrixParser : public Counted {\nprivate:\n  Ref<BitMatrix> bitMatrix_;\n  Ref<Version> parsedVersion_;\n  Ref<BitMatrix> readBitMatrix_;\n\n  int copyBit(size_t x, size_t y, int versionBits);\n\npublic:\n  BitMatrixParser(Ref<BitMatrix> bitMatrix);\n  Ref<Version> readVersion(Ref<BitMatrix> bitMatrix);\n  ArrayRef<unsigned char> readCodewords();\n  bool readModule(int row, int column, int numRows, int numColumns);\n\nprivate:\n  int readUtah(int row, int column, int numRows, int numColumns);\n  int readCorner1(int numRows, int numColumns);\n  int readCorner2(int numRows, int numColumns);\n  int readCorner3(int numRows, int numColumns);\n  int readCorner4(int numRows, int numColumns);\n  Ref<BitMatrix> extractDataRegion(Ref<BitMatrix> bitMatrix);\n};\n\n}\n}\n\n#endif // __BIT_MATRIX_PARSER_DM_H__\n\n// file: zxing/datamatrix/decoder/DataBlock.h\n\n#ifndef __DATA_BLOCK_DM_H__\n// #define __DATA_BLOCK_DM_H__\n\n/*\n *  DataBlock.h\n *  zxing\n *\n *  Created by Luiz Silva on 09/02/2010.\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <vector>\n// #include <zxing/common/Counted.h>\n// #include <zxing/common/Array.h>\n// #include <zxing/datamatrix/Version.h>\n\nnamespace zxing {\nnamespace datamatrix {\n\nclass DataBlock : public Counted {\nprivate:\n  int numDataCodewords_;\n  ArrayRef<unsigned char> codewords_;\n\n  DataBlock(int numDataCodewords, ArrayRef<unsigned char> codewords);\n\npublic:\n  static std::vector<Ref<DataBlock> > getDataBlocks(ArrayRef<unsigned char> rawCodewords, Version *version);\n\n  int getNumDataCodewords();\n  ArrayRef<unsigned char> getCodewords();\n};\n\n}\n}\n\n#endif // __DATA_BLOCK_DM_H__\n\n// file: zxing/datamatrix/decoder/DecodedBitStreamParser.h\n\n#ifndef __DECODED_BIT_STREAM_PARSER_DM_H__\n// #define __DECODED_BIT_STREAM_PARSER_DM_H__\n\n/*\n *  DecodedBitStreamParser.h\n *  zxing\n *\n *  Created by Luiz Silva on 09/02/2010.\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <string>\n// #include <sstream>\n// #include <zxing/common/Array.h>\n// #include <zxing/common/BitSource.h>\n// #include <zxing/common/Counted.h>\n// #include <zxing/common/DecoderResult.h>\n\n\nnamespace zxing {\nnamespace datamatrix {\n\nclass DecodedBitStreamParser {\nprivate:\n  static const int PAD_ENCODE = 0;  // Not really an encoding\n  static const int ASCII_ENCODE = 1;\n  static const int C40_ENCODE = 2;\n  static const int TEXT_ENCODE = 3;\n  static const int ANSIX12_ENCODE = 4;\n  static const int EDIFACT_ENCODE = 5;\n  static const int BASE256_ENCODE = 6;\n\n  /**\n   * See ISO 16022:2006, Annex C Table C.1\n   * The C40 Basic Character Set (*'s used for placeholders for the shift values)\n   */\n  static const char C40_BASIC_SET_CHARS[];\n\n  static const char C40_SHIFT2_SET_CHARS[];\n  /**\n   * See ISO 16022:2006, Annex C Table C.2\n   * The Text Basic Character Set (*'s used for placeholders for the shift values)\n   */\n  static const char TEXT_BASIC_SET_CHARS[];\n\n  static const char TEXT_SHIFT3_SET_CHARS[];\n  /**\n   * See ISO 16022:2006, 5.2.3 and Annex C, Table C.2\n   */\n  int decodeAsciiSegment(Ref<BitSource> bits, std::ostringstream &result, std::ostringstream &resultTrailer);\n  /**\n   * See ISO 16022:2006, 5.2.5 and Annex C, Table C.1\n   */\n  void decodeC40Segment(Ref<BitSource> bits, std::ostringstream &result);\n  /**\n   * See ISO 16022:2006, 5.2.6 and Annex C, Table C.2\n   */\n  void decodeTextSegment(Ref<BitSource> bits, std::ostringstream &result);\n  /**\n   * See ISO 16022:2006, 5.2.7\n   */\n  void decodeAnsiX12Segment(Ref<BitSource> bits, std::ostringstream &result);\n  /**\n   * See ISO 16022:2006, 5.2.8 and Annex C Table C.3\n   */\n  void decodeEdifactSegment(Ref<BitSource> bits, std::ostringstream &result);\n  /**\n   * See ISO 16022:2006, 5.2.9 and Annex B, B.2\n   */\n  void decodeBase256Segment(Ref<BitSource> bits, std::ostringstream &result, std::vector<unsigned char> byteSegments);\n\n  void parseTwoBytes(int firstByte, int secondByte, int*& result);\n  /**\n   * See ISO 16022:2006, Annex B, B.2\n   */\n  unsigned char unrandomize255State(int randomizedBase256Codeword,\n                                          int base256CodewordPosition) {\n    int pseudoRandomNumber = ((149 * base256CodewordPosition) % 255) + 1;\n    int tempVariable = randomizedBase256Codeword - pseudoRandomNumber;\n    return (unsigned char) (tempVariable >= 0 ? tempVariable : (tempVariable + 256));\n  };\n  void append(std::ostream &ost, const unsigned char *bufIn, size_t nIn, const char *src);\n\npublic:\n  DecodedBitStreamParser() { };\n  Ref<DecoderResult> decode(ArrayRef<unsigned char> bytes);\n};\n\n}\n}\n\n#endif // __DECODED_BIT_STREAM_PARSER_DM_H__\n\n// file: zxing/datamatrix/detector/CornerPoint.h\n\n#ifndef __CORNER_FINDER_H__\n// #define __CORNER_FINDER_H__\n\n/*\n *  CornerPoint.h\n *  zxing\n *\n *  Created by Luiz Silva on 09/02/2010.\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/ResultPoint.h>\n// #include <cmath>\n\nnamespace zxing {\n\tnamespace datamatrix {\n\n\t\tclass CornerPoint : public ResultPoint {\n\t\tprivate:\n\t\t\tint counter_;\n\n\t\tpublic:\n\t\t\tCornerPoint(float posX, float posY);\n\t\t\tint getCount() const;\n\t\t\tvoid incrementCount();\n\t\t\tbool equals(Ref<CornerPoint> other) const;\n\t\t};\n\t}\n}\n\n#endif // __CORNER_FINDER_H__\n\n// file: zxing/datamatrix/detector/MonochromeRectangleDetector.h\n\n#ifndef __MONOCHROMERECTANGLEDETECTOR_H__\n// #define __MONOCHROMERECTANGLEDETECTOR_H__\n\n/*\n *  MonochromeRectangleDetector.h\n *  zxing\n *\n *  Created by Luiz Silva on 09/02/2010.\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <vector>\n// #include <zxing/ReaderException.h>\n// #include <zxing/ResultPoint.h>\n// #include <zxing/common/BitMatrix.h>\n// #include <zxing/common/Counted.h>\n// #include <zxing/datamatrix/detector/CornerPoint.h>\n\nnamespace zxing {\nnamespace datamatrix {\n\nstruct TwoInts: public Counted {\n\tint start;\n\tint end;\n};\n\nclass MonochromeRectangleDetector : public Counted {\nprivate:\n  static const int MAX_MODULES = 32;\n  Ref<BitMatrix> image_;\n\npublic:\n  MonochromeRectangleDetector(Ref<BitMatrix> image) : image_(image) {  };\n\n  std::vector<Ref<CornerPoint> > detect();\n\nprivate:\n  Ref<CornerPoint> findCornerFromCenter(int centerX, int deltaX, int left, int right,\n      int centerY, int deltaY, int top, int bottom, int maxWhiteRun);\n\n  Ref<TwoInts> blackWhiteRange(int fixedDimension, int maxWhiteRun, int minDim, int maxDim,\n      bool horizontal);\n\n  int max(int a, float b) { return (float) a > b ? a : (int) b;};\n};\n}\n}\n\n#endif // __MONOCHROMERECTANGLEDETECTOR_H__\n\n// file: zxing/datamatrix/detector/Detector.h\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n#ifndef __DETECTOR_H__\n// #define __DETECTOR_H__\n\n/*\n *  Detector.h\n *  zxing\n *\n *  Created by Luiz Silva on 09/02/2010.\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/common/Counted.h>\n// #include <zxing/common/DetectorResult.h>\n// #include <zxing/common/BitMatrix.h>\n// #include <zxing/common/PerspectiveTransform.h>\n// #include <zxing/common/detector/WhiteRectangleDetector.h>\n\nnamespace zxing {\nnamespace datamatrix {\n\nclass ResultPointsAndTransitions: public Counted {\n  private:\n    Ref<ResultPoint> to_;\n    Ref<ResultPoint> from_;\n    int transitions_;\n\n  public:\n    ResultPointsAndTransitions();\n    ResultPointsAndTransitions(Ref<ResultPoint> from, Ref<ResultPoint> to, int transitions);\n    Ref<ResultPoint> getFrom();\n    Ref<ResultPoint> getTo();\n    int getTransitions();\n};\n\nclass Detector: public Counted {\n  private:\n    Ref<BitMatrix> image_;\n\n  protected:\n    Ref<BitMatrix> sampleGrid(Ref<BitMatrix> image, int dimensionX, int dimensionY,\n        Ref<PerspectiveTransform> transform);\n\n    void insertionSort(std::vector<Ref<ResultPointsAndTransitions> >& vector);\n\n    Ref<ResultPoint> correctTopRightRectangular(Ref<ResultPoint> bottomLeft,\n        Ref<ResultPoint> bottomRight, Ref<ResultPoint> topLeft, Ref<ResultPoint> topRight,\n        int dimensionTop, int dimensionRight);\n    Ref<ResultPoint> correctTopRight(Ref<ResultPoint> bottomLeft, Ref<ResultPoint> bottomRight,\n        Ref<ResultPoint> topLeft, Ref<ResultPoint> topRight, int dimension);\n    bool isValid(Ref<ResultPoint> p);\n    int distance(Ref<ResultPoint> a, Ref<ResultPoint> b);\n    Ref<ResultPointsAndTransitions> transitionsBetween(Ref<ResultPoint> from, Ref<ResultPoint> to);\n    int min(int a, int b) {\n      return a > b ? b : a;\n    }\n    /**\n     * Ends up being a bit faster than round(). This merely rounds its\n     * argument to the nearest int, where x.5 rounds up.\n     */\n    int round(float d) {\n      return (int) (d + 0.5f);\n    }\n\n  public:\n    Ref<BitMatrix> getImage();\n    Detector(Ref<BitMatrix> image);\n\n    virtual Ref<PerspectiveTransform> createTransform(Ref<ResultPoint> topLeft,\n        Ref<ResultPoint> topRight, Ref<ResultPoint> bottomLeft, Ref<ResultPoint> bottomRight,\n        int dimensionX, int dimensionY);\n\n    Ref<DetectorResult> detect();\n\n  private:\n    int compare(Ref<ResultPointsAndTransitions> a, Ref<ResultPointsAndTransitions> b);\n};\n\n}\n}\n\n#endif // __DETECTOR_H__\n\n// file: zxing/oned/OneDReader.h\n\n#ifndef __ONED_READER_H__\n// #define __ONED_READER_H__\n\n/*\n *  OneDReader.h\n *  ZXing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/Reader.h>\n\nnamespace zxing {\n\tnamespace oned {\n\t\tclass OneDReader : public Reader {\n\t\tprivate:\n\t\t\tstatic const int INTEGER_MATH_SHIFT = 8;\n\n\t\t\tRef<Result> doDecode(Ref<BinaryBitmap> image, DecodeHints hints);\n\t\tpublic:\n\t\t\tstatic const int PATTERN_MATCH_RESULT_SCALE_FACTOR = 1 << INTEGER_MATH_SHIFT;\n\n\t\t\tOneDReader();\n\t\t\tvirtual Ref<Result> decode(Ref<BinaryBitmap> image, DecodeHints hints);\n\n\t\t\t// Implementations must not throw any exceptions. If a barcode is not found on this row,\n\t\t\t// a empty ref should be returned e.g. return Ref<Result>();\n\t\t\tvirtual Ref<Result> decodeRow(int rowNumber, Ref<BitArray> row) = 0;\n\n\t\t\tstatic unsigned int patternMatchVariance(int counters[], int countersSize,\n\t\t\t    const int pattern[], int maxIndividualVariance);\n\t\t\tstatic bool recordPattern(Ref<BitArray> row, int start, int counters[], int countersCount);\n\t\t\tvirtual ~OneDReader();\n\t\t};\n\t}\n}\n\n#endif\n\n// file: zxing/oned/Code128Reader.h\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n#ifndef __CODE_128_READER_H__\n// #define __CODE_128_READER_H__\n/*\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/oned/OneDReader.h>\n// #include <zxing/common/BitArray.h>\n// #include <zxing/Result.h>\n\nnamespace zxing {\n\tnamespace oned {\n\t\tclass Code128Reader : public OneDReader {\n\n\t\tprivate:\n      enum {MAX_AVG_VARIANCE = (unsigned int) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 250/1000)};\n      enum {MAX_INDIVIDUAL_VARIANCE = (int) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 700/1000)};\n\t\t\tstatic const int CODE_SHIFT = 98;\n\n\t\t\tstatic const int CODE_CODE_C = 99;\n\t\t\tstatic const int CODE_CODE_B = 100;\n\t\t\tstatic const int CODE_CODE_A = 101;\n\n\t\t\tstatic const int CODE_FNC_1 = 102;\n\t\t\tstatic const int CODE_FNC_2 = 97;\n\t\t\tstatic const int CODE_FNC_3 = 96;\n\t\t\tstatic const int CODE_FNC_4_A = 101;\n\t\t\tstatic const int CODE_FNC_4_B = 100;\n\n\t\t\tstatic const int CODE_START_A = 103;\n\t\t\tstatic const int CODE_START_B = 104;\n\t\t\tstatic const int CODE_START_C = 105;\n\t\t\tstatic const int CODE_STOP = 106;\n\n\t\t\tstatic int* findStartPattern(Ref<BitArray> row);\n\t\t\tstatic int decodeCode(Ref<BitArray> row, int counters[], int countersCount, int rowOffset);\n\n\t\t\tvoid append(char* s, char c);\n\t\tpublic:\n\t\t\tRef<Result> decodeRow(int rowNumber, Ref<BitArray> row);\n\t\t\tCode128Reader();\n\t\t\t~Code128Reader();\n\t\t};\n\t}\n}\n\n#endif\n\n// file: zxing/oned/Code39Reader.h\n\n#ifndef __CODE_39_READER_H__\n// #define __CODE_39_READER_H__\n/*\n *  Code39Reader.h\n *  ZXing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/oned/OneDReader.h>\n// #include <zxing/common/BitArray.h>\n// #include <zxing/Result.h>\n\nnamespace zxing {\n\tnamespace oned {\n\n\t\t/**\n\t\t * <p>Decodes Code 39 barcodes. This does not support \"Full ASCII Code 39\" yet.</p>\n\t\t * Ported form Java (author Sean Owen)\n\t\t * @author Lukasz Warchol\n\t\t */\n\t\tclass Code39Reader : public OneDReader {\n\n\t\tprivate:\n\t\t\tstd::string alphabet_string;\n\n\t\t\tbool usingCheckDigit;\n\t\t\tbool extendedMode;\n\n\t\t\tstatic int* findAsteriskPattern(Ref<BitArray> row);\t\t\t\t\t\t\t\t\t\t\t\t\t\t//throws ReaderException\n\t\t\tstatic int toNarrowWidePattern(int counters[], int countersLen);\n\t\t\tstatic char patternToChar(int pattern);\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t//throws ReaderException\n\t\t\tstatic Ref<String> decodeExtended(std::string encoded);\t\t\t\t\t\t\t\t\t\t\t\t\t//throws ReaderException\n\n\t\t\tvoid append(char* s, char c);\n\t\tpublic:\n\t\t\tCode39Reader();\n\t\t\tCode39Reader(bool usingCheckDigit_);\n\t\t\tCode39Reader(bool usingCheckDigit_, bool extendedMode_);\n\n\t\t\tRef<Result> decodeRow(int rowNumber, Ref<BitArray> row);\n    };\n\t}\n}\n\n#endif\n\n// file: zxing/oned/UPCEANReader.h\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n#ifndef __UPC_EAN_READER_H__\n// #define __UPC_EAN_READER_H__\n\n/*\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/oned/OneDReader.h>\n// #include <zxing/common/BitArray.h>\n// #include <zxing/Result.h>\n\ntypedef enum UPC_EAN_PATTERNS {\n\tUPC_EAN_PATTERNS_L_PATTERNS = 0,\n\tUPC_EAN_PATTERNS_L_AND_G_PATTERNS\n} UPC_EAN_PATTERNS;\n\nnamespace zxing {\n\tnamespace oned {\n\t\tclass UPCEANReader : public OneDReader {\n\n\t\tprivate:\n      enum {MAX_AVG_VARIANCE = (unsigned int) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 420/1000)};\n      enum {MAX_INDIVIDUAL_VARIANCE = (int) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 700/1000)};\n\n\t\t\tstatic bool findStartGuardPattern(Ref<BitArray> row, int* rangeStart, int* rangeEnd);\n\n\t\t\tvirtual bool decodeEnd(Ref<BitArray> row, int endStart, int* endGuardBegin, int* endGuardEnd);\n\n\t\t\tstatic bool checkStandardUPCEANChecksum(std::string s);\n\t\tprotected:\n\t\t\tstatic bool findGuardPattern(Ref<BitArray> row, int rowOffset, bool whiteFirst,\n\t\t\t    const int pattern[], int patternLen, int* start, int* end);\n\n\t\t\tvirtual int getMIDDLE_PATTERN_LEN();\n\t\t\tvirtual const int* getMIDDLE_PATTERN();\n\n\t\tpublic:\n\t\t\tUPCEANReader();\n\n      // Returns < 0 on failure, >= 0 on success.\n\t\t\tvirtual int decodeMiddle(Ref<BitArray> row, int startGuardBegin, int startGuardEnd,\n\t\t\t    std::string& resultString) = 0;\n\n\t\t\tRef<Result> decodeRow(int rowNumber, Ref<BitArray> row);\n\n\t\t\t// TODO(dswitkin): Should this be virtual so that UPCAReader can override it?\n\t\t\tRef<Result> decodeRow(int rowNumber, Ref<BitArray> row, int startGuardBegin,\n          int startGuardEnd);\n\n      // Returns < 0 on failure, >= 0 on success.\n\t\t\tstatic int decodeDigit(Ref<BitArray> row, int counters[], int countersLen, int rowOffset,\n\t\t\t    UPC_EAN_PATTERNS patternType);\n\n\t\t\tvirtual bool checkChecksum(std::string s);\n\n\t\t\tvirtual BarcodeFormat getBarcodeFormat() = 0;\n\t\t\tvirtual ~UPCEANReader();\n\t\t};\n\t}\n}\n\n#endif\n\n// file: zxing/oned/EAN13Reader.h\n\n#ifndef __EAN_13_READER_H__\n// #define __EAN_13_READER_H__\n\n/*\n *  EAN13Reader.h\n *  ZXing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/oned/UPCEANReader.h>\n// #include <zxing/Result.h>\n\nnamespace zxing {\n  namespace oned {\n    class EAN13Reader : public UPCEANReader {\n\n    private:\n      static bool determineFirstDigit(std::string& resultString, int lgPatternFound);\n\n    public:\n      EAN13Reader();\n\n      int decodeMiddle(Ref<BitArray> row, int startGuardBegin, int startGuardEnd,\n          std::string& resultString);\n\n      BarcodeFormat getBarcodeFormat();\n    };\n  }\n}\n\n#endif\n\n// file: zxing/oned/EAN8Reader.h\n\n#ifndef __EAN_8_READER_H__\n// #define __EAN_8_READER_H__\n\n/*\n *  EAN8Reader.h\n *  ZXing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/oned/UPCEANReader.h>\n// #include <zxing/Result.h>\n\nnamespace zxing {\n  namespace oned {\n    class EAN8Reader : public UPCEANReader {\n\n    public:\n      EAN8Reader();\n\n      int decodeMiddle(Ref<BitArray> row, int startGuardBegin, int startGuardEnd,\n          std::string& resultString);\n\n      BarcodeFormat getBarcodeFormat();\n    };\n  }\n}\n\n#endif\n\n// file: zxing/oned/ITFReader.h\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n#ifndef __ITF_READER_H__\n// #define __ITF_READER_H__\n\n/*\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/oned/OneDReader.h>\n// #include <zxing/common/BitArray.h>\n// #include <zxing/Result.h>\n\nnamespace zxing {\n\tnamespace oned {\n\t\tclass ITFReader : public OneDReader {\n\n\t\tprivate:\n      enum {MAX_AVG_VARIANCE = (unsigned int) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 420/1000)};\n\t\t\tenum {MAX_INDIVIDUAL_VARIANCE = (int) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 800/1000)};\n\t\t\t// Stores the actual narrow line width of the image being decoded.\n\t\t\tint narrowLineWidth;\n\n\t\t\tint* decodeStart(Ref<BitArray> row);\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t//throws ReaderException\n\t\t\tint* decodeEnd(Ref<BitArray> row);\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t//throws ReaderException\n\t\t\tstatic void decodeMiddle(Ref<BitArray> row, int payloadStart, int payloadEnd, std::string& resultString);\t//throws ReaderException\n\t\t\tvoid validateQuietZone(Ref<BitArray> row, int startPattern);\t\t\t\t\t\t\t\t\t\t\t\t//throws ReaderException\n\t\t\tstatic int skipWhiteSpace(Ref<BitArray> row);\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t//throws ReaderException\n\n\t\t\tstatic int* findGuardPattern(Ref<BitArray> row, int rowOffset, const int pattern[], int patternLen);\t\t//throws ReaderException\n\t\t\tstatic int decodeDigit(int counters[], int countersLen);\t\t\t\t\t\t\t\t\t\t\t\t\t//throws ReaderException\n\n\t\t\tvoid append(char* s, char c);\n\t\tpublic:\n\t\t\tRef<Result> decodeRow(int rowNumber, Ref<BitArray> row);\t\t\t\t\t\t\t\t\t///throws ReaderException\n\t\t\tITFReader();\n\t\t\t~ITFReader();\n\t\t};\n\t}\n}\n\n#endif\n\n// file: zxing/oned/MultiFormatOneDReader.h\n\n#ifndef __MULTI_FORMAT_ONED_READER_H__\n// #define __MULTI_FORMAT_ONED_READER_H__\n/*\n *  MultiFormatOneDReader.h\n *  ZXing\n *\n  *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/oned/OneDReader.h>\n\nnamespace zxing {\n  namespace oned {\n    class MultiFormatOneDReader : public OneDReader {\n\n    private:\n      std::vector<Ref<OneDReader> > readers;\n    public:\n      MultiFormatOneDReader(DecodeHints hints);\n\n      Ref<Result> decodeRow(int rowNumber, Ref<BitArray> row);\n    };\n  }\n}\n\n#endif\n\n// file: zxing/oned/MultiFormatUPCEANReader.h\n\n#ifndef __MULTI_FORMAT_UPC_EAN_READER_H__\n// #define __MULTI_FORMAT_UPC_EAN_READER_H__\n/*\n *  MultiFormatUPCEANReader.h\n *  ZXing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/oned/OneDReader.h>\n\nnamespace zxing {\n  namespace oned {\n    class MultiFormatUPCEANReader : public OneDReader {\n\n    private:\n      std::vector<Ref<OneDReader> > readers;\n    public:\n      MultiFormatUPCEANReader(DecodeHints hints);\n\n      Ref<Result> decodeRow(int rowNumber, Ref<BitArray> row);\n    };\n  }\n}\n\n#endif\n\n// file: zxing/oned/OneDResultPoint.h\n\n#ifndef __ONED_RESULT_POINT_H__\n// #define __ONED_RESULT_POINT_H__\n/*\n *  OneDResultPoint.h\n *  ZXing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n// #include <zxing/ResultPoint.h>\n// #include <cmath>\n\nnamespace zxing {\n\tnamespace oned {\n\n\t\tclass OneDResultPoint : public ResultPoint {\n\n\t\tpublic:\n\t\t\tOneDResultPoint(float posX, float posY);\n\t\t};\n\t}\n}\n\n#endif\n\n// file: zxing/oned/UPCAReader.h\n\n#ifndef __UPCA_READER_H__\n// #define __UPCA_READER_H__\n/*\n *  UPCAReader.h\n *  ZXing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/oned/EAN13Reader.h>\n// #include <zxing/DecodeHints.h>\n\nnamespace zxing {\n  namespace oned {\n    class UPCAReader : public UPCEANReader {\n\n    private:\n      EAN13Reader ean13Reader;\n      static Ref<Result> maybeReturnResult(Ref<Result> result);\n\n    public:\n      UPCAReader();\n\n      int decodeMiddle(Ref<BitArray> row, int startGuardBegin, int startGuardEnd,\n          std::string& resultString);\n\n      Ref<Result> decodeRow(int rowNumber, Ref<BitArray> row);\n      Ref<Result> decodeRow(int rowNumber, Ref<BitArray> row, int startGuardBegin,\n          int startGuardEnd);\n      Ref<Result> decode(Ref<BinaryBitmap> image, DecodeHints hints);\n\n      BarcodeFormat getBarcodeFormat();\n    };\n  }\n}\n\n#endif\n\n// file: zxing/oned/UPCEReader.h\n\n#ifndef __UPC_E_READER_H__\n// #define __UPC_E_READER_H__\n\n/*\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/oned/UPCEANReader.h>\n// #include <zxing/Result.h>\n\nnamespace zxing {\n  namespace oned {\n    class UPCEReader : public UPCEANReader {\n\n    private:\n      static bool determineNumSysAndCheckDigit(std::string& resultString, int lgPatternFound);\n    protected:\n      bool decodeEnd(Ref<BitArray> row, int endStart, int* endGuardBegin, int* endGuardEnd);\n      bool checkChecksum(std::string s);\n    public:\n      UPCEReader();\n\n      int decodeMiddle(Ref<BitArray> row, int startGuardBegin, int startGuardEnd,\n          std::string& resultString);\n      static std::string convertUPCEtoUPCA(std::string upce);\n\n      BarcodeFormat getBarcodeFormat();\n    };\n  }\n}\n\n#endif\n\n// file: zxing/qrcode/ErrorCorrectionLevel.h\n\n#ifndef __ERROR_CORRECTION_LEVEL_H__\n// #define __ERROR_CORRECTION_LEVEL_H__\n\n/*\n *  ErrorCorrectionLevel.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/ReaderException.h>\n\nnamespace zxing {\nnamespace qrcode {\n\nclass ErrorCorrectionLevel {\nprivate:\n  int ordinal_;\n  int bits_;\n  std::string name_;\n  ErrorCorrectionLevel(int inOrdinal, int bits, char const* name);\n  static ErrorCorrectionLevel *FOR_BITS[];\n  static int N_LEVELS;\npublic:\n  static ErrorCorrectionLevel L;\n  static ErrorCorrectionLevel M;\n  static ErrorCorrectionLevel Q;\n  static ErrorCorrectionLevel H;\n\n  int ordinal() const;\n  int bits() const;\n  std::string const& name() const;\n  operator std::string const& () const;\n\n  static ErrorCorrectionLevel& forBits(int bits);\n};\n}\n}\n\n#endif // __ERROR_CORRECTION_LEVEL_H__\n\n// file: zxing/qrcode/FormatInformation.h\n\n#ifndef __FORMAT_INFORMATION_H__\n// #define __FORMAT_INFORMATION_H__\n\n/*\n *  FormatInformation.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/qrcode/ErrorCorrectionLevel.h>\n// #include <zxing/common/Counted.h>\n// #include <iostream>\n\nnamespace zxing {\nnamespace qrcode {\n\nclass FormatInformation : public Counted {\nprivate:\n  static int FORMAT_INFO_MASK_QR;\n  static int FORMAT_INFO_DECODE_LOOKUP[][2];\n  static int N_FORMAT_INFO_DECODE_LOOKUPS;\n  static int BITS_SET_IN_HALF_BYTE[];\n\n  ErrorCorrectionLevel &errorCorrectionLevel_;\n  unsigned char dataMask_;\n\n  FormatInformation(int formatInfo);\n\npublic:\n  static int numBitsDiffering(unsigned int a, unsigned int b);\n  static Ref<FormatInformation> decodeFormatInformation(int maskedFormatInfo1, int maskedFormatInfo2);\n  static Ref<FormatInformation> doDecodeFormatInformation(int maskedFormatInfo1, int maskedFormatInfo2);\n  ErrorCorrectionLevel &getErrorCorrectionLevel();\n  unsigned char getDataMask();\n  friend bool operator==(const FormatInformation &a, const FormatInformation &b);\n  friend std::ostream& operator<<(std::ostream& out, const FormatInformation& fi);\n};\n}\n}\n\n#endif // __FORMAT_INFORMATION_H__\n\n// file: zxing/qrcode/decoder/Decoder.h\n\n#ifndef __DECODER_H__\n// #define __DECODER_H__\n\n/*\n *  Decoder.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/common/reedsolomon/ReedSolomonDecoder.h>\n// #include <zxing/common/reedsolomon/GF256.h>\n// #include <zxing/common/Counted.h>\n// #include <zxing/common/Array.h>\n// #include <zxing/common/DecoderResult.h>\n// #include <zxing/common/BitMatrix.h>\n\nnamespace zxing {\nnamespace qrcode {\n\nclass Decoder {\nprivate:\n  ReedSolomonDecoder rsDecoder_;\n\n  void correctErrors(ArrayRef<unsigned char> bytes, int numDataCodewords);\n\npublic:\n  Decoder();\n  Ref<DecoderResult> decode(Ref<BitMatrix> bits);\n};\n\n}\n}\n\n#endif // __DECODER_H__\n\n// file: zxing/qrcode/QRCodeReader.h\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n#ifndef __QR_CODE_READER_H__\n// #define __QR_CODE_READER_H__\n\n/*\n *  QRCodeReader.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/Reader.h>\n// #include <zxing/qrcode/decoder/Decoder.h>\n// #include <zxing/DecodeHints.h>\n\nnamespace zxing {\n\tnamespace qrcode {\n\n\t\tclass QRCodeReader : public Reader {\n\t\tprivate:\n\t\t\tDecoder decoder_;\n\n    protected:\n      Decoder& getDecoder();\n\n\t\tpublic:\n\t\t\tQRCodeReader();\n\t\t\tvirtual Ref<Result> decode(Ref<BinaryBitmap> image, DecodeHints hints);\n\t\t\tvirtual ~QRCodeReader();\n\n\t\t};\n\t}\n}\n\n#endif // __QR_CODE_READER_H__\n\n// file: zxing/qrcode/Version.h\n\n#ifndef __VERSION_H__\n// #define __VERSION_H__\n\n/*\n *  Version.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/common/Counted.h>\n// #include <zxing/qrcode/ErrorCorrectionLevel.h>\n// #include <zxing/ReaderException.h>\n// #include <zxing/common/BitMatrix.h>\n// #include <zxing/common/Counted.h>\n// #include <vector>\n\nnamespace zxing {\nnamespace qrcode {\n\nclass ECB {\nprivate:\n  int count_;\n  int dataCodewords_;\npublic:\n  ECB(int count, int dataCodewords);\n  int getCount();\n  int getDataCodewords();\n};\n\nclass ECBlocks {\nprivate:\n  int ecCodewords_;\n  std::vector<ECB*> ecBlocks_;\npublic:\n  ECBlocks(int ecCodewords, ECB *ecBlocks);\n  ECBlocks(int ecCodewords, ECB *ecBlocks1, ECB *ecBlocks2);\n  int getECCodewords();\n  std::vector<ECB*>& getECBlocks();\n  ~ECBlocks();\n};\n\nclass Version : public Counted {\n\nprivate:\n  int versionNumber_;\n  std::vector<int> &alignmentPatternCenters_;\n  std::vector<ECBlocks*> ecBlocks_;\n  int totalCodewords_;\n  Version(int versionNumber, std::vector<int> *alignmentPatternCenters, ECBlocks *ecBlocks1, ECBlocks *ecBlocks2,\n          ECBlocks *ecBlocks3, ECBlocks *ecBlocks4);\n\npublic:\n  static unsigned int VERSION_DECODE_INFO[];\n  static int N_VERSION_DECODE_INFOS;\n  static std::vector<Ref<Version> > VERSIONS;\n\n  ~Version();\n  int getVersionNumber();\n  std::vector<int> &getAlignmentPatternCenters();\n  int getTotalCodewords();\n  int getDimensionForVersion();\n  ECBlocks &getECBlocksForLevel(ErrorCorrectionLevel &ecLevel);\n  static Version *getProvisionalVersionForDimension(int dimension);\n  static Version *getVersionForNumber(int versionNumber);\n  static Version *decodeVersionInformation(unsigned int versionBits);\n  Ref<BitMatrix> buildFunctionPattern();\n  static int buildVersions();\n};\n}\n}\n\n#endif // __VERSION_H__\n\n// file: zxing/qrcode/decoder/BitMatrixParser.h\n\n#ifndef __BIT_MATRIX_PARSER_H__\n// #define __BIT_MATRIX_PARSER_H__\n\n/*\n *  BitMatrixParser.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/ReaderException.h>\n// #include <zxing/common/BitMatrix.h>\n// #include <zxing/common/Counted.h>\n// #include <zxing/common/Array.h>\n// #include <zxing/qrcode/Version.h>\n// #include <zxing/qrcode/FormatInformation.h>\n\nnamespace zxing {\nnamespace qrcode {\n\nclass BitMatrixParser : public Counted {\nprivate:\n  Ref<BitMatrix> bitMatrix_;\n  Version *parsedVersion_;\n  Ref<FormatInformation> parsedFormatInfo_;\n\n  int copyBit(size_t x, size_t y, int versionBits);\n\npublic:\n  BitMatrixParser(Ref<BitMatrix> bitMatrix);\n  Ref<FormatInformation> readFormatInformation();\n  Version *readVersion();\n  ArrayRef<unsigned char> readCodewords();\n\nprivate:\n  BitMatrixParser(const BitMatrixParser&);\n  BitMatrixParser& operator =(const BitMatrixParser&);\n\n};\n\n}\n}\n\n#endif // __BIT_MATRIX_PARSER_H__\n\n// file: zxing/qrcode/decoder/DataBlock.h\n\n#ifndef __DATA_BLOCK_H__\n// #define __DATA_BLOCK_H__\n\n/*\n *  DataBlock.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <vector>\n// #include <zxing/common/Counted.h>\n// #include <zxing/common/Array.h>\n// #include <zxing/qrcode/Version.h>\n// #include <zxing/qrcode/ErrorCorrectionLevel.h>\n\nnamespace zxing {\nnamespace qrcode {\n\nclass DataBlock : public Counted {\nprivate:\n  int numDataCodewords_;\n  ArrayRef<unsigned char> codewords_;\n\n  DataBlock(int numDataCodewords, ArrayRef<unsigned char> codewords);\n\npublic:\n  static std::vector<Ref<DataBlock> >\n  getDataBlocks(ArrayRef<unsigned char> rawCodewords, Version *version, ErrorCorrectionLevel &ecLevel);\n\n  int getNumDataCodewords();\n  ArrayRef<unsigned char> getCodewords();\n};\n\n}\n}\n\n#endif // __DATA_BLOCK_H__\n\n// file: zxing/qrcode/decoder/DataMask.h\n\n#ifndef __DATA_MASK_H__\n// #define __DATA_MASK_H__\n\n/*\n *  DataMask.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/common/Array.h>\n// #include <zxing/common/Counted.h>\n// #include <zxing/common/BitMatrix.h>\n\n// #include <vector>\n\nnamespace zxing {\nnamespace qrcode {\n\nclass DataMask : public Counted {\nprivate:\n  static std::vector<Ref<DataMask> > DATA_MASKS;\n\nprotected:\n\npublic:\n  static int buildDataMasks();\n  DataMask();\n  virtual ~DataMask();\n  void unmaskBitMatrix(BitMatrix& matrix, size_t dimension);\n  virtual bool isMasked(size_t x, size_t y) = 0;\n  static DataMask& forReference(int reference);\n};\n\n}\n}\n\n#endif // __DATA_MASK_H__\n\n// file: zxing/qrcode/decoder/Mode.h\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n#ifndef __MODE_H__\n// #define __MODE_H__\n\n/*\n *  Mode.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/common/Counted.h>\n// #include <zxing/qrcode/Version.h>\n\nnamespace zxing {\nnamespace qrcode {\n\nclass Mode {\nprivate:\n  int characterCountBitsForVersions0To9_;\n  int characterCountBitsForVersions10To26_;\n  int characterCountBitsForVersions27AndHigher_;\n  int bits_;\n  std::string name_;\n\n  Mode(int cbv0_9, int cbv10_26, int cbv27, int bits, char const* name);\n\npublic:\n  static Mode TERMINATOR;\n  static Mode NUMERIC;\n  static Mode ALPHANUMERIC;\n  static Mode STRUCTURED_APPEND;\n  static Mode BYTE;\n  static Mode ECI;\n  static Mode KANJI;\n  static Mode FNC1_FIRST_POSITION;\n  static Mode FNC1_SECOND_POSITION;\n  static Mode HANZI;\n\n  static Mode& forBits(int bits);\n  int getCharacterCountBits(Version *version);\n};\n}\n}\n\n#endif // __MODE_H__\n\n// file: zxing/common/ECI.h\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n\n#ifndef __ECI__\n#define __ECI__\n\n/*\n * Copyright 2008-2011 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nnamespace zxing {\n  namespace common {\n    class ECI;\n  }\n}\nclass zxing::common::ECI {\nprivate:\n  const int value;\n\nprotected:\n  ECI(int value);\n\npublic:\n  int getValue() const;\n\n  static ECI* getECIByValue(int value);\n};\n\n#endif\n\n// file: zxing/common/CharacterSetECI.h\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n\n#ifndef __CHARACTERSET_ECI__\n#define __CHARACTERSET_ECI__\n\n/*\n * Copyright 2008-2011 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <map>\n// #include <zxing/common/ECI.h>\n// #include <zxing/DecodeHints.h>\n\nnamespace zxing {\n  namespace common {\n    class CharacterSetECI;\n  }\n}\n\nclass zxing::common::CharacterSetECI : public ECI {\nprivate:\n  static std::map<int, CharacterSetECI*> VALUE_TO_ECI;\n  static std::map<std::string, CharacterSetECI*> NAME_TO_ECI;\n  static const bool inited;\n  static bool init_tables();\n\n  char const* const encodingName;\n\n  CharacterSetECI(int value, char const* encodingName);\n\n  static void addCharacterSet(int value, char const* encodingName);\n  static void addCharacterSet(int value, char const* const* encodingNames);\n\npublic:\n  char const* getEncodingName();\n\n  static CharacterSetECI* getCharacterSetECIByValue(int value);\n  static CharacterSetECI* getCharacterSetECIByName(std::string const& name);\n};\n\n#endif\n\n// file: zxing/qrcode/decoder/DecodedBitStreamParser.h\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n\n#ifndef __DECODED_BIT_STREAM_PARSER_H__\n// #define __DECODED_BIT_STREAM_PARSER_H__\n\n/*\n *  DecodedBitStreamParser.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <string>\n// #include <sstream>\n// #include <map>\n// #include <zxing/qrcode/decoder/Mode.h>\n// #include <zxing/common/BitSource.h>\n// #include <zxing/common/Counted.h>\n// #include <zxing/common/Array.h>\n// #include <zxing/common/DecoderResult.h>\n// #include <zxing/common/CharacterSetECI.h>\n// #include <zxing/DecodeHints.h>\n\nnamespace zxing {\nnamespace qrcode {\n\nclass DecodedBitStreamParser {\npublic:\n  typedef std::map<DecodeHintType, std::string> Hashtable;\n\nprivate:\n  static char const ALPHANUMERIC_CHARS[];\n  static char toAlphaNumericChar(size_t value);\n\n  static void decodeHanziSegment(Ref<BitSource> bits, std::string &result, int count);\n  static void decodeKanjiSegment(Ref<BitSource> bits, std::string &result, int count);\n  static void decodeByteSegment(Ref<BitSource> bits, std::string &result, int count);\n  static void decodeByteSegment(Ref<BitSource> bits_,\n                                std::string& result,\n                                int count,\n                                zxing::common::CharacterSetECI* currentCharacterSetECI,\n                                ArrayRef< ArrayRef<unsigned char> >& byteSegments,\n                                Hashtable const& hints);\n  static void decodeAlphanumericSegment(Ref<BitSource> bits, std::string &result, int count, bool fc1InEffect);\n  static void decodeNumericSegment(Ref<BitSource> bits, std::string &result, int count);\n\n  static void append(std::string &ost, const unsigned char *bufIn, size_t nIn, const char *src);\n  static void append(std::string &ost, std::string const& in, const char *src);\n\npublic:\n  static Ref<DecoderResult> decode(ArrayRef<unsigned char> bytes,\n                                   Version *version,\n                                   ErrorCorrectionLevel const& ecLevel,\n                                   Hashtable const& hints);\n};\n\n}\n}\n\n#endif // __DECODED_BIT_STREAM_PARSER_H__\n\n// file: zxing/qrcode/detector/AlignmentPattern.h\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n\n#ifndef __ALIGNMENT_PATTERN_H__\n// #define __ALIGNMENT_PATTERN_H__\n\n/*\n *  AlignmentPattern.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/ResultPoint.h>\n// #include <cmath>\n\nnamespace zxing {\n\tnamespace qrcode {\n\n\t\tclass AlignmentPattern : public ResultPoint {\n\t\tprivate:\n\t\t\tfloat estimatedModuleSize_;\n\n\t\tpublic:\n\t\t\tAlignmentPattern(float posX, float posY, float estimatedModuleSize);\n\t\t\tbool aboutEquals(float moduleSize, float i, float j) const;\n      Ref<AlignmentPattern> combineEstimate(float i, float j,\n                                            float newModuleSize) const;\n\t\t};\n\n\t}\n}\n\n#endif // __ALIGNMENT_PATTERN_H__\n\n// file: zxing/qrcode/detector/AlignmentPatternFinder.h\n\n#ifndef __ALIGNMENT_PATTERN_FINDER_H__\n// #define __ALIGNMENT_PATTERN_FINDER_H__\n\n/*\n *  AlignmentPatternFinder.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include \"AlignmentPattern.h\"\n// #include <zxing/common/Counted.h>\n// #include <zxing/common/BitMatrix.h>\n// #include <zxing/ResultPointCallback.h>\n// #include <vector>\n\nnamespace zxing {\nnamespace qrcode {\n\nclass AlignmentPatternFinder : public Counted {\nprivate:\n  static int CENTER_QUORUM;\n  static int MIN_SKIP;\n  static int MAX_MODULES;\n\n  Ref<BitMatrix> image_;\n  std::vector<AlignmentPattern *> *possibleCenters_;\n  size_t startX_;\n  size_t startY_;\n  size_t width_;\n  size_t height_;\n  float moduleSize_;\n\n  static float centerFromEnd(std::vector<int> &stateCount, int end);\n  bool foundPatternCross(std::vector<int> &stateCount);\n\n  float crossCheckVertical(size_t startI, size_t centerJ, int maxCount, int originalStateCountTotal);\n\n  Ref<AlignmentPattern> handlePossibleCenter(std::vector<int> &stateCount, size_t i, size_t j);\n\npublic:\n  AlignmentPatternFinder(Ref<BitMatrix> image, size_t startX, size_t startY, size_t width, size_t height,\n                         float moduleSize, Ref<ResultPointCallback>const& callback);\n  ~AlignmentPatternFinder();\n  Ref<AlignmentPattern> find();\n\nprivate:\n  AlignmentPatternFinder(const AlignmentPatternFinder&);\n  AlignmentPatternFinder& operator =(const AlignmentPatternFinder&);\n\n  Ref<ResultPointCallback> callback_;\n};\n}\n}\n\n#endif // __ALIGNMENT_PATTERN_FINDER_H__\n\n// file: zxing/qrcode/detector/FinderPattern.h\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n#ifndef __FINDER_PATTERN_H__\n// #define __FINDER_PATTERN_H__\n\n/*\n *  FinderPattern.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/ResultPoint.h>\n// #include <cmath>\n\nnamespace zxing {\n\tnamespace qrcode {\n\n\t\tclass FinderPattern : public ResultPoint {\n\t\tprivate:\n\t\t\tfloat estimatedModuleSize_;\n\t\t\tint count_;\n\n\t\tpublic:\n\t\t\tFinderPattern(float posX, float posY, float estimatedModuleSize);\n\t\t\tFinderPattern(float posX, float posY, float estimatedModuleSize, int count);\n\t\t\tint getCount() const;\n\t\t\tfloat getEstimatedModuleSize() const;\n\t\t\tvoid incrementCount();\n\t\t\tbool aboutEquals(float moduleSize, float i, float j) const;\n\t\t\tRef<FinderPattern> combineEstimate(float i, float j, float newModuleSize) const;\n\t\t};\n\t}\n}\n\n#endif // __FINDER_PATTERN_H__\n\n// file: zxing/qrcode/detector/FinderPatternInfo.h\n\n#ifndef __FINDER_PATTERN_INFO_H__\n// #define __FINDER_PATTERN_INFO_H__\n\n/*\n *  FinderPatternInfo.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/qrcode/detector/FinderPattern.h>\n// #include <zxing/common/Counted.h>\n// #include <zxing/common/Array.h>\n// #include <vector>\n\nnamespace zxing {\nnamespace qrcode {\n\nclass FinderPatternInfo : public Counted {\nprivate:\n  Ref<FinderPattern> bottomLeft_;\n  Ref<FinderPattern> topLeft_;\n  Ref<FinderPattern> topRight_;\n\npublic:\n  FinderPatternInfo(std::vector<Ref<FinderPattern> > patternCenters);\n\n  Ref<FinderPattern> getBottomLeft();\n  Ref<FinderPattern> getTopLeft();\n  Ref<FinderPattern> getTopRight();\n};\n}\n}\n\n#endif // __FINDER_PATTERN_INFO_H__\n\n// file: zxing/qrcode/detector/Detector.h\n\n#ifndef __DETECTOR_H__\n// #define __DETECTOR_H__\n\n/*\n *  Detector.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/common/Counted.h>\n// #include <zxing/common/DetectorResult.h>\n// #include <zxing/common/BitMatrix.h>\n// #include <zxing/qrcode/detector/AlignmentPattern.h>\n// #include <zxing/common/PerspectiveTransform.h>\n// #include <zxing/ResultPointCallback.h>\n// #include <zxing/qrcode/detector/FinderPatternInfo.h>\n\nnamespace zxing {\n\nclass DecodeHints;\n\nnamespace qrcode {\n\nclass Detector : public Counted {\nprivate:\n  Ref<BitMatrix> image_;\n  Ref<ResultPointCallback> callback_;\n\nprotected:\n  Ref<BitMatrix> getImage();\n\n  static Ref<BitMatrix> sampleGrid(Ref<BitMatrix> image, int dimension, Ref<PerspectiveTransform>);\n  static int computeDimension(Ref<ResultPoint> topLeft, Ref<ResultPoint> topRight, Ref<ResultPoint> bottomLeft,\n                              float moduleSize);\n  float calculateModuleSize(Ref<ResultPoint> topLeft, Ref<ResultPoint> topRight, Ref<ResultPoint> bottomLeft);\n  float calculateModuleSizeOneWay(Ref<ResultPoint> pattern, Ref<ResultPoint> otherPattern);\n  float sizeOfBlackWhiteBlackRunBothWays(int fromX, int fromY, int toX, int toY);\n  float sizeOfBlackWhiteBlackRun(int fromX, int fromY, int toX, int toY);\n  Ref<AlignmentPattern> findAlignmentInRegion(float overallEstModuleSize, int estAlignmentX, int estAlignmentY,\n      float allowanceFactor);\n  Ref<DetectorResult> processFinderPatternInfo(Ref<FinderPatternInfo> info);\npublic:\n\n  virtual Ref<PerspectiveTransform> createTransform(Ref<ResultPoint> topLeft, Ref<ResultPoint> topRight, Ref <\n      ResultPoint > bottomLeft, Ref<ResultPoint> alignmentPattern, int dimension);\n\n  Detector(Ref<BitMatrix> image);\n  Ref<DetectorResult> detect(DecodeHints const& hints);\n};\n}\n}\n\n#endif // __DETECTOR_H__\n\n// file: zxing/qrcode/detector/FinderPatternFinder.h\n\n#ifndef __FINDER_PATTERN_FINDER_H__\n// #define __FINDER_PATTERN_FINDER_H__\n\n/*\n *  FinderPatternFinder.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/qrcode/detector/FinderPattern.h>\n// #include <zxing/qrcode/detector/FinderPatternInfo.h>\n// #include <zxing/common/Counted.h>\n// #include <zxing/common/BitMatrix.h>\n// #include <zxing/ResultPointCallback.h>\n// #include <vector>\n\nnamespace zxing {\n\nclass DecodeHints;\n\nnamespace qrcode {\n\nclass FinderPatternFinder {\nprivate:\n  static int CENTER_QUORUM;\n\nprotected:\n  static int MIN_SKIP;\n  static int MAX_MODULES;\n\n  Ref<BitMatrix> image_;\n  std::vector<Ref<FinderPattern> > possibleCenters_;\n  bool hasSkipped_;\n\n  Ref<ResultPointCallback> callback_;\n\n  /** stateCount must be int[5] */\n  static float centerFromEnd(int* stateCount, int end);\n  static bool foundPatternCross(int* stateCount);\n\n  float crossCheckVertical(size_t startI, size_t centerJ, int maxCount, int originalStateCountTotal);\n  float crossCheckHorizontal(size_t startJ, size_t centerI, int maxCount, int originalStateCountTotal);\n\n  /** stateCount must be int[5] */\n  bool handlePossibleCenter(int* stateCount, size_t i, size_t j);\n  int findRowSkip();\n  bool haveMultiplyConfirmedCenters();\n  std::vector<Ref<FinderPattern> > selectBestPatterns();\n  static std::vector<Ref<FinderPattern> > orderBestPatterns(std::vector<Ref<FinderPattern> > patterns);\npublic:\n  static float distance(Ref<ResultPoint> p1, Ref<ResultPoint> p2);\n  FinderPatternFinder(Ref<BitMatrix> image, Ref<ResultPointCallback>const&);\n  Ref<FinderPatternInfo> find(DecodeHints const& hints);\n};\n}\n}\n\n#endif // __FINDER_PATTERN_FINDER_H__\n\n// file: zxing/qrcode/detector/QREdgeDetector.h\n\n#ifndef __QREDGEDETECTOR_H__\n// #define __QREDGEDETECTOR_H__\n/*\n *  QREdgeDetector.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\n\n// #include <zxing/qrcode/detector/Detector.h>\n// #include <zxing/common/Point.h>\n\nnamespace zxing {\nnamespace qrcode {\n\nclass QREdgeDetector : public Detector {\npublic:\n  QREdgeDetector(Ref<BitMatrix> image);\n\n  virtual Ref<PerspectiveTransform> createTransform(Ref<ResultPoint> topLeft, Ref<ResultPoint> topRight, Ref <\n      ResultPoint > bottomLeft, Ref<ResultPoint> alignmentPattern, int dimension);\n\nprivate:\n  Point findCorner(const BitMatrix& image, Point topLeft, Point topRight, Point bottomLeft, int dimension);\n  Line findPatternEdge(const BitMatrix& image, Point pattern, Point opposite, Point direction, bool invert);\n\n  Point endOfReverseBlackWhiteBlackRun(const BitMatrix& image, Point from, Point to);\n\n  Ref<PerspectiveTransform> get1CornerTransform(Point topLeft, Point topRight, Point bottomLeft, Point corner, int dimension);\n};\n\n}\n}\n#endif // QREDGEDETECTOR_H_\n\n// file: zxing/FormatException.h\n\n#ifndef __FORMAT_EXCEPTION_H__\n// #define __FORMAT_EXCEPTION_H__\n\n/*\n *  FormatException.h\n *  zxing\n *\n *  Copyright 2010 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/ReaderException.h>\n\nnamespace zxing {\n\nclass FormatException : public ReaderException {\npublic:\n  FormatException();\n  FormatException(const char *msg);\n  ~FormatException() throw();\n};\n\n}\n#endif // __FORMAT_EXCEPTION_H__\n\n// file: zxing/NotFoundException.h\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n\n#ifndef __NOT_FOUND_EXCEPTION_H__\n// #define __NOT_FOUND_EXCEPTION_H__\n\n/*\n * Copyright 20011 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/ReaderException.h>\n\nnamespace zxing {\n\n  class NotFoundException : public ReaderException {\n  public:\n    NotFoundException(const char *msg);\n    ~NotFoundException() throw();\n  };\n\n}\n#endif // __NOT_FOUND_EXCEPTION_H__\n\n// file: zxing/common/StringUtils.h\n\n// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-\n\n#ifndef __STRING_UTILS__\n#define __STRING_UTILS__\n\n/*\n * Copyright (C) 2010-2011 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <string>\n// #include <map>\n// #include <zxing/DecodeHints.h>\n\nnamespace zxing {\n  namespace common {\n    class StringUtils;\n  }\n}\n\nclass zxing::common::StringUtils {\nprivate:\n  static char const* const PLATFORM_DEFAULT_ENCODING;\n\n  StringUtils() {}\n\npublic:\n  static char const* const ASCII;\n  static char const* const SHIFT_JIS;\n  static char const* const GB2312;\n  static char const* const EUC_JP;\n  static char const* const UTF8;\n  static char const* const ISO88591;\n  static const bool ASSUME_SHIFT_JIS;\n\n  typedef std::map<DecodeHintType, std::string> Hashtable;\n\n  static std::string guessEncoding(unsigned char* bytes, int length, Hashtable const& hints);\n};\n\n#endif\n\n// file: zxing/common/detector/MonochromeRectangleDetector.h\n\n#ifndef __MONOCHROMERECTANGLEDETECTOR_H__\n// #define __MONOCHROMERECTANGLEDETECTOR_H__\n\n/*\n *  MonochromeRectangleDetector.h\n *  y_wmk\n *\n *  Created by Luiz Silva on 09/02/2010.\n *  Copyright 2010 y_wmk authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <vector>\n// #include <zxing/NotFoundException.h>\n// #include <zxing/ResultPoint.h>\n// #include <zxing/common/BitMatrix.h>\n// #include <zxing/common/Counted.h>\n// #include <zxing/ResultPoint.h>\n\n\nnamespace zxing {\n\nstruct TwoInts: public Counted {\n\tint start;\n\tint end;\n};\n\nclass MonochromeRectangleDetector : public Counted {\nprivate:\n  static const int MAX_MODULES = 32;\n  Ref<BitMatrix> image_;\n\npublic:\n  MonochromeRectangleDetector(Ref<BitMatrix> image) : image_(image) {  };\n\n  std::vector<Ref<ResultPoint> > detect();\n\nprivate:\n  Ref<ResultPoint> findCornerFromCenter(int centerX, int deltaX, int left, int right,\n      int centerY, int deltaY, int top, int bottom, int maxWhiteRun);\n\n  Ref<TwoInts> blackWhiteRange(int fixedDimension, int maxWhiteRun, int minDim, int maxDim,\n      bool horizontal);\n\n  int max(int a, float b) { return (float) a > b ? a : (int) b;};\n};\n}\n\n#endif // __MONOCHROMERECTANGLEDETECTOR_H__\n\n// file: zxing/common/detector/WhiteRectangleDetector.h\n\n#ifndef __WHITERECTANGLEDETECTOR_H__\n// #define __WHITERECTANGLEDETECTOR_H__\n\n/*\n *  WhiteRectangleDetector.h\n *\n *\n *  Created by Luiz Silva on 09/02/2010.\n *  Copyright 2010  authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <vector>\n// #include <zxing/ReaderException.h>\n// #include <zxing/ResultPoint.h>\n// #include <zxing/common/BitMatrix.h>\n// #include <zxing/common/Counted.h>\n// #include <zxing/ResultPoint.h>\n\n\nnamespace zxing {\n\nclass WhiteRectangleDetector : public Counted {\n  private:\n    static int INIT_SIZE;\n    static int CORR;\n    Ref<BitMatrix> image_;\n    int width_;\n    int height_;\n\n  public:\n    WhiteRectangleDetector(Ref<BitMatrix> image);\n    std::vector<Ref<ResultPoint> > detect();\n\n  private:\n    int round(float a);\n    Ref<ResultPoint> getBlackPointOnSegment(float aX, float aY, float bX, float bY);\n    int distanceL2(float aX, float aY, float bX, float bY);\n    std::vector<Ref<ResultPoint> > centerEdges(Ref<ResultPoint> y, Ref<ResultPoint> z,\n                                    Ref<ResultPoint> x, Ref<ResultPoint> t);\n    bool containsBlackPoint(int a, int b, int fixed, bool horizontal);\n};\n}\n\n#endif\n\n// file: zxing/datamatrix/detector/DetectorException.h\n\n/*\n * DetectorException.h\n *\n *  Created on: Aug 26, 2011\n *      Author: luiz\n */\n\n#ifndef DETECTOREXCEPTION_H_\n#define DETECTOREXCEPTION_H_\n\n// #include <zxing/Exception.h>\n\nnamespace zxing {\nnamespace datamatrix {\n\nclass DetectorException : public Exception {\n  public:\n    DetectorException(const char *msg);\n    virtual ~DetectorException() throw();\n};\n} /* namespace nexxera */\n} /* namespace zxing */\n#endif /* DETECTOREXCEPTION_H_ */\n\n// file: zxing/multi/ByQuadrantReader.h\n\n#ifndef __BY_QUADRANT_READER_H__\n// #define __BY_QUADRANT_READER_H__\n\n/*\n *  Copyright 2011 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/Reader.h>\n// #include <zxing/BinaryBitmap.h>\n// #include <zxing/Result.h>\n// #include <zxing/DecodeHints.h>\n\nnamespace zxing {\nnamespace multi {\nclass ByQuadrantReader : public Reader {\n  private:\n    Reader& delegate_;\n\n  public:\n    ByQuadrantReader(Reader& delegate);\n    virtual ~ByQuadrantReader();\n    virtual Ref<Result> decode(Ref<BinaryBitmap> image);\n    virtual Ref<Result> decode(Ref<BinaryBitmap> image, DecodeHints hints);\n};\n} // End zxing::multi namespace\n} // End zxing namespace\n\n#endif // __BY_QUADRANT_READER_H__\n\n// file: zxing/multi/MultipleBarcodeReader.h\n\n#ifndef __MULTIPLE_BARCODE_READER_H__\n// #define __MULTIPLE_BARCODE_READER_H__\n\n/*\n *  Copyright 2011 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/common/Counted.h>\n// #include <zxing/Result.h>\n// #include <zxing/BinaryBitmap.h>\n// #include <zxing/DecodeHints.h>\n// #include <vector>\n\nnamespace zxing {\nnamespace multi {\nclass MultipleBarcodeReader : public Counted {\n  protected:\n    MultipleBarcodeReader() {}\n  public:\n    virtual std::vector<Ref<Result> > decodeMultiple(Ref<BinaryBitmap> image);\n    virtual std::vector<Ref<Result> > decodeMultiple(Ref<BinaryBitmap> image, DecodeHints hints) = 0;\n    virtual ~MultipleBarcodeReader();\n};\n} // End zxing::multi namespace\n} // End zxing namespace\n\n#endif // __MULTIPLE_BARCODE_READER_H__\n\n// file: zxing/multi/GenericMultipleBarcodeReader.h\n\n#ifndef __GENERIC_MULTIPLE_BARCODE_READER_H__\n// #define __GENERIC_MULTIPLE_BARCODE_READER_H__\n\n/*\n *  Copyright 2011 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/multi/MultipleBarcodeReader.h>\n// #include <zxing/Reader.h>\n\nnamespace zxing {\nnamespace multi {\nclass GenericMultipleBarcodeReader : public MultipleBarcodeReader {\n  private:\n    static Ref<Result> translateResultPoints(Ref<Result> result,\n                                             int xOffset,\n                                             int yOffset);\n    void doDecodeMultiple(Ref<BinaryBitmap> image,\n                          DecodeHints hints,\n                          std::vector<Ref<Result> >& results,\n                          int xOffset,\n                          int yOffset);\n    Reader& delegate_;\n    static const int MIN_DIMENSION_TO_RECUR = 100;\n\n  public:\n    GenericMultipleBarcodeReader(Reader& delegate);\n    virtual ~GenericMultipleBarcodeReader();\n    virtual std::vector<Ref<Result> > decodeMultiple(Ref<BinaryBitmap> image,\n                                                     DecodeHints hints);\n};\n} // End zxing::multi namespace\n} // End zxing namespace\n\n#endif // __GENERIC_MULTIPLE_BARCODE_READER_H__\n\n// file: zxing/multi/qrcode/QRCodeMultiReader.h\n\n#ifndef __QRCODE_MULTI_READER_H__\n// #define __QRCODE_MULTI_READER_H__\n\n/*\n *  Copyright 2011 ZXing authors All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/multi/MultipleBarcodeReader.h>\n// #include <zxing/qrcode/QRCodeReader.h>\n\nnamespace zxing {\nnamespace multi {\nclass QRCodeMultiReader: public zxing::qrcode::QRCodeReader, public MultipleBarcodeReader {\n  public:\n    QRCodeMultiReader();\n    virtual ~QRCodeMultiReader();\n    virtual std::vector<Ref<Result> > decodeMultiple(Ref<BinaryBitmap> image, DecodeHints hints);\n};\n} // End zxing::multi namespace\n} // End zxing namespace\n\n#endif // __QRCODE_MULTI_READER_H__\n\n// file: zxing/multi/qrcode/detector/MultiDetector.h\n\n#ifndef __MULTI_DETECTOR_H__\n// #define __MULTI_DETECTOR_H__\n\n/*\n *  Copyright 2011 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/qrcode/detector/Detector.h>\n// #include <zxing/common/DetectorResult.h>\n// #include <zxing/DecodeHints.h>\n\nnamespace zxing {\nnamespace multi {\nclass MultiDetector : public zxing::qrcode::Detector {\n  public:\n    MultiDetector(Ref<BitMatrix> image);\n    virtual ~MultiDetector();\n    virtual std::vector<Ref<DetectorResult> > detectMulti(DecodeHints hints);\n};\n} // End zxing::multi namespace\n} // End zxing namespace\n\n#endif // __MULTI_DETECTOR_H__\n\n// file: zxing/multi/qrcode/detector/MultiFinderPatternFinder.h\n\n#ifndef __MULTI_FINDER_PATTERN_FINDER_H__\n// #define __MULTI_FINDER_PATTERN_FINDER_H__\n\n/*\n *  Copyright 2011 ZXing authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// #include <zxing/qrcode/detector/FinderPattern.h>\n// #include <zxing/qrcode/detector/FinderPatternFinder.h>\n// #include <zxing/qrcode/detector/FinderPatternInfo.h>\n\nnamespace zxing {\nnamespace multi {\nclass MultiFinderPatternFinder : zxing::qrcode::FinderPatternFinder {\n  private:\n    std::vector<std::vector<Ref<zxing::qrcode::FinderPattern> > > selectBestPatterns();\n\n    static const float MAX_MODULE_COUNT_PER_EDGE;\n    static const float MIN_MODULE_COUNT_PER_EDGE;\n    static const float DIFF_MODSIZE_CUTOFF_PERCENT;\n    static const float DIFF_MODSIZE_CUTOFF;\n\n  public:\n    MultiFinderPatternFinder(Ref<BitMatrix> image, Ref<ResultPointCallback> resultPointCallback);\n    virtual ~MultiFinderPatternFinder();\n    virtual std::vector<Ref<zxing::qrcode::FinderPatternInfo> > findMulti(DecodeHints const& hints);\n\n\n};\n}\n}\n\n#endif // __MULTI_FINDER_PATTERN_FINDER_H__\n\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/windows/BarcodeScannerProxy.js",
    "content": "/*\n * Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.\n *\n * 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\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * 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.\n */\n\nmodule.exports = {\n\n    /**\n     * Scans image via device camera and retieves barcode from it.\n     * @param  {function} success Success callback\n     * @param  {function} fail    Error callback\n     * @param  {array} args       Arguments array\n     */\n    scan: function (success, fail, args) {\n\n        var capturePreview,\n            capturePreviewAlignmentMark,\n            captureCancelButton,\n            capture,\n            reader;\n        \n        /**\n         * Creates a preview frame and necessary objects\n         */\n        function createPreview() {\n\n            // Create fullscreen preview\n            capturePreview = document.createElement(\"video\");\n            capturePreview.style.cssText = \"position: absolute; left: 0; top: 0; width: 100%; height: 100%; background: black\";\n\n            capturePreviewAlignmentMark = document.createElement('div');\n            capturePreviewAlignmentMark.style.cssText = \"position: absolute; left: 0; top: 50%; width: 100%; height: 3px; background: red\";\n\n            // Create cancel button\n            captureCancelButton = document.createElement(\"button\");\n            captureCancelButton.innerText = \"Cancel\";\n            captureCancelButton.style.cssText = \"position: absolute; right: 0; bottom: 0; display: block; margin: 20px\";\n            captureCancelButton.addEventListener('click', cancelPreview, false);\n\n            capture = new Windows.Media.Capture.MediaCapture();\n        }\n\n        /**\n         * Starts stream transmission to preview frame and then run barcode search\n         */\n        function startPreview() {\n            var captureSettings = new Windows.Media.Capture.MediaCaptureInitializationSettings();\n            captureSettings.streamingCaptureMode = Windows.Media.Capture.StreamingCaptureMode.video;\n            captureSettings.photoCaptureSource = Windows.Media.Capture.PhotoCaptureSource.videoPreview;\n\n            capture.initializeAsync(captureSettings).done(function () {\n\n                //trying to set focus mode\n                var controller = capture.videoDeviceController;\n\n                if (controller.focusControl && controller.focusControl.supported) {\n                    if (controller.focusControl.configure) {\n                        var focusConfig = new Windows.Media.Devices.FocusSettings();\n                        focusConfig.autoFocusRange = Windows.Media.Devices.AutoFocusRange.macro;\n\n                        var supportContinuousFocus = controller.focusControl.supportedFocusModes.indexOf(Windows.Media.Devices.FocusMode.continuous).returnValue;\n                        var supportAutoFocus = controller.focusControl.supportedFocusModes.indexOf(Windows.Media.Devices.FocusMode.auto).returnValue;\n\n                        if (supportContinuousFocus) {\n                            focusConfig.mode = Windows.Media.Devices.FocusMode.continuous;\n                        } else if (supportAutoFocus) {                        \n                            focusConfig.mode = Windows.Media.Devices.FocusMode.auto;\n                        }\n\n                        controller.focusControl.configure(focusConfig);\n                        controller.focusControl.focusAsync();\n                    }\n                }\n\n                var deviceProps = controller.getAvailableMediaStreamProperties(Windows.Media.Capture.MediaStreamType.videoRecord);\n\n                deviceProps = Array.prototype.slice.call(deviceProps);\n                deviceProps = deviceProps.filter(function (prop) {\n                    // filter out streams with \"unknown\" subtype - causes errors on some devices\n                    return prop.subtype !== \"Unknown\";\n                }).sort(function (propA, propB) {\n                    // sort properties by resolution\n                    return propB.width - propA.width;\n                });\n\n                var maxResProps = deviceProps[0];\n\n                controller.setMediaStreamPropertiesAsync(Windows.Media.Capture.MediaStreamType.videoRecord, maxResProps).done(function () {\n                    // handle portrait orientation\n                    if (Windows.Graphics.Display.DisplayProperties.nativeOrientation == Windows.Graphics.Display.DisplayOrientations.portrait) {\n                        capture.setPreviewRotation(Windows.Media.Capture.VideoRotation.clockwise90Degrees);\n                        capturePreview.msZoom = true;\n                    }\n\n                    capturePreview.src = URL.createObjectURL(capture);\n                    capturePreview.play();\n\n                    // Insert preview frame and controls into page\n                    document.body.appendChild(capturePreview);\n                    document.body.appendChild(capturePreviewAlignmentMark);\n                    document.body.appendChild(captureCancelButton);\n\n                    startBarcodeSearch(maxResProps.width, maxResProps.height);\n                });\n            });\n        }\n\n        /**\n         * Starts barcode search process, implemented in WinRTBarcodeReader.winmd library\n         * Calls success callback, when barcode found.\n         */\n        function startBarcodeSearch(width, height) {\n\n            reader = new WinRTBarcodeReader.Reader();\n            reader.init(capture, width, height);\n            reader.readCode().done(function (result) {\n                destroyPreview();\n                success({ text: result && result.text, format: result && result.barcodeFormat, cancelled: !result });\n            }, function (err) {\n                destroyPreview();\n                fail(err);\n            });\n        }\n\n        /**\n         * Removes preview frame and corresponding objects from window\n         */\n        function destroyPreview() {\n\n            capturePreview.pause();\n            capturePreview.src = null;\n\n            [capturePreview, capturePreviewAlignmentMark, captureCancelButton].forEach(function (elem) {\n                elem && document.body.removeChild(elem);\n            });\n            \n            reader && reader.stop();\n            reader = null;\n\n            capture && capture.stopRecordAsync();\n            capture = null;\n        }\n\n        /**\n         * Stops preview and then call success callback with cancelled=true\n         * See https://github.com/phonegap-build/BarcodeScanner#using-the-plugin\n         */\n        function cancelPreview() {\n            reader && reader.stop();\n        }\n        \n        try {\n            createPreview();\n            startPreview();\n        } catch (ex) {\n            fail(ex);\n        }\n    },\n\n    /**\n     * Encodes specified data into barcode\n     * @param  {function} success Success callback\n     * @param  {function} fail    Error callback\n     * @param  {array} args       Arguments array\n     */\n    encode: function (success, fail, args) {\n        fail(\"Not implemented yet\");\n    }\n};\n\nrequire(\"cordova/exec/proxy\").add(\"BarcodeScanner\", module.exports);\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/windows/lib/Properties/AssemblyInfo.cs",
    "content": "﻿/*\n * Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.\n *\n * 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\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * 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.\n */\n\nusing System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"WinRTBarcodeReader\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"WinRTBarcodeReader\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2014\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version \n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers \n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n[assembly: ComVisible(false)]"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/windows/lib/Reader.cs",
    "content": "﻿/*\n * Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.\n *\n * 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\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * 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.\n */\n\nnamespace WinRTBarcodeReader\n{\n    using System;\n    using System.Threading;\n    using System.Threading.Tasks;\n\n    using Windows.Foundation;\n    using Windows.Graphics.Imaging;\n    using Windows.Media.Capture;\n    using Windows.Media.MediaProperties;\n    using Windows.Storage.Streams;\n\n    using ZXing;\n\n    /// <summary>\n    /// Defines the Reader type, that perform barcode search asynchronously.\n    /// </summary>\n    public sealed class Reader\n    {\n        #region Private fields\n\n        /// <summary>\n        ///     Data reader, used to create bitmap array.\n        /// </summary>\n        private BarcodeReader barcodeReader;\n\n        /// <summary>\n        ///     The cancel search flag.\n        /// </summary>\n        private CancellationTokenSource cancelSearch;\n\n        /// <summary>\n        ///     MediaCapture instance, used for barcode search.\n        /// </summary>\n        private MediaCapture capture;\n\n        /// <summary>\n        ///     Encoding properties for mediaCapture object.\n        /// </summary>\n        private ImageEncodingProperties encodingProps;\n\n        /// <summary>\n        ///     Flag that indicates successful barcode search.\n        /// </summary>\n        private bool barcodeFoundOrCancelled;\n\n        /// <summary>\n        ///     Image stream for MediaCapture content.\n        /// </summary>\n        private InMemoryRandomAccessStream imageStream;\n\n        #endregion\n\n        #region Constructor\n\n        /// <summary>\n        /// Initializes a new instance of the <see cref=\"Reader\" /> class.\n        /// </summary>\n        /// <param name=\"capture\">MediaCapture instance.</param>\n        /// <param name=\"width\">Capture frame width.</param>\n        /// <param name=\"height\">Capture frame height.</param>\n        public void Init(MediaCapture capture, uint width, uint height)\n        {\n            this.capture = capture;\n            encodingProps = ImageEncodingProperties.CreateJpeg();\n            encodingProps.Width = width;\n            encodingProps.Height = height;\n\n            barcodeReader = new BarcodeReader {Options = {TryHarder = true}};\n            cancelSearch = new CancellationTokenSource();\n        }\n\n        #endregion\n\n        #region Public methods\n\n        /// <summary>\n        /// Perform async MediaCapture analysis and searches for barcode.\n        /// </summary>\n        /// <returns>IAsyncOperation object</returns>\n        public IAsyncOperation<Result> ReadCode()\n        {\n            return this.Read().AsAsyncOperation();\n        }\n\n        /// <summary>\n        /// Send signal to stop barcode search.\n        /// </summary>\n        public void Stop()\n        {\n            this.cancelSearch.Cancel();\n        }\n\n        #endregion\n\n        #region Private methods\n\n        /// <summary>\n        /// Perform async MediaCapture analysis and searches for barcode.\n        /// </summary>\n        /// <returns>Task object</returns>\n        private async Task<Result> Read()\n        {\n            Result result = null;\n            try\n            {\n                while (result == null)\n                {\n                    result = await GetCameraImage(cancelSearch.Token);\n                }\n            }\n            catch (OperationCanceledException) { }\n\n            return result;\n        }\n\n        /// <summary>\n        /// Perform image capture from mediaCapture object\n        /// </summary>\n        /// <param name=\"cancelToken\">\n        /// The cancel Token.\n        /// </param>\n        /// <returns>\n        /// Decoded barcode string.\n        /// </returns>\n        private async Task<Result> GetCameraImage(CancellationToken cancelToken)\n        {\n            if (cancelToken.IsCancellationRequested)\n            {\n                throw new OperationCanceledException(cancelToken);\n            }\n\n            imageStream = new InMemoryRandomAccessStream();\n\n            await capture.CapturePhotoToStreamAsync(encodingProps, imageStream);\n            await imageStream.FlushAsync();\n\n            var decoder = await BitmapDecoder.CreateAsync(imageStream);\n\n            byte[] pixels =\n                (await\n                    decoder.GetPixelDataAsync(BitmapPixelFormat.Rgba8,\n                        BitmapAlphaMode.Ignore,\n                        new BitmapTransform(),\n                        ExifOrientationMode.IgnoreExifOrientation,\n                        ColorManagementMode.DoNotColorManage)).DetachPixelData();\n\n            const BitmapFormat format = BitmapFormat.RGB32;\n\n            imageStream.Dispose();\n\n            var result =\n                await\n                    Task.Run(\n                        () => barcodeReader.Decode(pixels, (int) decoder.PixelWidth, (int) decoder.PixelHeight, format),\n                        cancelToken);\n\n            return result;\n        }\n\n        #endregion\n    }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/windows/lib/WinRTBarcodeReader.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- \n  Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.\n  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\n\n  http://www.apache.org/licenses/LICENSE-2.0\n\n  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.\n-->\n<Project ToolsVersion=\"4.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProductVersion>8.0.30703</ProductVersion>\n    <SchemaVersion>2.0</SchemaVersion>\n    <ProjectName>WinRTBarcodeReader</ProjectName>\n    <ProjectGuid>{01412F36-3781-4AF0-903C-ACEA7552C99C}</ProjectGuid>\n    <OutputType>winmdobj</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>WinRTBarcodeReader</RootNamespace>\n    <AssemblyName>WinRTBarcodeReader</AssemblyName>\n    <DefaultLanguage>en-US</DefaultLanguage>\n    <FileAlignment>512</FileAlignment>\n    <ProjectTypeGuids>{BC8A1FFA-BEE3-4634-8014-F334798102B3};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE;NETFX_CORE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <DebugSymbols>false</DebugSymbols>\n    <DebugType>None</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE;NETFX_CORE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)' == 'Debug|ARM'\">\n    <DebugSymbols>true</DebugSymbols>\n    <OutputPath>bin\\ARM\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE;NETFX_CORE</DefineConstants>\n    <NoWarn>;2008</NoWarn>\n    <DebugType>full</DebugType>\n    <PlatformTarget>ARM</PlatformTarget>\n    <UseVSHostingProcess>false</UseVSHostingProcess>\n    <ErrorReport>prompt</ErrorReport>\n    <Prefer32Bit>true</Prefer32Bit>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)' == 'Release|ARM'\">\n    <OutputPath>bin\\ARM\\Release\\</OutputPath>\n    <DefineConstants>TRACE;NETFX_CORE</DefineConstants>\n    <Optimize>true</Optimize>\n    <NoWarn>;2008</NoWarn>\n    <DebugSymbols>false</DebugSymbols>\n    <DebugType>None</DebugType>\n    <PlatformTarget>ARM</PlatformTarget>\n    <UseVSHostingProcess>false</UseVSHostingProcess>\n    <ErrorReport>prompt</ErrorReport>\n    <Prefer32Bit>true</Prefer32Bit>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)' == 'Debug|x64'\">\n    <DebugSymbols>true</DebugSymbols>\n    <OutputPath>bin\\x64\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE;NETFX_CORE</DefineConstants>\n    <NoWarn>;2008</NoWarn>\n    <DebugType>full</DebugType>\n    <PlatformTarget>x64</PlatformTarget>\n    <UseVSHostingProcess>false</UseVSHostingProcess>\n    <ErrorReport>prompt</ErrorReport>\n    <Prefer32Bit>true</Prefer32Bit>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)' == 'Release|x64'\">\n    <OutputPath>bin\\x64\\Release\\</OutputPath>\n    <DefineConstants>TRACE;NETFX_CORE</DefineConstants>\n    <Optimize>true</Optimize>\n    <NoWarn>;2008</NoWarn>\n    <DebugSymbols>false</DebugSymbols>\n    <DebugType>None</DebugType>\n    <PlatformTarget>x64</PlatformTarget>\n    <UseVSHostingProcess>false</UseVSHostingProcess>\n    <ErrorReport>prompt</ErrorReport>\n    <Prefer32Bit>true</Prefer32Bit>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)' == 'Debug|x86'\">\n    <DebugSymbols>true</DebugSymbols>\n    <OutputPath>bin\\x86\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE;NETFX_CORE</DefineConstants>\n    <NoWarn>;2008</NoWarn>\n    <DebugType>full</DebugType>\n    <PlatformTarget>x86</PlatformTarget>\n    <UseVSHostingProcess>false</UseVSHostingProcess>\n    <ErrorReport>prompt</ErrorReport>\n    <Prefer32Bit>true</Prefer32Bit>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)' == 'Release|x86'\">\n    <OutputPath>bin\\x86\\Release\\</OutputPath>\n    <DefineConstants>TRACE;NETFX_CORE</DefineConstants>\n    <Optimize>true</Optimize>\n    <NoWarn>;2008</NoWarn>\n    <DebugSymbols>false</DebugSymbols>\n    <DebugType>None</DebugType>\n    <PlatformTarget>x86</PlatformTarget>\n    <UseVSHostingProcess>false</UseVSHostingProcess>\n    <ErrorReport>prompt</ErrorReport>\n    <Prefer32Bit>true</Prefer32Bit>\n  </PropertyGroup>\n  <ItemGroup>\n    <Compile Include=\"Reader.cs\" />\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Reference Include=\"ZXing\">\n      <HintPath>ZXing.winmd</HintPath>\n    </Reference>\n  </ItemGroup>\n  <PropertyGroup Condition=\" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '11.0' \">\n    <VisualStudioVersion>11.0</VisualStudioVersion>\n  </PropertyGroup>\n  <Import Project=\"$(MSBuildExtensionsPath)\\Microsoft\\WindowsXaml\\v$(VisualStudioVersion)\\Microsoft.Windows.UI.Xaml.CSharp.targets\" />\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\n</Project>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/wp8/BarcodeScanner.cs",
    "content": "﻿﻿/*\n * Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.\n *\n * 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\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * 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.\n */\n\n namespace WPCordovaClassLib.Cordova.Commands\n{\n    using System.Runtime.Serialization;\n    using Microsoft.Phone.Tasks;\n    using WPCordovaClassLib.Cordova.JSON;\n    using ZXing;\n\n    /// <summary>\n    /// Class that extends cordova with Barcode scanner functionality.\n    /// </summary>\n    public class BarcodeScanner : BaseCommand\n    {\n        /// <summary>\n        /// Scans the barcode.\n        /// </summary>\n        /// <param name=\"options\">Parameter is ignored.</param>\n        public void scan(string options)\n        {\n            var task = new BarcodeScannerTask();\n            task.Completed += this.TaskCompleted;\n            task.Show();\n        }\n\n        /// <summary>\n        /// Handler for barcode scanner task.\n        /// </summary>\n        /// <param name=\"sender\">The sender.</param>\n        /// <param name=\"e\">The scan result.</param>\n        private void TaskCompleted(object sender, BarcodeScannerTask.ScanResult e)\n        {\n            PluginResult result;\n\n            switch (e.TaskResult)\n            {\n                case TaskResult.OK:\n                    result = new PluginResult(PluginResult.Status.OK);\n                    result.Message = JsonHelper.Serialize(new BarcodeResult(e.Barcode));\n                    break;\n                case TaskResult.Cancel:\n                    // If scan is cancelled we return PluginResult.Status.OK with Message contains cancelled: true\n                    // See plugin docs https://github.com/MSOpenTech/BarcodeScanner#using-the-plugin\n                    result = new PluginResult(PluginResult.Status.OK);\n                    result.Message = JsonHelper.Serialize(new BarcodeResult());\n                    break;\n                default:\n                    result = new PluginResult(PluginResult.Status.ERROR);\n                    break;\n            }\n\n            this.DispatchCommandResult(result);\n        }\n    }\n\n    /// <summary>\n    /// Represents the barcode scan result, that should be serialized and passed to JS layer.\n    /// </summary>\n    [DataContract]\n    public sealed class BarcodeResult\n    {\n        /// <summary>\n        /// Initializes a new instance of the <see cref=\"BarcodeResult\"/> class.\n        /// </summary>\n        /// <param name=\"canceled\">if set to <c>true</c> [canceled].</param>\n        public BarcodeResult(bool canceled = true)\n        {\n            this.Cancelled = canceled;\n        }\n\n        /// <summary>\n        /// Initializes a new instance of the <see cref=\"BarcodeResult\"/> class.\n        /// </summary>\n        /// <param name=\"barcode\">The barcode result.</param>\n        public BarcodeResult(Result barcode)\n        {\n            this.Cancelled = false;\n            this.Format = (int)barcode.BarcodeFormat;\n            this.Text = barcode.Text;\n        }\n\n        /// <summary>\n        /// Gets a value indicating whether barcode scan is cancelled.\n        /// </summary>\n        /// <value>\n        ///   <c>true</c> if cancelled; otherwise, <c>false</c>.\n        /// </value>\n        [DataMember(Name = \"cancelled\")]\n        public bool Cancelled { get; private set; }\n\n        /// <summary>\n        /// Gets the format of barcode.\n        /// </summary>\n        /// <value>\n        /// The barcode format.\n        /// </value>\n        [DataMember(Name = \"format\")]\n        public int Format { get; private set; }\n\n        /// <summary>\n        /// Gets the barcode text.\n        /// </summary>\n        /// <value>\n        /// The barcode text.\n        /// </value>\n        [DataMember(Name = \"text\")]\n        public string Text { get; private set; }\n    }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/wp8/BarcodeScannerTask.cs",
    "content": "﻿﻿/*\n * Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.\n *\n * 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\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * 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.\n */\n\nnamespace WPCordovaClassLib.Cordova.Commands\n{\n    using System;\n    using System.Windows;\n    using System.Windows.Navigation;\n\n    using Microsoft.Phone.Controls;\n    using Microsoft.Phone.Tasks;\n    using ZXing;\n\n    /// <summary>\n    /// Class that represents barcode scanner task that mimics standart WP8 tasks.\n    /// </summary>\n    public class BarcodeScannerTask\n    {\n        /// <summary>\n        /// Occurs when task is [completed].\n        /// </summary>\n        public event EventHandler<ScanResult> Completed;\n\n        /// <summary>\n        /// Shows barcode scanner interface.\n        /// </summary>\n        public void Show()\n        {\n            Deployment.Current.Dispatcher.BeginInvoke(() =>\n            {\n                var root = Application.Current.RootVisual as PhoneApplicationFrame;\n\n                if (root == null)\n                {\n                    return;\n                }\n\n                root.Navigated += this.OnNavigated;\n                root.Navigate(new Uri(\"/Plugins/phonegap-plugin-barcodescanner/BarcodeScannerUI.xaml\", UriKind.Relative));\n            });\n        }\n\n        /// <summary>\n        /// Called when [navigated].\n        /// </summary>\n        /// <param name=\"sender\">The sender.</param>\n        /// <param name=\"e\">The <see cref=\"NavigationEventArgs\"/> instance containing the event data.</param>\n        private void OnNavigated(object sender, NavigationEventArgs e)\n        {\n            if (!(e.Content is BarcodeScannerUI))\n            {\n                return;\n            }\n\n            var phoneApplicationFrame = Application.Current.RootVisual as PhoneApplicationFrame;\n            if (phoneApplicationFrame != null)\n            {\n                phoneApplicationFrame.Navigated -= this.OnNavigated;\n            }\n\n            var barcodeScanner = (BarcodeScannerUI)e.Content;\n\n            if (barcodeScanner != null)\n            {\n                barcodeScanner.Completed += this.Completed;\n            }\n            else if (this.Completed != null)\n            {\n                this.Completed(this, new ScanResult(TaskResult.Cancel));\n            }\n        }\n\n        /// <summary>\n        /// Represents barcode scan result.\n        /// </summary>\n        public class ScanResult : TaskEventArgs\n        {\n            /// <summary>\n            /// Initializes a new instance of the <see cref=\"ScanResult\"/> class.\n            /// </summary>\n            /// <param name=\"taskResult\">One of the enumeration values that specifies the status of the task.</param>\n            public ScanResult(TaskResult taskResult)\n                : base(taskResult)\n            {\n            }\n\n            /// <summary>\n            /// Gets the barcode scan result.\n            /// </summary>\n            /// <value>\n            /// The barcode scan result.\n            /// </value>\n            public Result Barcode { get; internal set; }\n        }\n    }\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/wp8/BarcodeScannerUI.xaml",
    "content": "﻿<!-- \n  Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.\n  \n    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\n\n  http://www.apache.org/licenses/LICENSE-2.0\n\n  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.\n-->\n<phone:PhoneApplicationPage\n    x:Class=\"WPCordovaClassLib.Cordova.Commands.BarcodeScannerUI\"\n    xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n    xmlns:phone=\"clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone\"\n    xmlns:shell=\"clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone\"\n    xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n    xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n    FontFamily=\"{StaticResource PhoneFontFamilyNormal}\"\n    FontSize=\"{StaticResource PhoneFontSizeNormal}\"\n    Foreground=\"{StaticResource PhoneForegroundBrush}\"\n    SupportedOrientations=\"Portrait\" Orientation=\"Portrait\"\n    mc:Ignorable=\"d\"\n    shell:SystemTray.IsVisible=\"True\" CacheMode=\"BitmapCache\" >\n    <phone:PhoneApplicationPage.ApplicationBar>\n        <shell:ApplicationBar IsVisible=\"True\" IsMenuEnabled=\"False\" Mode=\"Minimized\">\n            <shell:ApplicationBarIconButton IconUri=\"/www/Images/appbar.cancel.png\" IsEnabled=\"True\" Text=\"Cancel\" Click=\"CancelScan\"/>\n        </shell:ApplicationBar>\n    </phone:PhoneApplicationPage.ApplicationBar>\n\n    <Grid Background=\"Transparent\">\n        <Canvas x:Name=\"CameraCanvas\">\n            <Canvas.Background>\n                <VideoBrush x:Name=\"CameraBrush\">\n                    <VideoBrush.RelativeTransform>\n                        <CompositeTransform\n                            CenterX=\"0.5\"\n                            CenterY=\"0.5\"\n                            Rotation=\"90\"/>\n                    </VideoBrush.RelativeTransform>\n                </VideoBrush>\n            </Canvas.Background>\n        </Canvas>\n        <Rectangle Margin=\"0\" Stroke=\"Red\" Height=\"2\"/>\n    </Grid>\n\n</phone:PhoneApplicationPage>"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/src/wp8/BarcodeScannerUI.xaml.cs",
    "content": "﻿﻿/*\n * Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.\n *\n * 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\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * 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.\n */\n\nnamespace WPCordovaClassLib.Cordova.Commands\n{\n    using System;\n    using System.Windows;\n    using System.Windows.Controls;\n    using System.Windows.Input;\n    using System.Windows.Media.Imaging;\n    using System.Windows.Navigation;\n    using System.Windows.Threading;\n\n    using Microsoft.Devices;\n    using Microsoft.Phone.Tasks;\n\n    using ZXing;\n\n    /// <summary>\n    /// Class that represents UI for barcode scanner.\n    /// </summary>\n    public partial class BarcodeScannerUI\n    {\n        /// <summary>\n        /// The result of scan operation.\n        /// </summary>\n        private BarcodeScannerTask.ScanResult result;\n\n        /// <summary>\n        /// The barcode reader object\n        /// </summary>\n        private BarcodeReader reader;\n\n        /// <summary>\n        /// Device camera object\n        /// </summary>\n        private PhotoCamera camera;\n\n        private DispatcherTimer timer;\n\n        /// <summary>\n        /// Initializes a new instance of the <see cref=\"BarcodeScannerUI\"/> class.\n        /// This implementation not use camera autofocus.\n        /// </summary>\n        public BarcodeScannerUI()\n        {\n            this.InitializeComponent();\n\n            // Instantiate objects and start camera preview\n            this.camera = new PhotoCamera();\n            this.reader = new BarcodeReader {Options = {TryHarder = true}};\n            this.CameraBrush.SetSource(this.camera);\n\n            // Bind events\n            this.camera.Initialized += this.CameraInitialized;\n            this.reader.ResultFound += this.ReaderResultFound;\n\n            this.timer = new DispatcherTimer {Interval = TimeSpan.FromMilliseconds(100)};\n            this.timer.Tick += (sender, args) => ScanForBarcode();\n\n            this.BackKeyPress += CancelScan;\n\n            CameraButtons.ShutterKeyHalfPressed += StartCameraFocus;\n            camera.AutoFocusCompleted += StartCameraFocus;\n\n        }\n\n        private void StartCameraFocus(object sender, EventArgs eventArgs)\n        {\n            camera.Focus();\n        }\n\n        /// <summary>\n        /// Occurs when barcode scan is [completed].\n        /// </summary>\n        public event EventHandler<BarcodeScannerTask.ScanResult> Completed;\n\n        /// <summary>\n        /// Called when a page is no longer the active page in a frame.\n        /// </summary>\n        /// <param name=\"e\">An object that contains the event data.</param>\n        protected override void OnNavigatedFrom(NavigationEventArgs e)\n        {\n            // If result is null, user is cancelled scan operation\n            this.result = this.result ?? new BarcodeScannerTask.ScanResult(TaskResult.Cancel);\n            this.Completed(this, this.result);\n            this.CleanUp();\n            base.OnNavigatedFrom(e);\n        }\n\n        /// <summary>\n        /// Called when device camera initialized.\n        /// </summary>\n        /// <param name=\"sender\">The sender.</param>\n        /// <param name=\"e\">The <see cref=\"CameraOperationCompletedEventArgs\"/> instance containing the event data.</param>\n        private void CameraInitialized(object sender, CameraOperationCompletedEventArgs e)\n        {\n            if (e.Succeeded)\n            {\n                if (camera.IsFocusSupported)\n                {\n                    camera.Focus();\n                }\n\n                // Start scan process in separate thread\n                this.Dispatcher.BeginInvoke(() => timer.Start());\n            }\n            else\n            {\n                this.result = new BarcodeScannerTask.ScanResult(TaskResult.None);\n                NavigationService.GoBack();\n            }\n        }\n\n        private void ScanForBarcode()\n        {\n            var cameraBuffer = new WriteableBitmap(\n                                (int)camera.PreviewResolution.Width,\n                                (int)camera.PreviewResolution.Height);\n\n            camera.GetPreviewBufferArgb32(cameraBuffer.Pixels);\n            cameraBuffer.Invalidate();\n\n            reader.Decode(cameraBuffer);\n        }\n\n        /// <summary>\n        /// Called when reader find barcode.\n        /// </summary>\n        /// <param name=\"obj\">Scan result object.</param>\n        private void ReaderResultFound(Result obj)\n        {\n            VibrateController.Default.Start(TimeSpan.FromMilliseconds(100));\n            this.result = new BarcodeScannerTask.ScanResult(TaskResult.OK) { Barcode = obj };\n            NavigationService.GoBack();\n        }\n\n        /// <summary>\n        /// Cleans up resources and removes unnecessary callbacks.\n        /// </summary>\n        private void CleanUp()\n        {\n            CameraButtons.ShutterKeyHalfPressed -= StartCameraFocus;\n            if (this.camera != null)\n            {\n                this.camera.AutoFocusCompleted -= StartCameraFocus;\n                this.camera.Initialized -= this.CameraInitialized;\n                this.camera.Dispose();\n                this.camera = null;\n            }\n\n            if (this.reader != null)\n            {\n                this.reader.ResultFound -= this.ReaderResultFound;\n                this.reader = null;\n            }\n\n            if (this.timer != null)\n            {\n                this.timer.Stop();\n                this.timer = null;\n            }\n        }\n\n        private void ApplicationBarIconButton_Click(object sender, EventArgs e)\n        {\n            NavigationService.GoBack();\n        }\n\n        private void CancelScan(object sender, EventArgs eventArgs)\n        {\n            NavigationService.GoBack();\n        }\n    }\n}"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/tests/plugin.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n  Licensed to the Apache Software Foundation (ASF) under one\n  or more contributor license agreements.  See the NOTICE file\n  distributed with this work for additional information\n  regarding copyright ownership.  The ASF licenses this file\n  to you under the Apache License, Version 2.0 (the\n  \"License\"); you may not use this file except in compliance\n  with the License.  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing,\n  software distributed under the License is distributed on an\n  \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n  KIND, either express or implied.  See the License for the\n  specific language governing permissions and limitations\n  under the License.\n-->\n\n<plugin xmlns=\"http://apache.org/cordova/ns/plugins/1.0\"\n    xmlns:rim=\"http://www.blackberry.com/ns/widgets\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    id=\"phonegap-plugin-barcodescanner-tests\"\n    version=\"3.1.0\">\n    <name>PhoneGap BarcodeScanner Plugin Tests</name>\n    <license>Apache 2.0</license>\n\n    <js-module src=\"tests.js\" name=\"tests\">\n    </js-module>\n</plugin>\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/tests/tests.js",
    "content": "/*\n *\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n *\n*/\nexports.defineAutoTests = function() {\n    var scanner;\n    describe('cordova.require object should exist', function () {\n        it(\"should exist\", function() {\n            expect(window.cordova).toBeDefined();\n            expect(typeof cordova.require == 'function').toBe(true);\n        });\n\n        it(\"BarcodeScanner plugin should exist\", function() {\n            scanner = cordova.plugins.barcodeScanner; \n            expect(scanner).toBeDefined();\n            expect(typeof scanner == 'object').toBe(true);\n        });\n\n        it(\"should contain a scan function\", function() {\n            expect(scanner.scan).toBeDefined();\n            expect(typeof scanner.scan == 'function').toBe(true);\n        });\n\n        it(\"should contain an encode function\", function() {\n            expect(scanner.encode).toBeDefined();\n            expect(typeof scanner.encode == 'function').toBe(true);\n        });\n\n        it(\"should contain three DestinationType constants\", function() {\n            expect(scanner.Encode.TEXT_TYPE).toBe(\"TEXT_TYPE\");\n            expect(scanner.Encode.EMAIL_TYPE).toBe(\"EMAIL_TYPE\");\n            expect(scanner.Encode.PHONE_TYPE).toBe(\"PHONE_TYPE\");\n            expect(scanner.Encode.SMS_TYPE).toBe(\"SMS_TYPE\");\n        });\n        /*\n        it(\"should call scan successfully\", function() {\n            scanner.scan(function() {}, function() {});\n        });\n        */\n    });\n}\n"
  },
  {
    "path": "plugins/phonegap-plugin-barcodescanner/www/barcodescanner.js",
    "content": "/**\n * cordova is available under *either* the terms of the modified BSD license *or* the\n * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.\n *\n * Copyright (c) Matt Kane 2010\n * Copyright (c) 2011, IBM Corporation\n */\n\n\nvar exec = require(\"cordova/exec\");\n\n/**\n * Constructor.\n *\n * @returns {BarcodeScanner}\n */\nfunction BarcodeScanner() {\n\n    /**\n     * Encoding constants.\n     *\n     * @type Object\n     */\n    this.Encode = {\n        TEXT_TYPE: \"TEXT_TYPE\",\n        EMAIL_TYPE: \"EMAIL_TYPE\",\n        PHONE_TYPE: \"PHONE_TYPE\",\n        SMS_TYPE: \"SMS_TYPE\"\n        //  CONTACT_TYPE: \"CONTACT_TYPE\",  // TODO:  not implemented, requires passing a Bundle class from Javascript to Java\n        //  LOCATION_TYPE: \"LOCATION_TYPE\" // TODO:  not implemented, requires passing a Bundle class from Javascript to Java\n    };\n\n    /**\n     * Barcode format constants, defined in ZXing library.\n     *\n     * @type Object\n     */\n    this.format = {\n        \"all_1D\": 61918,\n        \"aztec\": 1,\n        \"codabar\": 2,\n        \"code_128\": 16,\n        \"code_39\": 4,\n        \"code_93\": 8,\n        \"data_MATRIX\": 32,\n        \"ean_13\": 128,\n        \"ean_8\": 64,\n        \"itf\": 256,\n        \"maxicode\": 512,\n        \"msi\": 131072,\n        \"pdf_417\": 1024,\n        \"plessey\": 262144,\n        \"qr_CODE\": 2048,\n        \"rss_14\": 4096,\n        \"rss_EXPANDED\": 8192,\n        \"upc_A\": 16384,\n        \"upc_E\": 32768,\n        \"upc_EAN_EXTENSION\": 65536\n    };\n};\n\n/**\n * Read code from scanner.\n *\n * @param {Function} successCallback This function will recieve a result object: {\n *        text : '12345-mock',    // The code that was scanned.\n *        format : 'FORMAT_NAME', // Code format.\n *        cancelled : true/false, // Was canceled.\n *    }\n * @param {Function} errorCallback\n */\nBarcodeScanner.prototype.scan = function (successCallback, errorCallback, config) {\n\n    if(config instanceof Array) {\n        // do nothing\n    } else {\n        if(typeof(config) === 'object') {\n            config = [ config ];\n        } else {\n            config = [];\n        }\n    }\n\n    if (errorCallback == null) {\n        errorCallback = function () {\n        };\n    }\n\n    if (typeof errorCallback != \"function\") {\n        console.log(\"BarcodeScanner.scan failure: failure parameter not a function\");\n        return;\n    }\n\n    if (typeof successCallback != \"function\") {\n        console.log(\"BarcodeScanner.scan failure: success callback parameter must be a function\");\n        return;\n    }\n\n    exec(successCallback, errorCallback, 'BarcodeScanner', 'scan', config);\n};\n\n//-------------------------------------------------------------------\nBarcodeScanner.prototype.encode = function (type, data, successCallback, errorCallback, options) {\n    if (errorCallback == null) {\n        errorCallback = function () {\n        };\n    }\n\n    if (typeof errorCallback != \"function\") {\n        console.log(\"BarcodeScanner.encode failure: failure parameter not a function\");\n        return;\n    }\n\n    if (typeof successCallback != \"function\") {\n        console.log(\"BarcodeScanner.encode failure: success callback parameter must be a function\");\n        return;\n    }\n\n    exec(successCallback, errorCallback, 'BarcodeScanner', 'encode', [\n        {\"type\": type, \"data\": data, \"options\": options}\n    ]);\n};\n\nvar barcodeScanner = new BarcodeScanner();\nmodule.exports = barcodeScanner;\n"
  },
  {
    "path": "src/css/android.less",
    "content": "//\n// Android\n// ==============================\n\n\n\n\n// Variables\n// ------------------------------\n\n@android-gutter:                 17px;\n\n\n\n\n// Base\n// ------------------------------\n\n.device--Android {\n\tfont-family: Roboto;\n\n\t// attempt material design styles\n\t.View {\n\t\tbackground-color: white;\n\t\tcolor: @gray-darker;\n\t}\n\n\n\t// Re-Colouring Views Components\n\t// ------------------------------\n\n\t// onboarding\n\t.onboarding-heading-1 {\n\t\tcolor: white;\n\t}\n\t.onboarding-form__button {\n\t\tcolor: white;\n\t}\n\n\t// event info\n\t.EventInfo {\n\t\tcolor: white;\n\t}\n\t.EventInfo__hero-inner {\n\t\tbackground: rgba(0, 0, 0, 0.5);\n\t}\n\t.EventInfo__organisers {\n\t\tmargin-bottom: 0;\n\t\tpadding-bottom: 2em;\n\t}\n\n\t// talks\n\t.TalkDetails__speaker {\n\t\tborder-bottom: 1px solid @gray-lighter;\n\n\t\t&::before,\n\t\t&::after {\n\t\t\tdisplay: none;\n\t\t}\n\n\t\t&:first-child {\n\t\t\tborder-top: 1px solid @gray-lighter;\n\t\t}\n\n\t\t&.Tappable-active {\n\t\t\t#gradient .horizontal-three-colors(fade(black,0%),fade(black,5%),50%,fade(black,0%));\n\t\t}\n\t}\n\t.PersonDetails__talk {\n\t\tbackground-color: @gray-lighter;\n\t\tcolor: @gray-darker;\n\n\t\t&.Tappable-active {\n\t\t\tbackground-color: darken(@gray-lighter, 5%);\n\t\t}\n\t}\n\t.PersonDetails__talk__time {\n\t\tcolor: @gray;\n\t}\n\n\t// registration\n\t.MeRegistration__intro {\n\t\tcolor: @gray;\n\t}\n\t.MeRegistration__benefit__icon {\n\t\tbackground-color: fade(@app-primary, 10%);\n\t}\n\n\t// no results\n\t.no-results__icon,\n\t.no-results__text {\n\t\tcolor: #bbb;\n\t}\n\n\t// buton tables\n\t.button-table,\n\t.button-table .button-table__item {\n\t\tborder-color: @gray-lighter;\n\t\tcolor: @gray-darker;\n\n\t\t&.Tappable-active {\n\t\t\tbackground-color: fade(@gray-lighter, 50%);\n\t\t}\n\t}\n\n\t// misc.\n\t.text-block {\n\t\tcolor: @gray;\n\t}\n\t.panel {\n\t\tbackground-color: #f6f6f6;\n\t}\n\t.field-label {\n\t\tcolor: @gray;\n\t}\n\t.field {\n\t\tcolor: @gray-darker;\n\t}\n\t.PersonDetails__public-indicator {\n\t\tbackground-color: fade(@app-primary, 10%);\n\t}\n\n\n\t// Icon Manipulation\n\t// ------------------------------\n\n\t.ion-ios-star::before { content: @ionicon-var-android-star; }\n\t.ion-ios-star-outline::before { content: @ionicon-var-android-star-outline; }\n\t.ion-ios-search-strong::before { content: @ionicon-var-android-search; }\n\t.ion-close-circled::before { content: @ionicon-var-android-close; }\n\n\t.PersonItem__star::before { content: @ionicon-var-android-star-outline; }\n\t.PersonItem__starred::before { content: @ionicon-var-android-star; }\n}\n\n// android view transition animations\n.device--Android {\n\t.view-transition-show-from-right-enter {\n\t\t.animation( fadeIn 200ms linear );\n\t}\n\t.view-transition-reveal-from-right-enter {\n\t\t.animation( fadeInExpand 200ms linear );\n\t}\n\t.view-transition-show-from-right-leave,\n\t.view-transition-reveal-from-right-leave {\n\t\t.animation( fadeOut 200ms linear );\n\t}\n}\n\n\n\n\n// Title Bar\n// ------------------------------\n\n\n// base styles hacking\n\n.device--Android {\n\t// hide bottom border\n\t.NavigationBar {\n\t\tbackground-color: @app-primary;\n\t\tcolor: white;\n\n\t\t&::after {\n\t\t\tdisplay: none;\n\t\t}\n\t}\n\n\t// change the button colours\n\t.NavigationBarLeftButton,\n\t.NavigationBarRightButton {\n\t\tcolor: white;\n\t}\n\n\t// change to the android back arrow\n\t.NavigationBarLeftArrow {\n\t\tbackground: transparent;\n\t\twidth: 50px;\n\n\t\t&::before {\n\t\t\tcontent: @ionicon-var-android-arrow-back;\n\t\t}\n\t}\n\t.NavigationBarLeftIcon {\n\t\tdisplay: block;\n\t\twidth: 50px;\n\t}\n\n\t// android doesn't have left labels\n\t.NavigationBarLeftLabel {\n\t\tdisplay: none;\n\t}\n\t.NavigationBarTitle {\n\t\tpadding-left: @android-gutter;\n\t\ttext-align: left;\n\t}\n\t.NavigationBar.has-left-arrow .NavigationBarTitle,\n\t.NavigationBar.has-left-icon .NavigationBarTitle {\n\t\tpadding-left: 50px;\n\t}\n}\n\n// android titlebar transition animations are instant\n.device--Android {\n\t.NavigationBarTransition-Instant-enter,\n\t.NavigationBarTransition-Fade-enter,\n\t.NavigationBarTransition-Forwards-enter,\n\t.NavigationBarTransition-Backwards-enter  {\n\t\t.animation( fadeIn 10ms linear );\n\t}\n\n\t.NavigationBarTransition-Instant-leave,\n\t.NavigationBarTransition-Fade-leave,\n\t.NavigationBarTransition-Forwards-leave,\n\t.NavigationBarTransition-Backwards-leave  {\n\t\t.animation( fadeOut 10ms linear );\n\t}\n}\n\n\n\n\n// Headerbar Form (search)\n// ------------------------------\n\n.device--Android {\n\t.Headerbar-form-field {\n\t\tbackground-color: white;\n\t\tbox-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);\n\t\tcolor: black;\n\t\tpadding: @headerbar-field-gutter;\n\t\tz-index: 3;\n\t}\n\n\t// input\n\t.Headerbar-form-input {\n\t\t.placeholder( #999 );\n\t\tbackground-color: transparent;\n\n\t\t&:active {\n\t\t\tbackground-color: rgba(255, 255, 255, 0.05);\n\t\t}\n\t\t&:focus {\n\t\t\tbackground-color: rgba(255, 255, 255, 0.15);\n\t\t}\n\t}\n\n\t// icons\n\t.Headerbar-form-icon::before {\n\t\tcolor: #999;\n\t}\n\t.Headerbar-form-clear {\n\t\tcolor: #999;\n\n\t\t&.Tappable-active {\n\t\t\tcolor: #333;\n\t\t}\n\t}\n}\n\n\n\n\n// Lists\n// ------------------------------\n\n.device--Android {\n\t// hide the list header borders\n\t.ListHeader {\n\t\t&::before,\n\t\t&::after {\n\t\t\tdisplay: none;\n\t\t}\n\t}\n\t.EventInfo__organisers,\n\t.View--people,\n\t.View--schedule {\n\t\tbackground-color: #eee;\n\t\tcolor: #666;\n\n\t\t.ListItem {\n\t\t\tbackground-color: white;\n\t\t\tmargin-bottom: 1px;\n\n\t\t\t&.Tappable-active {\n\t\t\t\t#gradient .horizontal-three-colors(fade(black,0%),fade(black,5%),50%,fade(black,0%));\n\t\t\t}\n\t\t}\n\t\t.ListItem__heading {\n\t\t\tcolor: black;\n\t\t}\n\t\t.ListHeader {\n\t\t\tbackground-color: #eee;\n\t\t\tcolor: #666;\n\t\t}\n\t}\n}\n\n\n\n\n// Tab Navigator\n// ------------------------------\n\n.device--Android {\n\n\t// make the tabbar appear as a menu\n\t.Tabs-Navigator-wrapper {\n\t\t.transition( opacity 200ms );\n\t\tbackground-color: rgba(0, 0, 0, 0.66);\n\t\tdisplay: block;\n\t\theight: 100%;\n\t\tleft: 0;\n\t\topacity: 0;\n\t\tposition: absolute;\n\t\ttop: 0;\n\t\twidth: 100%;\n\t\tz-index: 1;\n\n\t\t// hide by default\n\t\tvisibility: hidden;\n\t\tpointer-events: none;\n\n\t}\n\t.Tabs-Navigator {\n\t\t.transition( all ease 200ms );\n\t\t.translateX(-100%);\n\t\tbackground-color: white;\n\t\tbottom: 0;\n\t\tbox-shadow: 0 0 10px -1px rgba(0, 0, 0, 0.21);\n\t\tcolor: black;\n\t\tdisplay: block;\n\t\theight: auto;\n\t\tleft: 0;\n\t\tposition: absolute;\n\t\tright: auto;\n\t\ttop: 0;\n\t\twidth: 66%;\n\t\tz-index: 2;\n\n\t\t// hide top border\n\t\t&::after {\n\t\t\tdisplay: none;\n\t\t}\n\t}\n\n\n\t// make the tabs look like menu items\n\t.Tabs-Tab {\n\t\tcolor: inherit;\n\t\tdisplay: block;\n\t\toverflow: hidden;\n\t\tpadding: @android-gutter 0;\n\t\ttext-align: left;\n\t}\n\n\t// labels & icons\n\t.Tabs-Icon,\n\t.Tabs-Label {\n\t\tcolor: inherit;\n\t\tdisplay: inline-block;\n\t\tvertical-align: middle;\n\t}\n\n\t// icons\n\t.Tabs-Icon {\n\t\ttext-align: center;\n\t\twidth: 50px;\n\t}\n\n\t// labels\n\t.Tabs-Label {\n\t\tfont-size: @font-size-base;\n\t}\n\n\t// update icons\n\n\t// schedule\n\t.is-selected > .Tabs-Icon--schedule::before,\n\t.Tabs-Icon--schedule::before { content: @ionicon-var-android-time; }\n\n\t// people\n\t.is-selected > .Tabs-Icon--people::before,\n\t.Tabs-Icon--people::before { content: @ionicon-var-android-people; }\n\n\t// event\n\t.is-selected > .Tabs-Icon--event::before,\n\t.Tabs-Icon--event::before { content: @ionicon-var-android-star; }\n\n\t// me\n\t.is-selected > .Tabs-Icon--me::before,\n\t.Tabs-Icon--me::before { content: @ionicon-var-android-contact; }\n}\n.android-menu-is-open .Tabs-Navigator-wrapper {\n\t.translateX(0);\n\topacity: 1;\n\tpointer-events: auto;\n\tvisibility: visible;\n}\n.android-menu-is-open .Tabs-Navigator {\n\t.translateX(0);\n}\n\n\n\n\n// Misc\n// ------------------------------\n\n.device--Android {\n\t.search-attendees-message {\n\t\tcolor: #888;\n\t}\n}\n\n\n\n\n// Animations\n// ------------------------------\n\n\n// fade in-expand\n\n@-webkit-keyframes fadeInExpand {\n\tfrom { opacity: 0; -webkit-transform: scale(.96); }\n\tto { opacity: 1; -webkit-transform: scale(1); }\n}\n@keyframes fadeInExpand {\n\tfrom { opacity: 0; transform: scale(.96); }\n\tto { opacity: 1; transform: scale(1); }\n}\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "src/css/app.less",
    "content": "//\n// App\n// ==============================\n\n@import \"ionicons/ionicons.less\";\n@import \"../../node_modules/touchstonejs/less/touchstone.less\";\n@import \"../../node_modules/react-container/less/component.less\";\n\n@import \"android\";\n@import \"demo\";\n@import \"mixins\";\n@import \"variables\";\n\n@import \"components/index\";\n@import \"views/index\";\n\n// Preload images\nimg.preload {\n\tdisplay: none;\n}\n"
  },
  {
    "path": "src/css/components/FeedbackModal.less",
    "content": "//\n// Modal\n// ==============================\n\n\n\n\n// Dialog\n// ---------------------------\n\n.FeedbackModal-dialog {\n\tbackground-color: fade(white, 96%);\n\tborder-radius: @border-radius-base;\n\tbottom: 1em;\n\tcolor: black;\n\tleft: 1em;\n\tposition: absolute;\n\tright: 1em;\n\ttop: 1em;\n\tz-index: @zindex-modal;\n}\n.FeedbackModal-dialog-enter {\n\t.animation-name( modalDialogEnter );\n\t.animation-duration( 260ms );\n\t.animation-timing-function( cubic-bezier(0.500, -0.550, 0.400, 1.550) );\n}\n.FeedbackModal-dialog-leave {\n\t.animation-duration( 260ms );\n\t.animation-name( modalDialogLeave );\n}\n\n\n\n\n// Form\n// wrap and layout the components\n// ------------------------------\n\n.FeedbackModal__form {\n\t.display-flex();\n\t.flex-direction(column);\n\theight: 100%;\n}\n\n\n\n\n// Header\n// ------------------------------\n\n@feedback-button-size: 60px;\n@feedback-button-bg:   #d8d8d8;\n\n\n// text\n\n.FeedbackModal__header {\n\tpadding: 1.5em 1em;\n\ttext-align: center;\n}\n.FeedbackModal__title {\n\tfont-weight: bold;\n\tmargin-bottom: .5em;\n}\n.FeedbackModal__subtitle {\n\tfont-size: @font-size-sm;\n}\n\n\n// buttons\n\n.FeedbackModal__buttons {\n\tmargin-top: 1em;\n\ttext-align: center;\n}\n.FeedbackModal__button {\n\t.square( @feedback-button-size );\n\tbackground-color: @feedback-button-bg;\n\tborder-radius: 50%;\n\tdisplay: inline-block;\n\tmargin: 0 15px;\n\n\t&.Tappable-active {\n\t\tbackground-color: darken(@feedback-button-bg, 10%);\n\t}\n}\n.FeedbackModal__button--positive {\n\t.ionicon(white, @ionicon-var-thumbsup, @ionicons-size-large);\n\tline-height: @feedback-button-size;\n\n\t&.is-selected {\n\t\tbackground-color: @app-success;\n\t}\n}\n.FeedbackModal__button--negative {\n\t.ionicon(white, @ionicon-var-thumbsdown, @ionicons-size-large);\n\tline-height: @feedback-button-size;\n\n\t&.is-selected {\n\t\tbackground-color: @app-danger;\n\t}\n}\n\n\n\n\n// Body\n// ------------------------------\n\n// stretch the body/textarea to fill all availble space\n\n.FeedbackModal__body {\n\t.flex(1,1,0);\n\tposition: relative;\n}\n.FeedbackModal__body__input {\n\tbackground: none;\n\tborder: none;\n\tborder-bottom: 1px solid rgba(0, 0, 0, 0.1);\n\tborder-top: 1px solid rgba(0, 0, 0, 0.1);\n\tborder-radius: 0;\n\theight: 100%;\n\tleft: 0;\n\tpadding: 1em;\n\tposition: absolute;\n\ttop: 0;\n\twidth: 100%;\n\t-webkit-appearance: none;\n\n\t&.has-value,\n\t&:focus {\n\t\tbackground-color: white;\n\t\toutline: none;\n\t}\n}\n\n\n\n\n// Footer\n// ------------------------------\n\n.FeedbackModal__footer {\n\t.display-flex();\n\tpadding: 1em .5em;\n}\n.FeedbackModal__footer__button {\n\tbackground: none;\n\tborder: none;\n\tborder-radius: @border-radius-small;\n\tline-height: 2em;\n\tmargin-left: .5em;\n\tmargin-right: .5em;\n\tpadding-left: 1em;\n\tpadding-right: 1em;\n\ttext-align: center;\n}\n.FeedbackModal__footer__button--primary {\n\t.flex(1,1,0);\n\tbackground-color: @app-success;\n\tcolor: white;\n\tfont-weight: 500;\n\t-webkit-appearance: none;\n\n\t&:active,\n\t&:focus {\n\t\toutline: none;\n\t}\n\n\t&.Tappable-active {\n\t\tbackground-color: darken(@app-success, 10%);\n\t}\n}\n.FeedbackModal__footer__button--disabled {\n\t.flex(1,1,0);\n\tbackground-color: rgba(0, 0, 0, 0.2);\n\tcolor: white;\n\tfont-weight: 500;\n\t-webkit-appearance: none;\n}\n.FeedbackModal__footer__button--link {\n\tcolor: @gray;\n\n\t&.Tappable-active {\n\t\tbackground-color: rgba(0, 0, 0, 0.1);\n\t}\n}\n\n\n\n\n// Backdrop\n// ------------------------------\n\n.FeedbackModal-backdrop {\n\t.animation-duration( 140ms );\n\tbackground-color: rgba(0, 0, 0, 0.66);\n\theight: 100%;\n\tleft: 0;\n\tposition: fixed;\n\ttop: 0;\n\twidth: 100%;\n\tz-index: @zindex-modal-backdrop;\n}\n.FeedbackModal-backdrop-enter {\n\t.animation-name( modalBackdropEnter );\n}\n.FeedbackModal-backdrop-leave {\n\t.animation-delay( 240ms );\n\t.animation-name( modalBackdropLeave );\n}\n\n\n\n\n// Animation\n// --------------------\n\n\n// modal dialog\n\n@-webkit-keyframes modalDialogEnter {\n\tfrom { opacity: 0; -webkit-transform: scale( .96 ); }\n\tto { opacity: 1; -webkit-transform: scale( 1 ); }\n}\n@keyframes modalDialogEnter {\n\tfrom { opacity: 0; transform: scale( .96 ); }\n\tto { opacity: 1; transform: scale( 1 ); }\n}\n\n@-webkit-keyframes modalDialogLeave {\n\tfrom { opacity: 1; -webkit-transform: scale( 1 ); }\n\tto { opacity: 0; -webkit-transform: scale( .8 ); }\n}\n@keyframes modalDialogLeave {\n\tfrom { opacity: 1; transform: scale( 1 ); }\n\tto { opacity: 0; transform: scale( .8 ); }\n}\n\n\n// modal backdrop\n\n@-webkit-keyframes modalBackdropEnter {\n\tfrom { opacity: 0; }\n\tto { opacity: 1; }\n}\n@keyframes modalBackdropEnter {\n\tfrom { opacity: 0; }\n\tto { opacity: 1; }\n}\n\n@-webkit-keyframes modalBackdropLeave {\n\tfrom { opacity: 1; }\n\tto { opacity: 0; }\n}\n@keyframes modalBackdropLeave {\n\tfrom { opacity: 1; }\n\tto { opacity: 0; }\n}\n\n"
  },
  {
    "path": "src/css/components/Footerbar.less",
    "content": "// \n// Footerbar\n// extends TouchstoneJS \"Footerbar\"\n// ==============================\n\n\n\n\n.Footerbar {\n\t.retina-1px-border-top(rgba(255, 255, 255, 0.3));\n\tbackground-color: @details-bg;\n}\n\n.Footerbar-button {\n\tcolor: white;\n\n\t// give visual feedback on a tap event\n\t&.Tappable-active {\n\t\tbackground-color: rgba(0, 0, 0, 0.1);\n\t}\n\n\t// selected view\n\t&.active {\n\t\tcolor: lighten(@app-primary, 33%);\n\t}\n}\n.Footerbar-button-label {\n\tcolor: inherit;\n}\n\n\n\n// ==============================\n// Tabs\n// ==============================\n\n\n// Base\n// ------------------------------\n\n.Tabs-Navigator {\n\t.align-items(stretch);\n\t.display-flex();\n\t.retina-1px-border-top(rgba(255, 255, 255, 0.3));\n\t.justify-content(space-around);\n\t.backface-visibility(hidden);\n\tbackground-color: @footerbar-bg;\n\tcolor: white;\n\theight: 44px;\n\twidth: 100%;\n\n\t// stack above the views\n\tposition: relative;\n\tz-index: @view-transition-stack-top;\n}\n\n\n// Tab Item\n// ------------------------------\n\n.Tabs-Tab {\n\t.align-items(center);\n\t.display-flex();\n\t.flex-flow(column nowrap);\n\t.flex-grow(1);\n\t.justify-content(center);\n\tbackground: none transparent;\n\tborder: 0 none;\n\tcolor: white;\n\tcursor: pointer; // for piece of mind when developing on the desktop\n\tline-height: 1; // remove unexpected vertical white-space\n\tpadding: 0 5px;\n\tposition: relative;\n\twidth: 100%; // make each button take equal width\n\t-webkit-appearance: none;\n\t\n\t// when pressed\n\t&.Tappable-active {\n\t\tbackground-color: rgba(0, 0, 0, 0.1);\n\t}\n\n\t// selected tab\n\t&.is-selected {\n\t\tcolor: lighten(@app-primary, 33%);\n\t}\n}\n\n\n// label\n\n.Tabs-Label {\n\t.text-overflow();\n\tfont-size: @font-size-xxs;\n}\n\n\n// icons\n\n.Tabs-Icon {\n\t.ion();\n\tfont-size: 28px;\n\n}\n.Tabs-Icon--schedule::before {\n\tcontent: @ionicon-var-ios-clock-outline;\n\n\t.is-selected > & {\n\t\tcontent: @ionicon-var-ios-clock;\n\t}\n}\n.Tabs-Icon--people::before {\n\tcontent: @ionicon-var-ios-people-outline;\n\n\t.is-selected > & {\n\t\tcontent: @ionicon-var-ios-people;\n\t}\n}\n.Tabs-Icon--event::before {\n\tcontent: @ionicon-var-ios-star-outline;\n\n\t.is-selected > & {\n\t\tcontent: @ionicon-var-ios-star;\n\t}\n}\n.Tabs-Icon--me::before {\n\tcontent: @ionicon-var-ios-contact-outline;\n\n\t.is-selected > & {\n\t\tcontent: @ionicon-var-ios-contact;\n\t}\n}\n.Tabs-Icon--about::before {\n\tcontent: @ionicon-var-ios-information-outline;\n\n\t.is-selected > & {\n\t\tcontent: @ionicon-var-ios-information;\n\t}\n}"
  },
  {
    "path": "src/css/components/Headerbar.less",
    "content": "// \n// Headerbar\n// extends TouchstoneJS \"Headerbar\"\n// ==============================\n\n\n\n\n// TEMP FIXES\n// ------------------------------\n\n.Titlebar {\n\t.retina-1px-border-bottom( rgba(255, 255, 255, 0.3) );\n\tbackground-color: @headerbar-bg;\n\tcolor: white;\n\tline-height: 44px;\n\ttext-align: center;\n\twidth: 100%;\n}\n\n\n\n\n// Layout\n\n\n// use a light border below all headerbars\n\n.Headerbar.default,\n.Headerbar.details {\n\t.retina-1px-border-bottom( rgba(255, 255, 255, 0.3) );\n}\n\n\n\n\n// Search\n// ------------------------------\n\n\n/*\n * 1. make the search component appear as if it's part of the headerbar\n * 2. pull the search field up over the headerbar and offset the gutter\n * 3. lighten the search elements to fit the theme\n **/\n\n.Headerbar-form-field {\n\tbackground-color: darken(@body-bg, 2%); // 1\n\tpadding: @headerbar-field-gutter; // 2\n\tz-index: 3; // 2\n}\n\n\n// 3:input\n\n.Headerbar-form-input {\n\t.placeholder( rgba(255, 255, 255, 0.5) );\n\tbackground-color: rgba(255, 255, 255, 0.1);\n\n\t&:active {\n\t\tbackground-color: rgba(255, 255, 255, 0.05);\n\t}\n\t&:focus {\n\t\tbackground-color: rgba(255, 255, 255, 0.15);\n\t}\n}\n\n\n// 3:icons\n\n.Headerbar-form-icon::before {\n\tcolor: rgba(255, 255, 255, 0.5);\n}\n.Headerbar-form-clear, {\n\tcolor: rgba(255, 255, 255, 0.5);\n\n\t&.Tappable-active {\n\t\tcolor: white;\n\t}\n}"
  },
  {
    "path": "src/css/components/ListItem.less",
    "content": "// \n// Components\n// ==============================\n\n\n\n\n// Base\n// ------------------------------\n\n/*\n * 1. using flex; items will position their children into columns\n *    content is \"stretched\" to fill available space\n * 2. darken to provide feedback on tap\n *    delay the tap highlight; it may just be a scroll\n **/\n\n.ListItem {\n\t.display-flex(); // 1\n\t.align-items(center); // 1\n\t.justify-content(space-between); // 1\n\tbackground-color: rgba(255, 255, 255, 0.1);\n\tmargin-bottom: 2px;\n\tpadding: 1em;\n\n\t// 2\n\t&.Tappable-active {\n\t\t.transition( background-color 10ms linear 40ms );\n\t\tbackground-color: rgba(255, 255, 255, 0.05);\n\t}\n\t\n\t// remove bottom margin\n\t&:last-child {\n\t\tmargin-bottom: 0;\n\t}\n}\n\n// 1\n\n.ListItem__content {\n\t.flex(1,1,0);\n\tpadding: 0 0.8em;\n}\n\n\n\n\n// Avatar\n// ------------------------------\n\n.ListItem__avatar {\n\t.avatar(60px);\n}\n\n\n\n\n// Type\n// ------------------------------\n\n.ListItem__heading {\n\tfont-weight: 500;\n\tmargin-bottom: .4em;\n}\n.ListItem__text {\n\tfont-size: @font-size-sm;\n\tline-height: 1.2;\n}\n\n\n\n\n// Headers\n// ------------------------------\n\n.ListHeader {\n\t.retina-1px-border-top-and-bottom(rgba(0, 0, 0, 0.3));\n\tbackground-color: darken(@body-bg, 3%);\n\tfont-size: @font-size-xs;\n\tfont-weight: 500;\n\tline-height: 2.4;\n\tpadding-left: @font-size-base;\n\ttext-transform: uppercase;\n\tz-index: 1;\n\n\t.ListItem + & {\n\t\tmargin-top: -2px;\n\t}\n}\n.ListHeader--sticky {\n\tpadding-top: 1px; // fix (sortof) jumpy bug with sticky positioning\n\tposition: -webkit-sticky;\n\ttop: -1px; // fix (sortof) jumpy bug with sticky positioning\n}\n\n\n\n\n// Disclosure Arrow\n// ------------------------------\n\n.ListItem__chevron {\n\t.ionicon(inherit, @ionicon-var-chevron-right, @ionicons-size-base);\n}\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "src/css/components/NavigationBar.less",
    "content": "//\n// Animated Navigation Bar\n// ==============================\n\n\n\n\n// Variables\n// ---------------------------\n\n@transition-distance:             125px; // 375/3 (375 = width of iPhone 6)\n@transition-duration:             320ms; // match the view transition duration | TODO: sync this with Touchstone's variables\n@headerbar-gutter:                9px;\n@left-arrow-width:                12px;\n@left-arrow-with-gutter:          @left-arrow-width + (@headerbar-gutter * 2);\n\n\n\n\n// Common\n// ---------------------------\n\n\n/*\n * buttons\n * 1. force hardware accelaration - prepare for animation\n *    removes antialising artefacts left by transform/animation\n * 2. remove browser default styles from <button>\n *    button is used to leverage the [disabled] attribute\n * 3. stops overflow without having to apply overflow:hidden on the wrapper\n * 4. position and stack the element for layout\n **/\n\n.NavigationBarLeftButton,\n.NavigationBarRightButton {\n\t.transition( opacity 80ms );\n\t.translateZ(0); // 1\n\tbackground: none; // 2\n\tcolor: @headerbar-button-color;\n\tborder: none; // 2\n\tbottom: 0;\n\tline-height: @headerbar-height; // 3\n\theight: @headerbar-height; // 3\n\toutline: none; // 2\n\tposition: absolute; // 4\n\tz-index: 2; // 4\n\t-webkit-appearance: none; // 2\n\n\t&[disabled] {\n\t\tcolor: @headerbar-button-color-disabled;\n\t}\n\n\t&.Tappable-active {\n\t\topacity: .5;\n\t}\n}\n\n\n\n\n\n// Base\n// ---------------------------\n\n.NavigationBar {\n\t.box-sizing(content-box); // allows us to set a fixed height whilst growing when padding is applied\n\t.retina-1px-border-bottom( rgba(255, 255, 255, 0.3) );\n\tbackground-color: @headerbar-bg;\n\tline-height: @headerbar-height;\n\theight: @headerbar-height;\n\tposition: relative;\n\tz-index: @view-transition-stack-top + 1;\n\n\t// make room for the iOS statusbar\n\t.device--iOS & {\n\t\tpadding-top: @statusbar-height;\n\t}\n}\n\n\n\n\n// Left Button\n// ---------------------------\n\n// arrow and label position themselves\n\n.NavigationBarLeftButton {}\n\n\n\n\n// Left Icon / Back Chevron (child of left button)\n// ---------------------------\n\n// common\n\n.NavigationBarLeftArrow,\n.NavigationBarLeftIcon {\n\t.translateZ(0);\n\tbottom: 0;\n\tleft: 0;\n\tline-height: inherit;\n\tposition: absolute;\n\ttext-align: center; // center the chevron\n\tvertical-align: top;\n\twidth: @left-arrow-with-gutter;\n\tz-index: 3; // should be the highest element in the navigation bar\n}\n\n// arrow\n\n.NavigationBarLeftArrow {\n\t#gradient .horizontal(@headerbar-bg, fade(@headerbar-bg, 0%), 50%, 100%); // mask the label as it enters and leaves\n\t.ionicon(inherit, @ionicon-var-chevron-left, @ionicons-size-large);\n\tline-height: inherit;\n}\n\n// icon\n\n.NavigationBarLeftIcon {\n\tdisplay: none; // hide from iOS\n\tfont-size: @ionicons-size-large;\n}\n\n\n\n\n// Left Label\n// Child of Left Button\n// ---------------------------\n\n.NavigationBarLeftLabel {\n\t.translateZ(0);\n\tbottom: 0;\n\tcolor: inherit;\n\tdisplay: inline-block;\n\tleft: @headerbar-gutter;\n\tvertical-align: top;\n\tline-height: @headerbar-height;\n\theight: @headerbar-height;\n\tposition: absolute;\n\n\t// FIXME: always offset the label to stop jank\n\t// .has-arrow & {\n\t// \tleft: @left-arrow-with-gutter;\n\t// }\n\tleft: @left-arrow-with-gutter;\n}\n\n\n\n\n// Title\n// ---------------------------\n\n.NavigationBarTitle {\n\tbottom: 0;\n\tfont-weight: 500;\n\theight: @headerbar-height;\n\tleft: 0;\n\tline-height: @headerbar-height;\n\tposition: absolute;\n\ttext-align: center;\n\twidth: 100%;\n\tz-index: 1;\n}\n\n\n\n\n// Right Button\n// ---------------------------\n\n.NavigationBarRightButton {\n\tright: @headerbar-gutter;\n}\n\n\n\n\n// Right Icon\n// ---------------------------\n\n.NavigationBarRightIcon {\n\tfont-size: @ionicons-size-large;\n}\n\n\n\n\n// Animation\n// ---------------------------\n\n// 1. set common duration\n// 2. set common timing function\n// 3. disable user interaction during transitions\n\n.NavigationBarTransition-Instant-enter,\n.NavigationBarTransition-Instant-leave,\n.NavigationBarTransition-Fade-enter,\n.NavigationBarTransition-Fade-leave,\n.NavigationBarTransition-Forwards-enter,\n.NavigationBarTransition-Forwards-leave,\n.NavigationBarTransition-Backwards-enter,\n.NavigationBarTransition-Backwards-leave {\n\t.animation-duration( @transition-duration ); // 1\n\t.animation-timing-function( cubic-bezier(0.645, 0.045, 0.355, 1) ); // 2\n\tpointer-events: none; // 3\n}\n\n// set transition types\n\n.NavigationBarTransition-Fade-enter {\n\t.animation-name( fadeIn );\n}\n.NavigationBarTransition-Fade-leave {\n\t.animation-name( fadeOut );\n}\n.NavigationBarTransition-Forwards-enter {\n\t.animation-name( NavigationBarTransitionForwardsEnter );\n}\n.NavigationBarTransition-Forwards-leave {\n\t.animation-name( NavigationBarTransitionForwardsLeave );\n}\n.NavigationBarTransition-Backwards-enter {\n\t.animation-name( NavigationBarTransitionBackwardsEnter );\n}\n.NavigationBarTransition-Backwards-leave {\n\t.animation-name( NavigationBarTransitionBackwardsLeave );\n}\n\n// instant is a special case. intentionally declared last\n\n.NavigationBarTransition-Instant-enter {\n\t.animation( fadeIn 50ms linear );\n}\n.NavigationBarTransition-Instant-leave {\n\t.animation( fadeOut 50ms linear );\n}\n\n\n// Describe animation keyframes\n\n// header element (forwards) - enter\n@-webkit-keyframes NavigationBarTransitionForwardsEnter {\n\tfrom { opacity: 0; -webkit-transform: translate3d(@transition-distance, 0, 0); }\n\tto   { opacity: 1; -webkit-transform: translate3d(0, 0, 0); }\n}\n@keyframes NavigationBarTransitionForwardsEnter {\n\tfrom { opacity: 0; transform: translate3d(@transition-distance, 0, 0); }\n\tto   { opacity: 1; transform: translate3d(0, 0, 0); }\n}\n\n// header element (forwards) - leave\n@-webkit-keyframes NavigationBarTransitionForwardsLeave {\n\tfrom { opacity: 1; -webkit-transform: translate3d(0, 0, 0); }\n\tto   { opacity: 0; -webkit-transform: translate3d(-@transition-distance, 0, 0); }\n}\n@keyframes NavigationBarTransitionForwardsLeave {\n\tfrom { opacity: 1; transform: translate3d(0, 0, 0); }\n\tto   { opacity: 0; transform: translate3d(-@transition-distance, 0, 0); }\n}\n\n// header element (backwards) - enter\n@-webkit-keyframes NavigationBarTransitionBackwardsEnter {\n\tfrom { opacity: 0; -webkit-transform: translate3d(-@transition-distance, 0, 0); }\n\tto   { opacity: 1; -webkit-transform: translate3d(0, 0, 0); }\n}\n@keyframes NavigationBarTransitionBackwardsEnter {\n\tfrom { opacity: 0; transform: translate3d(-@transition-distance, 0, 0); }\n\tto   { opacity: 1; transform: translate3d(0, 0, 0); }\n}\n\n// header element (backwards) - leave\n@-webkit-keyframes NavigationBarTransitionBackwardsLeave {\n\tfrom { opacity: 1; -webkit-transform: translate3d(0, 0, 0); }\n\tto   { opacity: 0; -webkit-transform: translate3d(@transition-distance, 0, 0); }\n}\n@keyframes NavigationBarTransitionBackwardsLeave {\n\tfrom { opacity: 1; transform: translate3d(0, 0, 0); }\n\tto   { opacity: 0; transform: translate3d(@transition-distance, 0, 0); }\n}\n"
  },
  {
    "path": "src/css/components/PersonItem.less",
    "content": "//\n// Person Item\n// extends \"./list-item\"\n// ==============================\n\n\n\n\n// Star\n// ------------------------------\n\n\n// base\n\n.PersonItem__star {\n\t.ionicon(inherit, @ionicon-var-ios-star-outline, @ionicons-size-base);\n\tmargin-left: .5em;\n\tvertical-align: top;\n}\n\n.PersonItem__starred {\n\t.ionicon(inherit, @ionicon-var-ios-star, @ionicons-size-base);\n\tmargin-left: .5em;\n\tvertical-align: top;\n}\n"
  },
  {
    "path": "src/css/components/ScheduleItem.less",
    "content": "//\n// Schedule Item\n// extends \"./ListItem\"\n// ==============================\n\n\n// fade out past talks\n\n.ScheduleItem.is-past {\n\tbackground-color: transparent;\n\topacity: .33;\n}\n\n\n// remove padding from the left of the content section\n\n.ScheduleItem__content {\n\tpadding-left: 0;\n\tposition: relative;\n}\n\n\n// provide spacing for the avatar + chevron\n\n.ScheduleItem__avatar-chevron {\n\tmargin-left: 1em;\n}\n\n.ScheduleItem__now {\n\t.square(6px);\n\tbackground-color: @app-success;\n\tborder-radius: 50%;\n\tdisplay: block;\n\tleft: -11px;\n\tposition: absolute;\n\ttext-indent: -9999em;\n\ttop: 6px;\n\twhite-space: nowrap;\n}\n\n\n// heading\n\n.ScheduleItem-header-wrapper {\n\t.ScheduleItem + & {\n\t\tmargin-top: -2px;\n\t}\n}\n\n\n// alternative style for \"non-talk\" items\n// disable user interaction on non-talk items\n\n.ScheduleItem--2,\n.ScheduleItem--3,\n.ScheduleItem--4,\n.ScheduleItem--5,\n.ScheduleItem--6,\n.ScheduleItem--8,\n.ScheduleItem--9 {\n\tbackground-color: fade(white, 10%);\n\tpadding-bottom: .5em;\n\tpadding-top: .6em;\n\tpointer-events: none;\n\n\t.ScheduleItem__content {\n\t\tpadding: 0;\n\t}\n\t.ListItem__heading,\n\t.ListItem__text {\n\t\tdisplay: inline-block;\n\t}\n\t.ListItem__heading {\n\t\tfont-size: @font-size-sm;\n\t\tfloat: right;\n\t}\n}\n\n\n// speakers\n\n.ScheduleItem__avatar-img {\n\t& + & {\n\t\tmargin-left: -30px;\n\t}\n}\n"
  },
  {
    "path": "src/css/components/index.less",
    "content": "// \n// Components\n// ==============================\n\n\n\n\n@import \"NavigationBar\";\n@import \"FeedbackModal\";\n@import \"Footerbar\";\n@import \"Headerbar\";\n@import \"ListItem\";\n@import \"PersonItem\";\n@import \"ScheduleItem\";\n"
  },
  {
    "path": "src/css/demo.less",
    "content": "//\n// Demo\n// ==============================\n\n\n\n// Variables\n// ------------------------------\n\n\n@demo-bg:                        darken(@app-primary, 15%);\n\n@iphone4-width:                  320px;\n@iphone4-height:                 480px;\n\n@iphone5-width:                  340px;\n@iphone5-height:                 568px;\n\n@iphone6-width:                  376px;\n@iphone6-height:                 668px;\n\n@device-width:                   @iphone6-width;\n@device-height:                  @iphone6-height;\n\n@silhouette-chrome-vertical:     50px;\n@silhouette-chrome-horizontal:   10px;\n@silhouette-width:               @device-width + (@silhouette-chrome-horizontal * 2);\n@silhouette-height:              @device-height + (@silhouette-chrome-vertical * 2);\n\n\n\n#app {\n\twidth: 100%;\n\theight: 100%;\n\tposition: absolute;\n}\n\n\n// desktop wrapper\n@media only screen and (min-width : 480px) {\n\t#app {\n\t\t#gradient .directional( spin(@demo-bg,-22%), spin(@demo-bg,22%), 135deg );\n\t\tbackground-color: @demo-bg;\n\t}\n\n\t.app-wrapper {\n\t\t.size(@device-width,@device-height);\n\t\tbackground: none;\n\t\tleft: 50%;\n\t\tmargin-left: -(@device-width / 2);\n\t\tmargin-top: -(@device-height / 2);\n\t\toverflow: visible;\n\t\tposition: absolute;\n\t\ttop: 50%;\n\t}\n\n\t// fixes for the desktop\n\t.view,\n\t.loading-overlay,\n\t.Modal,\n\t.Modal-backdrop,\n\t.Keypad {\n\t\tposition: absolute;\n\t}\n\n\t// view\n\t.view-wrapper {\n\t\tbackground: black;\n\t\theight: 100%;\n\t\toverflow: hidden;\n\t\tposition: relative;\n\t\twidth: 100%;\n\t}\n\n\t.device-silhouette {\n\t\t.size(@silhouette-width, @silhouette-height);\n\t\tbackground-color: fade(black, 20%);\n\t\tborder-radius: 20px;\n\t\tmargin: -@silhouette-chrome-vertical -@silhouette-chrome-horizontal;\n\t\tpadding: @silhouette-chrome-vertical @silhouette-chrome-horizontal;\n\t}\n}\n"
  },
  {
    "path": "src/css/ionicons/_ionicons-font.less",
    "content": "// Ionicons Font Path\n// --------------------------\n\n@font-face {\n font-family: @ionicons-font-family;\n src:url(\"@{ionicons-font-path}/ionicons.eot?v=@{ionicons-version}\");\n src:url(\"@{ionicons-font-path}/ionicons.eot?v=@{ionicons-version}#iefix\") format(\"embedded-opentype\"),\n  url(\"@{ionicons-font-path}/ionicons.ttf?v=@{ionicons-version}\") format(\"truetype\"),\n  url(\"@{ionicons-font-path}/ionicons.woff?v=@{ionicons-version}\") format(\"woff\"),\n  url(\"@{ionicons-font-path}/ionicons.svg?v=@{ionicons-version}#Ionicons\") format(\"svg\");\n font-weight: normal;\n font-style: normal;\n}\n\n.ion {\n  display: inline-block;\n  font-family: @ionicons-font-family;\n  speak: none;\n  font-style: normal;\n  font-weight: normal;\n  font-variant: normal;\n  text-transform: none;\n  text-rendering: auto;\n  line-height: 1;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}"
  },
  {
    "path": "src/css/ionicons/_ionicons-icons.less",
    "content": "// Ionicons Icons\n// --------------------------\n\n.ionicons,\n.@{ionicons-prefix}alert:before,\n.@{ionicons-prefix}alert-circled:before,\n.@{ionicons-prefix}android-add:before,\n.@{ionicons-prefix}android-add-circle:before,\n.@{ionicons-prefix}android-alarm-clock:before,\n.@{ionicons-prefix}android-alert:before,\n.@{ionicons-prefix}android-apps:before,\n.@{ionicons-prefix}android-archive:before,\n.@{ionicons-prefix}android-arrow-back:before,\n.@{ionicons-prefix}android-arrow-down:before,\n.@{ionicons-prefix}android-arrow-dropdown:before,\n.@{ionicons-prefix}android-arrow-dropdown-circle:before,\n.@{ionicons-prefix}android-arrow-dropleft:before,\n.@{ionicons-prefix}android-arrow-dropleft-circle:before,\n.@{ionicons-prefix}android-arrow-dropright:before,\n.@{ionicons-prefix}android-arrow-dropright-circle:before,\n.@{ionicons-prefix}android-arrow-dropup:before,\n.@{ionicons-prefix}android-arrow-dropup-circle:before,\n.@{ionicons-prefix}android-arrow-forward:before,\n.@{ionicons-prefix}android-arrow-up:before,\n.@{ionicons-prefix}android-attach:before,\n.@{ionicons-prefix}android-bar:before,\n.@{ionicons-prefix}android-bicycle:before,\n.@{ionicons-prefix}android-boat:before,\n.@{ionicons-prefix}android-bookmark:before,\n.@{ionicons-prefix}android-bulb:before,\n.@{ionicons-prefix}android-bus:before,\n.@{ionicons-prefix}android-calendar:before,\n.@{ionicons-prefix}android-call:before,\n.@{ionicons-prefix}android-camera:before,\n.@{ionicons-prefix}android-cancel:before,\n.@{ionicons-prefix}android-car:before,\n.@{ionicons-prefix}android-cart:before,\n.@{ionicons-prefix}android-chat:before,\n.@{ionicons-prefix}android-checkbox:before,\n.@{ionicons-prefix}android-checkbox-blank:before,\n.@{ionicons-prefix}android-checkbox-outline:before,\n.@{ionicons-prefix}android-checkbox-outline-blank:before,\n.@{ionicons-prefix}android-checkmark-circle:before,\n.@{ionicons-prefix}android-clipboard:before,\n.@{ionicons-prefix}android-close:before,\n.@{ionicons-prefix}android-cloud:before,\n.@{ionicons-prefix}android-cloud-circle:before,\n.@{ionicons-prefix}android-cloud-done:before,\n.@{ionicons-prefix}android-cloud-outline:before,\n.@{ionicons-prefix}android-color-palette:before,\n.@{ionicons-prefix}android-compass:before,\n.@{ionicons-prefix}android-contact:before,\n.@{ionicons-prefix}android-contacts:before,\n.@{ionicons-prefix}android-contract:before,\n.@{ionicons-prefix}android-create:before,\n.@{ionicons-prefix}android-delete:before,\n.@{ionicons-prefix}android-desktop:before,\n.@{ionicons-prefix}android-document:before,\n.@{ionicons-prefix}android-done:before,\n.@{ionicons-prefix}android-done-all:before,\n.@{ionicons-prefix}android-download:before,\n.@{ionicons-prefix}android-drafts:before,\n.@{ionicons-prefix}android-exit:before,\n.@{ionicons-prefix}android-expand:before,\n.@{ionicons-prefix}android-favorite:before,\n.@{ionicons-prefix}android-favorite-outline:before,\n.@{ionicons-prefix}android-film:before,\n.@{ionicons-prefix}android-folder:before,\n.@{ionicons-prefix}android-folder-open:before,\n.@{ionicons-prefix}android-funnel:before,\n.@{ionicons-prefix}android-globe:before,\n.@{ionicons-prefix}android-hand:before,\n.@{ionicons-prefix}android-hangout:before,\n.@{ionicons-prefix}android-happy:before,\n.@{ionicons-prefix}android-home:before,\n.@{ionicons-prefix}android-image:before,\n.@{ionicons-prefix}android-laptop:before,\n.@{ionicons-prefix}android-list:before,\n.@{ionicons-prefix}android-locate:before,\n.@{ionicons-prefix}android-lock:before,\n.@{ionicons-prefix}android-mail:before,\n.@{ionicons-prefix}android-map:before,\n.@{ionicons-prefix}android-menu:before,\n.@{ionicons-prefix}android-microphone:before,\n.@{ionicons-prefix}android-microphone-off:before,\n.@{ionicons-prefix}android-more-horizontal:before,\n.@{ionicons-prefix}android-more-vertical:before,\n.@{ionicons-prefix}android-navigate:before,\n.@{ionicons-prefix}android-notifications:before,\n.@{ionicons-prefix}android-notifications-none:before,\n.@{ionicons-prefix}android-notifications-off:before,\n.@{ionicons-prefix}android-open:before,\n.@{ionicons-prefix}android-options:before,\n.@{ionicons-prefix}android-people:before,\n.@{ionicons-prefix}android-person:before,\n.@{ionicons-prefix}android-person-add:before,\n.@{ionicons-prefix}android-phone-landscape:before,\n.@{ionicons-prefix}android-phone-portrait:before,\n.@{ionicons-prefix}android-pin:before,\n.@{ionicons-prefix}android-plane:before,\n.@{ionicons-prefix}android-playstore:before,\n.@{ionicons-prefix}android-print:before,\n.@{ionicons-prefix}android-radio-button-off:before,\n.@{ionicons-prefix}android-radio-button-on:before,\n.@{ionicons-prefix}android-refresh:before,\n.@{ionicons-prefix}android-remove:before,\n.@{ionicons-prefix}android-remove-circle:before,\n.@{ionicons-prefix}android-restaurant:before,\n.@{ionicons-prefix}android-sad:before,\n.@{ionicons-prefix}android-search:before,\n.@{ionicons-prefix}android-send:before,\n.@{ionicons-prefix}android-settings:before,\n.@{ionicons-prefix}android-share:before,\n.@{ionicons-prefix}android-share-alt:before,\n.@{ionicons-prefix}android-star:before,\n.@{ionicons-prefix}android-star-half:before,\n.@{ionicons-prefix}android-star-outline:before,\n.@{ionicons-prefix}android-stopwatch:before,\n.@{ionicons-prefix}android-subway:before,\n.@{ionicons-prefix}android-sunny:before,\n.@{ionicons-prefix}android-sync:before,\n.@{ionicons-prefix}android-textsms:before,\n.@{ionicons-prefix}android-time:before,\n.@{ionicons-prefix}android-train:before,\n.@{ionicons-prefix}android-unlock:before,\n.@{ionicons-prefix}android-upload:before,\n.@{ionicons-prefix}android-volume-down:before,\n.@{ionicons-prefix}android-volume-mute:before,\n.@{ionicons-prefix}android-volume-off:before,\n.@{ionicons-prefix}android-volume-up:before,\n.@{ionicons-prefix}android-walk:before,\n.@{ionicons-prefix}android-warning:before,\n.@{ionicons-prefix}android-watch:before,\n.@{ionicons-prefix}android-wifi:before,\n.@{ionicons-prefix}aperture:before,\n.@{ionicons-prefix}archive:before,\n.@{ionicons-prefix}arrow-down-a:before,\n.@{ionicons-prefix}arrow-down-b:before,\n.@{ionicons-prefix}arrow-down-c:before,\n.@{ionicons-prefix}arrow-expand:before,\n.@{ionicons-prefix}arrow-graph-down-left:before,\n.@{ionicons-prefix}arrow-graph-down-right:before,\n.@{ionicons-prefix}arrow-graph-up-left:before,\n.@{ionicons-prefix}arrow-graph-up-right:before,\n.@{ionicons-prefix}arrow-left-a:before,\n.@{ionicons-prefix}arrow-left-b:before,\n.@{ionicons-prefix}arrow-left-c:before,\n.@{ionicons-prefix}arrow-move:before,\n.@{ionicons-prefix}arrow-resize:before,\n.@{ionicons-prefix}arrow-return-left:before,\n.@{ionicons-prefix}arrow-return-right:before,\n.@{ionicons-prefix}arrow-right-a:before,\n.@{ionicons-prefix}arrow-right-b:before,\n.@{ionicons-prefix}arrow-right-c:before,\n.@{ionicons-prefix}arrow-shrink:before,\n.@{ionicons-prefix}arrow-swap:before,\n.@{ionicons-prefix}arrow-up-a:before,\n.@{ionicons-prefix}arrow-up-b:before,\n.@{ionicons-prefix}arrow-up-c:before,\n.@{ionicons-prefix}asterisk:before,\n.@{ionicons-prefix}at:before,\n.@{ionicons-prefix}backspace:before,\n.@{ionicons-prefix}backspace-outline:before,\n.@{ionicons-prefix}bag:before,\n.@{ionicons-prefix}battery-charging:before,\n.@{ionicons-prefix}battery-empty:before,\n.@{ionicons-prefix}battery-full:before,\n.@{ionicons-prefix}battery-half:before,\n.@{ionicons-prefix}battery-low:before,\n.@{ionicons-prefix}beaker:before,\n.@{ionicons-prefix}beer:before,\n.@{ionicons-prefix}bluetooth:before,\n.@{ionicons-prefix}bonfire:before,\n.@{ionicons-prefix}bookmark:before,\n.@{ionicons-prefix}bowtie:before,\n.@{ionicons-prefix}briefcase:before,\n.@{ionicons-prefix}bug:before,\n.@{ionicons-prefix}calculator:before,\n.@{ionicons-prefix}calendar:before,\n.@{ionicons-prefix}camera:before,\n.@{ionicons-prefix}card:before,\n.@{ionicons-prefix}cash:before,\n.@{ionicons-prefix}chatbox:before,\n.@{ionicons-prefix}chatbox-working:before,\n.@{ionicons-prefix}chatboxes:before,\n.@{ionicons-prefix}chatbubble:before,\n.@{ionicons-prefix}chatbubble-working:before,\n.@{ionicons-prefix}chatbubbles:before,\n.@{ionicons-prefix}checkmark:before,\n.@{ionicons-prefix}checkmark-circled:before,\n.@{ionicons-prefix}checkmark-round:before,\n.@{ionicons-prefix}chevron-down:before,\n.@{ionicons-prefix}chevron-left:before,\n.@{ionicons-prefix}chevron-right:before,\n.@{ionicons-prefix}chevron-up:before,\n.@{ionicons-prefix}clipboard:before,\n.@{ionicons-prefix}clock:before,\n.@{ionicons-prefix}close:before,\n.@{ionicons-prefix}close-circled:before,\n.@{ionicons-prefix}close-round:before,\n.@{ionicons-prefix}closed-captioning:before,\n.@{ionicons-prefix}cloud:before,\n.@{ionicons-prefix}code:before,\n.@{ionicons-prefix}code-download:before,\n.@{ionicons-prefix}code-working:before,\n.@{ionicons-prefix}coffee:before,\n.@{ionicons-prefix}compass:before,\n.@{ionicons-prefix}compose:before,\n.@{ionicons-prefix}connection-bars:before,\n.@{ionicons-prefix}contrast:before,\n.@{ionicons-prefix}crop:before,\n.@{ionicons-prefix}cube:before,\n.@{ionicons-prefix}disc:before,\n.@{ionicons-prefix}document:before,\n.@{ionicons-prefix}document-text:before,\n.@{ionicons-prefix}drag:before,\n.@{ionicons-prefix}earth:before,\n.@{ionicons-prefix}easel:before,\n.@{ionicons-prefix}edit:before,\n.@{ionicons-prefix}egg:before,\n.@{ionicons-prefix}eject:before,\n.@{ionicons-prefix}email:before,\n.@{ionicons-prefix}email-unread:before,\n.@{ionicons-prefix}erlenmeyer-flask:before,\n.@{ionicons-prefix}erlenmeyer-flask-bubbles:before,\n.@{ionicons-prefix}eye:before,\n.@{ionicons-prefix}eye-disabled:before,\n.@{ionicons-prefix}female:before,\n.@{ionicons-prefix}filing:before,\n.@{ionicons-prefix}film-marker:before,\n.@{ionicons-prefix}fireball:before,\n.@{ionicons-prefix}flag:before,\n.@{ionicons-prefix}flame:before,\n.@{ionicons-prefix}flash:before,\n.@{ionicons-prefix}flash-off:before,\n.@{ionicons-prefix}folder:before,\n.@{ionicons-prefix}fork:before,\n.@{ionicons-prefix}fork-repo:before,\n.@{ionicons-prefix}forward:before,\n.@{ionicons-prefix}funnel:before,\n.@{ionicons-prefix}gear-a:before,\n.@{ionicons-prefix}gear-b:before,\n.@{ionicons-prefix}grid:before,\n.@{ionicons-prefix}hammer:before,\n.@{ionicons-prefix}happy:before,\n.@{ionicons-prefix}happy-outline:before,\n.@{ionicons-prefix}headphone:before,\n.@{ionicons-prefix}heart:before,\n.@{ionicons-prefix}heart-broken:before,\n.@{ionicons-prefix}help:before,\n.@{ionicons-prefix}help-buoy:before,\n.@{ionicons-prefix}help-circled:before,\n.@{ionicons-prefix}home:before,\n.@{ionicons-prefix}icecream:before,\n.@{ionicons-prefix}image:before,\n.@{ionicons-prefix}images:before,\n.@{ionicons-prefix}information:before,\n.@{ionicons-prefix}information-circled:before,\n.@{ionicons-prefix}ionic:before,\n.@{ionicons-prefix}ios-alarm:before,\n.@{ionicons-prefix}ios-alarm-outline:before,\n.@{ionicons-prefix}ios-albums:before,\n.@{ionicons-prefix}ios-albums-outline:before,\n.@{ionicons-prefix}ios-americanfootball:before,\n.@{ionicons-prefix}ios-americanfootball-outline:before,\n.@{ionicons-prefix}ios-analytics:before,\n.@{ionicons-prefix}ios-analytics-outline:before,\n.@{ionicons-prefix}ios-arrow-back:before,\n.@{ionicons-prefix}ios-arrow-down:before,\n.@{ionicons-prefix}ios-arrow-forward:before,\n.@{ionicons-prefix}ios-arrow-left:before,\n.@{ionicons-prefix}ios-arrow-right:before,\n.@{ionicons-prefix}ios-arrow-thin-down:before,\n.@{ionicons-prefix}ios-arrow-thin-left:before,\n.@{ionicons-prefix}ios-arrow-thin-right:before,\n.@{ionicons-prefix}ios-arrow-thin-up:before,\n.@{ionicons-prefix}ios-arrow-up:before,\n.@{ionicons-prefix}ios-at:before,\n.@{ionicons-prefix}ios-at-outline:before,\n.@{ionicons-prefix}ios-barcode:before,\n.@{ionicons-prefix}ios-barcode-outline:before,\n.@{ionicons-prefix}ios-baseball:before,\n.@{ionicons-prefix}ios-baseball-outline:before,\n.@{ionicons-prefix}ios-basketball:before,\n.@{ionicons-prefix}ios-basketball-outline:before,\n.@{ionicons-prefix}ios-bell:before,\n.@{ionicons-prefix}ios-bell-outline:before,\n.@{ionicons-prefix}ios-body:before,\n.@{ionicons-prefix}ios-body-outline:before,\n.@{ionicons-prefix}ios-bolt:before,\n.@{ionicons-prefix}ios-bolt-outline:before,\n.@{ionicons-prefix}ios-book:before,\n.@{ionicons-prefix}ios-book-outline:before,\n.@{ionicons-prefix}ios-bookmarks:before,\n.@{ionicons-prefix}ios-bookmarks-outline:before,\n.@{ionicons-prefix}ios-box:before,\n.@{ionicons-prefix}ios-box-outline:before,\n.@{ionicons-prefix}ios-briefcase:before,\n.@{ionicons-prefix}ios-briefcase-outline:before,\n.@{ionicons-prefix}ios-browsers:before,\n.@{ionicons-prefix}ios-browsers-outline:before,\n.@{ionicons-prefix}ios-calculator:before,\n.@{ionicons-prefix}ios-calculator-outline:before,\n.@{ionicons-prefix}ios-calendar:before,\n.@{ionicons-prefix}ios-calendar-outline:before,\n.@{ionicons-prefix}ios-camera:before,\n.@{ionicons-prefix}ios-camera-outline:before,\n.@{ionicons-prefix}ios-cart:before,\n.@{ionicons-prefix}ios-cart-outline:before,\n.@{ionicons-prefix}ios-chatboxes:before,\n.@{ionicons-prefix}ios-chatboxes-outline:before,\n.@{ionicons-prefix}ios-chatbubble:before,\n.@{ionicons-prefix}ios-chatbubble-outline:before,\n.@{ionicons-prefix}ios-checkmark:before,\n.@{ionicons-prefix}ios-checkmark-empty:before,\n.@{ionicons-prefix}ios-checkmark-outline:before,\n.@{ionicons-prefix}ios-circle-filled:before,\n.@{ionicons-prefix}ios-circle-outline:before,\n.@{ionicons-prefix}ios-clock:before,\n.@{ionicons-prefix}ios-clock-outline:before,\n.@{ionicons-prefix}ios-close:before,\n.@{ionicons-prefix}ios-close-empty:before,\n.@{ionicons-prefix}ios-close-outline:before,\n.@{ionicons-prefix}ios-cloud:before,\n.@{ionicons-prefix}ios-cloud-download:before,\n.@{ionicons-prefix}ios-cloud-download-outline:before,\n.@{ionicons-prefix}ios-cloud-outline:before,\n.@{ionicons-prefix}ios-cloud-upload:before,\n.@{ionicons-prefix}ios-cloud-upload-outline:before,\n.@{ionicons-prefix}ios-cloudy:before,\n.@{ionicons-prefix}ios-cloudy-night:before,\n.@{ionicons-prefix}ios-cloudy-night-outline:before,\n.@{ionicons-prefix}ios-cloudy-outline:before,\n.@{ionicons-prefix}ios-cog:before,\n.@{ionicons-prefix}ios-cog-outline:before,\n.@{ionicons-prefix}ios-color-filter:before,\n.@{ionicons-prefix}ios-color-filter-outline:before,\n.@{ionicons-prefix}ios-color-wand:before,\n.@{ionicons-prefix}ios-color-wand-outline:before,\n.@{ionicons-prefix}ios-compose:before,\n.@{ionicons-prefix}ios-compose-outline:before,\n.@{ionicons-prefix}ios-contact:before,\n.@{ionicons-prefix}ios-contact-outline:before,\n.@{ionicons-prefix}ios-copy:before,\n.@{ionicons-prefix}ios-copy-outline:before,\n.@{ionicons-prefix}ios-crop:before,\n.@{ionicons-prefix}ios-crop-strong:before,\n.@{ionicons-prefix}ios-download:before,\n.@{ionicons-prefix}ios-download-outline:before,\n.@{ionicons-prefix}ios-drag:before,\n.@{ionicons-prefix}ios-email:before,\n.@{ionicons-prefix}ios-email-outline:before,\n.@{ionicons-prefix}ios-eye:before,\n.@{ionicons-prefix}ios-eye-outline:before,\n.@{ionicons-prefix}ios-fastforward:before,\n.@{ionicons-prefix}ios-fastforward-outline:before,\n.@{ionicons-prefix}ios-filing:before,\n.@{ionicons-prefix}ios-filing-outline:before,\n.@{ionicons-prefix}ios-film:before,\n.@{ionicons-prefix}ios-film-outline:before,\n.@{ionicons-prefix}ios-flag:before,\n.@{ionicons-prefix}ios-flag-outline:before,\n.@{ionicons-prefix}ios-flame:before,\n.@{ionicons-prefix}ios-flame-outline:before,\n.@{ionicons-prefix}ios-flask:before,\n.@{ionicons-prefix}ios-flask-outline:before,\n.@{ionicons-prefix}ios-flower:before,\n.@{ionicons-prefix}ios-flower-outline:before,\n.@{ionicons-prefix}ios-folder:before,\n.@{ionicons-prefix}ios-folder-outline:before,\n.@{ionicons-prefix}ios-football:before,\n.@{ionicons-prefix}ios-football-outline:before,\n.@{ionicons-prefix}ios-game-controller-a:before,\n.@{ionicons-prefix}ios-game-controller-a-outline:before,\n.@{ionicons-prefix}ios-game-controller-b:before,\n.@{ionicons-prefix}ios-game-controller-b-outline:before,\n.@{ionicons-prefix}ios-gear:before,\n.@{ionicons-prefix}ios-gear-outline:before,\n.@{ionicons-prefix}ios-glasses:before,\n.@{ionicons-prefix}ios-glasses-outline:before,\n.@{ionicons-prefix}ios-grid-view:before,\n.@{ionicons-prefix}ios-grid-view-outline:before,\n.@{ionicons-prefix}ios-heart:before,\n.@{ionicons-prefix}ios-heart-outline:before,\n.@{ionicons-prefix}ios-help:before,\n.@{ionicons-prefix}ios-help-empty:before,\n.@{ionicons-prefix}ios-help-outline:before,\n.@{ionicons-prefix}ios-home:before,\n.@{ionicons-prefix}ios-home-outline:before,\n.@{ionicons-prefix}ios-infinite:before,\n.@{ionicons-prefix}ios-infinite-outline:before,\n.@{ionicons-prefix}ios-information:before,\n.@{ionicons-prefix}ios-information-empty:before,\n.@{ionicons-prefix}ios-information-outline:before,\n.@{ionicons-prefix}ios-ionic-outline:before,\n.@{ionicons-prefix}ios-keypad:before,\n.@{ionicons-prefix}ios-keypad-outline:before,\n.@{ionicons-prefix}ios-lightbulb:before,\n.@{ionicons-prefix}ios-lightbulb-outline:before,\n.@{ionicons-prefix}ios-list:before,\n.@{ionicons-prefix}ios-list-outline:before,\n.@{ionicons-prefix}ios-location:before,\n.@{ionicons-prefix}ios-location-outline:before,\n.@{ionicons-prefix}ios-locked:before,\n.@{ionicons-prefix}ios-locked-outline:before,\n.@{ionicons-prefix}ios-loop:before,\n.@{ionicons-prefix}ios-loop-strong:before,\n.@{ionicons-prefix}ios-medical:before,\n.@{ionicons-prefix}ios-medical-outline:before,\n.@{ionicons-prefix}ios-medkit:before,\n.@{ionicons-prefix}ios-medkit-outline:before,\n.@{ionicons-prefix}ios-mic:before,\n.@{ionicons-prefix}ios-mic-off:before,\n.@{ionicons-prefix}ios-mic-outline:before,\n.@{ionicons-prefix}ios-minus:before,\n.@{ionicons-prefix}ios-minus-empty:before,\n.@{ionicons-prefix}ios-minus-outline:before,\n.@{ionicons-prefix}ios-monitor:before,\n.@{ionicons-prefix}ios-monitor-outline:before,\n.@{ionicons-prefix}ios-moon:before,\n.@{ionicons-prefix}ios-moon-outline:before,\n.@{ionicons-prefix}ios-more:before,\n.@{ionicons-prefix}ios-more-outline:before,\n.@{ionicons-prefix}ios-musical-note:before,\n.@{ionicons-prefix}ios-musical-notes:before,\n.@{ionicons-prefix}ios-navigate:before,\n.@{ionicons-prefix}ios-navigate-outline:before,\n.@{ionicons-prefix}ios-nutrition:before,\n.@{ionicons-prefix}ios-nutrition-outline:before,\n.@{ionicons-prefix}ios-paper:before,\n.@{ionicons-prefix}ios-paper-outline:before,\n.@{ionicons-prefix}ios-paperplane:before,\n.@{ionicons-prefix}ios-paperplane-outline:before,\n.@{ionicons-prefix}ios-partlysunny:before,\n.@{ionicons-prefix}ios-partlysunny-outline:before,\n.@{ionicons-prefix}ios-pause:before,\n.@{ionicons-prefix}ios-pause-outline:before,\n.@{ionicons-prefix}ios-paw:before,\n.@{ionicons-prefix}ios-paw-outline:before,\n.@{ionicons-prefix}ios-people:before,\n.@{ionicons-prefix}ios-people-outline:before,\n.@{ionicons-prefix}ios-person:before,\n.@{ionicons-prefix}ios-person-outline:before,\n.@{ionicons-prefix}ios-personadd:before,\n.@{ionicons-prefix}ios-personadd-outline:before,\n.@{ionicons-prefix}ios-photos:before,\n.@{ionicons-prefix}ios-photos-outline:before,\n.@{ionicons-prefix}ios-pie:before,\n.@{ionicons-prefix}ios-pie-outline:before,\n.@{ionicons-prefix}ios-pint:before,\n.@{ionicons-prefix}ios-pint-outline:before,\n.@{ionicons-prefix}ios-play:before,\n.@{ionicons-prefix}ios-play-outline:before,\n.@{ionicons-prefix}ios-plus:before,\n.@{ionicons-prefix}ios-plus-empty:before,\n.@{ionicons-prefix}ios-plus-outline:before,\n.@{ionicons-prefix}ios-pricetag:before,\n.@{ionicons-prefix}ios-pricetag-outline:before,\n.@{ionicons-prefix}ios-pricetags:before,\n.@{ionicons-prefix}ios-pricetags-outline:before,\n.@{ionicons-prefix}ios-printer:before,\n.@{ionicons-prefix}ios-printer-outline:before,\n.@{ionicons-prefix}ios-pulse:before,\n.@{ionicons-prefix}ios-pulse-strong:before,\n.@{ionicons-prefix}ios-rainy:before,\n.@{ionicons-prefix}ios-rainy-outline:before,\n.@{ionicons-prefix}ios-recording:before,\n.@{ionicons-prefix}ios-recording-outline:before,\n.@{ionicons-prefix}ios-redo:before,\n.@{ionicons-prefix}ios-redo-outline:before,\n.@{ionicons-prefix}ios-refresh:before,\n.@{ionicons-prefix}ios-refresh-empty:before,\n.@{ionicons-prefix}ios-refresh-outline:before,\n.@{ionicons-prefix}ios-reload:before,\n.@{ionicons-prefix}ios-reverse-camera:before,\n.@{ionicons-prefix}ios-reverse-camera-outline:before,\n.@{ionicons-prefix}ios-rewind:before,\n.@{ionicons-prefix}ios-rewind-outline:before,\n.@{ionicons-prefix}ios-rose:before,\n.@{ionicons-prefix}ios-rose-outline:before,\n.@{ionicons-prefix}ios-search:before,\n.@{ionicons-prefix}ios-search-strong:before,\n.@{ionicons-prefix}ios-settings:before,\n.@{ionicons-prefix}ios-settings-strong:before,\n.@{ionicons-prefix}ios-shuffle:before,\n.@{ionicons-prefix}ios-shuffle-strong:before,\n.@{ionicons-prefix}ios-skipbackward:before,\n.@{ionicons-prefix}ios-skipbackward-outline:before,\n.@{ionicons-prefix}ios-skipforward:before,\n.@{ionicons-prefix}ios-skipforward-outline:before,\n.@{ionicons-prefix}ios-snowy:before,\n.@{ionicons-prefix}ios-speedometer:before,\n.@{ionicons-prefix}ios-speedometer-outline:before,\n.@{ionicons-prefix}ios-star:before,\n.@{ionicons-prefix}ios-star-half:before,\n.@{ionicons-prefix}ios-star-outline:before,\n.@{ionicons-prefix}ios-stopwatch:before,\n.@{ionicons-prefix}ios-stopwatch-outline:before,\n.@{ionicons-prefix}ios-sunny:before,\n.@{ionicons-prefix}ios-sunny-outline:before,\n.@{ionicons-prefix}ios-telephone:before,\n.@{ionicons-prefix}ios-telephone-outline:before,\n.@{ionicons-prefix}ios-tennisball:before,\n.@{ionicons-prefix}ios-tennisball-outline:before,\n.@{ionicons-prefix}ios-thunderstorm:before,\n.@{ionicons-prefix}ios-thunderstorm-outline:before,\n.@{ionicons-prefix}ios-time:before,\n.@{ionicons-prefix}ios-time-outline:before,\n.@{ionicons-prefix}ios-timer:before,\n.@{ionicons-prefix}ios-timer-outline:before,\n.@{ionicons-prefix}ios-toggle:before,\n.@{ionicons-prefix}ios-toggle-outline:before,\n.@{ionicons-prefix}ios-trash:before,\n.@{ionicons-prefix}ios-trash-outline:before,\n.@{ionicons-prefix}ios-undo:before,\n.@{ionicons-prefix}ios-undo-outline:before,\n.@{ionicons-prefix}ios-unlocked:before,\n.@{ionicons-prefix}ios-unlocked-outline:before,\n.@{ionicons-prefix}ios-upload:before,\n.@{ionicons-prefix}ios-upload-outline:before,\n.@{ionicons-prefix}ios-videocam:before,\n.@{ionicons-prefix}ios-videocam-outline:before,\n.@{ionicons-prefix}ios-volume-high:before,\n.@{ionicons-prefix}ios-volume-low:before,\n.@{ionicons-prefix}ios-wineglass:before,\n.@{ionicons-prefix}ios-wineglass-outline:before,\n.@{ionicons-prefix}ios-world:before,\n.@{ionicons-prefix}ios-world-outline:before,\n.@{ionicons-prefix}ipad:before,\n.@{ionicons-prefix}iphone:before,\n.@{ionicons-prefix}ipod:before,\n.@{ionicons-prefix}jet:before,\n.@{ionicons-prefix}key:before,\n.@{ionicons-prefix}knife:before,\n.@{ionicons-prefix}laptop:before,\n.@{ionicons-prefix}leaf:before,\n.@{ionicons-prefix}levels:before,\n.@{ionicons-prefix}lightbulb:before,\n.@{ionicons-prefix}link:before,\n.@{ionicons-prefix}load-a:before,\n.@{ionicons-prefix}load-b:before,\n.@{ionicons-prefix}load-c:before,\n.@{ionicons-prefix}load-d:before,\n.@{ionicons-prefix}location:before,\n.@{ionicons-prefix}lock-combination:before,\n.@{ionicons-prefix}locked:before,\n.@{ionicons-prefix}log-in:before,\n.@{ionicons-prefix}log-out:before,\n.@{ionicons-prefix}loop:before,\n.@{ionicons-prefix}magnet:before,\n.@{ionicons-prefix}male:before,\n.@{ionicons-prefix}man:before,\n.@{ionicons-prefix}map:before,\n.@{ionicons-prefix}medkit:before,\n.@{ionicons-prefix}merge:before,\n.@{ionicons-prefix}mic-a:before,\n.@{ionicons-prefix}mic-b:before,\n.@{ionicons-prefix}mic-c:before,\n.@{ionicons-prefix}minus:before,\n.@{ionicons-prefix}minus-circled:before,\n.@{ionicons-prefix}minus-round:before,\n.@{ionicons-prefix}model-s:before,\n.@{ionicons-prefix}monitor:before,\n.@{ionicons-prefix}more:before,\n.@{ionicons-prefix}mouse:before,\n.@{ionicons-prefix}music-note:before,\n.@{ionicons-prefix}navicon:before,\n.@{ionicons-prefix}navicon-round:before,\n.@{ionicons-prefix}navigate:before,\n.@{ionicons-prefix}network:before,\n.@{ionicons-prefix}no-smoking:before,\n.@{ionicons-prefix}nuclear:before,\n.@{ionicons-prefix}outlet:before,\n.@{ionicons-prefix}paintbrush:before,\n.@{ionicons-prefix}paintbucket:before,\n.@{ionicons-prefix}paper-airplane:before,\n.@{ionicons-prefix}paperclip:before,\n.@{ionicons-prefix}pause:before,\n.@{ionicons-prefix}person:before,\n.@{ionicons-prefix}person-add:before,\n.@{ionicons-prefix}person-stalker:before,\n.@{ionicons-prefix}pie-graph:before,\n.@{ionicons-prefix}pin:before,\n.@{ionicons-prefix}pinpoint:before,\n.@{ionicons-prefix}pizza:before,\n.@{ionicons-prefix}plane:before,\n.@{ionicons-prefix}planet:before,\n.@{ionicons-prefix}play:before,\n.@{ionicons-prefix}playstation:before,\n.@{ionicons-prefix}plus:before,\n.@{ionicons-prefix}plus-circled:before,\n.@{ionicons-prefix}plus-round:before,\n.@{ionicons-prefix}podium:before,\n.@{ionicons-prefix}pound:before,\n.@{ionicons-prefix}power:before,\n.@{ionicons-prefix}pricetag:before,\n.@{ionicons-prefix}pricetags:before,\n.@{ionicons-prefix}printer:before,\n.@{ionicons-prefix}pull-request:before,\n.@{ionicons-prefix}qr-scanner:before,\n.@{ionicons-prefix}quote:before,\n.@{ionicons-prefix}radio-waves:before,\n.@{ionicons-prefix}record:before,\n.@{ionicons-prefix}refresh:before,\n.@{ionicons-prefix}reply:before,\n.@{ionicons-prefix}reply-all:before,\n.@{ionicons-prefix}ribbon-a:before,\n.@{ionicons-prefix}ribbon-b:before,\n.@{ionicons-prefix}sad:before,\n.@{ionicons-prefix}sad-outline:before,\n.@{ionicons-prefix}scissors:before,\n.@{ionicons-prefix}search:before,\n.@{ionicons-prefix}settings:before,\n.@{ionicons-prefix}share:before,\n.@{ionicons-prefix}shuffle:before,\n.@{ionicons-prefix}skip-backward:before,\n.@{ionicons-prefix}skip-forward:before,\n.@{ionicons-prefix}social-android:before,\n.@{ionicons-prefix}social-android-outline:before,\n.@{ionicons-prefix}social-angular:before,\n.@{ionicons-prefix}social-angular-outline:before,\n.@{ionicons-prefix}social-apple:before,\n.@{ionicons-prefix}social-apple-outline:before,\n.@{ionicons-prefix}social-bitcoin:before,\n.@{ionicons-prefix}social-bitcoin-outline:before,\n.@{ionicons-prefix}social-buffer:before,\n.@{ionicons-prefix}social-buffer-outline:before,\n.@{ionicons-prefix}social-chrome:before,\n.@{ionicons-prefix}social-chrome-outline:before,\n.@{ionicons-prefix}social-codepen:before,\n.@{ionicons-prefix}social-codepen-outline:before,\n.@{ionicons-prefix}social-css3:before,\n.@{ionicons-prefix}social-css3-outline:before,\n.@{ionicons-prefix}social-designernews:before,\n.@{ionicons-prefix}social-designernews-outline:before,\n.@{ionicons-prefix}social-dribbble:before,\n.@{ionicons-prefix}social-dribbble-outline:before,\n.@{ionicons-prefix}social-dropbox:before,\n.@{ionicons-prefix}social-dropbox-outline:before,\n.@{ionicons-prefix}social-euro:before,\n.@{ionicons-prefix}social-euro-outline:before,\n.@{ionicons-prefix}social-facebook:before,\n.@{ionicons-prefix}social-facebook-outline:before,\n.@{ionicons-prefix}social-foursquare:before,\n.@{ionicons-prefix}social-foursquare-outline:before,\n.@{ionicons-prefix}social-freebsd-devil:before,\n.@{ionicons-prefix}social-github:before,\n.@{ionicons-prefix}social-github-outline:before,\n.@{ionicons-prefix}social-google:before,\n.@{ionicons-prefix}social-google-outline:before,\n.@{ionicons-prefix}social-googleplus:before,\n.@{ionicons-prefix}social-googleplus-outline:before,\n.@{ionicons-prefix}social-hackernews:before,\n.@{ionicons-prefix}social-hackernews-outline:before,\n.@{ionicons-prefix}social-html5:before,\n.@{ionicons-prefix}social-html5-outline:before,\n.@{ionicons-prefix}social-instagram:before,\n.@{ionicons-prefix}social-instagram-outline:before,\n.@{ionicons-prefix}social-javascript:before,\n.@{ionicons-prefix}social-javascript-outline:before,\n.@{ionicons-prefix}social-linkedin:before,\n.@{ionicons-prefix}social-linkedin-outline:before,\n.@{ionicons-prefix}social-markdown:before,\n.@{ionicons-prefix}social-nodejs:before,\n.@{ionicons-prefix}social-octocat:before,\n.@{ionicons-prefix}social-pinterest:before,\n.@{ionicons-prefix}social-pinterest-outline:before,\n.@{ionicons-prefix}social-python:before,\n.@{ionicons-prefix}social-reddit:before,\n.@{ionicons-prefix}social-reddit-outline:before,\n.@{ionicons-prefix}social-rss:before,\n.@{ionicons-prefix}social-rss-outline:before,\n.@{ionicons-prefix}social-sass:before,\n.@{ionicons-prefix}social-skype:before,\n.@{ionicons-prefix}social-skype-outline:before,\n.@{ionicons-prefix}social-snapchat:before,\n.@{ionicons-prefix}social-snapchat-outline:before,\n.@{ionicons-prefix}social-tumblr:before,\n.@{ionicons-prefix}social-tumblr-outline:before,\n.@{ionicons-prefix}social-tux:before,\n.@{ionicons-prefix}social-twitch:before,\n.@{ionicons-prefix}social-twitch-outline:before,\n.@{ionicons-prefix}social-twitter:before,\n.@{ionicons-prefix}social-twitter-outline:before,\n.@{ionicons-prefix}social-usd:before,\n.@{ionicons-prefix}social-usd-outline:before,\n.@{ionicons-prefix}social-vimeo:before,\n.@{ionicons-prefix}social-vimeo-outline:before,\n.@{ionicons-prefix}social-whatsapp:before,\n.@{ionicons-prefix}social-whatsapp-outline:before,\n.@{ionicons-prefix}social-windows:before,\n.@{ionicons-prefix}social-windows-outline:before,\n.@{ionicons-prefix}social-wordpress:before,\n.@{ionicons-prefix}social-wordpress-outline:before,\n.@{ionicons-prefix}social-yahoo:before,\n.@{ionicons-prefix}social-yahoo-outline:before,\n.@{ionicons-prefix}social-yen:before,\n.@{ionicons-prefix}social-yen-outline:before,\n.@{ionicons-prefix}social-youtube:before,\n.@{ionicons-prefix}social-youtube-outline:before,\n.@{ionicons-prefix}soup-can:before,\n.@{ionicons-prefix}soup-can-outline:before,\n.@{ionicons-prefix}speakerphone:before,\n.@{ionicons-prefix}speedometer:before,\n.@{ionicons-prefix}spoon:before,\n.@{ionicons-prefix}star:before,\n.@{ionicons-prefix}stats-bars:before,\n.@{ionicons-prefix}steam:before,\n.@{ionicons-prefix}stop:before,\n.@{ionicons-prefix}thermometer:before,\n.@{ionicons-prefix}thumbsdown:before,\n.@{ionicons-prefix}thumbsup:before,\n.@{ionicons-prefix}toggle:before,\n.@{ionicons-prefix}toggle-filled:before,\n.@{ionicons-prefix}transgender:before,\n.@{ionicons-prefix}trash-a:before,\n.@{ionicons-prefix}trash-b:before,\n.@{ionicons-prefix}trophy:before,\n.@{ionicons-prefix}tshirt:before,\n.@{ionicons-prefix}tshirt-outline:before,\n.@{ionicons-prefix}umbrella:before,\n.@{ionicons-prefix}university:before,\n.@{ionicons-prefix}unlocked:before,\n.@{ionicons-prefix}upload:before,\n.@{ionicons-prefix}usb:before,\n.@{ionicons-prefix}videocamera:before,\n.@{ionicons-prefix}volume-high:before,\n.@{ionicons-prefix}volume-low:before,\n.@{ionicons-prefix}volume-medium:before,\n.@{ionicons-prefix}volume-mute:before,\n.@{ionicons-prefix}wand:before,\n.@{ionicons-prefix}waterdrop:before,\n.@{ionicons-prefix}wifi:before,\n.@{ionicons-prefix}wineglass:before,\n.@{ionicons-prefix}woman:before,\n.@{ionicons-prefix}wrench:before,\n.@{ionicons-prefix}xbox:before\n{\n  &:extend(.ion);\n}\n.@{ionicons-prefix}alert:before { content: @ionicon-var-alert; }\n.@{ionicons-prefix}alert-circled:before { content: @ionicon-var-alert-circled; }\n.@{ionicons-prefix}android-add:before { content: @ionicon-var-android-add; }\n.@{ionicons-prefix}android-add-circle:before { content: @ionicon-var-android-add-circle; }\n.@{ionicons-prefix}android-alarm-clock:before { content: @ionicon-var-android-alarm-clock; }\n.@{ionicons-prefix}android-alert:before { content: @ionicon-var-android-alert; }\n.@{ionicons-prefix}android-apps:before { content: @ionicon-var-android-apps; }\n.@{ionicons-prefix}android-archive:before { content: @ionicon-var-android-archive; }\n.@{ionicons-prefix}android-arrow-back:before { content: @ionicon-var-android-arrow-back; }\n.@{ionicons-prefix}android-arrow-down:before { content: @ionicon-var-android-arrow-down; }\n.@{ionicons-prefix}android-arrow-dropdown:before { content: @ionicon-var-android-arrow-dropdown; }\n.@{ionicons-prefix}android-arrow-dropdown-circle:before { content: @ionicon-var-android-arrow-dropdown-circle; }\n.@{ionicons-prefix}android-arrow-dropleft:before { content: @ionicon-var-android-arrow-dropleft; }\n.@{ionicons-prefix}android-arrow-dropleft-circle:before { content: @ionicon-var-android-arrow-dropleft-circle; }\n.@{ionicons-prefix}android-arrow-dropright:before { content: @ionicon-var-android-arrow-dropright; }\n.@{ionicons-prefix}android-arrow-dropright-circle:before { content: @ionicon-var-android-arrow-dropright-circle; }\n.@{ionicons-prefix}android-arrow-dropup:before { content: @ionicon-var-android-arrow-dropup; }\n.@{ionicons-prefix}android-arrow-dropup-circle:before { content: @ionicon-var-android-arrow-dropup-circle; }\n.@{ionicons-prefix}android-arrow-forward:before { content: @ionicon-var-android-arrow-forward; }\n.@{ionicons-prefix}android-arrow-up:before { content: @ionicon-var-android-arrow-up; }\n.@{ionicons-prefix}android-attach:before { content: @ionicon-var-android-attach; }\n.@{ionicons-prefix}android-bar:before { content: @ionicon-var-android-bar; }\n.@{ionicons-prefix}android-bicycle:before { content: @ionicon-var-android-bicycle; }\n.@{ionicons-prefix}android-boat:before { content: @ionicon-var-android-boat; }\n.@{ionicons-prefix}android-bookmark:before { content: @ionicon-var-android-bookmark; }\n.@{ionicons-prefix}android-bulb:before { content: @ionicon-var-android-bulb; }\n.@{ionicons-prefix}android-bus:before { content: @ionicon-var-android-bus; }\n.@{ionicons-prefix}android-calendar:before { content: @ionicon-var-android-calendar; }\n.@{ionicons-prefix}android-call:before { content: @ionicon-var-android-call; }\n.@{ionicons-prefix}android-camera:before { content: @ionicon-var-android-camera; }\n.@{ionicons-prefix}android-cancel:before { content: @ionicon-var-android-cancel; }\n.@{ionicons-prefix}android-car:before { content: @ionicon-var-android-car; }\n.@{ionicons-prefix}android-cart:before { content: @ionicon-var-android-cart; }\n.@{ionicons-prefix}android-chat:before { content: @ionicon-var-android-chat; }\n.@{ionicons-prefix}android-checkbox:before { content: @ionicon-var-android-checkbox; }\n.@{ionicons-prefix}android-checkbox-blank:before { content: @ionicon-var-android-checkbox-blank; }\n.@{ionicons-prefix}android-checkbox-outline:before { content: @ionicon-var-android-checkbox-outline; }\n.@{ionicons-prefix}android-checkbox-outline-blank:before { content: @ionicon-var-android-checkbox-outline-blank; }\n.@{ionicons-prefix}android-checkmark-circle:before { content: @ionicon-var-android-checkmark-circle; }\n.@{ionicons-prefix}android-clipboard:before { content: @ionicon-var-android-clipboard; }\n.@{ionicons-prefix}android-close:before { content: @ionicon-var-android-close; }\n.@{ionicons-prefix}android-cloud:before { content: @ionicon-var-android-cloud; }\n.@{ionicons-prefix}android-cloud-circle:before { content: @ionicon-var-android-cloud-circle; }\n.@{ionicons-prefix}android-cloud-done:before { content: @ionicon-var-android-cloud-done; }\n.@{ionicons-prefix}android-cloud-outline:before { content: @ionicon-var-android-cloud-outline; }\n.@{ionicons-prefix}android-color-palette:before { content: @ionicon-var-android-color-palette; }\n.@{ionicons-prefix}android-compass:before { content: @ionicon-var-android-compass; }\n.@{ionicons-prefix}android-contact:before { content: @ionicon-var-android-contact; }\n.@{ionicons-prefix}android-contacts:before { content: @ionicon-var-android-contacts; }\n.@{ionicons-prefix}android-contract:before { content: @ionicon-var-android-contract; }\n.@{ionicons-prefix}android-create:before { content: @ionicon-var-android-create; }\n.@{ionicons-prefix}android-delete:before { content: @ionicon-var-android-delete; }\n.@{ionicons-prefix}android-desktop:before { content: @ionicon-var-android-desktop; }\n.@{ionicons-prefix}android-document:before { content: @ionicon-var-android-document; }\n.@{ionicons-prefix}android-done:before { content: @ionicon-var-android-done; }\n.@{ionicons-prefix}android-done-all:before { content: @ionicon-var-android-done-all; }\n.@{ionicons-prefix}android-download:before { content: @ionicon-var-android-download; }\n.@{ionicons-prefix}android-drafts:before { content: @ionicon-var-android-drafts; }\n.@{ionicons-prefix}android-exit:before { content: @ionicon-var-android-exit; }\n.@{ionicons-prefix}android-expand:before { content: @ionicon-var-android-expand; }\n.@{ionicons-prefix}android-favorite:before { content: @ionicon-var-android-favorite; }\n.@{ionicons-prefix}android-favorite-outline:before { content: @ionicon-var-android-favorite-outline; }\n.@{ionicons-prefix}android-film:before { content: @ionicon-var-android-film; }\n.@{ionicons-prefix}android-folder:before { content: @ionicon-var-android-folder; }\n.@{ionicons-prefix}android-folder-open:before { content: @ionicon-var-android-folder-open; }\n.@{ionicons-prefix}android-funnel:before { content: @ionicon-var-android-funnel; }\n.@{ionicons-prefix}android-globe:before { content: @ionicon-var-android-globe; }\n.@{ionicons-prefix}android-hand:before { content: @ionicon-var-android-hand; }\n.@{ionicons-prefix}android-hangout:before { content: @ionicon-var-android-hangout; }\n.@{ionicons-prefix}android-happy:before { content: @ionicon-var-android-happy; }\n.@{ionicons-prefix}android-home:before { content: @ionicon-var-android-home; }\n.@{ionicons-prefix}android-image:before { content: @ionicon-var-android-image; }\n.@{ionicons-prefix}android-laptop:before { content: @ionicon-var-android-laptop; }\n.@{ionicons-prefix}android-list:before { content: @ionicon-var-android-list; }\n.@{ionicons-prefix}android-locate:before { content: @ionicon-var-android-locate; }\n.@{ionicons-prefix}android-lock:before { content: @ionicon-var-android-lock; }\n.@{ionicons-prefix}android-mail:before { content: @ionicon-var-android-mail; }\n.@{ionicons-prefix}android-map:before { content: @ionicon-var-android-map; }\n.@{ionicons-prefix}android-menu:before { content: @ionicon-var-android-menu; }\n.@{ionicons-prefix}android-microphone:before { content: @ionicon-var-android-microphone; }\n.@{ionicons-prefix}android-microphone-off:before { content: @ionicon-var-android-microphone-off; }\n.@{ionicons-prefix}android-more-horizontal:before { content: @ionicon-var-android-more-horizontal; }\n.@{ionicons-prefix}android-more-vertical:before { content: @ionicon-var-android-more-vertical; }\n.@{ionicons-prefix}android-navigate:before { content: @ionicon-var-android-navigate; }\n.@{ionicons-prefix}android-notifications:before { content: @ionicon-var-android-notifications; }\n.@{ionicons-prefix}android-notifications-none:before { content: @ionicon-var-android-notifications-none; }\n.@{ionicons-prefix}android-notifications-off:before { content: @ionicon-var-android-notifications-off; }\n.@{ionicons-prefix}android-open:before { content: @ionicon-var-android-open; }\n.@{ionicons-prefix}android-options:before { content: @ionicon-var-android-options; }\n.@{ionicons-prefix}android-people:before { content: @ionicon-var-android-people; }\n.@{ionicons-prefix}android-person:before { content: @ionicon-var-android-person; }\n.@{ionicons-prefix}android-person-add:before { content: @ionicon-var-android-person-add; }\n.@{ionicons-prefix}android-phone-landscape:before { content: @ionicon-var-android-phone-landscape; }\n.@{ionicons-prefix}android-phone-portrait:before { content: @ionicon-var-android-phone-portrait; }\n.@{ionicons-prefix}android-pin:before { content: @ionicon-var-android-pin; }\n.@{ionicons-prefix}android-plane:before { content: @ionicon-var-android-plane; }\n.@{ionicons-prefix}android-playstore:before { content: @ionicon-var-android-playstore; }\n.@{ionicons-prefix}android-print:before { content: @ionicon-var-android-print; }\n.@{ionicons-prefix}android-radio-button-off:before { content: @ionicon-var-android-radio-button-off; }\n.@{ionicons-prefix}android-radio-button-on:before { content: @ionicon-var-android-radio-button-on; }\n.@{ionicons-prefix}android-refresh:before { content: @ionicon-var-android-refresh; }\n.@{ionicons-prefix}android-remove:before { content: @ionicon-var-android-remove; }\n.@{ionicons-prefix}android-remove-circle:before { content: @ionicon-var-android-remove-circle; }\n.@{ionicons-prefix}android-restaurant:before { content: @ionicon-var-android-restaurant; }\n.@{ionicons-prefix}android-sad:before { content: @ionicon-var-android-sad; }\n.@{ionicons-prefix}android-search:before { content: @ionicon-var-android-search; }\n.@{ionicons-prefix}android-send:before { content: @ionicon-var-android-send; }\n.@{ionicons-prefix}android-settings:before { content: @ionicon-var-android-settings; }\n.@{ionicons-prefix}android-share:before { content: @ionicon-var-android-share; }\n.@{ionicons-prefix}android-share-alt:before { content: @ionicon-var-android-share-alt; }\n.@{ionicons-prefix}android-star:before { content: @ionicon-var-android-star; }\n.@{ionicons-prefix}android-star-half:before { content: @ionicon-var-android-star-half; }\n.@{ionicons-prefix}android-star-outline:before { content: @ionicon-var-android-star-outline; }\n.@{ionicons-prefix}android-stopwatch:before { content: @ionicon-var-android-stopwatch; }\n.@{ionicons-prefix}android-subway:before { content: @ionicon-var-android-subway; }\n.@{ionicons-prefix}android-sunny:before { content: @ionicon-var-android-sunny; }\n.@{ionicons-prefix}android-sync:before { content: @ionicon-var-android-sync; }\n.@{ionicons-prefix}android-textsms:before { content: @ionicon-var-android-textsms; }\n.@{ionicons-prefix}android-time:before { content: @ionicon-var-android-time; }\n.@{ionicons-prefix}android-train:before { content: @ionicon-var-android-train; }\n.@{ionicons-prefix}android-unlock:before { content: @ionicon-var-android-unlock; }\n.@{ionicons-prefix}android-upload:before { content: @ionicon-var-android-upload; }\n.@{ionicons-prefix}android-volume-down:before { content: @ionicon-var-android-volume-down; }\n.@{ionicons-prefix}android-volume-mute:before { content: @ionicon-var-android-volume-mute; }\n.@{ionicons-prefix}android-volume-off:before { content: @ionicon-var-android-volume-off; }\n.@{ionicons-prefix}android-volume-up:before { content: @ionicon-var-android-volume-up; }\n.@{ionicons-prefix}android-walk:before { content: @ionicon-var-android-walk; }\n.@{ionicons-prefix}android-warning:before { content: @ionicon-var-android-warning; }\n.@{ionicons-prefix}android-watch:before { content: @ionicon-var-android-watch; }\n.@{ionicons-prefix}android-wifi:before { content: @ionicon-var-android-wifi; }\n.@{ionicons-prefix}aperture:before { content: @ionicon-var-aperture; }\n.@{ionicons-prefix}archive:before { content: @ionicon-var-archive; }\n.@{ionicons-prefix}arrow-down-a:before { content: @ionicon-var-arrow-down-a; }\n.@{ionicons-prefix}arrow-down-b:before { content: @ionicon-var-arrow-down-b; }\n.@{ionicons-prefix}arrow-down-c:before { content: @ionicon-var-arrow-down-c; }\n.@{ionicons-prefix}arrow-expand:before { content: @ionicon-var-arrow-expand; }\n.@{ionicons-prefix}arrow-graph-down-left:before { content: @ionicon-var-arrow-graph-down-left; }\n.@{ionicons-prefix}arrow-graph-down-right:before { content: @ionicon-var-arrow-graph-down-right; }\n.@{ionicons-prefix}arrow-graph-up-left:before { content: @ionicon-var-arrow-graph-up-left; }\n.@{ionicons-prefix}arrow-graph-up-right:before { content: @ionicon-var-arrow-graph-up-right; }\n.@{ionicons-prefix}arrow-left-a:before { content: @ionicon-var-arrow-left-a; }\n.@{ionicons-prefix}arrow-left-b:before { content: @ionicon-var-arrow-left-b; }\n.@{ionicons-prefix}arrow-left-c:before { content: @ionicon-var-arrow-left-c; }\n.@{ionicons-prefix}arrow-move:before { content: @ionicon-var-arrow-move; }\n.@{ionicons-prefix}arrow-resize:before { content: @ionicon-var-arrow-resize; }\n.@{ionicons-prefix}arrow-return-left:before { content: @ionicon-var-arrow-return-left; }\n.@{ionicons-prefix}arrow-return-right:before { content: @ionicon-var-arrow-return-right; }\n.@{ionicons-prefix}arrow-right-a:before { content: @ionicon-var-arrow-right-a; }\n.@{ionicons-prefix}arrow-right-b:before { content: @ionicon-var-arrow-right-b; }\n.@{ionicons-prefix}arrow-right-c:before { content: @ionicon-var-arrow-right-c; }\n.@{ionicons-prefix}arrow-shrink:before { content: @ionicon-var-arrow-shrink; }\n.@{ionicons-prefix}arrow-swap:before { content: @ionicon-var-arrow-swap; }\n.@{ionicons-prefix}arrow-up-a:before { content: @ionicon-var-arrow-up-a; }\n.@{ionicons-prefix}arrow-up-b:before { content: @ionicon-var-arrow-up-b; }\n.@{ionicons-prefix}arrow-up-c:before { content: @ionicon-var-arrow-up-c; }\n.@{ionicons-prefix}asterisk:before { content: @ionicon-var-asterisk; }\n.@{ionicons-prefix}at:before { content: @ionicon-var-at; }\n.@{ionicons-prefix}backspace:before { content: @ionicon-var-backspace; }\n.@{ionicons-prefix}backspace-outline:before { content: @ionicon-var-backspace-outline; }\n.@{ionicons-prefix}bag:before { content: @ionicon-var-bag; }\n.@{ionicons-prefix}battery-charging:before { content: @ionicon-var-battery-charging; }\n.@{ionicons-prefix}battery-empty:before { content: @ionicon-var-battery-empty; }\n.@{ionicons-prefix}battery-full:before { content: @ionicon-var-battery-full; }\n.@{ionicons-prefix}battery-half:before { content: @ionicon-var-battery-half; }\n.@{ionicons-prefix}battery-low:before { content: @ionicon-var-battery-low; }\n.@{ionicons-prefix}beaker:before { content: @ionicon-var-beaker; }\n.@{ionicons-prefix}beer:before { content: @ionicon-var-beer; }\n.@{ionicons-prefix}bluetooth:before { content: @ionicon-var-bluetooth; }\n.@{ionicons-prefix}bonfire:before { content: @ionicon-var-bonfire; }\n.@{ionicons-prefix}bookmark:before { content: @ionicon-var-bookmark; }\n.@{ionicons-prefix}bowtie:before { content: @ionicon-var-bowtie; }\n.@{ionicons-prefix}briefcase:before { content: @ionicon-var-briefcase; }\n.@{ionicons-prefix}bug:before { content: @ionicon-var-bug; }\n.@{ionicons-prefix}calculator:before { content: @ionicon-var-calculator; }\n.@{ionicons-prefix}calendar:before { content: @ionicon-var-calendar; }\n.@{ionicons-prefix}camera:before { content: @ionicon-var-camera; }\n.@{ionicons-prefix}card:before { content: @ionicon-var-card; }\n.@{ionicons-prefix}cash:before { content: @ionicon-var-cash; }\n.@{ionicons-prefix}chatbox:before { content: @ionicon-var-chatbox; }\n.@{ionicons-prefix}chatbox-working:before { content: @ionicon-var-chatbox-working; }\n.@{ionicons-prefix}chatboxes:before { content: @ionicon-var-chatboxes; }\n.@{ionicons-prefix}chatbubble:before { content: @ionicon-var-chatbubble; }\n.@{ionicons-prefix}chatbubble-working:before { content: @ionicon-var-chatbubble-working; }\n.@{ionicons-prefix}chatbubbles:before { content: @ionicon-var-chatbubbles; }\n.@{ionicons-prefix}checkmark:before { content: @ionicon-var-checkmark; }\n.@{ionicons-prefix}checkmark-circled:before { content: @ionicon-var-checkmark-circled; }\n.@{ionicons-prefix}checkmark-round:before { content: @ionicon-var-checkmark-round; }\n.@{ionicons-prefix}chevron-down:before { content: @ionicon-var-chevron-down; }\n.@{ionicons-prefix}chevron-left:before { content: @ionicon-var-chevron-left; }\n.@{ionicons-prefix}chevron-right:before { content: @ionicon-var-chevron-right; }\n.@{ionicons-prefix}chevron-up:before { content: @ionicon-var-chevron-up; }\n.@{ionicons-prefix}clipboard:before { content: @ionicon-var-clipboard; }\n.@{ionicons-prefix}clock:before { content: @ionicon-var-clock; }\n.@{ionicons-prefix}close:before { content: @ionicon-var-close; }\n.@{ionicons-prefix}close-circled:before { content: @ionicon-var-close-circled; }\n.@{ionicons-prefix}close-round:before { content: @ionicon-var-close-round; }\n.@{ionicons-prefix}closed-captioning:before { content: @ionicon-var-closed-captioning; }\n.@{ionicons-prefix}cloud:before { content: @ionicon-var-cloud; }\n.@{ionicons-prefix}code:before { content: @ionicon-var-code; }\n.@{ionicons-prefix}code-download:before { content: @ionicon-var-code-download; }\n.@{ionicons-prefix}code-working:before { content: @ionicon-var-code-working; }\n.@{ionicons-prefix}coffee:before { content: @ionicon-var-coffee; }\n.@{ionicons-prefix}compass:before { content: @ionicon-var-compass; }\n.@{ionicons-prefix}compose:before { content: @ionicon-var-compose; }\n.@{ionicons-prefix}connection-bars:before { content: @ionicon-var-connection-bars; }\n.@{ionicons-prefix}contrast:before { content: @ionicon-var-contrast; }\n.@{ionicons-prefix}crop:before { content: @ionicon-var-crop; }\n.@{ionicons-prefix}cube:before { content: @ionicon-var-cube; }\n.@{ionicons-prefix}disc:before { content: @ionicon-var-disc; }\n.@{ionicons-prefix}document:before { content: @ionicon-var-document; }\n.@{ionicons-prefix}document-text:before { content: @ionicon-var-document-text; }\n.@{ionicons-prefix}drag:before { content: @ionicon-var-drag; }\n.@{ionicons-prefix}earth:before { content: @ionicon-var-earth; }\n.@{ionicons-prefix}easel:before { content: @ionicon-var-easel; }\n.@{ionicons-prefix}edit:before { content: @ionicon-var-edit; }\n.@{ionicons-prefix}egg:before { content: @ionicon-var-egg; }\n.@{ionicons-prefix}eject:before { content: @ionicon-var-eject; }\n.@{ionicons-prefix}email:before { content: @ionicon-var-email; }\n.@{ionicons-prefix}email-unread:before { content: @ionicon-var-email-unread; }\n.@{ionicons-prefix}erlenmeyer-flask:before { content: @ionicon-var-erlenmeyer-flask; }\n.@{ionicons-prefix}erlenmeyer-flask-bubbles:before { content: @ionicon-var-erlenmeyer-flask-bubbles; }\n.@{ionicons-prefix}eye:before { content: @ionicon-var-eye; }\n.@{ionicons-prefix}eye-disabled:before { content: @ionicon-var-eye-disabled; }\n.@{ionicons-prefix}female:before { content: @ionicon-var-female; }\n.@{ionicons-prefix}filing:before { content: @ionicon-var-filing; }\n.@{ionicons-prefix}film-marker:before { content: @ionicon-var-film-marker; }\n.@{ionicons-prefix}fireball:before { content: @ionicon-var-fireball; }\n.@{ionicons-prefix}flag:before { content: @ionicon-var-flag; }\n.@{ionicons-prefix}flame:before { content: @ionicon-var-flame; }\n.@{ionicons-prefix}flash:before { content: @ionicon-var-flash; }\n.@{ionicons-prefix}flash-off:before { content: @ionicon-var-flash-off; }\n.@{ionicons-prefix}folder:before { content: @ionicon-var-folder; }\n.@{ionicons-prefix}fork:before { content: @ionicon-var-fork; }\n.@{ionicons-prefix}fork-repo:before { content: @ionicon-var-fork-repo; }\n.@{ionicons-prefix}forward:before { content: @ionicon-var-forward; }\n.@{ionicons-prefix}funnel:before { content: @ionicon-var-funnel; }\n.@{ionicons-prefix}gear-a:before { content: @ionicon-var-gear-a; }\n.@{ionicons-prefix}gear-b:before { content: @ionicon-var-gear-b; }\n.@{ionicons-prefix}grid:before { content: @ionicon-var-grid; }\n.@{ionicons-prefix}hammer:before { content: @ionicon-var-hammer; }\n.@{ionicons-prefix}happy:before { content: @ionicon-var-happy; }\n.@{ionicons-prefix}happy-outline:before { content: @ionicon-var-happy-outline; }\n.@{ionicons-prefix}headphone:before { content: @ionicon-var-headphone; }\n.@{ionicons-prefix}heart:before { content: @ionicon-var-heart; }\n.@{ionicons-prefix}heart-broken:before { content: @ionicon-var-heart-broken; }\n.@{ionicons-prefix}help:before { content: @ionicon-var-help; }\n.@{ionicons-prefix}help-buoy:before { content: @ionicon-var-help-buoy; }\n.@{ionicons-prefix}help-circled:before { content: @ionicon-var-help-circled; }\n.@{ionicons-prefix}home:before { content: @ionicon-var-home; }\n.@{ionicons-prefix}icecream:before { content: @ionicon-var-icecream; }\n.@{ionicons-prefix}image:before { content: @ionicon-var-image; }\n.@{ionicons-prefix}images:before { content: @ionicon-var-images; }\n.@{ionicons-prefix}information:before { content: @ionicon-var-information; }\n.@{ionicons-prefix}information-circled:before { content: @ionicon-var-information-circled; }\n.@{ionicons-prefix}ionic:before { content: @ionicon-var-ionic; }\n.@{ionicons-prefix}ios-alarm:before { content: @ionicon-var-ios-alarm; }\n.@{ionicons-prefix}ios-alarm-outline:before { content: @ionicon-var-ios-alarm-outline; }\n.@{ionicons-prefix}ios-albums:before { content: @ionicon-var-ios-albums; }\n.@{ionicons-prefix}ios-albums-outline:before { content: @ionicon-var-ios-albums-outline; }\n.@{ionicons-prefix}ios-americanfootball:before { content: @ionicon-var-ios-americanfootball; }\n.@{ionicons-prefix}ios-americanfootball-outline:before { content: @ionicon-var-ios-americanfootball-outline; }\n.@{ionicons-prefix}ios-analytics:before { content: @ionicon-var-ios-analytics; }\n.@{ionicons-prefix}ios-analytics-outline:before { content: @ionicon-var-ios-analytics-outline; }\n.@{ionicons-prefix}ios-arrow-back:before { content: @ionicon-var-ios-arrow-back; }\n.@{ionicons-prefix}ios-arrow-down:before { content: @ionicon-var-ios-arrow-down; }\n.@{ionicons-prefix}ios-arrow-forward:before { content: @ionicon-var-ios-arrow-forward; }\n.@{ionicons-prefix}ios-arrow-left:before { content: @ionicon-var-ios-arrow-left; }\n.@{ionicons-prefix}ios-arrow-right:before { content: @ionicon-var-ios-arrow-right; }\n.@{ionicons-prefix}ios-arrow-thin-down:before { content: @ionicon-var-ios-arrow-thin-down; }\n.@{ionicons-prefix}ios-arrow-thin-left:before { content: @ionicon-var-ios-arrow-thin-left; }\n.@{ionicons-prefix}ios-arrow-thin-right:before { content: @ionicon-var-ios-arrow-thin-right; }\n.@{ionicons-prefix}ios-arrow-thin-up:before { content: @ionicon-var-ios-arrow-thin-up; }\n.@{ionicons-prefix}ios-arrow-up:before { content: @ionicon-var-ios-arrow-up; }\n.@{ionicons-prefix}ios-at:before { content: @ionicon-var-ios-at; }\n.@{ionicons-prefix}ios-at-outline:before { content: @ionicon-var-ios-at-outline; }\n.@{ionicons-prefix}ios-barcode:before { content: @ionicon-var-ios-barcode; }\n.@{ionicons-prefix}ios-barcode-outline:before { content: @ionicon-var-ios-barcode-outline; }\n.@{ionicons-prefix}ios-baseball:before { content: @ionicon-var-ios-baseball; }\n.@{ionicons-prefix}ios-baseball-outline:before { content: @ionicon-var-ios-baseball-outline; }\n.@{ionicons-prefix}ios-basketball:before { content: @ionicon-var-ios-basketball; }\n.@{ionicons-prefix}ios-basketball-outline:before { content: @ionicon-var-ios-basketball-outline; }\n.@{ionicons-prefix}ios-bell:before { content: @ionicon-var-ios-bell; }\n.@{ionicons-prefix}ios-bell-outline:before { content: @ionicon-var-ios-bell-outline; }\n.@{ionicons-prefix}ios-body:before { content: @ionicon-var-ios-body; }\n.@{ionicons-prefix}ios-body-outline:before { content: @ionicon-var-ios-body-outline; }\n.@{ionicons-prefix}ios-bolt:before { content: @ionicon-var-ios-bolt; }\n.@{ionicons-prefix}ios-bolt-outline:before { content: @ionicon-var-ios-bolt-outline; }\n.@{ionicons-prefix}ios-book:before { content: @ionicon-var-ios-book; }\n.@{ionicons-prefix}ios-book-outline:before { content: @ionicon-var-ios-book-outline; }\n.@{ionicons-prefix}ios-bookmarks:before { content: @ionicon-var-ios-bookmarks; }\n.@{ionicons-prefix}ios-bookmarks-outline:before { content: @ionicon-var-ios-bookmarks-outline; }\n.@{ionicons-prefix}ios-box:before { content: @ionicon-var-ios-box; }\n.@{ionicons-prefix}ios-box-outline:before { content: @ionicon-var-ios-box-outline; }\n.@{ionicons-prefix}ios-briefcase:before { content: @ionicon-var-ios-briefcase; }\n.@{ionicons-prefix}ios-briefcase-outline:before { content: @ionicon-var-ios-briefcase-outline; }\n.@{ionicons-prefix}ios-browsers:before { content: @ionicon-var-ios-browsers; }\n.@{ionicons-prefix}ios-browsers-outline:before { content: @ionicon-var-ios-browsers-outline; }\n.@{ionicons-prefix}ios-calculator:before { content: @ionicon-var-ios-calculator; }\n.@{ionicons-prefix}ios-calculator-outline:before { content: @ionicon-var-ios-calculator-outline; }\n.@{ionicons-prefix}ios-calendar:before { content: @ionicon-var-ios-calendar; }\n.@{ionicons-prefix}ios-calendar-outline:before { content: @ionicon-var-ios-calendar-outline; }\n.@{ionicons-prefix}ios-camera:before { content: @ionicon-var-ios-camera; }\n.@{ionicons-prefix}ios-camera-outline:before { content: @ionicon-var-ios-camera-outline; }\n.@{ionicons-prefix}ios-cart:before { content: @ionicon-var-ios-cart; }\n.@{ionicons-prefix}ios-cart-outline:before { content: @ionicon-var-ios-cart-outline; }\n.@{ionicons-prefix}ios-chatboxes:before { content: @ionicon-var-ios-chatboxes; }\n.@{ionicons-prefix}ios-chatboxes-outline:before { content: @ionicon-var-ios-chatboxes-outline; }\n.@{ionicons-prefix}ios-chatbubble:before { content: @ionicon-var-ios-chatbubble; }\n.@{ionicons-prefix}ios-chatbubble-outline:before { content: @ionicon-var-ios-chatbubble-outline; }\n.@{ionicons-prefix}ios-checkmark:before { content: @ionicon-var-ios-checkmark; }\n.@{ionicons-prefix}ios-checkmark-empty:before { content: @ionicon-var-ios-checkmark-empty; }\n.@{ionicons-prefix}ios-checkmark-outline:before { content: @ionicon-var-ios-checkmark-outline; }\n.@{ionicons-prefix}ios-circle-filled:before { content: @ionicon-var-ios-circle-filled; }\n.@{ionicons-prefix}ios-circle-outline:before { content: @ionicon-var-ios-circle-outline; }\n.@{ionicons-prefix}ios-clock:before { content: @ionicon-var-ios-clock; }\n.@{ionicons-prefix}ios-clock-outline:before { content: @ionicon-var-ios-clock-outline; }\n.@{ionicons-prefix}ios-close:before { content: @ionicon-var-ios-close; }\n.@{ionicons-prefix}ios-close-empty:before { content: @ionicon-var-ios-close-empty; }\n.@{ionicons-prefix}ios-close-outline:before { content: @ionicon-var-ios-close-outline; }\n.@{ionicons-prefix}ios-cloud:before { content: @ionicon-var-ios-cloud; }\n.@{ionicons-prefix}ios-cloud-download:before { content: @ionicon-var-ios-cloud-download; }\n.@{ionicons-prefix}ios-cloud-download-outline:before { content: @ionicon-var-ios-cloud-download-outline; }\n.@{ionicons-prefix}ios-cloud-outline:before { content: @ionicon-var-ios-cloud-outline; }\n.@{ionicons-prefix}ios-cloud-upload:before { content: @ionicon-var-ios-cloud-upload; }\n.@{ionicons-prefix}ios-cloud-upload-outline:before { content: @ionicon-var-ios-cloud-upload-outline; }\n.@{ionicons-prefix}ios-cloudy:before { content: @ionicon-var-ios-cloudy; }\n.@{ionicons-prefix}ios-cloudy-night:before { content: @ionicon-var-ios-cloudy-night; }\n.@{ionicons-prefix}ios-cloudy-night-outline:before { content: @ionicon-var-ios-cloudy-night-outline; }\n.@{ionicons-prefix}ios-cloudy-outline:before { content: @ionicon-var-ios-cloudy-outline; }\n.@{ionicons-prefix}ios-cog:before { content: @ionicon-var-ios-cog; }\n.@{ionicons-prefix}ios-cog-outline:before { content: @ionicon-var-ios-cog-outline; }\n.@{ionicons-prefix}ios-color-filter:before { content: @ionicon-var-ios-color-filter; }\n.@{ionicons-prefix}ios-color-filter-outline:before { content: @ionicon-var-ios-color-filter-outline; }\n.@{ionicons-prefix}ios-color-wand:before { content: @ionicon-var-ios-color-wand; }\n.@{ionicons-prefix}ios-color-wand-outline:before { content: @ionicon-var-ios-color-wand-outline; }\n.@{ionicons-prefix}ios-compose:before { content: @ionicon-var-ios-compose; }\n.@{ionicons-prefix}ios-compose-outline:before { content: @ionicon-var-ios-compose-outline; }\n.@{ionicons-prefix}ios-contact:before { content: @ionicon-var-ios-contact; }\n.@{ionicons-prefix}ios-contact-outline:before { content: @ionicon-var-ios-contact-outline; }\n.@{ionicons-prefix}ios-copy:before { content: @ionicon-var-ios-copy; }\n.@{ionicons-prefix}ios-copy-outline:before { content: @ionicon-var-ios-copy-outline; }\n.@{ionicons-prefix}ios-crop:before { content: @ionicon-var-ios-crop; }\n.@{ionicons-prefix}ios-crop-strong:before { content: @ionicon-var-ios-crop-strong; }\n.@{ionicons-prefix}ios-download:before { content: @ionicon-var-ios-download; }\n.@{ionicons-prefix}ios-download-outline:before { content: @ionicon-var-ios-download-outline; }\n.@{ionicons-prefix}ios-drag:before { content: @ionicon-var-ios-drag; }\n.@{ionicons-prefix}ios-email:before { content: @ionicon-var-ios-email; }\n.@{ionicons-prefix}ios-email-outline:before { content: @ionicon-var-ios-email-outline; }\n.@{ionicons-prefix}ios-eye:before { content: @ionicon-var-ios-eye; }\n.@{ionicons-prefix}ios-eye-outline:before { content: @ionicon-var-ios-eye-outline; }\n.@{ionicons-prefix}ios-fastforward:before { content: @ionicon-var-ios-fastforward; }\n.@{ionicons-prefix}ios-fastforward-outline:before { content: @ionicon-var-ios-fastforward-outline; }\n.@{ionicons-prefix}ios-filing:before { content: @ionicon-var-ios-filing; }\n.@{ionicons-prefix}ios-filing-outline:before { content: @ionicon-var-ios-filing-outline; }\n.@{ionicons-prefix}ios-film:before { content: @ionicon-var-ios-film; }\n.@{ionicons-prefix}ios-film-outline:before { content: @ionicon-var-ios-film-outline; }\n.@{ionicons-prefix}ios-flag:before { content: @ionicon-var-ios-flag; }\n.@{ionicons-prefix}ios-flag-outline:before { content: @ionicon-var-ios-flag-outline; }\n.@{ionicons-prefix}ios-flame:before { content: @ionicon-var-ios-flame; }\n.@{ionicons-prefix}ios-flame-outline:before { content: @ionicon-var-ios-flame-outline; }\n.@{ionicons-prefix}ios-flask:before { content: @ionicon-var-ios-flask; }\n.@{ionicons-prefix}ios-flask-outline:before { content: @ionicon-var-ios-flask-outline; }\n.@{ionicons-prefix}ios-flower:before { content: @ionicon-var-ios-flower; }\n.@{ionicons-prefix}ios-flower-outline:before { content: @ionicon-var-ios-flower-outline; }\n.@{ionicons-prefix}ios-folder:before { content: @ionicon-var-ios-folder; }\n.@{ionicons-prefix}ios-folder-outline:before { content: @ionicon-var-ios-folder-outline; }\n.@{ionicons-prefix}ios-football:before { content: @ionicon-var-ios-football; }\n.@{ionicons-prefix}ios-football-outline:before { content: @ionicon-var-ios-football-outline; }\n.@{ionicons-prefix}ios-game-controller-a:before { content: @ionicon-var-ios-game-controller-a; }\n.@{ionicons-prefix}ios-game-controller-a-outline:before { content: @ionicon-var-ios-game-controller-a-outline; }\n.@{ionicons-prefix}ios-game-controller-b:before { content: @ionicon-var-ios-game-controller-b; }\n.@{ionicons-prefix}ios-game-controller-b-outline:before { content: @ionicon-var-ios-game-controller-b-outline; }\n.@{ionicons-prefix}ios-gear:before { content: @ionicon-var-ios-gear; }\n.@{ionicons-prefix}ios-gear-outline:before { content: @ionicon-var-ios-gear-outline; }\n.@{ionicons-prefix}ios-glasses:before { content: @ionicon-var-ios-glasses; }\n.@{ionicons-prefix}ios-glasses-outline:before { content: @ionicon-var-ios-glasses-outline; }\n.@{ionicons-prefix}ios-grid-view:before { content: @ionicon-var-ios-grid-view; }\n.@{ionicons-prefix}ios-grid-view-outline:before { content: @ionicon-var-ios-grid-view-outline; }\n.@{ionicons-prefix}ios-heart:before { content: @ionicon-var-ios-heart; }\n.@{ionicons-prefix}ios-heart-outline:before { content: @ionicon-var-ios-heart-outline; }\n.@{ionicons-prefix}ios-help:before { content: @ionicon-var-ios-help; }\n.@{ionicons-prefix}ios-help-empty:before { content: @ionicon-var-ios-help-empty; }\n.@{ionicons-prefix}ios-help-outline:before { content: @ionicon-var-ios-help-outline; }\n.@{ionicons-prefix}ios-home:before { content: @ionicon-var-ios-home; }\n.@{ionicons-prefix}ios-home-outline:before { content: @ionicon-var-ios-home-outline; }\n.@{ionicons-prefix}ios-infinite:before { content: @ionicon-var-ios-infinite; }\n.@{ionicons-prefix}ios-infinite-outline:before { content: @ionicon-var-ios-infinite-outline; }\n.@{ionicons-prefix}ios-information:before { content: @ionicon-var-ios-information; }\n.@{ionicons-prefix}ios-information-empty:before { content: @ionicon-var-ios-information-empty; }\n.@{ionicons-prefix}ios-information-outline:before { content: @ionicon-var-ios-information-outline; }\n.@{ionicons-prefix}ios-ionic-outline:before { content: @ionicon-var-ios-ionic-outline; }\n.@{ionicons-prefix}ios-keypad:before { content: @ionicon-var-ios-keypad; }\n.@{ionicons-prefix}ios-keypad-outline:before { content: @ionicon-var-ios-keypad-outline; }\n.@{ionicons-prefix}ios-lightbulb:before { content: @ionicon-var-ios-lightbulb; }\n.@{ionicons-prefix}ios-lightbulb-outline:before { content: @ionicon-var-ios-lightbulb-outline; }\n.@{ionicons-prefix}ios-list:before { content: @ionicon-var-ios-list; }\n.@{ionicons-prefix}ios-list-outline:before { content: @ionicon-var-ios-list-outline; }\n.@{ionicons-prefix}ios-location:before { content: @ionicon-var-ios-location; }\n.@{ionicons-prefix}ios-location-outline:before { content: @ionicon-var-ios-location-outline; }\n.@{ionicons-prefix}ios-locked:before { content: @ionicon-var-ios-locked; }\n.@{ionicons-prefix}ios-locked-outline:before { content: @ionicon-var-ios-locked-outline; }\n.@{ionicons-prefix}ios-loop:before { content: @ionicon-var-ios-loop; }\n.@{ionicons-prefix}ios-loop-strong:before { content: @ionicon-var-ios-loop-strong; }\n.@{ionicons-prefix}ios-medical:before { content: @ionicon-var-ios-medical; }\n.@{ionicons-prefix}ios-medical-outline:before { content: @ionicon-var-ios-medical-outline; }\n.@{ionicons-prefix}ios-medkit:before { content: @ionicon-var-ios-medkit; }\n.@{ionicons-prefix}ios-medkit-outline:before { content: @ionicon-var-ios-medkit-outline; }\n.@{ionicons-prefix}ios-mic:before { content: @ionicon-var-ios-mic; }\n.@{ionicons-prefix}ios-mic-off:before { content: @ionicon-var-ios-mic-off; }\n.@{ionicons-prefix}ios-mic-outline:before { content: @ionicon-var-ios-mic-outline; }\n.@{ionicons-prefix}ios-minus:before { content: @ionicon-var-ios-minus; }\n.@{ionicons-prefix}ios-minus-empty:before { content: @ionicon-var-ios-minus-empty; }\n.@{ionicons-prefix}ios-minus-outline:before { content: @ionicon-var-ios-minus-outline; }\n.@{ionicons-prefix}ios-monitor:before { content: @ionicon-var-ios-monitor; }\n.@{ionicons-prefix}ios-monitor-outline:before { content: @ionicon-var-ios-monitor-outline; }\n.@{ionicons-prefix}ios-moon:before { content: @ionicon-var-ios-moon; }\n.@{ionicons-prefix}ios-moon-outline:before { content: @ionicon-var-ios-moon-outline; }\n.@{ionicons-prefix}ios-more:before { content: @ionicon-var-ios-more; }\n.@{ionicons-prefix}ios-more-outline:before { content: @ionicon-var-ios-more-outline; }\n.@{ionicons-prefix}ios-musical-note:before { content: @ionicon-var-ios-musical-note; }\n.@{ionicons-prefix}ios-musical-notes:before { content: @ionicon-var-ios-musical-notes; }\n.@{ionicons-prefix}ios-navigate:before { content: @ionicon-var-ios-navigate; }\n.@{ionicons-prefix}ios-navigate-outline:before { content: @ionicon-var-ios-navigate-outline; }\n.@{ionicons-prefix}ios-nutrition:before { content: @ionicon-var-ios-nutrition; }\n.@{ionicons-prefix}ios-nutrition-outline:before { content: @ionicon-var-ios-nutrition-outline; }\n.@{ionicons-prefix}ios-paper:before { content: @ionicon-var-ios-paper; }\n.@{ionicons-prefix}ios-paper-outline:before { content: @ionicon-var-ios-paper-outline; }\n.@{ionicons-prefix}ios-paperplane:before { content: @ionicon-var-ios-paperplane; }\n.@{ionicons-prefix}ios-paperplane-outline:before { content: @ionicon-var-ios-paperplane-outline; }\n.@{ionicons-prefix}ios-partlysunny:before { content: @ionicon-var-ios-partlysunny; }\n.@{ionicons-prefix}ios-partlysunny-outline:before { content: @ionicon-var-ios-partlysunny-outline; }\n.@{ionicons-prefix}ios-pause:before { content: @ionicon-var-ios-pause; }\n.@{ionicons-prefix}ios-pause-outline:before { content: @ionicon-var-ios-pause-outline; }\n.@{ionicons-prefix}ios-paw:before { content: @ionicon-var-ios-paw; }\n.@{ionicons-prefix}ios-paw-outline:before { content: @ionicon-var-ios-paw-outline; }\n.@{ionicons-prefix}ios-people:before { content: @ionicon-var-ios-people; }\n.@{ionicons-prefix}ios-people-outline:before { content: @ionicon-var-ios-people-outline; }\n.@{ionicons-prefix}ios-person:before { content: @ionicon-var-ios-person; }\n.@{ionicons-prefix}ios-person-outline:before { content: @ionicon-var-ios-person-outline; }\n.@{ionicons-prefix}ios-personadd:before { content: @ionicon-var-ios-personadd; }\n.@{ionicons-prefix}ios-personadd-outline:before { content: @ionicon-var-ios-personadd-outline; }\n.@{ionicons-prefix}ios-photos:before { content: @ionicon-var-ios-photos; }\n.@{ionicons-prefix}ios-photos-outline:before { content: @ionicon-var-ios-photos-outline; }\n.@{ionicons-prefix}ios-pie:before { content: @ionicon-var-ios-pie; }\n.@{ionicons-prefix}ios-pie-outline:before { content: @ionicon-var-ios-pie-outline; }\n.@{ionicons-prefix}ios-pint:before { content: @ionicon-var-ios-pint; }\n.@{ionicons-prefix}ios-pint-outline:before { content: @ionicon-var-ios-pint-outline; }\n.@{ionicons-prefix}ios-play:before { content: @ionicon-var-ios-play; }\n.@{ionicons-prefix}ios-play-outline:before { content: @ionicon-var-ios-play-outline; }\n.@{ionicons-prefix}ios-plus:before { content: @ionicon-var-ios-plus; }\n.@{ionicons-prefix}ios-plus-empty:before { content: @ionicon-var-ios-plus-empty; }\n.@{ionicons-prefix}ios-plus-outline:before { content: @ionicon-var-ios-plus-outline; }\n.@{ionicons-prefix}ios-pricetag:before { content: @ionicon-var-ios-pricetag; }\n.@{ionicons-prefix}ios-pricetag-outline:before { content: @ionicon-var-ios-pricetag-outline; }\n.@{ionicons-prefix}ios-pricetags:before { content: @ionicon-var-ios-pricetags; }\n.@{ionicons-prefix}ios-pricetags-outline:before { content: @ionicon-var-ios-pricetags-outline; }\n.@{ionicons-prefix}ios-printer:before { content: @ionicon-var-ios-printer; }\n.@{ionicons-prefix}ios-printer-outline:before { content: @ionicon-var-ios-printer-outline; }\n.@{ionicons-prefix}ios-pulse:before { content: @ionicon-var-ios-pulse; }\n.@{ionicons-prefix}ios-pulse-strong:before { content: @ionicon-var-ios-pulse-strong; }\n.@{ionicons-prefix}ios-rainy:before { content: @ionicon-var-ios-rainy; }\n.@{ionicons-prefix}ios-rainy-outline:before { content: @ionicon-var-ios-rainy-outline; }\n.@{ionicons-prefix}ios-recording:before { content: @ionicon-var-ios-recording; }\n.@{ionicons-prefix}ios-recording-outline:before { content: @ionicon-var-ios-recording-outline; }\n.@{ionicons-prefix}ios-redo:before { content: @ionicon-var-ios-redo; }\n.@{ionicons-prefix}ios-redo-outline:before { content: @ionicon-var-ios-redo-outline; }\n.@{ionicons-prefix}ios-refresh:before { content: @ionicon-var-ios-refresh; }\n.@{ionicons-prefix}ios-refresh-empty:before { content: @ionicon-var-ios-refresh-empty; }\n.@{ionicons-prefix}ios-refresh-outline:before { content: @ionicon-var-ios-refresh-outline; }\n.@{ionicons-prefix}ios-reload:before { content: @ionicon-var-ios-reload; }\n.@{ionicons-prefix}ios-reverse-camera:before { content: @ionicon-var-ios-reverse-camera; }\n.@{ionicons-prefix}ios-reverse-camera-outline:before { content: @ionicon-var-ios-reverse-camera-outline; }\n.@{ionicons-prefix}ios-rewind:before { content: @ionicon-var-ios-rewind; }\n.@{ionicons-prefix}ios-rewind-outline:before { content: @ionicon-var-ios-rewind-outline; }\n.@{ionicons-prefix}ios-rose:before { content: @ionicon-var-ios-rose; }\n.@{ionicons-prefix}ios-rose-outline:before { content: @ionicon-var-ios-rose-outline; }\n.@{ionicons-prefix}ios-search:before { content: @ionicon-var-ios-search; }\n.@{ionicons-prefix}ios-search-strong:before { content: @ionicon-var-ios-search-strong; }\n.@{ionicons-prefix}ios-settings:before { content: @ionicon-var-ios-settings; }\n.@{ionicons-prefix}ios-settings-strong:before { content: @ionicon-var-ios-settings-strong; }\n.@{ionicons-prefix}ios-shuffle:before { content: @ionicon-var-ios-shuffle; }\n.@{ionicons-prefix}ios-shuffle-strong:before { content: @ionicon-var-ios-shuffle-strong; }\n.@{ionicons-prefix}ios-skipbackward:before { content: @ionicon-var-ios-skipbackward; }\n.@{ionicons-prefix}ios-skipbackward-outline:before { content: @ionicon-var-ios-skipbackward-outline; }\n.@{ionicons-prefix}ios-skipforward:before { content: @ionicon-var-ios-skipforward; }\n.@{ionicons-prefix}ios-skipforward-outline:before { content: @ionicon-var-ios-skipforward-outline; }\n.@{ionicons-prefix}ios-snowy:before { content: @ionicon-var-ios-snowy; }\n.@{ionicons-prefix}ios-speedometer:before { content: @ionicon-var-ios-speedometer; }\n.@{ionicons-prefix}ios-speedometer-outline:before { content: @ionicon-var-ios-speedometer-outline; }\n.@{ionicons-prefix}ios-star:before { content: @ionicon-var-ios-star; }\n.@{ionicons-prefix}ios-star-half:before { content: @ionicon-var-ios-star-half; }\n.@{ionicons-prefix}ios-star-outline:before { content: @ionicon-var-ios-star-outline; }\n.@{ionicons-prefix}ios-stopwatch:before { content: @ionicon-var-ios-stopwatch; }\n.@{ionicons-prefix}ios-stopwatch-outline:before { content: @ionicon-var-ios-stopwatch-outline; }\n.@{ionicons-prefix}ios-sunny:before { content: @ionicon-var-ios-sunny; }\n.@{ionicons-prefix}ios-sunny-outline:before { content: @ionicon-var-ios-sunny-outline; }\n.@{ionicons-prefix}ios-telephone:before { content: @ionicon-var-ios-telephone; }\n.@{ionicons-prefix}ios-telephone-outline:before { content: @ionicon-var-ios-telephone-outline; }\n.@{ionicons-prefix}ios-tennisball:before { content: @ionicon-var-ios-tennisball; }\n.@{ionicons-prefix}ios-tennisball-outline:before { content: @ionicon-var-ios-tennisball-outline; }\n.@{ionicons-prefix}ios-thunderstorm:before { content: @ionicon-var-ios-thunderstorm; }\n.@{ionicons-prefix}ios-thunderstorm-outline:before { content: @ionicon-var-ios-thunderstorm-outline; }\n.@{ionicons-prefix}ios-time:before { content: @ionicon-var-ios-time; }\n.@{ionicons-prefix}ios-time-outline:before { content: @ionicon-var-ios-time-outline; }\n.@{ionicons-prefix}ios-timer:before { content: @ionicon-var-ios-timer; }\n.@{ionicons-prefix}ios-timer-outline:before { content: @ionicon-var-ios-timer-outline; }\n.@{ionicons-prefix}ios-toggle:before { content: @ionicon-var-ios-toggle; }\n.@{ionicons-prefix}ios-toggle-outline:before { content: @ionicon-var-ios-toggle-outline; }\n.@{ionicons-prefix}ios-trash:before { content: @ionicon-var-ios-trash; }\n.@{ionicons-prefix}ios-trash-outline:before { content: @ionicon-var-ios-trash-outline; }\n.@{ionicons-prefix}ios-undo:before { content: @ionicon-var-ios-undo; }\n.@{ionicons-prefix}ios-undo-outline:before { content: @ionicon-var-ios-undo-outline; }\n.@{ionicons-prefix}ios-unlocked:before { content: @ionicon-var-ios-unlocked; }\n.@{ionicons-prefix}ios-unlocked-outline:before { content: @ionicon-var-ios-unlocked-outline; }\n.@{ionicons-prefix}ios-upload:before { content: @ionicon-var-ios-upload; }\n.@{ionicons-prefix}ios-upload-outline:before { content: @ionicon-var-ios-upload-outline; }\n.@{ionicons-prefix}ios-videocam:before { content: @ionicon-var-ios-videocam; }\n.@{ionicons-prefix}ios-videocam-outline:before { content: @ionicon-var-ios-videocam-outline; }\n.@{ionicons-prefix}ios-volume-high:before { content: @ionicon-var-ios-volume-high; }\n.@{ionicons-prefix}ios-volume-low:before { content: @ionicon-var-ios-volume-low; }\n.@{ionicons-prefix}ios-wineglass:before { content: @ionicon-var-ios-wineglass; }\n.@{ionicons-prefix}ios-wineglass-outline:before { content: @ionicon-var-ios-wineglass-outline; }\n.@{ionicons-prefix}ios-world:before { content: @ionicon-var-ios-world; }\n.@{ionicons-prefix}ios-world-outline:before { content: @ionicon-var-ios-world-outline; }\n.@{ionicons-prefix}ipad:before { content: @ionicon-var-ipad; }\n.@{ionicons-prefix}iphone:before { content: @ionicon-var-iphone; }\n.@{ionicons-prefix}ipod:before { content: @ionicon-var-ipod; }\n.@{ionicons-prefix}jet:before { content: @ionicon-var-jet; }\n.@{ionicons-prefix}key:before { content: @ionicon-var-key; }\n.@{ionicons-prefix}knife:before { content: @ionicon-var-knife; }\n.@{ionicons-prefix}laptop:before { content: @ionicon-var-laptop; }\n.@{ionicons-prefix}leaf:before { content: @ionicon-var-leaf; }\n.@{ionicons-prefix}levels:before { content: @ionicon-var-levels; }\n.@{ionicons-prefix}lightbulb:before { content: @ionicon-var-lightbulb; }\n.@{ionicons-prefix}link:before { content: @ionicon-var-link; }\n.@{ionicons-prefix}load-a:before { content: @ionicon-var-load-a; }\n.@{ionicons-prefix}load-b:before { content: @ionicon-var-load-b; }\n.@{ionicons-prefix}load-c:before { content: @ionicon-var-load-c; }\n.@{ionicons-prefix}load-d:before { content: @ionicon-var-load-d; }\n.@{ionicons-prefix}location:before { content: @ionicon-var-location; }\n.@{ionicons-prefix}lock-combination:before { content: @ionicon-var-lock-combination; }\n.@{ionicons-prefix}locked:before { content: @ionicon-var-locked; }\n.@{ionicons-prefix}log-in:before { content: @ionicon-var-log-in; }\n.@{ionicons-prefix}log-out:before { content: @ionicon-var-log-out; }\n.@{ionicons-prefix}loop:before { content: @ionicon-var-loop; }\n.@{ionicons-prefix}magnet:before { content: @ionicon-var-magnet; }\n.@{ionicons-prefix}male:before { content: @ionicon-var-male; }\n.@{ionicons-prefix}man:before { content: @ionicon-var-man; }\n.@{ionicons-prefix}map:before { content: @ionicon-var-map; }\n.@{ionicons-prefix}medkit:before { content: @ionicon-var-medkit; }\n.@{ionicons-prefix}merge:before { content: @ionicon-var-merge; }\n.@{ionicons-prefix}mic-a:before { content: @ionicon-var-mic-a; }\n.@{ionicons-prefix}mic-b:before { content: @ionicon-var-mic-b; }\n.@{ionicons-prefix}mic-c:before { content: @ionicon-var-mic-c; }\n.@{ionicons-prefix}minus:before { content: @ionicon-var-minus; }\n.@{ionicons-prefix}minus-circled:before { content: @ionicon-var-minus-circled; }\n.@{ionicons-prefix}minus-round:before { content: @ionicon-var-minus-round; }\n.@{ionicons-prefix}model-s:before { content: @ionicon-var-model-s; }\n.@{ionicons-prefix}monitor:before { content: @ionicon-var-monitor; }\n.@{ionicons-prefix}more:before { content: @ionicon-var-more; }\n.@{ionicons-prefix}mouse:before { content: @ionicon-var-mouse; }\n.@{ionicons-prefix}music-note:before { content: @ionicon-var-music-note; }\n.@{ionicons-prefix}navicon:before { content: @ionicon-var-navicon; }\n.@{ionicons-prefix}navicon-round:before { content: @ionicon-var-navicon-round; }\n.@{ionicons-prefix}navigate:before { content: @ionicon-var-navigate; }\n.@{ionicons-prefix}network:before { content: @ionicon-var-network; }\n.@{ionicons-prefix}no-smoking:before { content: @ionicon-var-no-smoking; }\n.@{ionicons-prefix}nuclear:before { content: @ionicon-var-nuclear; }\n.@{ionicons-prefix}outlet:before { content: @ionicon-var-outlet; }\n.@{ionicons-prefix}paintbrush:before { content: @ionicon-var-paintbrush; }\n.@{ionicons-prefix}paintbucket:before { content: @ionicon-var-paintbucket; }\n.@{ionicons-prefix}paper-airplane:before { content: @ionicon-var-paper-airplane; }\n.@{ionicons-prefix}paperclip:before { content: @ionicon-var-paperclip; }\n.@{ionicons-prefix}pause:before { content: @ionicon-var-pause; }\n.@{ionicons-prefix}person:before { content: @ionicon-var-person; }\n.@{ionicons-prefix}person-add:before { content: @ionicon-var-person-add; }\n.@{ionicons-prefix}person-stalker:before { content: @ionicon-var-person-stalker; }\n.@{ionicons-prefix}pie-graph:before { content: @ionicon-var-pie-graph; }\n.@{ionicons-prefix}pin:before { content: @ionicon-var-pin; }\n.@{ionicons-prefix}pinpoint:before { content: @ionicon-var-pinpoint; }\n.@{ionicons-prefix}pizza:before { content: @ionicon-var-pizza; }\n.@{ionicons-prefix}plane:before { content: @ionicon-var-plane; }\n.@{ionicons-prefix}planet:before { content: @ionicon-var-planet; }\n.@{ionicons-prefix}play:before { content: @ionicon-var-play; }\n.@{ionicons-prefix}playstation:before { content: @ionicon-var-playstation; }\n.@{ionicons-prefix}plus:before { content: @ionicon-var-plus; }\n.@{ionicons-prefix}plus-circled:before { content: @ionicon-var-plus-circled; }\n.@{ionicons-prefix}plus-round:before { content: @ionicon-var-plus-round; }\n.@{ionicons-prefix}podium:before { content: @ionicon-var-podium; }\n.@{ionicons-prefix}pound:before { content: @ionicon-var-pound; }\n.@{ionicons-prefix}power:before { content: @ionicon-var-power; }\n.@{ionicons-prefix}pricetag:before { content: @ionicon-var-pricetag; }\n.@{ionicons-prefix}pricetags:before { content: @ionicon-var-pricetags; }\n.@{ionicons-prefix}printer:before { content: @ionicon-var-printer; }\n.@{ionicons-prefix}pull-request:before { content: @ionicon-var-pull-request; }\n.@{ionicons-prefix}qr-scanner:before { content: @ionicon-var-qr-scanner; }\n.@{ionicons-prefix}quote:before { content: @ionicon-var-quote; }\n.@{ionicons-prefix}radio-waves:before { content: @ionicon-var-radio-waves; }\n.@{ionicons-prefix}record:before { content: @ionicon-var-record; }\n.@{ionicons-prefix}refresh:before { content: @ionicon-var-refresh; }\n.@{ionicons-prefix}reply:before { content: @ionicon-var-reply; }\n.@{ionicons-prefix}reply-all:before { content: @ionicon-var-reply-all; }\n.@{ionicons-prefix}ribbon-a:before { content: @ionicon-var-ribbon-a; }\n.@{ionicons-prefix}ribbon-b:before { content: @ionicon-var-ribbon-b; }\n.@{ionicons-prefix}sad:before { content: @ionicon-var-sad; }\n.@{ionicons-prefix}sad-outline:before { content: @ionicon-var-sad-outline; }\n.@{ionicons-prefix}scissors:before { content: @ionicon-var-scissors; }\n.@{ionicons-prefix}search:before { content: @ionicon-var-search; }\n.@{ionicons-prefix}settings:before { content: @ionicon-var-settings; }\n.@{ionicons-prefix}share:before { content: @ionicon-var-share; }\n.@{ionicons-prefix}shuffle:before { content: @ionicon-var-shuffle; }\n.@{ionicons-prefix}skip-backward:before { content: @ionicon-var-skip-backward; }\n.@{ionicons-prefix}skip-forward:before { content: @ionicon-var-skip-forward; }\n.@{ionicons-prefix}social-android:before { content: @ionicon-var-social-android; }\n.@{ionicons-prefix}social-android-outline:before { content: @ionicon-var-social-android-outline; }\n.@{ionicons-prefix}social-angular:before { content: @ionicon-var-social-angular; }\n.@{ionicons-prefix}social-angular-outline:before { content: @ionicon-var-social-angular-outline; }\n.@{ionicons-prefix}social-apple:before { content: @ionicon-var-social-apple; }\n.@{ionicons-prefix}social-apple-outline:before { content: @ionicon-var-social-apple-outline; }\n.@{ionicons-prefix}social-bitcoin:before { content: @ionicon-var-social-bitcoin; }\n.@{ionicons-prefix}social-bitcoin-outline:before { content: @ionicon-var-social-bitcoin-outline; }\n.@{ionicons-prefix}social-buffer:before { content: @ionicon-var-social-buffer; }\n.@{ionicons-prefix}social-buffer-outline:before { content: @ionicon-var-social-buffer-outline; }\n.@{ionicons-prefix}social-chrome:before { content: @ionicon-var-social-chrome; }\n.@{ionicons-prefix}social-chrome-outline:before { content: @ionicon-var-social-chrome-outline; }\n.@{ionicons-prefix}social-codepen:before { content: @ionicon-var-social-codepen; }\n.@{ionicons-prefix}social-codepen-outline:before { content: @ionicon-var-social-codepen-outline; }\n.@{ionicons-prefix}social-css3:before { content: @ionicon-var-social-css3; }\n.@{ionicons-prefix}social-css3-outline:before { content: @ionicon-var-social-css3-outline; }\n.@{ionicons-prefix}social-designernews:before { content: @ionicon-var-social-designernews; }\n.@{ionicons-prefix}social-designernews-outline:before { content: @ionicon-var-social-designernews-outline; }\n.@{ionicons-prefix}social-dribbble:before { content: @ionicon-var-social-dribbble; }\n.@{ionicons-prefix}social-dribbble-outline:before { content: @ionicon-var-social-dribbble-outline; }\n.@{ionicons-prefix}social-dropbox:before { content: @ionicon-var-social-dropbox; }\n.@{ionicons-prefix}social-dropbox-outline:before { content: @ionicon-var-social-dropbox-outline; }\n.@{ionicons-prefix}social-euro:before { content: @ionicon-var-social-euro; }\n.@{ionicons-prefix}social-euro-outline:before { content: @ionicon-var-social-euro-outline; }\n.@{ionicons-prefix}social-facebook:before { content: @ionicon-var-social-facebook; }\n.@{ionicons-prefix}social-facebook-outline:before { content: @ionicon-var-social-facebook-outline; }\n.@{ionicons-prefix}social-foursquare:before { content: @ionicon-var-social-foursquare; }\n.@{ionicons-prefix}social-foursquare-outline:before { content: @ionicon-var-social-foursquare-outline; }\n.@{ionicons-prefix}social-freebsd-devil:before { content: @ionicon-var-social-freebsd-devil; }\n.@{ionicons-prefix}social-github:before { content: @ionicon-var-social-github; }\n.@{ionicons-prefix}social-github-outline:before { content: @ionicon-var-social-github-outline; }\n.@{ionicons-prefix}social-google:before { content: @ionicon-var-social-google; }\n.@{ionicons-prefix}social-google-outline:before { content: @ionicon-var-social-google-outline; }\n.@{ionicons-prefix}social-googleplus:before { content: @ionicon-var-social-googleplus; }\n.@{ionicons-prefix}social-googleplus-outline:before { content: @ionicon-var-social-googleplus-outline; }\n.@{ionicons-prefix}social-hackernews:before { content: @ionicon-var-social-hackernews; }\n.@{ionicons-prefix}social-hackernews-outline:before { content: @ionicon-var-social-hackernews-outline; }\n.@{ionicons-prefix}social-html5:before { content: @ionicon-var-social-html5; }\n.@{ionicons-prefix}social-html5-outline:before { content: @ionicon-var-social-html5-outline; }\n.@{ionicons-prefix}social-instagram:before { content: @ionicon-var-social-instagram; }\n.@{ionicons-prefix}social-instagram-outline:before { content: @ionicon-var-social-instagram-outline; }\n.@{ionicons-prefix}social-javascript:before { content: @ionicon-var-social-javascript; }\n.@{ionicons-prefix}social-javascript-outline:before { content: @ionicon-var-social-javascript-outline; }\n.@{ionicons-prefix}social-linkedin:before { content: @ionicon-var-social-linkedin; }\n.@{ionicons-prefix}social-linkedin-outline:before { content: @ionicon-var-social-linkedin-outline; }\n.@{ionicons-prefix}social-markdown:before { content: @ionicon-var-social-markdown; }\n.@{ionicons-prefix}social-nodejs:before { content: @ionicon-var-social-nodejs; }\n.@{ionicons-prefix}social-octocat:before { content: @ionicon-var-social-octocat; }\n.@{ionicons-prefix}social-pinterest:before { content: @ionicon-var-social-pinterest; }\n.@{ionicons-prefix}social-pinterest-outline:before { content: @ionicon-var-social-pinterest-outline; }\n.@{ionicons-prefix}social-python:before { content: @ionicon-var-social-python; }\n.@{ionicons-prefix}social-reddit:before { content: @ionicon-var-social-reddit; }\n.@{ionicons-prefix}social-reddit-outline:before { content: @ionicon-var-social-reddit-outline; }\n.@{ionicons-prefix}social-rss:before { content: @ionicon-var-social-rss; }\n.@{ionicons-prefix}social-rss-outline:before { content: @ionicon-var-social-rss-outline; }\n.@{ionicons-prefix}social-sass:before { content: @ionicon-var-social-sass; }\n.@{ionicons-prefix}social-skype:before { content: @ionicon-var-social-skype; }\n.@{ionicons-prefix}social-skype-outline:before { content: @ionicon-var-social-skype-outline; }\n.@{ionicons-prefix}social-snapchat:before { content: @ionicon-var-social-snapchat; }\n.@{ionicons-prefix}social-snapchat-outline:before { content: @ionicon-var-social-snapchat-outline; }\n.@{ionicons-prefix}social-tumblr:before { content: @ionicon-var-social-tumblr; }\n.@{ionicons-prefix}social-tumblr-outline:before { content: @ionicon-var-social-tumblr-outline; }\n.@{ionicons-prefix}social-tux:before { content: @ionicon-var-social-tux; }\n.@{ionicons-prefix}social-twitch:before { content: @ionicon-var-social-twitch; }\n.@{ionicons-prefix}social-twitch-outline:before { content: @ionicon-var-social-twitch-outline; }\n.@{ionicons-prefix}social-twitter:before { content: @ionicon-var-social-twitter; }\n.@{ionicons-prefix}social-twitter-outline:before { content: @ionicon-var-social-twitter-outline; }\n.@{ionicons-prefix}social-usd:before { content: @ionicon-var-social-usd; }\n.@{ionicons-prefix}social-usd-outline:before { content: @ionicon-var-social-usd-outline; }\n.@{ionicons-prefix}social-vimeo:before { content: @ionicon-var-social-vimeo; }\n.@{ionicons-prefix}social-vimeo-outline:before { content: @ionicon-var-social-vimeo-outline; }\n.@{ionicons-prefix}social-whatsapp:before { content: @ionicon-var-social-whatsapp; }\n.@{ionicons-prefix}social-whatsapp-outline:before { content: @ionicon-var-social-whatsapp-outline; }\n.@{ionicons-prefix}social-windows:before { content: @ionicon-var-social-windows; }\n.@{ionicons-prefix}social-windows-outline:before { content: @ionicon-var-social-windows-outline; }\n.@{ionicons-prefix}social-wordpress:before { content: @ionicon-var-social-wordpress; }\n.@{ionicons-prefix}social-wordpress-outline:before { content: @ionicon-var-social-wordpress-outline; }\n.@{ionicons-prefix}social-yahoo:before { content: @ionicon-var-social-yahoo; }\n.@{ionicons-prefix}social-yahoo-outline:before { content: @ionicon-var-social-yahoo-outline; }\n.@{ionicons-prefix}social-yen:before { content: @ionicon-var-social-yen; }\n.@{ionicons-prefix}social-yen-outline:before { content: @ionicon-var-social-yen-outline; }\n.@{ionicons-prefix}social-youtube:before { content: @ionicon-var-social-youtube; }\n.@{ionicons-prefix}social-youtube-outline:before { content: @ionicon-var-social-youtube-outline; }\n.@{ionicons-prefix}soup-can:before { content: @ionicon-var-soup-can; }\n.@{ionicons-prefix}soup-can-outline:before { content: @ionicon-var-soup-can-outline; }\n.@{ionicons-prefix}speakerphone:before { content: @ionicon-var-speakerphone; }\n.@{ionicons-prefix}speedometer:before { content: @ionicon-var-speedometer; }\n.@{ionicons-prefix}spoon:before { content: @ionicon-var-spoon; }\n.@{ionicons-prefix}star:before { content: @ionicon-var-star; }\n.@{ionicons-prefix}stats-bars:before { content: @ionicon-var-stats-bars; }\n.@{ionicons-prefix}steam:before { content: @ionicon-var-steam; }\n.@{ionicons-prefix}stop:before { content: @ionicon-var-stop; }\n.@{ionicons-prefix}thermometer:before { content: @ionicon-var-thermometer; }\n.@{ionicons-prefix}thumbsdown:before { content: @ionicon-var-thumbsdown; }\n.@{ionicons-prefix}thumbsup:before { content: @ionicon-var-thumbsup; }\n.@{ionicons-prefix}toggle:before { content: @ionicon-var-toggle; }\n.@{ionicons-prefix}toggle-filled:before { content: @ionicon-var-toggle-filled; }\n.@{ionicons-prefix}transgender:before { content: @ionicon-var-transgender; }\n.@{ionicons-prefix}trash-a:before { content: @ionicon-var-trash-a; }\n.@{ionicons-prefix}trash-b:before { content: @ionicon-var-trash-b; }\n.@{ionicons-prefix}trophy:before { content: @ionicon-var-trophy; }\n.@{ionicons-prefix}tshirt:before { content: @ionicon-var-tshirt; }\n.@{ionicons-prefix}tshirt-outline:before { content: @ionicon-var-tshirt-outline; }\n.@{ionicons-prefix}umbrella:before { content: @ionicon-var-umbrella; }\n.@{ionicons-prefix}university:before { content: @ionicon-var-university; }\n.@{ionicons-prefix}unlocked:before { content: @ionicon-var-unlocked; }\n.@{ionicons-prefix}upload:before { content: @ionicon-var-upload; }\n.@{ionicons-prefix}usb:before { content: @ionicon-var-usb; }\n.@{ionicons-prefix}videocamera:before { content: @ionicon-var-videocamera; }\n.@{ionicons-prefix}volume-high:before { content: @ionicon-var-volume-high; }\n.@{ionicons-prefix}volume-low:before { content: @ionicon-var-volume-low; }\n.@{ionicons-prefix}volume-medium:before { content: @ionicon-var-volume-medium; }\n.@{ionicons-prefix}volume-mute:before { content: @ionicon-var-volume-mute; }\n.@{ionicons-prefix}wand:before { content: @ionicon-var-wand; }\n.@{ionicons-prefix}waterdrop:before { content: @ionicon-var-waterdrop; }\n.@{ionicons-prefix}wifi:before { content: @ionicon-var-wifi; }\n.@{ionicons-prefix}wineglass:before { content: @ionicon-var-wineglass; }\n.@{ionicons-prefix}woman:before { content: @ionicon-var-woman; }\n.@{ionicons-prefix}wrench:before { content: @ionicon-var-wrench; }\n.@{ionicons-prefix}xbox:before { content: @ionicon-var-xbox; }"
  },
  {
    "path": "src/css/ionicons/_ionicons-variables.less",
    "content": "/*!\nIonicons, v2.0.0\nCreated by Ben Sperry for the Ionic Framework, http://ionicons.com/\nhttps://twitter.com/benjsperry  https://twitter.com/ionicframework\nMIT License: https://github.com/driftyco/ionicons\n*/\n// Ionicons Variables\n// --------------------------\n\n@ionicons-font-path: \"../fonts\";\n@ionicons-font-family: \"Ionicons\";\n@ionicons-version: \"2.0.0\";\n@ionicons-prefix: ion-;\n\n@ionicon-var-alert: \"\\f101\";\n@ionicon-var-alert-circled: \"\\f100\";\n@ionicon-var-android-add: \"\\f2c7\";\n@ionicon-var-android-add-circle: \"\\f359\";\n@ionicon-var-android-alarm-clock: \"\\f35a\";\n@ionicon-var-android-alert: \"\\f35b\";\n@ionicon-var-android-apps: \"\\f35c\";\n@ionicon-var-android-archive: \"\\f2c9\";\n@ionicon-var-android-arrow-back: \"\\f2ca\";\n@ionicon-var-android-arrow-down: \"\\f35d\";\n@ionicon-var-android-arrow-dropdown: \"\\f35f\";\n@ionicon-var-android-arrow-dropdown-circle: \"\\f35e\";\n@ionicon-var-android-arrow-dropleft: \"\\f361\";\n@ionicon-var-android-arrow-dropleft-circle: \"\\f360\";\n@ionicon-var-android-arrow-dropright: \"\\f363\";\n@ionicon-var-android-arrow-dropright-circle: \"\\f362\";\n@ionicon-var-android-arrow-dropup: \"\\f365\";\n@ionicon-var-android-arrow-dropup-circle: \"\\f364\";\n@ionicon-var-android-arrow-forward: \"\\f30f\";\n@ionicon-var-android-arrow-up: \"\\f366\";\n@ionicon-var-android-attach: \"\\f367\";\n@ionicon-var-android-bar: \"\\f368\";\n@ionicon-var-android-bicycle: \"\\f369\";\n@ionicon-var-android-boat: \"\\f36a\";\n@ionicon-var-android-bookmark: \"\\f36b\";\n@ionicon-var-android-bulb: \"\\f36c\";\n@ionicon-var-android-bus: \"\\f36d\";\n@ionicon-var-android-calendar: \"\\f2d1\";\n@ionicon-var-android-call: \"\\f2d2\";\n@ionicon-var-android-camera: \"\\f2d3\";\n@ionicon-var-android-cancel: \"\\f36e\";\n@ionicon-var-android-car: \"\\f36f\";\n@ionicon-var-android-cart: \"\\f370\";\n@ionicon-var-android-chat: \"\\f2d4\";\n@ionicon-var-android-checkbox: \"\\f374\";\n@ionicon-var-android-checkbox-blank: \"\\f371\";\n@ionicon-var-android-checkbox-outline: \"\\f373\";\n@ionicon-var-android-checkbox-outline-blank: \"\\f372\";\n@ionicon-var-android-checkmark-circle: \"\\f375\";\n@ionicon-var-android-clipboard: \"\\f376\";\n@ionicon-var-android-close: \"\\f2d7\";\n@ionicon-var-android-cloud: \"\\f37a\";\n@ionicon-var-android-cloud-circle: \"\\f377\";\n@ionicon-var-android-cloud-done: \"\\f378\";\n@ionicon-var-android-cloud-outline: \"\\f379\";\n@ionicon-var-android-color-palette: \"\\f37b\";\n@ionicon-var-android-compass: \"\\f37c\";\n@ionicon-var-android-contact: \"\\f2d8\";\n@ionicon-var-android-contacts: \"\\f2d9\";\n@ionicon-var-android-contract: \"\\f37d\";\n@ionicon-var-android-create: \"\\f37e\";\n@ionicon-var-android-delete: \"\\f37f\";\n@ionicon-var-android-desktop: \"\\f380\";\n@ionicon-var-android-document: \"\\f381\";\n@ionicon-var-android-done: \"\\f383\";\n@ionicon-var-android-done-all: \"\\f382\";\n@ionicon-var-android-download: \"\\f2dd\";\n@ionicon-var-android-drafts: \"\\f384\";\n@ionicon-var-android-exit: \"\\f385\";\n@ionicon-var-android-expand: \"\\f386\";\n@ionicon-var-android-favorite: \"\\f388\";\n@ionicon-var-android-favorite-outline: \"\\f387\";\n@ionicon-var-android-film: \"\\f389\";\n@ionicon-var-android-folder: \"\\f2e0\";\n@ionicon-var-android-folder-open: \"\\f38a\";\n@ionicon-var-android-funnel: \"\\f38b\";\n@ionicon-var-android-globe: \"\\f38c\";\n@ionicon-var-android-hand: \"\\f2e3\";\n@ionicon-var-android-hangout: \"\\f38d\";\n@ionicon-var-android-happy: \"\\f38e\";\n@ionicon-var-android-home: \"\\f38f\";\n@ionicon-var-android-image: \"\\f2e4\";\n@ionicon-var-android-laptop: \"\\f390\";\n@ionicon-var-android-list: \"\\f391\";\n@ionicon-var-android-locate: \"\\f2e9\";\n@ionicon-var-android-lock: \"\\f392\";\n@ionicon-var-android-mail: \"\\f2eb\";\n@ionicon-var-android-map: \"\\f393\";\n@ionicon-var-android-menu: \"\\f394\";\n@ionicon-var-android-microphone: \"\\f2ec\";\n@ionicon-var-android-microphone-off: \"\\f395\";\n@ionicon-var-android-more-horizontal: \"\\f396\";\n@ionicon-var-android-more-vertical: \"\\f397\";\n@ionicon-var-android-navigate: \"\\f398\";\n@ionicon-var-android-notifications: \"\\f39b\";\n@ionicon-var-android-notifications-none: \"\\f399\";\n@ionicon-var-android-notifications-off: \"\\f39a\";\n@ionicon-var-android-open: \"\\f39c\";\n@ionicon-var-android-options: \"\\f39d\";\n@ionicon-var-android-people: \"\\f39e\";\n@ionicon-var-android-person: \"\\f3a0\";\n@ionicon-var-android-person-add: \"\\f39f\";\n@ionicon-var-android-phone-landscape: \"\\f3a1\";\n@ionicon-var-android-phone-portrait: \"\\f3a2\";\n@ionicon-var-android-pin: \"\\f3a3\";\n@ionicon-var-android-plane: \"\\f3a4\";\n@ionicon-var-android-playstore: \"\\f2f0\";\n@ionicon-var-android-print: \"\\f3a5\";\n@ionicon-var-android-radio-button-off: \"\\f3a6\";\n@ionicon-var-android-radio-button-on: \"\\f3a7\";\n@ionicon-var-android-refresh: \"\\f3a8\";\n@ionicon-var-android-remove: \"\\f2f4\";\n@ionicon-var-android-remove-circle: \"\\f3a9\";\n@ionicon-var-android-restaurant: \"\\f3aa\";\n@ionicon-var-android-sad: \"\\f3ab\";\n@ionicon-var-android-search: \"\\f2f5\";\n@ionicon-var-android-send: \"\\f2f6\";\n@ionicon-var-android-settings: \"\\f2f7\";\n@ionicon-var-android-share: \"\\f2f8\";\n@ionicon-var-android-share-alt: \"\\f3ac\";\n@ionicon-var-android-star: \"\\f2fc\";\n@ionicon-var-android-star-half: \"\\f3ad\";\n@ionicon-var-android-star-outline: \"\\f3ae\";\n@ionicon-var-android-stopwatch: \"\\f2fd\";\n@ionicon-var-android-subway: \"\\f3af\";\n@ionicon-var-android-sunny: \"\\f3b0\";\n@ionicon-var-android-sync: \"\\f3b1\";\n@ionicon-var-android-textsms: \"\\f3b2\";\n@ionicon-var-android-time: \"\\f3b3\";\n@ionicon-var-android-train: \"\\f3b4\";\n@ionicon-var-android-unlock: \"\\f3b5\";\n@ionicon-var-android-upload: \"\\f3b6\";\n@ionicon-var-android-volume-down: \"\\f3b7\";\n@ionicon-var-android-volume-mute: \"\\f3b8\";\n@ionicon-var-android-volume-off: \"\\f3b9\";\n@ionicon-var-android-volume-up: \"\\f3ba\";\n@ionicon-var-android-walk: \"\\f3bb\";\n@ionicon-var-android-warning: \"\\f3bc\";\n@ionicon-var-android-watch: \"\\f3bd\";\n@ionicon-var-android-wifi: \"\\f305\";\n@ionicon-var-aperture: \"\\f313\";\n@ionicon-var-archive: \"\\f102\";\n@ionicon-var-arrow-down-a: \"\\f103\";\n@ionicon-var-arrow-down-b: \"\\f104\";\n@ionicon-var-arrow-down-c: \"\\f105\";\n@ionicon-var-arrow-expand: \"\\f25e\";\n@ionicon-var-arrow-graph-down-left: \"\\f25f\";\n@ionicon-var-arrow-graph-down-right: \"\\f260\";\n@ionicon-var-arrow-graph-up-left: \"\\f261\";\n@ionicon-var-arrow-graph-up-right: \"\\f262\";\n@ionicon-var-arrow-left-a: \"\\f106\";\n@ionicon-var-arrow-left-b: \"\\f107\";\n@ionicon-var-arrow-left-c: \"\\f108\";\n@ionicon-var-arrow-move: \"\\f263\";\n@ionicon-var-arrow-resize: \"\\f264\";\n@ionicon-var-arrow-return-left: \"\\f265\";\n@ionicon-var-arrow-return-right: \"\\f266\";\n@ionicon-var-arrow-right-a: \"\\f109\";\n@ionicon-var-arrow-right-b: \"\\f10a\";\n@ionicon-var-arrow-right-c: \"\\f10b\";\n@ionicon-var-arrow-shrink: \"\\f267\";\n@ionicon-var-arrow-swap: \"\\f268\";\n@ionicon-var-arrow-up-a: \"\\f10c\";\n@ionicon-var-arrow-up-b: \"\\f10d\";\n@ionicon-var-arrow-up-c: \"\\f10e\";\n@ionicon-var-asterisk: \"\\f314\";\n@ionicon-var-at: \"\\f10f\";\n@ionicon-var-backspace: \"\\f3bf\";\n@ionicon-var-backspace-outline: \"\\f3be\";\n@ionicon-var-bag: \"\\f110\";\n@ionicon-var-battery-charging: \"\\f111\";\n@ionicon-var-battery-empty: \"\\f112\";\n@ionicon-var-battery-full: \"\\f113\";\n@ionicon-var-battery-half: \"\\f114\";\n@ionicon-var-battery-low: \"\\f115\";\n@ionicon-var-beaker: \"\\f269\";\n@ionicon-var-beer: \"\\f26a\";\n@ionicon-var-bluetooth: \"\\f116\";\n@ionicon-var-bonfire: \"\\f315\";\n@ionicon-var-bookmark: \"\\f26b\";\n@ionicon-var-bowtie: \"\\f3c0\";\n@ionicon-var-briefcase: \"\\f26c\";\n@ionicon-var-bug: \"\\f2be\";\n@ionicon-var-calculator: \"\\f26d\";\n@ionicon-var-calendar: \"\\f117\";\n@ionicon-var-camera: \"\\f118\";\n@ionicon-var-card: \"\\f119\";\n@ionicon-var-cash: \"\\f316\";\n@ionicon-var-chatbox: \"\\f11b\";\n@ionicon-var-chatbox-working: \"\\f11a\";\n@ionicon-var-chatboxes: \"\\f11c\";\n@ionicon-var-chatbubble: \"\\f11e\";\n@ionicon-var-chatbubble-working: \"\\f11d\";\n@ionicon-var-chatbubbles: \"\\f11f\";\n@ionicon-var-checkmark: \"\\f122\";\n@ionicon-var-checkmark-circled: \"\\f120\";\n@ionicon-var-checkmark-round: \"\\f121\";\n@ionicon-var-chevron-down: \"\\f123\";\n@ionicon-var-chevron-left: \"\\f124\";\n@ionicon-var-chevron-right: \"\\f125\";\n@ionicon-var-chevron-up: \"\\f126\";\n@ionicon-var-clipboard: \"\\f127\";\n@ionicon-var-clock: \"\\f26e\";\n@ionicon-var-close: \"\\f12a\";\n@ionicon-var-close-circled: \"\\f128\";\n@ionicon-var-close-round: \"\\f129\";\n@ionicon-var-closed-captioning: \"\\f317\";\n@ionicon-var-cloud: \"\\f12b\";\n@ionicon-var-code: \"\\f271\";\n@ionicon-var-code-download: \"\\f26f\";\n@ionicon-var-code-working: \"\\f270\";\n@ionicon-var-coffee: \"\\f272\";\n@ionicon-var-compass: \"\\f273\";\n@ionicon-var-compose: \"\\f12c\";\n@ionicon-var-connection-bars: \"\\f274\";\n@ionicon-var-contrast: \"\\f275\";\n@ionicon-var-crop: \"\\f3c1\";\n@ionicon-var-cube: \"\\f318\";\n@ionicon-var-disc: \"\\f12d\";\n@ionicon-var-document: \"\\f12f\";\n@ionicon-var-document-text: \"\\f12e\";\n@ionicon-var-drag: \"\\f130\";\n@ionicon-var-earth: \"\\f276\";\n@ionicon-var-easel: \"\\f3c2\";\n@ionicon-var-edit: \"\\f2bf\";\n@ionicon-var-egg: \"\\f277\";\n@ionicon-var-eject: \"\\f131\";\n@ionicon-var-email: \"\\f132\";\n@ionicon-var-email-unread: \"\\f3c3\";\n@ionicon-var-erlenmeyer-flask: \"\\f3c5\";\n@ionicon-var-erlenmeyer-flask-bubbles: \"\\f3c4\";\n@ionicon-var-eye: \"\\f133\";\n@ionicon-var-eye-disabled: \"\\f306\";\n@ionicon-var-female: \"\\f278\";\n@ionicon-var-filing: \"\\f134\";\n@ionicon-var-film-marker: \"\\f135\";\n@ionicon-var-fireball: \"\\f319\";\n@ionicon-var-flag: \"\\f279\";\n@ionicon-var-flame: \"\\f31a\";\n@ionicon-var-flash: \"\\f137\";\n@ionicon-var-flash-off: \"\\f136\";\n@ionicon-var-folder: \"\\f139\";\n@ionicon-var-fork: \"\\f27a\";\n@ionicon-var-fork-repo: \"\\f2c0\";\n@ionicon-var-forward: \"\\f13a\";\n@ionicon-var-funnel: \"\\f31b\";\n@ionicon-var-gear-a: \"\\f13d\";\n@ionicon-var-gear-b: \"\\f13e\";\n@ionicon-var-grid: \"\\f13f\";\n@ionicon-var-hammer: \"\\f27b\";\n@ionicon-var-happy: \"\\f31c\";\n@ionicon-var-happy-outline: \"\\f3c6\";\n@ionicon-var-headphone: \"\\f140\";\n@ionicon-var-heart: \"\\f141\";\n@ionicon-var-heart-broken: \"\\f31d\";\n@ionicon-var-help: \"\\f143\";\n@ionicon-var-help-buoy: \"\\f27c\";\n@ionicon-var-help-circled: \"\\f142\";\n@ionicon-var-home: \"\\f144\";\n@ionicon-var-icecream: \"\\f27d\";\n@ionicon-var-image: \"\\f147\";\n@ionicon-var-images: \"\\f148\";\n@ionicon-var-information: \"\\f14a\";\n@ionicon-var-information-circled: \"\\f149\";\n@ionicon-var-ionic: \"\\f14b\";\n@ionicon-var-ios-alarm: \"\\f3c8\";\n@ionicon-var-ios-alarm-outline: \"\\f3c7\";\n@ionicon-var-ios-albums: \"\\f3ca\";\n@ionicon-var-ios-albums-outline: \"\\f3c9\";\n@ionicon-var-ios-americanfootball: \"\\f3cc\";\n@ionicon-var-ios-americanfootball-outline: \"\\f3cb\";\n@ionicon-var-ios-analytics: \"\\f3ce\";\n@ionicon-var-ios-analytics-outline: \"\\f3cd\";\n@ionicon-var-ios-arrow-back: \"\\f3cf\";\n@ionicon-var-ios-arrow-down: \"\\f3d0\";\n@ionicon-var-ios-arrow-forward: \"\\f3d1\";\n@ionicon-var-ios-arrow-left: \"\\f3d2\";\n@ionicon-var-ios-arrow-right: \"\\f3d3\";\n@ionicon-var-ios-arrow-thin-down: \"\\f3d4\";\n@ionicon-var-ios-arrow-thin-left: \"\\f3d5\";\n@ionicon-var-ios-arrow-thin-right: \"\\f3d6\";\n@ionicon-var-ios-arrow-thin-up: \"\\f3d7\";\n@ionicon-var-ios-arrow-up: \"\\f3d8\";\n@ionicon-var-ios-at: \"\\f3da\";\n@ionicon-var-ios-at-outline: \"\\f3d9\";\n@ionicon-var-ios-barcode: \"\\f3dc\";\n@ionicon-var-ios-barcode-outline: \"\\f3db\";\n@ionicon-var-ios-baseball: \"\\f3de\";\n@ionicon-var-ios-baseball-outline: \"\\f3dd\";\n@ionicon-var-ios-basketball: \"\\f3e0\";\n@ionicon-var-ios-basketball-outline: \"\\f3df\";\n@ionicon-var-ios-bell: \"\\f3e2\";\n@ionicon-var-ios-bell-outline: \"\\f3e1\";\n@ionicon-var-ios-body: \"\\f3e4\";\n@ionicon-var-ios-body-outline: \"\\f3e3\";\n@ionicon-var-ios-bolt: \"\\f3e6\";\n@ionicon-var-ios-bolt-outline: \"\\f3e5\";\n@ionicon-var-ios-book: \"\\f3e8\";\n@ionicon-var-ios-book-outline: \"\\f3e7\";\n@ionicon-var-ios-bookmarks: \"\\f3ea\";\n@ionicon-var-ios-bookmarks-outline: \"\\f3e9\";\n@ionicon-var-ios-box: \"\\f3ec\";\n@ionicon-var-ios-box-outline: \"\\f3eb\";\n@ionicon-var-ios-briefcase: \"\\f3ee\";\n@ionicon-var-ios-briefcase-outline: \"\\f3ed\";\n@ionicon-var-ios-browsers: \"\\f3f0\";\n@ionicon-var-ios-browsers-outline: \"\\f3ef\";\n@ionicon-var-ios-calculator: \"\\f3f2\";\n@ionicon-var-ios-calculator-outline: \"\\f3f1\";\n@ionicon-var-ios-calendar: \"\\f3f4\";\n@ionicon-var-ios-calendar-outline: \"\\f3f3\";\n@ionicon-var-ios-camera: \"\\f3f6\";\n@ionicon-var-ios-camera-outline: \"\\f3f5\";\n@ionicon-var-ios-cart: \"\\f3f8\";\n@ionicon-var-ios-cart-outline: \"\\f3f7\";\n@ionicon-var-ios-chatboxes: \"\\f3fa\";\n@ionicon-var-ios-chatboxes-outline: \"\\f3f9\";\n@ionicon-var-ios-chatbubble: \"\\f3fc\";\n@ionicon-var-ios-chatbubble-outline: \"\\f3fb\";\n@ionicon-var-ios-checkmark: \"\\f3ff\";\n@ionicon-var-ios-checkmark-empty: \"\\f3fd\";\n@ionicon-var-ios-checkmark-outline: \"\\f3fe\";\n@ionicon-var-ios-circle-filled: \"\\f400\";\n@ionicon-var-ios-circle-outline: \"\\f401\";\n@ionicon-var-ios-clock: \"\\f403\";\n@ionicon-var-ios-clock-outline: \"\\f402\";\n@ionicon-var-ios-close: \"\\f406\";\n@ionicon-var-ios-close-empty: \"\\f404\";\n@ionicon-var-ios-close-outline: \"\\f405\";\n@ionicon-var-ios-cloud: \"\\f40c\";\n@ionicon-var-ios-cloud-download: \"\\f408\";\n@ionicon-var-ios-cloud-download-outline: \"\\f407\";\n@ionicon-var-ios-cloud-outline: \"\\f409\";\n@ionicon-var-ios-cloud-upload: \"\\f40b\";\n@ionicon-var-ios-cloud-upload-outline: \"\\f40a\";\n@ionicon-var-ios-cloudy: \"\\f410\";\n@ionicon-var-ios-cloudy-night: \"\\f40e\";\n@ionicon-var-ios-cloudy-night-outline: \"\\f40d\";\n@ionicon-var-ios-cloudy-outline: \"\\f40f\";\n@ionicon-var-ios-cog: \"\\f412\";\n@ionicon-var-ios-cog-outline: \"\\f411\";\n@ionicon-var-ios-color-filter: \"\\f414\";\n@ionicon-var-ios-color-filter-outline: \"\\f413\";\n@ionicon-var-ios-color-wand: \"\\f416\";\n@ionicon-var-ios-color-wand-outline: \"\\f415\";\n@ionicon-var-ios-compose: \"\\f418\";\n@ionicon-var-ios-compose-outline: \"\\f417\";\n@ionicon-var-ios-contact: \"\\f41a\";\n@ionicon-var-ios-contact-outline: \"\\f419\";\n@ionicon-var-ios-copy: \"\\f41c\";\n@ionicon-var-ios-copy-outline: \"\\f41b\";\n@ionicon-var-ios-crop: \"\\f41e\";\n@ionicon-var-ios-crop-strong: \"\\f41d\";\n@ionicon-var-ios-download: \"\\f420\";\n@ionicon-var-ios-download-outline: \"\\f41f\";\n@ionicon-var-ios-drag: \"\\f421\";\n@ionicon-var-ios-email: \"\\f423\";\n@ionicon-var-ios-email-outline: \"\\f422\";\n@ionicon-var-ios-eye: \"\\f425\";\n@ionicon-var-ios-eye-outline: \"\\f424\";\n@ionicon-var-ios-fastforward: \"\\f427\";\n@ionicon-var-ios-fastforward-outline: \"\\f426\";\n@ionicon-var-ios-filing: \"\\f429\";\n@ionicon-var-ios-filing-outline: \"\\f428\";\n@ionicon-var-ios-film: \"\\f42b\";\n@ionicon-var-ios-film-outline: \"\\f42a\";\n@ionicon-var-ios-flag: \"\\f42d\";\n@ionicon-var-ios-flag-outline: \"\\f42c\";\n@ionicon-var-ios-flame: \"\\f42f\";\n@ionicon-var-ios-flame-outline: \"\\f42e\";\n@ionicon-var-ios-flask: \"\\f431\";\n@ionicon-var-ios-flask-outline: \"\\f430\";\n@ionicon-var-ios-flower: \"\\f433\";\n@ionicon-var-ios-flower-outline: \"\\f432\";\n@ionicon-var-ios-folder: \"\\f435\";\n@ionicon-var-ios-folder-outline: \"\\f434\";\n@ionicon-var-ios-football: \"\\f437\";\n@ionicon-var-ios-football-outline: \"\\f436\";\n@ionicon-var-ios-game-controller-a: \"\\f439\";\n@ionicon-var-ios-game-controller-a-outline: \"\\f438\";\n@ionicon-var-ios-game-controller-b: \"\\f43b\";\n@ionicon-var-ios-game-controller-b-outline: \"\\f43a\";\n@ionicon-var-ios-gear: \"\\f43d\";\n@ionicon-var-ios-gear-outline: \"\\f43c\";\n@ionicon-var-ios-glasses: \"\\f43f\";\n@ionicon-var-ios-glasses-outline: \"\\f43e\";\n@ionicon-var-ios-grid-view: \"\\f441\";\n@ionicon-var-ios-grid-view-outline: \"\\f440\";\n@ionicon-var-ios-heart: \"\\f443\";\n@ionicon-var-ios-heart-outline: \"\\f442\";\n@ionicon-var-ios-help: \"\\f446\";\n@ionicon-var-ios-help-empty: \"\\f444\";\n@ionicon-var-ios-help-outline: \"\\f445\";\n@ionicon-var-ios-home: \"\\f448\";\n@ionicon-var-ios-home-outline: \"\\f447\";\n@ionicon-var-ios-infinite: \"\\f44a\";\n@ionicon-var-ios-infinite-outline: \"\\f449\";\n@ionicon-var-ios-information: \"\\f44d\";\n@ionicon-var-ios-information-empty: \"\\f44b\";\n@ionicon-var-ios-information-outline: \"\\f44c\";\n@ionicon-var-ios-ionic-outline: \"\\f44e\";\n@ionicon-var-ios-keypad: \"\\f450\";\n@ionicon-var-ios-keypad-outline: \"\\f44f\";\n@ionicon-var-ios-lightbulb: \"\\f452\";\n@ionicon-var-ios-lightbulb-outline: \"\\f451\";\n@ionicon-var-ios-list: \"\\f454\";\n@ionicon-var-ios-list-outline: \"\\f453\";\n@ionicon-var-ios-location: \"\\f456\";\n@ionicon-var-ios-location-outline: \"\\f455\";\n@ionicon-var-ios-locked: \"\\f458\";\n@ionicon-var-ios-locked-outline: \"\\f457\";\n@ionicon-var-ios-loop: \"\\f45a\";\n@ionicon-var-ios-loop-strong: \"\\f459\";\n@ionicon-var-ios-medical: \"\\f45c\";\n@ionicon-var-ios-medical-outline: \"\\f45b\";\n@ionicon-var-ios-medkit: \"\\f45e\";\n@ionicon-var-ios-medkit-outline: \"\\f45d\";\n@ionicon-var-ios-mic: \"\\f461\";\n@ionicon-var-ios-mic-off: \"\\f45f\";\n@ionicon-var-ios-mic-outline: \"\\f460\";\n@ionicon-var-ios-minus: \"\\f464\";\n@ionicon-var-ios-minus-empty: \"\\f462\";\n@ionicon-var-ios-minus-outline: \"\\f463\";\n@ionicon-var-ios-monitor: \"\\f466\";\n@ionicon-var-ios-monitor-outline: \"\\f465\";\n@ionicon-var-ios-moon: \"\\f468\";\n@ionicon-var-ios-moon-outline: \"\\f467\";\n@ionicon-var-ios-more: \"\\f46a\";\n@ionicon-var-ios-more-outline: \"\\f469\";\n@ionicon-var-ios-musical-note: \"\\f46b\";\n@ionicon-var-ios-musical-notes: \"\\f46c\";\n@ionicon-var-ios-navigate: \"\\f46e\";\n@ionicon-var-ios-navigate-outline: \"\\f46d\";\n@ionicon-var-ios-nutrition: \"\\f470\";\n@ionicon-var-ios-nutrition-outline: \"\\f46f\";\n@ionicon-var-ios-paper: \"\\f472\";\n@ionicon-var-ios-paper-outline: \"\\f471\";\n@ionicon-var-ios-paperplane: \"\\f474\";\n@ionicon-var-ios-paperplane-outline: \"\\f473\";\n@ionicon-var-ios-partlysunny: \"\\f476\";\n@ionicon-var-ios-partlysunny-outline: \"\\f475\";\n@ionicon-var-ios-pause: \"\\f478\";\n@ionicon-var-ios-pause-outline: \"\\f477\";\n@ionicon-var-ios-paw: \"\\f47a\";\n@ionicon-var-ios-paw-outline: \"\\f479\";\n@ionicon-var-ios-people: \"\\f47c\";\n@ionicon-var-ios-people-outline: \"\\f47b\";\n@ionicon-var-ios-person: \"\\f47e\";\n@ionicon-var-ios-person-outline: \"\\f47d\";\n@ionicon-var-ios-personadd: \"\\f480\";\n@ionicon-var-ios-personadd-outline: \"\\f47f\";\n@ionicon-var-ios-photos: \"\\f482\";\n@ionicon-var-ios-photos-outline: \"\\f481\";\n@ionicon-var-ios-pie: \"\\f484\";\n@ionicon-var-ios-pie-outline: \"\\f483\";\n@ionicon-var-ios-pint: \"\\f486\";\n@ionicon-var-ios-pint-outline: \"\\f485\";\n@ionicon-var-ios-play: \"\\f488\";\n@ionicon-var-ios-play-outline: \"\\f487\";\n@ionicon-var-ios-plus: \"\\f48b\";\n@ionicon-var-ios-plus-empty: \"\\f489\";\n@ionicon-var-ios-plus-outline: \"\\f48a\";\n@ionicon-var-ios-pricetag: \"\\f48d\";\n@ionicon-var-ios-pricetag-outline: \"\\f48c\";\n@ionicon-var-ios-pricetags: \"\\f48f\";\n@ionicon-var-ios-pricetags-outline: \"\\f48e\";\n@ionicon-var-ios-printer: \"\\f491\";\n@ionicon-var-ios-printer-outline: \"\\f490\";\n@ionicon-var-ios-pulse: \"\\f493\";\n@ionicon-var-ios-pulse-strong: \"\\f492\";\n@ionicon-var-ios-rainy: \"\\f495\";\n@ionicon-var-ios-rainy-outline: \"\\f494\";\n@ionicon-var-ios-recording: \"\\f497\";\n@ionicon-var-ios-recording-outline: \"\\f496\";\n@ionicon-var-ios-redo: \"\\f499\";\n@ionicon-var-ios-redo-outline: \"\\f498\";\n@ionicon-var-ios-refresh: \"\\f49c\";\n@ionicon-var-ios-refresh-empty: \"\\f49a\";\n@ionicon-var-ios-refresh-outline: \"\\f49b\";\n@ionicon-var-ios-reload: \"\\f49d\";\n@ionicon-var-ios-reverse-camera: \"\\f49f\";\n@ionicon-var-ios-reverse-camera-outline: \"\\f49e\";\n@ionicon-var-ios-rewind: \"\\f4a1\";\n@ionicon-var-ios-rewind-outline: \"\\f4a0\";\n@ionicon-var-ios-rose: \"\\f4a3\";\n@ionicon-var-ios-rose-outline: \"\\f4a2\";\n@ionicon-var-ios-search: \"\\f4a5\";\n@ionicon-var-ios-search-strong: \"\\f4a4\";\n@ionicon-var-ios-settings: \"\\f4a7\";\n@ionicon-var-ios-settings-strong: \"\\f4a6\";\n@ionicon-var-ios-shuffle: \"\\f4a9\";\n@ionicon-var-ios-shuffle-strong: \"\\f4a8\";\n@ionicon-var-ios-skipbackward: \"\\f4ab\";\n@ionicon-var-ios-skipbackward-outline: \"\\f4aa\";\n@ionicon-var-ios-skipforward: \"\\f4ad\";\n@ionicon-var-ios-skipforward-outline: \"\\f4ac\";\n@ionicon-var-ios-snowy: \"\\f4ae\";\n@ionicon-var-ios-speedometer: \"\\f4b0\";\n@ionicon-var-ios-speedometer-outline: \"\\f4af\";\n@ionicon-var-ios-star: \"\\f4b3\";\n@ionicon-var-ios-star-half: \"\\f4b1\";\n@ionicon-var-ios-star-outline: \"\\f4b2\";\n@ionicon-var-ios-stopwatch: \"\\f4b5\";\n@ionicon-var-ios-stopwatch-outline: \"\\f4b4\";\n@ionicon-var-ios-sunny: \"\\f4b7\";\n@ionicon-var-ios-sunny-outline: \"\\f4b6\";\n@ionicon-var-ios-telephone: \"\\f4b9\";\n@ionicon-var-ios-telephone-outline: \"\\f4b8\";\n@ionicon-var-ios-tennisball: \"\\f4bb\";\n@ionicon-var-ios-tennisball-outline: \"\\f4ba\";\n@ionicon-var-ios-thunderstorm: \"\\f4bd\";\n@ionicon-var-ios-thunderstorm-outline: \"\\f4bc\";\n@ionicon-var-ios-time: \"\\f4bf\";\n@ionicon-var-ios-time-outline: \"\\f4be\";\n@ionicon-var-ios-timer: \"\\f4c1\";\n@ionicon-var-ios-timer-outline: \"\\f4c0\";\n@ionicon-var-ios-toggle: \"\\f4c3\";\n@ionicon-var-ios-toggle-outline: \"\\f4c2\";\n@ionicon-var-ios-trash: \"\\f4c5\";\n@ionicon-var-ios-trash-outline: \"\\f4c4\";\n@ionicon-var-ios-undo: \"\\f4c7\";\n@ionicon-var-ios-undo-outline: \"\\f4c6\";\n@ionicon-var-ios-unlocked: \"\\f4c9\";\n@ionicon-var-ios-unlocked-outline: \"\\f4c8\";\n@ionicon-var-ios-upload: \"\\f4cb\";\n@ionicon-var-ios-upload-outline: \"\\f4ca\";\n@ionicon-var-ios-videocam: \"\\f4cd\";\n@ionicon-var-ios-videocam-outline: \"\\f4cc\";\n@ionicon-var-ios-volume-high: \"\\f4ce\";\n@ionicon-var-ios-volume-low: \"\\f4cf\";\n@ionicon-var-ios-wineglass: \"\\f4d1\";\n@ionicon-var-ios-wineglass-outline: \"\\f4d0\";\n@ionicon-var-ios-world: \"\\f4d3\";\n@ionicon-var-ios-world-outline: \"\\f4d2\";\n@ionicon-var-ipad: \"\\f1f9\";\n@ionicon-var-iphone: \"\\f1fa\";\n@ionicon-var-ipod: \"\\f1fb\";\n@ionicon-var-jet: \"\\f295\";\n@ionicon-var-key: \"\\f296\";\n@ionicon-var-knife: \"\\f297\";\n@ionicon-var-laptop: \"\\f1fc\";\n@ionicon-var-leaf: \"\\f1fd\";\n@ionicon-var-levels: \"\\f298\";\n@ionicon-var-lightbulb: \"\\f299\";\n@ionicon-var-link: \"\\f1fe\";\n@ionicon-var-load-a: \"\\f29a\";\n@ionicon-var-load-b: \"\\f29b\";\n@ionicon-var-load-c: \"\\f29c\";\n@ionicon-var-load-d: \"\\f29d\";\n@ionicon-var-location: \"\\f1ff\";\n@ionicon-var-lock-combination: \"\\f4d4\";\n@ionicon-var-locked: \"\\f200\";\n@ionicon-var-log-in: \"\\f29e\";\n@ionicon-var-log-out: \"\\f29f\";\n@ionicon-var-loop: \"\\f201\";\n@ionicon-var-magnet: \"\\f2a0\";\n@ionicon-var-male: \"\\f2a1\";\n@ionicon-var-man: \"\\f202\";\n@ionicon-var-map: \"\\f203\";\n@ionicon-var-medkit: \"\\f2a2\";\n@ionicon-var-merge: \"\\f33f\";\n@ionicon-var-mic-a: \"\\f204\";\n@ionicon-var-mic-b: \"\\f205\";\n@ionicon-var-mic-c: \"\\f206\";\n@ionicon-var-minus: \"\\f209\";\n@ionicon-var-minus-circled: \"\\f207\";\n@ionicon-var-minus-round: \"\\f208\";\n@ionicon-var-model-s: \"\\f2c1\";\n@ionicon-var-monitor: \"\\f20a\";\n@ionicon-var-more: \"\\f20b\";\n@ionicon-var-mouse: \"\\f340\";\n@ionicon-var-music-note: \"\\f20c\";\n@ionicon-var-navicon: \"\\f20e\";\n@ionicon-var-navicon-round: \"\\f20d\";\n@ionicon-var-navigate: \"\\f2a3\";\n@ionicon-var-network: \"\\f341\";\n@ionicon-var-no-smoking: \"\\f2c2\";\n@ionicon-var-nuclear: \"\\f2a4\";\n@ionicon-var-outlet: \"\\f342\";\n@ionicon-var-paintbrush: \"\\f4d5\";\n@ionicon-var-paintbucket: \"\\f4d6\";\n@ionicon-var-paper-airplane: \"\\f2c3\";\n@ionicon-var-paperclip: \"\\f20f\";\n@ionicon-var-pause: \"\\f210\";\n@ionicon-var-person: \"\\f213\";\n@ionicon-var-person-add: \"\\f211\";\n@ionicon-var-person-stalker: \"\\f212\";\n@ionicon-var-pie-graph: \"\\f2a5\";\n@ionicon-var-pin: \"\\f2a6\";\n@ionicon-var-pinpoint: \"\\f2a7\";\n@ionicon-var-pizza: \"\\f2a8\";\n@ionicon-var-plane: \"\\f214\";\n@ionicon-var-planet: \"\\f343\";\n@ionicon-var-play: \"\\f215\";\n@ionicon-var-playstation: \"\\f30a\";\n@ionicon-var-plus: \"\\f218\";\n@ionicon-var-plus-circled: \"\\f216\";\n@ionicon-var-plus-round: \"\\f217\";\n@ionicon-var-podium: \"\\f344\";\n@ionicon-var-pound: \"\\f219\";\n@ionicon-var-power: \"\\f2a9\";\n@ionicon-var-pricetag: \"\\f2aa\";\n@ionicon-var-pricetags: \"\\f2ab\";\n@ionicon-var-printer: \"\\f21a\";\n@ionicon-var-pull-request: \"\\f345\";\n@ionicon-var-qr-scanner: \"\\f346\";\n@ionicon-var-quote: \"\\f347\";\n@ionicon-var-radio-waves: \"\\f2ac\";\n@ionicon-var-record: \"\\f21b\";\n@ionicon-var-refresh: \"\\f21c\";\n@ionicon-var-reply: \"\\f21e\";\n@ionicon-var-reply-all: \"\\f21d\";\n@ionicon-var-ribbon-a: \"\\f348\";\n@ionicon-var-ribbon-b: \"\\f349\";\n@ionicon-var-sad: \"\\f34a\";\n@ionicon-var-sad-outline: \"\\f4d7\";\n@ionicon-var-scissors: \"\\f34b\";\n@ionicon-var-search: \"\\f21f\";\n@ionicon-var-settings: \"\\f2ad\";\n@ionicon-var-share: \"\\f220\";\n@ionicon-var-shuffle: \"\\f221\";\n@ionicon-var-skip-backward: \"\\f222\";\n@ionicon-var-skip-forward: \"\\f223\";\n@ionicon-var-social-android: \"\\f225\";\n@ionicon-var-social-android-outline: \"\\f224\";\n@ionicon-var-social-angular: \"\\f4d9\";\n@ionicon-var-social-angular-outline: \"\\f4d8\";\n@ionicon-var-social-apple: \"\\f227\";\n@ionicon-var-social-apple-outline: \"\\f226\";\n@ionicon-var-social-bitcoin: \"\\f2af\";\n@ionicon-var-social-bitcoin-outline: \"\\f2ae\";\n@ionicon-var-social-buffer: \"\\f229\";\n@ionicon-var-social-buffer-outline: \"\\f228\";\n@ionicon-var-social-chrome: \"\\f4db\";\n@ionicon-var-social-chrome-outline: \"\\f4da\";\n@ionicon-var-social-codepen: \"\\f4dd\";\n@ionicon-var-social-codepen-outline: \"\\f4dc\";\n@ionicon-var-social-css3: \"\\f4df\";\n@ionicon-var-social-css3-outline: \"\\f4de\";\n@ionicon-var-social-designernews: \"\\f22b\";\n@ionicon-var-social-designernews-outline: \"\\f22a\";\n@ionicon-var-social-dribbble: \"\\f22d\";\n@ionicon-var-social-dribbble-outline: \"\\f22c\";\n@ionicon-var-social-dropbox: \"\\f22f\";\n@ionicon-var-social-dropbox-outline: \"\\f22e\";\n@ionicon-var-social-euro: \"\\f4e1\";\n@ionicon-var-social-euro-outline: \"\\f4e0\";\n@ionicon-var-social-facebook: \"\\f231\";\n@ionicon-var-social-facebook-outline: \"\\f230\";\n@ionicon-var-social-foursquare: \"\\f34d\";\n@ionicon-var-social-foursquare-outline: \"\\f34c\";\n@ionicon-var-social-freebsd-devil: \"\\f2c4\";\n@ionicon-var-social-github: \"\\f233\";\n@ionicon-var-social-github-outline: \"\\f232\";\n@ionicon-var-social-google: \"\\f34f\";\n@ionicon-var-social-google-outline: \"\\f34e\";\n@ionicon-var-social-googleplus: \"\\f235\";\n@ionicon-var-social-googleplus-outline: \"\\f234\";\n@ionicon-var-social-hackernews: \"\\f237\";\n@ionicon-var-social-hackernews-outline: \"\\f236\";\n@ionicon-var-social-html5: \"\\f4e3\";\n@ionicon-var-social-html5-outline: \"\\f4e2\";\n@ionicon-var-social-instagram: \"\\f351\";\n@ionicon-var-social-instagram-outline: \"\\f350\";\n@ionicon-var-social-javascript: \"\\f4e5\";\n@ionicon-var-social-javascript-outline: \"\\f4e4\";\n@ionicon-var-social-linkedin: \"\\f239\";\n@ionicon-var-social-linkedin-outline: \"\\f238\";\n@ionicon-var-social-markdown: \"\\f4e6\";\n@ionicon-var-social-nodejs: \"\\f4e7\";\n@ionicon-var-social-octocat: \"\\f4e8\";\n@ionicon-var-social-pinterest: \"\\f2b1\";\n@ionicon-var-social-pinterest-outline: \"\\f2b0\";\n@ionicon-var-social-python: \"\\f4e9\";\n@ionicon-var-social-reddit: \"\\f23b\";\n@ionicon-var-social-reddit-outline: \"\\f23a\";\n@ionicon-var-social-rss: \"\\f23d\";\n@ionicon-var-social-rss-outline: \"\\f23c\";\n@ionicon-var-social-sass: \"\\f4ea\";\n@ionicon-var-social-skype: \"\\f23f\";\n@ionicon-var-social-skype-outline: \"\\f23e\";\n@ionicon-var-social-snapchat: \"\\f4ec\";\n@ionicon-var-social-snapchat-outline: \"\\f4eb\";\n@ionicon-var-social-tumblr: \"\\f241\";\n@ionicon-var-social-tumblr-outline: \"\\f240\";\n@ionicon-var-social-tux: \"\\f2c5\";\n@ionicon-var-social-twitch: \"\\f4ee\";\n@ionicon-var-social-twitch-outline: \"\\f4ed\";\n@ionicon-var-social-twitter: \"\\f243\";\n@ionicon-var-social-twitter-outline: \"\\f242\";\n@ionicon-var-social-usd: \"\\f353\";\n@ionicon-var-social-usd-outline: \"\\f352\";\n@ionicon-var-social-vimeo: \"\\f245\";\n@ionicon-var-social-vimeo-outline: \"\\f244\";\n@ionicon-var-social-whatsapp: \"\\f4f0\";\n@ionicon-var-social-whatsapp-outline: \"\\f4ef\";\n@ionicon-var-social-windows: \"\\f247\";\n@ionicon-var-social-windows-outline: \"\\f246\";\n@ionicon-var-social-wordpress: \"\\f249\";\n@ionicon-var-social-wordpress-outline: \"\\f248\";\n@ionicon-var-social-yahoo: \"\\f24b\";\n@ionicon-var-social-yahoo-outline: \"\\f24a\";\n@ionicon-var-social-yen: \"\\f4f2\";\n@ionicon-var-social-yen-outline: \"\\f4f1\";\n@ionicon-var-social-youtube: \"\\f24d\";\n@ionicon-var-social-youtube-outline: \"\\f24c\";\n@ionicon-var-soup-can: \"\\f4f4\";\n@ionicon-var-soup-can-outline: \"\\f4f3\";\n@ionicon-var-speakerphone: \"\\f2b2\";\n@ionicon-var-speedometer: \"\\f2b3\";\n@ionicon-var-spoon: \"\\f2b4\";\n@ionicon-var-star: \"\\f24e\";\n@ionicon-var-stats-bars: \"\\f2b5\";\n@ionicon-var-steam: \"\\f30b\";\n@ionicon-var-stop: \"\\f24f\";\n@ionicon-var-thermometer: \"\\f2b6\";\n@ionicon-var-thumbsdown: \"\\f250\";\n@ionicon-var-thumbsup: \"\\f251\";\n@ionicon-var-toggle: \"\\f355\";\n@ionicon-var-toggle-filled: \"\\f354\";\n@ionicon-var-transgender: \"\\f4f5\";\n@ionicon-var-trash-a: \"\\f252\";\n@ionicon-var-trash-b: \"\\f253\";\n@ionicon-var-trophy: \"\\f356\";\n@ionicon-var-tshirt: \"\\f4f7\";\n@ionicon-var-tshirt-outline: \"\\f4f6\";\n@ionicon-var-umbrella: \"\\f2b7\";\n@ionicon-var-university: \"\\f357\";\n@ionicon-var-unlocked: \"\\f254\";\n@ionicon-var-upload: \"\\f255\";\n@ionicon-var-usb: \"\\f2b8\";\n@ionicon-var-videocamera: \"\\f256\";\n@ionicon-var-volume-high: \"\\f257\";\n@ionicon-var-volume-low: \"\\f258\";\n@ionicon-var-volume-medium: \"\\f259\";\n@ionicon-var-volume-mute: \"\\f25a\";\n@ionicon-var-wand: \"\\f358\";\n@ionicon-var-waterdrop: \"\\f25b\";\n@ionicon-var-wifi: \"\\f25c\";\n@ionicon-var-wineglass: \"\\f2b9\";\n@ionicon-var-woman: \"\\f25d\";\n@ionicon-var-wrench: \"\\f2ba\";\n@ionicon-var-xbox: \"\\f30c\";"
  },
  {
    "path": "src/css/ionicons/ionicons.less",
    "content": "@import \"_ionicons-variables\";\n@import \"_ionicons-font\";\n@import \"_ionicons-icons\";\n"
  },
  {
    "path": "src/css/mixins.less",
    "content": "// \n// Mixins\n// ==============================\n\n\n\n\n// Avatars\n// ------------------------------\n\n.avatar(@size) {\n\t.square(@size);\n\tbackground: rgba(255, 255, 255, 0.1);\n\tborder-radius: 50%;\n\tborder: 3px solid @text-color;\n}\n\n\n\n\n// Buttons\n// ------------------------------\n\n.button-press(@scale: .95; @opacity: .9) {\n\t.transition-transform( 80ms ease-in-out );\n\n\t// on tap shrink the button to make it feel depressed\n\t&.Tappable-active {\n\t\t.scale(@scale);\n\t\topacity: @opacity;\n\t\toutline: none;\n\t}\n}"
  },
  {
    "path": "src/css/variables.less",
    "content": "// \n// Variables\n// ==============================\n\n\n\n\n// Colours\n// ------------------------------\n\n@charcoal:                     #1B1D24;\n\n@app-primary:                  #0D7299; // bright blue\n@app-secondary:                #fdf64a; // bright yellow\n\n@twitter-brand:                #55acee;\n@facebook-brand:               #3b5998;\n\n\n\n\n// Scaffolding\n// ------------------------------\n\n@body-bg:                      @app-primary;\n@text-color:                   white;\n\n@link-color:                   @app-primary;\n@link-hover-color:             lighten(@link-color, 10%);\n\n\n\n\n// Typography\n// ------------------------------\n\n@font-family-sans-serif:      \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n@font-family-serif:           \"Times New Roman\", Times, Georgia, serif;\n@font-family-monospace:       Courier, monospace;\n@font-family-base:            @font-family-sans-serif;\n@font-weight-bold:            500;\n\n@font-size-xxs:               11px;\n@font-size-xs:                13px;\n@font-size-sm:                15px;\n@font-size-base:              17px;\n@font-size-lg:                20px;\n@font-size-xl:                24px;\n@font-size-xxl:               32px;\n\n\n\n\n// Components\n// ------------------------------\n\n@panel-bg:                    lighten(@details-bg, 5%);\n@panel-color:                 @text-color;\n@panel-header-color:          #4d4d4d;\n\n@item-divider-color:          rgba(255, 255, 255, 0.1);\n\n\n\n\n// Forms\n// ------------------------------\n\n// @field-color:                 black;\n// @field-border:                #ddd;\n// @field-border-focus:          darken(@field-border, 10%);\n// @field-placeholder:           #c7c7cd;\n@field-label-color:           rgba(255, 255, 255, 0.33);\n\n\n\n\n// Bars\n// ------------------------------\n\n\n// header bar\n\n@headerbar-bg:               @charcoal;\n@headerbar-color:            white;\n@headerbar-height:           44px;\n@headerbar-button-color:     lighten(@app-primary, 40%);\n\n\n// footer bar\n\n@footerbar-bg:               @charcoal;\n\n\n\n\n// Views\n// ------------------------------\n\n@details-bg:                 darken(@charcoal, 3%);\n// @details-bg:                 mix(@app-primary, black, 30%);"
  },
  {
    "path": "src/css/views/about.less",
    "content": "//\n// About View\n// ==============================\n\n\n// View gradient\n\n.View--about {\n\t#gradient .directional(#f83, #fa2562, 145deg);\n}\n\n\n// Layout & Common\n\n// layout\n\n.About {\n\ttext-align: center;\n}\n.About-section {\n\tpadding: 2em;\n\n\t& + & {\n\t\tborder-top: 1px solid rgba(255, 255, 255, 0.2);\n\t}\n}\n\n\n// lists\n\n.About__list {\n\t.display-flex();\n\t.flex-direction(row);\n\t.align-items(center);\n\t.justify-content(space-between);\n\tmargin-left: -10px;\n\tmargin-right: -10px;\n}\n.About__list__item {\n\t.flex(1,1,0);\n\tmargin: 0 10px;\n\n\t> img {\n\t\theight: auto;\n\t\tmax-width: 100%;\n\t}\n}\n\n\n\n\n// Top\n// ------------------------------\n\n\n// logo\n\n.About__logo {\n\t.square(90px);\n\tdisplay: inline-block;\n}\n\n\n// headings\n\n.About__heading {\n\tfont-size: @font-size-huge;\n\tfont-weight: 500;\n\tmargin-top: 1em;\n}\n.About__subheading {\n\t// font-size: @font-size-sm;\n\tmargin-bottom: 1em;\n\tmargin-top: 1em;\n}\n\n\n// content\n\n.About__content {\n\tline-height: 1.3;\n\ttext-align: left;\n\tmargin-top: 2em;\n}\n\n\n// button\n\n.About__button {\n\tmargin-top: 2em;\n}\n\n\n\n\n// Bottom\n// ------------------------------\n\n\n// lists\n\n.About__team {\n\tfont-weight: 500;\n\tmargin-top: 2em;\n}\n.About__team__member {\n\tcolor: @text-color;\n\t> img {\n\t\tbackground-color: white;\n\t\tborder-radius: 50%;\n\t\tbox-shadow: 0 0 0 3px @text-color;\n\t\tmargin-bottom: 1em;\n\t}\n}\n.About__team__member:hover {\n\tcolor: @text-color;\n}\n"
  },
  {
    "path": "src/css/views/announcement.less",
    "content": "//\n// Announcement\n// ==============================\n\n// TEMP\n\n.ErrorView {\n\t.align-items(center);\n\t.display-flex();\n\t.flex-direction(column);\n\t.justify-content(center);\n\ttext-align: center;\n}\n.ErrorView__icon {\n\tfont-size: 64px;\n\tmargin-bottom: .5em;\n}\n.ErrorView__heading {\n\tdisplay: block;\n\tfont-weight: bold;\n\tmargin-bottom: 1em;\n\tpadding-left: 2em;\n\tpadding-right: 2em;\n}\n.ErrorView__text {\n\tdisplay: block;\n\tfont-size: @font-size-sm;\n\tline-height: 1.4;\n\tpadding-left: 2em;\n\tpadding-right: 2em;\n}"
  },
  {
    "path": "src/css/views/details.less",
    "content": "// \n// Details Views\n// covers views like \"person, talk, me\"\n// ==============================\n\n\n\n\n\n// BG colour for details views\n// ------------------------------\n\n.View--about,\n.View--event,\n.View--me,\n.View--me-edit,\n.View--onboarding-registration,\n.View--person,\n.View--talk {\n\tbackground-color: @details-bg;\n}"
  },
  {
    "path": "src/css/views/event.less",
    "content": "//\n// Event Info\n// ==============================\n\n\n\n\n// Hero\n// ------------------------------\n\n.EventInfo__hero {\n\tbackground: url(\"../img/venue-hero.jpg\") no-repeat center top;\n\tbackground-size: cover;\n\t// height: 320px;\n\ttext-align: center;\n}\n\n// add a gradient over the image\n\n.EventInfo__hero-inner {\n\t#gradient .vertical(fade(@details-bg, 10%),@details-bg, -20%, 90%);\n\theight: 100%;\n\tpadding: 4em 2em 1.3em;\n\tposition: relative;\n\twidth: 100%;\n}\n\n\n.EventInfo__hero_subtitle {}\n.EventInfo__hero_title {\n\tfont-size: @font-size-xl;\n\tfont-weight: bold;\n\tmargin-bottom: 1em;\n\t// margin-top: 1em;\n}\n.EventInfo__hero_address {\n\tfont-size: @font-size-xl;\n}\n\n\n// button\n\n.EventInfo__hero_button {\n\tmargin-bottom: 2em;\n\tmargin-top: 2em;\n}\n\n\n\n\n// Summary\n// ------------------------------\n\n.EventInfo__summary {\n\tpadding: 2em;\n}\n\n\n\n\n// Links (twitter/facebook)\n// ------------------------------\n\n// on tap highlight the icon to give the user feedback\n.EventInfo__link {\n\t&.Tappable-active {\n\t\t.EventInfo__link__icon--twitter { color: @twitter-brand; }\n\t\t.EventInfo__link__icon--facebook { color: @facebook-brand; }\n\t}\n}\n\n\n\n\n// Organisers\n// ------------------------------\n\n.EventInfo__organisers {\n\tmargin-bottom: 2em;\n\n\t.ListHeader {\n\t\tbackground-color: @details-bg;\n\t\tline-height: 4;\n\t\ttext-align: center;\n\t}\n}\n\n\n\n\n// Sponsors\n// ------------------------------\n\n\n// base\n\n.EventInfo__sponsors {\n\tbackground-color: white;\n\tcolor: #222;\n\tpadding: 2em 1em;\n\ttext-align: center;\n\n\timg {\n\t\t.img-responsive();\n\t}\n}\n.EventInfo__sponsors__heading {\n\tfont-weight: bold;\n}\n\n\n// tiers\n\n.EventInfo__sponsors__tier {\n\tmargin-top: 3em;\n\tposition: relative;\n\n\t// line\n\t&::before {\n\t\tbackground-color: rgba(0, 0, 0, 0.1);\n\t\tcontent: \" \";\n\t\tleft: 0;\n\t\theight: 1px;\n\t\tposition: absolute;\n\t\ttop: 50%;\n\t\twidth: 100%;\n\t}\n}\n.EventInfo__sponsors__tier-text {\n\tbackground-color: white;\n\tdisplay: inline-block;\n\tpadding-left: 1em;\n\tpadding-right: 1em;\n\tposition: relative;\n\tz-index: 1;\n}\n\n\n// primary sponsors\n\n.EventInfo__sponsor--diamond,\n.EventInfo__sponsor--platinum,\n.EventInfo__sponsor--gold,\n.EventInfo__sponsor--silver,\n.EventInfo__sponsor--platinum {\n\n\t.EventInfo__sponsor__image {\n\t\tmargin: 2em;\n\t}\n\t.EventInfo__sponsor__text {\n\t\tfont-size: @font-size-sm;\n\t\tline-height: 1.3;\n\t\ttext-align: left;\n\t}\n}\n.EventInfo__sponsor__button {\n\tborder-radius: .25em;\n\tdisplay: block;\n\tline-height: 2.3;\n\tmargin-top: 1em;\n\n\t&.Tappable-active {\n\t\tbackground-color: rgba(0, 0, 0, 0.05);\n\t}\n}\n.EventInfo__sponsor__button--link {\n\tborder: 1px solid rgba(0, 0, 0, 0.1);\n\tfont-weight: 500;\n}\n\n\n// bronze sponsors\n\n// .EventInfo__sponsor--bronze {\n// \tdisplay: block;\n// \tpadding: 1em;\n// }\n\n\n// startup sponsors\n\n.EventInfo__sponsor--bronze,\n.EventInfo__sponsor--supporter,\n.EventInfo__sponsor--startup,\n.EventInfo__sponsor--partner {\n\tdisplay: inline-block;\n\tpadding: 1em;\n\ttext-align: center;\n\tvertical-align: middle;\n\twidth: 50%;\n}\n\n// .EventInfo__sponsor--supporter {\n// \twidth: 50%;\n// }\n\n\n// // supporting sponsors\n\n// .EventInfo__sponsor--startup {\n// \twidth: 33.33%;\n// }\n"
  },
  {
    "path": "src/css/views/index.less",
    "content": "// \n// Components\n// ==============================\n\n\n\n\n\n// Views\n// ------------------------------\n\n.View {\n\tbackground-color: black;\n}\n.ErrorView,\n.View--people,\n.View--schedule {\n\tbackground-color: @body-bg;\n}\n\n\n\n\n@import \"about\";\n@import \"announcement\";\n@import \"event\";\n@import \"details\";\n@import \"misc\";\n@import \"onboarding\";\n@import \"person\";\n@import \"schedule\";\n@import \"talk\";\n"
  },
  {
    "path": "src/css/views/misc.less",
    "content": "//\n// Miscellaneous\n// ==============================\n\n\n\n\n\n// View Feedback\n// ------------------------------\n\n\n// no results\n\n.no-results {\n\tcolor: fade(@text-color, 60%);\n}\n.no-results__icon {\n\tfont-size: 64px;\n}\n.no-results__text {\n\tmargin-top: 1em;\n}\n\n\n// search attendees message\n\n.search-attendees-message {\n\tcolor: fade(white, 50%);\n\tfont-size: @font-size-xs;\n\tline-height: 1.4;\n\tpadding: 2em;\n\ttext-align: center;\n}\n\n\n\n\n\n// Forms\n// ------------------------------\n\n\n// hide the last divider on stacked forms\n\n.field-item:last-child > .item-inner::after {\n\tdisplay: none;\n}\n\n\n\n\n\n// Table buttons\n// ------------------------------\n\n.button-table {\n\tborder-bottom: 1px solid rgba(255, 255, 255, 0.1);\n\tborder-top: 1px solid rgba(255, 255, 255, 0.1);\n\tdisplay: table;\n\ttable-layout: fixed;\n\twidth: 100%;\n}\n.button-table__item {\n\tbackground: none;\n\tborder: none;\n\tdisplay: table-cell;\n\tpadding: 1em;\n\ttext-align: center;\n\n\t& + & {\n\t\tborder-left: 1px solid rgba(255, 255, 255, 0.1);\n\t}\n\n\t&.Tappable-active {\n\t\tbackground-color: rgba(0, 0, 0, 0.1);\n\t}\n\n\t// disabled option\n\t&.is-disabled {\n\t\tpointer-events: none;\n\n\t\t> .button-table__item__icon,\n\t\t> .button-table__item__label {\n\t\t\topacity: .3;\n\t\t}\n\t}\n}\n.button-table__item__icon {\n\tdisplay: inline-block;\n\tfont-size: 32px;\n\tmargin-bottom: (@font-size-base / 2);\n}\n\n\n\n\n\n// Generic Buttons\n// ------------------------------\n\n.button {\n\t.button-press();\n\tbackground: white;\n\tborder: none;\n\tborder-radius: .3em;\n\tcolor: @details-bg;\n\tdisplay: inline-block;\n\tfont-weight: bold;\n\tline-height: 2.4;\n\tpadding-left: 1.25em;\n\tpadding-right: 1.25em;\n}\n\n\n\n\n\n// Type\n// ------------------------------\n\n.text-block {\n\tfont-size: @font-size-sm;\n\tline-height: 1.3;\n}"
  },
  {
    "path": "src/css/views/onboarding.less",
    "content": "//\n// Onboarding\n// ==============================\n\n\n\n// View BG\n// ------------------------------\n\n.onboarding-container {\n\t#gradient .vertical(spin(@body-bg, -12%), spin(@body-bg, 10%));\n}\n\n\n\n// TODO: ViewManager - move this later\n// ------------------------------\n\n.ViewManager {\n\theight: 100%;\n\toverflow: hidden;\n\tposition: absolute;\n\twidth: 100%;\n}\n\n\n\n// TODO: generic animations\n// ------------------------------\n\n.animation-fade-enter {\n\t.animation( fadeIn 320ms linear );\n}\n.animation-fade-leave {\n\t.animation( fadeOut 320ms linear );\n}\n\n\n\n// TODO: move this to touchstone\n// ------------------------------\n\n.panel {\n\ttext-align: left;\n}\n\n\n\n// Layout\n// ------------------------------\n\n// header\n\n.onboarding-header {\n\tline-height: 1.3;\n}\n\n\n// footer\n\n.onboarding-footer {\n\tborder-top: 1px solid mix(white, spin(@body-bg, 10%), 15%);\n\tfont-size: @font-size-sm;\n\tfont-weight: 500;\n\tline-height: 60px;\n\theight: 60px;\n\tpadding: 1px;\n}\n\n.onboarding-footer__button {\n\t.transition-transform( 40ms linear );\n\t.flex(1,1,0);\n\tcolor: white;\n\twhite-space: nowrap;\n\n\t&.Tappable-active {\n\t\tbackground-color: fade(black, 10%);\n\t\tbox-shadow: inset 0 2px 10px -5px rgba(0, 0, 0, 0.1);\n\t}\n\n\t& + & {\n\t\tborder-left: 1px solid mix(white, spin(@body-bg, 10%), 15%);\n\t}\n}\n\n\n\n\n// Type\n// ------------------------------\n\n\n// common\n\n.onboarding-heading {}\n\n// H1\n\n.onboarding-heading-1 {\n\tfont-size: 24px;\n\ttext-align: center;\n}\n\n// H2\n\n.onboarding-heading-2 {\n\tcolor: rgba(255, 255, 255, 0.75);\n\tfont-size: 18px;\n}\n\n\n\n\n// Logo\n// ------------------------------\n\n.onboarding-logo {\n\tmargin-bottom: 2em;\n\twidth: 90px;\n}\n\n\n\n\n// Scan Button\n// ------------------------------\n\n@scanbutton-image-size: 48px;\n@scanbutton-icon-size: 48px;\n\n.onboarding-scan-wrapper {\n\t.square(170px);\n\tdisplay: block;\n\tmax-width: 50%;\n\tposition: relative;\n\ttext-align: center;\n}\n.onboarding-scan {\n\tposition: absolute; // so it transitions nicely when switching between online/offline\n}\n.onboarding-scan__button {\n\t.button-press();\n\t.square(100px);\n\tbackground-color: white;\n\tborder-radius: 50%;\n\tdisplay: inline-block;\n\tmargin-bottom: 1em;\n\tposition: relative;\n}\n.onboarding-scan__image,\n.onboarding-scan__icon {\n\t.square(@scanbutton-icon-size);\n\tdisplay: inline-block;\n\tleft: 50%;\n\tposition: absolute;\n\ttop: 50%;\n\n\t> svg {\n\t\t.square(@scanbutton-icon-size);\n\t\tfill: @app-primary;\n\t}\n}\n\n.onboarding-scan__image {\n\t.square(@scanbutton-image-size);\n\tdisplay: inline-block;\n\tmargin-left: -(@scanbutton-image-size / 2);\n\tmargin-top: -(@scanbutton-image-size / 2);\n\n\t> svg {\n\t\t.square(@scanbutton-image-size);\n\t\tfill: @app-primary;\n\t}\n}\n.onboarding-scan__icon {\n\t.square(@scanbutton-icon-size);\n\tcolor: @app-primary;\n\tdisplay: inline-block;\n\tfont-size: @scanbutton-icon-size;\n\tmargin-left: -(@scanbutton-icon-size / 2);\n\tmargin-top: -(@scanbutton-icon-size / 2);\n\n\t&.is-loading {\n\t\t.animation( spin 1s linear infinite );\n\t\topacity: .5;\n\t}\n\t&.is-valid {\n\t\tcolor: @app-success;\n\t}\n}\n\n\n// accompanying text that sits beneath the button\n\n.onboarding-scan__text {\n\tcolor: rgba(255, 255, 255, 0.75);\n}\n\n\n\n\n// Form\n// ------------------------------\n\n@form-component-size: 48px;\n\n\n// base\n\n.onboarding-form {\n\t.display-flex();\n}\n\n\n// sections\n\n.onboarding-form__section {\n\tpadding-left: .5em;\n\tpadding-right: .5em;\n\n\t&:first-child { padding-left: 0; }\n\t&:last-child { padding-right: 0; }\n}\n.onboarding-form__section--field {\n\t.flex(1,1,0);\n}\n\n\n// input\n\n.onboarding-form__input {\n\t.placeholder(rgba(255, 255, 255, 0.5));\n\tbackground: none;\n\tborder: none;\n\tborder-bottom: 1px solid rgba(255, 255, 255, 0.5);\n\tborder-radius: 0;\n\tcolor: white;\n\tfont-size: 18px;\n\tline-height: 1.2;\n\theight: @form-component-size;\n\tpadding: 0;\n\twidth: 100%;\n\t-webkit-appearance: none;\n\n\t&:active,\n\t&:hover,\n\t&:focus {\n\t\toutline: none;\n\t}\n}\n\n\n// button\n\n.onboarding-form__button {\n\t.square(@form-component-size);\n\tbackground: none;\n\tborder-radius: 50%;\n\tborder: 3px solid currentColor;\n\tcolor: white;\n\tline-height: 0;\n\toutline: none;\n\t-webkit-appearance: none;\n\n\t// icon begins as an arrow pointing right\n\t.ionicon(inherit, @ionicon-var-arrow-right-c, 32px);\n\n\t// update the icon to a spinner\n\t&.is-loading {\n\t\t.animation( spin 1s linear infinite );\n\n\t\t&::before {\n\t\t\tcontent: @ionicon-var-load-b;\n\t\t\tcolor: rgba(255, 255, 255, 0.75);\n\t\t}\n\t}\n\n\t// update the icon to a green checkmark if valid\n\t&.is-valid::before {\n\t\tcontent: @ionicon-var-ios-checkmark;\n\t\tcolor: mix(@app-success, white, 50%);\n\t}\n\n\t// update the icon to a red cross if invalid\n\t&.is-invalid::before {\n\t\tcontent: @ionicon-var-ios-close;\n\t\tcolor: mix(@app-danger, white, 50%);\n\t}\n}\n\n\n\n\n// Form Feedback\n\n.onboarding-feedback {\n\t.animation( fadeIn 300ms );\n\tbackground-color: white;\n\tborder-left: 4px solid transparent;\n\tborder-radius: .25em;\n\tfont-weight: 500;\n\tline-height: 1.3;\n\tmargin-top: 2em;\n\tpadding: .5em 1em;\n\ttext-align: left;\n}\n.onboarding-feedback--danger {\n\tcolor: @app-danger;\n\tborder-left-color: @app-danger;\n}\n.onboarding-feedback--success {\n\tcolor: @app-success;\n\tborder-left-color: @app-success;\n}\n"
  },
  {
    "path": "src/css/views/person.less",
    "content": "//\n// Person\n// ==============================\n\n\n\n\n// Body\n// ------------------------------\n\n.PersonDetails {\n\tpadding: 2em;\n\ttext-align: center;\n}\n.PersonDetails__avatar {\n\t.avatar(120px);\n\tbackground-color: rgba(255, 255, 255, 0.5);\n\tmargin-bottom: 1em;\n}\n.PersonDetails__heading {\n\tfont-size: @font-size-lg;\n\tfont-weight: 500;\n}\n.PersonDetails__text {\n\tmargin-top: 1em;\n}\n\n\n// profile\n\n.PersonDetails__profiles {\n\tfont-size: @font-size-lg;\n\tmargin-top: 1em;\n}\n.PersonDetails__profile {\n\t.button-press();\n\tdisplay: block;\n\tpadding-bottom: .5em;\n\tpadding-top: .5em;\n}\n// 1. fix vertical alignment\n.PersonDetails__profile__icon {\n\tdisplay: inline-block;\n\tfont-size: 1.25em;\n\tline-height: 1; // 1\n\tmargin-right: .5em;\n\tmargin-top: -.15em; // 1\n\tvertical-align: middle;\n}\n\n.PersonDetails__public-indicator {\n\tbackground-color: rgba(255, 255, 255, 0.125);\n\tborder-radius: 2em;\n\tdisplay: inline-block;\n\tline-height: 2.4;\n\tfont-size: @font-size-xxs;\n\tfont-weight: 500;\n\tmargin-bottom: 1.8em;\n\tmargin-top: 1.8em;\n\tpadding-left: 1.25em;\n\tpadding-right: 1.25em;\n\ttext-transform: uppercase;\n}\n\n\n\n\n// QR + Code\n// ------------------------------\n\n.entry-code {\n\tpadding: 1em;\n\ttext-align: center;\n}\n.entry-code__image {\n\tbackground-color: white;\n\theight: auto;\n\tborder-radius: .3em;\n\t// padding: @gutter-base;\n\tmax-width: 200px;\n}\n.entry-code__heading {\n\tdisplay: inline-block;\n\tfont-weight: 500;\n\tline-height: 1.3;\n\tmargin-bottom: 1.6em;\n\tmax-width: 90%;\n}\n.entry-code__text {\n\tfont-family: monaco;\n\tmargin-top: 1em;\n}\n\n\n\n\n// Explain why register\n// ------------------------------\n\n\n// base\n\n.MeRegistration__body {\n\tpadding: 2em;\n}\n.MeRegistration__heading {\n\tfont-size: @font-size-huge;\n\tfont-weight: 500;\n\tmargin-bottom: 1em;\n}\n.MeRegistration__intro {\n\tcolor: rgba(255, 255, 255, 0.66);\n\tfont-size: @font-size-small;\n\tline-height: 1.2;\n}\n.MeRegistration__section {\n\tmargin: 2em auto;\n\twidth: 100%;\n}\n.MeRegistration__section:first-child {\n    margin-top: 0;\n}\n\n\n// benefits\n\n.MeRegistration__benefits {\n\tmargin: 1em 0;\n\ttext-align: left;\n}\n.MeRegistration__benefit {\n\tline-height: 1.3;\n\tmargin: 1em 0;\n\toverflow: hidden;\n}\n.MeRegistration__benefit__icon {\n\t.square(30px);\n\tbackground-color: white;\n\tborder-radius: 50%;\n\tcolor: @app-primary;\n\tfloat: left;\n\tline-height: 30px;\n\tmargin-right: 1em;\n\ttext-align: center;\n}\n.MeRegistration__benefit__label {\n\toverflow: hidden;\n}\n\n\n// footer\n\n.MeRegistration__footer {\n\tpadding: 1em;\n}\n.MeRegistration__footer-button {\n\t.button-press();\n\tbackground-color: @app-primary;\n\tborder-radius: .3em;\n\tcolor: white;\n\tdisplay: block;\n\tfont-weight: 500;\n\tline-height: 3;\n}\n\n\n\n\n// Footer\n// ------------------------------\n\n.PersonDetails__talk {\n\t.display-flex();\n\t.align-items(center);\n\tbackground-color: @charcoal;\n\tfont-size: @font-size-xs;\n\theight: @headerbar-height;\n\tpadding: 0 @gutter-base;\n\n\t&.Tappable-active {\n\t\tbackground-color: rgba(0, 0, 0, 0.2);\n\t}\n}\n.PersonDetails__talk-inner {\n\t.flex(1,1,0);\n\tline-height: 1.2;\n}\n.PersonDetails__talk__time {\n\tcolor: rgba(255, 255, 255, 0.75);\n}\n.PersonDetails__talk__title {\n\t.text-overflow();\n\tfont-weight: 500;\n}\n.PersonDetails__talk-chevron {\n\tfont-size: 24px;\n\tmargin-left: @gutter-base;\n}\n"
  },
  {
    "path": "src/css/views/schedule.less",
    "content": "// \n// Schedule\n// =============================="
  },
  {
    "path": "src/css/views/talk.less",
    "content": "// \n// Talk\n// ==============================\n\n\n\n\n// Base\n// ------------------------------\n\n.TalkDetails {\n}\n\n\n\n\n// Speaker\n// ------------------------------\n\n.TalkDetails__speakers {\n\tmargin-bottom: 2em;\n}\n\n.TalkDetails__speaker {\n\t.align-items(center);\n\t.display-flex();\n\t.retina-1px-border-bottom( rgba(255, 255, 255, 0.17) );\n\tmargin-right: -1em;\n\tpadding: 10px 1em 10px 0;\n\n\t&:first-child {\n\t\t.retina-1px-border-top-and-bottom( rgba(255, 255, 255, 0.17) );\n\t}\n\n\t&.Tappable-active {\n\t\t#gradient .horizontal-three-colors(fade(black,0%),fade(black,20%),50%,fade(black,0%));\n\t}\n}\n.TalkDetails__speaker__name {\n\t.flex(1,1,0);\n\tpadding: 0 1em;\n}\n.TalkDetails__speaker__avatar {\n\t.avatar(40px);\n}\n\n\n\n\n// Details\n// ------------------------------\n.TalkDetails__details {\n\tpadding: 1em 1em 2em;\n}\n\n.TalkDetails__heading {\n\tfont-size: @font-size-huge;\n\tfont-weight: 500;\n\tline-height: 1.2;\n\tmargin-bottom: 1em;\n\tmargin-top: 1em;\n}\n\n\n\n\n// Button\n// ------------------------------\n\n.TalkDetails__button__icon {\n\t&.is-positive { color: @app-success; }\n\t&.is-negative { color: @app-danger; }\n}\n\n\n\n\n// Next Talk\n// ------------------------------\n\n.TalkDetails__next-talk {\n\tdisplay: block; // reset because .Footerbar is displayed \"flex\" by default\n\tfont-size: @font-size-xs;\n\tline-height: 1.2;\n\theight: auto;\n\tpadding: @gutter-base;\n\ttext-align: center;\n}\n\n.TalkDetails__next-talk__time {\n\tcolor: rgba(255, 255, 255, 0.75);\n}\n.TalkDetails__next-talk__name {\n\tfont-weight: 500;\n}\n.TalkDetails__next-talk__chevron {\n\tfont-size: 24px;\n}\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "src/index.html",
    "content": "<!DOCTYPE html>\n<html>\n\t<!--\n\tCustomize this policy to fit your own app's needs. For more guidance, see:\n\t\thttps://github.com/apache/cordova-plugin-whitelist/blob/master/README.md#content-security-policy\n\t\thttps://developer.chrome.com/extensions/contentSecurityPolicy\n\n\tSome notes:\n\t\t* gap: is required only on iOS (when using UIWebView) and is needed for JS->native communication\n\t\t* https://ssl.gstatic.com is required only on Android and is needed for TalkBack to function properly\n\t\t* Disables use of inline scripts in order to mitigate risk of XSS vulnerabilities. To change this:\n\t\t\t* Enable inline JS: add 'unsafe-inline' to default-src\n\t-->\n\t<head>\n\t\t<!--- Debug CSP -->\n\t\t<meta http-equiv=\"Content-Security-Policy\" content=\"default-src https://codepush.azurewebsites.net 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval';; script-src 'self' * 'unsafe-inline'; img-src * data:; connect-src *; style-src 'self' 'unsafe-inline'; media-src *\">\n\n\t\t<!--- Production CSP\n\t\t<meta http-equiv=\"Content-Security-Policy\" content=\"default-src https://codepush.azurewebsites.net 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; connect-src *; style-src 'self' 'unsafe-inline'; media-src *\">\n\t\t-->\n\n\t\t<link rel=\"stylesheet\" type=\"text/css\" href=\"css/app.css\">\n\t\t<title>ReactEurope</title>\n\n\t\t<!-- Full screen -->\n\t\t<meta name=\"viewport\" content=\"user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width\">\n\n\t\t<!-- iOS mobile-web-app -->\n\t\t<meta name=\"apple-mobile-web-app-capable\" content=\"yes\" />\n\t\t<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black-translucent\" />\n\t\t<meta name=\"apple-mobile-web-app-title\" content=\"ReactEurope\" />\n\n\t\t<link href=\"img/ios-icon.png\" rel=\"apple-touch-icon\" />\n\t\t<link href=\"img/splash-screen.png\" rel=\"apple-touch-startup-image\" />\n\n\t\t<!-- Android mobile-web-app -->\n\t\t<meta name=\"mobile-web-app-capable\" content=\"yes\" />\n\n\t\t<!-- Windows mobile-web-app -->\n\t\t<meta name=\"msapplication-tap-highlight\" content=\"no\">\n\n\t\t<!-- Browser -->\n\t\t<link rel=\"shortcut icon\" href=\"favicon.ico\" type=\"image/x-icon\">\n\n\t\t<!-- Other -->\n\t\t<meta name=\"format-detection\" content=\"telephone=no\">\n\t</head>\n\t<body>\n\t\t<div id=\"app\"/>\n\n\t\t<script type=\"text/javascript\" src=\"cordova.js\"></script>\n\t\t<script type=\"text/javascript\" src=\"js/react.js\"></script>\n\t\t<script type=\"text/javascript\" src=\"js/app.js\"></script>\n\t</body>\n</html>\n"
  },
  {
    "path": "src/js/app.js",
    "content": "var React = require('react/addons');\nvar Sentry = require('react-sentry');\nvar {\n\tcreateApp,\n\tContainer,\n\tNavigationBar,\n\tTabs,\n\tViewManager,\n\tView\n} = require('./touchstone');\n\nvar DataStore = require('./stores/DataStore');\nvar dataStore = new DataStore();\nwindow.dataStore = dataStore;\n\nvar device = require('./lib/device');\n\nfunction hideSplashScreen () {\n\ttry {\n\t\tnavigator.splashscreen.hide();\n\t} catch(e) {}\n}\n\nfunction blockBodyTouchMove (e) {\n\tvar currentTarget = e.target;\n\twhile (currentTarget && currentTarget !== document.body) {\n\t\tif (currentTarget.scrollHeight > currentTarget.offsetHeight) {\n\t\t\t// we found a scrollable area; allow it.\n\t\t\treturn;\n\t\t}\n\t\tcurrentTarget = currentTarget.parentNode;\n\t}\n\t// no scrollable parent elements; prevent the move.\n\te.preventDefault();\n}\n\nfunction bindBlockBodyTouchMove () {\n\twindow.addEventListener('touchmove', blockBodyTouchMove);\n}\n\nfunction unbindBlockBodyTouchMove () {\n\twindow.removeEventListener('touchmove', blockBodyTouchMove);\n}\n\nvar lastWindowHeight = 0;\nvar keyboardIsVisible = false;\n\nfunction updateAppHeight(h) {\n\tif (typeof h === 'number') h = h + 'px';\n\tdocument.getElementById('app').style.height = h;\n};\n\nfunction fixWindowHeight () {\n\tvar resetAppHeight = function() {\n\t\tif (keyboardIsVisible || window.innerHeight === lastWindowHeight) return;\n\t\tlastWindowHeight = window.innerHeight;\n\t\tupdateAppHeight(lastWindowHeight);\n\t\t// if the iOS in-call status bar is visible, this fixes the scrolling\n\t\t// bug that's present on the document body.\n\t\tif (document.body.scrollHeight > window.innerHeight) {\n\t\t\tbindBlockBodyTouchMove();\n\t\t} else {\n\t\t\tunbindBlockBodyTouchMove();\n\t\t}\n\t}\n\tresetAppHeight();\n\tsetInterval(resetAppHeight, 250);\n}\n\nfunction keyboardShowHandler(e) {\n\tkeyboardIsVisible = true;\n\tdelete document.getElementById('app').style.height;\n    console.log('Keyboard height is: ' + e.keyboardHeight + ', window height is: ' + window.innerHeight + ', last window height is: ' + lastWindowHeight);\n}\n\nfunction keyboardHideHandler(e) {\n\tkeyboardIsVisible = false;\n\tupdateAppHeight(lastWindowHeight);\n    console.log('Keyboard is hidden, window height is: ' + window.innerHeight + ', last window height is: ' + lastWindowHeight);\n}\n\nvar App = React.createClass({\n\tmixins: [createApp(), Sentry()],\n\n\tchildContextTypes: {\n\t\tdataStore: React.PropTypes.object\n\t},\n\n\tgetChildContext () {\n\t\treturn {\n\t\t\tdataStore: dataStore\n\t\t};\n\t},\n\n\tgetInitialState () {\n\t\treturn {\n\t\t\tdefaultView: dataStore.amRegistered() ? 'main' : 'onboarding-main-event'\n\t\t};\n\t},\n\n\tcomponentDidMount () {\n\t\t// Delay the splash screen fade to allow for initial render to complete\n\t\tsetTimeout(hideSplashScreen, 1000);\n\n\t\tthis.watch(dataStore, 'update-settings', this.updateAppState);\n\t\tthis.watch(document, 'backbutton', function (e) {\n\t\t\te.preventDefault();\n\t\t\treturn console.info('Do nothing by default; where applicable views have their own back button handler.');\n\t\t});\n\n\t\tvar settings = dataStore.getSettings();\n\t\tif (!settings.kill) return;\n\n\t\tthis.updateAppState(settings);\n\t},\n\n\tupdateAppState (settings) {\n\t\tif (!settings.kill) return;\n\n\t\tthis.refs.vm.transitionTo('announcement', {\n\t\t\tviewProps: settings.kill\n\t\t});\n\t},\n\n\trender () {\n\t\tvar appWrapperClassName = 'app-wrapper device--' + device.platform;\n\n\t\treturn (\n\t\t\t<div className={appWrapperClassName}>\n\t\t\t\t<div className=\"device-silhouette\">\n\t\t\t\t\t<ViewManager ref=\"vm\" name=\"app\" defaultView={this.state.defaultView}>\n\t\t\t\t\t\t<View name=\"onboarding-main-event\" component={require('./views/onboarding/main-event/index')} />\n\t\t\t\t\t\t<View name=\"onboarding-main-event-resend-email\" component={require('./views/onboarding/main-event/resend-email')} />\n\t\t\t\t\t\t<View name=\"onboarding-main-event-enter-code\" component={require('./views/onboarding/main-event/enter-code')} />\n\t\t\t\t\t\t<View name=\"onboarding-workshop\" component={require('./views/onboarding/workshop/index')} />\n\t\t\t\t\t\t<View name=\"onboarding-workshop-resend-email\" component={require('./views/onboarding/workshop/resend-email')} />\n\t\t\t\t\t\t<View name=\"onboarding-workshop-enter-code\" component={require('./views/onboarding/workshop/enter-code')} />\n\t\t\t\t\t\t<View name=\"onboarding-hackathon\" component={require('./views/onboarding/hackathon/index')} />\n\t\t\t\t\t\t<View name=\"onboarding-hackathon-resend-email\" component={require('./views/onboarding/hackathon/resend-email')} />\n\t\t\t\t\t\t<View name=\"onboarding-hackathon-enter-code\" component={require('./views/onboarding/hackathon/enter-code')} />\n\t\t\t\t\t\t<View name=\"main\" component={MainViewController} />\n\t\t\t\t\t\t<View name=\"announcement\" component={require('./views/announcement')} />\n\t\t\t\t\t</ViewManager>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n});\n\nvar MainViewController = React.createClass({\n\trender () {\n\t\treturn (\n\t\t\t<Container>\n\t\t\t\t<NavigationBar name=\"main\" />\n\t\t\t\t<ViewManager name=\"main\" defaultView=\"tabs\">\n\t\t\t\t\t<View name=\"tabs\" component={TabViewController} />\n\t\t\t\t\t<View name=\"person\" component={require('./views/people/person')} />\n\t\t\t\t\t<View name=\"talk\" component={require('./views/schedule/talk')} />\n\t\t\t\t</ViewManager>\n\t\t\t</Container>\n\t\t);\n\t}\n});\n\nvar lastSelectedTab = 'me';\nvar TabViewController = React.createClass({\n\tcontextTypes: { dataStore: React.PropTypes.object.isRequired },\n\tmixins: [Sentry()],\n\n\tgetInitialState () {\n\t\tvar showAboutView = this.context.dataStore.getSettings().showAboutView;\n\t\tvar theBigReveal = Date.now() > new Date('Wed, 03 Jul 2015 10:00:00 GMT').getTime();\n\n\t\treturn {\n\t\t\tselectedTab: lastSelectedTab,\n\t\t\tshowAboutView: showAboutView || theBigReveal\n\t\t};\n\t},\n\n\tcomponentDidMount () {\n\t\t// android backbutton handler\n\t\tthis.watch(document, 'backbutton', () => {\n \t\t\t\tvar body = document.getElementsByTagName('body')[0];\n \t\t\t\tbody.classList.remove('android-menu-is-open');\n\t\t});\n\n\t\tthis.watch(dataStore, 'update-settings', this.updateTabState);\n\t},\n\n\tonViewChange (nextView) {\n\t\tlastSelectedTab = nextView;\n\n\t\tthis.setState({\n\t\t\tselectedTab: nextView\n\t\t});\n\t},\n\n\tupdateTabState (settings) {\n\t\tthis.setState({\n\t\t\tshowAboutView: settings.showAboutView\n\t\t});\n\t},\n\n\tselectTab (tab) {\n\t\tvar viewProps;\n\n\t\tif (tab.value === 'me') {\n\t\t\tviewProps = {\n\t\t\t\tme: this.context.dataStore.getMe()\n\t\t\t};\n\t\t}\n\n\t\tthis.refs.vm.transitionTo(tab.value, {\n\t\t\tviewProps: viewProps\n\t\t});\n\t},\n\n\trenderAboutTab () {\n\t\tif (!this.state.showAboutView) return <span />;\n\n\t\treturn (\n\t\t\t<Tabs.Tab value=\"about\">\n\t\t\t\t<span className=\"Tabs-Icon Tabs-Icon--about\" />\n\t\t\t\t<Tabs.Label>About</Tabs.Label>\n\t\t\t</Tabs.Tab>\n\t\t);\n\t},\n\n\trender () {\n\t\tvar selectedTab = this.state.selectedTab;\n\t\tif (selectedTab === 'me' || selectedTab === 'me-edit') {\n\t\t\tselectedTab = 'me';\n\t\t}\n\n\t\tvar me = this.context.dataStore.getMe();\n\n\t\treturn (\n\t\t\t<Container>\n\t\t\t\t<ViewManager ref=\"vm\" name=\"tabs\" defaultView={this.state.selectedTab} onViewChange={this.onViewChange}>\n\t\t\t\t\t<View name=\"schedule\" component={require('./views/schedule')} />\n\t\t\t\t\t<View name=\"people\" me={me} component={require('./views/people')} />\n\t\t\t\t\t<View name=\"event\" component={require('./views/event')} />\n\t\t\t\t\t<View name=\"me\" me={me} component={require('./views/me')} />\n\t\t\t\t\t<View name=\"me-edit\" component={require('./views/me/edit')} />\n\t\t\t\t\t<View name=\"about\" component={require('./views/about')} />\n\t\t\t\t</ViewManager>\n\t\t\t\t<Tabs.Navigator value={selectedTab} onChange={this.selectTab}>\n\t\t\t\t\t<Tabs.Tab value=\"schedule\">\n\t\t\t\t\t\t<span className=\"Tabs-Icon Tabs-Icon--schedule\" />\n\t\t\t\t\t\t<Tabs.Label>Schedule</Tabs.Label>\n\t\t\t\t\t</Tabs.Tab>\n\t\t\t\t\t<Tabs.Tab value=\"people\">\n\t\t\t\t\t\t<span className=\"Tabs-Icon Tabs-Icon--people\" />\n\t\t\t\t\t\t<Tabs.Label>People</Tabs.Label>\n\t\t\t\t\t</Tabs.Tab>\n\t\t\t\t\t<Tabs.Tab value=\"event\">\n\t\t\t\t\t\t<span className=\"Tabs-Icon Tabs-Icon--event\" />\n\t\t\t\t\t\t<Tabs.Label>Event</Tabs.Label>\n\t\t\t\t\t</Tabs.Tab>\n\t\t\t\t\t<Tabs.Tab value=\"me\">\n\t\t\t\t\t\t<span className=\"Tabs-Icon Tabs-Icon--me\" />\n\t\t\t\t\t\t<Tabs.Label>Me</Tabs.Label>\n\t\t\t\t\t</Tabs.Tab>\n\t\t\t\t\t{this.renderAboutTab()}\n\t\t\t\t</Tabs.Navigator>\n\t\t\t</Container>\n\t\t);\n\t}\n});\n\nfunction startApp () {\n\tif (window.StatusBar) {\n\t\twindow.StatusBar.styleLightContent();\n\t}\n\tfixWindowHeight();\n\tReact.render(<App />, document.getElementById('app'));\n}\n\nfunction startAppMobile () {\n\twindow.codePush.sync();\n\tstartApp();\n}\n\n// native? wait for deviceready and call codepush\nif (window.cordova) {\n\twindow.addEventListener('native.keyboardshow', keyboardShowHandler);\n\twindow.addEventListener('native.keyboardhide', keyboardHideHandler);\n\tdocument.addEventListener('deviceready', startAppMobile, false);\n\n// browser, start asap\n} else {\n\tstartApp();\n}\n"
  },
  {
    "path": "src/js/components/AppHeader.js",
    "content": "var React = require('react');\nvar Touchstone = require('../touchstone');\n\nvar { NavigationBar } = Touchstone;\n\nmodule.exports = React.createClass({\n\tdisplayName: 'AppHeader',\n\tpropTypes: {\n\t\tleftAction: React.PropTypes.func,\n\t\tleftArrow: React.PropTypes.bool,\n\t\tleftButtonDisabled: React.PropTypes.bool,\n\t\tleftIcon: React.PropTypes.string,\n\t\tleftLabel: React.PropTypes.string,\n\t\trightAction: React.PropTypes.func,\n\t\trightArrow: React.PropTypes.bool,\n\t\trightButtonDisabled: React.PropTypes.bool,\n\t\trightIcon: React.PropTypes.string,\n\t\trightLabel: React.PropTypes.string,\n\t\ttitle: React.PropTypes.string\n\t},\n\tgetInitialState () {\n\t\treturn {\n\t\t\tnavbarProps: this.getDefaultNavbarProps()\n\t\t};\n\t},\n\tgetDefaultNavbarProps () {\n\t\treturn {\n\t\t\tdirection: 0,\n\t\t\tleftAction: null,\n\t\t\tleftArrow: false,\n\t\t\tleftButtonDisabled: false,\n\t\t\tleftIcon: '',\n\t\t\tleftLabel: '',\n\t\t\trightAction: null,\n\t\t\trightArrow: false,\n\t\t\trightButtonDisabled: false,\n\t\t\trightIcon: '',\n\t\t\trightLabel: '',\n\t\t\ttitle: ''\n\t\t};\n\t},\n\tupdate (navbarProps) {\n\t\tthis.setState({ navbarProps: navbarProps });\n\t},\n\trender () {\n\t\treturn <NavigationBar {...this.state.navbarProps} />;\n\t}\n});"
  },
  {
    "path": "src/js/components/FeedbackModal.js",
    "content": "var React = require('react/addons');\nvar ReactCSSTransitionGroup = React.addons.CSSTransitionGroup;\n\nvar classnames = require('classnames');\n\nmodule.exports = React.createClass({\n\tdisplayName: 'FeedbackModal',\n\n\tpropTypes: {\n\t\tclassName: React.PropTypes.string,\n\t\tvisible: React.PropTypes.bool\n\t},\n\n\tgetDefaultProps () {\n\t\treturn {\n\t\t\ttransition: 'none'\n\t\t};\n\t},\n\n\trenderBackdrop () {\n\t\tif (!this.props.visible) return null;\n\t\treturn <div className=\"FeedbackModal-backdrop\" />\n\t},\n\n\trenderDialog () {\n\t\tif (!this.props.visible) return null;\n\n\t\t// Set classnames\n\t\tvar dialogClassName = classnames('FeedbackModal-dialog', this.props.className);\n\n\t\treturn (\n\t\t\t<div className={dialogClassName}>\n\t\t\t\t{this.props.children}\n\t\t\t</div>\n\t\t);\n\t},\n\n\trender () {\n\t\treturn (\n\t\t\t<div className=\"FeedbackModal\">\n\t\t\t\t<ReactCSSTransitionGroup transitionName=\"FeedbackModal-dialog\" component=\"div\">\n\t\t\t\t\t{this.renderDialog()}\n\t\t\t\t</ReactCSSTransitionGroup>\n\t\t\t\t<ReactCSSTransitionGroup transitionName=\"FeedbackModal-backdrop\" component=\"div\">\n\t\t\t\t\t{this.renderBackdrop()}\n\t\t\t\t</ReactCSSTransitionGroup>\n\t\t\t</div>\n\t\t);\n\t}\n});\n"
  },
  {
    "path": "src/js/components/ListHeader.js",
    "content": "var React = require('react');\nvar blacklist = require('blacklist');\nvar classNames = require('classnames');\n\nmodule.exports = React.createClass({\n\tdisplayName: 'ListHeader',\n\tpropsTypes: {\n\t\tsticky: React.PropTypes.bool\n\t},\n\trender () {\n\t\tvar className = classNames('ListHeader', {\n\t\t\t'ListHeader--sticky': this.props.sticky\n\t\t}, this.props.className);\n\t\tvar props = blacklist(this.props, 'children', 'sticky');\n\t\tprops.className = className;\n\n\t\treturn <div {...props}>{this.props.children}</div>;\n\t}\n});"
  },
  {
    "path": "src/js/components/Onboarding/enter-code.js",
    "content": "var Container = require('react-container');\nvar OnboardingHeader = require('../../components/OnboardingHeader');\nvar React = require('react');\nvar { Link, Transitions } = require('../../touchstone');\n\nvar classnames = require('classnames');\n\nmodule.exports = React.createClass({\n\tmixins: [Transitions],\n\tcontextTypes: { dataStore: React.PropTypes.object.isRequired },\n  propTypes: {\n\t\ttitle: React.PropTypes.string,\n    id: React.PropTypes.string.isRequired,\n    nextScreen: React.PropTypes.string.isRequired,\n\t\tonCodeEnter: React.PropTypes.func.isRequired\n  },\n\n\tgetInitialState () {\n\t\tvar showResendEmail = this.context.dataStore.getSettings().showResendEmail;\n\t\treturn {\n\t\t\tinput: '',\n\t\t\tloading: false,\n\t\t\tshowResendEmail: showResendEmail,\n\t\t\tvalid: null\n\t\t};\n\t},\n\n\tcomponentDidMount () {\n\t\tvar input = this.refs.input.getDOMNode();\n\n\t\t// wait until the view transition ends then focus the field\n\t\tsetTimeout(function () {\n\t\t\tinput.click();\n\t\t}, 320);\n\t},\n\n\thandleFormInput (e) {\n\t\tthis.setState({\n\t\t\tinput: e.target.value.toUpperCase()\n\t\t});\n\t},\n\n\trenderResendEmail () {\n\t\treturn (this.state.showResendEmail) ? (\n\t\t\t<Link to={\"app:onboarding-\" + this.props.id + \"-resend-email\"} transition=\"fade\" className=\"onboarding-footer__button\">Resend Code</Link>\n\t\t) : null;\n\t},\n\n\thandleFormSubmission (e) {\n\n\t\t// prevent the form from actually submitting\n\t\te.preventDefault();\n\n\t\tif (!this.state.input) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar ticketCode = this.state.input.toLowerCase();\n\t\tvar self = this;\n\n\t\tthis.setState({\n\t\t\tloading: true\n\t\t}, function () {\n\t\t\tthis.props.onCodeEnter(ticketCode, function (err) {\n\t\t\t\tself.setState({\n\t\t\t\t\tloading: false,\n\t\t\t\t\tvalid: !err\n\t\t\t\t}, function () {\n\t\t\t\t\t// success: show the success icon for 1 second then fade to the app\n\t\t\t\t\tif (self.state.valid === true) {\n\t\t\t\t\t\tsetTimeout(function () {\n\t\t\t\t\t\t\treturn self.transitionTo(self.props.nextScreen, {\n\t\t\t\t\t\t\t\ttransition: 'fade'\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}, 1000);\n\n\t\t\t\t\t// fail: return validity to neutral\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsetTimeout(function () {\n\t\t\t\t\t\t\treturn self.setState({ valid: null });\n\t\t\t\t\t\t}, 2000);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\t},\n\n\trender () {\n\t\tvar submitButtonClass = classnames('onboarding-form__button', {\n\t\t\t'is-loading': this.state.loading,\n\t\t\t'is-valid': this.state.valid,\n\t\t\t'is-invalid': this.state.valid === false\n\t\t});\n\n\t\tvar submitIsDisabled = this.state.loading || this.state.valid || this.state.valid === false;\n\n\t\treturn (\n\t\t\t<Container direction=\"column\" className=\"onboarding-container\">\n\t\t\t\t<OnboardingHeader />\n\t\t\t\t<h2 className=\"onboarding-heading-1\">{this.props.title}</h2>\n\t\t\t\t<Container justify align=\"center\" direction=\"column\">\n\t\t\t\t\t<form onSubmit={this.handleFormSubmission} action=\"#\" className=\"onboarding-form\" noValidate>\n\t\t\t\t\t\t<div className=\"onboarding-form__section onboarding-form__section--field\">\n\t\t\t\t\t\t\t<input type=\"text\" ref=\"input\" onChange={this.handleFormInput} value={this.state.input} placeholder=\"Enter Code\" className=\"onboarding-form__input\" disabled={this.state.feedback === 'sent'} />\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div className=\"onboarding-form__section onboarding-form__section--button\">\n\t\t\t\t\t\t\t<button type=\"submit\" className={submitButtonClass} disabled={submitIsDisabled} />\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</form>\n\t\t\t\t</Container>\n\t\t\t\t<Container justify align=\"center\" direction=\"row\" className=\"onboarding-footer\">\n\t\t\t\t\t{this.renderResendEmail()}\n\t\t\t\t\t<Link to={this.props.nextScreen} transition={this.props.transition || \"fade\"} className=\"onboarding-footer__button\">Skip</Link>\n\t\t\t\t\t<Link to={\"app:onboarding-\" + this.props.id} transition=\"show-from-left\" className=\"onboarding-footer__button onboarding-footer__button--primary\">Back</Link>\n\t\t\t\t</Container>\n\t\t\t</Container>\n\t\t);\n\t}\n});\n"
  },
  {
    "path": "src/js/components/Onboarding/index.js",
    "content": "var Container = require('react-container');\nvar Sentry = require('react-sentry');\nvar OnboardingHeader = require('../OnboardingHeader');\nvar React = require('react/addons');\nvar Scanner = require('../Scanner');\nvar Tappable = require('react-tappable');\nvar Transition = React.addons.CSSTransitionGroup;\nvar { Link, Transitions } = require('../../touchstone');\n\nvar classnames = require('classnames');\nvar icons = require('../../icons');\n\nvar OnboardingView = React.createClass({\n\tmixins: [Sentry(), Transitions],\n\tcontextTypes: { dataStore: React.PropTypes.object.isRequired },\n  propTypes: {\n    title: React.PropTypes.string,\n    id: React.PropTypes.string.isRequired,\n    nextScreen: React.PropTypes.string.isRequired,\n    onCodeEnter: React.PropTypes.func.isRequired,\n  },\n\n\tgetInitialState () {\n\t\tvar showResendEmail = this.context.dataStore.getSettings().showResendEmail;\n\t\treturn {\n\t\t\tonline: window.navigator.onLine,\n\t\t\tscanning: false,\n\t\t\tshowResendEmail: showResendEmail,\n\t\t\tvalid: false\n\t\t};\n\t},\n\n\tcomponentDidMount () {\n\t\tthis.watch(window, 'online', this.updateOnlineStatus);\n\t\tthis.watch(window, 'offline', this.updateOnlineStatus);\n\t\tdocument.addEventListener('online', this.onOnline, false);\n\t\tdocument.addEventListener('offline', this.onOffline, false);\n\t},\n\n\tonOnline () {\n\t\tthis.setState({\n\t\t\tonline: true,\n\t\t});\n\t},\n\n\tonOffline () {\n\t\tthis.setState({\n\t\t\tonline: false,\n\t\t});\n\t},\n\n\tupdateOnlineStatus (event) {\n\t\tthis.setState({\n\t\t\tonline: window.navigator.onLine\n\t\t});\n\t},\n\n\tenableScanner () {\n\t\tif (!window.cordova) return window.alert('Sorry, this is only available on mobile devices');\n\t\tthis.setState({ scanning: true });\n\t},\n\n\thandleScanner (err, ticketCode) {\n\t\tvar dataStore = this.context.dataStore;\n\t\tvar self = this;\n\n\t\tthis.setState({ scanning: false });\n\n\t\tif (!ticketCode || err) {\n\t\t\treturn console.error('Scanner Failed:', err);\n\t\t}\n\n\t\t// success\n\t\tthis.setState({\n\t\t\tloading: true\n\t\t}, function () {\n      self.props.onCodeEnter(ticketCode, (err) => {\n        self.setState({\n\t\t\t\t\tloading: false,\n\t\t\t\t\tvalid: !err\n\t\t\t\t}, function () {\n\t\t\t\t\t// success: show the success icon for 1 second then fade to the app\n\t\t\t\t\tif (self.state.valid === true) {\n\t\t\t\t\t\tsetTimeout(function () {\n\t\t\t\t\t\t\tself.transitionTo(self.props.nextScreen, {\n\t\t\t\t\t\t\t\ttransition: 'fade'\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}, 1000);\n\n\t\t\t\t\t// fail: return validity to neutral\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsetTimeout(function () {\n\t\t\t\t\t\t\tself.setState({ valid: null });\n\t\t\t\t\t\t}, 2000);\n\t\t\t\t\t}\n\t\t\t\t});\n      });\n    });\n\t},\n\n\trenderIcon (icon) {\n\t\tvar iconClassname = classnames('onboarding-scan__icon', {\n\t\t\t'ion-load-b': this.state.scanning,\n\t\t\t'is-loading': this.state.scanning || this.state.loading,\n\t\t\t'ion-ios-checkmark': this.state.valid,\n\t\t\t'is-valid': this.state.valid\n\t\t});\n\t\tvar element = (this.state.scanning || this.state.valid) ? (\n\t\t\t<span className={iconClassname} />\n\t\t) : (\n\t\t\t<span dangerouslySetInnerHTML={{__html: icon}} className=\"onboarding-scan__image\" />\n\t\t);\n\n\t\treturn element;\n\t},\n\n\trenderScanButton () {\n\t\tvar content = this.state.online ? (\n\t\t\t<div key=\"online\" className=\"onboarding-scan\">\n\t\t\t\t<Tappable loading={this.state.scanning} onTap={this.enableScanner} className=\"onboarding-scan__button\">\n\t\t\t\t\t{this.renderIcon(icons.qr)}\n\t\t\t\t</Tappable>\n\t\t\t\t<div className=\"onboarding-scan__text\">Scan the QR code in your email</div>\n\t\t\t</div>\n\t\t) : (\n\t\t\t<div key=\"offline\" className=\"onboarding-scan\">\n\t\t\t\t<div className=\"onboarding-scan__button\">\n\t\t\t\t\t<div className=\"onboarding-scan__icon ion-wifi\" />\n\t\t\t\t</div>\n\t\t\t\t<div className=\"onboarding-scan__text\">Please find a data connection to register</div>\n\t\t\t</div>\n\t\t);\n\n\t\treturn (\n\t\t\t<Transition transitionName=\"animation-fade\" className=\"onboarding-scan-wrapper\">\n\t\t\t\t{content}\n\t\t\t</Transition>\n\t\t);\n\t},\n\n\trenderEnterCode () {\n\t\treturn this.state.online ? <Link to={\"app:onboarding-\" + this.props.id + \"-enter-code\"} transition=\"fade\" className=\"onboarding-footer__button onboarding-footer__button--primary\">Enter Code</Link> : null;\n\t},\n\n\trenderResendEmail () {\n\t\treturn (this.state.online && this.state.showResendEmail) ? <Link to={\"app:onboarding-\" + this.props.id + \"-resend-email\"} transition=\"fade\" className=\"onboarding-footer__button\">Resend Code</Link> : null;\n\t},\n\n\trenderScanner () {\n\t\treturn this.state.scanning ? <Scanner action={this.handleScanner} /> : null;\n\t},\n\n\trender () {\n\t\treturn (\n\t\t\t<Container direction=\"column\" className=\"onboarding-container\">\n\t\t\t\t<OnboardingHeader />\n\t\t\t\t<h2 className=\"onboarding-heading-1\">{this.props.title}</h2>\n\t\t\t\t<Container justify align=\"center\" direction=\"column\" className=\"onboarding-body\">\n\t\t\t\t\t{this.renderScanButton()}\n\t\t\t\t</Container>\n\t\t\t\t<Container justify align=\"center\" direction=\"row\" className=\"onboarding-footer\">\n\t\t\t\t\t{this.renderResendEmail()}\n\t\t\t\t\t<Link to={this.props.nextScreen} transition={this.props.transition || \"fade\"} className=\"onboarding-footer__button\">Skip</Link>\n\t\t\t\t\t{this.renderEnterCode()}\n\t\t\t\t</Container>\n\t\t\t\t{this.renderScanner()}\n\t\t\t</Container>\n\t\t);\n\t}\n});\n\nexport default OnboardingView;\n"
  },
  {
    "path": "src/js/components/Onboarding/resend-email.js",
    "content": "var Container = require('react-container');\nvar OnboardingHeader = require('../../components/OnboardingHeader');\nvar React = require('react');\nvar { Link, Transitions } = require('../../touchstone');\n\nvar classnames = require('classnames');\n\nmodule.exports = React.createClass({\n\tmixins: [Transitions],\n\tcontextTypes: { dataStore: React.PropTypes.object.isRequired },\n  propTypes: {\n    id: React.PropTypes.string.isRequired,\n    nextScreen: React.PropTypes.string.isRequired\n  },\n\n\tgetInitialState () {\n\t\treturn {\n\t\t\tfeedback: false,\n\t\t\tinput: '',\n\t\t\tloading: false,\n\t\t\tonline: window.navigator.onLine\n\t\t};\n\t},\n\n\tcomponentDidMount () {\n\t\tvar input = this.refs.input.getDOMNode();\n\n\t\t// wait until the view transition ends then focus the field\n\t\tsetTimeout(function () {\n\t\t\tinput.focus();\n\t\t}, 320);\n\t},\n\n\thandleFormInput (e) {\n\t\tthis.setState({\n\t\t\tinput: e.target.value\n\t\t});\n\t},\n\n\thandleFormSubmission (e) {\n\t\te.preventDefault();\n\t\tvar self = this;\n\t\tvar dataStore = this.context.dataStore\n\n\t\tthis.setState({\n\t\t\tloading: true\n\t\t}, function () {\n\t\t\tdataStore.resend(this.state.input, function (err) {\n\t\t\t\tself.setState({\n\t\t\t\t\tloading: false,\n\t\t\t\t\tvalid: !err\n\t\t\t\t}, function () {\n\t\t\t\t\t// success: show the success icon for 1 second then fade to the app\n\t\t\t\t\tif (self.state.valid) {\n\t\t\t\t\t\tsetTimeout(function () {\n\t\t\t\t\t\t\treturn self.transitionTo(self.props.nextScreen, { transition: 'fade' });\n\t\t\t\t\t\t}, 1000);\n\n\t\t\t\t\t// fail: return validity to neutral\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsetTimeout(function () {\n\t\t\t\t\t\t\treturn self.setState({ valid: null });\n\t\t\t\t\t\t}, 2000);\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t})\n\t\t});\n\t},\n\n\trender () {\n\t\tvar submitButtonClass = classnames('onboarding-form__button', {\n\t\t\t'is-loading': this.state.loading,\n\t\t\t'is-valid': this.state.valid === true,\n\t\t\t'is-invalid': this.state.valid === false\n\t\t});\n\n\t\treturn (\n\t\t\t<Container direction=\"column\" className=\"onboarding-container\">\n\t\t\t\t<OnboardingHeader />\n\t\t\t\t<Container justify align=\"center\" direction=\"column\">\n\t\t\t\t\t<form onSubmit={this.handleFormSubmission} className=\"onboarding-form\" noValidate>\n\t\t\t\t\t\t<div className=\"onboarding-form__section onboarding-form__section--field\">\n\t\t\t\t\t\t\t<input type=\"email\" ref=\"input\" onChange={this.handleFormInput} value={this.state.input} placeholder=\"Enter Email\" className=\"onboarding-form__input\" disabled={this.state.feedback === 'sent'} />\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div className=\"onboarding-form__section onboarding-form__section--button\">\n\t\t\t\t\t\t\t<button type=\"submit\" className={submitButtonClass} />\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</form>\n\t\t\t\t</Container>\n\t\t\t\t<Container justify align=\"center\" direction=\"row\" className=\"onboarding-footer\">\n\t\t\t\t\t<Link to={\"app:onboarding-\" + this.props.id} transition=\"show-from-left\" className=\"onboarding-footer__button\">Back</Link>\n\t\t\t\t\t<Link to={this.props.nextScreen} transition={this.props.transition || \"fade\"} className=\"onboarding-footer__button\">Skip</Link>\n\t\t\t\t\t<Link to={\"app:onboarding-\" + this.props.id + \"-enter-code\"} transition=\"show-from-left\" className=\"onboarding-footer__button\">Enter Code</Link>\n\t\t\t\t</Container>\n\t\t\t</Container>\n\t\t);\n\t}\n});\n"
  },
  {
    "path": "src/js/components/OnboardingHeader.js",
    "content": "var Container = require('react-container');\nvar React = require('react');\n\nmodule.exports = React.createClass({\n\tgetInitialState () {\n\t\treturn {};\n\t},\n\trender () {\n\t\treturn (\n\t\t\t<Container align=\"center\" justify=\"center\" direction=\"column\" className=\"onboarding-header\">\n\t\t\t\t<img src=\"./img/logo-mark.svg\" className=\"onboarding-logo\" />\n\t\t\t\t<div className=\"onboarding-heading onboarding-heading-1\">React Europe 2016</div>\n\t\t\t\t<div className=\"onboarding-heading onboarding-heading-2\">June 02 & 03 — Paris, France</div>\n\t\t\t</Container>\n\t\t);\n\t}\n});\n"
  },
  {
    "path": "src/js/components/PeopleItem.js",
    "content": "var React = require('react');\nvar { Link } = require('../touchstone');\n\nvar classnames = require('classnames');\n\nmodule.exports = React.createClass({\n\tdisplayName: 'PeopleItem',\n\n\trender () {\n\t\tvar person = this.props.person\n\t\tvar bio = person.bio\n\t\tif (bio.length > 50) bio = bio.slice(0, 50) + '...'\n\n\t\t// FIXME: @jossmac\n\t\tvar starClassName = classnames({\n\t\t\t'PersonItem__star': !this.props.person.starred,\n\t\t\t'PersonItem__starred': this.props.person.starred\n\t\t})\n\n\t\treturn (\n\t\t\t<Link to=\"main:person\" transition=\"show-from-right\" viewProps={{ person: person, previousView: this.props.previousView }} className=\"ListItem Person\" component=\"div\">\n\t\t\t\t<img src={person.picture || person.avatar_url || person.pic_url} className=\"ListItem__avatar PersonItem__avatar\" />\n\t\t\t\t<div className=\"ListItem__content\">\n\t\t\t\t\t<div className=\"ListItem__heading\">\n\t\t\t\t\t\t{person.name}\n\t\t\t\t\t\t<span className={starClassName} />\n\t\t\t\t\t</div>\n\t\t\t\t\t<div className=\"ListItem__text\">{bio}</div>\n\t\t\t\t</div>\n\t\t\t\t<div className=\"ListItem__chevron\" />\n\t\t\t</Link>\n\t\t);\n\t}\n});\n"
  },
  {
    "path": "src/js/components/PeopleList.js",
    "content": "var React = require('react');\nvar blacklist = require('blacklist');\n\nvar ListHeader = require('../components/ListHeader');\nvar PeopleItem = require('./PeopleItem');\n\nmodule.exports = React.createClass({\n\tdisplayName: 'PeopleList',\n\tpropTypes: {\n\t\theading: React.PropTypes.string,\n\t\theadingIsSticky: React.PropTypes.bool,\n\t\tpeople: React.PropTypes.array,\n\t\tpreviousView: React.PropTypes.string\n\t},\n\n\tgetDefaultProps () {\n\t\treturn {\n\t\t\tpreviousView: 'people'\n\t\t};\n\t},\n\n\trender () {\n\t\tif (!this.props.people.length) return null;\n\n\t\tvar people = this.props.people;\n\t\tvar previousView = this.props.previousView;\n\t\tvar items = people.map(function (person, i) {\n\t\t\treturn <PeopleItem key={'person_' + i} person={person} previousView={previousView} />;\n\t\t});\n\n\t\tvar heading = this.props.heading ? <ListHeader sticky={this.props.headingIsSticky}>{this.props.heading}</ListHeader> : null;\n\t\tvar props = blacklist(this.props, 'heading', 'headingIsSticky', 'people');\n\n\t\treturn (\n\t\t\t<div {...props}>\n\t\t\t\t{heading}\n\t\t\t\t{items}\n\t\t\t</div>\n\t\t);\n\t}\n});\n"
  },
  {
    "path": "src/js/components/Scanner.js",
    "content": "var React = require(\"react\")\n\nmodule.exports = React.createClass({\n\tdisplayName: \"Scanner\",\n\tpropTypes: {\n\t\taction: React.PropTypes.func\n\t},\n\tgetInitialState () {\n\t\treturn {}\n\t},\n\tcomponentDidMount () {\n\t\tvar action = this.props.action\n\n\t\tif (!window.cordova) {\n\t\t\treturn action(new Error(\"QR code scanner is not available\"))\n\t\t}\n\n\t\twindow.cordova.plugins.barcodeScanner.scan(\n\t\t\tfunction(result) {\n\t\t\t\tif (result.cancelled) return action(undefined)\n\n\t\t\t\t// vibrate for 200ms\n\t\t\t\twindow.navigator.vibrate(200)\n\n\t\t\t\tsetTimeout(function() {\n\t\t\t\t\taction(undefined, result.text)\n\t\t\t\t}, 200)\n\t\t\t},\n\t\t\tfunction(err) {\n\t\t\t\tsetTimeout(function() {\n\t\t\t\t\taction(err)\n\t\t\t\t}, 200)\n\t\t\t}\n\t\t)\n\t},\n\trender () {\n\t\treturn (\n\t\t\t<div></div>\n\t\t)\n\t}\n})\n"
  },
  {
    "path": "src/js/components/Spinner.js",
    "content": "var React = require('react');\nvar classNames = require('classnames');\n\nmodule.exports = React.createClass({\n\tdisplayName: 'Spinner',\n\n\tpropTypes: {\n\t\tclassName: React.PropTypes.string,\n\t\ttext: React.PropTypes.string\n\t},\n\tgetDefaultProps () {\n\t\treturn {\n\t\t\ttext: 'Loading...'\n\t\t}\n\t},\n\trender () {\n\t\tvar componentClassName = classNames({\n\t\t\t'view-feedback': true,\n\t\t\t'is-static': this.props.static\n\t\t}, this.props.className);\n\n\t\treturn (\n\t\t\t<div className={componentClassName}>\n\t\t\t\t<div className=\"view-feedback-icon view-feedback-loading-icon\" />\n\t\t\t\t<div className=\"view-feedback-text\">{this.props.text}</div>\n\t\t\t</div>\n\t\t);\n\n\t}\n\n});\n"
  },
  {
    "path": "src/js/config.js",
    "content": "module.exports = {};\n"
  },
  {
    "path": "src/js/icons/index.js",
    "content": "module.exports = {\n\tqr: require('./qr')\n};"
  },
  {
    "path": "src/js/icons/qr.js",
    "content": "module.exports = '<?xml version=\"1.0\" encoding=\"utf-8\"?>' +\n'<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">' +\n'<svg version=\"1.1\" id=\"Layer_1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"32\" height=\"32\" x=\"0px\" y=\"0px\" viewBox=\"467.1 267.1 32 32\" enable-background=\"new 467.1 267.1 32 32\" xml:space=\"preserve\">' +\n\t'<path d=\"M476.1,280.8L476.1,280.8C476.1,280.8,476.1,280.8,476.1,280.8C476.1,280.8,476.1,280.8,476.1,280.8z M486.9,283.7 c0-1,0-2,0-2.9c0.5,0,1,0,1.5,0c0-0.5,0-1,0-1.5c-1,0-2.1,0-3,0c0,1,0,2,0,3c-1,0-2,0-3,0c0-1.5,0-3.1,0-4.6c-0.5,0-1,0-1.5,0 c0,0.5,0,1,0,1.6c-1.6,0-3.1,0-4.6,0c0,0.5,0,1,0,1.5c1,0,2,0,3.1,0c0,0.5,0,1,0,1.6c0.5,0,1,0,1.5,0c0,0.5,0,0.9,0,1.4 c-0.5,0-1,0-1.5,0c0,2.1,0,4.1,0,6.2c0.5,0,1,0,1.5,0c0-1,0-2,0-3.1c0.6,0,1,0,1.6,0c0-0.5,0-1,0-1.6c0.5,0,0.9,0,1.4,0 c0-0.5,0-1,0-1.5c0.5,0,1,0,1.6,0c0,1,0,2,0,3c0.5,0,1,0,1.6,0c0-0.5,0-1,0-1.5c0.5,0,1,0,1.5,0c0-0.5,0-1,0-1.6 C487.8,283.7,487.3,283.7,486.9,283.7z M485.3,279.2L485.3,279.2L485.3,279.2L485.3,279.2L485.3,279.2z M488.4,285.3L488.4,285.3 L488.4,285.3C488.4,285.3,488.4,285.3,488.4,285.3z M499.1,267.1c0,3.5,0,7,0,10.5c-3.5,0-7.1,0-10.6,0c0-3.5,0-7,0-10.5 C491.9,267.1,495.5,267.1,499.1,267.1z M497.5,268.5c-2.5,0-5,0-7.5,0c0,2.6,0,5.1,0,7.5c2.6,0,5.1,0,7.5,0 C497.5,273.5,497.5,271,497.5,268.5z M467.1,288.4c3.5,0,7,0,10.5,0c0,3.5,0,7.1,0,10.7c-3.5,0-7,0-10.5,0 C467.1,295.5,467.1,291.9,467.1,288.4z M468.5,297.5c2.6,0,5.1,0,7.6,0c0-2.5,0-5,0-7.5c-2.5,0-5,0-7.6,0 C468.5,292.5,468.5,295,468.5,297.5z M477.6,277.6c-3.5,0-7,0-10.5,0c0-3.5,0-7,0-10.5c3.5,0,7,0,10.5,0 C477.6,270.6,477.6,274.1,477.6,277.6z M476.1,268.5c-2.5,0-5,0-7.5,0c0,2.6,0,5.1,0,7.5c2.6,0,5.1,0,7.5,0 C476.1,273.5,476.1,271,476.1,268.5z M480.7,291.3L480.7,291.3C480.8,291.3,480.7,291.3,480.7,291.3L480.7,291.3z M479.3,299.1 c1,0,2,0,3,0c0-0.5,0-1,0-1.5l0,0c0,0,0,0,0,0c-0.5,0-0.9,0-1.5,0c0-0.5,0-1,0-1.6c0.5,0,1,0,1.5,0c0,0,0,0,0,0c0,0,0,0,0,0 c0-0.5,0-1,0-1.5c0.5,0,0.9,0,1.4,0c0,0.5,0,0.9,0,1.5c-0.5,0-0.9,0-1.4,0c0,0,0,0,0,0c0,0,0,0,0,0c0,0.5,0,1,0,1.6l0,0 c0,0,0,0,0,0c1,0,2,0,3,0c0,0.5,0,1,0,1.5c1.1,0,2.1,0,3,0c0-1,0-2,0-3.1c-0.5,0-1,0-1.6,0c0-1.6,0-3.1,0-4.6c-0.5,0-1,0-1.6,0 c0,0.5,0,1,0,1.5c-1.6,0-3,0-4.6,0c0-0.5,0-1,0-1.5c-0.5,0-1,0-1.5,0C479.3,294,479.3,296.5,479.3,299.1z M474.7,279.2 c-2.6,0-5.1,0-7.6,0c0,1,0,2,0,3c0.5,0,0.9,0,1.4,0c0-0.5,0-1,0-1.5c1.6,0,3.1,0,4.7,0c0,0.5,0,1,0,1.5c0.5,0,1,0,1.5,0 c0,0.5,0,0.9,0,1.4c1,0,2,0,2.9,0c0-0.5,0-0.9,0-1.4c-0.5,0-1,0-1.5,0c0-0.5,0-1,0-1.5c-0.5,0-0.9,0-1.5,0 C474.7,280.2,474.7,279.7,474.7,279.2z M476.1,280.8C476.1,280.8,476.1,280.8,476.1,280.8C476.1,280.8,476.1,280.8,476.1,280.8 L476.1,280.8z M485.3,270c0.5,0,1,0,1.5,0c0-0.5,0-1,0-1.5c-1,0-2,0-3.1,0c0,1,0,2,0,3c-1.5,0-2.9,0-4.5,0c0,0.6,0,1,0,1.5 c2,0,4,0,6,0C485.3,272,485.3,271.1,485.3,270z M496,286.9c-0.5,0-1,0-1.5,0c0,1,0,2,0,3.1c-0.5,0-1,0-1.5,0c0,0.5,0,0.9,0,1.4 c0.5,0,1,0,1.5,0c0,0.5,0,1,0,1.5c0.5,0,1,0,1.5,0c0-0.5,0-1,0-1.6c0.6,0,1,0,1.5,0c0-1,0-2,0-2.9c-0.5,0-1,0-1.6,0 C496,287.8,496,287.3,496,286.9z M492.9,294.4C492.9,294.4,492.9,294.4,492.9,294.4C492.9,294.4,493,294.4,492.9,294.4L492.9,294.4 z M491.3,292.9c0-0.5,0-1,0-1.5c-1,0-2,0-2.9,0c0,0.5,0,1,0,1.5c0.5,0,1,0,1.6,0c0,0.5,0,1,0,1.5c1,0,2,0,2.9,0c0-0.5,0-1,0-1.6 C492.3,292.9,491.9,292.9,491.3,292.9z M492.9,283.8c0.5,0,1,0,1.6,0c0,0.5,0,1,0,1.5c0.5,0,1,0,1.6,0c0-0.5,0-1,0-1.6 c0.5,0,1,0,1.5,0c0-0.5,0-0.9,0-1.4c-1.5,0-3.1,0-4.6,0C492.9,282.8,492.9,283.2,492.9,283.8z M497.5,282.3L497.5,282.3 C497.5,282.3,497.5,282.3,497.5,282.3C497.5,282.3,497.5,282.3,497.5,282.3C497.5,282.3,497.5,282.3,497.5,282.3L497.5,282.3z  M492.9,282.3C492.9,282.3,492.9,282.3,492.9,282.3C492.9,282.3,492.9,282.3,492.9,282.3L492.9,282.3z M470,285.3 C470,285.3,470,285.3,470,285.3C470,285.3,470,285.3,470,285.3L470,285.3z M467.1,283.8c0,0.5,0,1,0,1.5c1,0,2,0,2.9,0 c0-0.5,0-1,0-1.6c0.6,0,1,0,1.5,0c0-0.5,0-0.9,0-1.4c-1,0-2.1,0-3,0c0,0.5,0,0.9,0,1.4C467.9,283.8,467.5,283.8,467.1,283.8z  M468.5,282.3L468.5,282.3C468.5,282.3,468.5,282.3,468.5,282.3C468.5,282.3,468.5,282.3,468.5,282.3 C468.5,282.3,468.5,282.3,468.5,282.3z M492.9,282.3L492.9,282.3C492.9,282.3,492.9,282.3,492.9,282.3L492.9,282.3z M491.3,280.8 c0-0.6,0-1,0-1.5c-0.5,0-0.9,0-1.4,0c0,1.5,0,3,0,4.5c0.5,0,0.9,0,1.4,0c0-0.5,0-0.9,0-1.4c0.5,0,1,0,1.5,0c0-0.5,0-1,0-1.5 C492.4,280.8,491.9,280.8,491.3,280.8z M470,285.3C470,285.3,470,285.3,470,285.3C470,285.3,470,285.3,470,285.3L470,285.3z  M474.6,286.8c0-0.5,0-1,0-1.5c-1.6,0-3.1,0-4.6,0c0,0.5,0,1,0,1.5C471.6,286.8,473.1,286.8,474.6,286.8z M496,294.4L496,294.4 C496,294.4,496,294.4,496,294.4C496,294.4,496,294.4,496,294.4C496,294.4,496,294.4,496,294.4L496,294.4z M492.9,294.4L492.9,294.4 C493,294.4,493,294.4,492.9,294.4C493,294.4,492.9,294.4,492.9,294.4z M493,296c0.5,0,1,0,1.6,0c0,0.5,0,1,0,1.5c0.5,0,1,0,1.5,0 c0-1,0-2.1,0-3.1c-1,0-2,0-3,0C493,294.9,493,295.5,493,296z M492.9,288.4c0-1,0-2,0-3c-0.5,0-1,0-1.6,0c0,0.5,0,1,0,1.6 c-0.5,0-0.9,0-1.4,0c0,0.5,0,1,0,1.5C491,288.4,491.9,288.4,492.9,288.4z M489.9,286.9L489.9,286.9 C489.9,286.9,489.9,286.8,489.9,286.9C489.9,286.8,489.9,286.8,489.9,286.9C489.9,286.8,489.9,286.9,489.9,286.9L489.9,286.9z  M485.3,277.6c0.5,0,1,0,1.5,0c0-1,0-2,0-2.9c-1,0-2,0-3,0c0,0.5,0,0.9,0,1.4c0.5,0,1,0,1.6,0C485.3,276.6,485.3,277.1,485.3,277.6 z M483.7,276.1L483.7,276.1L483.7,276.1L483.7,276.1L483.7,276.1z M482.2,268.5c-1,0-2,0-3,0c0,0.5,0,1,0,1.5c1,0,2,0,3,0 C482.2,269.5,482.2,269,482.2,268.5z M485.3,289.9c1,0,2,0,3,0c0-0.5,0-1,0-1.5c-1,0-2,0-3,0C485.3,288.9,485.3,289.4,485.3,289.9z  M479.2,274.7c0,1,0,2,0,2.9c0.5,0,1,0,1.5,0c0-1,0-2,0-2.9C480.2,274.7,479.7,274.7,479.2,274.7z M480.8,277.6L480.8,277.6 L480.8,277.6L480.8,277.6L480.8,277.6z M490,299.1c0.5,0,0.9,0,1.3,0c0-1.1,0-2.1,0-3c-0.5,0-0.9,0-1.3,0 C490,297.1,490,298.1,490,299.1z M496,297.6C496,297.5,496,297.5,496,297.6C496,297.5,496,297.5,496,297.6 C496,297.5,496,297.5,496,297.6C496,297.6,496,297.6,496,297.6z M497.5,299.1c0-0.5,0-1,0-1.5c-0.5,0-1,0-1.5,0c0,0.5,0,1,0,1.5 C496.6,299.1,497,299.1,497.5,299.1z M496,292.9L496,292.9C496,292.9,496,292.9,496,292.9C496,292.9,496,292.9,496,292.9 C496,292.9,496,292.9,496,292.9z M497.5,294.4c0-0.5,0-1,0-1.5c-0.5,0-1,0-1.5,0c0,0.5,0,1,0,1.5 C496.5,294.4,497,294.4,497.5,294.4z M483.7,279.2c0.5,0,1,0,1.5,0c0-0.5,0-1,0-1.5c-0.5,0-1,0-1.5,0 C483.7,278.1,483.7,278.6,483.7,279.2z M485.3,277.6L485.3,277.6L485.3,277.6L485.3,277.6L485.3,277.6z M497.6,286.8 c0.5,0,1,0,1.5,0c0-0.5,0-1,0-1.5c-0.5,0-1,0-1.5,0C497.6,285.9,497.6,286.3,497.6,286.8z M489.9,286.8c0-0.5,0-1,0-1.6 c-0.5,0-1,0-1.5,0c0,0.5,0,1,0,1.6C488.9,286.8,489.4,286.8,489.9,286.8z M488.4,285.3C488.4,285.3,488.4,285.3,488.4,285.3 C488.4,285.3,488.4,285.3,488.4,285.3C488.4,285.3,488.4,285.3,488.4,285.3z M476.1,286.8c0.5,0,1,0,1.5,0c0-0.5,0-1,0-1.5 c-0.5,0-1,0-1.5,0C476.1,285.8,476.1,286.3,476.1,286.8z M492.9,280.8L492.9,280.8C492.9,280.8,492.9,280.8,492.9,280.8 L492.9,280.8L492.9,280.8z M494.4,279.2c-0.5,0-1,0-1.5,0c0,0.5,0,1,0,1.5c0.5,0,1,0,1.5,0C494.4,280.2,494.4,279.7,494.4,279.2z  M496.1,279.2c0,0.5,0,1,0,1.5c0.5,0,1,0,1.5,0c0-0.5,0-1,0-1.5C497,279.2,496.5,279.2,496.1,279.2z M497.5,280.8L497.5,280.8 L497.5,280.8C497.6,280.8,497.6,280.8,497.5,280.8L497.5,280.8z M499.1,280.8c-0.5,0-1,0-1.5,0c0,0.5,0,1,0,1.5c0.5,0,1,0,1.5,0 C499.1,281.7,499.1,281.3,499.1,280.8z M482.2,291.3c0-0.5,0-0.9,0-1.4c-0.5,0-1,0-1.5,0c0,0.5,0,0.9,0,1.4 C481.3,291.3,481.8,291.3,482.2,291.3z M480.8,289.9L480.8,289.9C480.8,289.9,480.8,289.9,480.8,289.9L480.8,289.9L480.8,289.9z  M480.8,291.3L480.8,291.3C480.7,291.3,480.7,291.3,480.8,291.3C480.7,291.3,480.8,291.3,480.8,291.3z M483.7,276.1 c-0.5,0-0.9,0-1.4,0c0,0.6,0,1,0,1.5c0.5,0,0.9,0,1.4,0C483.7,277.1,483.7,276.6,483.7,276.1z M482.3,277.6L482.3,277.6 L482.3,277.6L482.3,277.6L482.3,277.6z M483.7,277.6L483.7,277.6L483.7,277.6L483.7,277.6L483.7,277.6z M496,270 c-1.6,0-3.1,0-4.6,0c0,1.6,0,3.1,0,4.6c1.6,0,3.1,0,4.6,0C496,273.1,496,271.6,496,270z M470,296c1.5,0,3,0,4.6,0 c0-1.6,0-3.1,0-4.6c-1.6,0-3.1,0-4.6,0C470,293,470,294.5,470,296z M474.6,270.1c-1.6,0-3.1,0-4.6,0c0,1.6,0,3,0,4.6 c1.5,0,3,0,4.6,0C474.6,273.1,474.6,271.6,474.6,270.1z\"/>' +\n'</svg>';"
  },
  {
    "path": "src/js/lib/device.js",
    "content": "var map = {\n\t'Android': /Android/,\n\t'iOS': /(iPad|iPhone)/\n}\n\nvar userAgent = window.navigator.userAgent\nvar deviceType = 'Browser'\n\nfor (var key in map) {\n\tif (map[key].test(userAgent)) {\n\t\tdeviceType = key\n\t}\n}\n\nmodule.exports = {\n\tplatform: deviceType\n}\n"
  },
  {
    "path": "src/js/mixins/social.js",
    "content": "var React = require('react');\nvar Tappable = require('react-tappable');\n\nvar device = require('../lib/device')\n\nmodule.exports = {\n\topenFacebook (handle, pageId) {\n\t\tif (!window.plugins) return window.alert('Sorry, this functionality requires a mobile device.')\n\t\tpageId = pageId || 1541044122821917; // ReactEurope default\n\n\t\tvar scheme = {\n\t\t\t'Android': 'fb://',\n\t\t\t'iOS': 'com.facebook.katana'\n\t\t}[device.platform]\n\n\t\twindow.appAvailability.check(\n\t\t\tscheme,\n\t\t\tfunction () {\n\t\t\t\twindow.location.href = 'fb://profile/' + pageId;\n\t\t\t},\n\t\t\tfunction () {\n\t\t\t\twindow.open('https://www.facebook.com/' + handle, '_blank', 'toolbar=yes,location=no,transitionstyle=coververtical');\n\t\t\t}\n\t\t);\n\t},\n\n\topenGithub (handle) {\n\t\twindow.open('https://www.github.com/' + handle, '_blank', 'toolbar=yes,location=no,transitionstyle=coververtical');\n\t},\n\n\topenTwitter (handle) {\n\t\tif (!window.plugins) return window.alert('Sorry, this functionality requires a mobile device.');\n\n\t\tvar scheme = {\n\t\t\t'Android': 'com.twitter.android',\n\t\t\t'iOS': 'twitter://'\n\t\t}[device.platform]\n\n\t\twindow.appAvailability.check(\n\t\t\tscheme,\n\t\t\tfunction () {\n\t\t\t\twindow.location.href = 'twitter://user?screen_name=' + handle;\n\t\t\t},\n\t\t\tfunction () {\n\t\t\t\twindow.open('https://twitter.com/' + handle, '_blank', 'toolbar=yes,location=no,transitionstyle=coververtical');\n\t\t\t}\n\t\t);\n\t},\n\n\trenderTwitter (handle) {\n\t\treturn (\n\t\t\t<Tappable onTap={this.openTwitter.bind(this, handle)} className=\"PersonDetails__profile\">\n\t\t\t\t<span className=\"PersonDetails__profile__icon ion-social-twitter\" />\n\t\t\t\t@{handle}\n\t\t\t</Tappable>\n\t\t);\n\t},\n\n\trenderGithub (handle) {\n\t\treturn (\n\t\t\t<Tappable onTap={this.openGithub.bind(this, handle)} className=\"PersonDetails__profile\">\n\t\t\t\t<span className=\"PersonDetails__profile__icon ion-social-github\" />\n\t\t\t\t{handle}\n\t\t\t</Tappable>\n\t\t);\n\t}\n}\n"
  },
  {
    "path": "src/js/stores/DataStore.js",
    "content": "var EventEmitter = require('events').EventEmitter;\n\nvar async = require('async');\nvar defaultData = require('./default');\nvar secret = require('./secret');\nvar defaults = require('defaults');\nvar httpify = require('httpify');\nvar assign = require('object-assign');\n\nfunction DataStore () {\n\tEventEmitter.call(this);\n\n\t// assign localStorage to our internal cache\n\tvar storage = this.cache = {};\n\tfor (var key in window.localStorage) {\n\t\tstorage[key] = JSON.parse(window.localStorage[key]);\n\t}\n\n\t// default our internal cache to pre-loaded data\n\tdefaults(storage, defaultData);\n  this.cache.settings = {\n\t\taboutLogo: './img/thinkmill-logo_white.svg'\n\t};\n  this.cache.starred = {};\n\tthis.cache.speakers = [];\n\tthis.cache.sponsors = [];\n\tthis.cache.organisers = [];\n\tthis.__preprocess(storage);\n\tthis.cache = Object.assign(this.cache, storage);\n\n// \tTODO maybe window.addEventListener('online', this.updateOnlineStatus);\n// \tTODO maybe window.addEventListener('offline', this.updateOnlineStatus);\n\n\t// generic API queue\n\tvar self = this;\n\tvar url = 'http://api.eventlama.com';\n\tthis.apiQueue = async.queue(function (opts, callback) {\n\t\tvar { authToken } = storage;\n\t\tvar { endpoint, data, method } = opts;\n\n\t\thttpify({\n\t\t\tmethod: method || 'POST',\n\t\t\turl: url + endpoint,\n\t\t\theaders: { 'Content-Type': 'application/json' },\n\t\t\ttimeout: 20000\n\t\t}, (err, res) => {\n\t\t\tif (err) return callback(err);\n\t\t\tif (res.statusCode !== 200) return callback(new Error('Error ' + res.statusCode));\n\n\t\t\tvar body = res.body || {};\n\n\t\t\tvar data = body || {};\n\t\t\tself.__preprocess(data);\n\n\t\t\t// emit all the events\n\t\t\tfor (var key in data) {\n\t\t\t\tvar updated = data[key];\n\n\t\t\t\tstorage[key] = updated;\n\t\t\t\twindow.localStorage[key] = JSON.stringify(updated);\n\n\t\t\t\tself.emit('update-' + key, updated);\n\t\t\t}\n\t\t\tself.emit('update', data);\n\n\t\t\tcallback(null, data);\n\t\t});\n\t}, 1)\n\n\tvar context = this;\n\tthis.apiQueue.push({\n\t\tmethod: 'GET',\n\t\tendpoint: '/checkin/events/28/checkinlists/' + secret.main.id + '/' + secret.main.token\n\t}, function (err, data) {\n\t\t// TODO Proper error handling\n\t\tif (!err) {\n\t\t\tcontext.cache.people = data.attendees;\n\t\t}\n\t});\n\n\t// every 30s, attempt synchronize, queues incase it takes a while\n\tself.synchronize();\n\tsetInterval(function () {\n\t\tself.synchronize();\n\t}, 30000);\n}\n\n// mutates data\nDataStore.prototype.__preprocess = function (data) {\n\tif (data.attendees) {\n\t\tvar starred = this.cache.starred;\n\t\tvar talks = data.Proposals || this.cache.Proposals;\n\t\tdata.attendees.forEach(person => {\n      // Set properties of attendees\n\t\t\tperson.bio = person.bio || '';\n\t\t\tperson.github = person.github || '';\n\t\t\tperson.picture = person.picture || '';\n\t\t\tperson.starred = starred[person.id];\n\t\t\tperson.twitter = person.twitter || '';\n\t\t\tperson.name = person.purchase.attendee_first_name + ' ' + person.purchase.attendee_last_name;\n\n      // Filter for talks associated with a person\n\t\t\tperson.talks = person.talks || talks\n\t\t\t\t.filter(talk => {\n\t\t\t\t\tif (talk.speakers) {\n\t\t\t\t\t\tvar isSpeaker = false;\n            // Map over the speakers of a talk\n\t\t\t\t\t\ttalk.speakers.map((speaker) => {\n              // If the email of the speaker is the same as the attendee email, they're giving this talk!\n\t\t\t\t\t\t\tif (speaker.email === person.purchase.attendee_email) {\n\t\t\t\t\t\t\t\tisSpeaker = true;\n\t\t\t\t\t\t\t\tperson.bio = speaker.bio;\n\t\t\t\t\t\t\t\tperson.twitter = speaker.twitter;\n\t\t\t\t\t\t\t\tperson.url = speaker.url;\n\t\t\t\t\t\t\t\tperson.github = speaker.github;\n\t\t\t\t\t\t\t\tperson.picture = speaker.avatar_url;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn isSpeaker;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t});\n\n\t\tthis.cache.people = data.attendees;\n\t}\n\n\tif (data.Proposals && this.cache.speakers.length === 0) {\n\t\tvar feedback = this.cache.feedback;\n\t\tvar speakers = this.cache.speakers;\n    var talks = this.cache.Proposals;\n\t\tif (!feedback) {\n\t\t\tfeedback = this.cache.feedback = {};\n\t\t}\n\n\t\tdata.Proposals.forEach(talk => {\n\t\t\ttalk.endTime = talk.start_date + talk.length;\n\t\t\tif (!feedback[talk.id]) {\n\t\t\t\tfeedback[talk.id] = {};\n\t\t\t}\n\t\t\ttalk.feedback = feedback[talk.id];\n\t\t\tif (talk.speakers) {\n\t\t\t\ttalk.speakers.forEach(speaker => {\n          var duplicate = false;\n          this.cache.speakers.forEach((cachedSpeaker) => {\n            if (cachedSpeaker.email === speaker.email) {\n              duplicate = true;\n            }\n          });\n          if (!duplicate) {\n            speaker.talks = talks.filter(talk => {\n              var isSpeaker = false;\n              talk.speakers && talk.speakers.filter((talkSpeaker) => {\n                if (speaker.email === talkSpeaker.email) {\n                  isSpeaker = true;\n                }\n              });\n              return isSpeaker;\n            });\n            speakers.push(speaker);\n          }\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t}\n\n\tif (data.Organizer && this.cache.organisers.length === 0) {\n\t\tvar organisers = this.cache.organisers;\n\t\torganisers.push(data.Organizer);\n\t\tdata.Collaborators.forEach(function (collaborator) {\n\t\t\torganisers.push(collaborator);\n\t\t});\n\t\tthis.cache.organisers = organisers;\n\t}\n\n\tif (data.DiamondSponsors && this.cache.sponsors.length === 0) {\n\t\tvar sponsors = this.cache.sponsors;\n\t\tif (data.DiamondSponsors) {\n\t\t\tdata.DiamondSponsors.map(sponsor => {\n\t\t\t\tsponsor.tier = 'diamond';\n\t\t\t\tsponsors.push(sponsor);\n\t\t\t});\n\t\t}\n\t\tif (data.PlatinumSponsors) {\n\t\t\tdata.PlatinumSponsors.map(sponsor => {\n\t\t\t\tsponsor.tier = 'platinum';\n\t\t\t\tsponsors.push(sponsor);\n\t\t\t});\n\t\t}\n\t\tif (data.GoldSponsors) {\n\t\t\tdata.GoldSponsors.map(sponsor => {\n\t\t\t\tsponsor.tier = 'gold';\n\t\t\t\tsponsors.push(sponsor);\n\t\t\t});\n\t\t}\n\t\tif (data.BronzeSponsors) {\n\t\t\tdata.BronzeSponsors.map(sponsor => {\n\t\t\t\tsponsor.tier = 'bronze';\n\t\t\t\tsponsors.push(sponsor);\n\t\t\t});\n\t\t}\n\t\tif (data.BasicSponsors) {\n\t\t\tdata.BasicSponsors.map(sponsor => {\n\t\t\t\tsponsor.tier = 'basic';\n\t\t\t\tsponsors.push(sponsor);\n\t\t\t});\n\t\t}\n\t\tif (data.PartnersSponsors) {\n\t\t\tdata.PartnersSponsors.map(sponsor => {\n\t\t\t\tsponsor.tier = 'partner';\n\t\t\t\tsponsors.push(sponsor);\n\t\t\t});\n\t\t}\n\t\tthis.cache.sponsors = sponsors;\n\t}\n};\n\nObject.assign(DataStore.prototype, EventEmitter.prototype);\n\n// Synchronized, external API functions\nDataStore.prototype.activate = function (ticketCode, callback) {\n\tthis.cache.ticketCode = ticketCode;\n\tvar context = this;\n\n\tthis.apiQueue.push({\n\t\tmethod: 'GET',\n\t\tendpoint: '/checkin/events/28/checkinlists/' + secret.main.id + '/' + secret.main.token + '/attendee/' + ticketCode\n\t}, function (err, data) {\n\t\tif (err) return callback(err);\n\t\tcontext.cache.me = assign({}, context.cache.me, data);\n\t\t// Save answer to questions to user data\n\t\tfor (var i = 0; i < data.Questions.length; i++) {\n\t\t\tswitch (data.Questions[i].question) {\n\t\t\t\tcase \"A one line bio about you or what you do\":\n\t\t\t\t\tcontext.cache.me.bio = data.Questions[i].answer;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"Twitter\":\n\t\t\t\t\tcontext.cache.me.twitter = data.Questions[i].answer;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tcallback();\n\t});\n};\n\nDataStore.prototype.activateHackathon = function (hackathonTicketCode, callback) {\n\tvar context = this;\n\n\tthis.apiQueue.push({\n\t\tmethod: 'GET',\n\t\tendpoint: '/checkin/events/28/checkinlists/' + secret.hackathon.id + '/' + secret.hackathon.token + '/attendee/' + hackathonTicketCode\n\t}, function (err, data) {\n\t\tif (err) return callback(err);\n\t\tcontext.cache.me = context.cache.me || {};\n\t\tcontext.cache.me.hackathonTicketCode = hackathonTicketCode;\n\t\tcallback();\n\t});\n}\n\nDataStore.prototype.activateWorkshop = function (workshopTicketCode, callback) {\n\tvar context = this;\n\n\tthis.apiQueue.push({\n\t\tmethod: 'GET',\n\t\tendpoint: '/checkin/events/28/checkinlists/' + secret.workshop.id + '/' + secret.workshop.token + '/attendee/' + workshopTicketCode\n\t}, function (err, data) {\n\t\tif (err) return callback(err);\n\t\tcontext.cache.me = context.cache.me || {};\n\t\tcontext.cache.me.workshopTicketCode = workshopTicketCode;\n\t\tcallback();\n\t});\n}\n\nDataStore.prototype.editMe = function (newMe, callback) {\n\tthis.cache.me = newMe;\n\tthis.apiQueue.push({\n\t\tendpoint: '/me/update',\n\t\tdata: { me: newMe }\n\t}, callback || function () {});\n};\n\nDataStore.prototype.feedback = function (id, feedback, callback) {\n\tthis.cache.feedback[id] = feedback;\n\n\t// update feedback cache\n\tthis.cache.schedule.forEach(function (talk) {\n\t\tif (talk.id !== id) return;\n\n\t\ttalk.feedback = feedback;\n\t});\n\n\tthis.apiQueue.push({\n\t\tendpoint: '/me/feedback',\n\t\tdata: Object.assign({ id: id }, feedback)\n\t}, callback || function () {})\n};\n\nDataStore.prototype.resend = function (email, callback) {\n\tthis.apiQueue.push({\n\t\tendpoint: '/resend',\n\t\tdata: { email: email }\n\t}, callback || function () {});\n};\n\nDataStore.prototype.synchronize = function (callback) {\n\tvar context = this;\n\tthis.apiQueue.push({\n\t\tmethod: 'GET',\n\t\tendpoint: '/data/reacteurope-2016/all.json'\n\t}, function (err, data) {\n\t});\n};\n\n// Unsynchronized, non external API functions\nDataStore.prototype.star = function (id, starred) {\n\tthis.cache.starred[id] = starred;\n\tvar foundStarredPerson = false;\n\n\t// update people cache\n\tthis.cache.speakers.forEach(function (person) {\n\t\tif (person.id !== id || foundStarredPerson) return;\n\t\tfoundStarredPerson = true;\n\t\tperson.starred = starred;\n\t});\n\n\tif (!foundStarredPerson) {\n\t\tthis.cache.organisers.forEach(function (person) {\n\t\t\tif (person.id !== id || foundStarredPerson) return;\n\t\t\tfoundStarredPerson = true;\n\t\t\tperson.starred = starred;\n\t\t});\n\t}\n\n\twindow.localStorage.starred = JSON.stringify(this.cache.starred);\n};\n\nDataStore.prototype.amRegistered = function () { return !!this.cache.me };\nDataStore.prototype.getAttendees = function () { return [] };\nDataStore.prototype.getMe = function () { return this.cache.me };\nDataStore.prototype.getOrganisers = function () { return this.cache.organisers };\nDataStore.prototype.getPerson = function (id) { return this.cache.speakers.filter(person => person.id === id).pop() };\nDataStore.prototype.getPeople = function () { return this.cache.people };\nDataStore.prototype.getSchedule = function () { return this.cache.Proposals.sort((a, b) => new Date(a.start_date) - new Date(b.start_date)) };\nDataStore.prototype.getSettings = function () { return this.cache.settings };\nDataStore.prototype.getSpeakers = function () { return this.cache.speakers };\nDataStore.prototype.getSponsors = function () { return this.cache.sponsors };\nDataStore.prototype.getTicketCode = function () { return this.cache.ticketCode };\nDataStore.prototype.getHackathonTicketCode = function () { return this.cache.me && this.cache.me.hackathonTicketCode };\nDataStore.prototype.getWorkshopTicketCode = function () { return this.cache.me && this.cache.me.workshopTicketCode };\n\nmodule.exports = DataStore;\n"
  },
  {
    "path": "src/js/stores/default.json",
    "content": "{\"Event\":{\"id\":28,\"name\":\"ReactEurope\",\"tag_line\":\"The original React.js conference in Europe.\",\"description\":\"\\u003cp\\u003eReactEurope is back on 2-3 June 2016 to bring you the best and most passionate people from the very \\u003cstrong\\u003ecore team\\u003c/strong\\u003e to the coolest people from the community we love. The conference aims to give talks that inspire and explore new futuristic ideas dealing with all the techs we enjoy including \\u003cstrong\\u003eReact.js, React Native, GraphQL, Relay, Universal apps, inline CSS and more\\u003c/strong\\u003e.\\u003c/p\\u003e\\n\\n\\u003cp\\u003eReactEurope is also a great occasion to socialize, meet new people and old friends, hack together, taste delicious food and have fun in the beautiful city of Paris.\\u003c/p\\u003e\\n\\n\\u003cp\\u003e\\u003cstrong\\u003eJoin us at ReactEurope Conf to shape the future of client-side, mobile and universal applications!\\u003c/strong\\u003e\\u003c/p\\u003e\\n\",\"description_tickets_page\":\"ReactEurope is back on 2-3 June 2016 to bring you the best and most passionate people from the very core team to the coolest people from the community we love. The conference aims to give talks that inspire and explore new futuristic ideas dealing with all the techs we enjoy including React.js, React Native, GraphQL, Relay, Universal apps, inline CSS and more.\\n\\nReactEurope is also a great occasion to socialize, meet new people and old friends, hack together, taste delicious food and have fun in the beautiful city of Paris.\\n\\nALL SALES ARE FINAL - NO REFUNDS but tickets are transferable\",\"venue_name\":\"Espace Charenton\",\"venue_address\":\"323bis Rue de Charenton\",\"venue_city\":\"Paris\",\"venue_country\":\"France\",\"venue_postal_code\":\"75012\",\"venue_latitude\":48.8329894,\"venue_longitude\":2.396152099999995,\"vat_amount\":2000,\"slug\":\"reacteurope-2016\",\"url\":\"https://checkout.eventlama.com/#/events/reacteurope-2016/tickets\",\"timezone_id\":\"Europe/Paris\",\"sponsor_pdf_url\":\"\",\"twitter_handle\":\"ReactEurope\",\"facebook_url\":\"https://www.facebook.com/ReactEurope\",\"google_plus_url\":\"\",\"website_url\":\"https://www.react-europe.org/\",\"lanyrd_url\":\"http://lanyrd.com/2016/reacteu/\",\"bg_color\":\"#4656a0\",\"font_color\":\"#FFF\",\"custom_domain\":\"\",\"schedule_legend\":\"\",\"getting_there_legend\":\"\",\"speakers_legend\":\"\\u003cp\\u003eReactEurope will feature core-team and top community members from your favorite technologies with a diverse range of expertise from all around the globe. Stay tuned for the Call for Paper announcement.\\u003c/p\\u003e\\n\",\"copyrights_legend\":\"\",\"hotels_list\":\"\",\"offset\":7200,\"start_date\":\"2016-06-02T06:30:00Z\",\"end_date\":\"2016-06-03T16:30:00Z\",\"github_repo_url\":\"https://github.com/facebook/react\",\"logo_url\":\"https://api.eventlama.com/events/28/logo.png\"},\"Organizer\":{\"id\":2,\"name\":\"Patrick Aljord\",\"twitter\":\"patcito\",\"github\":\"patcito\",\"url\":\"\",\"pic_url\":\"https://api.eventlama.com/avatars/users/2/avatar.png\",\"bio\":\"\"},\"Collaborators\":[{\"id\":21,\"name\":\"Katiuska Gamero\",\"twitter\":\"katy_gca\",\"github\":\"katcita\",\"url\":\"https://www.react-europe.org/\",\"pic_url\":\"https://api.eventlama.com/avatars/events/28/collaborators/21/avatar.png\",\"bio\":\"\"},{\"id\":22,\"name\":\"Christopher Chedeaux\",\"twitter\":\"vjeux\",\"github\":\"vjeux\",\"url\":\"http://blog.vjeux.com/\",\"pic_url\":\"https://api.eventlama.com/avatars/events/28/collaborators/22/avatar.png\",\"bio\":\"\"}],\"Proposals\":[{\"id\":396,\"title\":\"Workshop With Dan Abramov and Andrew Clark Day 1\",\"description\":\"Don't forget to bring your laptop and a French AC adapter during the workshop. We will serve breakfast and lunch. Needs separate ticket. Checkin starts at 8:45am until 9:30am and workshop lasts until 5:30pm at Espace Charenton (room Mir), 5 rue Théodore Hamont, 75012, Paris https://goo.gl/maps/ho5DRzgRW742\",\"length\":525,\"tags\":\"\",\"status\":1,\"uuid\":\"\",\"agree_to_coc\":false,\"type\":1,\"start_date\":\"2016-05-31T06:45:00Z\",\"created_at\":\"2016-04-11T18:30:33Z\",\"updated_at\":\"2016-04-12T00:33:17Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"comments\":null,\"likes\":0,\"event_id\":28,\"speakers\":[{\"id\":146,\"name\":\"Dan Abramov\",\"twitter\":\"dan_abramov\",\"github\":\"gaearon\",\"url\":\"https://medium.com/@dan_abramov\",\"past_experience\":\"\",\"email\":\"dan.abramov@me.com\",\"bio\":\"Making hot reloading mainstream. Created React Hot Loader, Redux, React DnD.\",\"uuid\":\"0b57beb1-b6e0-467f-a301-63c6506ee046\",\"status\":1,\"avatar_url\":\"https://api.eventlama.com/avatars/events/28/speakers/146/avatar.png\",\"travel_costs\":false,\"agree_to_coc\":false,\"created_at\":\"2015-10-27T19:04:44Z\",\"updated_at\":\"2015-10-27T19:04:44Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"display_order\":0,\"event_id\":28,\"proposal_id\":0},{\"id\":147,\"name\":\"Andrew Clark\",\"twitter\":\"acdlite\",\"github\":\"acdlite\",\"url\":\"https://medium.com/@acdlite\",\"past_experience\":\"\",\"email\":\"acdlite@me.com\",\"bio\":\"Engineer at OpenGov. Currently living in React / JavaScript / Node -land. He's a prolific contributor to projects such as flummox, recompose, redux \\u0026 more.\",\"uuid\":\"b139bf70-b340-4899-98d0-c033832e7968\",\"status\":1,\"avatar_url\":\"https://api.eventlama.com/avatars/events/28/speakers/147/avatar.png\",\"travel_costs\":false,\"agree_to_coc\":false,\"created_at\":\"2016-04-11T18:05:23Z\",\"updated_at\":\"2016-04-11T18:05:23Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"display_order\":0,\"event_id\":28,\"proposal_id\":386}]},{\"id\":397,\"title\":\"Workshop With Dan Abramov and Andrew Clark Day 2\",\"description\":\"Don't forget to bring your laptop and a French AC adapter during the workshop. We will serve breakfast and lunch. Needs separate ticket. Checkin starts at 8:45am until 9:30am and workshop lasts until 5:30pm at Espace Charenton (room Mir), 5 rue Théodore Hamont, 75012, Paris https://goo.gl/maps/ho5DRzgRW742\",\"length\":525,\"tags\":\"\",\"status\":1,\"uuid\":\"\",\"agree_to_coc\":false,\"type\":1,\"start_date\":\"2016-06-01T06:45:00Z\",\"created_at\":\"2016-04-11T18:31:01Z\",\"updated_at\":\"2016-04-12T00:33:28Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"comments\":null,\"likes\":0,\"event_id\":28,\"speakers\":[{\"id\":146,\"name\":\"Dan Abramov\",\"twitter\":\"dan_abramov\",\"github\":\"gaearon\",\"url\":\"https://medium.com/@dan_abramov\",\"past_experience\":\"\",\"email\":\"dan.abramov@me.com\",\"bio\":\"Making hot reloading mainstream. Created React Hot Loader, Redux, React DnD.\",\"uuid\":\"0b57beb1-b6e0-467f-a301-63c6506ee046\",\"status\":1,\"avatar_url\":\"https://api.eventlama.com/avatars/events/28/speakers/146/avatar.png\",\"travel_costs\":false,\"agree_to_coc\":false,\"created_at\":\"2015-10-27T19:04:44Z\",\"updated_at\":\"2015-10-27T19:04:44Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"display_order\":0,\"event_id\":28,\"proposal_id\":0},{\"id\":147,\"name\":\"Andrew Clark\",\"twitter\":\"acdlite\",\"github\":\"acdlite\",\"url\":\"https://medium.com/@acdlite\",\"past_experience\":\"\",\"email\":\"acdlite@me.com\",\"bio\":\"Engineer at OpenGov. Currently living in React / JavaScript / Node -land. He's a prolific contributor to projects such as flummox, recompose, redux \\u0026 more.\",\"uuid\":\"b139bf70-b340-4899-98d0-c033832e7968\",\"status\":1,\"avatar_url\":\"https://api.eventlama.com/avatars/events/28/speakers/147/avatar.png\",\"travel_costs\":false,\"agree_to_coc\":false,\"created_at\":\"2016-04-11T18:05:23Z\",\"updated_at\":\"2016-04-11T18:05:23Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"display_order\":0,\"event_id\":28,\"proposal_id\":386}]},{\"id\":407,\"title\":\"Hackathon at Mozilla on June 1st\",\"description\":\"Our official ReactEurope Hackathon at Mozilla office in Paris from 9am to 6:30pm on June 1st. IMPORTANT: The address is \\\"16 Boulevard Montmartre, 75009 Paris, France (https://goo.gl/NLbvX1)\\\". Make sure to bring your own laptop and French AC adaptor.\",\"length\":540,\"tags\":\"\",\"status\":1,\"uuid\":\"\",\"agree_to_coc\":false,\"type\":0,\"start_date\":\"2016-06-01T07:00:00Z\",\"created_at\":\"2016-04-11T19:10:16Z\",\"updated_at\":\"2016-04-12T00:29:34Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"comments\":null,\"likes\":0,\"event_id\":28,\"speakers\":null},{\"id\":408,\"title\":\"RedBadger Bar Night 🍹🍸🎉🍟🍔\",\"description\":\"At brewery The Frog sponsored by Red-Badger at 6h:45pm, located at Bercy Village, Cour Saint-Emilion, Paris, France  https://goo.gl/maps/gudDaEvvaXS2\",\"length\":150,\"tags\":\"\",\"status\":1,\"uuid\":\"\",\"agree_to_coc\":false,\"type\":9,\"start_date\":\"2016-06-01T16:45:00Z\",\"created_at\":\"2016-04-12T00:19:28Z\",\"updated_at\":\"2016-04-12T00:25:44Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"comments\":null,\"likes\":0,\"event_id\":28,\"speakers\":null},{\"id\":391,\"title\":\"Registration\",\"description\":\"Make sure to get in early at 323bis Rue de Charenton, 75012 Paris https://goo.gl/maps/t4FKT93C25u\",\"length\":90,\"tags\":\"\",\"status\":1,\"uuid\":\"\",\"agree_to_coc\":false,\"type\":8,\"start_date\":\"2016-06-02T06:30:00Z\",\"created_at\":\"2016-04-11T18:24:02Z\",\"updated_at\":\"2016-04-12T00:53:01Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"comments\":null,\"likes\":0,\"event_id\":28,\"speakers\":null},{\"id\":394,\"title\":\"Breakfast\",\"description\":\"Your typical French breakfast with croissants, coffee and more.\",\"length\":60,\"tags\":\"\",\"status\":1,\"uuid\":\"\",\"agree_to_coc\":false,\"type\":3,\"start_date\":\"2016-06-02T06:45:00Z\",\"created_at\":\"2016-04-11T18:29:50Z\",\"updated_at\":\"2016-04-12T00:27:30Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"comments\":null,\"likes\":0,\"event_id\":28,\"speakers\":null},{\"id\":142,\"title\":\"Keynote\",\"description\":\"Keynote\",\"length\":30,\"tags\":\"\",\"status\":1,\"uuid\":\"\",\"agree_to_coc\":false,\"type\":0,\"start_date\":\"2016-06-02T08:00:00Z\",\"created_at\":\"2015-10-27T19:22:22Z\",\"updated_at\":\"2016-04-11T00:21:49Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"comments\":null,\"likes\":0,\"event_id\":28,\"speakers\":[{\"id\":146,\"name\":\"Dan Abramov\",\"twitter\":\"dan_abramov\",\"github\":\"gaearon\",\"url\":\"https://medium.com/@dan_abramov\",\"past_experience\":\"\",\"email\":\"dan.abramov@me.com\",\"bio\":\"Making hot reloading mainstream. Created React Hot Loader, Redux, React DnD.\",\"uuid\":\"0b57beb1-b6e0-467f-a301-63c6506ee046\",\"status\":1,\"avatar_url\":\"https://api.eventlama.com/avatars/events/28/speakers/146/avatar.png\",\"travel_costs\":false,\"agree_to_coc\":false,\"created_at\":\"2015-10-27T19:04:44Z\",\"updated_at\":\"2015-10-27T19:04:44Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"display_order\":0,\"event_id\":28,\"proposal_id\":0}]},{\"id\":376,\"title\":\"Native Navigation for Every Platform\",\"description\":\"Navigation on native mobile apps can be very tricky. Unlike the browser, mobile apps have no built-in navigation system, and the navigation state is often deeply nested. Animations and gestures are critical for mobile apps, and are tricky to get right. To help the community address these concerns, I will introduce and demo our new navigation system for React Native, and show what innovations we can bring back to the web.\",\"length\":30,\"tags\":\"\",\"status\":1,\"uuid\":\"\",\"agree_to_coc\":false,\"type\":0,\"start_date\":\"2016-06-02T08:30:00Z\",\"created_at\":\"2016-04-10T23:40:45Z\",\"updated_at\":\"2016-04-10T23:42:51Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"comments\":null,\"likes\":0,\"event_id\":28,\"speakers\":[{\"id\":400,\"name\":\"Eric Vicenti\",\"twitter\":\"ericvicenti\",\"github\":\"ericvicenti\",\"url\":\"\",\"past_experience\":\"\",\"email\":\"eric@fb.com\",\"bio\":\"Working on React Native and using it to build cross-platform apps at Facebook since 2014.\",\"uuid\":\"7229a9a4-c587-4269-bf47-13b1442f82d0\",\"status\":1,\"avatar_url\":\"https://api.eventlama.com/avatars/events/28/speakers/400/avatar.png\",\"travel_costs\":false,\"agree_to_coc\":false,\"created_at\":\"2016-04-10T23:42:01Z\",\"updated_at\":\"2016-04-10T23:42:01Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"display_order\":0,\"event_id\":28,\"proposal_id\":0}]},{\"id\":409,\"title\":\"Coffee Break\",\"description\":\"Socialize, have some coffee or other drinks.\",\"length\":30,\"tags\":\"\",\"status\":1,\"uuid\":\"\",\"agree_to_coc\":false,\"type\":2,\"start_date\":\"2016-06-02T09:00:00Z\",\"created_at\":\"2016-04-12T00:21:45Z\",\"updated_at\":\"2016-04-12T00:30:24Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"comments\":null,\"likes\":0,\"event_id\":28,\"speakers\":null},{\"id\":377,\"title\":\"A cartoon guide to performance in React\",\"description\":\"Everyone talks about how performant React is... but why? What makes people talk about how speedy React is? In this talk, you'll learn *why* people talk about React being fast, and what you can do to make it faster.\",\"length\":30,\"tags\":\"\",\"status\":1,\"uuid\":\"\",\"agree_to_coc\":true,\"type\":0,\"start_date\":\"2016-06-02T09:30:00Z\",\"created_at\":\"2016-04-10T23:45:53Z\",\"updated_at\":\"2016-04-10T23:46:46Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"comments\":null,\"likes\":0,\"event_id\":28,\"speakers\":[{\"id\":401,\"name\":\"Lin Clark\",\"twitter\":\"linclark\",\"github\":\"linclark\",\"url\":\"https://code-cartoons.com/\",\"past_experience\":\"\",\"email\":\"linclark@mozilla.org\",\"bio\":\"Code cartoonist and developer tools engineer at Mozilla.\",\"uuid\":\"93c90231-4e66-43ac-9d66-938096ea3d11\",\"status\":1,\"avatar_url\":\"https://api.eventlama.com/avatars/events/28/speakers/401/avatar.png\",\"travel_costs\":false,\"agree_to_coc\":false,\"created_at\":\"2016-04-10T23:45:53Z\",\"updated_at\":\"2016-04-10T23:45:53Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"display_order\":0,\"event_id\":28,\"proposal_id\":377}]},{\"id\":378,\"title\":\"React Native \\u003c3 60FPS -- Improving React Native animations\\u003e\",\"description\":\"Coming soon...\",\"length\":30,\"tags\":\"\",\"status\":1,\"uuid\":\"\",\"agree_to_coc\":true,\"type\":0,\"start_date\":\"2016-06-02T10:00:00Z\",\"created_at\":\"2016-04-10T23:49:22Z\",\"updated_at\":\"2016-04-10T23:50:15Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"comments\":null,\"likes\":0,\"event_id\":28,\"speakers\":[{\"id\":402,\"name\":\"Krzysztof Magiera\",\"twitter\":\"kzzzf\",\"github\":\"kmagiera\",\"url\":\"https://www.linkedin.com/in/krzysztof-magiera-5a698367?authType=NAME_SEARCH\\u0026authToken=65d2\\u0026locale=pl_PL\\u0026srchid=138075431454355939983\\u0026srchindex=1\\u0026srchtotal=14\\u0026trk=vsrp_people_res_name\\u0026trkInfo=VSRPsearchId%3A138075431454355939983%2CVSRPtargetId%3A238304142%\",\"past_experience\":\"\",\"email\":\"k@fb.com\",\"bio\":\"Software engineer working on @ReactJS Native for android.\",\"uuid\":\"e2a904ec-be6d-43b7-9ac4-31650e94176a\",\"status\":1,\"avatar_url\":\"https://api.eventlama.com/avatars/events/28/speakers/402/avatar.png\",\"travel_costs\":false,\"agree_to_coc\":false,\"created_at\":\"2016-04-10T23:49:22Z\",\"updated_at\":\"2016-04-10T23:49:22Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"display_order\":0,\"event_id\":28,\"proposal_id\":378}]},{\"id\":401,\"title\":\"French Buffet\",\"description\":\"Lunch time! Socialize while eating at our delicious buffet.\",\"length\":90,\"tags\":\"\",\"status\":1,\"uuid\":\"\",\"agree_to_coc\":false,\"type\":4,\"start_date\":\"2016-06-02T10:30:00Z\",\"created_at\":\"2016-04-11T18:35:29Z\",\"updated_at\":\"2016-04-11T18:42:24Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"comments\":null,\"likes\":0,\"event_id\":28,\"speakers\":null},{\"id\":379,\"title\":\"Being Successful at Open Source\",\"description\":\"I've been directly involved in the open source process of many Facebook projects such as React, React Native, css-layout, mention-bot and Jest in the past 3 years. We've tried a lot of different things in order to grow a community around those projects and I want to take this opportunity to share what worked for us and can likely be applied to other projects.\",\"length\":30,\"tags\":\"\",\"status\":1,\"uuid\":\"\",\"agree_to_coc\":true,\"type\":0,\"start_date\":\"2016-06-02T12:00:00Z\",\"created_at\":\"2016-04-10T23:51:55Z\",\"updated_at\":\"2016-04-10T23:52:33Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"comments\":null,\"likes\":0,\"event_id\":28,\"speakers\":[{\"id\":403,\"name\":\"Christopher Chedeau\",\"twitter\":\"vjeux\",\"github\":\"vjeux\",\"url\":\"http://blog.vjeux.com/\",\"past_experience\":\"\",\"email\":\"vjeux@fb.com\",\"bio\":\"Frenchy Front-end Engineer at Facebook. Working on React and React Native.\",\"uuid\":\"5105ea60-11e2-4aa9-9576-dfd0148c33fa\",\"status\":2,\"avatar_url\":\"https://api.eventlama.com/avatars/events/28/speakers/403/avatar.png\",\"travel_costs\":false,\"agree_to_coc\":false,\"created_at\":\"2016-04-10T23:51:55Z\",\"updated_at\":\"2016-04-10T23:51:55Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"display_order\":0,\"event_id\":28,\"proposal_id\":379}]},{\"id\":380,\"title\":\"GraphQL at Facebook\",\"description\":\"Facebook has been using GraphQL in production for almost four years; today, it serves over 300 billion queries a day and its schema has nearly 10,000 types. In building this API, we’ve developed a set of best practices for designing an understandable and scalable GraphQL schema. Based on real examples in Facebook’s production GraphQL API, we'll discuss common GraphQL patterns, how they differ from other best practices, and their implications on server and client design.\",\"length\":30,\"tags\":\"\",\"status\":1,\"uuid\":\"\",\"agree_to_coc\":false,\"type\":0,\"start_date\":\"2016-06-02T12:30:00Z\",\"created_at\":\"2016-04-10T23:54:09Z\",\"updated_at\":\"2016-04-19T01:32:01Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"comments\":null,\"likes\":0,\"event_id\":28,\"speakers\":[{\"id\":404,\"name\":\"Dan Schafer\",\"twitter\":\"dlschafer\",\"github\":\"dschafer\",\"url\":\"https://www.facebook.com/dschafer\",\"past_experience\":\"\",\"email\":\"dan@fb.com\",\"bio\":\"Software engineer at Facebook, GraphQL co-creator.\",\"uuid\":\"90684d22-95fa-448b-8890-d91f1922fc6b\",\"status\":1,\"avatar_url\":\"https://api.eventlama.com/avatars/events/28/speakers/404/avatar.png\",\"travel_costs\":false,\"agree_to_coc\":false,\"created_at\":\"2016-04-10T23:59:30Z\",\"updated_at\":\"2016-04-10T23:59:30Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"display_order\":0,\"event_id\":28,\"proposal_id\":0}]},{\"id\":393,\"title\":\"Coffee Break\",\"description\":\"Socialize, have some coffee or other drinks.\",\"length\":30,\"tags\":\"\",\"status\":1,\"uuid\":\"\",\"agree_to_coc\":false,\"type\":2,\"start_date\":\"2016-06-02T13:00:00Z\",\"created_at\":\"2016-04-11T18:29:24Z\",\"updated_at\":\"2016-04-12T00:30:36Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"comments\":null,\"likes\":0,\"event_id\":28,\"speakers\":null},{\"id\":381,\"title\":\"A Deepdive Into Flow\",\"description\":\"Many have heard about Flow and some are using it a lot already, but what is it that makes Flow so powerful? I'll dive deeper into Flow, how it works, and why we're using it at Facebook to improve the quality of our code at scale.\",\"length\":30,\"tags\":\"\",\"status\":1,\"uuid\":\"\",\"agree_to_coc\":true,\"type\":0,\"start_date\":\"2016-06-02T13:30:00Z\",\"created_at\":\"2016-04-11T00:03:36Z\",\"updated_at\":\"2016-04-11T00:03:55Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"comments\":null,\"likes\":0,\"event_id\":28,\"speakers\":[{\"id\":405,\"name\":\"Jeff Morrison\",\"twitter\":\"lbljeffmo\",\"github\":\"jeffmo\",\"url\":\"https://www.linkedin.com/in/jeff-morrison-30374910\",\"past_experience\":\"\",\"email\":\"jeff@fb.com\",\"bio\":\"Jeff works on @flowtype at Facebook.\",\"uuid\":\"af462335-7cc4-4ebe-b6a1-eba2d0c7148c\",\"status\":1,\"avatar_url\":\"https://api.eventlama.com/avatars/events/28/speakers/405/avatar.png\",\"travel_costs\":false,\"agree_to_coc\":false,\"created_at\":\"2016-04-11T00:03:36Z\",\"updated_at\":\"2016-04-11T00:03:36Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"display_order\":0,\"event_id\":28,\"proposal_id\":381}]},{\"id\":218,\"title\":\"Debugging flux applications in production\",\"description\":\"We have brilliant tools and highly efficient practices for developing and debugging flux applications. But it’s not that easy when it comes to deal with troubles in production, especially with bug reports like “nothing works”. The predictable states could help a lot, but user actions along with API calls are not that predictable.\\n\\nThis talk will dive into how to firmly debug client-side state for web and native flux applications, how to reproduce the exact state despite of diverse factors, track the original cause and get fixes out to users. You’ll push development to the next level and improve user experience.\",\"length\":30,\"tags\":\"flux, redux, reactnative, debugging\",\"status\":1,\"uuid\":\"\",\"agree_to_coc\":false,\"type\":0,\"start_date\":\"2016-06-02T14:00:09Z\",\"created_at\":\"2016-01-23T19:59:49Z\",\"updated_at\":\"2016-04-11T00:08:47Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"comments\":null,\"likes\":0,\"event_id\":28,\"speakers\":[{\"id\":223,\"name\":\"Mihail Diordiev\",\"twitter\":\"mdiordiev\",\"github\":\"zalmoxisus\",\"url\":\"https://medium.com/@zalmoxis\",\"past_experience\":\"\",\"email\":\"contact@dioart.com\",\"bio\":\"Debugging geek, cares too much. Created Redux DevTools Extension, Remote Redux DevTools, RemoteDev and CrossBuilder.\",\"uuid\":\"a06dae94-4e9f-44de-aa29-ba0c70f8fede\",\"status\":1,\"avatar_url\":\"https://api.eventlama.com/avatars/events/28/speakers/223/avatar.png\",\"travel_costs\":true,\"agree_to_coc\":true,\"created_at\":\"2016-01-23T19:59:49Z\",\"updated_at\":\"2016-01-23T20:32:39Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"display_order\":0,\"event_id\":28,\"proposal_id\":218}]},{\"id\":395,\"title\":\"Coffee Break\",\"description\":\"Socialize, have some coffee or other drinks.\",\"length\":30,\"tags\":\"\",\"status\":1,\"uuid\":\"\",\"agree_to_coc\":false,\"type\":2,\"start_date\":\"2016-06-02T14:30:00Z\",\"created_at\":\"2016-04-11T18:30:14Z\",\"updated_at\":\"2016-04-12T00:30:49Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"comments\":null,\"likes\":0,\"event_id\":28,\"speakers\":null},{\"id\":383,\"title\":\"On the Spectrum of Abstraction\",\"description\":\"JavaScript and the React community have evolved over the years through all the ups and downs. This talk goes over the tools we've come to recognize, from Angular, Ember and Grunt, all the way go Gulp, Webpack, React and beyond, and captures all these in a unifying mental framework for reasoning in terms of abstraction levels, in an attempt to make sense of what is and might be happening.\",\"length\":30,\"tags\":\"\",\"status\":1,\"uuid\":\"\",\"agree_to_coc\":false,\"type\":0,\"start_date\":\"2016-06-02T15:00:00Z\",\"created_at\":\"2016-04-11T00:10:37Z\",\"updated_at\":\"2016-04-14T22:48:18Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"comments\":null,\"likes\":0,\"event_id\":28,\"speakers\":[{\"id\":143,\"name\":\"Cheng Lou\",\"twitter\":\"_chenglou\",\"github\":\"chenglou\",\"url\":\"https://medium.com/@chenglou\",\"past_experience\":\"\",\"email\":\"chenglou92@gmail.com\",\"bio\":\"React core member. Currently working on animation-related problems.\",\"uuid\":\"346e99ef-c5a2-408e-a5d1-8b711b2d730d\",\"status\":1,\"avatar_url\":\"https://api.eventlama.com/avatars/events/28/speakers/143/avatar.png\",\"travel_costs\":false,\"agree_to_coc\":false,\"created_at\":\"2016-04-11T00:10:37Z\",\"updated_at\":\"2016-04-11T00:10:37Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"display_order\":0,\"event_id\":28,\"proposal_id\":383}]},{\"id\":233,\"title\":\"React Redux Analytics\",\"description\":\"The Lean Startup advocates an iterative approach to finding the right product and market, with a constant cycle of building, measuring and learning. Lean Analytics is a new approach which dives deeper into the measurement component of this process. With Lean Analytics we can measure the state of the application and make informed decisions about the product and its vision based on end user interactions.\\nRedux allows us to maintain our application state in a single store, and provides a single location for state changes. By hooking analytics into this event loop we can infer a lot about end user behaviour. Our Redux Segment middleware allows you to draw deep and rich analytics from your Redux application with minimal configuration.\\nIn this talk, we will walk through the process of adding analytics to your existing Redux application and share our implementation which works with segment.io.\",\"length\":30,\"tags\":\"react, redux, analytics, segment\",\"status\":1,\"uuid\":\"\",\"agree_to_coc\":false,\"type\":0,\"start_date\":\"2016-06-02T15:30:00Z\",\"created_at\":\"2016-01-25T13:15:09Z\",\"updated_at\":\"2016-04-11T00:12:13Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"comments\":null,\"likes\":0,\"event_id\":28,\"speakers\":[{\"id\":239,\"name\":\"Evan Schultz\",\"twitter\":\"e_p82\",\"github\":\"e-schultz\",\"url\":\"http://blog.rangle.io\",\"past_experience\":\"https://angularsummit.com/topics/reactive_flux_architecture_for_angularjs_apps#preview-video\",\"email\":\"evan@rangle.io\",\"bio\":\"Evan is a passionate software developer with nearly 10 years experience. As a seasoned JavaScript architect he adapts to new technologies and has contributed to many team-based projects, whilst mentoring other developers. Evan leads and contributes to the Rangle.io’s  guidelines, code reviews and training material. He educates peers and clients and writes about development best practices for Rangle.io’s blog, http://blog.rangle.io\",\"uuid\":\"b7b8d836-ec18-4199-8658-5b5fe6e344eb\",\"status\":1,\"avatar_url\":\"https://api.eventlama.com/avatars/events/28/speakers/239/avatar.png\",\"travel_costs\":true,\"agree_to_coc\":true,\"created_at\":\"2016-01-25T13:15:09Z\",\"updated_at\":\"2016-01-25T13:16:05Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"display_order\":0,\"event_id\":28,\"proposal_id\":233},{\"id\":240,\"name\":\"Bertrand Karerangabo\",\"twitter\":\"codenarian\",\"github\":\"bertrandk\",\"url\":\"http://blog.rangle.io\",\"past_experience\":\"https://www.youtube.com/watch?v=Elr_RNt2R5Q\",\"email\":\"bertrand@rangle.io\",\"bio\":\"Bertrand is a full-stack web developer with extensive experience building complex applications in ReactJS on web and native platforms. He also spends his time managing everything from server infrastructure to analytics dashboard.\",\"uuid\":\"8b8afe38-d1ce-444a-92d3-0c3ae7d7f986\",\"status\":1,\"avatar_url\":\"https://api.eventlama.com/avatars/events/28/speakers/240/avatar.png\",\"travel_costs\":true,\"agree_to_coc\":true,\"created_at\":\"2016-01-25T13:15:09Z\",\"updated_at\":\"2016-01-25T13:16:05Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"display_order\":0,\"event_id\":28,\"proposal_id\":233}]},{\"id\":404,\"title\":\"Lightning talks session\",\"description\":\"Small five minute short talks on React and its ecosystem.\",\"length\":60,\"tags\":\"\",\"status\":1,\"uuid\":\"\",\"agree_to_coc\":false,\"type\":0,\"start_date\":\"2016-06-02T16:00:00Z\",\"created_at\":\"2016-04-11T18:38:18Z\",\"updated_at\":\"2016-04-12T00:33:43Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"comments\":null,\"likes\":0,\"event_id\":28,\"speakers\":null},{\"id\":403,\"title\":\"Dinner\",\"description\":\"Drinks, food, music.\",\"length\":150,\"tags\":\"\",\"status\":1,\"uuid\":\"\",\"agree_to_coc\":false,\"type\":5,\"start_date\":\"2016-06-02T17:00:00Z\",\"created_at\":\"2016-04-11T18:37:19Z\",\"updated_at\":\"2016-04-12T00:35:36Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"comments\":null,\"likes\":0,\"event_id\":28,\"speakers\":null},{\"id\":400,\"title\":\"Check-in\",\"description\":\"Make sure to get in early.\",\"length\":30,\"tags\":\"\",\"status\":1,\"uuid\":\"\",\"agree_to_coc\":false,\"type\":8,\"start_date\":\"2016-06-03T06:30:00Z\",\"created_at\":\"2016-04-11T18:31:53Z\",\"updated_at\":\"2016-04-11T18:53:38Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"comments\":null,\"likes\":0,\"event_id\":28,\"speakers\":null},{\"id\":406,\"title\":\"Breakfast\",\"description\":\"Your typical French breakfast with croissants, coffee and more.\",\"length\":75,\"tags\":\"\",\"status\":1,\"uuid\":\"\",\"agree_to_coc\":false,\"type\":3,\"start_date\":\"2016-06-03T06:45:00Z\",\"created_at\":\"2016-04-11T18:56:47Z\",\"updated_at\":\"2016-04-12T00:27:45Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"comments\":null,\"likes\":0,\"event_id\":28,\"speakers\":null},{\"id\":384,\"title\":\"Evolving the Visual Programming Environment with React\",\"description\":\"Tools shape our thinking. The \\\"React Way\\\" of thinking has already found many applications beyond building user interfaces. Particularly, React's functional, component-based design makes it an ideal candidate for building a better Visual Programming Environment. We'll examine how to overcome challenges such as lack of standardized APIs and limits of composition, and show how we can drastically improve the way humans create digital artifacts today.\",\"length\":30,\"tags\":\"\",\"status\":1,\"uuid\":\"\",\"agree_to_coc\":true,\"type\":0,\"start_date\":\"2016-06-03T08:00:00Z\",\"created_at\":\"2016-04-11T00:17:54Z\",\"updated_at\":\"2016-04-11T00:18:47Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"comments\":null,\"likes\":0,\"event_id\":28,\"speakers\":[{\"id\":407,\"name\":\"Jonas Gebhardt\",\"twitter\":\"jonasgebhardt\",\"github\":\"jgebhardt\",\"url\":\"http://jonasgebhardt.com/\",\"past_experience\":\"\",\"email\":\"jonas@fb.com\",\"bio\":\"Front-end Engineer at Facebook Seattle, working on Nuclide \\u0026 building tools to empower humans.\",\"uuid\":\"11817199-1b74-4364-9713-588771b79588\",\"status\":1,\"avatar_url\":\"https://api.eventlama.com/avatars/events/28/speakers/407/avatar.png\",\"travel_costs\":false,\"agree_to_coc\":false,\"created_at\":\"2016-04-11T00:17:54Z\",\"updated_at\":\"2016-04-11T00:17:54Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"display_order\":0,\"event_id\":28,\"proposal_id\":384}]},{\"id\":385,\"title\":\"React Native Retrospective\",\"description\":\"Remember when React Native beta access was shared illicitly via flash drives behind closed doors? Since its first release in January 2015, React Native has experienced incredible growth and adoption. We'll discuss the evolution of React Native over the last year, looking at the maturation of the library as well as the ever-increasing community around it. From the release of Android support to the focus on better build systems and asset management, to the influx of interest from \\\"traditional\\\" mobile developers, there's a lot to take in. Understanding how we reached the present will help us see where we're going next. What problems remain to be solved? How will React Native continue to evolve and grow?\",\"length\":30,\"tags\":\"\",\"status\":1,\"uuid\":\"\",\"agree_to_coc\":false,\"type\":0,\"start_date\":\"2016-06-03T08:30:00Z\",\"created_at\":\"2016-04-11T00:21:00Z\",\"updated_at\":\"2016-04-11T00:21:17Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"comments\":null,\"likes\":0,\"event_id\":28,\"speakers\":[{\"id\":144,\"name\":\"Bonnie Eisenman\",\"twitter\":\"brindelle\",\"github\":\"bonniee\",\"url\":\"http://blog.bonnieeisenman.com/\",\"past_experience\":\"\",\"email\":\"bonnie.eisenman@gmail.com\",\"bio\":\"Software eng at Codecademy, NYC Resistor member, author of Learning React Native. Learning Esperanto \\u0026 Japanese.\",\"uuid\":\"da178f0e-a519-4ea7-b082-5db832307e04\",\"status\":1,\"avatar_url\":\"https://api.eventlama.com/avatars/events/28/speakers/144/avatar.png\",\"travel_costs\":false,\"agree_to_coc\":false,\"created_at\":\"2016-04-11T00:21:00Z\",\"updated_at\":\"2016-04-11T00:21:00Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"display_order\":0,\"event_id\":28,\"proposal_id\":385}]},{\"id\":392,\"title\":\"Coffee Break\",\"description\":\"Socialize, have some coffee or other drinks.\",\"length\":30,\"tags\":\"\",\"status\":1,\"uuid\":\"\",\"agree_to_coc\":false,\"type\":2,\"start_date\":\"2016-06-03T09:00:00Z\",\"created_at\":\"2016-04-11T18:27:00Z\",\"updated_at\":\"2016-04-12T00:31:00Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"comments\":null,\"likes\":0,\"event_id\":28,\"speakers\":null},{\"id\":245,\"title\":\"The Evolution of React UI Development\",\"description\":\"Hot reloading makes for a great Developer Experience, but we can do even better. Using interactive style guides that show our components in a variety of different states we can test their look and feel in diverse situations.\\n\\nCollaborate with designers and marketers on testing them and pushing them to their limits. UI fuzz testing can help us discover combinations of props we haven't even thought of so we catch potential UI issues early on.\\n\\nIn the future, we might be able to detect styling and layout issues. Integrating these checks into our Continuous Integration system means we could catch potential problems with our components before any user can see them.\",\"length\":30,\"tags\":\"reactjs, ux, styleguide, uidiscovery\",\"status\":1,\"uuid\":\"\",\"agree_to_coc\":false,\"type\":0,\"start_date\":\"2016-06-03T09:30:00Z\",\"created_at\":\"2016-01-25T20:54:13Z\",\"updated_at\":\"2016-04-11T18:04:00Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"comments\":null,\"likes\":0,\"event_id\":28,\"speakers\":[{\"id\":254,\"name\":\"Max Stoiber\",\"twitter\":\"mxstbr\",\"github\":\"mxstbr\",\"url\":\"http://mxstbr.com\",\"past_experience\":\"I have given a few talks at local meetups in front of 50-100 devs before. Two of them were recorded, see http://mxs.is/pctalk and http://mxs.is/swtalk\",\"email\":\"contact@mxstbr.com\",\"bio\":\"I travel around the world, brew rad coffee, ski beautiful mountains and make stuff on the web. Co-organiser of React Vienna.\",\"uuid\":\"dda5c93b-5090-4110-ba60-e90ef0f38bd4\",\"status\":1,\"avatar_url\":\"https://api.eventlama.com/avatars/events/28/speakers/254/avatar.png\",\"travel_costs\":true,\"agree_to_coc\":true,\"created_at\":\"2016-01-25T20:54:13Z\",\"updated_at\":\"2016-01-27T10:13:47Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"display_order\":0,\"event_id\":28,\"proposal_id\":245},{\"id\":255,\"name\":\"Nik Graf\",\"twitter\":\"nikgraf\",\"github\":\"nikgraf\",\"url\":\"https://medium.com/@nikgraf\",\"past_experience\":\"I gave an introductory talk on React and Redux which was featured in the React Newsletter. (http://bit.ly/1nuDWxY) We have yet to present this talk, but we'll do a test run at Stripe and React Vienna. (which I co-founded)\",\"email\":\"nik@nikgraf.com\",\"bio\":\"I care a lot about consistent and easy to grasp user interfaces. While working as a freelancer I created the React UI library Belle and co-founded the React Vienna Meetup. I was invited to Stripe's Open Source Retreat and currently work full-time on several React \\u0026 Redux open source projects.\",\"uuid\":\"24dd5ae7-d40f-49fd-93c8-3f752de459ea\",\"status\":1,\"avatar_url\":\"https://api.eventlama.com/avatars/events/28/speakers/255/avatar.png\",\"travel_costs\":true,\"agree_to_coc\":true,\"created_at\":\"2016-01-25T20:54:13Z\",\"updated_at\":\"2016-01-27T10:13:47Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"display_order\":0,\"event_id\":28,\"proposal_id\":245}]},{\"id\":386,\"title\":\"Recomposing your React application\",\"description\":\"Recompose is a functional utility library for React components. It provides a suite of higher-order components that encapsulate common React patterns. In this talk, I’ll describe the history and rationale of the library, and discuss strategies for building React apps for scalability and reuse.\",\"length\":30,\"tags\":\"\",\"status\":1,\"uuid\":\"\",\"agree_to_coc\":false,\"type\":0,\"start_date\":\"2016-06-03T10:00:00Z\",\"created_at\":\"2016-04-11T18:05:23Z\",\"updated_at\":\"2016-04-11T18:06:26Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"comments\":null,\"likes\":0,\"event_id\":28,\"speakers\":[{\"id\":147,\"name\":\"Andrew Clark\",\"twitter\":\"acdlite\",\"github\":\"acdlite\",\"url\":\"https://medium.com/@acdlite\",\"past_experience\":\"\",\"email\":\"acdlite@me.com\",\"bio\":\"Engineer at OpenGov. Currently living in React / JavaScript / Node -land. He's a prolific contributor to projects such as flummox, recompose, redux \\u0026 more.\",\"uuid\":\"b139bf70-b340-4899-98d0-c033832e7968\",\"status\":1,\"avatar_url\":\"https://api.eventlama.com/avatars/events/28/speakers/147/avatar.png\",\"travel_costs\":false,\"agree_to_coc\":false,\"created_at\":\"2016-04-11T18:05:23Z\",\"updated_at\":\"2016-04-11T18:05:23Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"display_order\":0,\"event_id\":28,\"proposal_id\":386}]},{\"id\":402,\"title\":\"French Buffet\",\"description\":\"Lunch time! Socialize while eating at our delicious buffet.\",\"length\":90,\"tags\":\"\",\"status\":1,\"uuid\":\"\",\"agree_to_coc\":false,\"type\":4,\"start_date\":\"2016-06-03T10:30:00Z\",\"created_at\":\"2016-04-11T18:36:18Z\",\"updated_at\":\"2016-04-11T18:52:35Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"comments\":null,\"likes\":0,\"event_id\":28,\"speakers\":null},{\"id\":387,\"title\":\"JavaScript, React Native and Performance.\",\"description\":\"With React Native, some of your applications core functionalities, that would previously be written in native code, are now implemented in JavaScript. And that's great! Now you can use things like Hot Module Reloading and ship updates to your app whenever you want. But what about performance and User Experience? Is JavaScript fast enough to replace native code? I'm going to talk about some of the challenges we are working on at the React Native Performance team.\",\"length\":30,\"tags\":\"\",\"status\":1,\"uuid\":\"\",\"agree_to_coc\":true,\"type\":0,\"start_date\":\"2016-06-03T12:00:00Z\",\"created_at\":\"2016-04-11T18:08:29Z\",\"updated_at\":\"2016-04-19T01:28:22Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"comments\":null,\"likes\":0,\"event_id\":28,\"speakers\":[{\"id\":408,\"name\":\"Tadeu Zagallo\",\"twitter\":\"tadeuzagallo\",\"github\":\"tadeuzagallo\",\"url\":\"http://tadeuzagallo.com/blog/\",\"past_experience\":\"\",\"email\":\"tadeu@fb.com\",\"bio\":\"Software Engineer @Facebook working on React Native and one of its top committer.\",\"uuid\":\"9ce19631-09ff-4af2-95b1-e87aaf1dedec\",\"status\":1,\"avatar_url\":\"https://api.eventlama.com/avatars/events/28/speakers/408/avatar.png\",\"travel_costs\":false,\"agree_to_coc\":false,\"created_at\":\"2016-04-11T18:08:29Z\",\"updated_at\":\"2016-04-11T18:08:29Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"display_order\":0,\"event_id\":28,\"proposal_id\":387}]},{\"id\":388,\"title\":\"Falcor: One Model Everywhere\",\"description\":\"Imagine how easy building your web application would be if all of your data was available in-memory on the client. Falcor lets you to code that way.\\n\\nFalcor is the open-source, JS data access framework that powers Netflix. Falcor lets you represent all of your cloud data sources as one virtual JSON model on the server. On the client, Falcor makes it appear as if the entire JSON model is available locally and allows you to access data the same way you would from an in-memory JSON object. Falcor retrieves the model data you request from the cloud on-demand, transparently handling all the network communication and keeping the server and client in sync.\\n\\nCome learn about how Netflix integrates React and Falcor.\",\"length\":30,\"tags\":\"\",\"status\":1,\"uuid\":\"\",\"agree_to_coc\":false,\"type\":0,\"start_date\":\"2016-06-03T12:30:00Z\",\"created_at\":\"2016-04-11T18:10:12Z\",\"updated_at\":\"2016-04-11T18:10:57Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"comments\":null,\"likes\":0,\"event_id\":28,\"speakers\":[{\"id\":145,\"name\":\"Jafar Husain\",\"twitter\":\"jhusain\",\"github\":\"jhusain\",\"url\":\"https://www.linkedin.com/pub/jafar-husain/7/756/785\",\"past_experience\":\"\",\"email\":\"jhusain@gmail.com\",\"bio\":\"Technical Lead at Netflix, Architect of @falcorjs, TC-39 Representative.\",\"uuid\":\"ca419806-2e17-48ac-8af3-c41fd44b8e05\",\"status\":1,\"avatar_url\":\"https://api.eventlama.com/avatars/events/28/speakers/145/avatar.png\",\"travel_costs\":false,\"agree_to_coc\":false,\"created_at\":\"2016-04-11T18:10:12Z\",\"updated_at\":\"2016-04-11T18:10:12Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"display_order\":0,\"event_id\":28,\"proposal_id\":388}]},{\"id\":410,\"title\":\"Coffee Break\",\"description\":\"Socialize, have some coffee or other drinks.\",\"length\":30,\"tags\":\"\",\"status\":1,\"uuid\":\"\",\"agree_to_coc\":false,\"type\":2,\"start_date\":\"2016-06-03T13:00:00Z\",\"created_at\":\"2016-04-12T00:32:03Z\",\"updated_at\":\"2016-04-12T00:32:30Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"comments\":null,\"likes\":0,\"event_id\":28,\"speakers\":null},{\"id\":389,\"title\":\"Building li.st for Android with Exponent and React Native\",\"description\":\"li.st for Android is likely one of the largest pure React Native codebases around at this time. The only native modules that we use are generic and included in Exponent because they would apply to many other apps (social login, image picker, push notifications) -- otherwise it's JavaScript all the way down. The functionality that li.st provides covers a wide range of common patterns that you'll find in most apps, which is one of the reasons why we wanted to build it in the first place: to test the limits of Exponent and React Native with in real world scenarios. Living on the edge with both React Native and Exponent, you'd be right to guess that we ran into our fair share of problems. You're going to encounter most of these problems if you are building a big React Native app (possibly some for React DOM apps) in the next year and I'm here to let you know that you're not alone and arm you with some knowledge you'll want when building a large app.\",\"length\":30,\"tags\":\"\",\"status\":1,\"uuid\":\"\",\"agree_to_coc\":true,\"type\":0,\"start_date\":\"2016-06-03T13:30:00Z\",\"created_at\":\"2016-04-11T18:13:57Z\",\"updated_at\":\"2016-05-15T20:29:48Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"comments\":null,\"likes\":0,\"event_id\":28,\"speakers\":[{\"id\":409,\"name\":\"Brent Vatne\",\"twitter\":\"notbrent\",\"github\":\"brentvatne\",\"url\":\"http://brentvatne.ca/\",\"past_experience\":\"\",\"email\":\"brent@exponentjs.com\",\"bio\":\"Front-end web/mobile developer working on Exponent (exponentjs.com) and one of React Native top committers.\",\"uuid\":\"825c481a-d443-4336-8136-a3c9d69ecb6a\",\"status\":1,\"avatar_url\":\"https://api.eventlama.com/avatars/events/28/speakers/409/avatar.png\",\"travel_costs\":false,\"agree_to_coc\":false,\"created_at\":\"2016-04-11T18:13:57Z\",\"updated_at\":\"2016-04-11T18:13:57Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"display_order\":0,\"event_id\":28,\"proposal_id\":389}]},{\"id\":390,\"title\":\"GraphQL Future\",\"description\":\"nc\",\"length\":30,\"tags\":\"\",\"status\":1,\"uuid\":\"\",\"agree_to_coc\":true,\"type\":0,\"start_date\":\"2016-06-03T14:00:00Z\",\"created_at\":\"2016-04-11T18:17:01Z\",\"updated_at\":\"2016-04-11T18:19:28Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"comments\":null,\"likes\":0,\"event_id\":28,\"speakers\":[{\"id\":410,\"name\":\"Lee Byron\",\"twitter\":\"leeb\",\"github\":\"leebyron\",\"url\":\"\",\"past_experience\":\"\",\"email\":\"leeb@fb.com\",\"bio\":\"Making things at Facebook since 2008: React, GraphQL, Immutable.js, Mobile, JavaScript.\",\"uuid\":\"f6fc737f-4146-4d29-bae8-240e9d462b23\",\"status\":1,\"avatar_url\":\"https://api.eventlama.com/avatars/events/28/speakers/410/avatar.png\",\"travel_costs\":false,\"agree_to_coc\":false,\"created_at\":\"2016-04-11T18:17:01Z\",\"updated_at\":\"2016-04-11T18:17:01Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"display_order\":0,\"event_id\":28,\"proposal_id\":390},{\"id\":411,\"name\":\"Laney Kuenzel\",\"twitter\":\"laneykuenzel\",\"github\":\"laneyk\",\"url\":\"http://www.slideshare.net/LaneyKuenzel\",\"past_experience\":\"\",\"email\":\"laney@fb.com\",\"bio\":\"Software engineer at Facebook Boston working on subscriptions in GraphQL.\",\"uuid\":\"6483e8e2-5ae9-48a2-a2b7-ac61eda824f6\",\"status\":1,\"avatar_url\":\"https://api.eventlama.com/avatars/events/28/speakers/411/avatar.png\",\"travel_costs\":false,\"agree_to_coc\":false,\"created_at\":\"2016-04-11T18:18:42Z\",\"updated_at\":\"2016-04-11T18:18:42Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"display_order\":0,\"event_id\":28,\"proposal_id\":0}]},{\"id\":398,\"title\":\"Coffee Break\",\"description\":\"Socialize, have some coffee or other drinks.\",\"length\":30,\"tags\":\"\",\"status\":1,\"uuid\":\"\",\"agree_to_coc\":false,\"type\":2,\"start_date\":\"2016-06-03T14:30:00Z\",\"created_at\":\"2016-04-11T18:31:19Z\",\"updated_at\":\"2016-04-12T00:31:17Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"comments\":null,\"likes\":0,\"event_id\":28,\"speakers\":null},{\"id\":200,\"title\":\"Progressive enhancement for mobile apps: exploring the continuum between web apps and React Native\",\"description\":\"Rather than looking at web apps and React Native as two separate technologies that mobile developers have to choose between, these approaches can be seen as part of a continuum that allows for progressive enhancement. It should be possible to build apps from a shared codebase that work out of the box on both desktop and mobile devices, but that can be iterated on to get you all the way to a fully native user experience for the parts where this makes sense.\\n\\nThe React programming model is especially suited for this, both because of its focus on composability, and because it has shown that a JavaScript UI framework does not have to be dependent on the DOM. This talk will explore how this model makes it possible to reuse components between web and native platforms, and may even allow for ways to seamlessly mix native views and web elements within a single component tree. It will also discuss ongoing work on establishing a common API surface for accessing device-native features.\",\"length\":30,\"tags\":\"reactjs, reactnative, mobile, cordova\",\"status\":1,\"uuid\":\"\",\"agree_to_coc\":false,\"type\":0,\"start_date\":\"2016-06-03T15:00:00Z\",\"created_at\":\"2016-01-18T16:20:47Z\",\"updated_at\":\"2016-04-12T00:47:37Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"comments\":null,\"likes\":0,\"event_id\":28,\"speakers\":[{\"id\":205,\"name\":\"Martijn Walraven\",\"twitter\":\"martijnwalraven\",\"github\":\"martijnwalraven\",\"url\":\"\",\"past_experience\":\"https://www.youtube.com/watch?v=fHbmqTiTKRg\",\"email\":\"martijnwalraven@meteor.com\",\"bio\":\"Martijn Walraven is a core developer at Meteor Development Group, where he works on mobile support for the Meteor JavaScript app platform, including the Cordova integration. He is also the creator of Meteor iOS, which integrates native iOS apps with Meteor.\",\"uuid\":\"0385ebbd-31ef-47e1-98cf-6ceb41841987\",\"status\":1,\"avatar_url\":\"https://api.eventlama.com/avatars/events/28/speakers/205/avatar.png\",\"travel_costs\":true,\"agree_to_coc\":true,\"created_at\":\"2016-01-18T16:20:47Z\",\"updated_at\":\"2016-01-18T17:24:56Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"display_order\":0,\"event_id\":28,\"proposal_id\":200}]},{\"id\":405,\"title\":\"Q\\u0026A Panel\",\"description\":\"This is your opportunity to ask questions to the team. Use the tag #AskReactEu on twitter and we'll forward them your question.\",\"length\":60,\"tags\":\"\",\"status\":1,\"uuid\":\"\",\"agree_to_coc\":false,\"type\":6,\"start_date\":\"2016-06-03T15:30:00Z\",\"created_at\":\"2016-04-11T18:39:10Z\",\"updated_at\":\"2016-04-12T00:49:23Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"comments\":null,\"likes\":0,\"event_id\":28,\"speakers\":null},{\"id\":399,\"title\":\"Drink up\",\"description\":\"Have a last drink before leaving.\",\"length\":120,\"tags\":\"\",\"status\":1,\"uuid\":\"\",\"agree_to_coc\":false,\"type\":9,\"start_date\":\"2016-06-03T16:30:00Z\",\"created_at\":\"2016-04-11T18:31:36Z\",\"updated_at\":\"2016-04-11T18:48:02Z\",\"deleted_at\":\"0001-01-01T00:00:00Z\",\"comments\":null,\"likes\":0,\"event_id\":28,\"speakers\":null}],\"DiamondSponsors\":[{\"Id\":12746,\"Name\":\"Rangle.io\",\"Description\":\"Rangle.io is North America's leading next-generation full-stack JavaScript design and development firm. Dedicated to well-crafted responsive web and mobile applications, we only work with modern JavaScript, HTML5, and CSS. Our specialities include Angular, React, Node, Ionic, Meteor, Backbone and other modern JavaScript technologies. As strong functional programming advocates, we lean towards functional reactive programming (FRP) for more complex applications. We are a pioneer in Lean UX and our integrated Agile design and development methodologies allow us to start delivering value quickly and continuously, enabling our clients to quickly test and validate their features and business model on an ongoing basis. With over two dozen modern JavaScript projects delivered in the last two years, we are the partner of choice for companies starting a new project or migrating to modern HTML5 web and mobile applications.\",\"Url\":\"http://rangle.io/\",\"LogoUrl\":\"https://api.eventlama.com/events/28/purchases/12746/logo.png\"},{\"Id\":14386,\"Name\":\"\",\"Description\":\"\",\"Url\":\"\",\"LogoUrl\":\"https://api.eventlama.com/events/28/purchases/14386/logo.png\"}],\"PlatinumSponsors\":null,\"GoldSponsors\":[{\"Id\":10166,\"Name\":\"Red Badger\",\"Description\":\"Red Badger is a creative software workshop in East London. We love to craft. We love to innovate. And more than anything, we love to create beautiful, compelling experiences built around robust technologies. We work for clients such as Fortnum \\u0026 Mason, BSkyB, Tesco and the BBC. We love React.js and run the brilliant React meetup in London.\",\"Url\":\"http://red-badger.com/\",\"LogoUrl\":\"https://api.eventlama.com/events/28/purchases/10166/logo.png\"},{\"Id\":12160,\"Name\":\"Automattic\",\"Description\":\"Automattic is a distributed company, democratizing publishing and development. We are the people behind WordPress.com, which serves more than 15.8 billion pages a month, as well as a host of other popular services, such as Akismet, Jetpack, and VaultPress. We are strong believers in Open Source, and the vast majority of our work is available under licenses like the GPL. Our team members hail from nearly every continent and 36 countries around the world. We are hiring! Learn more at http://automattic.com.\",\"Url\":\"http://automattic.com/\",\"LogoUrl\":\"https://api.eventlama.com/events/28/purchases/12160/logo.png\"},{\"Id\":13734,\"Name\":\"Shoutem\",\"Description\":\"Shoutem's mission is to supercharge React Native development. 80% of the app development is boilerplate. Let us handle, while you focus on developing the unique parts of your app. Use over 20+ open sourced extensions written 100% in React Native. Modify them or write your own from scratch.\",\"Url\":\"http://shoutem.github.io/\",\"LogoUrl\":\"https://api.eventlama.com/events/28/purchases/13734/logo.png\"},{\"Id\":13747,\"Name\":\"Coursio\",\"Description\":\"We are refactoring education to be bidirectional using the best unidirectional data flow library out there.\",\"Url\":\"http://coursio.com/\",\"LogoUrl\":\"https://api.eventlama.com/events/28/purchases/13747/logo.png\"},{\"Id\":14242,\"Name\":\"Zalando SE\",\"Description\":\"Zalando is transforming from an e-commerce company into a multi-service platform that provides fashion as a service. We make it our mission to imagine and predict the infinite points of interaction between fashion and people - and develop the technology to make them possible. Our 1000+ technologists build most of our products in-house and open source, from our logistics software to our mobile applications.\",\"Url\":\"https://tech.zalando.com/\",\"LogoUrl\":\"https://api.eventlama.com/events/28/purchases/14242/logo.png\"},{\"Id\":14342,\"Name\":\"Heroku\",\"Description\":\"Heroku, a Salesforce company and industry pioneer in platform as a service (PaaS), enables developers to build and run applications entirely in the cloud, without the need to purchase or maintain any servers or software. With Heroku you can focus on your app, not your infrastructure.\",\"Url\":\"https://www.heroku.com\",\"LogoUrl\":\"https://api.eventlama.com/events/28/purchases/14342/logo.png\"},{\"Id\":14563,\"Name\":\"Monaca Onsen UI\",\"Description\":\"Onsen UI bundles a rich collection of React Components and supports flat (iOS) and Material Design (Android) equally, giving a native look and feel to hybrid apps. It is part of the Monaca Cloud Platform.\",\"Url\":\"https://monaca.io/\",\"LogoUrl\":\"https://api.eventlama.com/events/28/purchases/14563/logo.png\"}],\"SilverSponsors\":[{\"Id\":13743,\"Name\":\"Ekino\",\"Description\":\"Understand and analyse business expectations.\\n\\nBuild and enhance customer experiences through innovation. Integrate cutting-edge technologies into our client’s information systems: this is the new model of agency we established in order to address digital transformation issues.\\n\\nEkino develops and industrializes your digital services.  We are a team of 200 digital enthusiasts, part of the Havas Group, supporting businesses in their digital initiatives from ideation to realization. It is because we all share the same culture that we successfully design, develop and industrialize all kinds of digital services. From international groups, such as SFR, Renault or the Canal Group, to startups, we have always met our challenges with the same passion for what we do: enable our clients to make the best use of digital technology.\",\"Url\":\"http://www.ekino.com/\",\"LogoUrl\":\"https://api.eventlama.com/events/28/purchases/13743/logo.png\"}],\"BronzeSponsors\":[{\"Id\":10495,\"Name\":\"bitcrowd\",\"Description\":\"Bitcrowd provides quality software development for startups in every livecycle. Clients hire us because we bring our experience, skill and passion to their project. We give advice, conceptualise, design and implement your application using state-of-the-art technologies likeRails and ReactJS.\",\"Url\":\"http://bitcrowd.net/\",\"LogoUrl\":\"https://api.eventlama.com/events/28/purchases/10495/logo.png\"},{\"Id\":13353,\"Name\":\"JoliCode\",\"Description\":\"JoliCode is a French company based in Paris, with a high level of expertise in developing high quality web and mobile projects. Our goal is to help improve the level of quality of the Web and mobile projects of our clients.\\n\\nOur main domains of expertise include :\\n\\nAudit and consulting: we help our clients in fixing architecture problems or performance, scalability and platform optimization issues, and can run mobile application or website audits;\\nArchitecture and expertise: we can deliver team support/coaching during projects initialization or later in projects lifecycles, from an organizational or purely technical perspective;\\nDevelopment: we can build ourselves your whole stacks, from the technical specifications to the production;\\nTraining courses: we offer trainings for all the technologies we use in our projects like PHP, Symfony, Elasticsearch, Appcelerator Titanium, JavaScript, Docker,...\\n\\nWe are eager to integrate new open source tools in our daily work, and fell in love with \",\"Url\":\"http://jolicode.com/\",\"LogoUrl\":\"https://api.eventlama.com/events/28/purchases/13353/logo.png\"}],\"BasicSponsors\":null,\"PartnersSponsors\":[{\"Id\":14617,\"Name\":\"Facebook\",\"Description\":\"https://www.facebook.com/careers\",\"Url\":\"https://www.facebook.com/careers\",\"LogoUrl\":\"https://api.eventlama.com/events/28/purchases/14617/logo.png\"},{\"Id\":14618,\"Name\":\"EventLama\",\"Description\":\"EventLama is built and used by people who run big tech events. We know it's a lot of work, you need to build a web site, a mobile app, add speakers one by one, set up a call for paper, manage sponsors keep track of social media, manage orders, tickets, refunds, leads and more! \\nWe make all these daunting tasks just one click away so you can relax and spend more time focusing on making your attendee experience awesome with great innovative features that will make your customers love you.\",\"Url\":\"https://eventlama.com/\",\"LogoUrl\":\"https://api.eventlama.com/events/28/purchases/14618/logo.png\"},{\"Id\":14619,\"Name\":\"Mozilla\",\"Description\":\"https://www.mozilla.org/\",\"Url\":\"https://www.mozilla.org/\",\"LogoUrl\":\"https://api.eventlama.com/events/28/purchases/14619/logo.png\"},{\"Id\":14620,\"Name\":\"exponent.js\",\"Description\":\"Exponent brings together the best of web (development speed, fast iteration cycles, easy deploys, automatic cross-platform support, and simple sharing with URLs) and the performance and user experience of native apps.\\n\\nWith Exponent, you can write iOS and Android experiences in JavaScript using React Native, without Xcode or Android Studio, and share them with anyone else who has the app in a single click.\",\"Url\":\"https://exponentjs.com/\",\"LogoUrl\":\"https://api.eventlama.com/events/28/purchases/14620/logo.png\"},{\"Id\":14621,\"Name\":\"Thinkmill\",\"Description\":\"http://www.thinkmill.com.au/\",\"Url\":\"http://www.thinkmill.com.au/\",\"LogoUrl\":\"https://api.eventlama.com/events/28/purchases/14621/logo.png\"},{\"Id\":14622,\"Name\":\"socialtables\",\"Description\":\"The #1 software for planners and properties to work together online\",\"Url\":\"https://www.socialtables.com/\",\"LogoUrl\":\"https://api.eventlama.com/events/28/purchases/14622/logo.png\"},{\"Id\":14623,\"Name\":\"x-team\",\"Description\":\"X-Team is trusted by the world's leading brands, providing high-quality developers when you need them most since 2006.\",\"Url\":\"http://x-team.com/\",\"LogoUrl\":\"https://api.eventlama.com/events/28/purchases/14623/logo.png\"},{\"Id\":14624,\"Name\":\"RemoteDev\",\"Description\":\"Remote debugging even on production.\",\"Url\":\"http://remotedev.io/\",\"LogoUrl\":\"https://api.eventlama.com/events/28/purchases/14624/logo.png\"}],\"ApiRootURL\":\"https://api.eventlama.com/\"}\n"
  },
  {
    "path": "src/js/stores/default.secret.json",
    "content": "{\n  \"main\": {\n    \"id\": 0,\n    \"token\": \"qwerty123\"\n  },\n  \"hackathon\": {\n    \"id\": 1,\n    \"token\": \"qwerty234\"\n  },\n  \"workshop\": {\n    \"id\": 2,\n    \"token\": \"qwerty345\"\n  }\n}\n"
  },
  {
    "path": "src/js/touchstone/Container.js",
    "content": "var Container = require('react-container');\n\nexport default Container;\n"
  },
  {
    "path": "src/js/touchstone/ErrorView.js",
    "content": "var React = require('react');\nvar Container = require('react-container');\n\nvar ErrorView = React.createClass({\n\trender () {\n\t\treturn (\n\t\t\t<Container fill className=\"View ErrorView\">\n\t\t\t\t{this.props.children}\n\t\t\t</Container>\n\t\t);\n\t}\n});\n\nexport default ErrorView;\n"
  },
  {
    "path": "src/js/touchstone/Icon.js",
    "content": "var React = require('react');\n\nvar Icon = React.createClass({\n\trender () {\n\t\treturn (\n\t\t\t<div className=\"Icon\">\n\t\t\t\t{this.props.children}\n\t\t\t</div>\n\t\t);\n\t}\n});\n\nexport default Icon;\n"
  },
  {
    "path": "src/js/touchstone/LabelInput.js",
    "content": "var React = require('react/addons');\nvar blacklist = require('blacklist');\nvar classnames = require('classnames');\n\nmodule.exports = React.createClass({\n\tdisplayName: 'LabelInput',\n\n\tpropTypes: {\n\t\talignTop: React.PropTypes.bool,\n\t\tclassName: React.PropTypes.string,\n\t\tdisabled: React.PropTypes.bool,\n\t\tfirst: React.PropTypes.bool,\n\t\tlabel: React.PropTypes.string,\n\t\treadOnly: React.PropTypes.bool,\n\t\tvalue: React.PropTypes.string\n\t},\n\n\tgetDefaultProps () {\n\t\treturn {\n\t\t\ttype: 'text',\n\t\t\treadOnly: false\n\t\t};\n\t},\n\n\trender () {\n\t\tvar className = classnames(this.props.className, 'list-item', 'field-item', {\n\t\t\t'align-top': this.props.alignTop,\n\t\t\t'is-first': this.props.first,\n\t\t\t'u-selectable': this.props.disabled\n\t\t});\n\n\t\tvar props = blacklist(this.props, 'alignTop', 'children', 'first', 'readOnly');\n\t\tvar renderInput = this.props.readOnly ? (\n\t\t\t<div className=\"field u-selectable\">{this.props.value}</div>\n\t\t) : (\n\t\t\t<input className=\"field\" {...props}/>\n\t\t);\n\n\t\treturn (\n\t\t\t<label className={className}>\n\t\t\t\t<div className=\"item-inner\">\n\t\t\t\t\t<div className=\"field-label\">{this.props.label}</div>\n\t\t\t\t\t<div className=\"field-control\">\n\t\t\t\t\t\t{renderInput}\n\t\t\t\t\t\t{this.props.children}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</label>\n\t\t);\n\t}\n});\n"
  },
  {
    "path": "src/js/touchstone/LabelTextarea.js",
    "content": "var React = require('react/addons');\n\nvar blacklist = require('blacklist')\nvar classnames = require('classnames');\n\nmodule.exports = React.createClass({\n\tdisplayName: 'LabelTextarea',\n\n\tpropTypes: {\n\t\tclassName: React.PropTypes.string,\n\t\tdisabled: React.PropTypes.bool,\n\t\tfirst: React.PropTypes.bool,\n\t\tlabel: React.PropTypes.string,\n\t\treadOnly: React.PropTypes.bool,\n\t\tvalue: React.PropTypes.string\n\t},\n\n\tgetDefaultProps () {\n\t\treturn {\n\t\t\trows: 3\n\t\t};\n\t},\n\n\trender () {\n\t\tvar className = classnames(this.props.className, 'list-item', 'field-item', 'align-top', {\n\t\t\t'is-first': this.props.first,\n\t\t\t'u-selectable': this.props.disabled\n\t\t});\n\n\t\tvar props = blacklist(this.props, 'children', 'className', 'disabled', 'first', 'label', 'readOnly')\n\n\t\tvar renderInput = this.props.readOnly ? (\n\t\t\t<div className=\"field u-selectable\">{this.props.value}</div>\n\t\t) : (\n\t\t\t<textarea {...props} className=\"field\" />\n\t\t);\n\n\t\treturn (\n\t\t\t<div className={className}>\n\t\t\t\t<label className=\"item-inner\">\n\t\t\t\t\t<div className=\"field-label\">{this.props.label}</div>\n\t\t\t\t\t<div className=\"field-control\">\n\t\t\t\t\t\t{renderInput}\n\t\t\t\t\t\t{this.props.children}\n\t\t\t\t\t</div>\n\t\t\t\t</label>\n\t\t\t</div>\n\t\t);\n\t}\n});\n"
  },
  {
    "path": "src/js/touchstone/Link.js",
    "content": "var blacklist = require('blacklist');\nvar React = require('react');\nvar Tappable = require('react-tappable');\nvar Transitions = require('./Transitions');\n\nvar Link = React.createClass({\n\tmixins: [Transitions],\n\tpropTypes: {\n\t\tchildren: React.PropTypes.any,\n\t\toptions: React.PropTypes.object,\n\t\ttransition: React.PropTypes.string,\n\t\tviewProps: React.PropTypes.any\n\t},\n\n\tdoTransition () {\n\t\tvar options = Object.assign({ viewProps: this.props.viewProps, transition: this.props.transition }, this.props.options);\n\t\tconsole.info('Link to \"' + this.props.to + '\" using transition \"' + this.props.transition + '\"' + ' with props ', this.props.viewProps);\n\t\tthis.transitionTo(this.props.to, options);\n\t},\n\n\trender () {\n\t\tvar tappableProps = blacklist(this.props, 'children', 'options', 'transition', 'viewProps');\n\n\t\treturn (\n\t\t\t<Tappable onTap={this.doTransition} {...tappableProps}>\n\t\t\t\t{this.props.children}\n\t\t\t</Tappable>\n\t\t);\n\t}\n});\n\nexport default Link;\n"
  },
  {
    "path": "src/js/touchstone/NavigationBar.js",
    "content": "var classNames = require('classnames');\nvar React = require('react/addons');\nvar Tappable = require('react-tappable');\nvar Transition = React.addons.CSSTransitionGroup;\n\nvar defaultControllerState = {\n\tdirection: 0,\n\tfade: false,\n\tleftArrow: false,\n\tleftButtonDisabled: false,\n\tleftIcon: '',\n\tleftLabel: '',\n\tleftAction: null,\n\trightArrow: false,\n\trightButtonDisabled: false,\n\trightIcon: '',\n\trightLabel: '',\n\trightAction: null,\n\ttitle: ''\n};\n\nfunction newState (from) {\n\tvar ns = Object.assign({}, defaultControllerState);\n\tif (from) Object.assign(ns, from);\n\tdelete ns.name; // may leak from props\n\treturn ns;\n}\n\nvar NavigationBar = React.createClass({\n\tcontextTypes: {\n\t\tapp: React.PropTypes.object\n\t},\n\tpropTypes: {\n\t\tname: React.PropTypes.string\n\t},\n\tgetInitialState () {\n\t\treturn newState(this.props);\n\t},\n\tcomponentDidMount () {\n\t\tif (this.props.name) {\n\t\t\tthis.context.app.navigationBars[this.props.name] = this;\n\t\t}\n\t},\n\tcomponentWillUnmount () {\n\t\tif (this.props.name) {\n\t\t\tdelete this.context.app.navigationBars[this.props.name];\n\t\t}\n\t},\n\tcomponentWillReceiveProps (nextProps) {\n\t\tthis.setState(newState(nextProps));\n\t\tif (nextProps.name !== this.props.name) {\n\t\t\tif (nextProps.name) {\n\t\t\t\tthis.context.app.navigationBars[nextProps.name] = this;\n\t\t\t}\n\t\t\tif (this.props.name) {\n\t\t\t\tdelete this.context.app.navigationBars[this.props.name];\n\t\t\t}\n\t\t}\n\t},\n\tupdate (state) {\n\t\tstate = newState(state);\n\t\t// console.info('Updating NavigationBar ' + this.props.name, state);\n\t\tthis.setState(newState(state));\n\t},\n\tupdateWithTransition (state, transition) {\n\t\tstate = newState(state);\n\t\tif (transition === ('show-from-right' || 'reveal-from-left')) {\n\t\t\tstate.direction = 1;\n\t\t} else if (transition === ('reveal-from-right' || 'show-from-left')) {\n\t\t\tstate.direction = -1;\n\t\t} else if (transition === 'fade') {\n\t\t\tstate.fade = true;\n\t\t}\n\t\t// console.info('Updating NavigationBar ' + this.props.name + ' with transition ' + transition, state);\n\t\tthis.setState(state);\n\t},\n\n\trenderLeftButton () {\n\t\tvar className = classNames('NavigationBarLeftButton', {\n\t\t\t'has-icon': this.state.leftArrow || this.state.leftIcon\n\t\t});\n\n\t\treturn (\n\t\t\t<Tappable onTap={this.state.leftAction} className={className} disabled={this.state.leftButtonDisabled} component=\"button\">\n\t\t\t\t{this.renderLeftArrow()}\n\t\t\t\t{this.renderLeftIcon()}\n\t\t\t\t{this.renderLeftLabel()}\n\t\t\t</Tappable>\n\t\t);\n\t},\n\trenderLeftArrow () {\n\t\tvar transitionName = 'NavigationBarTransition-Instant';\n\t\tif (this.state.fade || this.state.direction) {\n\t\t\ttransitionName = 'NavigationBarTransition-Fade';\n\t\t}\n\n\t\tvar arrow = this.state.leftArrow ? <span className=\"NavigationBarLeftArrow\" /> : null;\n\n\t\treturn (\n\t\t\t<Transition transitionName={transitionName}>\n\t\t\t\t{arrow}\n\t\t\t</Transition>\n\t\t);\n\t},\n\trenderLeftIcon () {\n\t\tvar transitionName = 'NavigationBarTransition-Instant';\n\t\tif (this.state.fade || this.state.direction) {\n\t\t\ttransitionName = 'NavigationBarTransition-Fade';\n\t\t}\n\t\tvar className = classNames('NavigationBarLeftIcon', this.state.leftIcon);\n\t\tvar icon = this.state.leftIcon ? <span className={className} /> : null;\n\n\t\treturn (\n\t\t\t<Transition transitionName={transitionName}>\n\t\t\t\t{icon}\n\t\t\t</Transition>\n\t\t);\n\t},\n\trenderLeftLabel () {\n\t\tvar transitionName = 'NavigationBarTransition-Instant';\n\t\tif (this.state.fade) {\n\t\t\ttransitionName = 'NavigationBarTransition-Fade';\n\t\t} else if (this.state.direction > 0) {\n\t\t\ttransitionName = 'NavigationBarTransition-Forwards';\n\t\t} else if (this.state.direction < 0) {\n\t\t\ttransitionName = 'NavigationBarTransition-Backwards';\n\t\t}\n\n\t\treturn (\n\t\t\t<Transition transitionName={transitionName}>\n\t\t\t\t<span key={Date.now()} className=\"NavigationBarLeftLabel\">{this.state.leftLabel}</span>\n\t\t\t</Transition>\n\t\t);\n\t},\n\trenderTitle () {\n\t\tvar title = this.state.title ? <span key={Date.now()} className=\"NavigationBarTitle\">{this.state.title}</span> : null;\n\t\tvar transitionName = 'NavigationBarTransition-Instant';\n\t\tif (this.state.fade) {\n\t\t\ttransitionName = 'NavigationBarTransition-Fade';\n\t\t} else if (this.state.direction > 0) {\n\t\t\ttransitionName = 'NavigationBarTransition-Forwards';\n\t\t} else if (this.state.direction < 0) {\n\t\t\ttransitionName = 'NavigationBarTransition-Backwards';\n\t\t}\n\n\t\treturn (\n\t\t\t<Transition transitionName={transitionName}>\n\t\t\t\t{title}\n\t\t\t</Transition>\n\t\t);\n\t},\n\trenderRightButton () {\n\t\tvar transitionName = 'NavigationBarTransition-Instant';\n\t\tif (this.state.fade || this.state.direction) {\n\t\t\ttransitionName = 'NavigationBarTransition-Fade';\n\t\t}\n\t\tvar button = (this.state.rightIcon || this.state.rightLabel) ? (\n\t\t\t<Tappable key={Date.now()} onTap={this.state.rightAction} className=\"NavigationBarRightButton\" disabled={this.state.rightButtonDisabled} component=\"button\">\n\t\t\t\t{this.renderRightLabel()}\n\t\t\t\t{this.renderRightIcon()}\n\t\t\t</Tappable>\n\t\t) : null;\n\t\treturn (\n\t\t\t<Transition transitionName={transitionName}>\n\t\t\t\t{button}\n\t\t\t</Transition>\n\t\t);\n\t},\n\trenderRightIcon () {\n\t\tif (!this.state.rightIcon) return null;\n\n\t\tvar className = classNames('NavigationBarRightIcon', this.state.rightIcon);\n\n\t\treturn <span className={className} />;\n\t},\n\trenderRightLabel () {\n\t\treturn this.state.rightLabel ? <span key={Date.now()} className=\"NavigationBarRightLabel\">{this.state.rightLabel}</span> : null;\n\t},\n\trender () {\n\t\tvar className = classNames('NavigationBar', {\n\t\t\t'has-left-arrow': this.state.leftArrow,\n\t\t\t'has-left-icon': this.state.leftIcon,\n\t\t\t'has-left-label': this.state.leftLabel,\n\t\t\t'has-right-icon': this.state.rightIcon,\n\t\t\t'has-right-label': this.state.rightLabel\n\t\t});\n\t\treturn (\n\t\t\t<div className={className}>\n\t\t\t\t{this.renderLeftButton()}\n\t\t\t\t{this.renderTitle()}\n\t\t\t\t{this.renderRightButton()}\n\t\t\t</div>\n\t\t);\n\t}\n});\n\n/*\nfunction createController () {\n\tvar state = newState();\n\tvar listeners = [];\n\treturn {\n\t\tupdate (ns) {\n\t\t\tstate = newState(ns);\n\t\t\tlisteners.forEach(fn => fn());\n\t\t},\n\t\tgetState () {\n\t\t\treturn state;\n\t\t},\n\t\taddListener (fn) {\n\t\t\tlisteners.push(fn);\n\t\t},\n\t\tremoveListener (fn) {\n\t\t\tlisteners = listeners.filter(i => fn !== i);\n\t\t}\n\t};\n}\n*/\n\nexport default NavigationBar;\n"
  },
  {
    "path": "src/js/touchstone/Switch.js",
    "content": "var classnames = require('classnames');\nvar React = require('react');\nvar Tappable = require('react-tappable');\n\nmodule.exports = React.createClass({\n\tdisplayName: 'Switch',\n\n\tpropTypes: {\n\t\tclassName: React.PropTypes.string,\n\t\ton: React.PropTypes.bool,\n\t\tonTap: React.PropTypes.func,\n\t\ttype: React.PropTypes.string\n\t},\n\n\tgetDefaultProps () {\n\t\treturn {\n\t\t\ttype: 'default'\n\t\t};\n\t},\n\n\trender () {\n\t\tvar className = classnames('switch', 'switch-' + this.props.type, { 'on': this.props.on });\n\n\t\treturn (\n\t\t\t<Tappable onTap={this.props.onTap} className={className} component=\"label\">\n\t\t\t\t<div className=\"track\">\n\t\t\t\t\t<div className=\"handle\" />\n\t\t\t\t</div>\n\t\t\t</Tappable>\n\t\t);\n\t}\n});\n"
  },
  {
    "path": "src/js/touchstone/Tabs.js",
    "content": "var blacklist = require('blacklist');\nvar classnames = require('classnames');\nvar React = require('react');\nvar Tappable = require('react-tappable');\n\nexport var Navigator = React.createClass({\n\trender () {\n\t\treturn (\n\t\t\t<div className=\"Tabs-Navigator-wrapper\">\n\t\t\t\t<div className=\"Tabs-Navigator\">\n\t\t\t\t\t{React.Children.map(this.props.children, (tab) => {\n\t\t\t\t\t\treturn React.cloneElement(tab, {\n\t\t\t\t\t\t\tonSelect: this.props.onChange,\n\t\t\t\t\t\t\tnavigatorValue: this.props.value\n\t\t\t\t\t\t});\n\t\t\t\t\t})}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n});\n\nexport var Tab = React.createClass({\n\tcontextTypes: {\n\t\ttabNavigator: React.PropTypes.object\n\t},\n\tonSelect () {\n\t\tvar tab = blacklist(this.props, 'children');\n\t\tthis.props.onSelect(tab);\n\t},\n\trender () {\n\t\tvar isCurrent = this.props.navigatorValue === this.props.value;\n\t\tvar className = classnames('Tabs-Tab', {\n\t\t\t'is-selected': isCurrent\n\t\t});\n\t\treturn (\n\t\t\t<Tappable onTap={this.props.onSelect && this.onSelect} className={className}>\n\t\t\t\t{this.props.children}\n\t\t\t</Tappable>\n\t\t);\n\t}\n});\n\nexport var Label = React.createClass({\n\trender () {\n\t\treturn (\n\t\t\t<div className=\"Tabs-Label\">\n\t\t\t\t{this.props.children}\n\t\t\t</div>\n\t\t);\n\t}\n});\n"
  },
  {
    "path": "src/js/touchstone/Transitions.js",
    "content": "var React = require('react');\n\nvar Transitions = {\n\tcontextTypes: {\n\t\tapp: React.PropTypes.object\n\t},\n\ttransitionTo (view, opts) {\n\t\tvar vm = '__default';\n\t\tview = view.split(':');\n\t\tif (view.length > 1) {\n\t\t\tvm = view.shift();\n\t\t}\n\t\tview = view[0];\n\t\tthis.context.app.viewManagers[vm].transitionTo(view, opts);\n\t}\n};\n\nexport default Transitions;\n"
  },
  {
    "path": "src/js/touchstone/View.js",
    "content": "var React = require('react');\n\nvar View = React.createClass({\n\tpropTypes: {\n\t\tcomponent: React.PropTypes.func.isRequired,\n\t\tname: React.PropTypes.string.isRequired\n\t},\n\trender () {\n\t\tthrow \"TouchstoneJS <View> should not be rendered directly.\";\n\t}\n});\n\nexport default View;\n"
  },
  {
    "path": "src/js/touchstone/ViewManager.js",
    "content": "var blacklist = require('blacklist');\nvar classNames = require('classnames');\nvar ErrorView = require('./ErrorView');\nvar React = require('react/addons');\nvar Transition = React.addons.CSSTransitionGroup;\n\nfunction createViewsFromChildren (children) {\n\tvar views = {};\n\tReact.Children.forEach(children, function (view) {\n\t\tviews[view.props.name] = view;\n\t});\n\treturn views;\n}\n\nvar ViewContainer = React.createClass({\n\tstatics: {\n\t\tshouldFillVerticalSpace: true\n\t},\n\trender () {\n\t\treturn <div className={this.props.className}>{this.props.children}</div>;\n\t}\n});\n\nvar ViewManager = React.createClass({\n\tstatics: {\n\t\tshouldFillVerticalSpace: true\n\t},\n\tcontextTypes: {\n\t\tapp: React.PropTypes.object.isRequired\n\t},\n\tpropTypes: {\n\t\tname: React.PropTypes.string\n\t},\n\tgetDefaultProps () {\n\t\tname: '__default'\n\t},\n\tgetInitialState () {\n\t\treturn {\n\t\t\tviews: createViewsFromChildren(this.props.children),\n\t\t\tcurrentView: this.props.defaultView,\n\t\t\toptions: {}\n\t\t}\n\t},\n\tcomponentDidMount () {\n\t\tthis.context.app.viewManagers[this.props.name] = this;\n\t},\n\tcomponentWillUnmount () {\n\t\tdelete this.context.app.viewManagers[this.props.name];\n\t},\n\tcomponentWillReceiveProps (nextProps) {\n\t\tthis.setState({\n\t\t\tviews: createViewsFromChildren(this.props.children)\n\t\t});\n\t\tif (nextProps.name !== this.props.name) {\n\t\t\tthis.context.app.viewManagers[nextProps.name] = this;\n\t\t\tdelete this.context.app.viewManagers[this.props.name];\n\t\t}\n\t\tif (nextProps.currentView && nextProps.currentView !== this.state.currentView) {\n\t\t\tthis.transitionTo(nextProps.currentView, { viewProps: nextProps.viewProps });\n\t\t}\n\t},\n\ttransitionTo (viewKey, options) {\n\t\tif (typeof options === 'string') {\n\t\t\toptions = { transition: options };\n\t\t}\n\t\tif (!options) options = {};\n\t\tthis.activeTransitionOptions = options;\n\t\tthis.context.app.viewManagerInTransition = this;\n\t\tthis.props.onViewChange && this.props.onViewChange(viewKey);\n\t\tthis.setState({\n\t\t\tcurrentView: viewKey,\n\t\t\toptions: options\n\t\t}, function() {\n\t\t\tdelete this.activeTransitionOptions;\n\t\t\tdelete this.context.app.viewManagerInTransition;\n\t\t});\n\t},\n\trenderViewContainer () {\n\t\tvar viewKey = this.state.currentView;\n\t\tif (!viewKey) {\n\t\t\treturn (\n\t\t\t\t<ErrorView>\n\t\t\t\t\t<span className=\"ErrorView__heading\">ViewManager: {this.props.name}</span>\n\t\t\t\t\t<span className=\"ErrorView__text\">Error: There is no current View.</span>\n\t\t\t\t</ErrorView>\n\t\t\t);\n\t\t}\n\t\tvar view = this.state.views[viewKey];\n\t\tif (!view || !view.props.component) {\n\t\t\treturn (\n\t\t\t\t<ErrorView>\n\t\t\t\t\t<span className=\"ErrorView__heading\">ViewManager: {this.props.name}</span>\n\t\t\t\t\t<span className=\"ErrorView__text\">Error: The Current View ({viewKey}) is invalid.</span>\n\t\t\t\t</ErrorView>\n\t\t\t);\n\t\t}\n\t\tvar options = this.state.options || {};\n\t\tvar viewClassName = classNames('View View--' + viewKey, view.props.className);\n\t\tvar ViewComponent = view.props.component;\n\t\tvar viewProps = blacklist(view.props, 'component', 'className');\n\t\tObject.assign(viewProps, options.viewProps);\n\t\tvar viewElement = <ViewComponent {...viewProps} />;\n\n\t\tif (this.__lastRenderedView !== viewKey) {\n\t\t\t// console.log('initialising view ' + viewKey + ' with options', options);\n\t\t\tif (viewElement.type.navigationBar && viewElement.type.getNavigation) {\n\t\t\t\tvar app = this.context.app;\n\t\t\t\tvar transition = options.transition;\n\t\t\t\tif (app.viewManagerInTransition) {\n\t\t\t\t\ttransition = app.viewManagerInTransition.activeTransitionOptions.transition;\n\t\t\t\t}\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tapp.navigationBars[viewElement.type.navigationBar].updateWithTransition(viewElement.type.getNavigation(viewProps), transition);\n\t\t\t\t}, 0);\n\t\t\t}\n\t\t\tthis.__lastRenderedView = viewKey;\n\t\t}\n\n\t\treturn (\n\t\t\t<ViewContainer className={viewClassName} key={viewKey}>\n\t\t\t\t{viewElement}\n\t\t\t</ViewContainer>\n\t\t);\n\t},\n\trender () {\n\t\tvar className = classNames('ViewManager', this.props.className);\n\t\tvar viewContainer = this.renderViewContainer(this.state.currentView, { viewProps: this.state.currentViewProps });\n\n\t\tvar transitionName = 'view-transition-instant';\n\t\tif (this.state.options.transition) {\n\t\t\t// console.log('applying view transition: ' + this.state.options.transition + ' to view ' + this.state.currentView);\n\t\t\ttransitionName = 'view-transition-' + this.state.options.transition;\n\t\t}\n\t\treturn (\n\t\t\t<Transition transitionName={transitionName} transitionEnter={true} transitionLeave={true} className={className} component=\"div\">\n\t\t\t\t{viewContainer}\n\t\t\t</Transition>\n\t\t);\n\t}\n});\n\nexport default ViewManager;\n"
  },
  {
    "path": "src/js/touchstone/animation.js",
    "content": "var animation = require('tween.js');\nvar React = require('react');\n\nfunction update () {\n\tanimation.update();\n\tif (animation.getAll().length) {\n\t\trequestAnimationFrame(update);\n\t}\n}\n\nfunction scrollToTop (el, options) {\n\toptions = options || {};\n\tvar from = el.scrollTop;\n\tvar duration = Math.min(Math.max(200, from / 2), 350);\n\tif (from > 200) duration = 300;\n\tel.style.webkitOverflowScrolling = 'auto';\n\tel.style.overflow = 'hidden';\n\tvar tween = new animation.Tween({ pos: from })\n\t\t.to({ pos: 0 }, duration)\n\t\t.easing(animation.Easing.Quadratic.Out)\n\t\t.onUpdate(function() {\n\t\t\tel.scrollTop = this.pos;\n\t\t\tif (options.onUpdate) {\n\t\t\t\toptions.onUpdate();\n\t\t\t}\n\t\t})\n\t\t.onComplete(function() {\n\t\t\tel.style.webkitOverflowScrolling = 'touch';\n\t\t\tel.style.overflow = 'scroll';\n\t\t\tif (options.onComplete) options.onComplete();\n\t\t})\n\t\t.start();\n\tupdate();\n\treturn tween;\n}\n\nexports.scrollToTop = scrollToTop;\n\nvar Mixins = exports.Mixins = {};\n\nMixins.ScrollContainerToTop = {\n\tcomponentDidMount () {\n\t\twindow.addEventListener('statusTap', this.scrollContainerToTop);\n\t},\n\tcomponentWillUnmount () {\n\t\twindow.removeEventListener('statusTap', this.scrollContainerToTop);\n\t\tif (this._scrollContainerAnimation) {\n\t\t\tthis._scrollContainerAnimation.stop();\n\t\t}\n\t},\n\tscrollContainerToTop () {\n\t\tif (!this.isMounted() || !this.refs.scrollContainer) return;\n\t\tthis._scrollContainerAnimation = scrollToTop(React.findDOMNode(this.refs.scrollContainer), {\n\t\t\tonComplete: () => { delete this._scrollContainerAnimation }\n\t\t});\n\t}\n};\n"
  },
  {
    "path": "src/js/touchstone/index.js",
    "content": "var React = require('react');\n\nexport var animation = require('./animation');\nexport var Container = require('./Container');\nexport var Icon = require('./Icon');\nexport var LabelInput = require('./LabelInput');\nexport var LabelTextarea = require('./LabelTextarea');\nexport var Link = require('./Link');\nexport var NavigationBar = require('./NavigationBar');\nexport var Switch = require('./Switch');\nexport var Tabs = require('./Tabs');\nexport var Transitions = require('./Transitions');\nexport var View = require('./View');\nexport var ViewManager = require('./ViewManager');\n\nexport function createApp() {\n\tvar app = {\n\t\tnavigationBars: {},\n\t\tviewManagers: {},\n\t\tviews: {}\n\t};\n\t\n\treturn {\n\t\tchildContextTypes: {\n\t\t\tapp: React.PropTypes.object\n\t\t},\n\t\tgetChildContext () {\n\t\t\treturn {\n\t\t\t\tapp: app\n\t\t\t};\n\t\t}\n\t};\n}\n"
  },
  {
    "path": "src/js/views/about.js",
    "content": "var animation = require('../touchstone/animation');\nvar Container = require('react-container');\nvar React = require('react');\nvar Tappable = require('react-tappable');\n\nconst scrollable = Container.initScrollable();\n\nmodule.exports = React.createClass({\n\tdisplayName: 'ViewAbout',\n\tcontextTypes: { dataStore: React.PropTypes.object.isRequired },\n\tmixins: [animation.Mixins.ScrollContainerToTop],\n\n\tstatics: {\n\t\tnavigationBar: 'main',\n\t\tgetNavigation () {\n\t\t\treturn {\n\t\t\t\ttitle: 'About'\n\t\t\t}\n\t\t}\n\t},\n\n\tgetDefaultProps () {\n\t\treturn {\n\t\t\taboutButtonLink: 'http://thinkmill.com.au/',\n\t\t\taboutButtonLabel: 'Learn More'\n\t\t}\n\t},\n\n\thandleButton () {\n\t\twindow.open(this.props.aboutButtonLink, '_blank', 'toolbar=yes,location=no,transitionstyle=coververtical');\n\t},\n\n\trender () {\n\t\tvar settings = this.context.dataStore.getSettings()\n\n\t\treturn (\n\t\t\t<Container scrollable={scrollable} className=\"About\" ref=\"scrollContainer\">\n\t\t\t\t<div className=\"About-section\">\n\t\t\t\t\t<img src={settings.aboutLogo} className=\"About__logo\" />\n\t\t\t\t\t<div className=\"About__heading\">Made by Thinkmill</div>\n\t\t\t\t\t<div className=\"About__subheading\">using these great tools</div>\n\t\t\t\t\t<div className=\"About__tools About__list\">\n\t\t\t\t\t\t<div className=\"About__tool About__list__item\"><img src=\"./img/touchstone-logo.svg\" alt=\"TouchstoneJS\" /></div>\n\t\t\t\t\t\t<div className=\"About__tool About__list__item\"><img src=\"./img/react-logo.svg\" alt=\"React.js\" /></div>\n\t\t\t\t\t\t<div className=\"About__tool About__list__item\"><img src=\"./img/keystone-logo.svg\" alt=\"KeystoneJS\" /></div>\n\t\t\t\t\t\t<div className=\"About__tool About__list__item\"><img src=\"./img/cordova-logo.png\" alt=\"Cordova\" /></div>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div className=\"About__content\" dangerouslySetInnerHTML={{__html: settings.aboutContent }} />\n\t\t\t\t\t<Tappable onTap={this.handleButton} className=\"About__button button\">{this.props.aboutButtonLabel}</Tappable>\n\t\t\t\t</div>\n\t\t\t\t<div className=\"About-section\">\n\t\t\t\t\t<div className=\"About__subheading\">Project Team</div>\n\t\t\t\t\t<div className=\"About__team About__list\">\n\t\t\t\t\t\t<a href=\"https://twitter.com/borisbozic\" className=\"About__team__member About__list__item\">\n\t\t\t\t\t\t\t<img src=\"./img/team/boris-bozic.jpeg\" alt=\"Boris Bozic\" />\n\t\t\t\t\t\t\tBoris\n\t\t\t\t\t\t</a>\n\t\t\t\t\t\t<a href=\"https://twitter.com/DanCuzns\" className=\"About__team__member About__list__item\">\n\t\t\t\t\t\t\t<img src=\"./img/team/daniel-cousens.jpg\" alt=\"Daniel Cousens\" />\n\t\t\t\t\t\t\tDaniel\n\t\t\t\t\t\t</a>\n\t\t\t\t\t\t<a href=\"https://twitter.com/JedWatson\" className=\"About__team__member About__list__item\">\n\t\t\t\t\t\t\t<img src=\"./img/team/jed-watson.png\" alt=\"Jed Watson\" />\n\t\t\t\t\t\t\tJed\n\t\t\t\t\t\t</a>\n\t\t\t\t\t\t<a href=\"https://twitter.com/JossMackison\" className=\"About__team__member About__list__item\">\n\t\t\t\t\t\t\t<img src=\"./img/team/joss-mackison.png\" alt=\"Joss Mackison\" />\n\t\t\t\t\t\t\tJoss\n\t\t\t\t\t\t</a>\n\t\t\t\t\t\t<a href=\"https://twitter.com/mxstbr\" className=\"About__team__member About__list__item\">\n\t\t\t\t\t\t\t<img src=\"./img/team/max-stoiber.jpg\" alt=\"Max Stoiber\" />\n\t\t\t\t\t\t\tMax\n\t\t\t\t\t\t</a>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</Container>\n\t\t);\n\t}\n});\n"
  },
  {
    "path": "src/js/views/announcement.js",
    "content": "var React = require('react')\nvar Container = require('react-container');\n\nvar classnames = require('classnames')\n\nmodule.exports = React.createClass({\n\tpropTypes: {\n\t\ticon: React.PropTypes.string,\n\t\ttext: React.PropTypes.string,\n\t\tsubText: React.PropTypes.string\n\t},\n\n\tgetDefaultProps () {\n\t\treturn {\n\t\t\ticon: 'ion-sad-outline',\n\t\t\ttext: 'Sorry!',\n\t\t\tsubText: \"Something has gone wrong, you may need to update this app to continue...\"\n\t\t}\n\t},\n\n\trender () {\n\t\tvar iconClassName = classnames('ErrorView__icon', this.props.icon);\n\n\t\treturn (\n\t\t\t<Container fill align=\"center\" justify=\"center\" scrollable direction=\"column\" className=\"View ErrorView\">\n\t\t\t\t<div className={iconClassName} />\n\t\t\t\t<div className='ErrorView__heading'>{this.props.text}</div>\n\t\t\t\t<div className='ErrorView__text'>{this.props.subText}</div>\n\t\t\t</Container>\n\t\t);\n\t}\n})\n"
  },
  {
    "path": "src/js/views/event/index.js",
    "content": "var animation = require('../../touchstone/animation');\nvar Container = require('react-container');\nvar Sentry = require('react-sentry');\nvar React = require('react');\nvar Tappable = require('react-tappable');\nvar Social = require('../../mixins/social');\n\nvar PeopleList = require('../../components/PeopleList');\nvar Sponsor = require('./sponsor');\nvar capitalize = require('capitalize');\n\nvar EventEmitter = require('events').EventEmitter;\nvar emitter = new EventEmitter();\n\nvar TIER_PRIORITIES = {\n\t'diamond': 0,\n\t'platinum': 1,\n\t'gold': 2,\n\t'silver': 3,\n\t'bronze': 4,\n\t'basic': 5,\n\t'partner': 6\n};\n\nconst scrollable = Container.initScrollable();\n\nmodule.exports = React.createClass({\n\tdisplayName: 'ViewEvent',\n\tmixins: [Sentry(), Social, animation.Mixins.ScrollContainerToTop],\n\tcontextTypes: {\n\t\tdataStore: React.PropTypes.object.isRequired\n\t},\n\n\tstatics: {\n\t\tnavigationBar: 'main',\n\t\tgetNavigation () {\n\t\t\treturn {\n\t\t\t\tleftIcon: 'ion-android-menu',\n\t\t\t\tleftAction: emitter.emit.bind(emitter, 'navigationBarLeftAction'),\n\t\t\t\ttitle: 'Event'\n\t\t\t};\n\t\t}\n\t},\n\n\tgetInitialState () {\n\t\treturn {\n\t\t\tsearchString: '',\n\t\t\torganisers: this.context.dataStore.getOrganisers(),\n\t\t\tsponsors: this.context.dataStore.getSponsors()\n\t\t};\n\t},\n\n\tcomponentDidMount () {\n\t\tvar body = document.getElementsByTagName('body')[0];\n\t\tvar menuWrapper = document.getElementsByClassName('Tabs-Navigator-wrapper')[0];\n\t\tbody.classList.remove('android-menu-is-open');\n\t\tmenuWrapper.addEventListener('click', function(e) {\n\t\t\tbody.classList.remove('android-menu-is-open');\n\t\t});\n\n\t\tthis.watch(emitter, 'navigationBarLeftAction', function () {\n\t\t\tbody.classList.toggle('android-menu-is-open');\n\t\t});\n\t\tthis.watch(this.context.dataStore, 'update-people', this.updateEventState);\n\t\tthis.watch(this.context.dataStore, 'update-sponsors', this.updateEventState);\n\t},\n\n\tupdateEventState () {\n\t\tthis.setState({\n\t\t\torganisers: this.context.dataStore.getOrganisers(),\n\t\t\tsponsors: this.context.dataStore.getSponsors()\n\t\t});\n\t},\n\n\topenAddress () {\n\t\twindow.open('http://maps.apple.com/?daddr=327+Rue+de+Charenton,+75012+Paris,+France', '_blank', 'toolbar=yes,location=no,transitionstyle=coververtical')\n\t},\n\n\trender () {\n\t\tvar organisers = this.state.organisers;\n\t\tvar sponsorData = this.state.sponsors;\n\t\tvar sponsors = [];\n\n\t\tfunction orderByPriority (sponsor1, sponsor2) {\n\t\t\treturn TIER_PRIORITIES[sponsor1.tier] - TIER_PRIORITIES[sponsor2.tier];\n\t\t}\n\t\tconsole.log(sponsorData);\n\t\tvar lastTier;\n\t\tsponsorData.sort(orderByPriority).forEach(function (sponsor, i) {\n\t\t\tvar tierName = capitalize(sponsor.tier);\n\t\t\tvar tierPriority = TIER_PRIORITIES[sponsor.tier];\n\t\t\tvar lite = tierPriority > 3;\n\n\t\t\tif (tierName !== lastTier) {\n\t\t\t\tvar tierLabel = tierName === 'Supporter' ? 'Supporters' : tierName;\n\t\t\t\tsponsors.push(\n\t\t\t\t\t<div key={'tierHeading' + i} className=\"EventInfo__sponsors__tier\">\n\t\t\t\t\t\t<span className=\"EventInfo__sponsors__tier-text\">{tierName}</span>\n\t\t\t\t\t</div>\n\t\t\t\t);\n\t\t\t\tlastTier = tierName;\n\t\t\t}\n\n\t\t\tsponsors.push(<Sponsor key={'sponsor' + i} image={sponsor.LogoUrl} { ... sponsor} lite={lite} />)\n\t\t});\n\n\t\t// Social\n\t\tvar dataStore = this.context.dataStore;\n\t\tvar eventTwitter = dataStore.getSettings().eventTwitter;\n\t\tvar eventFacebook = dataStore.getSettings().eventFacebookPageId;\n\n\t\treturn (\n\t\t\t<Container fill scrollable={scrollable} ref=\"scrollContainer\" className=\"EventInfo\">\n\t\t\t\t<div className=\"EventInfo__hero\">\n\t\t\t\t\t<div className=\"EventInfo__hero-inner\">\n\t\t\t\t\t\t<div className=\"EventInfo__hero_title\">Espace Charenton</div>\n\t\t\t\t\t\t<div className=\"EventInfo__hero_address\">327, rue de Charenton 75012 Paris</div>\n\t\t\t\t\t\t<Tappable onTap={this.openAddress} className=\"EventInfo__hero_button button\">Get Directions</Tappable>\n\t\t\t\t\t\t<div className=\"EventInfo__hero_date\">June 02 & 03 — Paris, France</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div className=\"EventInfo__summary text-block\">ReactEurope is the occasion to meet the core team and other awesome members of the community to learn, socialize and have fun in the beautiful city of Paris with great food, entertainment, connectivity, prizes and more!</div>\n\t\t\t\t<div className=\"button-table\">\n\t\t\t\t\t<Tappable onTap={this.openTwitter.bind(this, eventTwitter)} className=\"button-table__item EventInfo__link\">\n\t\t\t\t\t\t<span className=\"button-table__item__icon EventInfo__link__icon--twitter ion-social-twitter\" />\n\t\t\t\t\t\t<div className=\"button-table__item__label\">@ReactEurope</div>\n\t\t\t\t\t</Tappable>\n\t\t\t\t\t<Tappable onTap={this.openFacebook.bind(this, eventFacebook)} className=\"button-table__item EventInfo__link\">\n\t\t\t\t\t\t<span className=\"button-table__item__icon EventInfo__link__icon--facebook ion-social-facebook\" />\n\t\t\t\t\t\t<div className=\"button-table__item__label\">ReactEurope</div>\n\t\t\t\t\t</Tappable>\n\t\t\t\t</div>\n\t\t\t\t<PeopleList people={organisers} heading=\"Organisers\" previousView=\"event\" className=\"EventInfo__organisers\" />\n\t\t\t\t<div className=\"EventInfo__sponsors\">\n\t\t\t\t\t<div className=\"EventInfo__sponsors__heading\">Sponsors</div>\n\t\t\t\t\t{sponsors}\n\t\t\t\t</div>\n\t\t\t</Container>\n\t\t);\n\t}\n});\n"
  },
  {
    "path": "src/js/views/event/sponsor.js",
    "content": "var React = require('react');\nvar Tappable = require('react-tappable');\n\nmodule.exports = React.createClass({\n\tdisplayName: 'Sponsor',\n\n\tpropTypes: {\n\t\timage: React.PropTypes.string,\n\t\tname: React.PropTypes.string,\n\t\tdescription: React.PropTypes.string,\n\t\tsummary: React.PropTypes.string,\n\t\ttier: React.PropTypes.string,\n\t\tlite: React.PropTypes.bool,\n\t\turl: React.PropTypes.string\n\t},\n\n\tgetInitialState () {\n\t\treturn {\n\t\t\tisExpanded: false\n\t\t};\n\t},\n\n\ttoggleFullText () {\n\t\tthis.setState({ isExpanded: !this.state.isExpanded });\n\t},\n\n\topenURL () {\n\t\twindow.open(this.props.website, '_blank', 'toolbar=yes,location=no,transitionstyle=coververtical');\n\t},\n\n\trender () {\n\t\tvar expanse\n\n\t\t// if (!this.props.lite) {\n\t\t// \tvar isExpanded = this.state.isExpanded\n\t\t// \tvar sponsorText = isExpanded ? this.props.description : this.props.summary.slice(0, 80) + ' ...'\n\t\t// \tvar tappable = isExpanded ? (\n\t\t// \t\t<Tappable onTap={this.openURL} className=\"EventInfo__sponsor__button EventInfo__sponsor__button--link\">View Website</Tappable>\n\t\t// \t) : (\n\t\t// \t\t<Tappable onTap={this.toggleFullText} className=\"EventInfo__sponsor__button EventInfo__sponsor__button--disclosure ion-chevron-down\" component=\"div\" />\n\t\t// \t);\n\n\t\t// \texpanse = (\n\t\t// \t\t<div>\n\t\t// \t\t\t<div className=\"EventInfo__sponsor__text\">{sponsorText}</div>\n\t\t// \t\t\t{tappable}\n\t\t// \t\t</div>\n\t\t// \t)\n\t\t// }\n\n\t\treturn (\n\t\t\t<div className={'EventInfo__sponsor--' + this.props.tier}>\n\t\t\t\t<div className=\"EventInfo__sponsor__image\">\n\t\t\t\t\t<img src={this.props.image} alt={this.props.name} />\n\t\t\t\t</div>\n\t\t\t\t{expanse}\n\t\t\t</div>\n\t\t);\n\t}\n});\n"
  },
  {
    "path": "src/js/views/me/edit.js",
    "content": "var React = require('react');\nvar Container = require('react-container');\nvar Sentry = require('react-sentry');\nvar { animation, LabelInput, LabelTextarea, Switch, Transitions } = require('../../touchstone');\n\nvar EventEmitter = require('events').EventEmitter;\nvar emitter = new EventEmitter();\n\nmodule.exports = React.createClass({\n\tdisplayName: 'ViewMe-edit',\n\tcontextTypes: { dataStore: React.PropTypes.object.isRequired },\n\tmixins: [Sentry(), Transitions, animation.Mixins.ScrollContainerToTop],\n\n\tstatics: {\n\t\tnavigationBar: 'main',\n\t\tgetNavigation () {\n\t\t\treturn {\n\t\t\t\tleftIcon: 'ion-android-menu',\n\t\t\t\tleftAction: emitter.emit.bind(emitter, 'navigationBarLeftAction'),\n\t\t\t\ttitle: 'Me'\n\t\t\t}\n\t\t}\n\t},\n\n\tgetInitialState () {\n\t\treturn this.context.dataStore.getMe();\n\t},\n\n\tcomponentDidMount () {\n\t\tthis.watch(this.context.dataStore, 'update-me', this.updateMeState);\n\n\t\t// android backbutton handler\n\t\tthis.watch(document, 'backbutton', () => {\n\t\t\tthis.transitionTo('tabs:me', {\n\t\t\t\ttransition: 'fade',\n\t\t\t\tviewProps: {\n\t\t\t\t\tme: this.state\n\t\t\t\t}\n\t\t\t});\n\t\t})\n\n\t\tvar body = document.getElementsByTagName('body')[0];\n\t\tvar menuWrapper = document.getElementsByClassName('Tabs-Navigator-wrapper')[0];\n\t\tbody.classList.remove('android-menu-is-open');\n\t\tmenuWrapper.addEventListener('click', function (e) {\n\t\t\tbody.classList.remove('android-menu-is-open');\n\t\t});\n\n\t\t// navbar actions\n\t\tthis.watch(emitter, 'navigationBarLeftAction', function () {\n\t\t\tbody.classList.toggle('android-menu-is-open');\n\t\t});\n\t},\n\n\tcomponentWillUnmount () {\n\t\tthis.context.dataStore.editMe(this.state);\n\t\tthis.context.dataStore.synchronize();\n\t},\n\n\tupdateMeState (me) {\n\t\tthis.setState(me);\n\t},\n\n\tonChange (field, event) {\n\t\tvar state = {};\n\t\tstate[field] = event.target.value;\n\t\tthis.setState(state);\n\t},\n\n\ttogglePublic () {\n\t\tthis.setState({ isPublic: !this.state.isPublic });\n\t},\n\n\trender () {\n\t\treturn (\n\t\t\t<Container scrollable ref=\"scrollContainer\">\n\t\t\t\t<div className=\"PersonDetails\">\n\t\t\t\t\t<div><img src={this.state.picture} className=\"PersonDetails__avatar\" /></div>\n\t\t\t\t\t<div className=\"PersonDetails__heading\">{this.state.name}</div>\n\t\t\t\t</div>\n\t\t\t\t<div className=\"panel\">\n\t\t\t\t\t<label className=\"list-item field-item\">\n\t\t\t\t\t\t<div className=\"item-inner\">\n\t\t\t\t\t\t\t<div className=\"field-label\">Public</div>\n\t\t\t\t\t\t\t<Switch onTap={this.togglePublic} on={this.state.isPublic} />\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</label>\n\t\t\t\t</div>\n\t\t\t\t<div className=\"panel\">\n\t\t\t\t\t<LabelInput onChange={this.onChange.bind(this, 'twitter')} name=\"twitter\" label=\"Twitter\" defaultValue={this.state.twitter} />\n\t\t\t\t\t<LabelInput onChange={this.onChange.bind(this, 'github')} name=\"github\" label=\"GitHub\" defaultValue={this.state.github} />\n\t\t\t\t</div>\n\t\t\t\t<div className=\"panel\">\n\t\t\t\t\t<LabelTextarea onChange={this.onChange.bind(this, 'bio')} name=\"bio\" label=\"Bio\" defaultValue={this.state.bio} rows={6} />\n\t\t\t\t</div>\n\t\t\t</Container>\n\t\t);\n\t}\n});\n\n"
  },
  {
    "path": "src/js/views/me/index.js",
    "content": "var Container = require('react-container');\nvar Sentry = require('react-sentry');\nvar React = require('react');\nvar { animation, Link, Transitions } = require('../../touchstone');\nvar Social = require('../../mixins/social')\nvar Section = require('./section');\n\nvar EventEmitter = require('events').EventEmitter;\nvar emitter = new EventEmitter();\n\nmodule.exports = React.createClass({\n\tdisplayName: 'ViewMe',\n\tcontextTypes: { dataStore: React.PropTypes.object.isRequired },\n\tmixins: [Sentry(), Transitions, Social, animation.Mixins.ScrollContainerToTop],\n\n\tstatics: {\n\t\tnavigationBar: 'main',\n\t\tgetNavigation (props) {\n\t\t\tvar name = props.me && props.me.name\n\n\t\t\treturn {\n\t\t\t\tleftIcon: 'ion-android-menu',\n\t\t\t\tleftAction: emitter.emit.bind(emitter, 'navigationBarLeftAction'),\n\t\t\t\trightAction: emitter.emit.bind(emitter, 'navigationBarRightAction'),\n\t\t\t\trightButtonDisabled: !name,\n\t\t\t\trightLabel: name ? 'Edit' : '',\n\t\t\t\ttitle: 'Me'\n\t\t\t}\n\t\t}\n\t},\n\n\tgetDefaultProps () {\n\t\treturn {\n\t\t\tme: {}\n\t\t}\n\t},\n\n\tcomponentDidMount () {\n\t\tvar self = this;\n\t\tvar body = document.getElementsByTagName('body')[0];\n\t\tvar menuWrapper = document.getElementsByClassName('Tabs-Navigator-wrapper')[0];\n\t\tbody.classList.remove('android-menu-is-open');\n\t\tmenuWrapper.addEventListener('click', function (e) {\n\t\t\tbody.classList.remove('android-menu-is-open');\n\t\t});\n\n\t\t// navbar actions\n\t\tthis.watch(emitter, 'navigationBarLeftAction', function () {\n\t\t\tbody.classList.toggle('android-menu-is-open');\n\t\t});\n\t\tthis.watch(emitter, 'navigationBarRightAction', function () {\n\t\t\tself.transitionTo('tabs:me-edit', { transition: 'fade' })\n\t\t});\n\t},\n\n\trender () {\n\t\tvar person = this.props.me\n\t\tvar github = person.github && this.renderGithub(person.github)\n\t\tvar twitter = person.twitter && this.renderTwitter(person.twitter)\n\t\tvar ticketCode = this.context.dataStore.getTicketCode()\n\t\tvar hackathonTicketCode = this.context.dataStore.getHackathonTicketCode();\n\t\tvar workshopTicketCode = this.context.dataStore.getWorkshopTicketCode();\n\t\tvar qrUrl = 'https://chart.googleapis.com/chart?cht=qr&chl=' + ticketCode + '&chs=400x400';\n\n\t\treturn (\n\t\t\t<Container scrollable ref=\"scrollContainer\" align=\"center\" direction=\"column\" className=\"MeRegistration__body\">\n\n\t\t\t\t\t{/* Main event*/}\n\t\t\t\t\t{(person && person.first_name) ? (\n\t\t\t\t\t\t<Container align=\"center\" className=\"MeRegistration__section\">\n\t\t\t\t\t\t\t<div className=\"PersonDetails\">\n\t\t\t\t\t\t\t\t{(person.picture || person.avatar_url || person.pic_url) ? (\n\t\t\t\t\t\t\t\t\t<img src={person.picture || person.avatar_url || person.pic_url} className=\"PersonDetails__avatar\" />\n\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t\t{person.first_name && <div className=\"PersonDetails__heading\">{person.first_name} {person.last_name}</div>}\n\t\t\t\t\t\t\t\t{person.bio && <div className=\"PersonDetails__text text-block\">{person.bio}</div>}\n\t\t\t\t\t\t\t\t{(person.twitter || person.github) && <div className=\"PersonDetails__profiles\">\n\t\t\t\t\t\t\t\t\t{twitter}\n\t\t\t\t\t\t\t\t\t{github}\n\t\t\t\t\t\t\t\t</div>}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<Container align=\"center\" className=\"entry-code\">\n\t\t\t\t\t\t\t\t<div className=\"entry-code__heading\">Please show this to gain entry:</div>\n\t\t\t\t\t\t\t\t<img src={qrUrl} className=\"entry-code__image\" />\n\t\t\t\t\t\t\t\t<div className=\"entry-code__text\">{ticketCode.toUpperCase()}</div>\n\t\t\t\t\t\t\t</Container>\n\t\t\t\t\t\t</Container>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<Container align=\"center\" className=\"MeRegistration__section\">\n\t\t\t\t\t\t\t<div className=\"MeRegistration__heading\">ReactEurope 2016</div>\n\t\t\t\t\t\t\t<p className=\"MeRegistration__intro\">Register to get the most out of ReactEurope&nbsp;2016!</p>\n\t\t\t\t\t\t\t<Link to=\"app:onboarding-main-event\" transition=\"fade\" className=\"MeRegistration__footer-button\">Register</Link>\n\t\t\t\t\t\t</Container>\n\t\t\t\t\t)}\n\t\t\t\t\t<Section\n\t\t\t\t\t\ttitle=\"Workshop\"\n\t\t\t\t\t\tticketCode={workshopTicketCode}\n\t\t\t\t\t\tregisterLink=\"app:onboarding-workshop\"\n\t\t\t\t\t/>\n\t\t\t\t\t<Section\n\t\t\t\t\t\ttitle=\"Hackathon\"\n\t\t\t\t\t\tticketCode={hackathonTicketCode}\n\t\t\t\t\t\tregisterLink=\"app:onboarding-hackathon\"\n\t\t\t\t\t/>\n\t\t\t\t</Container>\n\t\t);\n\t}\n});\n\n// OLD CODE\n/* <div className=\"MeRegistration__benefits\">\n\t<div className=\"MeRegistration__benefit\">\n\t\t<div className=\"MeRegistration__benefit__icon ion-qr-scanner\" />\n\t\t<div className=\"MeRegistration__benefit__label\">Enter the conference simply by having your QR code scanned</div>\n\t</div>\n\t<div className=\"MeRegistration__benefit\">\n\t\t<div className=\"MeRegistration__benefit__icon ion-person\" />\n\t\t<div className=\"MeRegistration__benefit__label\">Make your profile public and view the full list of public attendees</div>\n\t</div>\n\t<div className=\"MeRegistration__benefit\">\n\t\t<div className=\"MeRegistration__benefit__icon ion-speakerphone\" />\n\t\t<div className=\"MeRegistration__benefit__label\">Leave feedback for the speakers on your favourite talks</div>\n\t</div>\n</div> */\n"
  },
  {
    "path": "src/js/views/me/section.js",
    "content": "var React = require('react');\nvar Container = require('react-container');\nvar { animation, Link, Transitions } = require('../../touchstone');\n\nmodule.exports = React.createClass({\n  mixins: [Transitions, animation.Mixins.ScrollContainerToTop],\n  displayName: 'Me Section',\n  propTypes: {\n    registerLink: React.PropTypes.string.isRequired,\n    title: React.PropTypes.string.isRequired,\n    ticketCode: React.PropTypes.string\n  },\n  render: function () {\n    // If they aren't registered, show a registration button\n    if (!this.props.ticketCode) {\n      return (\n        <Container align=\"center\" className=\"MeRegistration__section\">\n\t\t\t\t\t<div className=\"MeRegistration__heading\">{this.props.title}</div>\n\t\t\t\t\t<p className=\"MeRegistration__intro\">Register your {this.props.title} ticket!</p>\n\t\t\t\t\t<Link to={this.props.registerLink} transition=\"fade\" className=\"MeRegistration__footer-button\">Register</Link>\n\t\t\t\t</Container>\n      );\n    }\n\n    var qrUrl = 'https://chart.googleapis.com/chart?cht=qr&chl=' + this.props.ticketCode + '&chs=400x400';\n\n    return (\n      <Container align=\"center\" className=\"MeRegistration__section\">\n        <div className=\"MeRegistration__heading\">{this.props.title}</div>\n        <div className=\"entry-code__heading\">Please show this to gain entry:</div>\n        <img src={qrUrl} className=\"entry-code__image\" />\n        <div className=\"entry-code__text\">{this.props.ticketCode.toUpperCase()}</div>\n      </Container>\n    );\n  }\n})\n"
  },
  {
    "path": "src/js/views/onboarding/hackathon/enter-code.js",
    "content": "var React = require('react');\nvar { Transitions } = require('../../../touchstone');\n\nvar OnboardingEnterCode = require('../../../components/Onboarding/enter-code');\n\nmodule.exports = React.createClass({\n\tmixins: [Transitions],\n\tcontextTypes: { dataStore: React.PropTypes.object.isRequired },\n\n\tonCodeEnter (ticketCode, callback) {\n\t\tdataStore.activateHackathon(ticketCode, function (err) {\n\t\t\tdataStore.synchronize();\n\t\t\tcallback(err);\n\t\t});\n\t},\n\n\trender () {\n\t\treturn (\n\t\t\t<OnboardingEnterCode\n\t\t\t\tonCodeEnter={this.onCodeEnter}\n\t\t\t\tnextScreen=\"app:main\"\n\t\t\t\tid=\"hackathon\"\n\t\t\t\ttitle=\"Hackathon\"\n\t\t\t/>\n\t\t);\n\t}\n});\n"
  },
  {
    "path": "src/js/views/onboarding/hackathon/index.js",
    "content": "var Sentry = require('react-sentry');\nvar React = require('react/addons');\n\nvar { Transitions } = require('../../../touchstone');\n\nvar OnboardingView = require('../../../components/Onboarding');\n\nvar MainEventOnboarding = React.createClass({\n\tmixins: [Sentry(), Transitions],\n\tcontextTypes: { dataStore: React.PropTypes.object.isRequired },\n\n\tonCodeEnter (ticketCode, callback) {\n\t\tdataStore.activateHackathon(ticketCode, function (err) {\n\t\t\tdataStore.synchronize();\n\t\t\tcallback(err);\n\t\t});\n\t},\n\n\trender () {\n\t\treturn (\n\t\t\t<OnboardingView\n\t\t\t\tonCodeEnter={this.onCodeEnter}\n\t\t\t\tnextScreen=\"app:main\"\n\t\t\t\tid=\"hackathon\"\n\t\t\t\ttitle=\"Hackathon\"\n\t\t\t/>\n\t\t);\n\t}\n});\n\nexport default MainEventOnboarding;\n"
  },
  {
    "path": "src/js/views/onboarding/hackathon/resend-email.js",
    "content": "var OnboardingResendEmail = require('../../../components/Onboarding/resend-email');\nvar React = require('react');\nvar { Transitions } = require('../../../touchstone');\n\nmodule.exports = React.createClass({\n\tmixins: [Transitions],\n\trender () {\n\t\treturn (\n\t\t\t<OnboardingResendEmail\n\t\t\t\tid=\"hackathon\"\n\t\t\t\tnextScreen=\"app:onboarding-hackathon\"\n\t\t\t/>\n\t\t);\n\t}\n});\n"
  },
  {
    "path": "src/js/views/onboarding/main-event/enter-code.js",
    "content": "var React = require('react');\nvar { Transitions } = require('../../../touchstone');\n\nvar OnboardingEnterCode = require('../../../components/Onboarding/enter-code');\n\nmodule.exports = React.createClass({\n\tmixins: [Transitions],\n\tcontextTypes: { dataStore: React.PropTypes.object.isRequired },\n\n\tonCodeEnter (ticketCode, callback) {\n\t\tdataStore.activate(ticketCode, function (err) {\n\t\t\tdataStore.synchronize();\n\t\t\tcallback(err);\n\t\t});\n\t},\n\n\trender () {\n\t\treturn (\n\t\t\t<OnboardingEnterCode\n\t\t\t\tid=\"main-event\"\n\t\t\t\tonCodeEnter={this.onCodeEnter}\n\t\t\t\tnextScreen=\"app:main\"\n\t\t\t\ttitle=\"Main Event\"\n\t\t\t\ttransition=\"fade\"\n\t\t\t/>\n\t\t);\n\t}\n});\n"
  },
  {
    "path": "src/js/views/onboarding/main-event/index.js",
    "content": "var Sentry = require('react-sentry');\nvar React = require('react/addons');\n\nvar { Transitions } = require('../../../touchstone');\n\nvar OnboardingView = require('../../../components/Onboarding');\n\nvar MainEventOnboarding = React.createClass({\n\tmixins: [Sentry(), Transitions],\n\tcontextTypes: { dataStore: React.PropTypes.object.isRequired },\n\n\tonCodeEnter (ticketCode, callback) {\n\t\tdataStore.activate(ticketCode, function (err) {\n\t\t\tdataStore.synchronize();\n\t\t\tcallback(err);\n\t\t});\n\t},\n\n\trender () {\n\t\treturn (\n\t\t\t<OnboardingView\n\t\t\t\tonCodeEnter={this.onCodeEnter}\n\t\t\t\tnextScreen=\"app:main\"\n\t\t\t\tid=\"main-event\"\n\t\t\t\ttitle=\"Main Event\"\n\t\t\t\ttransition=\"fade\"\n\t\t\t/>\n\t\t);\n\t}\n});\n\nexport default MainEventOnboarding;\n"
  },
  {
    "path": "src/js/views/onboarding/main-event/resend-email.js",
    "content": "var OnboardingResendEmail = require('../../../components/Onboarding/resend-email');\nvar React = require('react');\nvar { Transitions } = require('../../../touchstone');\n\nmodule.exports = React.createClass({\n\tmixins: [Transitions],\n\trender () {\n\t\treturn (\n\t\t\t<OnboardingResendEmail\n\t\t\t\tid=\"main-event\"\n\t\t\t\tnextScreen=\"app:onboarding-main-event\"\n\t\t\t\ttransition=\"fade\"\n\t\t\t/>\n\t\t);\n\t}\n});\n"
  },
  {
    "path": "src/js/views/onboarding/workshop/enter-code.js",
    "content": "var React = require('react');\nvar { Transitions } = require('../../../touchstone');\n\nvar OnboardingEnterCode = require('../../../components/Onboarding/enter-code');\n\nmodule.exports = React.createClass({\n\tmixins: [Transitions],\n\tcontextTypes: { dataStore: React.PropTypes.object.isRequired },\n\n\tonCodeEnter (ticketCode, callback) {\n\t\tdataStore.activateWorkshop(ticketCode, function (err) {\n\t\t\tdataStore.synchronize();\n\t\t\tcallback(err);\n\t\t});\n\t},\n\n\trender () {\n\t\treturn (\n\t\t\t<OnboardingEnterCode\n\t\t\t\tonCodeEnter={this.onCodeEnter}\n\t\t\t\tnextScreen=\"app:main\"\n\t\t\t\tid=\"workshop\"\n\t\t\t\ttitle=\"Workshop\"\n\t\t\t\ttransition=\"fade\"\n\t\t\t/>\n\t\t);\n\t}\n});\n"
  },
  {
    "path": "src/js/views/onboarding/workshop/index.js",
    "content": "var Sentry = require('react-sentry');\nvar React = require('react/addons');\n\nvar { Transitions } = require('../../../touchstone');\n\nvar OnboardingView = require('../../../components/Onboarding');\n\nvar MainEventOnboarding = React.createClass({\n\tmixins: [Sentry(), Transitions],\n\tcontextTypes: { dataStore: React.PropTypes.object.isRequired },\n\n\tonCodeEnter (ticketCode, callback) {\n\t\tdataStore.activateWorkshop(ticketCode, function (err) {\n\t\t\tdataStore.synchronize();\n\t\t\tcallback(err);\n\t\t});\n\t},\n\n\trender () {\n\t\treturn (\n\t\t\t<OnboardingView\n\t\t\t\tonCodeEnter={this.onCodeEnter}\n\t\t\t\tnextScreen=\"app:main\"\n\t\t\t\tid=\"workshop\"\n\t\t\t\ttitle=\"Workshop\"\n\t\t\t\ttransition=\"fade\"\n\t\t\t/>\n\t\t);\n\t}\n});\n\nexport default MainEventOnboarding;\n"
  },
  {
    "path": "src/js/views/onboarding/workshop/resend-email.js",
    "content": "var OnboardingResendEmail = require('../../../components/Onboarding/resend-email');\nvar React = require('react');\nvar { Transitions } = require('../../../touchstone');\n\nmodule.exports = React.createClass({\n\tmixins: [Transitions],\n\trender () {\n\t\treturn (\n\t\t\t<OnboardingResendEmail\n\t\t\t\tid=\"workshop\"\n\t\t\t\tnextScreen=\"app:onboarding-workshop\"\n\t\t\t\ttransition=\"show-from-right\"\n\t\t\t/>\n\t\t);\n\t}\n});\n"
  },
  {
    "path": "src/js/views/people/index.js",
    "content": "var animation = require('../../touchstone/animation');\nvar Container = require('react-container');\nvar Sentry = require('react-sentry');\nvar React = require('react');\n\nvar PeopleList = require('../../components/PeopleList');\nvar Search = require('./search');\n\nvar EventEmitter = require('events').EventEmitter;\nvar emitter = new EventEmitter();\n\nconst scrollable = Container.initScrollable();\n\nvar lastFilterStarred = false;\nvar lastFilterSearch = '';\n\nfunction getNavigation (props, onlyStarred) {\n\tif (onlyStarred === undefined) {\n\t\tonlyStarred = lastFilterStarred;\n\t}\n\n\treturn {\n\t\tleftIcon: 'ion-android-menu',\n\t\tleftAction: emitter.emit.bind(emitter, 'navigationBarLeftAction'),\n\t\trightLabel: onlyStarred ? 'All' : 'Starred',\n\t\trightAction: emitter.emit.bind(emitter, 'navigationBarRightAction'),\n\t\ttitle: 'People'\n\t};\n}\n\nmodule.exports = React.createClass({\n\tdisplayName: 'ViewPeople',\n\tcontextTypes: {\n\t\tapp: React.PropTypes.object,\n\t\tdataStore: React.PropTypes.object.isRequired\n\t},\n\tmixins: [Sentry(), animation.Mixins.ScrollContainerToTop],\n\n\tstatics: {\n\t\tnavigationBar: 'main',\n\t\tgetNavigation: getNavigation\n\t},\n\n\tgetInitialState () {\n\t\treturn {\n\t\t\tattendees: this.context.dataStore.getAttendees(),\n\t\t\torganisers: this.context.dataStore.getOrganisers(),\n\t\t\tspeakers: this.context.dataStore.getSpeakers(),\n\t\t\tsearchString: lastFilterSearch,\n\t\t\tonlyStarred: lastFilterStarred\n\t\t};\n\t},\n\n\tcomponentDidMount () {\n\t\tvar body = document.getElementsByTagName('body')[0];\n\t\tvar menuWrapper = document.getElementsByClassName('Tabs-Navigator-wrapper')[0];\n\t\tbody.classList.remove('android-menu-is-open');\n\t\tmenuWrapper.addEventListener('click', function(e) {\n\t\t\tbody.classList.remove('android-menu-is-open');\n\t\t});\n\n\t\t// navbar actions\n\t\tthis.watch(emitter, 'navigationBarLeftAction', function () {\n\t\t\tbody.classList.toggle('android-menu-is-open');\n\t\t});\n\t\tthis.watch(emitter, 'navigationBarRightAction', this.toggleStarred);\n\t\tthis.watch(this.context.dataStore, 'update-people', this.updatePeopleState);\n\t},\n\n\tupdatePeopleState () {\n\t\tvar dataStore = this.context.dataStore;\n\n\t\tthis.setState({\n\t\t\tattendees: dataStore.getAttendees(),\n\t\t\torganisers: dataStore.getOrganisers(),\n\t\t\tspeakers: dataStore.getSpeakers()\n\t\t});\n\t},\n\n\tupdateSearch (str) {\n\t\tlastFilterSearch = str.toLowerCase();\n\t\tthis.setState({ searchString: lastFilterSearch });\n\t},\n\n\ttoggleStarred () {\n\t\tvar onlyStarred = !this.state.onlyStarred;\n\t\tlastFilterStarred = onlyStarred;\n\n\t\tthis.setState({ onlyStarred: onlyStarred });\n\t\tthis.context.app.navigationBars.main.update(getNavigation({}, onlyStarred));\n\t},\n\n\trender () {\n\t\tvar me = this.context.dataStore.getMe();\n\t\tvar authed = me && me.name;\n\t\tvar search = this.state.searchString;\n\t\tvar onlyStarred = this.state.onlyStarred;\n\n\t\tfunction searchFilter (person) {\n\t\t\treturn new RegExp(search).test(person.name.toLowerCase());\n\t\t}\n\n\t\tfunction starredFilter (person) {\n\t\t\treturn !onlyStarred || person.starred;\n\t\t}\n\n\t\tvar attendees = [];\n\t\tvar attendeeCount = 0;\n\t\tvar organisers = this.state.organisers.filter(searchFilter).filter(starredFilter);\n\t\tvar speakers = this.state.speakers.filter(searchFilter).filter(starredFilter);\n\n\t\tif (authed && search || this.state.onlyStarred) {\n\t\t\tattendees = this.state.attendees.filter(searchFilter).filter(starredFilter);\n\t\t\tattendeeCount = attendees.length;\n\t\t\tif (search) {\n\t\t\t\tattendees = attendees.slice(0,15);\n\t\t\t}\n\t\t}\n\n\t\tvar results;\n\t\tvar noResults = !attendees.length && !organisers.length && !speakers.length;\n\t\tif (noResults) {\n\t\t\tvar noResultsText = search ? ('No results for \"' + this.state.searchString + '\"') : 'Go star some people :)';\n\t\t\tvar noResultsIcon = search ? 'no-results__icon ion-ios-search-strong' : 'no-results__icon ion-ios-star';\n\n\t\t\tresults = (\n\t\t\t\t<Container direction=\"column\" align=\"center\" justify=\"center\" className=\"no-results\">\n\t\t\t\t\t<div className={noResultsIcon} />\n\t\t\t\t\t<div className=\"no-results__text\">{noResultsText}</div>\n\t\t\t\t</Container>\n\t\t\t);\n\t\t} else {\n\t\t\tvar attendeesMessage;\n\t\t\tvar displayAttendees = [];\n\t\t\tif (!authed) {\n\t\t\t\tattendeesMessage = <div className=\"search-attendees-message\">If you're at the conference, scan your Ticket QR to set up your profile and connect with other attendees.</div>;\n\t\t\t} else if (search && attendeeCount > attendees.length) {\n\t\t\t\tvar notDisplayedCount = attendeeCount - attendees.length;\n\t\t\t\tattendeesMessage = <div className=\"search-attendees-message\">{notDisplayedCount} more {notDisplayedCount === 1 ? 'person' : 'people'} matching {search}... be more specific.</div>;\n\t\t\t} else if (!search && !onlyStarred) {\n\t\t\t\tattendeesMessage = <div className=\"search-attendees-message\">To find attendees use the searchbar above.<br /><br />If you can't find someone, make sure they've registered their app and made their profile public.</div>;\n\t\t\t}\n\t\t\tresults = (\n\t\t\t\t<Container fill scrollable={scrollable} ref=\"scrollContainer\">\n\t\t\t\t\t<PeopleList people={organisers} heading=\"Organisers\" headingIsSticky previousView=\"people\" />\n\t\t\t\t\t<PeopleList people={speakers} heading=\"Speakers\" headingIsSticky previousView=\"people\" />\n\t\t\t\t\t<PeopleList people={attendees.slice(0,20)} heading=\"Attendees\" headingIsSticky previousView=\"people\" />\n\t\t\t\t\t{attendeesMessage}\n\t\t\t\t</Container>\n\t\t\t);\n\t\t}\n\n\t\treturn (\n\t\t\t<Container direction=\"column\">\n\t\t\t\t<Search searchString={this.state.searchString} onChange={this.updateSearch} />\n\t\t\t\t{results}\n\t\t\t</Container>\n\t\t);\n\t}\n});\n"
  },
  {
    "path": "src/js/views/people/person.js",
    "content": "var Container = require('react-container');\nvar React = require('react');\nvar moment = require('moment');\nvar Social = require('../../mixins/social')\nvar Tappable = require('react-tappable');\nvar { animation, Link, Transitions } = require('../../touchstone');\n\nvar Sentry = require('react-sentry');\nvar EventEmitter = require('events').EventEmitter;\nvar emitter = new EventEmitter();\n\nfunction getNavigation2 (props) {\n\tvar leftLabel = 'People';\n\tif (props.previousView === 'event') {\n\t\tleftLabel = 'Event';\n\t} else if (props.previousView === 'talk') {\n\t\tleftLabel = 'Talk';\n\t}\n\n\treturn {\n\t\tleftArrow: true,\n\t\tleftLabel: leftLabel,\n\t\tleftAction: emitter.emit.bind(emitter, 'navigationBarLeftAction'),\n\t\trightIcon: props.person.starred ? 'ion-ios-star' : 'ion-ios-star-outline',\n\t\trightAction: emitter.emit.bind(emitter, 'navigationBarRightAction'),\n\t\ttitle: 'Person'\n\t}\n}\n\nmodule.exports = React.createClass({\n\tdisplayName: 'ViewPerson',\n\tcontextTypes: {\n\t\tdataStore: React.PropTypes.object.isRequired\n\t},\n\tmixins: [Sentry(), Transitions, Social, animation.Mixins.ScrollContainerToTop],\n\n\tstatics: {\n\t\tnavigationBar: 'main',\n\t\tgetNavigation: getNavigation2\n\t},\n\n\tgetDefaultProps () {\n\t\treturn {\n\t\t\tpreviousView: 'people'\n\t\t};\n\t},\n\n\tcomponentDidMount () {\n\t\tvar self = this;\n\t\tvar gotoView = 'main:tabs';\n\n\t\tif (this.props.previousView === 'talk') {\n\t\t\tgotoView = 'main:talk';\n\t\t}\n\n\t\t// android backbutton handler\n\t\tthis.watch(document, 'backbutton', function () {\n\t\t\tself.transitionTo(gotoView, {\n\t\t\t\ttransition: 'reveal-from-right',\n\t\t\t\tviewProps: self.props.previousViewProps\n\t\t\t});\n\t\t});\n\n\t\t// navbar actions\n\t\tthis.watch(emitter, 'navigationBarLeftAction', function () {\n\t\t\tself.transitionTo(gotoView, {\n\t\t\t\ttransition: 'reveal-from-right',\n\t\t\t\tviewProps: self.props.previousViewProps\n\t\t\t});\n\t\t});\n\n\t\tthis.watch(emitter, 'navigationBarRightAction', this.starThisUser);\n\t},\n\n\tstarThisUser () {\n\t\tthis.context.dataStore.star(this.props.person.id, !this.props.person.starred)\n\t\tthis.context.app.navigationBars.main.update(getNavigation2(this.props))\n\t},\n\n\trenderTalk () {\n\t\tvar person = this.props.person;\n\t\tif (!person.talks) return;\n\t\tif ((this.props.previousView === 'talk') || (this.props.previousView === 'event')) return;\n\n\t\treturn person.talks.map((talk, i) => {\n\t\t\tvar viewProps = {\n\t\t\t\tpreviousView: 'person',\n\t\t\t\tpreviousViewProps: this.props,\n\t\t\t\ttalk: talk\n\t\t\t}\n\t\t\tvar talkTime = moment(talk.start_date).utcOffset('+0200').format('h:mma')\n\n\t\t\treturn (\n\t\t\t\t<Link key={'talk_' + i} to=\"main:talk\" transition=\"show-from-right\" viewProps={viewProps} className=\"Footerbar PersonDetails__talk\" component=\"div\">\n\t\t\t\t\t<div className=\"PersonDetails__talk-inner\">\n\t\t\t\t\t\t<div className=\"PersonDetails__talk__time\">{talkTime}</div>\n\t\t\t\t\t\t<div className=\"PersonDetails__talk__title\">{talk.title}</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div className=\"PersonDetails__talk-chevron ion-chevron-right\" />\n\t\t\t\t</Link>\n\t\t\t);\n\t\t})\n\t},\n\n\trender () {\n\t\tvar person = this.props.person;\n\t\tvar github = person.github && this.renderGithub(person.github)\n\t\tvar twitter = person.twitter && this.renderTwitter(person.twitter)\n\n\t\treturn (\n\t\t\t<Container direction=\"column\">\n\t\t\t\t<Container fill scrollable ref=\"scrollContainer\" className=\"PersonDetails\">\n\t\t\t\t\t<img src={person.picture || person.avatar_url || person.pic_url} className=\"PersonDetails__avatar\" />\n\t\t\t\t\t<div className=\"PersonDetails__heading\">{person.name}</div>\n\t\t\t\t\t<div className=\"PersonDetails__text text-block\">{person.bio}</div>\n\t\t\t\t\t{(person.twitter || person.github) && <div className=\"PersonDetails__profiles\">\n\t\t\t\t\t\t{twitter}\n\t\t\t\t\t\t{github}\n\t\t\t\t\t</div>}\n\t\t\t\t</Container>\n\t\t\t\t{this.renderTalk()}\n\t\t\t</Container>\n\t\t);\n\t}\n});\n"
  },
  {
    "path": "src/js/views/people/search.js",
    "content": "var React = require('react');\nvar Tappable = require('react-tappable');\n\nmodule.exports = React.createClass({\n\tdisplayName: 'PeopleSearch',\n\tpropTypes: {\n\t\tsearchString: React.PropTypes.string,\n\t\tonChange: React.PropTypes.func.isRequired\n\t},\n\n\thandleChange (event) {\n\t\tthis.props.onChange(event.target.value);\n\t},\n\n\treset () {\n\t\tthis.props.onChange('');\n\t\t// JW - this shouldn't focus the search field\n\t\t// this.refs.input.getDOMNode().focus();\n\t},\n\n\trender () {\n\t\tvar clearIcon;\n\n\t\tif (this.props.searchString.length > 0) {\n\t\t\tclearIcon = <Tappable onTap={this.reset} className=\"Headerbar-form-clear ion-close-circled\" />;\n\t\t}\n\n\t\treturn (\n\t\t\t<div className=\"Headerbar-form-field Headerbar-form-icon ion-ios-search-strong\">\n\t\t\t\t<input ref=\"input\" value={this.props.searchString} onChange={this.handleChange} className=\"Headerbar-form-input\" placeholder='Search...' autoCapitalize=\"off\" />\n\t\t\t\t{clearIcon}\n\t\t\t</div>\n\t\t);\n\t}\n});\n"
  },
  {
    "path": "src/js/views/schedule/index.js",
    "content": "var animation = require('../../touchstone/animation');\nvar Container = require('react-container');\nvar Sentry = require('react-sentry');\nvar React = require('react');\nvar Timers = require('react-timers');\n\nvar ListHeader = require('../../components/ListHeader');\nvar ScheduleItem = require('./item');\n\nvar moment = require('moment');\nconst scrollable = Container.initScrollable();\n\nvar EventEmitter = require('events').EventEmitter;\nvar emitter = new EventEmitter();\n\nmodule.exports = React.createClass({\n\tdisplayName: 'Schedule',\n\tcontextTypes: {\n\t\tdataStore: React.PropTypes.object.isRequired\n\t},\n\tmixins: [Sentry(), Timers(), animation.Mixins.ScrollContainerToTop],\n\n\tstatics: {\n\t\tnavigationBar: 'main',\n\t\tgetNavigation () {\n\t\t\treturn {\n\t\t\t\tleftIcon: 'ion-android-menu',\n\t\t\t\tleftAction: emitter.emit.bind(emitter, 'navigationBarLeftAction'),\n\t\t\t\ttitle: 'Schedule'\n\t\t\t}\n\t\t}\n\t},\n\n\tgetInitialState () {\n\t\treturn {\n\t\t\tschedule: this.context.dataStore.getSchedule(),\n\t\t\tsearchString: '',\n\t\t\ttimeNow: window.timeNow || Date.now()\n\t\t}\n\t},\n\n\tcomponentDidMount () {\n\t\tvar body = document.getElementsByTagName('body')[0];\n\t\tvar menuWrapper = document.getElementsByClassName('Tabs-Navigator-wrapper')[0];\n\t\tbody.classList.remove('android-menu-is-open');\n\t\tmenuWrapper.addEventListener('click', function(e) {\n\t\t\tbody.classList.remove('android-menu-is-open');\n\t\t});\n\n\t\t// navbar actions\n\t\tthis.watch(emitter, 'navigationBarLeftAction', function () {\n\t\t\tbody.classList.toggle('android-menu-is-open');\n\t\t});\n\n\t\t// watch the local store and update when the schedule changes\n\t\tthis.watch(this.context.dataStore, 'update-schedule', this.updateScheduleState);\n\n\t\t// hard-update every minute to update \"on now\" indicator for talks\n\t\tthis.setInterval(() => {\n\t\t\t// FIXME: remove, window.timeNow is for debugging\n\t\t\tthis.setState({ timeNow: window.timeNow || Date.now() })\n\t\t}, 60 * 1000)\n\t},\n\n\tupdateScheduleState () {\n\t\tthis.setState({\n\t\t\tschedule: this.context.dataStore.getSchedule()\n\t\t});\n\t},\n\n\trender () {\n\t\tvar days = [];\n\t\tvar currentDay;\n\t\tvar timeNow = this.state.timeNow;\n\n\t\tthis.state.schedule.forEach(function (scheduleItem, i) {\n\t\t\tvar itemDayName = moment(scheduleItem.start_date).utcOffset('+0200').format('dddd');\n\n\t\t\tif (!currentDay || currentDay.name !== itemDayName) {\n\t\t\t\tcurrentDay = { name: itemDayName, items: [] };\n\t\t\t\tdays.push(currentDay);\n\t\t\t}\n\n\t\t\tvar begun = timeNow > new Date(scheduleItem.start_date).getTime();\n\t\t\tvar finished = timeNow > new Date(scheduleItem.endTime).getTime();\n\t\t\tvar onNow = begun && !finished;\n\n\t\t\tcurrentDay.items.push({\n\t\t\t\tdetails: scheduleItem,\n\t\t\t\tbegun: begun,\n\t\t\t\tfinished: finished,\n\t\t\t\tonNow: onNow\n\t\t\t});\n\t\t});\n\n\t\treturn (\n\t\t\t<Container scrollable={scrollable} ref=\"scrollContainer\">\n\t\t\t\t{days.map((day, i) => {\n\t\t\t\t\treturn (<div key={'day' + i}>\n\t\t\t\t\t\t<ListHeader key={'schedule_header_' + day.name} sticky>{day.name}</ListHeader>\n\t\t\t\t\t\t{day.items.map((item, i) => {\n\t\t\t\t\t\t\treturn (<ScheduleItem key={'schedule_' + i} talk={item.details} finished={item.finished} onNow={item.onNow} />)\n\t\t\t\t\t\t})}\n\t\t\t\t\t</div>)\n\t\t\t\t})}\n\t\t\t</Container>\n\t\t);\n\t}\n});\n"
  },
  {
    "path": "src/js/views/schedule/item.js",
    "content": "var classnames = require('classnames');\nvar Blink = require('react-blink');\nvar moment = require('moment');\nvar React = require('react');\nvar { Link } = require('../../touchstone');\n\nmodule.exports = React.createClass({\n\tdisplayName: 'ScheduleItem',\n\tcontextTypes: {\n\t\tdataStore: React.PropTypes.object.isRequired\n\t},\n\n\tpropTypes: {\n\t\tonNow: React.PropTypes.bool,\n\t\tfinished: React.PropTypes.bool,\n\t\ttalk: React.PropTypes.object.isRequired\n\t},\n\n\trenderSpeakers () {\n\t\tvar dataStore = this.context.dataStore\n\t\tvar speakerIds = this.props.talk.speakers;\n\t\tvar speakers = speakerIds.map(speakerId => dataStore.getPerson(speakerId)).filter(speaker => speaker)\n\n\t\treturn speakers.map((speaker, i) => {\n\t\t\treturn <img className=\"ListItem__avatar ScheduleItem__avatar-img\" key={'avatar_' + i} src={speaker.picture}/>\n\t\t})\n\t},\n\n\trender () {\n\t\tvar onNow = this.props.onNow ? <Blink className=\"ScheduleItem__now\">On Now</Blink> : null;\n\t\tvar talk = this.props.talk;\n\t\tvar linkClassName = classnames('ListItem ScheduleItem', {\n\t\t\t'is-past': this.props.finished\n\t\t}, ('ScheduleItem--' + talk.type));\n\t\tvar avatarWrapperClassName = classnames('ScheduleItem__avatar', {\n\t\t\t'ScheduleItem__avatar--multiple': talk.speakers && talk.speakers.length > 1\n\t\t});\n\t\tvar renderTheDisclosureArrow = (talk.type <= 1) ? <span className=\"ScheduleItem__avatar-chevron ion-chevron-right\" /> : null;\n\t\tvar startTime = moment(talk.start_date).utcOffset('+0200').format('h:mma')\n\n\t\treturn (\n\t\t\t<Link to=\"main:talk\" transition=\"show-from-right\" viewProps={{ talk: talk }} className={linkClassName} component=\"div\">\n\t\t\t\t<div className=\"ListItem__content ScheduleItem__content\">\n\t\t\t\t\t{onNow}\n\t\t\t\t\t<div className=\"ListItem__text ScheduleItem__text\">{startTime}</div>\n\t\t\t\t\t<div className=\"ListItem__heading ScheduleItem__heading\">{talk.title}</div>\n\t\t\t\t</div>\n\t\t\t\t<div className={avatarWrapperClassName}>\n\t\t\t\t\t{(talk.speakers) ? this.renderSpeakers() : null}\n\t\t\t\t\t{renderTheDisclosureArrow}\n\t\t\t\t</div>\n\t\t\t</Link>\n\t\t);\n\t}\n});\n"
  },
  {
    "path": "src/js/views/schedule/talk.js",
    "content": "var Container = require('react-container');\nvar FeedbackModal = require('../../components/FeedbackModal');\nvar moment = require('moment');\nvar React = require('react');\nvar Tappable = require('react-tappable');\nvar { Link, Transitions } = require('../../touchstone');\n\nvar Sentry = require('react-sentry');\nvar EventEmitter = require('events').EventEmitter;\n\nvar classnames = require('classnames')\nvar emitter = new EventEmitter();\n\nfunction getNavigation (props) {\n\tvar leftLabel = 'Schedule';\n\tif (props.previousView === 'person') {\n\t\tleftLabel = 'Person';\n\t}\n\n\treturn {\n\t\tleftArrow: true,\n\t\tleftLabel: leftLabel,\n\t\tleftAction: emitter.emit.bind(emitter, 'navigationBarLeftAction'),\n\t\trightArrow: false,\n\t\trightAction: null,\n\t\ttitle: 'Talk'\n\t}\n}\n\nmodule.exports = React.createClass({\n\tdisplayName: 'Talk',\n\tmixins: [Sentry(), Transitions],\n\tcontextTypes: {\n\t\tdataStore: React.PropTypes.object.isRequired\n\t},\n\n\tstatics: {\n\t\tnavigationBar: 'main',\n\t\tgetNavigation: getNavigation\n\t},\n\n\tgetDefaultProps () {\n\t\treturn {\n\t\t\tpreviousView: 'schedule'\n\t\t};\n\t},\n\n\tgetInitialState () {\n\t\treturn {\n\t\t\tfeedbackModalIsVisible: false,\n\t\t\tfeedbackType: this.props.feedback && this.props.talk.feedback.type || '',\n\t\t\tfeedbackText: this.props.feedback && this.props.talk.feedback.text || '',\n\t\t\tonline: window.navigator.onLine\n\t\t};\n\t},\n\n\tcomponentDidMount () {\n\t\tvar self = this;\n\t\tvar gotoView = 'main:tabs:schedule';\n\t\tif (this.props.previousView === 'person') {\n\t\t\tgotoView = 'main:person';\n\t\t}\n\n\t\t// android backbutton handler\n\t\tthis.watch(document, 'backbutton', function () {\n\t\t\tself.transitionTo(gotoView, {\n\t\t\t\ttransition: 'reveal-from-right',\n\t\t\t\tviewProps: self.props.previousViewProps\n\t\t\t});\n\t\t});\n\n\t\t// navbar actions\n\t\tthis.watch(emitter, 'navigationBarLeftAction', () => {\n\t\t\tself.transitionTo(gotoView, {\n\t\t\t\ttransition: 'reveal-from-right',\n\t\t\t\tviewProps: self.props.previousViewProps\n\t\t\t});\n\t\t});\n\n\t\t// online status\n\t\tthis.watch(window, 'online', this.updateOnlineStatus);\n\t\tthis.watch(window, 'offline', this.updateOnlineStatus);\n\t},\n\n\tupdateOnlineStatus (event) {\n\t\tthis.setState({\n\t\t\tonline: window.navigator.onLine\n\t\t});\n\t},\n\n\ttweetThisTalk () {\n\t\tif (!window.plugins) return window.alert('Sorry, sharing is not available with this device.')\n\n\t\tvar dataStore = this.context.dataStore\n\t\tvar eventTwitter = dataStore.getSettings().eventTwitter;\n\t\tvar speakers = this.props.talk.speakers.map(speakerId => dataStore.getPerson(speakerId));\n\t\tvar speakerText = speakers.map(speaker => speaker.twitter ? ('@' + speaker.twitter) : speaker.name).join(' and ');\n\n\t\tvar preComposedTweet = 'Watching ' + speakerText + ' talk about ' + this.props.talk.title + ' at @' + eventTwitter;\n\n\t\treturn window.plugins.socialsharing.shareViaTwitter(preComposedTweet);\n\t},\n\n\tsubmitFeedback (e) {\n\t\tthis.closeFeedbackModal();\n\n\t\tthis.context.dataStore.feedback(this.props.talk.id, {\n\t\t\ttype: this.state.feedbackType,\n\t\t\ttext: this.state.feedbackText\n\t\t});\n\t},\n\n\topenFeedbackModal () {\n\t\tvar scrollableContainer = this.refs.scrollableContainer.getDOMNode();\n\n\t\tthis.setState({ feedbackModalIsVisible: true }, function () {\n\t\t\tscrollableContainer.style.overflow = 'hidden'\n\t\t});\n\t},\n\n\tcloseFeedbackModal () {\n\t\tvar scrollableContainer = this.refs.scrollableContainer.getDOMNode();\n\n\t\tthis.setState({ feedbackModalIsVisible: false }, function () {\n\t\t\tscrollableContainer.style.overflow = 'scroll'\n\t\t});\n\t},\n\n\tupdateFeedbackType (type) {\n\t\tthis.setState({ feedbackType: type });\n\t},\n\n\tupdateFeedbackText (e) {\n\t\tthis.setState({ feedbackText: e.target.value });\n\t},\n\n\tcancelFeedback () {\n\t\tthis.closeFeedbackModal();\n\t\tthis.setState(this.getInitialState());\n\t},\n\n\trenderFeedbackModal () {\n\t\tvar positiveButtonClass = classnames('FeedbackModal__button', 'FeedbackModal__button--positive', {\n\t\t\t'is-selected': this.state.feedbackType === 'positive'\n\t\t});\n\t\tvar negativeButtonClass = classnames('FeedbackModal__button', 'FeedbackModal__button--negative', {\n\t\t\t'is-selected': this.state.feedbackType === 'negative'\n\t\t});\n\t\tvar inputClass = classnames('FeedbackModal__body__input', {\n\t\t\t'has-value': this.state.feedbackText.length > 0\n\t\t});\n\n\t\treturn (\n\t\t\t<FeedbackModal visible={this.state.feedbackModalIsVisible}>\n\t\t\t\t<div className=\"FeedbackModal__form\">\n\t\t\t\t\t<div className=\"FeedbackModal__header\">\n\t\t\t\t\t\t<div className=\"FeedbackModal__title\">What did you think of this talk?</div>\n\t\t\t\t\t\t<div className=\"FeedbackModal__subtitle\">Feedback is private and anonymous</div>\n\t\t\t\t\t\t<div className=\"FeedbackModal__buttons\">\n\t\t\t\t\t\t\t<Tappable onTap={this.updateFeedbackType.bind(this, 'positive')} className={positiveButtonClass} />\n\t\t\t\t\t\t\t<Tappable onTap={this.updateFeedbackType.bind(this, 'negative')} className={negativeButtonClass} />\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div className=\"FeedbackModal__body\">\n\t\t\t\t\t\t<textarea value={this.state.feedbackText} onChange={this.updateFeedbackText} placeholder=\"Leave feedback for the speaker...\" className={inputClass} />\n\t\t\t\t\t</div>\n\t\t\t\t\t<div className=\"FeedbackModal__footer\">\n\t\t\t\t\t\t{this.state.online ? (\n\t\t\t\t\t\t\t<Tappable onTap={this.submitFeedback} className=\"FeedbackModal__footer__button FeedbackModal__footer__button--primary\">Save</Tappable>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<span className=\"FeedbackModal__footer__button FeedbackModal__footer__button--disabled\">Offline</span>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t<Tappable onTap={this.cancelFeedback} className=\"FeedbackModal__footer__button FeedbackModal__footer__button--link\">Cancel</Tappable>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</FeedbackModal>\n\t\t);\n\t},\n\n\trenderSpeakers () {\n\t\tvar previousView = this.props.previousView;\n\t\tvar dataStore = this.context.dataStore;\n\t\tvar speakers = this.props.talk.speakers || [];\n\t\tvar self = this;\n\n\t\treturn speakers.map(function (speaker, i) {\n\t\t\tvar viewProps = {\n\t\t\t\tperson: speaker,\n\t\t\t\tpreviousView: 'talk',\n\t\t\t\tpreviousViewProps: self.props\n\t\t\t};\n\n\t\t\t// if the user hasn't arrived from the person view, link through to the person\n\t\t\t// otherwise we create a weird loop\n\t\t\treturn previousView === 'person' ? (\n\t\t\t\t<div className=\"TalkDetails__speaker\" key={'speaker' + i}>\n\t\t\t\t\t<img src={speaker.picture || speaker.avatar_url} className=\"TalkDetails__speaker__avatar\" />\n\t\t\t\t\t<div className=\"TalkDetails__speaker__name\">{speaker.name}</div>\n\t\t\t\t</div>\n\t\t\t) : (\n\t\t\t\t<Link key={'speaker' + i} to=\"main:person\" transition=\"show-from-right\" className=\"TalkDetails__speaker\" viewProps={viewProps} component=\"div\">\n\t\t\t\t\t<img src={speaker.picture || speaker.avatar_url} className=\"TalkDetails__speaker__avatar\" />\n\t\t\t\t\t<div className=\"TalkDetails__speaker__name\">{speaker.name}</div>\n\t\t\t\t\t<span className=\"ion-chevron-right\" />\n\t\t\t\t</Link>\n\t\t\t);\n\t\t});\n\t},\n\n\trender () {\n\t\tvar talk = this.props.talk;\n\t\tvar talkTime = moment(talk.start_date).utcOffset('+0200').format('h:mma');\n\n\t\t// handle feedback button / icon state\n\t\tvar feedbackButtonClass = classnames('TalkDetails__button', 'button-table__item', {\n\t\t\t'is-disabled': !this.context.dataStore.amRegistered()\n\t\t});\n\t\tvar feedbackButtonIcon = classnames('button-table__item__icon', {\n\t\t\t'TalkDetails__button__icon': this.state.feedbackType,\n\t\t\t'ion-thumbsup': !this.state.feedbackType,\n\t\t\t'ion-thumbsup is-positive': this.state.feedbackType === 'positive',\n\t\t\t'ion-thumbsdown is-negative': this.state.feedbackType === 'negative'\n\t\t});\n\n\t\treturn (\n\t\t\t<Container fill>\n\t\t\t\t<Container scrollable className=\"TalkDetails\" ref=\"scrollableContainer\">\n\t\t\t\t\t<div className=\"TalkDetails__details\">\n\t\t\t\t\t\t<div className=\"TalkDetails__text text-block\">{talkTime}</div>\n\t\t\t\t\t\t<div className=\"TalkDetails__heading\">{talk.title}</div>\n\t\t\t\t\t\t<div className=\"TalkDetails__speakers\">\n\t\t\t\t\t\t\t{this.renderSpeakers()}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div className=\"TalkDetails__text text-block\" dangerouslySetInnerHTML={{__html: talk.description}} />\n\t\t\t\t\t</div>\n\t\t\t\t\t<div className=\"TalkDetails__buttons button-table\">\n\t\t\t\t\t\t<Tappable onTap={this.tweetThisTalk} className=\"TalkDetails__button button-table__item\">\n\t\t\t\t\t\t\t<span className=\"TalkDetails__button__icon button-table__item__icon ion-social-twitter\" />\n\t\t\t\t\t\t\t<div className=\"button-table__item__label\">Tweet this talk</div>\n\t\t\t\t\t\t</Tappable>\n\t\t\t\t\t\t<Tappable onTap={this.openFeedbackModal} className={feedbackButtonClass}>\n\t\t\t\t\t\t\t<span className={feedbackButtonIcon} />\n\t\t\t\t\t\t\t<div className=\"button-table__item__label\">Leave feedback</div>\n\t\t\t\t\t\t</Tappable>\n\t\t\t\t\t</div>\n\t\t\t\t</Container>\n\t\t\t\t{this.renderFeedbackModal()}\n\t\t\t</Container>\n\t\t);\n\t}\n});\n"
  }
]