1 2 3 Previous Next

Qlik Design Blog

488 posts

Football season is almost over, only the Champions League winner is undecided yet, but soon the fútbol - football, soccer -  aficionado’s eyes will turn to this summer's tournament. Honestly, I can’t wait, this is the competition we all have been patiently waiting for the last four years. A long wait, especially if your team had a very disappointing tournament last time. No, it wasn’t a good 2014 World Cup for Spain.


If you are anything like me, you’d probably have already memorized each group’s teams, imagined any possible what-if scenario, and visualized your team’s captain getting that gorgeous golden trophy by July the 15th. We want to help you to take your guesses to the next level, and have a little bit of fun and competition.


Choose your Champion app will let you predict how this summer’s competition will finish, and more.




How it works


Our bracket is bit more sophisticated that most, we have created a data-driven experience. Each one of the decision points in the app has been enhanced with data, so when you pick a team to end up in the first place of a group, you can corroborate if your gut feeling matches with our data predictions. If you are doubtful about a knockout game winner simply check the stats and make an informed decision.


The process is simple, select first and second place in the groups stage, the bars next to the team names will tell you who is more likely to move to the next stage. Then in knockout round, check the gauge and the extended stats and pick the winner of each match to complete the bracket. Finally decide your tournament winner, and share it with your friends.


But there’s more


This year, we also want you to be able to track your bracket and check how do you rank among other people.


We added a simple login system using Facebook - no, we are not getting any of your personal data, not even your Facebook name nor email - and now you will be able to submit and save your bracket safely.  After the tournament have started, we will provide each one of you with a score based on how many predictions you got right.


You can use the Choose Your Champion score to compete against your friends and coworkers privately and beat them all!




Enjoy and share it!


If you want to use data from a hypercube to create a chart with picasso.js you're probably going to want to use the picasso.js q plugin. The q plugin makes it easy to extract data from a hypercube for use with picasso.js. In this post I'm going to go through the steps needed to use the q plugin for picasso.js to show you how to use hypercube data to create a chart with picasso.js, and also go over updating the chart when the hypercube data changes, and making selections in the QIX Engine from a picasso.js chart.


picasso.js scatter plot with hypercube data.png

Check out this observable notebook of creating a scatter plot with hypercube data and the q plugin

Setup picasso.js

You'll need to install picasso and picassoQ, and register picassoQ with picasso. You can install them with npm install --save picasso.js picasso-plugin-q, and then register picassoQ with picasso like below.

import picasso from 'picasso.js';
import picassoQ from 'picasso-plugin-q';

picasso.use(picassoQ); // this registers the picasso q plugin with picasso.js


Create and update picasso.js chart with hypercube data

You'll need a hypercube of course. I'm going to assume here that you know how to create a hypercube with the App API or enigma.js, and if not, there's other resources for learning how to do that, so we won't cover it again here. Below is a general pattern for creating and updating a picasso.js chart after creating a hypercube with enigma.js

