In this example we have extracted the FaceBook App reviews from Itunes.
Rating trends across the last few months

- Sharp increase in negative ratings while positive ratings are flat.
What is the market wise sentiment?

- India shows more positive trends compared with US & GB
Trend of actual ratings across the months/markets

- We do not have a very good spread of data since US has maximum reviews in last month itself while countries like IN have it spread over last few months.
Trend of actual ratings across the months/app versions

- We can see that certain app versions spiked in their negative ratings. We will check on this fact during the sentiment analysis on the comments.
Trend of actual ratings across the app versions/markets

- We see that due to the data extract where certain markets have higher review counts compared with others, the app versions are not linear. US/GB have high reviews in last 1-2 months hence we have data only for the latest few app versions.
Lets process the review texts and do some sentiment analysis via natural language processing(NLP)
Polarity analysis by positive/negative sentiment

Sentiment distribution

Sentiment analysis on the review text per ratings


- Users giving ratings=1&2 show high usage of negative sentiments.
Sentiment analysis on the review text per market

- Indians tend to be positive in their overall sentiments. UK/US tends to be more negative.


- Indians are having the spike in the negative flavors in their sentiments. UK does show high negative sentiments.

- US is showing more positive trends in their review. We need to note that we have gaps in review across markets/months/app versions so US could be positive across certain app versions while GB/IN might not.

- Indians have a high spike in negative sentiments while British have for positive sentiment.
What are the string lengths of the reviews per rating, markets?

