UNOMI-208 Improve documentation flow & document tracker integration

Signed-off-by: Serge Huber <shu...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/incubator-unomi/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-unomi/commit/cfe3158e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-unomi/tree/cfe3158e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-unomi/diff/cfe3158e

Branch: refs/heads/UNOMI-180-CXS-GRAPHQLAPI
Commit: cfe3158e7bb0fecd38e980e7d99e401f3c345ec8
Parents: 5e4cd37
Author: Serge Huber <shu...@apache.org>
Authored: Fri Nov 2 16:44:10 2018 +0100
Committer: Serge Huber <shu...@apache.org>
Committed: Fri Nov 2 16:44:10 2018 +0100

----------------------------------------------------------------------
 manual/src/main/asciidoc/5-min-quickstart.adoc  |  38 +++++++
 .../main/asciidoc/building-and-deploying.adoc   |  40 +-------
 manual/src/main/asciidoc/configuration.adoc     |   4 -
 manual/src/main/asciidoc/custom-extensions.adoc |  89 ----------------
 manual/src/main/asciidoc/getting-started.adoc   |   7 +-
 manual/src/main/asciidoc/index.adoc             |  30 +++---
 .../src/main/asciidoc/installing-tracker.adoc   |  44 ++++++++
 manual/src/main/asciidoc/patches.adoc           | 102 +++++++++++++++++++
 .../src/main/asciidoc/samples/login-sample.adoc |  10 --
 9 files changed, 208 insertions(+), 156 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/cfe3158e/manual/src/main/asciidoc/5-min-quickstart.adoc
----------------------------------------------------------------------
diff --git a/manual/src/main/asciidoc/5-min-quickstart.adoc 
b/manual/src/main/asciidoc/5-min-quickstart.adoc
new file mode 100644
index 0000000..5bb2e20
--- /dev/null
+++ b/manual/src/main/asciidoc/5-min-quickstart.adoc
@@ -0,0 +1,38 @@
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+==== Five Minutes QuickStart
+
+1) Install JDK 8 
(http://www.oracle.com/technetwork/java/javase/downloads/index.html) and make 
sure you set the
+JAVA_HOME variable 
https://docs.oracle.com/cd/E19182-01/820-7851/inst_cli_jdk_javahome_t/
+
+2) Download ElasticSearch here : 
https://www.elastic.co/downloads/past-releases/elasticsearch-5-6-3 (please 
<strong>make sure</strong> you use the proper version : 5.6.3)
+
+3) Uncompress it and change the `config/elasticsearch.yml` to include the 
following config : <code>cluster.name: contextElasticSearch</code>
+
+4) Launch ElasticSearch using : `bin/elasticsearch`
+
+5) Download Apache Unomi here : http://unomi.incubator.apache.org/download.html
+
+6) Start it using : `./bin/karaf`
+
+7) Start the Apache Unomi packages using `unomi:start` in the Apache Karaf 
Shell
+
+8) Wait for startup to complete
+
+9) Try accessing https://localhost:9443/cxs/cluster with username/password: 
`karaf/karaf` . You might get a certificate warning in your browser, just 
accept it despite the warning it is safe.
+
+10) Request your first context by simply accessing : 
http://localhost:8181/context.js?sessionId=1234
+
+11) If something goes wrong, you should check the logs in 
`./data/log/karaf.log`. If you get errors on ElasticSearch,
+make sure you are using the proper version.

http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/cfe3158e/manual/src/main/asciidoc/building-and-deploying.adoc
----------------------------------------------------------------------
diff --git a/manual/src/main/asciidoc/building-and-deploying.adoc 
b/manual/src/main/asciidoc/building-and-deploying.adoc
index b285779..e7e5a11 100644
--- a/manual/src/main/asciidoc/building-and-deploying.adoc
+++ b/manual/src/main/asciidoc/building-and-deploying.adoc
@@ -29,8 +29,9 @@
 
 ==== Building
 
