This applies to Ubuntu 16.04 LTS.
Compiled from https://www.howtoforge.com/tutorial/installing-nginx-with-php7-fpm-and-mysql-on-ubuntu–16.04-lts-lemp/
Install MySQL
See also https://support.rackspace.com/how-to/configuring-mysql-server-on-ubuntu/
Run the following and provide the appropriate answers to subsequent prompts:
apt-get -y install mysql-server
mysql_secure_installation
If you want to manage your MySQL instance from external computers choose No to the question Disallow root login remotely?
and change the mysql.conf
(usually found in /etc/mysql/mysql.conf.d/mysqld.cnf
) and set the bind-address
parameter to 0.0.0.0
.
To find the actual path for the configuration file run /usr/sbin/mysqld --help --verbose
If you install Piwik on the same machine this is not required.
Create database/user for Piwik
$ mysql -u root -p
mysql> CREATE DATABASE piwik;
mysql> CREATE USER 'piwik'@'localhost' IDENTIFIED BY 'change_to_real_password';
mysql> GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES ON piwik.* TO 'piwik'@'localhost';
mysql> EXIT
Install Nginx
If you have already installed Apache, remove it:
service apache2 stop
update-rc.d -f apache2 remove
apt-get remove apache2
sudo -i
apt-get update
apt-get -y install nginx
Check the status of the firewall
Nginx
registers itself with ufw
so:
- Check of
ufw
is enabled: ufw status
- If enabled then register one of the
Nginx
registered profiles (found out by running ufw app list
) like:
Check Nginx
From within a browser try http://\<IP\>
Install PHP 7
apt-get -y install php7.0-fpm
Modify default site configuration file /etc/nginx/sites-available/default
by de-commenting the following lines:
...
location ~ \.php$ {
include snippets/fastcgi-php.conf;
...
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}
...
location ~ /\.ht {
deny all;
}
Reload Nginx:
service nginx reload
Open /etc/php/7.0/fpm/php.ini
and set cgi.fix_pathinfo=0:
Restart php:
service php7.0-fpm reload
Check the installation
Create info.php
in /var/www/html/info.php
with the following content:
<?php
phpinfo();
?>
Watch out for CRLFs on Windows (end of line should be \n regularly in Linux).
Try now http://<IP>/info.php
Install additional packages required by Piwik
apt-get -y install php7.0-curl php7.0-gd php7.0-cli php-geoip php7.0-mysql
apt-get -y install php-mbstring php7.0-mbstring
apt-get -y install php-xml
Install Piwik
Run:
cd /tmp
apt-get install unzip
wget https://builds.piwik.org/piwik.zip && unzip piwik.zip
mkdir /var/www//html/piwik
cp -R ./piwik/* /var/www/html/piwik
chown -R www-data:www-data /var/www/html/piwik
chmod -R 0755 /var/www/html/piwik/tmp
Now browse to http://<FQDN>/piwik/index.php
Configure your Piwik instance. The following script-let should be included in each page of your site (as specified by the setup:Make sure this code is on every page of your website. We recommend to paste it immediately before the closing </head> tag.
).
Be sure to change the <FQDN>
with the appropriate value.
<!-- Piwik -->
<script type="text/javascript">
var _paq = _paq || [];
// tracker methods like "setCustomDimension" should be called before "trackPageView"
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="//<FQDN>/piwik/";
_paq.push(['setTrackerUrl', u+'piwik.php']);
_paq.push(['setSiteId', '1']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s);
})();
</script>
<!-- End Piwik Code -->
Publishing Problem
The monitored site had some peculiarities:
- It is used from intranet or from internet, published through a reverse proxy
- It can be used over plain HTTP or over HTTPS (through SSO or from internet); when used over HTTP from intranet it worked fine but over HTTPS (also from intranet) the request to Piwik (due to security reasons) was also done over HTTPS which obviously failed (the
//<FQDN>/piwik/
syntax indicates to the browser to make the request over the same protocol as the referral page was loaded)
So overall the default Piwik installation didn’t work since it was not accessible through HTTPS nor from internet.
The first step was to publish the site through the same reverse proxy, both HTTP and HTTPS (with the tunnel being terminated at proxy level) with Forward Original HOST Header
set to Off. Trying to access the administrative interface through the public FQDN led to a security error (something with actual Referral not matching the expected one).
Next step was to change the proxy settings so that the original HOST header was forwarded to Piwik. Another error popped up stating (as a conclusion, the error text was rather stupid like Piwik was accessed from [URL] but it was configured to be accessed from [URL]) that the value of the HOST header is not registered as safe in config\config.ini.php
.
By adding the FQDN in [General]
section as:
trusted_hosts[] = "FQDN"
the integration works just fine.
PHA+VGhpcyBhcHBsaWVzIHRvIFVidW50dSAxNi4wNCBMVFMuPC9wPg0KDQo8cD5Db21waWxl
ZCBmcm9tIDxhIGhyZWY9Imh0dHBzOi8vd3d3Lmhvd3RvZm9yZ2UuY29tL3R1dG9yaWFsL2lu
c3RhbGxpbmctbmdpbngtd2l0aC1waHA3LWZwbS1hbmQtbXlzcWwtb24tdWJ1bnR1LTE2LjA0
LWx0cy1sZW1wLyI+aHR0cHM6Ly93d3cuaG93dG9mb3JnZS5jb20vdHV0b3JpYWwvaW5zdGFs
bGluZy1uZ2lueC13aXRoLXBocDctZnBtLWFuZC1teXNxbC1vbi11YnVudHUmIzgyMTE7MTYu
MDQtbHRzLWxlbXAvPC9hPjwvcD4NCg0KPGgxIGlkPSJpbnN0YWxsbXlzcWwiPkluc3RhbGwg
TXlTUUw8L2gxPg0KDQo8cD5TZWUgYWxzbyA8YSBocmVmPSJodHRwczovL3N1cHBvcnQucmFj
a3NwYWNlLmNvbS9ob3ctdG8vY29uZmlndXJpbmctbXlzcWwtc2VydmVyLW9uLXVidW50dS8i
Pmh0dHBzOi8vc3VwcG9ydC5yYWNrc3BhY2UuY29tL2hvdy10by9jb25maWd1cmluZy1teXNx
bC1zZXJ2ZXItb24tdWJ1bnR1LzwvYT48L3A+DQoNCjxwPlJ1biB0aGUgZm9sbG93aW5nIGFu
ZCBwcm92aWRlIHRoZSBhcHByb3ByaWF0ZSBhbnN3ZXJzIHRvIHN1YnNlcXVlbnQgcHJvbXB0
czoNCjxjb2RlPg0KYXB0LWdldCAteSBpbnN0YWxsIG15c3FsLXNlcnZlcg0KbXlzcWxfc2Vj
dXJlX2luc3RhbGxhdGlvbg0KPC9jb2RlPg0KSWYgeW91IHdhbnQgdG8gbWFuYWdlIHlvdXIg
TXlTUUwgaW5zdGFuY2UgZnJvbSBleHRlcm5hbCBjb21wdXRlcnMgY2hvb3NlIE5vIHRvIHRo
ZSBxdWVzdGlvbiA8Y29kZT5EaXNhbGxvdyByb290IGxvZ2luIHJlbW90ZWx5PzwvY29kZT4g
YW5kIGNoYW5nZSB0aGUgPGNvZGU+bXlzcWwuY29uZjwvY29kZT4gKHVzdWFsbHkgZm91bmQg
aW4gPGNvZGU+L2V0Yy9teXNxbC9teXNxbC5jb25mLmQvbXlzcWxkLmNuZjwvY29kZT4pIGFu
ZCBzZXQgdGhlIDxjb2RlPmJpbmQtYWRkcmVzczwvY29kZT4gcGFyYW1ldGVyIHRvIDxjb2Rl
PjAuMC4wLjA8L2NvZGU+Lg0KVG8gZmluZCB0aGUgYWN0dWFsIHBhdGggZm9yIHRoZSBjb25m
aWd1cmF0aW9uIGZpbGUgcnVuIDxjb2RlPi91c3Ivc2Jpbi9teXNxbGQgLS1oZWxwIC0tdmVy
Ym9zZTwvY29kZT4NCklmIHlvdSBpbnN0YWxsIFBpd2lrIG9uIHRoZSBzYW1lIG1hY2hpbmUg
dGhpcyBpcyBub3QgcmVxdWlyZWQuPC9wPg0KDQo8aDIgaWQ9ImNyZWF0ZWRhdGFiYXNldXNl
cmZvcnBpd2lrIj5DcmVhdGUgZGF0YWJhc2UvdXNlciBmb3IgUGl3aWs8L2gyPg0KDQo8cHJl
Pjxjb2RlPiQgbXlzcWwgLXUgcm9vdCAtcA0KbXlzcWwmZ3Q7IENSRUFURSBEQVRBQkFTRSBw
aXdpazsNCm15c3FsJmd0OyBDUkVBVEUgVVNFUiAncGl3aWsnQCdsb2NhbGhvc3QnIElERU5U
SUZJRUQgQlkgJ2NoYW5nZV90b19yZWFsX3Bhc3N3b3JkJzsNCm15c3FsJmd0OyBHUkFOVCBT
RUxFQ1QsIElOU0VSVCwgVVBEQVRFLCBERUxFVEUsIENSRUFURSwgRFJPUCwgQUxURVIsIENS
RUFURSBURU1QT1JBUlkgVEFCTEVTLCBMT0NLIFRBQkxFUyBPTiBwaXdpay4qIFRPICdwaXdp
aydAJ2xvY2FsaG9zdCc7DQpteXNxbCZndDsgRVhJVA0KPC9jb2RlPjwvcHJlPg0KDQo8aDEg
aWQ9Imluc3RhbGxuZ2lueCI+SW5zdGFsbCBOZ2lueDwvaDE+DQoNCjxwPklmIHlvdSBoYXZl
IGFscmVhZHkgaW5zdGFsbGVkIEFwYWNoZSwgcmVtb3ZlIGl0OjwvcD4NCg0KPHByZT48Y29k
ZT5zZXJ2aWNlIGFwYWNoZTIgc3RvcA0KdXBkYXRlLXJjLmQgLWYgYXBhY2hlMiByZW1vdmUN
CmFwdC1nZXQgcmVtb3ZlIGFwYWNoZTINCjwvY29kZT48L3ByZT4NCg0KPHByZT48Y29kZT5z
dWRvIC1pDQphcHQtZ2V0IHVwZGF0ZQ0KYXB0LWdldCAteSBpbnN0YWxsIG5naW54DQo8L2Nv
ZGU+PC9wcmU+DQoNCjxoMiBpZD0iY2hlY2t0aGVzdGF0dXNvZnRoZWZpcmV3YWxsIj5DaGVj
ayB0aGUgc3RhdHVzIG9mIHRoZSBmaXJld2FsbDwvaDI+DQoNCjxwPjxjb2RlPk5naW54PC9j
b2RlPiByZWdpc3RlcnMgaXRzZWxmIHdpdGggPGNvZGU+dWZ3PC9jb2RlPiBzbzo8L3A+DQoN
Cjx1bD4NCjxsaT5DaGVjayBvZiA8Y29kZT51Znc8L2NvZGU+IGlzIGVuYWJsZWQ6IDxjb2Rl
PnVmdyBzdGF0dXM8L2NvZGU+PC9saT4NCjxsaT5JZiBlbmFibGVkIHRoZW4gcmVnaXN0ZXIg
b25lIG9mIHRoZSA8Y29kZT5OZ2lueDwvY29kZT4gcmVnaXN0ZXJlZCBwcm9maWxlcyAoZm91
bmQgb3V0IGJ5IHJ1bm5pbmcgPGNvZGU+dWZ3IGFwcCBsaXN0PC9jb2RlPikgbGlrZToNCg0K
PHVsPg0KPGxpPjxjb2RlPnVmdyBhbGxvdyAnTmdpbnggSFRUUCc8L2NvZGU+PC9saT4NCjwv
dWw+PC9saT4NCjwvdWw+DQoNCjxoMiBpZD0iY2hlY2tuZ2lueCI+Q2hlY2sgTmdpbng8L2gy
Pg0KDQo8cD5Gcm9tIHdpdGhpbiBhIGJyb3dzZXIgdHJ5IDxjb2RlPmh0dHA6Ly9cJmx0O0lQ
XCZndDs8L2NvZGU+PC9wPg0KDQo8aDEgaWQ9Imluc3RhbGxwaHA3Ij5JbnN0YWxsIFBIUCA3
PC9oMT4NCg0KPHByZT48Y29kZT5hcHQtZ2V0IC15IGluc3RhbGwgcGhwNy4wLWZwbQ0KPC9j
b2RlPjwvcHJlPg0KDQo8cD5Nb2RpZnkgZGVmYXVsdCBzaXRlIGNvbmZpZ3VyYXRpb24gZmls
ZSA8Y29kZT4vZXRjL25naW54L3NpdGVzLWF2YWlsYWJsZS9kZWZhdWx0PC9jb2RlPiBieSBk
ZS1jb21tZW50aW5nIHRoZSBmb2xsb3dpbmcgbGluZXM6PC9wPg0KDQo8cHJlPjxjb2RlPi4u
Lg0KICAgIGxvY2F0aW9uIH4gXC5waHAkIHsNCiAgICAgICAgaW5jbHVkZSBzbmlwcGV0cy9m
YXN0Y2dpLXBocC5jb25mOw0KLi4uDQogICAgICAgIGZhc3RjZ2lfcGFzcyB1bml4Oi9ydW4v
cGhwL3BocDcuMC1mcG0uc29jazsNCiAgICB9DQoNCi4uLg0KICAgIGxvY2F0aW9uIH4gL1wu
aHQgew0KICAgICAgICBkZW55IGFsbDsNCiAgICB9DQo8L2NvZGU+PC9wcmU+DQoNCjxwPlJl
bG9hZCBOZ2lueDo8L3A+DQoNCjxwcmU+PGNvZGU+c2VydmljZSBuZ2lueCByZWxvYWQNCjwv
Y29kZT48L3ByZT4NCg0KPHA+T3BlbiA8Y29kZT4vZXRjL3BocC83LjAvZnBtL3BocC5pbmk8
L2NvZGU+IGFuZCBzZXQgPGNvZGU+Y2dpLmZpeF9wYXRoaW5mbz0wOjwvY29kZT4NClJlc3Rh
cnQgcGhwOjwvcD4NCg0KPHByZT48Y29kZT5zZXJ2aWNlIHBocDcuMC1mcG0gcmVsb2FkDQo8
L2NvZGU+PC9wcmU+DQoNCjxoMiBpZD0iY2hlY2t0aGVpbnN0YWxsYXRpb24iPkNoZWNrIHRo
ZSBpbnN0YWxsYXRpb248L2gyPg0KDQo8cD5DcmVhdGUgPGNvZGU+aW5mby5waHA8L2NvZGU+
IGluIDxjb2RlPi92YXIvd3d3L2h0bWwvaW5mby5waHA8L2NvZGU+IHdpdGggdGhlIGZvbGxv
d2luZyBjb250ZW50OjwvcD4NCg0KPHByZT48Y29kZT4mbHQ7P3BocA0KcGhwaW5mbygpOw0K
PyZndDsNCjwvY29kZT48L3ByZT4NCg0KPHA+V2F0Y2ggb3V0IGZvciBDUkxGcyBvbiBXaW5k
b3dzIChlbmQgb2YgbGluZSBzaG91bGQgYmUgXG4gcmVndWxhcmx5IGluIExpbnV4KS48L3A+
DQoNCjxwPlRyeSBub3cgPGNvZGU+aHR0cDovLyZsdDtJUCZndDsvaW5mby5waHA8L2NvZGU+
PC9wPg0KDQo8aDIgaWQ9Imluc3RhbGxhZGRpdGlvbmFscGFja2FnZXNyZXF1aXJlZGJ5cGl3
aWsiPkluc3RhbGwgYWRkaXRpb25hbCBwYWNrYWdlcyByZXF1aXJlZCBieSBQaXdpazwvaDI+
DQoNCjxwcmU+PGNvZGU+YXB0LWdldCAteSBpbnN0YWxsIHBocDcuMC1jdXJsIHBocDcuMC1n
ZCBwaHA3LjAtY2xpIHBocC1nZW9pcCBwaHA3LjAtbXlzcWwNCmFwdC1nZXQgLXkgaW5zdGFs
bCBwaHAtbWJzdHJpbmcgcGhwNy4wLW1ic3RyaW5nDQphcHQtZ2V0IC15IGluc3RhbGwgcGhw
LXhtbA0KPC9jb2RlPjwvcHJlPg0KDQo8aDEgaWQ9Imluc3RhbGxwaXdpayI+SW5zdGFsbCBQ
aXdpazwvaDE+DQoNCjxwPlJ1bjo8L3A+DQoNCjxwcmU+PGNvZGU+Y2QgL3RtcA0KYXB0LWdl
dCBpbnN0YWxsIHVuemlwDQp3Z2V0IGh0dHBzOi8vYnVpbGRzLnBpd2lrLm9yZy9waXdpay56
aXAgJmFtcDsmYW1wOyB1bnppcCBwaXdpay56aXANCm1rZGlyIC92YXIvd3d3Ly9odG1sL3Bp
d2lrDQpjcCAtUiAuL3Bpd2lrLyogL3Zhci93d3cvaHRtbC9waXdpaw0KY2hvd24gLVIgd3d3
LWRhdGE6d3d3LWRhdGEgL3Zhci93d3cvaHRtbC9waXdpaw0KY2htb2QgLVIgMDc1NSAvdmFy
L3d3dy9odG1sL3Bpd2lrL3RtcA0KPC9jb2RlPjwvcHJlPg0KDQo8cD5Ob3cgYnJvd3NlIHRv
IDxjb2RlPmh0dHA6Ly8mbHQ7RlFETiZndDsvcGl3aWsvaW5kZXgucGhwPC9jb2RlPjwvcD4N
Cg0KPHA+Q29uZmlndXJlIHlvdXIgUGl3aWsgaW5zdGFuY2UuIFRoZSBmb2xsb3dpbmcgc2Ny
aXB0LWxldCBzaG91bGQgYmUgaW5jbHVkZWQgaW4gZWFjaCBwYWdlIG9mIHlvdXIgc2l0ZSAo
YXMgc3BlY2lmaWVkIGJ5IHRoZSBzZXR1cDo8Y29kZT5NYWtlIHN1cmUgdGhpcyBjb2RlIGlz
IG9uIGV2ZXJ5IHBhZ2Ugb2YgeW91ciB3ZWJzaXRlLiBXZSByZWNvbW1lbmQgdG8gcGFzdGUg
aXQgaW1tZWRpYXRlbHkgYmVmb3JlIHRoZSBjbG9zaW5nICZsdDsvaGVhZCZndDsgdGFnLjwv
Y29kZT4pLg0KQmUgc3VyZSB0byBjaGFuZ2UgdGhlIDxjb2RlPiZsdDtGUUROJmd0OzwvY29k
ZT4gd2l0aCB0aGUgYXBwcm9wcmlhdGUgdmFsdWUuPC9wPg0KDQo8cHJlPjxjb2RlPiZsdDsh
LS0gUGl3aWsgLS0mZ3Q7DQombHQ7c2NyaXB0IHR5cGU9JnF1b3Q7dGV4dC9qYXZhc2NyaXB0
JnF1b3Q7Jmd0Ow0KICB2YXIgX3BhcSA9IF9wYXEgfHwgW107DQogIC8vIHRyYWNrZXIgbWV0
aG9kcyBsaWtlICZxdW90O3NldEN1c3RvbURpbWVuc2lvbiZxdW90OyBzaG91bGQgYmUgY2Fs
bGVkIGJlZm9yZSAmcXVvdDt0cmFja1BhZ2VWaWV3JnF1b3Q7DQogIF9wYXEucHVzaChbJ3Ry
YWNrUGFnZVZpZXcnXSk7DQogIF9wYXEucHVzaChbJ2VuYWJsZUxpbmtUcmFja2luZyddKTsN
CiAgKGZ1bmN0aW9uKCkgew0KICAgIHZhciB1PSZxdW90Oy8vJmx0O0ZRRE4mZ3Q7L3Bpd2lr
LyZxdW90OzsNCiAgICBfcGFxLnB1c2goWydzZXRUcmFja2VyVXJsJywgdSsncGl3aWsucGhw
J10pOw0KICAgIF9wYXEucHVzaChbJ3NldFNpdGVJZCcsICcxJ10pOw0KICAgIHZhciBkPWRv
Y3VtZW50LCBnPWQuY3JlYXRlRWxlbWVudCgnc2NyaXB0JyksIHM9ZC5nZXRFbGVtZW50c0J5
VGFnTmFtZSgnc2NyaXB0JylbMF07DQogICAgZy50eXBlPSd0ZXh0L2phdmFzY3JpcHQnOyBn
LmFzeW5jPXRydWU7IGcuZGVmZXI9dHJ1ZTsgZy5zcmM9dSsncGl3aWsuanMnOyBzLnBhcmVu
dE5vZGUuaW5zZXJ0QmVmb3JlKGcscyk7DQogIH0pKCk7DQombHQ7L3NjcmlwdCZndDsNCiZs
dDshLS0gRW5kIFBpd2lrIENvZGUgLS0mZ3Q7DQo8L2NvZGU+PC9wcmU+DQoNCjxoMSBpZD0i
cHVibGlzaGluZ3Byb2JsZW0iPlB1Ymxpc2hpbmcgUHJvYmxlbTwvaDE+DQoNCjxwPlRoZSBt
b25pdG9yZWQgc2l0ZSBoYWQgc29tZSBwZWN1bGlhcml0aWVzOjwvcD4NCg0KPHVsPg0KPGxp
Pkl0IGlzIHVzZWQgZnJvbSBpbnRyYW5ldCBvciBmcm9tIGludGVybmV0LCBwdWJsaXNoZWQg
dGhyb3VnaCBhIHJldmVyc2UgcHJveHk8L2xpPg0KPGxpPkl0IGNhbiBiZSB1c2VkIG92ZXIg
cGxhaW4gSFRUUCBvciBvdmVyIEhUVFBTICh0aHJvdWdoIFNTTyBvciBmcm9tIGludGVybmV0
KTsgd2hlbiB1c2VkIG92ZXIgSFRUUCBmcm9tIGludHJhbmV0IGl0IHdvcmtlZCBmaW5lIGJ1
dCBvdmVyIEhUVFBTIChhbHNvIGZyb20gaW50cmFuZXQpIHRoZSByZXF1ZXN0IHRvIFBpd2lr
IChkdWUgdG8gc2VjdXJpdHkgcmVhc29ucykgd2FzIGFsc28gZG9uZSBvdmVyIEhUVFBTIHdo
aWNoIG9idmlvdXNseSBmYWlsZWQgKHRoZSA8Y29kZT4vLyZsdDtGUUROJmd0Oy9waXdpay88
L2NvZGU+IHN5bnRheCBpbmRpY2F0ZXMgdG8gdGhlIGJyb3dzZXIgdG8gbWFrZSB0aGUgcmVx
dWVzdCBvdmVyIHRoZSBzYW1lIHByb3RvY29sIGFzIHRoZSByZWZlcnJhbCBwYWdlIHdhcyBs
b2FkZWQpPC9saT4NCjwvdWw+DQoNCjxwPlNvIG92ZXJhbGwgdGhlIGRlZmF1bHQgUGl3aWsg
aW5zdGFsbGF0aW9uIGRpZG4mIzgyMTc7dCB3b3JrIHNpbmNlIGl0IHdhcyBub3QgYWNjZXNz
aWJsZSB0aHJvdWdoIEhUVFBTIG5vciBmcm9tIGludGVybmV0LjwvcD4NCg0KPHA+VGhlIGZp
cnN0IHN0ZXAgd2FzIHRvIHB1Ymxpc2ggdGhlIHNpdGUgdGhyb3VnaCB0aGUgc2FtZSByZXZl
cnNlIHByb3h5LCBib3RoIEhUVFAgYW5kIEhUVFBTICh3aXRoIHRoZSB0dW5uZWwgYmVpbmcg
dGVybWluYXRlZCBhdCBwcm94eSBsZXZlbCkgd2l0aCA8Y29kZT5Gb3J3YXJkIE9yaWdpbmFs
IEhPU1QgSGVhZGVyPC9jb2RlPiBzZXQgdG8gT2ZmLiBUcnlpbmcgdG8gYWNjZXNzIHRoZSBh
ZG1pbmlzdHJhdGl2ZSBpbnRlcmZhY2UgdGhyb3VnaCB0aGUgcHVibGljIEZRRE4gbGVkIHRv
IGEgc2VjdXJpdHkgZXJyb3IgKHNvbWV0aGluZyB3aXRoIGFjdHVhbCBSZWZlcnJhbCBub3Qg
bWF0Y2hpbmcgdGhlIGV4cGVjdGVkIG9uZSkuPC9wPg0KDQo8cD5OZXh0IHN0ZXAgd2FzIHRv
IGNoYW5nZSB0aGUgcHJveHkgc2V0dGluZ3Mgc28gdGhhdCB0aGUgb3JpZ2luYWwgSE9TVCBo
ZWFkZXIgd2FzIGZvcndhcmRlZCB0byBQaXdpay4gQW5vdGhlciBlcnJvciBwb3BwZWQgdXAg
c3RhdGluZyAoYXMgYSBjb25jbHVzaW9uLCB0aGUgZXJyb3IgdGV4dCB3YXMgcmF0aGVyIHN0
dXBpZCBsaWtlIDxzdHJvbmc+UGl3aWsgd2FzIGFjY2Vzc2VkIGZyb20gW1VSTF0gYnV0IGl0
IHdhcyBjb25maWd1cmVkIHRvIGJlIGFjY2Vzc2VkIGZyb20gW1VSTF08L3N0cm9uZz4pIHRo
YXQgdGhlIHZhbHVlIG9mIHRoZSBIT1NUIGhlYWRlciBpcyBub3QgcmVnaXN0ZXJlZCBhcyBz
YWZlIGluIDxjb2RlPmNvbmZpZ1xjb25maWcuaW5pLnBocDwvY29kZT4uPC9wPg0KDQo8cD5C
eSBhZGRpbmcgdGhlIEZRRE4gaW4gPGNvZGU+W0dlbmVyYWxdPC9jb2RlPiBzZWN0aW9uIGFz
OjwvcD4NCg0KPHByZT48Y29kZT50cnVzdGVkX2hvc3RzW10gPSAmcXVvdDtGUUROJnF1b3Q7
DQo8L2NvZGU+PC9wcmU+DQoNCjxwPnRoZSBpbnRlZ3JhdGlvbiB3b3JrcyBqdXN0IGZpbmUu
PC9wPg0K