diff --git a/Import files from another server/.debug b/Import files from another server/.debug
new file mode 100644
index 0000000..0528b06
--- /dev/null
+++ b/Import files from another server/.debug
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Import files from another server/.gitignore b/Import files from another server/.gitignore
new file mode 100644
index 0000000..883aea4
--- /dev/null
+++ b/Import files from another server/.gitignore
@@ -0,0 +1,3 @@
+.DS_Store
+node_modules
+client/js/lib/CSInterface.js
diff --git a/Import files from another server/com.cep.import/CSXS/manifest.xml b/Import files from another server/com.cep.import/CSXS/manifest.xml
new file mode 100644
index 0000000..b9c2ba8
--- /dev/null
+++ b/Import files from another server/com.cep.import/CSXS/manifest.xml
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ./client/index.html
+ ./host/index.jsx
+
+
+ true
+
+
+ Panel
+
+
+
+ 500
+ 350
+
+
+ 200
+ 200
+
+
+ 600
+ 400
+
+
+
+
+
+
+
+
+
+ ./client/localServer.html
+
+ --enable-nodejs
+ --mixed-context
+
+
+
+ false
+
+
+ Custom
+
+
+ 500
+ 350
+
+
+
+
+
+
+
+
diff --git a/Import files from another server/com.cep.import/client/index.html b/Import files from another server/com.cep.import/client/index.html
new file mode 100644
index 0000000..f519f24
--- /dev/null
+++ b/Import files from another server/com.cep.import/client/index.html
@@ -0,0 +1,19 @@
+
+
+
+
+ Import Example Panel
+
+
+
Import Example Panel
+
+
+
Choose your download location
+
+
+
+
+
+
+
+
diff --git a/Import files from another server/com.cep.import/client/index.js b/Import files from another server/com.cep.import/client/index.js
new file mode 100644
index 0000000..a47701d
--- /dev/null
+++ b/Import files from another server/com.cep.import/client/index.js
@@ -0,0 +1,69 @@
+/*
+ CSInterface
+*/
+var csInterface = new CSInterface();
+
+/*
+ UI Elements
+*/
+var importButton = document.querySelector("#import-button");
+var documentsButton = document.querySelector("#documents-button");
+var extensionButton = document.querySelector("#extension-button");
+var downloadOptions = document.querySelector("#download-options");
+
+/*
+ Event listeners
+*/
+importButton.addEventListener("click", importToggle);
+documentsButton.addEventListener("click", function(){importTo('documents');}, false);
+extensionButton.addEventListener("click", function(){importTo('extension');}, false);
+
+/*
+ User folder paths
+*/
+var extensionDirectory = csInterface.getSystemPath("extension");
+var documentsDirectory = csInterface.getSystemPath("myDocuments");
+
+/*
+ Starting Node JS
+*/
+csInterface.requestOpenExtension("com.cep.import.localserver", "");
+
+/*
+ Helper methods
+*/
+function importToggle() {
+ if (downloadOptions.style.display === "none") {
+ downloadOptions.style.display = "block";
+ importButton.innerText = "Cacel";
+ } else {
+ downloadOptions.style.display = "none";
+ importButton.innerText = "Import from external server";
+ }
+}
+
+function importTo(location) {
+ var directory = location == "documents" ? documentsDirectory : extensionDirectory;
+ var url = "http://localhost:3200/import";
+
+ $.ajax({
+ type: "GET",
+ url: url,
+ headers: {
+ "directory": directory
+ },
+ success: response => {
+ downloadOptions.style.display = "none";
+ importButton.innerText = "Import from external server";
+ alert(`File imported. Location: ${response}`);
+ csInterface.evalScript(`displayFile("${response}")`);
+ },
+ error: (jqXHR, textStatus, errorThrown) => {
+ console.log("error");
+ alert(errorThrown, jqXHR.responseJSON);
+ }
+ })
+
+}
+
+
diff --git a/Import files from another server/com.cep.import/client/js/lib/DownloadCSInterfaceHere.md b/Import files from another server/com.cep.import/client/js/lib/DownloadCSInterfaceHere.md
new file mode 100644
index 0000000..f4bd138
--- /dev/null
+++ b/Import files from another server/com.cep.import/client/js/lib/DownloadCSInterfaceHere.md
@@ -0,0 +1,2 @@
+## Access Adobe CEP Repository at https://github.com/Adobe-CEP/CEP-Resources/
+## Copy and paste the newest version of CSInterface.js that's compatible with your version of Creative Cloud
\ No newline at end of file
diff --git a/Import files from another server/com.cep.import/client/localServer.html b/Import files from another server/com.cep.import/client/localServer.html
new file mode 100644
index 0000000..e6d9fd7
--- /dev/null
+++ b/Import files from another server/com.cep.import/client/localServer.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+ Import Example App
+
+
+
+
+
diff --git a/Import files from another server/com.cep.import/host/index.jsx b/Import files from another server/com.cep.import/host/index.jsx
new file mode 100644
index 0000000..1c4ef49
--- /dev/null
+++ b/Import files from another server/com.cep.import/host/index.jsx
@@ -0,0 +1,6 @@
+function displayFile(path) {
+ if (app.name == "Adobe Photoshop") {
+ var fileRef = new File(path)
+ app.open(fileRef)
+ }
+}
diff --git a/Import files from another server/com.cep.import/package-lock.json b/Import files from another server/com.cep.import/package-lock.json
new file mode 100644
index 0000000..f20fbbb
--- /dev/null
+++ b/Import files from another server/com.cep.import/package-lock.json
@@ -0,0 +1,763 @@
+{
+ "name": "adobe-import-example-panel",
+ "version": "1.0.0",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "accepts": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz",
+ "integrity": "sha1-hiRnWMfdbSGmR0/whKR0DsBesh8=",
+ "requires": {
+ "mime-types": "2.1.18",
+ "negotiator": "0.6.1"
+ }
+ },
+ "ajv": {
+ "version": "5.5.2",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
+ "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
+ "requires": {
+ "co": "4.6.0",
+ "fast-deep-equal": "1.0.0",
+ "fast-json-stable-stringify": "2.0.0",
+ "json-schema-traverse": "0.3.1"
+ }
+ },
+ "array-flatten": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+ "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
+ },
+ "asn1": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
+ "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y="
+ },
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
+ },
+ "asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
+ },
+ "aws-sign2": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+ "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
+ },
+ "aws4": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
+ "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4="
+ },
+ "basic-auth": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.0.tgz",
+ "integrity": "sha1-AV2z81PgLlY3d1X5YnQuiYHnu7o=",
+ "requires": {
+ "safe-buffer": "5.1.1"
+ }
+ },
+ "bcrypt-pbkdf": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
+ "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
+ "optional": true,
+ "requires": {
+ "tweetnacl": "0.14.5"
+ }
+ },
+ "body-parser": {
+ "version": "1.18.2",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz",
+ "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=",
+ "requires": {
+ "bytes": "3.0.0",
+ "content-type": "1.0.4",
+ "debug": "2.6.9",
+ "depd": "1.1.2",
+ "http-errors": "1.6.2",
+ "iconv-lite": "0.4.19",
+ "on-finished": "2.3.0",
+ "qs": "6.5.1",
+ "raw-body": "2.3.2",
+ "type-is": "1.6.16"
+ }
+ },
+ "boom": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz",
+ "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=",
+ "requires": {
+ "hoek": "4.2.1"
+ }
+ },
+ "bytes": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
+ "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg="
+ },
+ "caseless": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
+ },
+ "co": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+ "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ="
+ },
+ "combined-stream": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz",
+ "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=",
+ "requires": {
+ "delayed-stream": "1.0.0"
+ }
+ },
+ "content-disposition": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
+ "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ="
+ },
+ "content-type": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
+ },
+ "cookie": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
+ "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s="
+ },
+ "cookie-signature": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+ "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
+ },
+ "cryptiles": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz",
+ "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=",
+ "requires": {
+ "boom": "5.2.0"
+ },
+ "dependencies": {
+ "boom": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz",
+ "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==",
+ "requires": {
+ "hoek": "4.2.1"
+ }
+ }
+ }
+ },
+ "dashdash": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+ "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+ "requires": {
+ "assert-plus": "1.0.0"
+ }
+ },
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
+ },
+ "depd": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
+ },
+ "destroy": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
+ "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
+ },
+ "ecc-jsbn": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
+ "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
+ "optional": true,
+ "requires": {
+ "jsbn": "0.1.1"
+ }
+ },
+ "ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
+ },
+ "encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
+ },
+ "escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
+ },
+ "etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
+ },
+ "express": {
+ "version": "4.16.2",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.16.2.tgz",
+ "integrity": "sha1-41xt/i1kt9ygpc1PIXgb4ymeB2w=",
+ "requires": {
+ "accepts": "1.3.4",
+ "array-flatten": "1.1.1",
+ "body-parser": "1.18.2",
+ "content-disposition": "0.5.2",
+ "content-type": "1.0.4",
+ "cookie": "0.3.1",
+ "cookie-signature": "1.0.6",
+ "debug": "2.6.9",
+ "depd": "1.1.2",
+ "encodeurl": "1.0.2",
+ "escape-html": "1.0.3",
+ "etag": "1.8.1",
+ "finalhandler": "1.1.0",
+ "fresh": "0.5.2",
+ "merge-descriptors": "1.0.1",
+ "methods": "1.1.2",
+ "on-finished": "2.3.0",
+ "parseurl": "1.3.2",
+ "path-to-regexp": "0.1.7",
+ "proxy-addr": "2.0.3",
+ "qs": "6.5.1",
+ "range-parser": "1.2.0",
+ "safe-buffer": "5.1.1",
+ "send": "0.16.1",
+ "serve-static": "1.13.1",
+ "setprototypeof": "1.1.0",
+ "statuses": "1.3.1",
+ "type-is": "1.6.16",
+ "utils-merge": "1.0.1",
+ "vary": "1.1.2"
+ },
+ "dependencies": {
+ "setprototypeof": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
+ "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ=="
+ },
+ "statuses": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
+ "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4="
+ }
+ }
+ },
+ "extend": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
+ "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ="
+ },
+ "extsprintf": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+ "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
+ },
+ "fast-deep-equal": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz",
+ "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8="
+ },
+ "fast-json-stable-stringify": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
+ "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I="
+ },
+ "finalhandler": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz",
+ "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=",
+ "requires": {
+ "debug": "2.6.9",
+ "encodeurl": "1.0.2",
+ "escape-html": "1.0.3",
+ "on-finished": "2.3.0",
+ "parseurl": "1.3.2",
+ "statuses": "1.3.1",
+ "unpipe": "1.0.0"
+ },
+ "dependencies": {
+ "statuses": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
+ "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4="
+ }
+ }
+ },
+ "forever-agent": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+ "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
+ },
+ "form-data": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz",
+ "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=",
+ "requires": {
+ "asynckit": "0.4.0",
+ "combined-stream": "1.0.6",
+ "mime-types": "2.1.18"
+ }
+ },
+ "forwarded": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
+ "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
+ },
+ "fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
+ },
+ "getpass": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+ "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+ "requires": {
+ "assert-plus": "1.0.0"
+ }
+ },
+ "har-schema": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+ "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
+ },
+ "har-validator": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz",
+ "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=",
+ "requires": {
+ "ajv": "5.5.2",
+ "har-schema": "2.0.0"
+ }
+ },
+ "hawk": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz",
+ "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==",
+ "requires": {
+ "boom": "4.3.1",
+ "cryptiles": "3.1.2",
+ "hoek": "4.2.1",
+ "sntp": "2.1.0"
+ }
+ },
+ "hoek": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz",
+ "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA=="
+ },
+ "http-errors": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz",
+ "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=",
+ "requires": {
+ "depd": "1.1.1",
+ "inherits": "2.0.3",
+ "setprototypeof": "1.0.3",
+ "statuses": "1.4.0"
+ },
+ "dependencies": {
+ "depd": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
+ "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k="
+ }
+ }
+ },
+ "http-signature": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+ "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+ "requires": {
+ "assert-plus": "1.0.0",
+ "jsprim": "1.4.1",
+ "sshpk": "1.13.1"
+ }
+ },
+ "iconv-lite": {
+ "version": "0.4.19",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
+ "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ=="
+ },
+ "inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+ },
+ "ipaddr.js": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.6.0.tgz",
+ "integrity": "sha1-4/o1e3c9phnybpXwSdBVxyeW+Gs="
+ },
+ "is-typedarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
+ },
+ "isstream": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
+ },
+ "jquery": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.3.1.tgz",
+ "integrity": "sha512-Ubldcmxp5np52/ENotGxlLe6aGMvmF4R8S6tZjsP6Knsaxd/xp3Zrh50cG93lR6nPXyUFwzN3ZSOQI0wRJNdGg=="
+ },
+ "jsbn": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
+ "optional": true
+ },
+ "json-schema": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+ "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
+ },
+ "json-schema-traverse": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
+ "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A="
+ },
+ "json-stringify-safe": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
+ },
+ "jsprim": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
+ "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
+ "requires": {
+ "assert-plus": "1.0.0",
+ "extsprintf": "1.3.0",
+ "json-schema": "0.2.3",
+ "verror": "1.10.0"
+ }
+ },
+ "media-typer": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+ "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
+ },
+ "merge-descriptors": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+ "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
+ },
+ "methods": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+ "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
+ },
+ "mime": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
+ "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ=="
+ },
+ "mime-db": {
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz",
+ "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ=="
+ },
+ "mime-types": {
+ "version": "2.1.18",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz",
+ "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==",
+ "requires": {
+ "mime-db": "1.33.0"
+ }
+ },
+ "morgan": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.0.tgz",
+ "integrity": "sha1-0B+mxlhZt2/PMbPLU6OCGjEdgFE=",
+ "requires": {
+ "basic-auth": "2.0.0",
+ "debug": "2.6.9",
+ "depd": "1.1.2",
+ "on-finished": "2.3.0",
+ "on-headers": "1.0.1"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ },
+ "negotiator": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
+ "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk="
+ },
+ "oauth-sign": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
+ "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM="
+ },
+ "on-finished": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+ "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
+ "requires": {
+ "ee-first": "1.1.1"
+ }
+ },
+ "on-headers": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz",
+ "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c="
+ },
+ "parseurl": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
+ "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M="
+ },
+ "path-to-regexp": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
+ "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
+ },
+ "performance-now": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
+ },
+ "proxy-addr": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.3.tgz",
+ "integrity": "sha512-jQTChiCJteusULxjBp8+jftSQE5Obdl3k4cnmLA6WXtK6XFuWRnvVL7aCiBqaLPM8c4ph0S4tKna8XvmIwEnXQ==",
+ "requires": {
+ "forwarded": "0.1.2",
+ "ipaddr.js": "1.6.0"
+ }
+ },
+ "punycode": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
+ },
+ "qs": {
+ "version": "6.5.1",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
+ "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A=="
+ },
+ "range-parser": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
+ "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4="
+ },
+ "raw-body": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz",
+ "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=",
+ "requires": {
+ "bytes": "3.0.0",
+ "http-errors": "1.6.2",
+ "iconv-lite": "0.4.19",
+ "unpipe": "1.0.0"
+ }
+ },
+ "request": {
+ "version": "2.83.0",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz",
+ "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==",
+ "requires": {
+ "aws-sign2": "0.7.0",
+ "aws4": "1.6.0",
+ "caseless": "0.12.0",
+ "combined-stream": "1.0.6",
+ "extend": "3.0.1",
+ "forever-agent": "0.6.1",
+ "form-data": "2.3.2",
+ "har-validator": "5.0.3",
+ "hawk": "6.0.2",
+ "http-signature": "1.2.0",
+ "is-typedarray": "1.0.0",
+ "isstream": "0.1.2",
+ "json-stringify-safe": "5.0.1",
+ "mime-types": "2.1.18",
+ "oauth-sign": "0.8.2",
+ "performance-now": "2.1.0",
+ "qs": "6.5.1",
+ "safe-buffer": "5.1.1",
+ "stringstream": "0.0.5",
+ "tough-cookie": "2.3.3",
+ "tunnel-agent": "0.6.0",
+ "uuid": "3.2.1"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
+ "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
+ },
+ "send": {
+ "version": "0.16.1",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.16.1.tgz",
+ "integrity": "sha512-ElCLJdJIKPk6ux/Hocwhk7NFHpI3pVm/IZOYWqUmoxcgeyM+MpxHHKhb8QmlJDX1pU6WrgaHBkVNm73Sv7uc2A==",
+ "requires": {
+ "debug": "2.6.9",
+ "depd": "1.1.2",
+ "destroy": "1.0.4",
+ "encodeurl": "1.0.2",
+ "escape-html": "1.0.3",
+ "etag": "1.8.1",
+ "fresh": "0.5.2",
+ "http-errors": "1.6.2",
+ "mime": "1.4.1",
+ "ms": "2.0.0",
+ "on-finished": "2.3.0",
+ "range-parser": "1.2.0",
+ "statuses": "1.3.1"
+ },
+ "dependencies": {
+ "statuses": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
+ "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4="
+ }
+ }
+ },
+ "serve-static": {
+ "version": "1.13.1",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.1.tgz",
+ "integrity": "sha512-hSMUZrsPa/I09VYFJwa627JJkNs0NrfL1Uzuup+GqHfToR2KcsXFymXSV90hoyw3M+msjFuQly+YzIH/q0MGlQ==",
+ "requires": {
+ "encodeurl": "1.0.2",
+ "escape-html": "1.0.3",
+ "parseurl": "1.3.2",
+ "send": "0.16.1"
+ }
+ },
+ "setprototypeof": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz",
+ "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ="
+ },
+ "sntp": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz",
+ "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==",
+ "requires": {
+ "hoek": "4.2.1"
+ }
+ },
+ "sshpk": {
+ "version": "1.13.1",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz",
+ "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=",
+ "requires": {
+ "asn1": "0.2.3",
+ "assert-plus": "1.0.0",
+ "bcrypt-pbkdf": "1.0.1",
+ "dashdash": "1.14.1",
+ "ecc-jsbn": "0.1.1",
+ "getpass": "0.1.7",
+ "jsbn": "0.1.1",
+ "tweetnacl": "0.14.5"
+ }
+ },
+ "statuses": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
+ "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew=="
+ },
+ "stringstream": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
+ "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg="
+ },
+ "tough-cookie": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz",
+ "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=",
+ "requires": {
+ "punycode": "1.4.1"
+ }
+ },
+ "tunnel-agent": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+ "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+ "requires": {
+ "safe-buffer": "5.1.1"
+ }
+ },
+ "tweetnacl": {
+ "version": "0.14.5",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+ "optional": true
+ },
+ "type-is": {
+ "version": "1.6.16",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz",
+ "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==",
+ "requires": {
+ "media-typer": "0.3.0",
+ "mime-types": "2.1.18"
+ }
+ },
+ "unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
+ },
+ "utils-merge": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+ "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
+ },
+ "uuid": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz",
+ "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA=="
+ },
+ "vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
+ },
+ "verror": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+ "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+ "requires": {
+ "assert-plus": "1.0.0",
+ "core-util-is": "1.0.2",
+ "extsprintf": "1.3.0"
+ }
+ }
+ }
+}
diff --git a/Import files from another server/com.cep.import/package.json b/Import files from another server/com.cep.import/package.json
new file mode 100644
index 0000000..d56e327
--- /dev/null
+++ b/Import files from another server/com.cep.import/package.json
@@ -0,0 +1,18 @@
+{
+ "name": "adobe-import-example-panel",
+ "version": "1.0.0",
+ "description": "",
+ "main": "server/main.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "author": "",
+ "license": "ISC",
+ "dependencies": {
+ "body-parser": "^1.18.2",
+ "express": "^4.16.2",
+ "jquery": "^3.3.1",
+ "morgan": "^1.9.0",
+ "request": "^2.83.0"
+ }
+}
diff --git a/Import files from another server/com.cep.import/server/main.js b/Import files from another server/com.cep.import/server/main.js
new file mode 100644
index 0000000..ae81568
--- /dev/null
+++ b/Import files from another server/com.cep.import/server/main.js
@@ -0,0 +1,40 @@
+const express = require("express");
+const app = express();
+const request = require('request');
+const http = require('http');
+const path = require("path");
+const bodyParser = require("body-parser");
+const logger = require("morgan");
+const fs = require('fs');
+const httpServer = http.Server(app);
+
+module.exports = run
+
+function run(){
+ var port = 3200;
+ var hostname = "localhost"
+ httpServer.listen(port);
+
+ app.use(logger("dev"));
+ app.use(bodyParser.json());
+ app.use(bodyParser.urlencoded({ limit: '50mb',extended: true }));
+ app.use(express.static(path.join(__dirname, "../client")));
+
+ app.get("/import", (req, res, next) => {
+
+ var path = req.headers["directory"] + "/placeholder.png"
+ var uri = "http://via.placeholder.com/350x150";
+
+ var saveImage = function(uri, filepath, callback){
+ request.head(uri, function(err, res, body){
+ request(uri).pipe(fs.createWriteStream(filepath)).on('close', callback);
+ });
+ };
+
+ saveImage(uri, path, function(){
+ res.status(200).send(path)
+ });
+
+
+ });
+}
\ No newline at end of file
diff --git a/Import files from another server/readme-assets/folder-structure.png b/Import files from another server/readme-assets/folder-structure.png
new file mode 100644
index 0000000..9a0a0e1
Binary files /dev/null and b/Import files from another server/readme-assets/folder-structure.png differ
diff --git a/Import files from another server/readme.md b/Import files from another server/readme.md
new file mode 100644
index 0000000..a85bbca
--- /dev/null
+++ b/Import files from another server/readme.md
@@ -0,0 +1,453 @@
+# Importing files from the network
+Many Creative Cloud app extensions require the ability to talk to API services on the web. With both Chromium Embedded Framework (CEF) and Node.js at its core, CEP gives you the flexibility to make network calls from within your extension in the way that makes sense for your workflow.
+
+This guide and its companion sample extension will show you how you can create a Node.js-based extension to allow users to retrieve files from an external server/url and load them in Adobe host applications.
+
+By the end of this guide, we will have an Adobe Photoshop extension that:
+
+1. Downloads an image from a url and saves it in a user-specified location on the local machine
+1. Loads the image in Photoshop
+
+
+
+
+
+
+## Contents
+
+1. [Technology Used](#technology-used)
+1. [Prerequisites](#prerequisites)
+1. [Folder Structure](#folder-structure)
+1. [Configuration Setup](#configuration-setup)
+1. [Client-side: HTML Markup for user-facing extension](#client-side-html-markup-for-user-facing-extension)
+1. [Client-side: HTML Markup for Node.js server extension](#client-side-html-markup-for-nodejs-server-extension)
+1. [Client-side: Service API interaction](#client-side-service-api-interaction)
+1. [Host app: Automation with ExtendScript](#host-app-automation-with-extendscript)
+1. [Server-side: Setup](#server-side-setup)
+1. [Troubleshooting and Known Issues](#troubleshooting-and-known-issues)
+1. [Other Resources](#other-resources)
+
+
+
+
+## Technology Used
+
+- Supported Host Applications: Photoshop
+- Libraries/Frameworks/APIs:
+ - Adobe-specific: [CEP](https://github.com/Adobe-CEP/CEP-Resources)
+ - Other: [jQuery](https://jquery.com/), [Dropbox Auth API](https://www.dropbox.com/developers/reference/oauth-guide)
+
+
+## Prerequisites
+This guide will assume that you have installed all software and completed all steps in the following guides:
+
+- [Getting Started Guide](https://github.com/Adobe-CEP/Getting-Started-guides)
+
+## Folder Structure
+If you have a directory structure similar to the one suggested in the [Getting Started Guide](https://github.com/Adobe-CEP/Getting-Started-guides), all you have to add is a folder designated for your server, a Node.js file, a `main.js` file inside the server folder, and another HTML file, `localServer.html`, all under the existing client folder:
+
+
+
+The `main.js` file is a Node.js file where write server logic. The root directory can be saved either at the root level or at the user level, depending on who’s allowed to use the extension (refer to the [CEP 8 HTML Extension Cookbook](https://github.com/Adobe-CEP/CEP-Resources/blob/master/CEP_8.x/Documentation/CEP%208.0%20HTML%20Extension%20Cookbook.md#extension-folders) for the exact paths).
+
+Note that except for the required `CSXS` folder, which must contain manifest.xml, the folder structure is flexible.
+
+## Configuration Setup
+
+### Set up the sample extension
+
+The following steps will help you get the sample extension for this guide up and running:
+
+1. Install the `./com.cep.import/` directory in your `extensions` folder. ([See the Cookbook](https://github.com/Adobe-CEP/CEP-Resources/blob/master/CEP_8.x/Documentation/CEP%208.0%20HTML%20Extension%20Cookbook.md#extension-folders) if you are unsure where your `extensions` folder is.)
+1. [Download CEP's `CSInterface.js` library](https://github.com/Adobe-CEP/CEP-Resources/blob/master/CEP_8.x/CSInterface.js) and move it to `./com.cep.import/client/js/lib/CSInterface.js`.
+
+After following these steps, you'll be able to run the sample extension within the host apps indicated in the [Technology Used](#technology-used) section of this guide.
+
+### Configure `manifest.xml`
+
+As noted in the [Getting Started guide](https://github.com/Adobe-CEP/Getting-Started-guides), the `manifest.xml` file is where you set various configurations for your panel, such as supported host apps, panel type, CEF parameters, main path, script path, default/minimum/maximum panel size, and others. Refer to the latest version of XML schema in [CEP Github](https://github.com/Adobe-CEP/CEP-Resources/).
+
+**List supported host apps and versions**
+
+The first configuration to set in `manifest.xml` is indicating which Creative Cloud host apps and version numbers your extension supports. For this guide, we'll make an extension that supports Photoshop. So in the `manifest.xml`, make sure you list the supported host names for Photoshop within the `` element:
+
+```xml
+
+
+
+
+
+
+
+
+
+
+```
+
+Note that the versions indicated in the example code above only target a single version of each host app, for the sake of demo simplicity. Most extension developers will want to target a range of host app versions. To learn how to support multiple host app versions, [see the Cookbook](https://github.com/Adobe-CEP/CEP-Resources/blob/master/CEP_8.x/Documentation/CEP%208.0%20HTML%20Extension%20Cookbook.md#extension-manifest).
+
+**Configure the user-facing extension**
+
+This sample panel is comprised of two separate extensions. However, this does not mean that users will have to load two separate extensions. Only the user-facing panel will be visible to the user while the second extension will be loaded automatically in the background when a simple JavaScript CEP method is called (This will be covered later). Let's configure the user facing extension first.
+
+In the `manifest.xml`, there is a tag called `` which lists all extensions used in the panel. Let's list the main extension, which includes the client side and the host application side logic. As configured in `manifest.xml`, this extension will be visible to the user.
+
+```xml
+
+
+
+```
+
+The next step is to configure details for this main extension, `com.cep.import.panel`. You can insert configurations for this extension by starting with the `` tag under the `` tag:
+
+```xml
+
+
+ ...
+
+```
+
+Under this tag, you can provide details, such as type, script paths, menu name, and sizes:
+
+```xml
+
+
+
+ ./client/index.html
+ ./host/index.jsx
+
+
+ true
+
+
+ Panel
+
+
+
+ 500
+ 350
+
+
+ 200
+ 200
+
+
+ 600
+ 400
+
+
+
+
+
+
+```
+
+Now configurations for the main extension have been set up. The next step is to configure the invisible Node.js server extension.
+
+**Configure the invisible Node.js server extension**
+
+As mentioned above, there are two separate extensions in this sample panel. The purpose of the second extension,`com.cep.import.localserver`, is to set and start the Node.js server.
+
+Let's add this second extension to the `` tag.
+
+```xml
+
+
+
+
+```
+
+Similar to setting the main extension, you need to configure details for this invisible extension, `com.cep.import.localserver`. Note that you can insert multiple `` tags under the `` tag. You need to simply insert another `` tag for this server extension.
+
+```xml
+
+```
+
+Under this tag, you can provide details, such as type, script paths, menu name, and sizes:
+
+```xml
+
+
+
+ ./client/localServer.html
+
+ --enable-nodejs
+ --mixed-context
+
+
+
+ false
+
+
+ Custom
+
+
+ 500
+ 350
+
+
+
+
+
+
+```
+
+Note that since `com.cep.import.localserver` will be using Node.js, the two parameters, `--enable-nodejs` and `--mixed-context`, are added within `` as seen above. Also, the `` tag is set to `false` and the `` of the extension is set to `Custom`. This setting makes this server extension invisible to the user.
+
+## Client-side: HTML Markup for user-facing extension
+
+The user interface for CEP extensions is written in HTML. For this sample, you will need to create two HTML documents, one for each extension. Let's create a HTML for the main extension first.
+
+As written in the `` tag of the extension in the `manifest.xml` file, you will find the main HTML located at `./com.cep.import/client/index.html`. This HTML will be loaded and be visible to the user.
+
+See comments **#1-3**:
+
+```html
+
+
+
+
+ Import Example Panel
+
+
+
Import Example Panel
+
+
+
+
+
+
+
Choose your download location
+
+
+
+
+
+
+
+
+
+
+
+```
+
+This HTML markup for the main extension, `com.cep.import.panel`, is the HTML page users will see when they first launch your panel.
+
+## Client-side: HTML Markup for Node.js server extension
+
+As written in the `` tag of the server extension, another HTML markup will be loaded from `./com.cep.import/client/localServer.html` in the background and run the `cep_node` method to start the Node.JS server at `/server/main.js`. This HTML will be invisible to users as mentioned above.
+
+_Note: the server extension will load only after the main extension's JavaScript invokes `csInterface.requestOpenExtension()` function. This will be explained shortly in [the later section](#load-the-second-extension-for-running-an-express-server)_
+
+see comments **#1**:
+
+```html
+
+
+
+
+
+ Import Example App
+
+
+
+
+```
+
+The sole purpose of this HTML markup for the server extension, `com.cep.import.localserver`, is to start the Node.js server. This page will not be visible to users.
+
+## Client-side: Service API interaction
+As we saw in the previous section's `index.html` code, the client-side JavaScript for the main extension is located at `./com.cep.import/client/js/index.js`. We will look at this `index.js` file in this section.
+
+### Instantiate `CSInterface`
+For any CEP extension, you'll need an instance of `CSInterface`, which, among other things, gives you a way to communicate with the host app's scripting engine:
+
+```javascript
+var csInterface = new CSInterface();
+```
+
+We'll make use of this `csInterface` constant later on.
+
+### Load the second extension for running an Express server
+`csInterface` has a method called `requestOpenExtension`, which opens another extension given an extension ID. In this sample, this method is used to launch the server extension:
+
+```javascript
+csInterface.requestOpenExtension("com.cep.import.localserver", "");
+```
+
+Simply include the line above in your main extension’s JavaScript file, `client/index.js`. This will open the HTML markup of the invisible server extension. Then, JavaScript written in the HTML markup will start the Node.js server located at `/server/main.js`. Once the second extension is loaded, the Express located at `/server/main.js` will start as written in `/client/localServer.html`.
+
+### Create references to the UI elements
+In `index.js`, we'll first reference the elements in our `index.html`:
+
+```javascript
+var importButton = document.querySelector("#import-button");
+var documentsButton = document.querySelector("#documents-button");
+var extensionButton = document.querySelector("#extension-button");
+var downloadOptions = document.querySelector("#download-options");
+```
+
+We'll work with these UI elements in the next step.
+
+### Add a click handler to the button
+We'll add a click handler to the buttons:
+
+```javascript
+importButton.addEventListener("click", importToggle);
+documentsButton.addEventListener("click", function(){importTo('documents');}, false);
+extensionButton.addEventListener("click", function(){importTo('extension');}, false);
+```
+
+We'll make the `importToggle()` and `importTo()` helper methods in the next step.
+
+### Toggling button to show/hide options
+`importToggle()` helper function simply shows/hides the options and changes the text of the button dynamically.
+```
+function importToggle() {
+ if (downloadOptions.style.display === "none") {
+ downloadOptions.style.display = "block";
+ importButton.innerText = "Cacel";
+ } else {
+ downloadOptions.style.display = "none";
+ importButton.innerText = "Import from external server";
+ }
+}
+```
+
+### Getting the local path
+`CSInterface` has a method called `getSystemPath()` which returns the user's path. In this example, we only use two user paths. Refer to [CSInterface Documentation](https://github.com/Adobe-CEP/CEP-Resources/blob/master/CEP_8.x/CSInterface.js) for other paths.
+```
+var extensionDirectory = csInterface.getSystemPath("extension");
+var documentsDirectory = csInterface.getSystemPath("myDocuments");
+```
+We will use these directory variables in the following section.
+
+### Communicating with the server
+In this sample, `importTo()` uses `jQuery` to communicate with the server. (see comments **#1-6**)
+```javascript
+function importTo(location) {
+ /* 1) Uses the correct variable based on the user's input */
+ var directory = location == "documents" ? documentsDirectory : extensionDirectory;
+ /* 2) Server import endpoint */
+ var url = "http://localhost:3200/import";
+
+ $.ajax({
+ type: "GET",
+ url: url,
+ headers: {
+ "directory": directory
+ },
+ success: response => {
+ /* 3) Hide options */
+ downloadOptions.style.display = "none";
+
+ /* 4) Change the button text */
+ importButton.innerText = "Import from external server";
+
+ /* 5) Show the user where the file was saved */
+ alert(`File imported. Location: ${response}`);
+
+ /* 6) Use ExtendScript to show the file in Photoshop */
+ csInterface.evalScript(`displayFile("${response}")`);
+ },
+ error: (jqXHR, textStatus, errorThrown) => {
+ console.log("error");
+ alert(errorThrown, jqXHR.responseJSON);
+ }
+ })
+
+}
+```
+
+### Communicate with the host app
+To communicate with the host app's scripting engine, we'll make use of the `csInterface.evalScript()` method. (If you need a refresher on the `.evalScript()` method, refer to the [Getting Started guide](https://github.com/Adobe-CEP/Getting-Started-guides).)
+
+In this sample app, our `.evalScript()` call will be invoked once we get the response back from the server in the step above. We could interpret the `.evalScript()` call in the code above as meaning:
+
+> Hey host app, call the `displayFile()` function from my ExtendScript file.
+
+We’ll need to make sure that ExtendScript function exists in the next section.
+
+## Host app: Automation with ExtendScript
+Many CC host apps like Photoshop and InDesign (and many more) can be automated with ExtendScript. In this sample extension, we're going to simply display the downloaded asset in Photoshop.
+
+Note once again that this sample app is extremely simple for the purpose of focus. ExtendScript provides many deep features to automate work in CC host apps; you can explore more ExtendScript features in our Scripting Guides.
+
+The ExtendScript file for this extension is located at `./com.cep.import/host/index.jsx`.
+
+
+### Create an ExtendScript function
+In the extension's `index.jsx` file, let's create a function called `displayFile()`. (see comments **#1-3**):
+
+```javascript
+function displayFile(path) {
+ /* 1) First, check if the user is in the supported host app, Photoshop, in this case */
+ if (app.name == "Adobe Photoshop") {
+
+ /* 2) Create a file reference */
+ var fileRef = new File(path)
+
+ /* 3) Open the file inside Photoshop */
+ app.open(fileRef)
+ }
+}
+```
+
+The function runs and displays the downloaded asset in Photoshop. Note that this function does not `return` anything. However, you can write your ExtendScript function to `return` something, which can be captured in a callback like below:
+
+```javascript
+csInterface.evalScript('doSomething()', function(value){
+ console.log(value)
+})
+```
+
+## Server-side: Setup
+### Install Node.js and npm
+[Download and install Node.js and its package manager, npm](https://www.npmjs.com/get-npm), and make sure you have the `package.json` file in the root level directory of your panel.
+
+### Install node modules
+Make sure to install all node dependencies required by this extension.
+```
+npm install
+```
+
+### Write server logic in `main.js`
+This sample extension uses `express` and `http` to set up a server. Make sure to the same port, in this case, `3000`. While this example simply downloads an image from a url, you can imagin you can modifiy this to hit other APIs or your own server to retrieve data. (see comments **#1-4**):
+
+```
+app.get("/import", (req, res, next) => {
+
+ /* 1) Grab the desired directory from the headers and insert the default image name */
+ var path = req.headers["directory"] + "/placeholder.png"
+
+ /* 2) Note this uri variable can be a server endpoint as well */
+ var uri = "http://via.placeholder.com/350x150";
+
+ download(uri, path, function(){
+ /* 3) Once download is completed, send the path to the client side */
+ res.status(200).send(path)
+ });
+
+ /* 4) Helper function to download the asset using the fs module */
+ var download = function(uri, filepath, callback){
+ request.head(uri, function(err, res, body){
+ request(uri).pipe(fs.createWriteStream(filepath)).on('close', callback);
+ });
+ };
+
+});
+```
+
+After saving the file, the server simply responds with the path of the file, which is eventually used by `index.jsx` to load the image in Photoshop.
+
+## Troubleshooting and Known Issues
+Articles about common issues are [here](!LINK).
+
+You can submit tickets for bugs and feature requests [here](!LINK).
+
+## Other Resources
+- [CEP Cookbook](https://github.com/Adobe-CEP/CEP-Resources/blob/master/CEP_8.x/Documentation/CEP%208.0%20HTML%20Extension%20Cookbook.md)
+- [Photoshop ExtendScript](https://www.adobe.com/devnet/photoshop/scripting.html)