-1) Change to the top level directory of Apache Unomi source distribution.
-2) Run
+1) Get the code: `git clone 
https://git-wip-us.apache.org/repos/asf/incubator-unomi.git`
+2) Change to the top level directory of Apache Unomi source distribution.
+3) Run
 
 [source]
 ----
@@ -48,27 +49,21 @@ This will compile Apache Unomi and run all of the tests in 
the
 This will compile Apache Unomi without running the tests and takes less
  time to build.
 
-3) The distributions will be available under "package/target" directory.
+4) The distributions will be available under "package/target" directory.
 
 ==== Installing an ElasticSearch server
 
 Starting with version 1.2, Apache Unomi no longer embeds an ElasticSearch 
server as this is no longer supported by
 the developers of ElasticSearch. Therefore you will need to install a 
standalone ElasticSearch using the following steps:
 
-. 
-
 Download an ElasticSearch version. Here's the version you will need depending
 on your version of Apache Unomi.
 
 Apache Unomi &lt;= 1.2 : 
https://www.elastic.co/downloads/past-releases/elasticsearch-5-1-2[https://www.elastic.co/downloads/past-releases/elasticsearch-5-1-2]
 Apache Unomi &gt;= 1.3 : 
https://www.elastic.co/downloads/past-releases/elasticsearch-5-6-3[https://www.elastic.co/downloads/past-releases/elasticsearch-5-6-3]
 
-. 
-
 Uncompress the downloaded package into a directory
 
-. 
-
 In the config/elasticsearch.yml file, uncomment and modify the following line :
 
 [source]
@@ -76,8 +71,6 @@ In the config/elasticsearch.yml file, uncomment and modify 
the following line :
 cluster.name: contextElasticSearch
 ----
 
-. 
-
 Launch the server using
 
 [source]
@@ -86,9 +79,7 @@ bin/elasticsearch (Mac, Linux)
 bin\elasticsearch.bat (Windows)
 ----
 
-. 
-
-Check that the ElasticSearch is up and running by accessing the following URL 
: 
+Check that the ElasticSearch is up and running by accessing the following URL :
 
 http://localhost:9200[http://localhost:9200] 
 
@@ -128,8 +119,6 @@ environment if you intend to re-deploy the context server 
KAR iteratively.
 Additional requirements:
 * Apache Karaf 3.x, http://karaf.apache.org[http://karaf.apache.org]
 
-. 
-
 Before deploying, make sure that you have Apache Karaf properly installed. You 
will also have to increase the
 default maximum memory size and perm gen size by adjusting the following 
environment values in the bin/setenv(.bat)
 files (at the end of the file):
@@ -142,8 +131,6 @@ files (at the end of the file):
    export JAVA_MAX_PERM_MEM=384M
 ----
 
-. 
-
 Install the WAR support, CXF and Karaf Cellar into Karaf by doing the 
following in the Karaf command line:
 
 [source]
@@ -154,8 +141,6 @@ Install the WAR support, CXF and Karaf Cellar into Karaf by 
doing the following
    feature:install unomi-kar
 ----
 
-. 
-
 Create a new $MY_KARAF_HOME/etc/org.apache.cxf.osgi.cfg file and put the 
following property inside :
 
 [source]
@@ -163,8 +148,6 @@ Create a new $MY_KARAF_HOME/etc/org.apache.cxf.osgi.cfg 
file and put the followi
    org.apache.cxf.servlet.context=/cxs
 ----
 
-. 
-
 If all went smoothly, you should be able to access the context script here : 
http://localhost:8181/cxs/cluster[http://localhost:8181/cxs/cluster] .
  You should be able to login with karaf / karaf and see basic server 
information. If not something went wrong during the install.
 
@@ -261,16 +244,3 @@ A default test page is provided at the following URL:
 This test page will trigger the loading of the /context.js script, which will 
try to retrieving the user context
 or create a new one if it doesn't exist yet. It also contains an experimental 
integration with Facebook Login, but it
 doesn't yet save the context back to the context server.
-
-==== Integrating onto a page
-
-Simply reference the context script in your HTML as in the following example:
-
-[source,javascript]
-----
-<script type="text/javascript">
-    (function(){ var u=(("https:" ==== document.location.protocol) ? 
"https://localhost:8181/"; : "http://localhost:8181/";);
-    var d=document, g=d.createElement('script'), 
s=d.getElementsByTagName('script')[0]; g.type='text/javascript'; g.defer=true; 
g.async=true; g.src=u+'context.js';
-    s.parentNode.insertBefore(g,s); })();
-</script>
-----
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/cfe3158e/manual/src/main/asciidoc/configuration.adoc
----------------------------------------------------------------------
diff --git a/manual/src/main/asciidoc/configuration.adoc 
b/manual/src/main/asciidoc/configuration.adoc
index d6103e8..79b787c 100644
--- a/manual/src/main/asciidoc/configuration.adoc
+++ b/manual/src/main/asciidoc/configuration.adoc
@@ -100,14 +100,10 @@ By default, the login/password for the REST API full 
administrative access is "k
 
 The generated package is also configured with a default SSL certificate. You 
can change it by following these steps :
 
-. 
-
 Replace the existing keystore in $MY_KARAF_HOME/etc/keystore by your own 
certificate :
 
 
http://wiki.eclipse.org/Jetty/Howto/Configure_SSL[http://wiki.eclipse.org/Jetty/Howto/Configure_SSL]
 
-. 
-
 Update the keystore and certificate password in 
$MY_KARAF_HOME/etc/custom.properties file :
 
 [source]

http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/cfe3158e/manual/src/main/asciidoc/custom-extensions.adoc
----------------------------------------------------------------------
diff --git a/manual/src/main/asciidoc/custom-extensions.adoc 
b/manual/src/main/asciidoc/custom-extensions.adoc
index 0007815..c7e37b7 100644
--- a/manual/src/main/asciidoc/custom-extensions.adoc
+++ b/manual/src/main/asciidoc/custom-extensions.adoc
@@ -418,92 +418,3 @@ You can find the implementation of the two classes here :
 * 
https://github.com/apache/incubator-unomi/blob/master/plugins/baseplugin/src/main/java/org/apache/unomi/plugins/baseplugin/conditions/MatchAllConditionESQueryBuilder.java[org.apache.unomi.plugins.baseplugin.conditions.MatchAllConditionESQueryBuilder]
 * 
https://github.com/apache/incubator-unomi/blob/master/plugins/baseplugin/src/main/java/org/apache/unomi/plugins/baseplugin/conditions/MatchAllConditionEvaluator.java[org.apache.unomi.plugins.baseplugin.conditions.MatchAllConditionEvaluator]
 