(async () => {
const hypercube = await qDoc.createSessionObject(/* hypercube def */);
const layout = await hypercube.getLayout();
createPic(layout); // function that calls chart method on a picasso instance
hypercube.on('changed', async () => {  // listen for updates to hypercube
    const newLayout = await hypercube.getLayout();  // get new layout
    updatePic(newLayout); // function that calls update method on a picasso instance


In the above block, we create a hypercube, get the layout, and call a function we define that calls the chart method on an instance of picasso.js. Then we watch for the hypercube to update, and can use the update method of picasso.js to simply update the data for the chart. The createPic and updatePic functions might look something like this.

let chart;
const createPic = (layout) => {
chart = picasso().chart({
   element: document.querySelector('#container'), // some DOM element
   data: [{
     type: 'q', // this tells picasso the data is from a hypercube
     key: 'qHyperCube', // path to the hypercube from the layout,
     data: layout.qHyperCube
   settings: {} // the chart settings (scales, components, etc.)

const updatePic = (layout) => {
chart.update({ // we just need to update the data
    data: [{
     type: 'q',
     key: 'qHyperCube',
     data: layout.qHyperCube


Making selections in the QIX engine

The picasso q plugin has helper functions for generating methods to make QIX selections from a picasso.js brush. You just get a reference to the brush using the brush method of picasso, then use the selections method of picassoQ to generate the QIX methods, then apply them to your QIX model. It would look something like this.

const brush = chart.brush('name-of-brush'); // get reference to brush
const selection = picassoQ.selections(brush)[0]; // generate selection method
qDoc[selection.method](...selection.params); // apply selection method to model



And that's it. You can check out the observable notebook I created for this blog post, and the picasso-plugin-q too.

Hi folks - this video will show you how to get started with Qlik Sense Mobile from a basic sense. There have been some signifcant changes since I last recorded a video on this and it was time for a brief update. Due note that we have much more for those of you who administer, secure and deploy mobile BI. We work with Enterprise Mobile management vendors to tightly integrate our solution with their platforms. See the resource links below.


In this video you will learn how to:


  • Install the Qlik Sense Mobile App on iOS
  • Configure and Send Client Authentication Link Using the QMC
  • Verify Offline Security Settings
  • Start the app and login to your server
  • Download your app
  • Access your app offline


Note: Offline access via the Qlik Sense Mobile App is only available to Qlik Sense Enterprise customers. However, Qlik Sense servers and Qlik Sense Cloud can be quickly and easily accessed via a mobile device such as a tablet or smart phone by simply using a mobile browser that supports HTML5 - i.e. Chrome, Safari, etc. Check out these 2 videos to learn more:


Please let me know if you have any comments or questions.



Qlik Sense Mobile







Michael Tarallo (@mtarallo) | Twitter


Can't see the embedded video? YouTube blocked by your organization or region? Download the .mp4 to watch on your computer or mobile device.

layout.pngHey guys - I recently was inspired at Qonnections 2018 by our Big Data Qlik IoT Race game, so much so that I had to understand how it all worked and wanted to play with the underlying technology. Aside from gathering the statistics and providing an analysis on the results, I was really interested in learning about those little devices or "things" that were connected to the track. However, how would I use something like that? Not really knowing anything about Arduino, WEMOS and IoT in general, I set out on a mission to learn about this fascinating technology while incorporating somethings I enjoy such as Qlik and retro-gaming. Take a look how I made IoT interesting and fun to learn, by incorporating a Retrogaming spin and of course added some Qlik Sense data analysis.



5-9-2018 9-47-26 PM.png

Atari Action Analysis Dashboard




Thanks guys, hope you enjoyed it. Let me know what you think by leaving your questions and comments. I'll do my best to respond.


Can't see the video? YouTube blocked by your region or organization?


A copy of the video can be downloaded or streamed from here:



Michael Tarallo (@mtarallo) | Twitter

Jennell McIntire

Nested Loops

Posted by Jennell McIntire May 4, 2018

There are various loops/control statements that can be used in a script to control script execution.  Some common ones include:

  • If…then
  • Do…loop
  • For…next
  • For each…next

It is also possible to use one loop/control statement within another loop.  In the script I am going to review in this blog, I used all of these control statements except the do…loop to generate the rank of a company, by region, over 8 years.  Let me begin by setting the scene and explaining what I am trying to do.  I had 8 years’ worth of company data that included the company's overall rank (in a Data table).  Let’s say the overall rank is the company’s rank based on sales across all regions for a given year.  My goal is to get a company’s rank for their specific region, each year, based on the overall rank.  For example, in the example data table below Company C may have an overall rank of 3 in 2017 but in its region, North America, it is the top company so it has a regional rank of 1.


Example Data

YearCompanyOverall RankRegionRegional Rank
2017Company A1Europe1
2017Company B2Europe2
2017Company C3North America1
2017Company D4Central America1
2017Company E5North America2
2017Company F6Europe3
2017Company G7Europe4


What I would like to do via the script is determine the regional rank for each company, each year, so I can use it in a KPI object in an app.  Here is the script that I am using to accomplish this:


Let’s step through the script step by step.

  1. First, I use a For each…next loop to loop through each region (line 1). 
  2. Then I use a For…next loop to loop through the years (line 3).  Since I knew what years of data I had, I hard-coded the years but you can also use variables for the years which is a good idea if the years may vary. 
  3. My next step is to use an If…then statement (line7) to determine if this is my first time through the loop.  If it is the first time, year will be 2010 and the region will be Africa so this is what I check for in the If...then statement.  If this is the first time through the loop, I create a Temp table that has the key field, CompanyRegionKey, and the field, Regional Rank, which I calculate using the RowNo() function.  The RowNo() function returns the position of the current row in the resulting table starting at 1.  Since I am sorting the table by Rank, the rows will be added to the table in the regional rank order.  You can learn more about the RowNo() function in my RecNo or RowNo? blog.  If this is not the first time through the loop, then I create the Temp table and I use the noconcatenate prefix so that the data is not concatenated to the already existing Temp2 table (which has the same fields). 
  4. My next step is to create (line 26) or concatenate to (line 29) the Temp2 table which will store the key field and the new Regional Rank field. 
  5. After this step, I Drop the Temp table (line 32).  I remove the Temp table from the data model and recreate it every time I loop through the script so that RowNo() always starts at 1.  If I did not delete the Temp table and concatenated the data to it, the RowNo() function will pick up where it left off instead of starting over at 1.
  6. For each region, I loop through all the years and create and save the Regional Rank.  Once all the years are complete for a region, the script will go to the next region in the For each…next loop. 
  7. Once all regions and years are complete, I Left Join the Regional Rank field to my Data table and then Drop the Temp2 table from the data model.  I now have a Regional Rank value for each company in my Data table.

Save yourself time and lines of script by using loops when you need to repeat one or a series of statements in your script.  Loops can be nested, as I did in the script above, or used one at a time.  Instead of repeating the same statements for each year and each region, use nested loops so the statements in the script only need to be written once.  This also makes maintenance easier.  In the future, if a change needs to be made to the script, it only needs to be done once.  Check out other blogs about loops with Henric Cronstrom’s blog on Loops in the Script and my blog on the Do…Loop.



thumb.pngHey guys - what a week we had at Qonnections! If I met some of you while attending, it was a pleasure to meet you in person and I'm glad we had a chance to chat. I look forward to working with you in the Qlik Community.  I also hope you have seen all the great content created by our Qlikies, analysts, partners and colleagues. Be sure to check our corp blog for the latest highlights and references. As we play catch-up and recoup from Qonnections withdrawal, one particular feature made a good impression on many that I spoke with at Qonnections.  So much so I decided to create a Qlik Sense in 60 on it to showcase it.


Within in the April 2018 release of Qlik Sense, you can now publish Qlik Sense apps to - AND - move apps from - Streams directly from within the Qlik Sense Hub. Making it much easier for content admins to share their Qlik Sense apps with the greater community. Check out this quick video to see how it is done:



Qlik Sense in 60 - Publish and Move from Hub



Michael Tarallo (@mtarallo) | Twitter


Can't see the video? YouTube blocked by your region or organization? Download the .mp4 to view on your computer or mobile device.



Hopefully you all attended Qonnections 2018 and saw Jimmie on the bike !!!



Bike.qlik.com is the latest mashup build entirely with Qlik's open source libraries, Qlik Core, Enigma.js, Picasso.js, Leonardo UI and the Demo Team's Qdt-components.



Here is briefly how we did it

  • Sensors are sending data wireless to the Raspberry Pi
  • Node.js reads and writes csv
  • Qlik Core in Raspberry Pi is reading csv with a reload script and saves the data
  • Enigma.js connects and gets the data from Qlik Core then, Picasso.js is displaying that data in a graphical format
  • Node.js is uploading the qvds on Bike.qlik.com
  • Bike.qlik.com is a Docker that runs 2 containers in an AWS EC2 instance. One for the Qlik Core / Engine and another for an apache server
  • The htdocs and the Apps for the Qlik Core, are mounted outside of the 2 containers so there is no need to reload containers or recreate the Docker images, once the html code is changed or the qvf
  • Once uploaded, a Node.js restful api endpoint is reloading the session app, reads the new data from the just uploaded qvds and saves the qvf with the new data
  • React.js with Qdt-components is connecting to Qlik Core on the server and is getting the data
  • Qdt-components is rendering 11 KPI components and one search component (Leonardo UI) on the Rider field
  • Picasso.js is used to read the data and display a scatter plot and a line chart with tooltip and multiple selections


Expect more examples in the coming future with these combinations of our Open Source Software!!!!!



Arturo Muñoz

Introducing qdt-theme

Posted by Arturo Muñoz Apr 24, 2018

On the demo team we have been very busy lately working in some cool stuff for the community, qdt-components is a notable example of our commitment and contributions to the Qlik Community.


With the announcement of the new theme capabilities that were added to Qlik Sense in the February release we wanted to extend our involvement with you by sharing a custom theme we developed internally.


The qdt-theme is a curvy, bolder theme that significantly modifies the default look of Qlik Sense Desktop. Our goal was to create an appealing theme that you all can use right away, but more importantly we wanted it to be a theme for you to modify and extend as well.

In qdt-theme we changed font types, font sizes and a variety of styles including the current selection bar to make it fit in the new color scheme. Also, we incorporated lots of color palettes (borrowed from other themes, thank you) so you have a wild variety of schemes to choose from.



You can check out the qdt-theme library at our Demo Team's GitHub: https://github.com/qlik-demo-team/qdt-theme.


Hopefully you find it useful.

Enjoy it!

Hey guys - it's What's New in Qlik Sense time and I have prepared a brief video to share some of the awesome highlights in our next release Qlik Sense April 2018.



Highlights include:


Assisted data visualization with Qlik Sense chart suggestions / recommendations

Qlik Sense recommendations make it easier to create a visualization by allowing you to simply drag and drop fields onto your sheets. Chart suggestions are created using the Cognitive Engine in Qlik, which leverages insights from the data loaded and combines them with best practices for data visualization.


NEW Grid Size control

Now with the creation of a new sheet, the application author can choose between 3 grid sizes - small, medium and large.


Maps visualizations improvements

Qlik Sense April 2018 features significant improvements to the built-in maps visualization:

  • Support for multiple layers.
  • Labels for point layers and area layers.
  • Quick look up of countries, divisions, cities, postal code areas.
  • Circle select with distance measure.
  • Drill down support.
  • Layer control, zoom limit and draw order.
  • English or local name in the background map.


Publishing an app from the hub

In Qlik Sense April 2018 you can publish an app that you have created to any stream for which you have publish access. If you have published an app to a stream, you can move your app between the streams for which you have permission to publish.


Qlik Geocoding
A new subscription service part of the Qlik GeoAnalytics product package, that allows you to coordinate geo lookups all the way down to the street level.


Also included:


Keyboard navigation support for Qlik Sense hub

To improve accessibility, Qlik Sense hub now supports keyboard navigation and shortcuts.


Linking Qlik Sense Mobile to third-party applications

Qlik Sense Mobile can now interact with third party mobile applications through a custom generated URL (deep link). The link can be embedded within the third party mobile application, with appropriate selections and filters. Clicking the link opens the app in Qlik Sense Mobile with the filters and selections that were applied during original presentation. As a result, user experience is improved and context is provided when interacting with the app.


Enable anonymous users to export data

From Qlik Sense April 2018 anonymous users can print and export data.


For a complete list of fixes and improvements check out the release notes in the Qlik Help site.


You can download it from our customer downloads site or play with it right now on http://qlikcloud.com/.


Note: Our amazing product content and media team has also produced a number of updated videos supporting this release, check them out here on the Qlik Help YouTube channel:


Qlik Sense April 2018 Playlist


Can't see the video? YouTube blocked by your region or organization? Download the attached .mp4 to play on your computer or mobile device.


Additional resources:




Michael Tarallo (@mtarallo) | Twitter


Hey guys - I know you will love this blog and video as much as I enjoyed making it; working with this really smart feature in the Qlik Sense April 2018 release. Here I will present a new feature made available in Qlik Sense April 2018, Chart Suggestions / Recommendations. If you have tried the Qlik Sense 2018 Technical Preview, then you have already got a glimpse of the power of the new Cognitive Engine. In my opinion the best part of this release are the new capabilities and future possibilities brought about by the new Cognitive Engine. Its main purpose is to streamline and enhance the analytics creation experience - taking you from data to insight in a matter of seconds / minutes. In short the Cognitive Engine leverages best practices, augmented intelligence and perhaps a little elf magic - along with your loaded data, to not only recommend data model associations BUT also suggests the best visualization for your data. All you need to do is drag and drop measures and dimensions either on to the design canvas or chart objects and the suggested visualization will display -  best depicting your data (no magic words required).  Allowing users to focus their efforts on gaining insight instead of building charts. Let me give you a quick demonstration.


You can try this right now in Qlik Sense Cloud!




Can't see the video? YouTube blocked by your region or office? Download the .mp4 to watch on your computer or mobile device.


Sample data attached.

Francis Kabinoff

Introducing qdt-lui

Posted by Francis Kabinoff Apr 13, 2018

If you follow our blog posts regularly, you'll know we've been working on a library called qdt-components which includes a bunch of custom components we're using in our Qlik-powered apps. We've been using Bootstrap 4 with reactstrap, which is a collection of React components that use Bootstrap 4. The thing is that made Bootstrap 4 a dependency, and many of its styles are global, and that was a problem. We also wanted to be able to use Qlik's own Leonardo UI as a general style guide, but we needed the functionality of things like Bootstraps dropdowns. So we've been working on a new library called qdt-lui, which is a collection of React components that use Leonardo UI,  Just today we finally finished replacing all of the reactstrap components in qdt-components with qdt-lui components! There's still a bit of styling to touch up on because of this transition, but for the most part it's looking and working great.


So the general idea is very similar to reactstrap, but instead of creating React components that use Bootstrap for styles, we use Leonardo UI. So far, we have 6 components, and they are - LuiButton, LuiDropdown, LuiIcon, LuiList, LuiListItem, and LuiSearch. If you're familiar with Leonardo UI, you may be aware that Leonardo UI doesn't have a dropdown component at all, it's actually a select component that just reskins an actual html select element. But for our use cases, select elements are generally not very useful, so we borrowed the styles from the Leonardo UI select component and built something very similar to a bootstrap dropdown.


The LuiSearch component uses the Leonardo UI search component styles, but makes it a controlled react component which accepts as props a value and a clear method, so you can control the value from the parent component, and we can call the passed down clear method to clear the value in the parent component when you click on the clear symbol that's in the component. Again, this pattern is very similar to reactstrap, and what we've been using as a reference when building these components.


So check it out here - https://github.com/qlik-demo-team/qdt-lui and hopefully you find it useful. You'll be seeing it used a lot from us now in most of our projects on the demo team, and we'll have a lot of examples soon. Documentation is non-existent at the moment, but checking the source of each component and taking a look at the prop-types it should be pretty clear for now, but documentation will be coming. It's still marked as alpha, but we'll be moving it to beta soon. Let us know what you guys think, if you find this useful, and any features that you would like to see. Oh, and any pull requests submitted would have us spinning in our chairs excited, so if you're so inclined to contribute, that would be very, very cool.

1 f6YOV8dKjI9lXCC7TUpjIQ.pngImagine having a suite of proven tools and technologies built for developers by developers that allows you to build highly-scalable, cloud ready solutions using the power of the Qlik Associative Engine. Well, imagine no longer last Friday, 4/6,  we released the Beta of Qlik Core. Qlik Core is a development platform built on top of the Qlik Associative Engine. With Qlik Core, you can take advantage of the powerful associative indexing engine from Qlik to build your custom data exploration and data visualization solutions.


Please note that Qlik Core is a product - but it is not something you simply download and install with an installer. It works with technologies such as Node.js, Docker and Kubernetes and development knowledge of working with APIs is a prerequisite.  To learn more about the Qlik Core Beta and to get started watch this brief video below and visit https://branch-blog.qlik.com/introducing-qlik-core-beta-30221d627132 - where our product manager John Trigg provides some more of the particulars. You can also visit the many getting started resources here https://qlikcore.com/.


This brief video below is a short promotional video designed to briefly introduce Qlik Core.


Introducing Qlik Core



Michael Tarallo (@mtarallo) | Twitter



Can't see the video? YouTube blocked by your region or organization? Download the .mp4 to view on your computer or mobile device.

Jennell McIntire

Replace() Function

Posted by Jennell McIntire Apr 6, 2018

The Replace() function can be used in the script or a chart to replace all occurrences of a sub-string with another sub-string within an input string.  Basically, you can replace a character or string of characters in a field or input string.  The syntax from Qlik Help looks like this:


Replace(text, from_str, to_str)

The first parameter, text, is a string.  This can be a field or some text.  The second parameter, from_str, is the string you would like to replace in the input string.  This can be a single character or a string of characters.  The third parameter, to_str, is the string that should replace the second parameter.  If the from_str is not found in the text then nothing is replaced.  The Replace() function works from left to right.


I have used the Replace() function when I have a field that has some characters that I do not need.  For example, I was loading names in a recent project and some of the names had a leading underscore character (_).  Since this was the case with only some of the names and not all, I used the Replace() function to replace the underscore with an empty string using syntax like this:


You can also nest the Replace() function.  I have used this if there is more than one character I would like to replace in a string.  The nesting works from the inside out so keep this in mind as it may affect your results.  In the table below are a few examples of how Replace() can be used.


  • Column 1 - shows the original text string for Product.  This is the first parameter for all the Replace() examples.
  • Column 2 – replaces the underscore with a space.
  • Column 3 – is an example of a nested Replace() function.  First it replaces the underscore with an empty string.  Then it looks at the result of that string and replaces the question mark with an empty string.  The last step is to look at the results of that string and replace underscore question mark (_?) with a space (which will not be found in the Column 3 example).
  • Column 4 – is another example of a nested Replace() function but notice how the order affects the results for the input string “Product_?E”.  Since the first Replace() function to be evaluated replaces the “_?” with a space, the next two Replace() functions do not find the second parameter to replace.  Therefore, the result is “Product E” with a space before “E.”  In Column 3, the result is “ProductE,” without a space, since the underscore and the question mark were replaced individually with an empty string before the Replace(‘_?’, ‘ ‘) part of the expression was executed.


While my example shows how the Replace() function can be used in a chart expression, I always use it in the script to handle any replacements as I load the data.  What is nice about the Replace() function is it does not modify the text if the sub-string cannot be found.  With that in mind, you should make sure you want to replace all occurrences of the sub-string because there is not an option to pick and choose which sub-string occurrences to replace - all of them will be replaced.




We have been adding more features to our qdt-components and some of these, are the latest Picasso.js charts.


Here are the charts that we have so far.

Also you can interact with them live on our react template, https://webapps.qlik.com/qdt-components/react/index.html


  1. You can Embed any object from Qlik Sense and the Capability API
  2. You can create any custom Session object by defining your own definition properties like dimension, measures, title, subtitle, color, order etc
  3. There is a custom Selection Toolbar that we use extensively in our mashups
  4. A Picasso Horizontal bar that detects the height of the div. Once The bars exceed that, it adds a scrollbar. It also features multiple selections and tooltip
  5. The same idea but with vertical bars
  6. A new Picasso Pie Chart with Legend, multiple selections and tooltip
  7. A new Scotterplot with multiple selections, tooltip and legend
  8. And now the latest addition, scotterplot with custom images
  9. A simple line chart

10. Combo chart



More are coming soon with this amazing library!!!!



My buddy from down under is back in this week's edition of the Qlik Design Blog. Lee Mathews, Qlik Principal Solution Architect based in Melbourne Victoria, Australia, shows and tells how Qlik Sense can be used for financial reporting.


Financial Reports with Qlik Sense


I often have customers asking how they can produce financial style reports in Qlik. These reports are actually quite difficult to produce in most BI systems, as they usually require calculations and formatting that needs to change row by row. Most BI systems produce tables of data that display a single calculation in each column, with a dimension being used to provide a breakdown for the rows. Qlik is actually no different in this regard, however there are several aspects of the Qlik platform that provide the flexibility to replicate structured financial reports. Let me briefly introduce these aspects below:

  • Qlik’s powerful Extract Transform and Load (ETL) capabilities make Qlik the ideal platform for combining and reporting on data from disparate systems. But these ETL capabilities also allow you to take a data set and restructure it to include the necessary sub-totals that must be displayed in a financial report for example. You can also then flag these sub-totals in the data model so that different formatting can be applied to them in the UI.

  • Qlik’s extensive APIs allow visualization extensions to be created easily, with formatting options specifically for structured financial reporting. Two such extensions are illustrated in the video below, along with the use of the standard Qlik Sense pivot table object.

  • Qlik’s flexible expression syntax allows for a variety of tricks, to ensure that the right expression is displayed on each row. This includes Pick/Match functions, If Then Else logic, and of course Qlik’s powerful set analysis capabilities.

3-27-2018 10-40-08 AM.png

The short video below shows several approaches to producing structured financial reports. It is by no means an exhaustive list of techniques, but is a good overview of some of the options available.




Lee Matthews
Principal Solution Architect


Qlik Sense for Financial Reporting


Can't see the video? Download the .mp4 to watch on your computer or mobile device.

Filter Blog

By date:
By tag: