diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..1af2cc7
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2018 Aaron Tan
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..a024837
--- /dev/null
+++ b/README.md
@@ -0,0 +1,2 @@
+# Fitbit Pomodoro
+A Pomodoro app for the Fitbit Ionic.
diff --git a/app/index.js b/app/index.js
new file mode 100644
index 0000000..655e69f
--- /dev/null
+++ b/app/index.js
@@ -0,0 +1,101 @@
+'use strict';
+
+function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
+
+var document = _interopDefault(require('document'));
+var haptics = require('haptics');
+
+var backgroundRect = document.getElementById("backgroundRect");
+var backgroundRectResting = document.getElementById("backgroundRectResting");
+var backgroundRectLongResting = document.getElementById("backgroundRectLongResting");
+
+var btnBR = document.getElementById("btn-br");
+var stateText = document.getElementById("stateText");
+var minuteText = document.getElementById("minuteText");
+var unitText = document.getElementById("unitText");
+var times = 0;
+
+btnBR.onactivate = function (evt) {
+ btnBR.style.display = "none";
+ haptics.vibration.start("confirmation");
+ minuteText.text = "24:59";
+ unitText.style.display = "none";
+ backgroundRect.animate("disable");
+ setTimeout(function() {
+ startWorkTimer(times);
+ }, 300);
+};
+
+function startWorkTimer(times) {
+ stateText.text = "Get to work!";
+ backgroundRect.animate("enable");
+ var end = new Date(new Date().getTime() + 25 * 60000);
+ minuteText.text = "24:59";
+ var timer = setInterval(function () {
+ var now = new Date().getTime();
+ var distance = end - now;
+ var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
+ var seconds = Math.floor((distance % (1000 * 60)) / 1000);
+ minutes = (minutes < 10) ? ("0" + minutes) : minutes;
+ seconds = (seconds < 10) ? ("0" + seconds) : seconds;
+ minuteText.text = minutes + ":" + seconds;
+ if (distance < 1) {
+ clearInterval(timer);
+ haptics.vibration.start("ping");
+ backgroundRect.animate("disable");
+ times++;
+ if (times < 2) {
+ backgroundRectResting.animate("enable");
+ startShortBreakTimer(times);
+ } else {
+ times = 0;
+ backgroundRectLongResting.animate("enable");
+ startLongBreakTimer(times);
+ }
+ }
+ }, 1000);
+};
+
+function startShortBreakTimer(times) {
+ stateText.text = "Take a short break";
+ var end = new Date(new Date().getTime() + 5 * 60000);
+ minuteText.text = "04:59";
+ var timer = setInterval(function () {
+ var now = new Date().getTime();
+ var distance = end - now;
+ var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
+ var seconds = Math.floor((distance % (1000 * 60)) / 1000);
+ minutes = (minutes < 10) ? ("0" + minutes) : minutes;
+ seconds = (seconds < 10) ? ("0" + seconds) : seconds;
+ minuteText.text = minutes + ":" + seconds;
+ if (distance < 1) {
+ clearInterval(timer);
+ haptics.vibration.start("ping");
+ backgroundRectResting.animate("disable");
+ backgroundRect.animate("enable");
+ startWorkTimer(times);
+ }
+ }, 1000);
+}
+
+function startLongBreakTimer(times) {
+ stateText.text = "Take a long break";
+ var end = new Date(new Date().getTime() + 15 * 60000);
+ minuteText.text = "14:59";
+ var timer = setInterval(function () {
+ var now = new Date().getTime();
+ var distance = end - now;
+ var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
+ var seconds = Math.floor((distance % (1000 * 60)) / 1000);
+ minutes = (minutes < 10) ? ("0" + minutes) : minutes;
+ seconds = (seconds < 10) ? ("0" + seconds) : seconds;
+ minuteText.text = minutes + ":" + seconds;
+ if (distance < 1) {
+ clearInterval(timer);
+ haptics.vibration.start("ping");
+ backgroundRectLongResting.animate("disable");
+ backgroundRect.animate("enable");
+ startWorkTimer(times);
+ }
+ }, 1000);
+}
\ No newline at end of file
diff --git a/manifest.json b/manifest.json
new file mode 100644
index 0000000..364ce85
--- /dev/null
+++ b/manifest.json
@@ -0,0 +1 @@
+{"appManifestVersion":1,"main":"app/index.js","svgMain":"resources/index.gui","svgWidgets":"resources/widgets.gui","appType":"app","i18n":{"en":{"name":"Tomatina"}},"buildId":"0x0730781e263c063b","uuid":"4c0f5346-6d11-4494-a04f-731b152e6c1e","name":"Tomatina","bundleDate":"2018-01-09T22:46:27.359Z","requestedPermissions":[],"wipeColor":"#f44336"}
\ No newline at end of file
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..cc7dda3
--- /dev/null
+++ b/package.json
@@ -0,0 +1,33 @@
+{
+ "fitbit": {
+ "appUUID": "55d5be9a-1571-4987-b5e7-cda00dc7d56b",
+ "appType": "app",
+ "appDisplayName": "Tomatina",
+ "iconFile": "resources/icon.png",
+ "wipeColor": "#f44336",
+ "requestedPermissions": [],
+ "i18n": {
+ "en": {
+ "name": "Tomatina"
+ },
+ "zh-cn": {
+ "name": "番茄工作计时器"
+ },
+ "zh-tw": {
+ "name": "番茄工作計時器"
+ },
+ "fr": {
+ "name": "Tomatina"
+ },
+ "es": {
+ "name": "Tomatina"
+ },
+ "ja": {
+ "name": "トマティーナ"
+ },
+ "ko": {
+ "name": "토마티나"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/resources/icon.png b/resources/icon.png
new file mode 100644
index 0000000..2f22147
Binary files /dev/null and b/resources/icon.png differ
diff --git a/resources/icon.svg b/resources/icon.svg
new file mode 100644
index 0000000..ae76bc7
--- /dev/null
+++ b/resources/icon.svg
@@ -0,0 +1,144 @@
+
+
+
+
diff --git a/resources/index.gui b/resources/index.gui
new file mode 100644
index 0000000..416e639
--- /dev/null
+++ b/resources/index.gui
@@ -0,0 +1,72 @@
+
\ No newline at end of file
diff --git a/resources/play.png.txi b/resources/play.png.txi
new file mode 100644
index 0000000..58dc78e
Binary files /dev/null and b/resources/play.png.txi differ
diff --git a/resources/play_press.png.txi b/resources/play_press.png.txi
new file mode 100644
index 0000000..6f747c8
Binary files /dev/null and b/resources/play_press.png.txi differ
diff --git a/resources/styles.css b/resources/styles.css
new file mode 100644
index 0000000..e318867
--- /dev/null
+++ b/resources/styles.css
@@ -0,0 +1,27 @@
+#backgroundRectResting {
+ display: inline;
+}
+
+#backgroundRect {
+ display: inline;
+}
+
+.minutesBigText {
+ fill: #FFFFFF;
+ font-family: Seville-Book;
+ font-size: 105;
+}
+
+.stateText {
+ display: inline;
+ fill: #D3D3D3;
+ font-family: Seville-Book;
+ font-size: 35;
+}
+
+.unitText {
+ display: inline;
+ fill: #C0C0C0;
+ font-family: Seville-Book;
+ font-size: 40;
+}
\ No newline at end of file
diff --git a/resources/widgets.gui b/resources/widgets.gui
new file mode 100644
index 0000000..ee90e99
--- /dev/null
+++ b/resources/widgets.gui
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file