- As expected, positive reviews have less average review lengths compared to negative review.. We do like to rant i guess !
LS0tCnRpdGxlOiAiRXhwbG9yZSBJT1MgQXBwcyBSZXZpZXdzIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpgYGB7ciBnbG9iYWxfb3B0aW9ucywgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGZpZy53aWR0aD02LCBmaWcuYXNwPTAuNjE4LG91dC53aWR0aCA9ICI3MCUiLGZpZy5hbGlnbiA9ImNlbnRlciIsZWNobz1GQUxTRSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgcm93cy5wcmludD0zMCxjb2xzLnByaW50PTEwKQoKbGlicmFyeShyZXRpY3VsYXRlKQp1c2VfcHl0aG9uKCIvVXNlcnMvdmluYXljaHVyaS9hbmFjb25kYTMvYmluL3B5dGhvbiIpCm9wdGlvbnMoc2NpcGVuID0gOTk5KQoKCmBgYAoKSW4gdGhpcyBleGFtcGxlIHdlIGhhdmUgZXh0cmFjdGVkIHRoZSBGYWNlQm9vayBBcHAgcmV2aWV3cyBmcm9tIEl0dW5lcy4KCmBgYHtyIGxvYWRfbGlicywgaW5jbHVkZT1GQUxTRX0KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkodGlkeXRleHQpCmxpYnJhcnkoZGF0YS50YWJsZSkKbGlicmFyeShsdWJyaWRhdGUpCmxpYnJhcnkoUkNvbG9yQnJld2VyKSAKbGlicmFyeShnZ3RoZW1lcykKc291cmNlKCIvVXNlcnMvdmluYXljaHVyaS9WSU5BWS9WSU5BWV9SL3ZpbmF5X2Z1bmN0aW9ucy92aW5heV9mdW5jLlIiKQoKdGhlbWVfc2V0KHRoZW1lX2dyYXkoMTIpICsgIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiksdGV4dCA9IGVsZW1lbnRfdGV4dChmYW1pbHkgPSAiTWVubG8tUmVndWxhciIpKSkKdGhlbWVfc2V0KHRoZW1lX2dyYXkoMTIpICsgIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiksdGV4dCA9IGVsZW1lbnRfdGV4dChmYW1pbHkgPSAiQW5kYWxlTW9ubyIpKSkKdGhlbWVfc2V0KHRoZW1lX2dyYXkoMTEpICsgIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJwbGFpbiIpLHRleHQgPSBlbGVtZW50X3RleHQoZmFtaWx5ID0gIkZpcmFDb2RlLUxpZ2h0IikpKQoKCmBgYAoKYGBge3IgLGluY2x1ZGU9RkFMU0V9CmRmPC0gZnJlYWQoIi9Vc2Vycy92aW5heWNodXJpL1ZJTkFZL2RhdGFzZXQvaXR1bmVzX3Jldmlld3MvaXR1bmVzLmNzdiIpCm5hbWVzKGRmKTwtIHZpbl9zZXRkZm5hbWVzKG5hbWVzKGRmKSkKZGYkSUQ8LSByb3cubmFtZXMoZGYpCgojIyByZWFycmFuZ2UgY29sdW1ucwpkZjwtY2JpbmQoZGYlPiVzZWxlY3QoSUQpLGRmJT4lc2VsZWN0KC1JRCkpCgoKdG1wX2RmPC0gZGYlPiUKICBzZWxlY3QoSUQscmV2aWV3KQoKCm5hbWVzKGRmKQpgYGAKCmBgYHtyfQphZGRfZml2ZTMwPC1mdW5jdGlvbihwKXsKICAgIHJldHVybihwK3RoZW1lX2ZpdmV0aGlydHllaWdodCgpK3NjYWxlX2ZpbGxfZml2ZXRoaXJ0eWVpZ2h0KCkpCn0KYGBgCgpgYGB7ciBpbmNsdWRlPUZBTFNFfQpzdHIoZGYpCmBgYAoKYGBge3J9CiMgTGV0cyBhZGQgc29tZSBtb3JlIGNvbHVtbnMgYmFzZWQgb24gdGhlIGRhdGVzIGFuZCByYXRpbmdzCgojbmV3IGRhdGUKZGYkbmV3X2RhdGU8LSBhcy5EYXRlKGRmJGRhdGUpCgpkZiRkYXRlX21vbnRoPC1sdWJyaWRhdGU6Om1vbnRoKGRmJGRhdGUpCmRmJGRhdGVfeWVhcjwtbHVicmlkYXRlOjp5ZWFyKGRmJGRhdGUpCmRmJGRhdGVfeWVhcl9tb250aDwtcGFzdGUwKGx1YnJpZGF0ZTo6eWVhcihkZiRkYXRlKSxzdHJfcGFkKGx1YnJpZGF0ZTo6bW9udGgoZGYkZGF0ZSksd2lkdGg9MixzaWRlPSJsZWZ0IixwYWQ9IjAiKSkKCiNyYXRpbmdzIDEtMyBhcmUgbmVnYXRpdmUsIDQtNSBhcmUgcG9zaXRpdmUKZGYlPiUKICBtdXRhdGUobmV3X3JhdGluZ3M9aWZlbHNlKHJhdGluZzw0LCduZWdhdGl2ZScsJ3Bvc2l0aXZlJykpLT5kZgoKYGBgCgo8YnI+PGhyPgojIyMjIFJhdGluZyB0cmVuZHMgYWNyb3NzIHRoZSBsYXN0IGZldyBtb250aHMKYGBge3J9CmRmJT4lCiAgY291bnQoZGF0ZV95ZWFyX21vbnRoLG5ld19yYXRpbmdzKSU+JQogIGdncGxvdChhZXMoZGF0ZV95ZWFyX21vbnRoLG4sZmlsbD1uZXdfcmF0aW5ncykpKwogIGxhYnModGl0bGU9IlJhdGluZyB0cmVuZHMiLHg9IiIseT0iIikrCiAgZ2VvbV9jb2woKS0+cAoKcHJpbnQoYWRkX2ZpdmUzMChwKSkKCmBgYAoqIFNoYXJwIGluY3JlYXNlIGluIG5lZ2F0aXZlIHJhdGluZ3Mgd2hpbGUgcG9zaXRpdmUgcmF0aW5ncyBhcmUgZmxhdC4KCgo8YnI+PGhyPgojIyMjIFdoYXQgaXMgdGhlIG1hcmtldCB3aXNlIHNlbnRpbWVudD8KYGBge3J9CgpkZiU+JQogIGNvdW50KG1hcmtldCxuZXdfcmF0aW5ncyklPiUKICBnZ3Bsb3QoYWVzKG1hcmtldCxuLGZpbGw9bmV3X3JhdGluZ3MpKSsKICBsYWJzKHRpdGxlPSJNYXJrZXQgd2lzZSBzZW50aW1lbnQiLHg9IiIseT0iIikrCiAgZ2VvbV9jb2woKS0+cAoKcHJpbnQoYWRkX2ZpdmUzMChwKSkKCmBgYAoKKiBJbmRpYSBzaG93cyBtb3JlIHBvc2l0aXZlIHRyZW5kcyBjb21wYXJlZCB3aXRoIFVTICYgR0IKCjxicj48aHI+CiMjIyMgVHJlbmQgb2YgYWN0dWFsIHJhdGluZ3MgYWNyb3NzIHRoZSBtb250aHMvbWFya2V0cwoKYGBge3J9CmRmJT4lCiAgY291bnQoZGF0ZV95ZWFyX21vbnRoLG1hcmtldCxyYXRpbmcpJT4lCiAgZ2dwbG90KGFlcyhyYXRpbmcsbikpKwogIGdlb21fY29sKGZpbGw9IiM0Nzc5QzciKSsKICBsYWJzKHRpdGxlPSJBY3R1YWwgcmF0aW5ncyBhY3Jvc3MgdGhlIG1vbnRocy9tYXJrZXRzIix4PSIiLHk9IiIpKwogIGZhY2V0X2dyaWQobWFya2V0fmRhdGVfeWVhcl9tb250aCktPnAKCgpwcmludChhZGRfZml2ZTMwKHApKQoKCmBgYAoKKiBXZSBkbyBub3QgaGF2ZSBhIHZlcnkgZ29vZCBzcHJlYWQgb2YgZGF0YSBzaW5jZSBVUyBoYXMgbWF4aW11bSByZXZpZXdzIGluIGxhc3QgbW9udGggaXRzZWxmIHdoaWxlIGNvdW50cmllcyBsaWtlIElOIGhhdmUgaXQgc3ByZWFkIG92ZXIgbGFzdCBmZXcgbW9udGhzLgoKPGJyPjxocj4KIyMjIyBUcmVuZCBvZiBhY3R1YWwgcmF0aW5ncyBhY3Jvc3MgdGhlIG1vbnRocy9hcHAgdmVyc2lvbnMKCmBgYHtyLGZpZy53aWR0aD02LjMsZmlnLmhlaWdodD0zfQpkZiU+JQogIGNvdW50KGRhdGVfeWVhcl9tb250aCxhcHBfdmVyc2lvbixyYXRpbmcpJT4lCiAgZ2dwbG90KGFlcyhyYXRpbmcsbikpKwogIGdlb21fY29sKGZpbGw9IiM0Nzc5QzciKSsKICBmYWNldF9ncmlkKGRhdGVfeWVhcl9tb250aH5hcHBfdmVyc2lvbixzY2FsZXM9ImZyZWUiKSsKICBsYWJzKHRpdGxlPSJBY3R1YWwgcmF0aW5ncyBhY3Jvc3MgdGhlIG1vbnRocy9hcHAgdmVyc2lvbiIseD0iIix5PSIiKSsKICB0aGVtZV91cGRhdGUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE0KSktPnAKCgpwcmludChhZGRfZml2ZTMwKHApKQoKYGBgCgoqIFdlIGNhbiBzZWUgdGhhdCBjZXJ0YWluIGFwcCB2ZXJzaW9ucyBzcGlrZWQgaW4gdGhlaXIgbmVnYXRpdmUgcmF0aW5ncy4gV2Ugd2lsbCBjaGVjayBvbiB0aGlzIGZhY3QgZHVyaW5nIHRoZSBzZW50aW1lbnQgYW5hbHlzaXMgb24gdGhlIGNvbW1lbnRzLgoKPGJyPjxocj4KIyMjIyBUcmVuZCBvZiBhY3R1YWwgcmF0aW5ncyBhY3Jvc3MgdGhlIGFwcCB2ZXJzaW9ucy9tYXJrZXRzCgpgYGB7cixmaWcud2lkdGg9Ni4zLGZpZy5oZWlnaHQ9M30KZGYlPiUKICBjb3VudChtYXJrZXQsYXBwX3ZlcnNpb24scmF0aW5nKSU+JQogIGdncGxvdChhZXMocmF0aW5nLG4pKSsKICBnZW9tX2NvbChmaWxsPSIjNDc3OUM3IikrCiAgZmFjZXRfZ3JpZChtYXJrZXR+YXBwX3ZlcnNpb24sc2NhbGVzPSJmcmVlIikrCiAgbGFicyh0aXRsZT0iQWN0dWFsIHJhdGluZ3MgYWNyb3NzIHRoZSBtYXJrZXRzL2FwcCB2ZXJzaW9uIix4PSIiLHk9IiIpKwogIHRoZW1lX3VwZGF0ZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTQpKS0+cAoKCnByaW50KGFkZF9maXZlMzAocCkpCgpgYGAKCiogV2Ugc2VlIHRoYXQgZHVlIHRvIHRoZSBkYXRhIGV4dHJhY3Qgd2hlcmUgY2VydGFpbiBtYXJrZXRzIGhhdmUgaGlnaGVyIHJldmlldyBjb3VudHMgY29tcGFyZWQgd2l0aCBvdGhlcnMsIHRoZSBhcHAgdmVyc2lvbnMgYXJlIG5vdCBsaW5lYXIuIFVTL0dCIGhhdmUgaGlnaCByZXZpZXdzIGluIGxhc3QgMS0yIG1vbnRocyBoZW5jZSB3ZSBoYXZlIGRhdGEgb25seSBmb3IgdGhlIGxhdGVzdCBmZXcgYXBwIHZlcnNpb25zLgoKCjxicj48aHI+CkxldHMgcHJvY2VzcyB0aGUgcmV2aWV3IHRleHRzIGFuZCBkbyBzb21lIHNlbnRpbWVudCBhbmFseXNpcyB2aWEgbmF0dXJhbCBsYW5ndWFnZSBwcm9jZXNzaW5nKE5MUCkKCmBgYHtyfQojIGRmJT4lCiMgICBmaWx0ZXIobWFya2V0PT0ndXMnKSU+JQojICAgdW5uZXN0X3Rva2VucyhvdXRwdXQ9IndvcmQiLGlucHV0PXJldmlldyklPiUKIyAgIGFudGlfam9pbihieT0id29yZCIsc3RvcF93b3JkcyktPnRtcF9kZgojIAojIHRtcF9kZiU+JQojICAgaW5uZXJfam9pbihieT0id29yZCIsZ2V0X3NlbnRpbWVudHMoImxvdWdocmFuIikpLT50bXBfZGYyCgoKCiMgdG1wX2RmPC0gZGYlPiUKIyAgIHNlbGVjdChJRCxyZXZpZXcpCgoKYGBgCgpgYGB7cHl0aG9ufQpmcm9tIHRleHRibG9iIGltcG9ydCBUZXh0QmxvYgoKZnJvbSB2YWRlclNlbnRpbWVudC52YWRlclNlbnRpbWVudCBpbXBvcnQgU2VudGltZW50SW50ZW5zaXR5QW5hbHl6ZXIKIyBwb3NpdGl2ZSBzZW50aW1lbnQ6IGNvbXBvdW5kIHNjb3JlID49IDAuNQojIG5ldXRyYWwgc2VudGltZW50OiAoY29tcG91bmQgc2NvcmUgPiAtMC41KSBhbmQgKGNvbXBvdW5kIHNjb3JlIDwgMC41KQojIG5lZ2F0aXZlIHNlbnRpbWVudDogY29tcG91bmQgc2NvcmUgPD0gLTAuNQoKCgphbmFseXNlciA9IFNlbnRpbWVudEludGVuc2l0eUFuYWx5emVyKCkKZGVmIHNlbnRpbWVudF9hbmFseXplcl9zY29yZXMoc2VudGVuY2UpOgogICAgcmV0dXJuKGFuYWx5c2VyLnBvbGFyaXR5X3Njb3JlcyhzZW50ZW5jZSkpCgoKIyBUaGUgcG9sYXJpdHkgaXMgdGhlIHNlbnRpbWVudCBpdHNlbGYsIHJhbmdpbmcgZnJvbSBhIC0xIHRvIGEgKzEuIAojIFRoZSBzdWJqZWN0aXZpdHkgaXMgYSBtZWFzdXJlIG9mIHRoZSBzZW50aW1lbnQgYmVpbmcgb2JqZWN0aXZlIHRvIHN1YmplY3RpdmUsIGFuZCBnb2VzIGZyb20gMCB0byAxLiBXZSdkIHJhdGhlciBzZWUgc2VudGltZW50IHRoYXQgaXMgb2JqZWN0aXZlIHRoYW4gc3ViamVjdGl2ZSwgc28gYSBsb3dlciBzY29yZSBzaG91bGQgbGlrZWx5IGRlbm90ZSBhIG1vcmUgbGlrZWx5LXRvLWJlLWFjY3VyYXRlIHJlYWRpbmcKCmRlZiBkZXRlY3RfcG9sYXJpdHkodGV4dCk6CiAgICB0bXBfeD1UZXh0QmxvYih0ZXh0KS5zZW50aW1lbnQKICAgIHRtcF9kaWM9eydwb2xhcml0eSc6dG1wX3hbMF0sJ3N1YmplY3Rpdml0eSc6dG1wX3hbMV19CiAgICByZXR1cm4odG1wX2RpYykKICAgIAoKYGBgCgpgYGB7cHl0aG9uLGluY2x1ZGU9RkFMU0V9CmltcG9ydCBwYW5kYXMgYXMgcGQgCgpwMT1yLnRtcF9kZgoKcDFbJ2xlbl9yZXZpZXcnXT1wMVsncmV2aWV3J10uc3RyLmxlbigpCgpwb2xhcml0eT1wMVsncmV2aWV3J10uYXBwbHkoZGV0ZWN0X3BvbGFyaXR5KQpwb2xhcml0eT1wZC5EYXRhRnJhbWUuZnJvbV9yZWNvcmRzKHBvbGFyaXR5KQoKc2VudGltZW50ID0gcDFbJ3JldmlldyddLmFwcGx5KHNlbnRpbWVudF9hbmFseXplcl9zY29yZXMpCnNlbnRpbWVudD1wZC5EYXRhRnJhbWUuZnJvbV9yZWNvcmRzKHNlbnRpbWVudCkKCnAxPXAxLmpvaW4ocG9sYXJpdHkpLmpvaW4oc2VudGltZW50KQoKIyBwMSA9IHBkLmNvbmNhdChbcDEsc2VudGltZW50LmFwcGx5KHBkLlNlcmllcyldLDEpCiMgcDE9cGQuY29uY2F0KHAxLHBkLkRhdGFGcmFtZShbc2VudGltZW50XSksYXhpcz0xKQoKcHJpbnQoIlZBREVSIE5MUCBkb25lIikKYGBgCgoKYGBge3J9CnRtcF9kZjI8LSBweSRwMQpgYGAKCmBgYHtyfQp0bXBfZGYzPC0gbGVmdF9qb2luKGRmLHRtcF9kZjIlPiVzZWxlY3QoLXJldmlldyksYnk9IklEIikKCmBgYAoKPGJyPjxocj4KIyMjIyBQb2xhcml0eSBhbmFseXNpcyBieSBwb3NpdGl2ZS9uZWdhdGl2ZSBzZW50aW1lbnQKYGBge3IsfQojI05vdyBsZXRzIHBsb3QgISEKCgp0bXBfZGYzJT4lCiAgZ2dwbG90KGFlcyhwb2xhcml0eSxmaWxsPW5ld19yYXRpbmdzKSkrCiAgbGFicyh0aXRsZT0iU2VudGltZW50IHBvbGFyaXR5IikrCiAgZ2VvbV9kZW5zaXR5KGFscGhhID0gMC41KS0+cDEKICAKcDE8LWFkZF9maXZlMzAocDEpCgp0bXBfZGYzJT4lCiAgZ2dwbG90KGFlcyhwb2xhcml0eSkpKwogIGdlb21fZGVuc2l0eShmaWxsPSIjNDc3OUM3IikrCiAgbGFicyh0aXRsZT0iUG9sYXJpdHkgZGlzdHJpYnV0aW9uIGJ5IHNlbnRpbWVudCIpKwogICMgZ2VvbV9kZW5zaXR5KGFlcyhzdWJqZWN0aXZpdHkpLGFscGhhPTAuNSxmaWxsPSJncmF5IikrCiAgZmFjZXRfd3JhcCh+bmV3X3JhdGluZ3MpLT5wMgogIApwMjwtYWRkX2ZpdmUzMChwMikKCmNvd3Bsb3Q6OnBsb3RfZ3JpZChwMSxwMixuY29sID0gMSkKCgpgYGAKCjxicj48aHI+CiMjIyMgU2VudGltZW50IGRpc3RyaWJ1dGlvbgpgYGB7cn0KCnRtcF9kZjMlPiUKICBnZ3Bsb3QoYWVzKG5ldSxmaWxsPW5ld19yYXRpbmdzKSkrCiAgbGFicyh0aXRsZT0iUmV2aWV3IHNlbnRpbWVudHM6TmV1dHJhbCIpKwogIGdlb21fZGVuc2l0eShhbHBoYSA9IDAuNyktPnAxCiAgCiAKcDE8LWFkZF9maXZlMzAocDEpCgp0bXBfZGYzJT4lCiAgZ2dwbG90KGFlcyhwb3MsZmlsbD1uZXdfcmF0aW5ncykpKwogIGxhYnModGl0bGU9IlJldmlldyBzZW50aW1lbnRzOlBvc2l0aXZlIikrCiAgZ2VvbV9kZW5zaXR5KGFscGhhID0gMC43KS0+cDIKICAKcDI8LWFkZF9maXZlMzAocDIpCgp0bXBfZGYzJT4lCiAgZ2dwbG90KGFlcyhuZWcsZmlsbD1uZXdfcmF0aW5ncykpKwogIGxhYnModGl0bGU9IlJldmlldyBzZW50aW1lbnRzOk5lZ2F0aXZlIikrCiAgZ2VvbV9kZW5zaXR5KGFscGhhID0gMC43KS0+cDMKCiAgCnAzPC1hZGRfZml2ZTMwKHAzKQoKdG1wX2RmMyU+JQogIGdncGxvdChhZXMoY29tcG91bmQsZmlsbD1uZXdfcmF0aW5ncykpKwogIGxhYnModGl0bGU9IlJldmlldyBzZW50aW1lbnRzOkNvbXBvdW5kIikrCiAgZ2VvbV9kZW5zaXR5KGFscGhhID0gMC43KS0+cDQKCnA0PC1hZGRfZml2ZTMwKHA0KQoKCmBgYAoKYGBge3IsIGZpZy53aWR0aD02LjIsZmlnLmhlaWdodD0zfQpjb3dwbG90OjpwbG90X2dyaWQocDIscDMscDEscDQpCgpgYGAKCjxicj48aHI+CiMjIyMgU2VudGltZW50IGFuYWx5c2lzIG9uIHRoZSByZXZpZXcgdGV4dCBwZXIgcmF0aW5ncwpgYGB7cn0KdG1wX2RmMyU+JQogIGdncGxvdChhZXMocG9zKSkrCiAgZ2VvbV9kZW5zaXR5KGZpbGw9IiM0Nzc5QzciKSsKICBsYWJzKHRpdGxlPSJSZXZpZXcgdGV4dCBwb3NpdGl2ZSBzZW50aW1lbnQgcGVyIHJhdGluZyIpKwogIGZhY2V0X3dyYXAofnJhdGluZyxsYWJlbGxlciA9ICJsYWJlbF9ib3RoIiktPnAKCgpwcmludChhZGRfZml2ZTMwKHApKQoKCmBgYAoKYGBge3J9CnRtcF9kZjMlPiUKICBnZ3Bsb3QoYWVzKG5lZykpKwogIGdlb21fZGVuc2l0eShmaWxsPSIjNDc3OUM3IikrCiAgbGFicyh0aXRsZT0iUmV2aWV3IHRleHQgbmVnYXRpdmUgc2VudGltZW50IHBlciByYXRpbmciKSsKICBmYWNldF93cmFwKH5yYXRpbmcsbGFiZWxsZXIgPSAibGFiZWxfYm90aCIpLT5wCiAgCnByaW50KGFkZF9maXZlMzAocCkpCgpgYGAKCiogVXNlcnMgZ2l2aW5nIHJhdGluZ3M9MSYyIHNob3cgaGlnaCB1c2FnZSBvZiBuZWdhdGl2ZSBzZW50aW1lbnRzLgoKCjxicj48aHI+CiMjIyMgU2VudGltZW50IGFuYWx5c2lzIG9uIHRoZSByZXZpZXcgdGV4dCBwZXIgbWFya2V0CmBgYHtyLH0KCnRtcF9kZjMlPiUKICBnZ3Bsb3QoYWVzKGNvbXBvdW5kKSkrCiAgZ2VvbV9kZW5zaXR5KGZpbGw9IiM0Nzc5QzciKSsKICBsYWJzKHRpdGxlPSJSZXZpZXcgdGV4dCBzZW50aW1lbnQgcGVyIG1hcmtldCIpKwogIGZhY2V0X3dyYXAofm1hcmtldCxsYWJlbGxlciA9ICJsYWJlbF9ib3RoIiktPnAKICAKcHJpbnQoYWRkX2ZpdmUzMChwKSkKCmBgYAoKKiBJbmRpYW5zIHRlbmQgdG8gYmUgcG9zaXRpdmUgaW4gdGhlaXIgb3ZlcmFsbCBzZW50aW1lbnRzLiBVSy9VUyB0ZW5kcyB0byBiZSBtb3JlIG5lZ2F0aXZlLgoKYGBge3J9CnRtcF9kZjMlPiUKICBnZ3Bsb3QoYWVzKG5ldSkpKwogIGdlb21fZGVuc2l0eShmaWxsPSIjNDc3OUM3IikrCiAgbGFicyh0aXRsZT0iUmV2aWV3IHRleHQgbmV1dHJhbCBzZW50aW1lbnQgcGVyIG1hcmtldCIpKwogIGZhY2V0X3dyYXAofm1hcmtldCxsYWJlbGxlciA9ICJsYWJlbF9ib3RoIiktPnAKICAKcHJpbnQoYWRkX2ZpdmUzMChwKSkKCmBgYAoKYGBge3J9CnRtcF9kZjMlPiUKICBnZ3Bsb3QoYWVzKG5lZykpKwogIGdlb21fZGVuc2l0eShmaWxsPSIjNDc3OUM3IikrCiAgbGFicyh0aXRsZT0iUmV2aWV3IHRleHQgbmVnYXRpdmUgc2VudGltZW50IHBlciBtYXJrZXQiKSsKICBmYWNldF93cmFwKH5tYXJrZXQsbGFiZWxsZXIgPSAibGFiZWxfYm90aCIpLT5wCiAgCnByaW50KGFkZF9maXZlMzAocCkpCgpgYGAKCiogSW5kaWFucyBhcmUgaGF2aW5nIHRoZSBzcGlrZSBpbiB0aGUgbmVnYXRpdmUgZmxhdm9ycyBpbiB0aGVpciBzZW50aW1lbnRzLiBVSyBkb2VzIHNob3cgaGlnaCBuZWdhdGl2ZSBzZW50aW1lbnRzLgoKYGBge3J9CnRtcF9kZjMlPiUKICBnZ3Bsb3QoYWVzKHBvcykpKwogIGdlb21fZGVuc2l0eShmaWxsPSIjNDc3OUM3IikrCiAgbGFicyh0aXRsZT0iUmV2aWV3IHRleHQgcG9zaXRpdmUgc2VudGltZW50IHBlciBtYXJrZXQiKSsKICBmYWNldF93cmFwKH5tYXJrZXQsbGFiZWxsZXIgPSAibGFiZWxfYm90aCIpLT5wCiAgCnByaW50KGFkZF9maXZlMzAocCkpCgpgYGAKCiogVVMgaXMgc2hvd2luZyBtb3JlIHBvc2l0aXZlIHRyZW5kcyBpbiB0aGVpciByZXZpZXcuIFdlIG5lZWQgdG8gbm90ZSB0aGF0IHdlIGhhdmUgZ2FwcyBpbiByZXZpZXcgYWNyb3NzIG1hcmtldHMvbW9udGhzL2FwcCB2ZXJzaW9ucyBzbyBVUyBjb3VsZCBiZSBwb3NpdGl2ZSBhY3Jvc3MgY2VydGFpbiBhcHAgdmVyc2lvbnMgd2hpbGUgR0IvSU4gbWlnaHQgbm90LgoKYGBge3IsIGluY2x1ZGU9RkFMU0V9Cgp0bXBfZGYzJT4lCiAgc2VsZWN0KG5lZyxwb3MsY29tcG91bmQscmF0aW5nKSU+JQogIHJlc2hhcGUyOjptZWx0KGlkLnZhcnM9InJhdGluZyIpJT4lCiAgZ2dwbG90KGFlcyh2YWx1ZSkpKwogIGdlb21fZGVuc2l0eShmaWxsPSIjNDc3OUM3IikrCiAgZmFjZXRfZ3JpZCh2YXJpYWJsZX5yYXRpbmcsbGFiZWxsZXIgPSAibGFiZWxfYm90aCIpLT5wCiAgCnByaW50KGFkZF9maXZlMzAocCkpCgpgYGAKCgpgYGB7cn0KdG1wX2RmMyU+JQogIHNlbGVjdChuZXUsbmVnLHBvcyxjb21wb3VuZCxtYXJrZXQpJT4lCiAgcmVzaGFwZTI6Om1lbHQoaWQudmFycz0ibWFya2V0IiklPiUKICBnZ3Bsb3QoYWVzKHZhbHVlKSkrCiAgbGFicyh0aXRsZT0iUmV2aWV3IHRleHQgc2VudGltZW50cyBwZXIgbWFya2V0IikrCiAgZ2VvbV9kZW5zaXR5KGZpbGw9IiM0Nzc5QzciKSsKICBmYWNldF9ncmlkKG1hcmtldH52YXJpYWJsZSxsYWJlbGxlciA9ICJsYWJlbF92YWx1ZSIpLT5wCiAgCnByaW50KGFkZF9maXZlMzAocCkpCgpgYGAKCiogSW5kaWFucyBoYXZlIGEgaGlnaCBzcGlrZSBpbiBuZWdhdGl2ZSBzZW50aW1lbnRzIHdoaWxlIEJyaXRpc2ggaGF2ZSBmb3IgcG9zaXRpdmUgc2VudGltZW50LgoKPGJyPjxocj4KIyMjIyBXaGF0IGFyZSB0aGUgc3RyaW5nIGxlbmd0aHMgb2YgdGhlIHJldmlld3MgcGVyIHJhdGluZywgbWFya2V0cz8KCmBgYHtyIGxlbl9yZXZpZXdzLH0KdmxpbmVfZGY8LSB0bXBfZGYzJT4lCiAgZ3JvdXBfYnkocmF0aW5nKSU+JQogIHN1bW1hcmlzZSh0bXBfbWVhbj1tZWRpYW4obGVuX3JldmlldykpCgoKIyAwID0gYmxhbmssIDEgPSBzb2xpZCwgMiA9IGRhc2hlZCwgMyA9IGRvdHRlZCwgNCA9IGRvdGRhc2gsIDUgPSBsb25nZGFzaCwgNiA9IHR3b2Rhc2gKCnRtcF9kZjMlPiUKICBnZ3Bsb3QoYWVzKGxlbl9yZXZpZXcpKSsKICBnZW9tX2RlbnNpdHkoZmlsbD0iIzQ3NzlDNyIpKwogIGxhYnModGl0bGU9Ik1lZGlhbiBvZiByZXZpZXcgdGV4dCBsZW5ndGggcGVyIHJhdGluZyIpKwogIGdlb21fdmxpbmUoZGF0YSA9IHZsaW5lX2RmLCBhZXMoeGludGVyY2VwdCA9IHRtcF9tZWFuKSwgbGluZXR5cGUgPSAyLGNvbG91ciA9ICJyZWQ0IikrCiAgZmFjZXRfd3JhcCh+cmF0aW5nLGxhYmVsbGVyID0gImxhYmVsX2JvdGgiKS0+cAogIAoKcHJpbnQoYWRkX2ZpdmUzMChwKSkKCmBgYAoKKiBBcyBleHBlY3RlZCwgcG9zaXRpdmUgcmV2aWV3cyBoYXZlIGxlc3MgYXZlcmFnZSByZXZpZXcgbGVuZ3RocyBjb21wYXJlZCB0byBuZWdhdGl2ZSByZXZpZXcuLiBXZSBkbyBsaWtlIHRvIHJhbnQgaSBndWVzcyAhCgo8YnI+PGhyPgojIyMjIE1lZGlhbiBvZiByZXZpZXcgbGVuZ3RocyBwZXIgcmF0aW5ncwpgYGB7cn0KCnZsaW5lX2RmPC0gdG1wX2RmMyU+JQogIGdyb3VwX2J5KG5ld19yYXRpbmdzKSU+JQogIHN1bW1hcmlzZSh0bXBfbWVhbj1tZWRpYW4obGVuX3JldmlldykpCgp0bXBfZGYzJT4lCiAgZ2dwbG90KGFlcyhsZW5fcmV2aWV3KSkrCiAgZ2VvbV9kZW5zaXR5KGZpbGw9IiM0Nzc5QzciKSsKICBsYWJzKHRpdGxlPSJNZWRpYW4gb2YgcmV2aWV3IHRleHQgbGVuZ3RoIGZvciBlYWNoIHJhdGluZyIpKwogIGdlb21fdmxpbmUoZGF0YSA9IHZsaW5lX2RmLCBhZXMoeGludGVyY2VwdCA9IHRtcF9tZWFuKSwgbGluZXR5cGUgPSAyLGNvbG91ciA9ICJyZWQ0IikrCiAgZmFjZXRfd3JhcCh+bmV3X3JhdGluZ3MsbGFiZWxsZXIgPSAibGFiZWxfYm90aCIpLT5wCiAgCgpwcmludChhZGRfZml2ZTMwKHApKQoKYGBgCgoqIFBlb3BsZSB3cml0ZSBtb3JlIGZvciBuZWdhdGl2ZSByZXZpZXcgYXMgY29tcGFyZWQgdG8gcG9zaXRpdmUKCjxicj48aHI+CiMjIyMgTWVkaWFuIG9mIHJldmlldyBsZW5ndGhzIHBlciBtYXJrZXQKYGBge3J9CnZsaW5lX2RmPC0gdG1wX2RmMyU+JQogIGdyb3VwX2J5KG1hcmtldCklPiUKICBzdW1tYXJpc2UodG1wX21lYW49bWVkaWFuKGxlbl9yZXZpZXcpKQoKCnRtcF9kZjMlPiUKICBnZ3Bsb3QoYWVzKGxlbl9yZXZpZXcpKSsKICBnZW9tX2RlbnNpdHkoZmlsbD0iIzQ3NzlDNyIpKwogIGxhYnModGl0bGU9Ik1lZGlhbiBvZiByZXZpZXcgdGV4dCBsZW5ndGggZm9yIGVhY2ggbWFya2V0IikrCiAgZ2VvbV92bGluZShkYXRhID0gdmxpbmVfZGYsIGFlcyh4aW50ZXJjZXB0ID0gdG1wX21lYW4pLCBsaW5ldHlwZSA9ICJkYXNoZWQiLGNvbG91ciA9ICJyZWQ0IikrCiAgZmFjZXRfd3JhcCh+bWFya2V0LGxhYmVsbGVyID0gImxhYmVsX2JvdGgiKS0+cAogIAoKcHJpbnQoYWRkX2ZpdmUzMChwKSkKCgpgYGAKCiogQW1lcmljYW5zIHdyaXRlIG1vcmUgaW4gZ2VuZXJhbCBhcyBjb21wYXJlZCB3aXRoIElOICYgR0IuIFRoZXJlIGFyZSBmZXcgb3V0bGluZXJzIGhhdmluZyA+MTAwMCB0ZXh0IGxlbmd0aHMsIHdlIHdpbGwgaGF2ZSB0byByZXZpZXcgdGhvc2UgdG8gc2VlIGlmIHRoZXkgYXJlIHZhbGlkIG9yIHJhbnRpbmdzIQoKCgoKCgoKCmBgYHtyIHJvdWdoX3dvcmsgLGluY2x1ZGU9RkFMU0UsIGV2YWw9RkFMU0V9CgojIFN1biBKdWwgMjEgMjA6MzA6MzQgMjAxOSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVJPVUdIIFdPUkstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKdG1wX2RmMyU+JQogIHNlbGVjdChuZXUscG9zLGNvbXBvdW5kLG1hcmtldCklPiUKICByZXNoYXBlMjo6bWVsdChpZC52YXJzPSJtYXJrZXQiKSU+JQogIGdncGxvdChhZXModmFsdWUpKSsKICBnZW9tX2RlbnNpdHkoYWxwaGE9LjUsZmlsbD0iIzQ3NzlDNyIscG9zaXRpb24gPSAic3RhY2siKSsKICBmYWNldF9ncmlkKG1hcmtldH52YXJpYWJsZSxzY2FsZXM9ImZyZWUiLGxhYmVsbGVyID0gImxhYmVsX2JvdGgiKQoKZGlzcGxheS5icmV3ZXIuYWxsKCkKCgpgYGAKCgoK