reader/flutter: adds initial scaffold

Change-Id: I02b338f9e69b697d8a086b5b07de8f2c10e0060f
diff --git a/flutter/.gitignore b/flutter/.gitignore
new file mode 100644
index 0000000..d815521
--- /dev/null
+++ b/flutter/.gitignore
@@ -0,0 +1,10 @@
+.DS_Store
+.atom/
+.idea
+.packages
+.pub/
+build/
+doc/
+ios/.generated/
+packages
+pubspec.lock
diff --git a/flutter/Makefile b/flutter/Makefile
new file mode 100644
index 0000000..dd3dee9
--- /dev/null
+++ b/flutter/Makefile
@@ -0,0 +1,29 @@
+MAKEFLAGS += --warn-undefined-variables
+SHELL := /bin/bash
+
+.SHELLFLAGS := -eu -o pipefail -c
+.DEFAULT_GOAL := all
+.SUFFIXES:
+
+.PHONY: all
+all: .packages doc
+	@true # silences watch
+
+.packages: pubspec.yaml
+	pub get
+
+.PHONY: upgrade
+upgrade:
+	pub upgrade
+
+.PHONY: analyze
+analyze:
+	dartanalyzer lib/main.dart
+
+.PHONY: fmt
+fmt: packages
+	dartfmt --overwrite lib
+
+doc:
+	dartdoc
+	@touch $@
diff --git a/flutter/README.md b/flutter/README.md
new file mode 100644
index 0000000..8effe7a
--- /dev/null
+++ b/flutter/README.md
@@ -0,0 +1,8 @@
+# reader
+
+Create a new Flutter project.
+
+## Getting Started
+
+For help getting started with Flutter, view our online
+[documentation](http://flutter.io/).
diff --git a/flutter/android/AndroidManifest.xml b/flutter/android/AndroidManifest.xml
new file mode 100644
index 0000000..4df3a1d
--- /dev/null
+++ b/flutter/android/AndroidManifest.xml
@@ -0,0 +1,22 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="io.v.flutter.apps.reader"
+    android:versionCode="1"
+    android:versionName="0.0.1">
+
+    <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="21" />
+    <uses-permission android:name="android.permission.INTERNET"/>
+
+    <application android:name="org.domokit.sky.shell.SkyApplication" android:label="reader" android:icon="@mipmap/ic_launcher">
+        <activity android:name="org.domokit.sky.shell.SkyActivity"
+                  android:launchMode="singleTask"
+                  android:theme="@android:style/Theme.Black.NoTitleBar"
+                  android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection"
+                  android:hardwareAccelerated="true"
+                  android:windowSoftInputMode="adjustResize">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/flutter/android/res/mipmap-hdpi/ic_launcher.png b/flutter/android/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..f0a55cd
--- /dev/null
+++ b/flutter/android/res/mipmap-hdpi/ic_launcher.png
Binary files differ
diff --git a/flutter/android/res/mipmap-mdpi/ic_launcher.png b/flutter/android/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..eb98dc4
--- /dev/null
+++ b/flutter/android/res/mipmap-mdpi/ic_launcher.png
Binary files differ
diff --git a/flutter/android/res/mipmap-xhdpi/ic_launcher.png b/flutter/android/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..f1783db
--- /dev/null
+++ b/flutter/android/res/mipmap-xhdpi/ic_launcher.png
Binary files differ
diff --git a/flutter/android/res/mipmap-xxhdpi/ic_launcher.png b/flutter/android/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..46828a2
--- /dev/null
+++ b/flutter/android/res/mipmap-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/flutter/android/res/mipmap-xxxhdpi/ic_launcher.png b/flutter/android/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..a527671
--- /dev/null
+++ b/flutter/android/res/mipmap-xxxhdpi/ic_launcher.png
Binary files differ
diff --git a/flutter/flutter.yaml b/flutter/flutter.yaml
new file mode 100644
index 0000000..17b15fb
--- /dev/null
+++ b/flutter/flutter.yaml
@@ -0,0 +1,6 @@
+name: reader
+material-design-icons:
+  - name: content/add
+  - name: navigation/arrow_back
+  - name: navigation/menu
+  - name: navigation/more_vert
diff --git a/flutter/ios/Assets.xcassets/AppIcon.appiconset/Contents.json b/flutter/ios/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..363d1c4
--- /dev/null
+++ b/flutter/ios/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,142 @@
+{
+  "images" : [
+    {
+      "size" : "29x29",
+      "idiom" : "iphone",
+      "filename" : "Icon-Small@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "29x29",
+      "idiom" : "iphone",
+      "filename" : "Icon-Small@3x.png",
+      "scale" : "3x"
+    },
+    {
+      "size" : "40x40",
+      "idiom" : "iphone",
+      "filename" : "Icon-Small-40@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "40x40",
+      "idiom" : "iphone",
+      "filename" : "Icon-Small-40@3x.png",
+      "scale" : "3x"
+    },
+    {
+      "size" : "60x60",
+      "idiom" : "iphone",
+      "filename" : "Icon-60@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "60x60",
+      "idiom" : "iphone",
+      "filename" : "Icon-60@3x.png",
+      "scale" : "3x"
+    },
+    {
+      "size" : "29x29",
+      "idiom" : "ipad",
+      "filename" : "Icon-Small.png",
+      "scale" : "1x"
+    },
+    {
+      "size" : "29x29",
+      "idiom" : "ipad",
+      "filename" : "Icon-Small@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "40x40",
+      "idiom" : "ipad",
+      "filename" : "Icon-Small-40.png",
+      "scale" : "1x"
+    },
+    {
+      "size" : "40x40",
+      "idiom" : "ipad",
+      "filename" : "Icon-Small-40@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "76x76",
+      "idiom" : "ipad",
+      "filename" : "Icon-76.png",
+      "scale" : "1x"
+    },
+    {
+      "size" : "76x76",
+      "idiom" : "ipad",
+      "filename" : "Icon-76@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "83.5x83.5",
+      "idiom" : "ipad",
+      "filename" : "Icon-83.5@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "16x16",
+      "idiom" : "mac",
+      "filename" : "icon_16x16.png",
+      "scale" : "1x"
+    },
+    {
+      "size" : "16x16",
+      "idiom" : "mac",
+      "filename" : "icon_16x16@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "32x32",
+      "idiom" : "mac",
+      "filename" : "icon_32x32.png",
+      "scale" : "1x"
+    },
+    {
+      "size" : "32x32",
+      "idiom" : "mac",
+      "filename" : "icon_32x32@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "128x128",
+      "idiom" : "mac",
+      "filename" : "icon_128x128.png",
+      "scale" : "1x"
+    },
+    {
+      "size" : "128x128",
+      "idiom" : "mac",
+      "filename" : "icon_128x128@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "256x256",
+      "idiom" : "mac",
+      "filename" : "icon_256x256.png",
+      "scale" : "1x"
+    },
+    {
+      "size" : "256x256",
+      "idiom" : "mac",
+      "filename" : "icon_256x256@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "512x512",
+      "idiom" : "mac",
+      "filename" : "icon_512x512.png",
+      "scale" : "1x"
+    },
+    {
+      "size" : "512x512",
+      "idiom" : "mac",
+      "filename" : "icon_512x512@2x.png",
+      "scale" : "2x"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/flutter/ios/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png b/flutter/ios/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png
new file mode 100644
index 0000000..9996f5e
--- /dev/null
+++ b/flutter/ios/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png
Binary files differ
diff --git a/flutter/ios/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png b/flutter/ios/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png
new file mode 100644
index 0000000..7a543ed
--- /dev/null
+++ b/flutter/ios/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png
Binary files differ
diff --git a/flutter/ios/Assets.xcassets/AppIcon.appiconset/Icon-76.png b/flutter/ios/Assets.xcassets/AppIcon.appiconset/Icon-76.png
new file mode 100644
index 0000000..05a8268
--- /dev/null
+++ b/flutter/ios/Assets.xcassets/AppIcon.appiconset/Icon-76.png
Binary files differ
diff --git a/flutter/ios/Assets.xcassets/AppIcon.appiconset/Icon-76@2x.png b/flutter/ios/Assets.xcassets/AppIcon.appiconset/Icon-76@2x.png
new file mode 100644
index 0000000..bfbca28
--- /dev/null
+++ b/flutter/ios/Assets.xcassets/AppIcon.appiconset/Icon-76@2x.png
Binary files differ
diff --git a/flutter/ios/Assets.xcassets/AppIcon.appiconset/Icon-83.5@2x.png b/flutter/ios/Assets.xcassets/AppIcon.appiconset/Icon-83.5@2x.png
new file mode 100644
index 0000000..c924b8e
--- /dev/null
+++ b/flutter/ios/Assets.xcassets/AppIcon.appiconset/Icon-83.5@2x.png
Binary files differ
diff --git a/flutter/ios/Assets.xcassets/AppIcon.appiconset/Icon-Small-40.png b/flutter/ios/Assets.xcassets/AppIcon.appiconset/Icon-Small-40.png
new file mode 100644
index 0000000..3006f1d
--- /dev/null
+++ b/flutter/ios/Assets.xcassets/AppIcon.appiconset/Icon-Small-40.png
Binary files differ
diff --git a/flutter/ios/Assets.xcassets/AppIcon.appiconset/Icon-Small-40@2x.png b/flutter/ios/Assets.xcassets/AppIcon.appiconset/Icon-Small-40@2x.png
new file mode 100644
index 0000000..5f7d22d
--- /dev/null
+++ b/flutter/ios/Assets.xcassets/AppIcon.appiconset/Icon-Small-40@2x.png
Binary files differ
diff --git a/flutter/ios/Assets.xcassets/AppIcon.appiconset/Icon-Small-40@3x.png b/flutter/ios/Assets.xcassets/AppIcon.appiconset/Icon-Small-40@3x.png
new file mode 100644
index 0000000..9996f5e
--- /dev/null
+++ b/flutter/ios/Assets.xcassets/AppIcon.appiconset/Icon-Small-40@3x.png
Binary files differ
diff --git a/flutter/ios/Assets.xcassets/AppIcon.appiconset/Icon-Small.png b/flutter/ios/Assets.xcassets/AppIcon.appiconset/Icon-Small.png
new file mode 100644
index 0000000..3433da1
--- /dev/null
+++ b/flutter/ios/Assets.xcassets/AppIcon.appiconset/Icon-Small.png
Binary files differ
diff --git a/flutter/ios/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png b/flutter/ios/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png
new file mode 100644
index 0000000..f7f9f16
--- /dev/null
+++ b/flutter/ios/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png
Binary files differ
diff --git a/flutter/ios/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png b/flutter/ios/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png
new file mode 100644
index 0000000..e9c2360
--- /dev/null
+++ b/flutter/ios/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png
Binary files differ
diff --git a/flutter/ios/Assets.xcassets/AppIcon.appiconset/icon_128x128.png b/flutter/ios/Assets.xcassets/AppIcon.appiconset/icon_128x128.png
new file mode 100644
index 0000000..dd5fccb
--- /dev/null
+++ b/flutter/ios/Assets.xcassets/AppIcon.appiconset/icon_128x128.png
Binary files differ
diff --git a/flutter/ios/Assets.xcassets/AppIcon.appiconset/icon_128x128@2x.png b/flutter/ios/Assets.xcassets/AppIcon.appiconset/icon_128x128@2x.png
new file mode 100644
index 0000000..1909e27
--- /dev/null
+++ b/flutter/ios/Assets.xcassets/AppIcon.appiconset/icon_128x128@2x.png
Binary files differ
diff --git a/flutter/ios/Assets.xcassets/AppIcon.appiconset/icon_16x16.png b/flutter/ios/Assets.xcassets/AppIcon.appiconset/icon_16x16.png
new file mode 100644
index 0000000..40a701b
--- /dev/null
+++ b/flutter/ios/Assets.xcassets/AppIcon.appiconset/icon_16x16.png
Binary files differ
diff --git a/flutter/ios/Assets.xcassets/AppIcon.appiconset/icon_16x16@2x.png b/flutter/ios/Assets.xcassets/AppIcon.appiconset/icon_16x16@2x.png
new file mode 100644
index 0000000..06c1a80
--- /dev/null
+++ b/flutter/ios/Assets.xcassets/AppIcon.appiconset/icon_16x16@2x.png
Binary files differ
diff --git a/flutter/ios/Assets.xcassets/AppIcon.appiconset/icon_256x256.png b/flutter/ios/Assets.xcassets/AppIcon.appiconset/icon_256x256.png
new file mode 100644
index 0000000..1909e27
--- /dev/null
+++ b/flutter/ios/Assets.xcassets/AppIcon.appiconset/icon_256x256.png
Binary files differ
diff --git a/flutter/ios/Assets.xcassets/AppIcon.appiconset/icon_256x256@2x.png b/flutter/ios/Assets.xcassets/AppIcon.appiconset/icon_256x256@2x.png
new file mode 100644
index 0000000..69c96ef
--- /dev/null
+++ b/flutter/ios/Assets.xcassets/AppIcon.appiconset/icon_256x256@2x.png
Binary files differ
diff --git a/flutter/ios/Assets.xcassets/AppIcon.appiconset/icon_32x32.png b/flutter/ios/Assets.xcassets/AppIcon.appiconset/icon_32x32.png
new file mode 100644
index 0000000..06c1a80
--- /dev/null
+++ b/flutter/ios/Assets.xcassets/AppIcon.appiconset/icon_32x32.png
Binary files differ
diff --git a/flutter/ios/Assets.xcassets/AppIcon.appiconset/icon_32x32@2x.png b/flutter/ios/Assets.xcassets/AppIcon.appiconset/icon_32x32@2x.png
new file mode 100644
index 0000000..0f94371
--- /dev/null
+++ b/flutter/ios/Assets.xcassets/AppIcon.appiconset/icon_32x32@2x.png
Binary files differ
diff --git a/flutter/ios/Assets.xcassets/AppIcon.appiconset/icon_512x512.png b/flutter/ios/Assets.xcassets/AppIcon.appiconset/icon_512x512.png
new file mode 100644
index 0000000..69c96ef
--- /dev/null
+++ b/flutter/ios/Assets.xcassets/AppIcon.appiconset/icon_512x512.png
Binary files differ
diff --git a/flutter/ios/Assets.xcassets/AppIcon.appiconset/icon_512x512@2x.png b/flutter/ios/Assets.xcassets/AppIcon.appiconset/icon_512x512@2x.png
new file mode 100644
index 0000000..1d6355f
--- /dev/null
+++ b/flutter/ios/Assets.xcassets/AppIcon.appiconset/icon_512x512@2x.png
Binary files differ
diff --git a/flutter/ios/Info.plist b/flutter/ios/Info.plist
new file mode 100644
index 0000000..f7f5d07
--- /dev/null
+++ b/flutter/ios/Info.plist
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>en</string>
+	<key>CFBundleExecutable</key>
+	<string>Runner</string>
+	<key>CFBundleIdentifier</key>
+	<string>io.v.flutter.apps.reader</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>reader</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>1</string>
+	<key>LSRequiresIPhoneOS</key>
+	<true/>
+	<key>UILaunchStoryboardName</key>
+	<string>LaunchScreen</string>
+	<key>UIRequiredDeviceCapabilities</key>
+	<array>
+		<string>arm64</string>
+	</array>
+	<key>UISupportedInterfaceOrientations</key>
+	<array>
+		<string>UIInterfaceOrientationPortrait</string>
+		<string>UIInterfaceOrientationLandscapeLeft</string>
+		<string>UIInterfaceOrientationLandscapeRight</string>
+	</array>
+	<key>UISupportedInterfaceOrientations~ipad</key>
+	<array>
+		<string>UIInterfaceOrientationPortrait</string>
+		<string>UIInterfaceOrientationPortraitUpsideDown</string>
+		<string>UIInterfaceOrientationLandscapeLeft</string>
+		<string>UIInterfaceOrientationLandscapeRight</string>
+	</array>
+	<key>UIViewControllerBasedStatusBarAppearance</key>
+	<false/>
+</dict>
+</plist>
diff --git a/flutter/ios/LaunchScreen.storyboard b/flutter/ios/LaunchScreen.storyboard
new file mode 100644
index 0000000..78686cd
--- /dev/null
+++ b/flutter/ios/LaunchScreen.storyboard
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="9531" systemVersion="15C50" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" initialViewController="01J-lp-oVM">
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9529"/>
+    </dependencies>
+    <scenes>
+        <!--View Controller-->
+        <scene sceneID="EHf-IW-A2E">
+            <objects>
+                <viewController id="01J-lp-oVM" sceneMemberID="viewController">
+                    <layoutGuides>
+                        <viewControllerLayoutGuide type="top" id="Llm-lL-Icb"/>
+                        <viewControllerLayoutGuide type="bottom" id="xb3-aO-Qok"/>
+                    </layoutGuides>
+                    <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
+                        <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
+                    </view>
+                </viewController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
+            </objects>
+            <point key="canvasLocation" x="53" y="375"/>
+        </scene>
+    </scenes>
+</document>
diff --git a/flutter/lib/main.dart b/flutter/lib/main.dart
new file mode 100644
index 0000000..6625aa4
--- /dev/null
+++ b/flutter/lib/main.dart
@@ -0,0 +1,39 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+import 'package:flutter/material.dart';
+
+void main() {
+  runApp(new MaterialApp(
+      title: 'Flutter Demo',
+      routes: <String, RouteBuilder>{
+        '/': (RouteArguments args) => new FlutterDemo()
+      }));
+}
+
+class FlutterDemo extends StatefulComponent {
+  _FlutterDemoState createState() => new _FlutterDemoState();
+}
+
+class _FlutterDemoState extends State<FlutterDemo> {
+  int _counter = 0;
+
+  void _incrementCounter() {
+    setState(() {
+      _counter++;
+    });
+  }
+
+  Widget build(BuildContext context) {
+    return new Scaffold(
+        toolBar: new ToolBar(center: new Text('Flutter Demo')),
+        body: new Center(
+            child: new Text(
+                'Button tapped $_counter time${ _counter == 1 ? '' : 's' }.')),
+        floatingActionButton: new FloatingActionButton(
+            onPressed: _incrementCounter,
+            tooltip: 'Increment',
+            child: new Icon(icon: 'content/add')));
+  }
+}
diff --git a/flutter/pubspec.yaml b/flutter/pubspec.yaml
new file mode 100644
index 0000000..df057b1
--- /dev/null
+++ b/flutter/pubspec.yaml
@@ -0,0 +1,5 @@
+name: reader
+description: Create a new Flutter project.
+dependencies:
+  flutter:
+    path: ../../../../../flutter/packages/flutter
diff --git a/web/Makefile b/web/Makefile
index b9da02e..4ea729b 100644
--- a/web/Makefile
+++ b/web/Makefile
@@ -21,7 +21,7 @@
 
 .PHONY:
 all: public/bundle.js public/pdf-web-view.js
-	@true  # silences watch
+	@true # silences watch
 
 .PHONY:
 bin: bin/principal bin/syncbased