-==== Migration patches
-
-You may provide patches on any predefined items by simply adding a JSON file 
in :
-
-[source]
-----
-src/main/resources/META-INF/cxs/patches
-----
-
-These patches will be applied when the module will be deployed the first time.
-They allow to modify an item, that would have been previously deployed on 
unomi by a previous version of the extension or by something else.
-
-Each patch must have a unique id - unomi will use this id to remember that the 
patch has already been applied. It can also be used to reapply the patch when 
need by using the karaf command `unomi:deploy-definition`
-
-A patch also need to reference the item to patch by setting `patchedItemId` 
and `patchedItemType`, and an operation that tells what the patch should do.
-
-
-.`patchedItemType` can take one of the following value:
-- condition
-- action
-- goal
-- campaign
-- persona
-- propertyType
-- rule
-- segment
-- scoring
-
-.`operation` can take one of the following value:
-- patch
-- override
-- remove
-
-You can apply a patch in http://jsonpatch.com/[json-patch] format in the 
`data` field, and by specifying operation `patch` like in this example :
-
-[source]
-----
-{
-  "itemId": "firstName-patch1",
-  "patchedItemId": "firstName",
-  "patchedItemType": "propertyType",
-  "operation": "patch",
-  "data": [
-    {
-      "op": "replace", "path": "/defaultValue", "value": "foo"
-    }
-  ]
-}
-----
-
-If you need to completely redeploy a definition, you can use the `override` 
operation and put the definition in `data`
-
-[source]
-----
-{
-  "itemId": "gender-patch1",
-  "patchedItemId": "gender",
-  "patchedItemType": "propertyType",
-  "operation": "override",
-  "data": {
-    "metadata": {
-      "id": "gender",
-      "name": "Gender",
-      "systemTags": [
-        "properties",
-        "profileProperties"
-      ]
-    },
-    "type": "string",
-    "defaultValue": "foo",
-    "automaticMappingsFrom": [ ],
-    "rank": "105.0"
-  }
-}
-----
-
-It is also possible to simply remove an item by using the operation `remove` :
-
-[source]
-----
-{
-  "itemId": "firstName-patch2",
-  "patchedItemId": "firstName",
-  "patchedItemType": "propertyType",
-  "operation": "remove"
-}
-----
-
-Patches can also be deployed at runtime by using the REST endpoint 
/patch/apply .

http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/cfe3158e/manual/src/main/asciidoc/getting-started.adoc
----------------------------------------------------------------------
diff --git a/manual/src/main/asciidoc/getting-started.adoc 
b/manual/src/main/asciidoc/getting-started.adoc
index b0307a2..1984310 100644
--- a/manual/src/main/asciidoc/getting-started.adoc
+++ b/manual/src/main/asciidoc/getting-started.adoc
@@ -21,14 +21,9 @@ This document assumes that you are already familiar with 
Unomi's link:concepts.h
 
 ==== Running Unomi
 
-===== Building Unomi
-
-. Get the code: `git clone 
https://git-wip-us.apache.org/repos/asf/incubator-unomi.git`
-. Build and install according to the 
link:building-and-deploying.html[instructions] and install Unomi.
-
 ===== Start Unomi
 
-Start Unomi according to the 
link:building-and-deploying.html#Deploying_the_generated_package[instructions]. 
Once you have Karaf running,
+Start Unomi according to the link:5-min-quickstart.html[5 minute quick start] 
or by compiling using the building 
link:building-and-deploying.html#Deploying_the_generated_package[instructions]. 
Once you have Karaf running,
  you should wait until you see the following messages on the Karaf console:
 
 [source]

http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/cfe3158e/manual/src/main/asciidoc/index.adoc
----------------------------------------------------------------------
diff --git a/manual/src/main/asciidoc/index.adoc 
b/manual/src/main/asciidoc/index.adoc
index bf2ad48..bf29433 100644
--- a/manual/src/main/asciidoc/index.adoc
+++ b/manual/src/main/asciidoc/index.adoc
@@ -24,23 +24,23 @@ Apache Software Foundation
 
 image::incubator-logo.png[pdfwidth=35%,align=center]
 
+== Quick start
+
+include::5-min-quickstart.adoc[]
+
 == Concepts
 
 include::concepts.adoc[]
 
-== Quick start
-
-include::building-and-deploying.adoc[]
+== Setup
 
 include::getting-started.adoc[]
 
-include::configuration.adoc[]
-
-== Extending Unomi via plugins
+include::installing-tracker.adoc[]
 
-include::extending-plugins.adoc[]
+include::configuration.adoc[]
 
-== Samples
+== Integration samples
 
 include::samples/samples.adoc[]
 
@@ -60,10 +60,16 @@ include::connectors/salesforce-connector.adoc[]
 
 include::clustering.adoc[]
 
-== Custom extensions
+== Consent API
 
-include::custom-extensions.adoc[]
+include::consent-api.adoc[]
 
-== Consent API
+== Developers
+
+include::building-and-deploying.adoc[]
+
+include::extending-plugins.adoc[]
+
+include::custom-extensions.adoc[]
 
-include::consent-api.adoc[]
\ No newline at end of file
+include::patches.adoc[]

http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/cfe3158e/manual/src/main/asciidoc/installing-tracker.adoc
----------------------------------------------------------------------
diff --git a/manual/src/main/asciidoc/installing-tracker.adoc 
b/manual/src/main/asciidoc/installing-tracker.adoc
new file mode 100644
index 0000000..0739c4c
--- /dev/null
+++ b/manual/src/main/asciidoc/installing-tracker.adoc
@@ -0,0 +1,44 @@
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+==== Web Tracker
+
+This extension is providing the web tracker to start collecting visitors data 
on your website.
+The tracker is implemented as an integration of 
https://github.com/segmentio/analytics.js[analytics.js] for Unomi.
+
+===== Getting started
+
+Extension can be tested at : `http://localhost:8181/tracker/index.html`
+
+In your page include unomiOptions and include code snippet from 
`snippet.min.js` :
+
+[source]
+----
+<script type="text/javascript">
+        var unomiOption = {
+            scope: 'realEstateManager',
+            url: 'http://localhost:8181'
+        };
+        window.unomiTracker||(window.unomiTracker={}),function(){function 
e(e){for(unomiTracker.initialize({"Apache Unomi":unomiOption});n.length>0;){var 
r=n.shift(),t=r.shift();unomiTracker[t]&&unomiTracker[t].apply(unomiTracker,r)}}for(var
 
n=[],r=["trackSubmit","trackClick","trackLink","trackForm","initialize","pageview","identify","reset","group","track","ready","alias","debug","page","once","off","on","personalize"],t=0;t<r.length;t++){var
 i=r[t];window.unomiTracker[i]=function(e){return function(){var 
r=Array.prototype.slice.call(arguments);return 
r.unshift(e),n.push(r),window.unomiTracker}}(i)}unomiTracker.load=function(){var
 
n=document.createElement("script");n.type="text/javascript",n.async=!0,n.src=unomiOption.url+"/tracker/unomi-tracker.min.js",n.addEventListener?n.addEventListener("load",function(n){"function"==typeof
 
e&&e(n)},!1):n.onreadystatechange=function(){"complete"!==this.readyState&&"loaded"!==this.readyState||e(window.event)};var
 r=document.getElementsByTagName(
 
"script")[0];r.parentNode.insertBefore(n,r)},document.addEventListener("DOMContentLoaded",unomiTracker.load),unomiTracker.page()}();
+</script>
+----
+
+`window.unomiTracker` can be used to send additional events when needed.
+
+Check analytics.js API 
https://segment.com/docs/sources/website/analytics.js/[here].
+All methods can be used on `unomiTracker` object, although not all event types 
are supported by Unomi intergation.
+
+===== How to contribute
+
+The source code is in the folder javascript with a package.json, the file to 
update is `analytics.js-integration-apache-unomi.js` apply your modification in 
this file then use the command `yarn build` to compile a new JS file.
+Then you can use the test page to try your changes 
`http://localhost:8181/tracker/index.html`.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/cfe3158e/manual/src/main/asciidoc/patches.adoc
----------------------------------------------------------------------
diff --git a/manual/src/main/asciidoc/patches.adoc 
b/manual/src/main/asciidoc/patches.adoc
new file mode 100644
index 0000000..3baba57
--- /dev/null
+++ b/manual/src/main/asciidoc/patches.adoc
@@ -0,0 +1,102 @@
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+==== Migration patches
+
+You may provide patches on any predefined items by simply adding a JSON file 
in :
+
+[source]
+----
+src/main/resources/META-INF/cxs/patches
+----
+
+These patches will be applied when the module will be deployed the first time.
+They allow to modify an item, that would have been previously deployed on 
unomi by a previous version of the extension or by something else.
+
+Each patch must have a unique id - unomi will use this id to remember that the 
patch has already been applied. It can also be used to reapply the patch when 
need by using the karaf command `unomi:deploy-definition`
+
+A patch also need to reference the item to patch by setting `patchedItemId` 
and `patchedItemType`, and an operation that tells what the patch should do.
+
+
+.`patchedItemType` can take one of the following value:
+- condition
+- action
+- goal
+- campaign
+- persona
+- propertyType
+- rule
+- segment
+- scoring
+
+.`operation` can take one of the following value:
+- patch
+- override
+- remove
+
+You can apply a patch in http://jsonpatch.com/[json-patch] format in the 
`data` field, and by specifying operation `patch` like in this example :
+
+[source]
+----
+{
+  "itemId": "firstName-patch1",
+  "patchedItemId": "firstName",
+  "patchedItemType": "propertyType",
+  "operation": "patch",
+  "data": [
+    {
+      "op": "replace", "path": "/defaultValue", "value": "foo"
+    }
+  ]
+}
+----
+
+If you need to completely redeploy a definition, you can use the `override` 
operation and put the definition in `data`
+
+[source]
+----
+{
+  "itemId": "gender-patch1",
+  "patchedItemId": "gender",
+  "patchedItemType": "propertyType",
+  "operation": "override",
+  "data": {
+    "metadata": {
+      "id": "gender",
+      "name": "Gender",
+      "systemTags": [
+        "properties",
+        "profileProperties"
+      ]
+    },
+    "type": "string",
+    "defaultValue": "foo",
+    "automaticMappingsFrom": [ ],
+    "rank": "105.0"
+  }
+}
+----
+
+It is also possible to simply remove an item by using the operation `remove` :
+
+[source]
+----
+{
+  "itemId": "firstName-patch2",
+  "patchedItemId": "firstName",
+  "patchedItemType": "propertyType",
+  "operation": "remove"
+}
+----
+
+Patches can also be deployed at runtime by using the REST endpoint 
/patch/apply .

http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/cfe3158e/manual/src/main/asciidoc/samples/login-sample.adoc
----------------------------------------------------------------------
diff --git a/manual/src/main/asciidoc/samples/login-sample.adoc 
b/manual/src/main/asciidoc/samples/login-sample.adoc
index b1664d8..10d0084 100644
--- a/manual/src/main/asciidoc/samples/login-sample.adoc
+++ b/manual/src/main/asciidoc/samples/login-sample.adoc
@@ -25,8 +25,6 @@ only be sent if the user has authenticated properly, and only 
the authentication
 
 ==== Installing the samples
 
-. 
-
 Login into the Unomi Karaf SSH shell using something like this :
 
 [source]
@@ -34,8 +32,6 @@ Login into the Unomi Karaf SSH shell using something like 
this :
 ssh -p 8102 karaf@localhost (default password is karaf) 
 ----
 
-. 
-
 Install the login samples using the following command:
 
 [source]
@@ -45,8 +41,6 @@ bundle:install 
mvn:org.apache.unomi/login-integration-samples/${project.version}
 
 when the bundle is successfully install you will get an bundle ID back we will 
call it BUNDLE_ID. 
 
-. 
-
 You can then do:
 
 [source]
@@ -54,8 +48,6 @@ You can then do:
 bundle:start BUNDLE_ID
 ----
 
-. 
-
 If all went well you can access the login samples HTML page here :
 
 [source]
@@ -63,8 +55,6 @@ If all went well you can access the login samples HTML page 
here :
 http://localhost:8181/login/index.html
 ----
 
-. 
-
 You can fill in the form to test it. Note that the hardcoded password is:
 
 [source]

Reply via email to