aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.babelrc2
-rw-r--r--package-lock.json109
-rw-r--r--package.json7
-rw-r--r--src/Analyze.tsx (renamed from src/Analyze.js)36
-rw-r--r--src/Chart.tsx (renamed from src/Chart.js)0
-rw-r--r--src/Dashboard.tsx (renamed from src/Dashboard.js)0
-rw-r--r--src/Dialog.tsx (renamed from src/Dialog.js)0
-rw-r--r--src/Logo.tsx (renamed from src/Logo.js)0
-rw-r--r--src/PatternTable.tsx (renamed from src/PatternTable.js)0
-rw-r--r--src/RegexField.tsx (renamed from src/RegexField.js)0
-rw-r--r--src/Settings.tsx (renamed from src/Settings.js)16
-rw-r--r--src/Snackbar.tsx (renamed from src/Snackbar.js)0
-rw-r--r--src/background.ts (renamed from src/background.js)2
-rw-r--r--src/decl.ts1
-rw-r--r--src/duration.js21
-rw-r--r--src/duration.ts26
-rw-r--r--src/gapi.js335
-rw-r--r--src/gapi.ts369
-rw-r--r--src/index.js11
-rw-r--r--src/index.tsx5
-rw-r--r--src/msg.js97
-rw-r--r--src/msg.ts87
-rw-r--r--src/pattern.ts (renamed from src/pattern.js)46
-rw-r--r--src/popup.tsx (renamed from src/popup.js)10
-rw-r--r--src/serviceWorker.js135
-rw-r--r--src/theme.tsx (renamed from src/theme.js)0
-rw-r--r--tsconfig.json16
-rw-r--r--types/lru-cache/index.d.ts10
-rw-r--r--types/lru-cache/log1485
-rw-r--r--webpack.config.js19
30 files changed, 2199 insertions, 646 deletions
diff --git a/.babelrc b/.babelrc
index 58a023d..2775ac7 100644
--- a/.babelrc
+++ b/.babelrc
@@ -1,4 +1,4 @@
{
- "presets": ["@babel/preset-env", "@babel/preset-react"],
+ "presets": ["@babel/preset-env", "@babel/preset-react", "@babel/preset-typescript"],
"plugins": ["@babel/plugin-proposal-class-properties", "@babel/plugin-transform-runtime"]
}
diff --git a/package-lock.json b/package-lock.json
index d5894e7..331f290 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -424,6 +424,15 @@
"@babel/helper-plugin-utils": "^7.0.0"
}
},
+ "@babel/plugin-syntax-typescript": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.2.0.tgz",
+ "integrity": "sha512-WhKr6yu6yGpGcNMVgIBuI9MkredpVc7Y3YR4UzEZmDztHoL6wV56YBHLhWnjO1EvId1B32HrD3DRFc+zSoKI1g==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.0.0"
+ }
+ },
"@babel/plugin-transform-arrow-functions": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz",
@@ -743,6 +752,16 @@
"@babel/helper-plugin-utils": "^7.0.0"
}
},
+ "@babel/plugin-transform-typescript": {
+ "version": "7.3.2",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.3.2.tgz",
+ "integrity": "sha512-Pvco0x0ZSCnexJnshMfaibQ5hnK8aUHSvjCQhC1JR8eeg+iBwt0AtCO7gWxJ358zZevuf9wPSO5rv+WJcbHPXQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "@babel/plugin-syntax-typescript": "^7.2.0"
+ }
+ },
"@babel/plugin-transform-unicode-regex": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.2.0.tgz",
@@ -836,6 +855,16 @@
"@babel/plugin-transform-react-jsx-source": "^7.0.0"
}
},
+ "@babel/preset-typescript": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.1.0.tgz",
+ "integrity": "sha512-LYveByuF9AOM8WrsNne5+N79k1YxjNB6gmpCQsnuSBAcV8QUeB+ZUxQzL7Rz7HksPbahymKkq2qBR+o36ggFZA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "@babel/plugin-transform-typescript": "^7.1.0"
+ }
+ },
"@babel/runtime": {
"version": "7.3.1",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.3.1.tgz",
@@ -964,6 +993,27 @@
"react-is": "^16.6.3"
}
},
+ "@types/chrome": {
+ "version": "0.0.79",
+ "resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.0.79.tgz",
+ "integrity": "sha512-4+Xducpig6lpwVX65Hk8KSZwRoURHXMDbd38SDNcV8TBaw4xyJki39fjB1io2h7ip+BsyFvgTm9OxR5qneLPiA==",
+ "requires": {
+ "@types/filesystem": "*"
+ }
+ },
+ "@types/filesystem": {
+ "version": "0.0.29",
+ "resolved": "https://registry.npmjs.org/@types/filesystem/-/filesystem-0.0.29.tgz",
+ "integrity": "sha512-85/1KfRedmfPGsbK8YzeaQUyV1FQAvMPMTuWFQ5EkLd2w7szhNO96bk3Rh/SKmOfd9co2rCLf0Voy4o7ECBOvw==",
+ "requires": {
+ "@types/filewriter": "*"
+ }
+ },
+ "@types/filewriter": {
+ "version": "0.0.28",
+ "resolved": "https://registry.npmjs.org/@types/filewriter/-/filewriter-0.0.28.tgz",
+ "integrity": "sha1-wFTor02d11205jq8dviFFocU1LM="
+ },
"@types/jss": {
"version": "9.5.7",
"resolved": "https://registry.npmjs.org/@types/jss/-/jss-9.5.7.tgz",
@@ -1416,6 +1466,15 @@
"integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==",
"dev": true
},
+ "async": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz",
+ "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.17.10"
+ }
+ },
"async-each": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz",
@@ -1765,6 +1824,23 @@
"ssri": "^6.0.1",
"unique-filename": "^1.1.1",
"y18n": "^4.0.0"
+ },
+ "dependencies": {
+ "lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "dev": true,
+ "requires": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "yallist": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz",
+ "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==",
+ "dev": true
+ }
}
},
"cache-base": {
@@ -4907,7 +4983,6 @@
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
"integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
- "dev": true,
"requires": {
"yallist": "^3.0.2"
}
@@ -6822,6 +6897,16 @@
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
"dev": true
},
+ "source-map-loader": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-0.2.4.tgz",
+ "integrity": "sha512-OU6UJUty+i2JDpTItnizPrlpOIBLmQbWMuBg9q5bVtnHACqw1tn9nNwqJLbv0/00JjnJb/Ee5g5WS5vrRv7zIQ==",
+ "dev": true,
+ "requires": {
+ "async": "^2.5.0",
+ "loader-utils": "^1.1.0"
+ }
+ },
"source-map-resolve": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz",
@@ -7168,6 +7253,19 @@
"integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=",
"dev": true
},
+ "ts-loader": {
+ "version": "5.3.3",
+ "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-5.3.3.tgz",
+ "integrity": "sha512-KwF1SplmOJepnoZ4eRIloH/zXL195F51skt7reEsS6jvDqzgc/YSbz9b8E07GxIUwLXdcD4ssrJu6v8CwaTafA==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.3.0",
+ "enhanced-resolve": "^4.0.0",
+ "loader-utils": "^1.0.2",
+ "micromatch": "^3.1.4",
+ "semver": "^5.0.1"
+ }
+ },
"tslib": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz",
@@ -7200,6 +7298,12 @@
"resolved": "https://registry.npmjs.org/typeface-roboto/-/typeface-roboto-0.0.54.tgz",
"integrity": "sha512-sOFA1FXgP0gOgBYlS6irwq6hHYA370KE3dPlgYEJHL3PJd5X8gQE0RmL79ONif6fL5JZuGDj+rtOrFeOqz5IZQ=="
},
+ "typescript": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.3.tgz",
+ "integrity": "sha512-Y21Xqe54TBVp+VDSNbuDYdGw0BpoR/Q6wo/+35M8PAU0vipahnyduJWirxxdxjsAkS7hue53x2zp8gz7F05u0A==",
+ "dev": true
+ },
"ua-parser-js": {
"version": "0.7.19",
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.19.tgz",
@@ -7657,8 +7761,7 @@
"yallist": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz",
- "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==",
- "dev": true
+ "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A=="
},
"yargs": {
"version": "12.0.5",
diff --git a/package.json b/package.json
index 6914549..75f0a66 100644
--- a/package.json
+++ b/package.json
@@ -20,6 +20,7 @@
"@babel/polyfill": "^7.2.5",
"@babel/preset-env": "^7.3.1",
"@babel/preset-react": "^7.0.0",
+ "@babel/preset-typescript": "^7.1.0",
"babel-eslint": "^10.0.1",
"babel-loader": "^8.0.5",
"copy-webpack-plugin": "^4.6.0",
@@ -28,7 +29,10 @@
"eslint-loader": "^2.1.2",
"eslint-plugin-react": "^7.12.4",
"html-webpack-plugin": "^4.0.0-beta.5",
+ "source-map-loader": "^0.2.4",
"style-loader": "^0.23.1",
+ "ts-loader": "^5.3.3",
+ "typescript": "^3.3.3",
"url-loader": "^1.1.2",
"webpack": "^4.29.2",
"webpack-cli": "^3.2.3"
@@ -36,6 +40,9 @@
"dependencies": {
"@material-ui/core": "^3.9.2",
"@material-ui/icons": "^3.0.2",
+ "@types/chrome": "0.0.79",
+ "@types/react": "^16.8.2",
+ "lru-cache": "^5.1.1",
"moment": "^2.24.0",
"react": "^16.8.1",
"react-dates": "^19.0.0",
diff --git a/src/Analyze.js b/src/Analyze.tsx
index 98e3ce2..5450998 100644
--- a/src/Analyze.js
+++ b/src/Analyze.tsx
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import 'react-dates/initialize';
import 'react-dates/lib/css/_datepicker.css';
import { DateRangePicker } from 'react-dates';
-import { withStyles } from '@material-ui/core/styles';
+import { Theme, withStyles } from '@material-ui/core/styles';
import cyan from '@material-ui/core/colors/cyan';
import deepOrange from '@material-ui/core/colors/deepOrange';
import CssBaseline from '@material-ui/core/CssBaseline';
@@ -15,51 +15,55 @@ import Grid from '@material-ui/core/Grid';
import AddCircleIcon from '@material-ui/icons/AddCircle';
import IconButton from '@material-ui/core/IconButton';
import * as gapi from './gapi';
-import { msgType, MsgClient } from './msg';
+import { MsgType, MsgClient } from './msg';
import { Pattern, PatternEntry } from './pattern';
import { AnalyzePieChart, getChartData } from './Chart';
import PatternTable from './PatternTable';
import Snackbar from './Snackbar';
import AlertDialog from './Dialog';
+import moment from 'moment';
const default_chart_data = [
{name: 'Work', value: 10, color: cyan[300]},
{name: 'Wasted', value: 10, color: deepOrange[300]}];
-const styles = theme => ({
+const styles = (theme: Theme) => ({
buttonSpacer: {
marginBottom: theme.spacing.unit * 4,
},
});
class Analyze extends React.Component {
+ msgClient: MsgClient;
+
state = {
- patterns: [],
+ patterns: [] as PatternEntry[],
calendars: {},
- startDate: null,
- endDate: null,
+ startDate: null as moment.Moment,
+ endDate: null as moment.Moment,
patternGraphData: default_chart_data,
calendarGraphData: default_chart_data,
snackBarOpen: false,
snackBarMsg: 'unknown',
snackBarVariant: 'error',
dialogOpen: false,
- dialogMsg: {title: '', message: ''},
+ dialogMsg: {title: '', message: ''}
};
- constructor(props) {
+ constructor(props: any) {
super(props);
+
this.msgClient = new MsgClient('main');
this.msgClient.sendMsg({
- type: msgType.getPatterns,
+ type: MsgType.getPatterns,
data: { id: 'analyze' }
}).then(msg => {
this.setState({ patterns: msg.data.map(p => PatternEntry.inflate(p)) });
});
this.msgClient.sendMsg({
- type: msgType.getCalendars,
+ type: MsgType.getCalendars,
data: { enabledOnly: true }
}).then(msg => {
this.setState({ calendars: msg.data });
@@ -71,20 +75,20 @@ class Analyze extends React.Component {
this.dialogPromiseResolver = null;
}
- loadPatterns = patterns => {
+ loadPatterns = (patterns: PatternEntry[]) => {
this.msgClient.sendMsg({
- type: msgType.updatePatterns,
+ type: MsgType.updatePatterns,
data: { id: 'analyze', patterns: patterns.map(p => p.deflate()) }
}).then(() => this.setState({ patterns }));
};
- updatePattern = (field, idx, value) => {
+ updatePattern = (field: string, idx: number, value: PatternEntry[]) => {
let patterns = this.state.patterns;
patterns[idx][field] = value;
this.loadPatterns(patterns);
};
- removePattern = idx => {
+ removePattern = (idx: number) => {
let patterns = this.state.patterns;
patterns.splice(idx, 1);
for (let i = 0; i < patterns.length; i++)
@@ -99,8 +103,8 @@ class Analyze extends React.Component {
this.loadPatterns(patterns);
};
- getCalEvents = (id, start, end) => {
- return this.msgClient.sendMsg({ type: msgType.getCalEvents, data: { id,
+ getCalEvents = (id: string, start: Date, end: Date) => {
+ return this.msgClient.sendMsg({ type: MsgType.getCalEvents, data: { id,
start: start.getTime(),
end: end.getTime() } })
.then(({ data }) => data.map(e => {
diff --git a/src/Chart.js b/src/Chart.tsx
index b1c36ed..b1c36ed 100644
--- a/src/Chart.js
+++ b/src/Chart.tsx
diff --git a/src/Dashboard.js b/src/Dashboard.tsx
index 04ced46..04ced46 100644
--- a/src/Dashboard.js
+++ b/src/Dashboard.tsx
diff --git a/src/Dialog.js b/src/Dialog.tsx
index 7e24176..7e24176 100644
--- a/src/Dialog.js
+++ b/src/Dialog.tsx
diff --git a/src/Logo.js b/src/Logo.tsx
index a4036a9..a4036a9 100644
--- a/src/Logo.js
+++ b/src/Logo.tsx
diff --git a/src/PatternTable.js b/src/PatternTable.tsx
index 93be293..93be293 100644
--- a/src/PatternTable.js
+++ b/src/PatternTable.tsx
diff --git a/src/RegexField.js b/src/RegexField.tsx
index e3fa9f4..e3fa9f4 100644
--- a/src/RegexField.js
+++ b/src/RegexField.tsx
diff --git a/src/Settings.js b/src/Settings.tsx
index 2835483..83f1da6 100644
--- a/src/Settings.js
+++ b/src/Settings.tsx
@@ -20,7 +20,7 @@ import ListItem from '@material-ui/core/ListItem';
import ListItemText from '@material-ui/core/ListItemText';
import Checkbox from '@material-ui/core/Checkbox';
import * as gapi from './gapi';
-import { msgType, MsgClient } from './msg';
+import { MsgType, MsgClient } from './msg';
import { Pattern, PatternEntry } from './pattern';
import PatternTable from './PatternTable';
import Snackbar from './Snackbar';
@@ -137,21 +137,21 @@ class Settings extends React.Component {
this.msgClient = new MsgClient('main');
this.msgClient.sendMsg({
- type: msgType.getPatterns,
+ type: MsgType.getPatterns,
data: { id: 'main' }
}).then(msg => {
this.setState({ patterns: msg.data.map(p => PatternEntry.inflate(p)) });
});
this.msgClient.sendMsg({
- type: msgType.getCalendars,
+ type: MsgType.getCalendars,
data: { enabledOnly: false }
}).then(msg => {
this.setState({ calendars: msg.data });
});
this.msgClient.sendMsg({
- type: msgType.getConfig,
+ type: MsgType.getConfig,
data: ['trackedPeriods']
}).then(msg => {
let config = {
@@ -191,7 +191,7 @@ class Settings extends React.Component {
var calendars = {...this.state.calendars};
calendars[id].enabled = !calendars[id].enabled;
this.msgClient.sendMsg({
- type: msgType.updateCalendars,
+ type: MsgType.updateCalendars,
data: calendars
}).then(() => this.setState({ calendars }));
}
@@ -240,14 +240,14 @@ class Settings extends React.Component {
calendars[id].enabled = this.state.calendars[id].enabled;
}
this.msgClient.sendMsg({
- type: msgType.updateCalendars,
+ type: MsgType.updateCalendars,
data: calendars
}).then(() => this.setState({ calendars }));
};
loadPatterns = (patterns, id) => {
this.msgClient.sendMsg({
- type: msgType.updatePatterns,
+ type: MsgType.updatePatterns,
data: { id, patterns: patterns.map(p => p.deflate()) }
}).then(() => this.setState({ patterns }));
};
@@ -297,7 +297,7 @@ class Settings extends React.Component {
updateTrackedPeriods = trackedPeriods => {
this.msgClient.sendMsg({
- type: msgType.updateConfig,
+ type: MsgType.updateConfig,
data: { trackedPeriods: trackedPeriods.map(p => ({
name: p.name,
start: p.start.deflate(),
diff --git a/src/Snackbar.js b/src/Snackbar.tsx
index f17863c..f17863c 100644
--- a/src/Snackbar.js
+++ b/src/Snackbar.tsx
diff --git a/src/background.js b/src/background.ts
index f22970e..2a23b57 100644
--- a/src/background.js
+++ b/src/background.ts
@@ -5,7 +5,7 @@ import moment from 'moment';
import { getChartData } from './Chart';
import { PatternEntry } from './pattern';
-let mainPatterns = [];
+let mainPatterns: number[] = [];
let analyzePatterns = [];
let calendars = {};
let calData = {};
diff --git a/src/decl.ts b/src/decl.ts
new file mode 100644
index 0000000..5b3daa3
--- /dev/null
+++ b/src/decl.ts
@@ -0,0 +1 @@
+declare module 'react-dates';
diff --git a/src/duration.js b/src/duration.js
deleted file mode 100644
index 53de0ad..0000000
--- a/src/duration.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import moment from 'moment';
-
-export class Duration {
- constructor(value, unit) {
- this.value = value
- this.unit = unit
- }
-
- toMoment() {
- let m = moment.duration(this.value, this.unit);
- if (m.isValid()) return m;
- return null;
- }
-
- static days(n) { return new Duration(n, 'days'); }
- static weeks(n) { return new Duration(n, 'weeks'); }
- static months(n) { return new Duration(n, 'months'); }
-
- deflate() { return { value: this.value, unit: this.unit }; }
- static inflate = obj => new Duration(obj.value, obj.unit);
-}
diff --git a/src/duration.ts b/src/duration.ts
new file mode 100644
index 0000000..18849a0
--- /dev/null
+++ b/src/duration.ts
@@ -0,0 +1,26 @@
+import moment from 'moment';
+
+export type TimeUnit = moment.unitOfTime.DurationConstructor;
+
+export class Duration {
+ value: number;
+ unit: TimeUnit;
+ constructor(value: number, unit: TimeUnit) {
+ this.value = value
+ this.unit = unit
+ }
+
+ isValid() { return moment.duration(this.value, this.unit).isValid(); }
+ toMoment() {
+ let m = moment.duration(this.value, this.unit);
+ if (m.isValid()) return m;
+ return null;
+ }
+
+ static days(n: number) { return new Duration(n, 'days'); }
+ static weeks(n: number) { return new Duration(n, 'weeks'); }
+ static months(n: number) { return new Duration(n, 'months'); }
+
+ deflate() { return { value: this.value, unit: this.unit }; }
+ static inflate = (obj: { value: number, unit: TimeUnit }) => new Duration(obj.value, obj.unit);
+}
diff --git a/src/gapi.js b/src/gapi.js
deleted file mode 100644
index 3938864..0000000
--- a/src/gapi.js
+++ /dev/null
@@ -1,335 +0,0 @@
-/* global chrome */
-import LRU from "lru-cache";
-const gapi_base = 'https://www.googleapis.com/calendar/v3';
-
-const GApiError = Object.freeze({
- invalidSyncToken: Symbol("invalidSyncToken"),
- notLoggedIn: Symbol("notLoggedIn"),
- notLoggedOut: Symbol("notLoggedOut"),
- otherError: Symbol("otherError"),
-});
-
-function to_params(dict) {
- return Object.entries(dict).filter(([k, v]) => v).map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`).join('&');
-}
-
-let loggedIn = null;
-
-function _getAuthToken(interactive = false) {
- return new Promise(resolver =>
- chrome.identity.getAuthToken(
- { interactive }, token => resolver([token, !chrome.runtime.lastError])))
- .then(([token, ok]) => {
- if (ok) return token;
- else throw GApiError.notLoggedIn;
- });
-}
-
-function _removeCachedAuthToken(token) {
- return new Promise(resolver =>
- chrome.identity.removeCachedAuthToken({ token }, () => resolver()));
-}
-
-export function getLoggedIn() {
- if (loggedIn === null)
- {
- return _getAuthToken(false)
- .then(() => loggedIn = true)
- .catch(() => loggedIn = false)
- .then(() => loggedIn);
- }
- else return Promise.resolve(loggedIn);
-}
-
-export function getAuthToken() {
- return getLoggedIn().then(b => {
- if (b) return _getAuthToken(false);
- else throw GApiError.notLoggedIn;
- });
-}
-
-export function login() {
- return getLoggedIn().then(b => {
- if (!b) return _getAuthToken(true).then(() => loggedIn = true);
- else throw GApiError.notLoggedOut;
- });
-}
-
-export function logout() {
- return getAuthToken().then(token => {
- return fetch(`https://accounts.google.com/o/oauth2/revoke?${to_params({ token })}`,
- { method: 'GET', async: true }).then(response => {
- //if (response.status === 200)
- return _removeCachedAuthToken(token);
- //else throw GApiError.otherError;
- });
- }).then(() => loggedIn = false);
-}
-
-export function getCalendars(token) {
- return fetch(`${gapi_base}/users/me/calendarList?${to_params({access_token: token})}`,
- { method: 'GET', async: true })
- .then(response => response.json())
- .then(data => data.items);
-}
-
-export function getColors(token) {
- return fetch(`${gapi_base}/colors?${to_params({access_token: token})}`,
- { method: 'GET', async: true })
- .then(response => response.json());
-}
-
-function getEvent(calId, eventId, token) {
- return fetch(`${gapi_base}/calendars/${calId}/events/${eventId}?${to_params({access_token: token})}`,
- { method: 'GET', async: true })
- .then(response => response.json());
-}
-
-function getEvents(calId, token, syncToken=null, timeMin=null, timeMax=null, resultsPerRequest=100) {
- let results = [];
- const singleFetch = (pageToken, syncToken) => fetch(`${gapi_base}/calendars/${calId}/events?${to_params({
- access_token: token,
- pageToken,
- syncToken,
- timeMin,
- timeMax,
- maxResults: resultsPerRequest
- })}`, { method: 'GET', async: true })
- .then(response => {
- if (response.status === 200)
- return response.json();
- else if (response.status === 410)
- throw GApiError.invalidSyncToken;
- else throw GApiError.otherError;
- })
- .then(data => {
- results.push(...data.items);
- if (data.nextPageToken) {
- return singleFetch(data.nextPageToken, '');
- } else {
- return ({
- nextSyncToken: data.nextSyncToken,
- results
- });
- }
- })
-
- return singleFetch('', syncToken);
-}
-
-export class GCalendar {
- constructor(calId, name, options={maxCachedItems: 100, nDaysPerSlot: 10, largeQuery: 10}) {
- this.calId = calId;
- this.name = name;
- this.syncToken = '';
- this.cache = new LRU({
- max: options.maxCachedItems,
- dispose: (k, v) => this.onRemoveSlot(k, v)
- });
- this.eventMeta = {};
- this.options = options;
- this.divider = 8.64e7 * this.options.nDaysPerSlot;
- }
-
- get token() { return getAuthToken(); }
-
- dateToCacheKey(date) {
- return Math.floor(date / this.divider);
- }
-
- dateRangeToCacheKeys(range) {
- return {
- start: this.dateToCacheKey(range.start),
- end: this.dateToCacheKey(new Date(range.end.getTime() - 1))
- };
- }
-
- getSlot(k) {
- if (!this.cache.has(k))
- {
- let res = {};
- this.cache.set(k, res);
- return res;
- }
- else return this.cache.get(k);
- }
-
- onRemoveSlot(k, v) {
- for (let id in v) {
- console.assert(this.eventMeta[id]);
- let keys = this.eventMeta[id].keys;
- keys.delete(k);
- if (keys.size === 0)
- delete this.eventMeta[id];
- }
- }
-
- slotStartDate(k) { return new Date(k * this.divider); }
- slotEndDate(k) { return new Date((k + 1) * this.divider); }
-
- addEvent(e, evict = false) {
- //console.log('adding event', e);
- if (this.eventMeta.hasOwnProperty(e.id))
- this.removeEvent(e);
- let r = this.dateRangeToCacheKeys(e);
- let ks = r.start;
- let ke = r.end;
- let t = this.cache.length;
- let keys = new Set();
- for (let i = ks; i <= ke; i++)
- {
- keys.add(i);
- if (!this.cache.has(i)) t++;
- }
- this.eventMeta[e.id] = {
- keys,
- summary: e.summary,
- };
- if (!evict && t > this.options.maxCachedItems) return;
- if (ks === ke)
- this.getSlot(ks)[e.id] = {
- start: e.start,
- end: e.end,
- id: e.id };
- else
- {
- this.getSlot(ks)[e.id] = {
- start: e.start,
- end: this.slotEndDate(ks),
- id: e.id };
- this.getSlot(ke)[e.id] = {
- start: this.slotStartDate(ke),
- end: e.end,
- id: e.id };
- for (let k = ks + 1; k < ke; k++)
- this.getSlot(k)[e.id] = {
- start: this.slotStartDate(k),
- end: this.slotEndDate(k),
- id: e.id};
- }
- }
-
- removeEvent(e) {
- let keys = this.eventMeta[e.id].keys;
- console.assert(keys);
- keys.forEach(k => delete this.getSlot(k)[e.id]);
- delete this.eventMeta[e.id];
- }
-
- getSlotEvents(k, start, end) {
- let s = this.getSlot(k);
- //console.log(s);
- let results = [];
- for (let id in s) {
- if (!(s[id].start >= end || s[id].end <= start))
- {
- results.push({
- id,
- start: s[id].start < start ? start: s[id].start,
- end: s[id].end > end ? end: s[id].end,
- summary: this.eventMeta[id].summary
- });
- }
- }
- return results;
- }
-
- getCachedEvents(_r) {
- let r = this.dateRangeToCacheKeys(_r);
- let ks = r.start;
- let ke = r.end;
- let results = this.getSlotEvents(ks, _r.start, _r.end);
- for (let k = ks + 1; k < ke; k++)
- {
- let s = this.getSlot(k);
- for (let id in s)
- results.push(s[id]);
- }
- if (ke > ks)
- results.push(...this.getSlotEvents(ke, _r.start, _r.end));
- return results;
- }
-
- sync() {
- return this.token.then(token => getEvents(this.calId, token, this.syncToken).then(r => {
- let pms = r.results.map(e => e.start ? Promise.resolve(e) : getEvent(this.calId, e.id, token));
- return Promise.all(pms).then(results => {
- results.forEach(e => {
- e.start = new Date(e.start.dateTime);
- e.end = new Date(e.end.dateTime);
- if (e.status === 'confirmed')
- this.addEvent(e);
- else if (e.status === 'cancelled')
- this.removeEvent(e);
- });
- this.syncToken = r.nextSyncToken;
- });
- })).catch(e => {
- if (e === GApiError.invalidSyncToken) {
- this.syncToken = '';
- this.sync();
- } else throw e;
- });
- }
-
- getEvents(start, end) {
- let r = this.dateRangeToCacheKeys({ start, end });
- let query = {};
- for (let k = r.start; k <= r.end; k++)
- if (!this.cache.has(k))
- {
- if (!query.hasOwnProperty('start'))
- query.start = k;
- query.end = k;
- }
- //console.log(`start: ${start} end: ${end}`);
- if (query.hasOwnProperty('start'))
- {
- console.assert(query.start <= query.end);
- if (query.end - query.start + 1 > this.options.largeQuery) {
- console.log(`encounter large query, use direct fetch`);
- return this.token.then(token => getEvents(this.calId, token, null,
- start.toISOString(), end.toISOString()).then(r => {
- let results = [];
- r.results.forEach(e => {
- console.assert(e.start);
- e.start = new Date(e.start.dateTime);
- e.end = new Date(e.end.dateTime);
- results.push(e);
- });
- return results.filter(e => !(e.start >= end || e.end <= start)).map(e => {
- return {
- id: e.id,
- start: e.start < start ? start: e.start,
- end: e.end > end ? end: e.end,
- summary: e.summary,
- };
- });
- }));
- }
-
- console.log(`fetching short event list`);
- return this.token.then(token => getEvents(this.calId, token, null,
- this.slotStartDate(query.start).toISOString(),
- this.slotEndDate(query.end).toISOString()).then(r => {
- r.results.forEach(e => {
- if (e.status === 'confirmed')
- {
- console.assert(e.start);
- e.start = new Date(e.start.dateTime);
- e.end = new Date(e.end.dateTime);
- this.addEvent(e, true);
- }
- });
- if (this.syncToken === '')
- this.syncToken = r.nextSyncToken;
- })).then(() => this.sync())
- .then(() => this.getCachedEvents({ start, end }));
- }
- else
- {
- console.log(`cache hit`);
- return this.sync().then(() => this.getCachedEvents({ start, end }));
- }
- }
-}
diff --git a/src/gapi.ts b/src/gapi.ts
new file mode 100644
index 0000000..bf45ffc
--- /dev/null
+++ b/src/gapi.ts
@@ -0,0 +1,369 @@
+/* global chrome */
+
+import LRU from "lru-cache";
+
+const gapiBase = 'https://www.googleapis.com/calendar/v3';
+
+enum GApiError {
+ invalidSyncToken = "invalidSyncToken",
+ notLoggedIn = "notLoggedIn",
+ notLoggedOut = "notLoggedOut",
+ otherError = "otherError",
+}
+
+function to_params(dict: Object) {
+ return Object.entries(dict).filter(([k, v] : string[]) => v)
+ .map(([k, v]: string[]) => (
+ `${encodeURIComponent(k)}=${encodeURIComponent(v)}`
+ )).join('&');
+}
+
+let loggedIn = false;
+
+function _getAuthToken(interactive = false): Promise<string> {
+ return new Promise(resolver =>
+ chrome.identity.getAuthToken(
+ { interactive }, token => resolver([token, !chrome.runtime.lastError])))
+ .then(([token, ok] : [string, boolean]) => {
+ if (ok) return token;
+ else throw GApiError.notLoggedIn;
+ });
+}
+
+function _removeCachedAuthToken(token: string) {
+ return new Promise(resolver =>
+ chrome.identity.removeCachedAuthToken({ token }, () => resolver()));
+}
+
+export function getLoggedIn() {
+ if (loggedIn === null)
+ {
+ return _getAuthToken(false)
+ .then(() => loggedIn = true)
+ .catch(() => loggedIn = false)
+ .then(() => loggedIn);
+ }
+ else return Promise.resolve(loggedIn);
+}
+
+export function getAuthToken(): Promise<string> {
+ return getLoggedIn().then(b => {
+ if (b) return _getAuthToken(false);
+ else throw GApiError.notLoggedIn;
+ });
+}
+
+export function login() {
+ return getLoggedIn().then(b => {
+ if (!b) return _getAuthToken(true).then(() => loggedIn = true);
+ else throw GApiError.notLoggedOut;
+ });
+}
+
+export async function logout() {
+ let token = await getAuthToken();
+ let response = await fetch(
+ `https://accounts.google.com/o/oauth2/revoke?${to_params({ token })}`, { method: 'GET' });
+ //if (response.status === 200)
+ await _removeCachedAuthToken(token);
+ //else throw GApiError.otherError;
+ loggedIn = false;
+}
+
+export async function getCalendars(token: string) {
+ let response = await fetch(
+ `${gapiBase}/users/me/calendarList?${to_params({access_token: token})}`, { method: 'GET' });
+ return (await response.json()).items;
+}
+
+export async function getColors(token: string) {
+ let response = await fetch(
+ `${gapiBase}/colors?${to_params({access_token: token})}`, { method: 'GET' });
+ return response.json();
+}
+
+async function getEvent(calId: string, eventId: string, token: string) {
+ let response = await fetch(
+ `${gapiBase}/calendars/${calId}/events/${eventId}?${to_params({access_token: token})}`,
+ { method: 'GET' });
+ return response.json();
+}
+
+function getEvents(calId: string, token: string,
+ syncToken=null as string,
+ timeMin=null as string,
+ timeMax=null as string,
+ resultsPerRequest=100 as number):
+ Promise<{ results: any[], nextSyncToken: string }> {
+ let results = [] as any[];
+ const singleFetch = async (pageToken: string, syncToken: string):
+ Promise<{nextSyncToken: string, results: any[]}> => {
+ let response = await fetch(`${gapiBase}/calendars/${calId}/events?${to_params({
+ access_token: token,
+ pageToken,
+ syncToken,
+ timeMin,
+ timeMax,
+ maxResults: resultsPerRequest
+ })}`, { method: 'GET' });
+ if (response.status === 200)
+ {
+ let data = await response.json();
+ results.push(...data.items);
+ if (data.nextPageToken) {
+ return singleFetch(data.nextPageToken, '');
+ } else {
+ return ({
+ nextSyncToken: data.nextSyncToken,
+ results
+ });
+ }
+ }
+ else if (response.status === 410)
+ throw GApiError.invalidSyncToken;
+ else throw GApiError.otherError;
+ };
+
+ return singleFetch('', syncToken);
+}
+
+type GCalendarOptions = {
+ maxCachedItems: number,
+ nDaysPerSlot: number,
+ largeQuery: number
+};
+
+type GCalendarEvent = {
+ start: Date,
+ end: Date,
+ id: string
+};
+
+type GCalendarSlot = { [id: string]: GCalendarEvent };
+
+export class GCalendar {
+ calId: string;
+ name: string;
+ syncToken: string;
+ cache: LRU<number, GCalendarSlot>;
+ eventMeta: { [id: string]: { keys: Set<number>, summary: string } };
+ options: GCalendarOptions;
+ divider: number;
+
+ constructor(calId: string, name: string,
+ options={maxCachedItems: 100, nDaysPerSlot: 10, largeQuery: 10}) {
+ this.calId = calId;
+ this.name = name;
+ this.syncToken = '';
+ this.cache = new LRU<number, GCalendarSlot>({
+ max: options.maxCachedItems,
+ dispose: (k, v) => this.onRemoveSlot(k, v)
+ });
+ this.eventMeta = {};
+ this.options = options;
+ this.divider = 8.64e7 * this.options.nDaysPerSlot;
+ }
+
+ get token() { return getAuthToken(); }
+
+ dateToCacheKey(date: Date) {
+ return Math.floor(date.getTime() / this.divider);
+ }
+
+ dateRangeToCacheKeys(range: { start: Date, end: Date }) {
+ return {
+ start: this.dateToCacheKey(range.start),
+ end: this.dateToCacheKey(new Date(range.end.getTime() - 1))
+ };
+ }
+
+ getSlot(k: number) {
+ if (!this.cache.has(k))
+ {
+ let res = {};
+ this.cache.set(k, res);
+ return res;
+ }
+ else return this.cache.get(k);
+ }
+
+ onRemoveSlot(k: number, v: GCalendarSlot) {
+ for (let id in v) {
+ console.assert(this.eventMeta.hasOwnProperty(id));
+ let keys = this.eventMeta[id].keys;
+ keys.delete(k);
+ if (keys.size === 0)
+ delete this.eventMeta[id];
+ }
+ }
+
+ slotStartDate(k: number) { return new Date(k * this.divider); }
+ slotEndDate(k: number) { return new Date((k + 1) * this.divider); }
+
+ addEvent(e: {start: Date, end: Date, id: string, summary: string}, evict = false) {
+ //console.log('adding event', e);
+ if (this.eventMeta.hasOwnProperty(e.id))
+ this.removeEvent(e);
+ let r = this.dateRangeToCacheKeys(e);
+ let ks = r.start;
+ let ke = r.end;
+ let t = this.cache.length;
+ let keys = new Set();
+ for (let i = ks; i <= ke; i++)
+ {
+ keys.add(i);
+ if (!this.cache.has(i)) t++;
+ }
+ this.eventMeta[e.id] = {
+ keys,
+ summary: e.summary,
+ };
+ if (!evict && t > this.options.maxCachedItems) return;
+ if (ks === ke)
+ this.getSlot(ks)[e.id] = {
+ start: e.start,
+ end: e.end,
+ id: e.id };
+ else
+ {
+ this.getSlot(ks)[e.id] = {
+ start: e.start,
+ end: this.slotEndDate(ks),
+ id: e.id };
+ this.getSlot(ke)[e.id] = {
+ start: this.slotStartDate(ke),
+ end: e.end,
+ id: e.id };
+ for (let k = ks + 1; k < ke; k++)
+ this.getSlot(k)[e.id] = {
+ start: this.slotStartDate(k),
+ end: this.slotEndDate(k),
+ id: e.id};
+ }
+ }
+
+ removeEvent(e: {id: string}) {
+ let keys = this.eventMeta[e.id].keys;
+ keys.forEach(k => delete this.getSlot(k)[e.id]);
+ delete this.eventMeta[e.id];
+ }
+
+ getSlotEvents(k: number, r: {start: Date, end: Date}) {
+ let s = this.getSlot(k);
+ //console.log(s);
+ let results = [];
+ for (let id in s) {
+ if (!(s[id].start >= r.end || s[id].end <= r.start))
+ {
+ results.push({
+ id,
+ start: s[id].start < r.start ? r.start: s[id].start,
+ end: s[id].end > r.end ? r.end: s[id].end,
+ summary: this.eventMeta[id].summary
+ });
+ }
+ }
+ return results;
+ }
+
+ getCachedEvents(_r: {start: Date, end: Date}) {
+ let r = this.dateRangeToCacheKeys(_r);
+ let ks = r.start;
+ let ke = r.end;
+ let results = this.getSlotEvents(ks, _r);
+ for (let k = ks + 1; k < ke; k++)
+ {
+ let s = this.getSlot(k);
+ for (let id in s)
+ results.push({...s[id], summary: this.eventMeta[id].summary});
+ }
+ if (ke > ks)
+ results.push(...this.getSlotEvents(ke, _r));
+ return results;
+ }
+
+ async sync() {
+ try {
+ let token = await this.token;
+ let r = await getEvents(this.calId, token, this.syncToken);
+ let results = await Promise.all(
+ r.results.map(e => e.start ? Promise.resolve(e) : getEvent(this.calId, e.id, token)));
+ results.forEach(e => {
+ e.start = new Date(e.start.dateTime);
+ e.end = new Date(e.end.dateTime);
+ if (e.status === 'confirmed')
+ this.addEvent(e);
+ else if (e.status === 'cancelled')
+ this.removeEvent(e);
+ });
+ this.syncToken = r.nextSyncToken;
+ } catch(err) {
+ if (err === GApiError.invalidSyncToken) {
+ this.syncToken = '';
+ this.sync();
+ } else throw err;
+ }
+ }
+
+ async getEvents(start: Date, end: Date) {
+ let r = this.dateRangeToCacheKeys({ start, end });
+ let query = {
+ start: null as number,
+ end: null as number
+ };
+ for (let k = r.start; k <= r.end; k++)
+ if (!this.cache.has(k))
+ {
+ if (query.start === null)
+ query.start = k;
+ query.end = k;
+ }
+ //console.log(`start: ${start} end: ${end}`);
+ if (query.start !== null)
+ {
+ console.assert(query.start <= query.end);
+ if (query.end - query.start + 1 > this.options.largeQuery) {
+ console.log(`encounter large query, use direct fetch`);
+ let token = await this.token;
+ let r = await getEvents(this.calId, token, null,
+ start.toISOString(), end.toISOString());
+ return r.results.map(e => {
+ console.assert(e.start);
+ e.start = new Date(e.start.dateTime);
+ e.end = new Date(e.end.dateTime);
+ return e;
+ }).filter(e => !(e.start >= end || e.end <= start)).map(e => ({
+ id: e.id,
+ start: e.start < start ? start: e.start,
+ end: e.end > end ? end: e.end,
+ summary: e.summary,
+ }));
+ }
+
+ console.log(`fetching short event list`);
+ let token = await this.token;
+ let r = await getEvents(this.calId, token, null,
+ this.slotStartDate(query.start).toISOString(),
+ this.slotEndDate(query.end).toISOString());
+ r.results.forEach(e => {
+ if (e.status === 'confirmed')
+ {
+ console.assert(e.start);
+ e.start = new Date(e.start.dateTime);
+ e.end = new Date(e.end.dateTime);
+ this.addEvent(e, true);
+ }
+ });
+ if (this.syncToken === '')
+ this.syncToken = r.nextSyncToken;
+ await this.sync();
+ return this.getCachedEvents({ start, end });
+ }
+ else
+ {
+ console.log(`cache hit`);
+ await this.sync();
+ return this.getCachedEvents({ start, end });
+ }
+ }
+}
diff --git a/src/index.js b/src/index.js
deleted file mode 100644
index adcb634..0000000
--- a/src/index.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import React from 'react';
-import ReactDOM from 'react-dom';
-import Dashboard from './Dashboard';
-import * as serviceWorker from './serviceWorker';
-
-ReactDOM.render(<Dashboard />, document.getElementById('root'));
-
-// If you want your app to work offline and load faster, you can change
-// unregister() to register() below. Note this comes with some pitfalls.
-// Learn more about service workers: http://bit.ly/CRA-PWA
-serviceWorker.unregister();
diff --git a/src/index.tsx b/src/index.tsx
new file mode 100644
index 0000000..f5c836b
--- /dev/null
+++ b/src/index.tsx
@@ -0,0 +1,5 @@
+import React from 'react';
+import ReactDOM from 'react-dom';
+import Dashboard from './Dashboard';
+
+ReactDOM.render(<Dashboard />, document.getElementById('root'));
diff --git a/src/msg.js b/src/msg.js
deleted file mode 100644
index 2e72ea7..0000000
--- a/src/msg.js
+++ /dev/null
@@ -1,97 +0,0 @@
-/* global chrome */
-const _updatePatterns = "updatePatterns";
-const _getPatterns = "getPatterns";
-const _updateCalendars = "updateCalendars";
-const _getCalendars = "getCalendars";
-const _getCalEvents = "getCalEvents";
-const _updateConfig = "updateConfig";
-const _getConfig = "getConfig";
-const _getGraphData = "getGraphData";
-
-export const msgType = Object.freeze({
- updatePatterns: Symbol(_updatePatterns),
- getPatterns: Symbol(_getPatterns),
- updateCalendars: Symbol(_updateCalendars),
- getCalendars: Symbol(_getCalendars),
- getCalEvents: Symbol(_getCalEvents),
- updateConfig: Symbol(_updateConfig),
- getConfig: Symbol(_getConfig),
- getGraphData: Symbol(_getGraphData),
-});
-
-function stringifyMsgType(mt) {
- switch (mt) {
- case msgType.updatePatterns: return _updatePatterns;
- case msgType.getPatterns: return _getPatterns;
- case msgType.updateCalendars: return _updateCalendars;
- case msgType.getCalendars: return _getCalendars;
- case msgType.getCalEvents: return _getCalEvents;
- case msgType.updateConfig: return _updateConfig;
- case msgType.getConfig: return _getConfig;
- case msgType.getGraphData: return _getGraphData;
- default: console.error("unreachable");
- }
-}
-
-function parseMsgType(s) {
- switch(s) {
- case _updatePatterns: return msgType.updatePatterns;
- case _getPatterns: return msgType.getPatterns;
- case _updateCalendars: return msgType.updateCalendars;
- case _getCalendars: return msgType.getCalendars;
- case _getCalEvents: return msgType.getCalEvents;
- case _updateConfig: return msgType.updateConfig;
- case _getConfig: return msgType.getConfig;
- case _getGraphData: return msgType.getGraphData;
- default: console.error("unreachable");
- }
-}
-
-export class Msg {
- constructor(id, type, data) {
- this.id = id;
- this.type = type;
- this.data = data;
- }
- genResp(data) { return new Msg(this.id, this.type, data); }
- deflate() {
- return {
- id: this.id,
- type: stringifyMsgType(this.type),
- data: this.data
- }
- }
- static inflate = obj => new Msg(obj.id, parseMsgType(obj.type), obj.data);
-}
-
-export class MsgClient {
- constructor(channelName) {
- let port = chrome.runtime.connect({name: channelName});
- const getCallBack = rcb => this.requestCallback;
- port.onMessage.addListener(function(msg) {
- console.log(msg);
- let rcb = getCallBack(msg.type);
- let cb = rcb.inFlight[msg.id];
- console.assert(cb !== undefined);
- rcb.ids.push(msg.id);
- cb(msg);
- });
- this.port = port;
- this.requestCallback = {inFlight: {}, ids: [], maxId: 0};
- }
-
- sendMsg = ({ type, data }) => {
- let rcb = this.requestCallback;
- let cb;
- let pm = new Promise(resolve => { cb = resolve; });
- let id;
- if (rcb.ids.length > 0) {
- id = rcb.ids.pop();
- } else {
- id = rcb.maxId++;
- }
- rcb.inFlight[id] = cb;
- this.port.postMessage((new Msg(id, type, data)).deflate());
- return pm;
- }
-}
diff --git a/src/msg.ts b/src/msg.ts
new file mode 100644
index 0000000..12eb2bc
--- /dev/null
+++ b/src/msg.ts
@@ -0,0 +1,87 @@
+/* global chrome */
+
+export enum MsgType {
+ updatePatterns = "updatePatterns",
+ getPatterns = "getPatterns",
+ updateCalendars = "updateCalendars",
+ getCalendars = "getCalendars",
+ getCalEvents = "getCalEvents",
+ updateConfig = "updateConfig",
+ getConfig = "getConfig",
+ getGraphData = "getGraphData"
+}
+
+function stringifyMsgType(mt: MsgType): string { return MsgType[mt]; }
+
+function parseMsgType(s: string): MsgType {
+ switch (s) {
+ case "updatePatterns": return MsgType.updatePatterns;
+ case "getPatterns": return MsgType.getPatterns;
+ case "updateCalendars" : return MsgType.updateCalendars;
+ case "getCalendars": return MsgType.getCalendars;
+ case "updateConfig": return MsgType.updateConfig;
+ case "getConfig": return MsgType.getConfig;
+ case "getGraphData": return MsgType.getGraphData;
+ default: console.error("unreachable");
+ }
+}
+
+export class Msg<T> {
+ id: number;
+ mt: MsgType;
+ data: T;
+ constructor(id: number, mt: MsgType, data: T) {
+ this.id = id;
+ this.mt = mt;
+ this.data = data;
+ }
+ genResp(data: T) { return new Msg(this.id, this.mt, data); }
+ deflate() {
+ return {
+ id: this.id,
+ mt: stringifyMsgType(this.mt),
+ data: this.data
+ }
+ }
+ static inflate = <T>(obj: {id: number, mt: MsgType, data: T}) => (
+ new Msg(obj.id, parseMsgType(obj.mt), obj.data)
+ );
+}
+
+export class MsgClient {
+ requestCallback: {
+ ids: number[],
+ inFlight: {[id: number]: (msg: Msg<any>) => any; },
+ maxId: number
+ };
+ port: chrome.runtime.Port;
+
+ constructor(channelName: string) {
+ let port = chrome.runtime.connect({name: channelName});
+ const rcb = this.requestCallback;
+ port.onMessage.addListener(function(msg) {
+ console.log(msg);
+ let cb = rcb.inFlight[msg.id];
+ console.assert(cb !== undefined);
+ rcb.ids.push(msg.id);
+ cb(msg);
+ });
+ this.port = port;
+ this.requestCallback = {inFlight: {}, ids: [], maxId: 0};
+ }
+
+ sendMsg({ mt, data }: { mt: MsgType, data: any }) {
+ const rcb = this.requestCallback;
+ let cb;
+ let pm = new Promise(resolve => { cb = resolve; });
+ let id;
+ if (rcb.ids.length > 0) {
+ id = rcb.ids.pop();
+ } else {
+ id = rcb.maxId++;
+ }
+ rcb.inFlight[id] = cb;
+ this.port.postMessage((new Msg(id, mt, data)).deflate());
+ return pm;
+ }
+}
diff --git a/src/pattern.js b/src/pattern.ts
index 858f2a3..cae35a9 100644
--- a/src/pattern.js
+++ b/src/pattern.ts
@@ -1,5 +1,17 @@
+interface PatternFlat {
+ id: number | string;
+ isRegex: boolean;
+ value: string;
+ label: string;
+}
+
export class Pattern {
- constructor(id, isRegex, value, label) {
+ id: number | string;
+ isRegex: boolean;
+ value: string;
+ label: string;
+
+ constructor(id: number | string, isRegex: boolean, value: string, label: string) {
this.id = id;
this.isRegex = isRegex;
this.value = value;
@@ -18,11 +30,31 @@ export class Pattern {
}
static emptyPattern = () => new Pattern(0, true, '', null);
static anyPattern = () => new Pattern('any', true, '.*', 'Any');
- static inflate = obj => new Pattern(obj.id, obj.isRegex, obj.value, obj.label);
+ static inflate = (obj: PatternFlat) => new Pattern(obj.id, obj.isRegex, obj.value, obj.label);
+}
+
+interface PatternEntryColor {
+ background: string
+}
+
+interface PatternEntryFlat {
+ name: string;
+ idx: number;
+ cal: PatternFlat;
+ event: PatternFlat;
+ color: PatternEntryColor;
}
export class PatternEntry {
- constructor(name, idx, calPattern, eventPattern, color) {
+ name: string;
+ idx: number;
+ cal: Pattern;
+ event: Pattern;
+ color: PatternEntryColor;
+
+ constructor(name: string, idx: number,
+ calPattern: Pattern, eventPattern: Pattern,
+ color: PatternEntryColor) {
this.name = name;
this.idx = idx;
this.cal = calPattern;
@@ -40,8 +72,12 @@ export class PatternEntry {
};
}
- static defaultPatternEntry = (idx) => new PatternEntry('', idx, Pattern.emptyPattern(), Pattern.anyPattern(), {background: null});
- static inflate = obj => new PatternEntry(
+ static defaultPatternEntry = (idx: number) => (
+ new PatternEntry('', idx,
+ Pattern.emptyPattern(),
+ Pattern.anyPattern(), {background: null}));
+
+ static inflate = (obj: PatternEntryFlat) => new PatternEntry(
obj.name, obj.idx,
Pattern.inflate(obj.cal), Pattern.inflate(obj.event),
obj.color);
diff --git a/src/popup.js b/src/popup.tsx
index c93ce91..5474476 100644
--- a/src/popup.js
+++ b/src/popup.tsx
@@ -1,6 +1,5 @@
import React from 'react';
import ReactDOM from 'react-dom';
-import * as serviceWorker from './serviceWorker';
import { withStyles, MuiThemeProvider } from '@material-ui/core/styles';
import Button from '@material-ui/core/Button';
import IconButton from '@material-ui/core/IconButton';
@@ -11,7 +10,7 @@ import { theme } from './theme';
import CssBaseline from '@material-ui/core/CssBaseline';
import { PatternEntry } from './pattern';
import { Duration } from './duration';
-import { msgType, MsgClient } from './msg';
+import { MsgType, MsgClient } from './msg';
import { StyledPatternPieChart } from './Chart';
import Divider from '@material-ui/core/Divider';
import moment from 'moment';
@@ -49,7 +48,7 @@ class Popup extends React.Component {
loadGraphData(sync) {
return this.msgClient.sendMsg({
- type: msgType.getGraphData,
+ type: MsgType.getGraphData,
data: { sync }
}).then(msg => {
this.setState({ patternGraphData: msg.data.map(d => ({
@@ -111,8 +110,3 @@ class Popup extends React.Component {
const StyledPopup = withStyles(styles)(Popup);
ReactDOM.render(<StyledPopup />, document.getElementById('root'));
-
-// If you want your app to work offline and load faster, you can change
-// unregister() to register() below. Note this comes with some pitfalls.
-// Learn more about service workers: http://bit.ly/CRA-PWA
-serviceWorker.unregister();
diff --git a/src/serviceWorker.js b/src/serviceWorker.js
deleted file mode 100644
index 2283ff9..0000000
--- a/src/serviceWorker.js
+++ /dev/null
@@ -1,135 +0,0 @@
-// This optional code is used to register a service worker.
-// register() is not called by default.
-
-// This lets the app load faster on subsequent visits in production, and gives
-// it offline capabilities. However, it also means that developers (and users)
-// will only see deployed updates on subsequent visits to a page, after all the
-// existing tabs open on the page have been closed, since previously cached
-// resources are updated in the background.
-
-// To learn more about the benefits of this model and instructions on how to
-// opt-in, read http://bit.ly/CRA-PWA
-
-const isLocalhost = Boolean(
- window.location.hostname === 'localhost' ||
- // [::1] is the IPv6 localhost address.
- window.location.hostname === '[::1]' ||
- // 127.0.0.1/8 is considered localhost for IPv4.
- window.location.hostname.match(
- /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
- )
-);
-
-export function register(config) {
- if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
- // The URL constructor is available in all browsers that support SW.
- const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
- if (publicUrl.origin !== window.location.origin) {
- // Our service worker won't work if PUBLIC_URL is on a different origin
- // from what our page is served on. This might happen if a CDN is used to
- // serve assets; see https://github.com/facebook/create-react-app/issues/2374
- return;
- }
-
- window.addEventListener('load', () => {
- const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
-
- if (isLocalhost) {
- // This is running on localhost. Let's check if a service worker still exists or not.
- checkValidServiceWorker(swUrl, config);
-
- // Add some additional logging to localhost, pointing developers to the
- // service worker/PWA documentation.
- navigator.serviceWorker.ready.then(() => {
- console.log(
- 'This web app is being served cache-first by a service ' +
- 'worker. To learn more, visit http://bit.ly/CRA-PWA'
- );
- });
- } else {
- // Is not localhost. Just register service worker
- registerValidSW(swUrl, config);
- }
- });
- }
-}
-
-function registerValidSW(swUrl, config) {
- navigator.serviceWorker
- .register(swUrl)
- .then(registration => {
- registration.onupdatefound = () => {
- const installingWorker = registration.installing;
- if (installingWorker == null) {
- return;
- }
- installingWorker.onstatechange = () => {
- if (installingWorker.state === 'installed') {
- if (navigator.serviceWorker.controller) {
- // At this point, the updated precached content has been fetched,
- // but the previous service worker will still serve the older
- // content until all client tabs are closed.
- console.log(
- 'New content is available and will be used when all ' +
- 'tabs for this page are closed. See http://bit.ly/CRA-PWA.'
- );
-
- // Execute callback
- if (config && config.onUpdate) {
- config.onUpdate(registration);
- }
- } else {
- // At this point, everything has been precached.
- // It's the perfect time to display a
- // "Content is cached for offline use." message.
- console.log('Content is cached for offline use.');
-
- // Execute callback
- if (config && config.onSuccess) {
- config.onSuccess(registration);
- }
- }
- }
- };
- };
- })
- .catch(error => {
- console.error('Error during service worker registration:', error);
- });
-}
-
-function checkValidServiceWorker(swUrl, config) {
- // Check if the service worker can be found. If it can't reload the page.
- fetch(swUrl)
- .then(response => {
- // Ensure service worker exists, and that we really are getting a JS file.
- const contentType = response.headers.get('content-type');
- if (
- response.status === 404 ||
- (contentType != null && contentType.indexOf('javascript') === -1)
- ) {
- // No service worker found. Probably a different app. Reload the page.
- navigator.serviceWorker.ready.then(registration => {
- registration.unregister().then(() => {
- window.location.reload();
- });
- });
- } else {
- // Service worker found. Proceed as normal.
- registerValidSW(swUrl, config);
- }
- })
- .catch(() => {
- console.log(
- 'No internet connection found. App is running in offline mode.'
- );
- });
-}
-
-export function unregister() {
- if ('serviceWorker' in navigator) {
- navigator.serviceWorker.ready.then(registration => {
- registration.unregister();
- });
- }
-}
diff --git a/src/theme.js b/src/theme.tsx
index 0269fd3..0269fd3 100644
--- a/src/theme.js
+++ b/src/theme.tsx
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..c15d47c
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,16 @@
+{
+ "compilerOptions": {
+ "outDir": "./dist/",
+ "sourceMap": true,
+ "noImplicitAny": true,
+ "module": "commonjs",
+ "target": "es5",
+ "lib": ["dom", "es2016", "es2017"],
+ "jsx": "react",
+ "typeRoots": ["./types", "./node_modules/@types"],
+ "allowSyntheticDefaultImports": true
+ },
+ "include": [
+ "./src/**/*"
+ ]
+}
diff --git a/types/lru-cache/index.d.ts b/types/lru-cache/index.d.ts
new file mode 100644
index 0000000..1f1f2b7
--- /dev/null
+++ b/types/lru-cache/index.d.ts
@@ -0,0 +1,10 @@
+declare module 'lru-cache' {
+ class LRUCache<K, V> {
+ constructor(config: { max: number, dispose: (k: K, v: V) => any});
+ get length(): number;
+ has(key: K): boolean;
+ get(key: K): V;
+ set(key: K, val: V);
+ }
+ export = LRUCache;
+}
diff --git a/types/lru-cache/log b/types/lru-cache/log
new file mode 100644
index 0000000..44b539f
--- /dev/null
+++ b/types/lru-cache/log
@@ -0,0 +1,1485 @@
+
+> [email protected] start /home/ymf/work/chromicle
+> webpack --mode development --watch
+
+
+webpack is watching the files…
+
+Hash: 6a08dd4d420190403f37
+Version: webpack 4.29.2
+Time: 8919ms
+Built at: 02/13/2019 12:28:26 AM
+ Asset Size Chunks Chunk Names
+ ./index.html 508 bytes [emitted]
+ ./manifest.json 1.24 KiB [emitted]
+ ./popup.html 508 bytes [emitted]
+ background.js 3.63 MiB background [emitted] background
+ background.js.map 3.67 MiB background [emitted] background
+ fonts/TypoPRO-FantasqueSansMono-Regular.css 568 bytes [emitted]
+ fonts/TypoPRO-FantasqueSansMono-Regular.eot 56.9 KiB [emitted]
+ fonts/TypoPRO-FantasqueSansMono-Regular.ttf 56.5 KiB [emitted]
+fonts/TypoPRO-FantasqueSansMono-Regular.woff 28.4 KiB [emitted]
+ icon128.png 4.06 KiB [emitted]
+ icon16.png 561 bytes [emitted]
+ icon48.png 1.64 KiB [emitted]
+ index.js 6.04 MiB index [emitted] index
+ index.js.map 6.1 MiB index [emitted] index
+ popup.js 3.71 MiB popup [emitted] popup
+ popup.js.map 3.74 MiB popup [emitted] popup
+Entrypoint index = index.js index.js.map
+Entrypoint background = background.js background.js.map
+Entrypoint popup = popup.js popup.js.map
+[./node_modules/moment/locale sync recursive ^\.\/.*$] ./node_modules/moment/locale sync ^\.\/.*$ 3 KiB {index} {background} {popup} [optional] [built]
+[./node_modules/webpack/buildin/module.js] (webpack)/buildin/module.js 497 bytes {index} {background} {popup} [built]
+[./src/Analyze.tsx] 11.7 KiB {index} [built] [27 errors]
+[./src/Chart.tsx] 6.41 KiB {index} {background} {popup} [built] [34 errors]
+[./src/Dashboard.tsx] 5.14 KiB {index} [built] [13 errors]
+[./src/Logo.tsx] 1.34 KiB {index} {popup} [built] [1 error]
+[./src/Settings.tsx] 22.2 KiB {index} [built] [81 errors]
+[./src/background.ts] 11.2 KiB {background} [built] [47 errors]
+[./src/duration.ts] 1010 bytes {index} {background} [built]
+[./src/gapi.ts] 19.3 KiB {index} {background} [built] [4 errors]
+[./src/index.tsx] 310 bytes {index} [built] [1 error]
+[./src/msg.ts] 2.67 KiB {index} {background} {popup} [built]
+[./src/pattern.ts] 2.07 KiB {index} {background} [built]
+[./src/popup.tsx] 5.12 KiB {popup} [built] [12 errors]
+[./src/theme.tsx] 619 bytes {index} {background} {popup} [built]
+ + 1404 hidden modules
+
+ERROR in /home/ymf/work/chromicle/src/Analyze.tsx
+./src/Analyze.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Analyze.tsx(59,13)
+ TS2345: Argument of type '{ type: MsgType; data: { id: string; }; }' is not assignable to parameter of type '{ mt: MsgType; data: any; }'.
+ Object literal may only specify known properties, and 'type' does not exist in type '{ mt: MsgType; data: any; }'.
+
+ERROR in /home/ymf/work/chromicle/src/Analyze.tsx
+./src/Analyze.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Analyze.tsx(61,17)
+ TS7006: Parameter 'msg' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Analyze.tsx
+./src/Analyze.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Analyze.tsx(62,52)
+ TS7006: Parameter 'p' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Analyze.tsx
+./src/Analyze.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Analyze.tsx(66,13)
+ TS2345: Argument of type '{ type: MsgType; data: { enabledOnly: boolean; }; }' is not assignable to parameter of type '{ mt: MsgType; data: any; }'.
+ Object literal may only specify known properties, and 'type' does not exist in type '{ mt: MsgType; data: any; }'.
+
+ERROR in /home/ymf/work/chromicle/src/Analyze.tsx
+./src/Analyze.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Analyze.tsx(68,17)
+ TS7006: Parameter 'msg' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Analyze.tsx
+./src/Analyze.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Analyze.tsx(75,14)
+ TS2339: Property 'dialogPromiseResolver' does not exist on type 'Analyze'.
+
+ERROR in /home/ymf/work/chromicle/src/Analyze.tsx
+./src/Analyze.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Analyze.tsx(80,13)
+ TS2345: Argument of type '{ type: MsgType; data: { id: string; patterns: { name: string; idx: number; cal: { id: ReactText; isRegex: boolean; value: string; label: string; }; event: { id: ReactText; isRegex: boolean; value: string; label: string; }; color: PatternEntryColor; }[]; }; }' is not assignable to parameter of type '{ mt: MsgType; data: any; }'.
+ Object literal may only specify known properties, and 'type' does not exist in type '{ mt: MsgType; data: any; }'.
+
+ERROR in /home/ymf/work/chromicle/src/Analyze.tsx
+./src/Analyze.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Analyze.tsx(87,9)
+ TS7017: Element implicitly has an 'any' type because type 'PatternEntry' has no index signature.
+
+ERROR in /home/ymf/work/chromicle/src/Analyze.tsx
+./src/Analyze.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Analyze.tsx(107,41)
+ TS2345: Argument of type '{ type: MsgType; data: { id: string; start: number; end: number; }; }' is not assignable to parameter of type '{ mt: MsgType; data: any; }'.
+ Object literal may only specify known properties, and 'type' does not exist in type '{ mt: MsgType; data: any; }'.
+
+ERROR in /home/ymf/work/chromicle/src/Analyze.tsx
+./src/Analyze.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Analyze.tsx(110,22)
+ TS7031: Binding element 'data' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Analyze.tsx
+./src/Analyze.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Analyze.tsx(110,42)
+ TS7006: Parameter 'e' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Analyze.tsx
+./src/Analyze.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Analyze.tsx(145,23)
+ TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
+
+ERROR in /home/ymf/work/chromicle/src/Analyze.tsx
+./src/Analyze.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Analyze.tsx(163,28)
+ TS7006: Parameter 'event' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Analyze.tsx
+./src/Analyze.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Analyze.tsx(163,35)
+ TS7006: Parameter 'reason' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Analyze.tsx
+./src/Analyze.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Analyze.tsx(168,27)
+ TS7006: Parameter 'msg' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Analyze.tsx
+./src/Analyze.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Analyze.tsx(168,32)
+ TS7006: Parameter 'variant' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Analyze.tsx
+./src/Analyze.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Analyze.tsx(172,25)
+ TS7006: Parameter 'title' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Analyze.tsx
+./src/Analyze.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Analyze.tsx(172,32)
+ TS7006: Parameter 'message' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Analyze.tsx
+./src/Analyze.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Analyze.tsx(174,18)
+ TS2339: Property 'dialogPromiseResolver' does not exist on type 'Analyze'.
+
+ERROR in /home/ymf/work/chromicle/src/Analyze.tsx
+./src/Analyze.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Analyze.tsx(180,25)
+ TS7006: Parameter 'result' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Analyze.tsx
+./src/Analyze.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Analyze.tsx(181,14)
+ TS2339: Property 'dialogPromiseResolver' does not exist on type 'Analyze'.
+
+ERROR in /home/ymf/work/chromicle/src/Analyze.tsx
+./src/Analyze.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Analyze.tsx(186,17)
+ TS2339: Property 'classes' does not exist on type 'Readonly<{ children?: ReactNode; }> & Readonly<{}>'.
+
+ERROR in /home/ymf/work/chromicle/src/Analyze.tsx
+./src/Analyze.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Analyze.tsx(225,55)
+ TS7031: Binding element 'startDate' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Analyze.tsx
+./src/Analyze.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Analyze.tsx(225,66)
+ TS7031: Binding element 'endDate' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Analyze.tsx
+./src/Analyze.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Analyze.tsx(228,62)
+ TS2339: Property 'focusedInput' does not exist on type '{ patterns: PatternEntry[]; calendars: {}; startDate: Moment; endDate: Moment; patternGraphData: { name: string; value: number; color: string; }[]; calendarGraphData: { name: string; value: number; color: string; }[]; ... 4 more ...; dialogMsg: { ...; }; }'.
+
+ERROR in /home/ymf/work/chromicle/src/Analyze.tsx
+./src/Analyze.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Analyze.tsx(229,52)
+ TS7006: Parameter 'focusedInput' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Analyze.tsx
+./src/Analyze.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Analyze.tsx(266,9)
+ TS2339: Property 'propTypes' does not exist on type 'typeof Analyze'.
+
+ERROR in /home/ymf/work/chromicle/src/Chart.tsx
+./src/Chart.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Chart.tsx(6,46)
+ TS7016: Could not find a declaration file for module 'recharts'. '/home/ymf/work/chromicle/node_modules/recharts/lib/index.js' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Chart.tsx
+./src/Chart.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Chart.tsx(9,30)
+ TS7006: Parameter 'start' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Chart.tsx
+./src/Chart.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Chart.tsx(9,37)
+ TS7006: Parameter 'end' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Chart.tsx
+./src/Chart.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Chart.tsx(9,42)
+ TS7006: Parameter 'patterns' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Chart.tsx
+./src/Chart.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Chart.tsx(9,52)
+ TS7006: Parameter 'calendars' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Chart.tsx
+./src/Chart.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Chart.tsx(9,63)
+ TS7006: Parameter 'calEventsGetter' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Chart.tsx
+./src/Chart.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Chart.tsx(15,40)
+ TS7006: Parameter 'p' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Chart.tsx
+./src/Chart.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Chart.tsx(18,23)
+ TS7006: Parameter 'r' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Chart.tsx
+./src/Chart.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Chart.tsx(26,13)
+ TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
+
+ERROR in /home/ymf/work/chromicle/src/Chart.tsx
+./src/Chart.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Chart.tsx(27,13)
+ TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
+
+ERROR in /home/ymf/work/chromicle/src/Chart.tsx
+./src/Chart.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Chart.tsx(30,13)
+ TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
+
+ERROR in /home/ymf/work/chromicle/src/Chart.tsx
+./src/Chart.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Chart.tsx(32,18)
+ TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
+
+ERROR in /home/ymf/work/chromicle/src/Chart.tsx
+./src/Chart.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Chart.tsx(33,13)
+ TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
+
+ERROR in /home/ymf/work/chromicle/src/Chart.tsx
+./src/Chart.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Chart.tsx(33,32)
+ TS7006: Parameter 'event' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Chart.tsx
+./src/Chart.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Chart.tsx(34,17)
+ TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
+
+ERROR in /home/ymf/work/chromicle/src/Chart.tsx
+./src/Chart.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Chart.tsx(34,43)
+ TS7006: Parameter 'p' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Chart.tsx
+./src/Chart.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Chart.tsx(37,25)
+ TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
+
+ERROR in /home/ymf/work/chromicle/src/Chart.tsx
+./src/Chart.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Chart.tsx(40,21)
+ TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
+
+ERROR in /home/ymf/work/chromicle/src/Chart.tsx
+./src/Chart.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Chart.tsx(41,21)
+ TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
+
+ERROR in /home/ymf/work/chromicle/src/Chart.tsx
+./src/Chart.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Chart.tsx(47,32)
+ TS7006: Parameter 'data' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Chart.tsx
+./src/Chart.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Chart.tsx(51,26)
+ TS7006: Parameter 'd' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Chart.tsx
+./src/Chart.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Chart.tsx(52,26)
+ TS7006: Parameter 'd' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Chart.tsx
+./src/Chart.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Chart.tsx(67,24)
+ TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
+
+ERROR in /home/ymf/work/chromicle/src/Chart.tsx
+./src/Chart.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Chart.tsx(73,25)
+ TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
+
+ERROR in /home/ymf/work/chromicle/src/Chart.tsx
+./src/Chart.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Chart.tsx(82,16)
+ TS7006: Parameter 'theme' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Chart.tsx
+./src/Chart.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Chart.tsx(88,26)
+ TS7006: Parameter 'props' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Chart.tsx
+./src/Chart.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Chart.tsx(111,26)
+ TS7006: Parameter 'props' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Chart.tsx
+./src/Chart.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Chart.tsx(124,32)
+ TS7006: Parameter 'd' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Chart.tsx
+./src/Chart.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Chart.tsx(124,35)
+ TS7006: Parameter 'i' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Chart.tsx
+./src/Chart.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Chart.tsx(126,36)
+ TS7006: Parameter 'value' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Chart.tsx
+./src/Chart.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Chart.tsx(135,25)
+ TS7006: Parameter 'props' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Chart.tsx
+./src/Chart.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Chart.tsx(151,43)
+ TS7006: Parameter 'd' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Chart.tsx
+./src/Chart.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Chart.tsx(151,46)
+ TS7006: Parameter 'i' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Chart.tsx
+./src/Chart.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Chart.tsx(153,32)
+ TS7006: Parameter 'value' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Dashboard.tsx
+./src/Dashboard.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Dashboard.tsx(13,81)
+ TS7016: Could not find a declaration file for module 'react-router-dom'. '/home/ymf/work/chromicle/node_modules/react-router-dom/index.js' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Dashboard.tsx
+./src/Dashboard.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Dashboard.tsx(14,29)
+ TS7016: Could not find a declaration file for module 'react-router'. '/home/ymf/work/chromicle/node_modules/react-router/index.js' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Dashboard.tsx
+./src/Dashboard.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Dashboard.tsx(20,16)
+ TS7006: Parameter 'theme' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Dashboard.tsx
+./src/Dashboard.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Dashboard.tsx(48,24)
+ TS7006: Parameter 'event' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Dashboard.tsx
+./src/Dashboard.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Dashboard.tsx(48,31)
+ TS7006: Parameter 'currentTab' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Dashboard.tsx
+./src/Dashboard.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Dashboard.tsx(49,20)
+ TS2339: Property 'history' does not exist on type 'Readonly<{ children?: ReactNode; }> & Readonly<{}>'.
+
+ERROR in /home/ymf/work/chromicle/src/Dashboard.tsx
+./src/Dashboard.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Dashboard.tsx(52,17)
+ TS2339: Property 'classes' does not exist on type 'Readonly<{ children?: ReactNode; }> & Readonly<{}>'.
+
+ERROR in /home/ymf/work/chromicle/src/Dashboard.tsx
+./src/Dashboard.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Dashboard.tsx(62,26)
+ TS2322: Type '{ children: Element[]; styles: { display: string; }; classes: { indicator: any; }; value: any; onChange: (event: any, currentTab: any) => void; }' is not assignable to type 'IntrinsicAttributes & TabsProps & { children?: ReactNode; }'.
+ Property 'styles' does not exist on type 'IntrinsicAttributes & TabsProps & { children?: ReactNode; }'.
+
+ERROR in /home/ymf/work/chromicle/src/Dashboard.tsx
+./src/Dashboard.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Dashboard.tsx(64,47)
+ TS2339: Property 'history' does not exist on type 'Readonly<{ children?: ReactNode; }> & Readonly<{}>'.
+
+ERROR in /home/ymf/work/chromicle/src/Dashboard.tsx
+./src/Dashboard.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Dashboard.tsx(66,30)
+ TS2322: Type '{ label: string; component: any; to: string; value: string; }' is not assignable to type 'IntrinsicAttributes & TabProps & { children?: ReactNode; }'.
+ Property 'to' does not exist on type 'IntrinsicAttributes & TabProps & { children?: ReactNode; }'.
+
+ERROR in /home/ymf/work/chromicle/src/Dashboard.tsx
+./src/Dashboard.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Dashboard.tsx(67,30)
+ TS2322: Type '{ label: string; component: any; to: string; value: string; }' is not assignable to type 'IntrinsicAttributes & TabProps & { children?: ReactNode; }'.
+ Property 'to' does not exist on type 'IntrinsicAttributes & TabProps & { children?: ReactNode; }'.
+
+ERROR in /home/ymf/work/chromicle/src/Dashboard.tsx
+./src/Dashboard.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Dashboard.tsx(83,15)
+ TS2339: Property 'propTypes' does not exist on type 'typeof DashboardTabs'.
+
+ERROR in /home/ymf/work/chromicle/src/Dashboard.tsx
+./src/Dashboard.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Dashboard.tsx(89,17)
+ TS2339: Property 'classes' does not exist on type 'Readonly<{ children?: ReactNode; }> & Readonly<{}>'.
+
+ERROR in /home/ymf/work/chromicle/src/Dialog.tsx
+./src/Dialog.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Dialog.tsx(12,21)
+ TS7006: Parameter 'props' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Dialog.tsx
+./src/Dialog.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Dialog.tsx(16,22)
+ TS7006: Parameter 'props' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Logo.tsx
+./src/Logo.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Logo.tsx(2,17)
+ TS7006: Parameter 'props' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx
+./src/PatternTable.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx(13,33)
+ TS7016: Could not find a declaration file for module 'react-material-color-picker'. '/home/ymf/work/chromicle/node_modules/react-material-color-picker/dist/MaterialColorPicker.js' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx
+./src/PatternTable.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx(17,16)
+ TS7006: Parameter 'theme' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx
+./src/PatternTable.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx(53,20)
+ TS7006: Parameter 'props' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx
+./src/PatternTable.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx(70,31)
+ TS2554: Expected 0 arguments, but got 1.
+
+ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx
+./src/PatternTable.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx(71,28)
+ TS2554: Expected 0 arguments, but got 1.
+
+ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx
+./src/PatternTable.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx(77,9)
+ TS7018: Object literal's property 'activePattern' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx
+./src/PatternTable.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx(78,9)
+ TS7018: Object literal's property 'anchorEl' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx
+./src/PatternTable.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx(83,25)
+ TS7006: Parameter 'event' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx
+./src/PatternTable.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx(83,32)
+ TS7006: Parameter 'page' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx
+./src/PatternTable.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx(87,31)
+ TS7006: Parameter 'event' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx
+./src/PatternTable.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx(93,14)
+ TS2339: Property 'activeColorPattern' does not exist on type 'PatternTable'.
+
+ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx
+./src/PatternTable.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx(94,18)
+ TS2339: Property 'chosenColor' does not exist on type 'PatternTable'.
+
+ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx
+./src/PatternTable.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx(95,24)
+ TS2339: Property 'onUpdatePattern' does not exist on type 'Readonly<{ children?: ReactNode; }> & Readonly<{}>'.
+
+ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx
+./src/PatternTable.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx(95,54)
+ TS2339: Property 'activeColorPattern' does not exist on type 'PatternTable'.
+
+ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx
+./src/PatternTable.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx(96,35)
+ TS2339: Property 'chosenColor' does not exist on type 'PatternTable'.
+
+ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx
+./src/PatternTable.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx(100,17)
+ TS2339: Property 'classes' does not exist on type 'Readonly<{ children?: ReactNode; }> & Readonly<{}>'.
+
+ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx
+./src/PatternTable.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx(100,26)
+ TS2339: Property 'calendars' does not exist on type 'Readonly<{ children?: ReactNode; }> & Readonly<{}>'.
+
+ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx
+./src/PatternTable.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx(100,37)
+ TS2339: Property 'patterns' does not exist on type 'Readonly<{ children?: ReactNode; }> & Readonly<{}>'.
+
+ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx
+./src/PatternTable.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx(103,86)
+ TS7006: Parameter 'p' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx
+./src/PatternTable.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx(103,89)
+ TS7006: Parameter 'i' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx
+./src/PatternTable.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx(113,51)
+ TS2339: Property 'onRemovePattern' does not exist on type 'Readonly<{ children?: ReactNode; }> & Readonly<{}>'.
+
+ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx
+./src/PatternTable.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx(126,48)
+ TS7006: Parameter 'field' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx
+./src/PatternTable.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx(126,55)
+ TS7006: Parameter 'value' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx
+./src/PatternTable.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx(126,76)
+ TS2339: Property 'onUpdatePattern' does not exist on type 'Readonly<{ children?: ReactNode; }> & Readonly<{}>'.
+
+ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx
+./src/PatternTable.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx(127,51)
+ TS7006: Parameter 'event' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx
+./src/PatternTable.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx(128,46)
+ TS2339: Property 'activeColorPattern' does not exist on type 'PatternTable'.
+
+ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx
+./src/PatternTable.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx(158,35)
+ TS7006: Parameter 'color' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx
+./src/PatternTable.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx(160,34)
+ TS2339: Property 'chosenColor' does not exist on type 'PatternTable'.
+
+ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx
+./src/PatternTable.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx(200,14)
+ TS2339: Property 'propTypes' does not exist on type 'typeof PatternTable'.
+
+ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx
+./src/PatternTable.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/PatternTable.tsx(208,27)
+ TS2345: Argument of type '(theme: any) => { deleteButton: { width: number; position: string; marginRight: string; right: number; height: number; }; deleteButtonHide: { display: string; }; deleteButtonShow: {}; deleteIcon: { position: string; height: string; cursor: string; }; patternTableWrapper: { ...; }; patternTable: { ...; }; }' is not assignable to parameter of type 'StyleRulesCallback<"deleteButton" | "deleteButtonHide" | "deleteButtonShow" | "deleteIcon" | "patternTableWrapper" | "patternTable"> | Record<"deleteButton" | "deleteButtonHide" | "deleteButtonShow" | "deleteIcon" | "patternTableWrapper" | "patternTable", CSSProperties>'.
+ Type '(theme: any) => { deleteButton: { width: number; position: string; marginRight: string; right: number; height: number; }; deleteButtonHide: { display: string; }; deleteButtonShow: {}; deleteIcon: { position: string; height: string; cursor: string; }; patternTableWrapper: { ...; }; patternTable: { ...; }; }' is not assignable to type 'StyleRulesCallback<"deleteButton" | "deleteButtonHide" | "deleteButtonShow" | "deleteIcon" | "patternTableWrapper" | "patternTable">'.
+ Type '{ deleteButton: { width: number; position: string; marginRight: string; right: number; height: number; }; deleteButtonHide: { display: string; }; deleteButtonShow: {}; deleteIcon: { position: string; height: string; cursor: string; }; patternTableWrapper: { ...; }; patternTable: { ...; }; }' is not assignable to type 'Record<"deleteButton" | "deleteButtonHide" | "deleteButtonShow" | "deleteIcon" | "patternTableWrapper" | "patternTable", CSSProperties>'.
+ Types of property 'deleteButton' are incompatible.
+ Type '{ width: number; position: string; marginRight: string; right: number; height: number; }' is not assignable to type 'CSSProperties'.
+ Types of property 'position' are incompatible.
+ Type 'string' is not assignable to type 'PositionProperty'.
+
+ERROR in /home/ymf/work/chromicle/src/RegexField.tsx
+./src/RegexField.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/RegexField.tsx(10,16)
+ TS7006: Parameter 'theme' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/RegexField.tsx
+./src/RegexField.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/RegexField.tsx(21,17)
+ TS2339: Property 'classes' does not exist on type 'Readonly<{ children?: ReactNode; }> & Readonly<{}>'.
+
+ERROR in /home/ymf/work/chromicle/src/RegexField.tsx
+./src/RegexField.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/RegexField.tsx(23,33)
+ TS2339: Property 'options' does not exist on type 'Readonly<{ children?: ReactNode; }> & Readonly<{}>'.
+
+ERROR in /home/ymf/work/chromicle/src/RegexField.tsx
+./src/RegexField.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/RegexField.tsx(24,20)
+ TS7009: 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/RegexField.tsx
+./src/RegexField.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/RegexField.tsx(29,49)
+ TS2339: Property 'theme' does not exist on type 'Readonly<{ children?: ReactNode; }> & Readonly<{}>'.
+
+ERROR in /home/ymf/work/chromicle/src/RegexField.tsx
+./src/RegexField.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/RegexField.tsx(32,31)
+ TS7006: Parameter 'event' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/RegexField.tsx
+./src/RegexField.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/RegexField.tsx(36,32)
+ TS2339: Property 'value' does not exist on type 'Readonly<{ children?: ReactNode; }> & Readonly<{}>'.
+
+ERROR in /home/ymf/work/chromicle/src/RegexField.tsx
+./src/RegexField.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/RegexField.tsx(37,32)
+ TS2339: Property 'value' does not exist on type 'Readonly<{ children?: ReactNode; }> & Readonly<{}>'.
+
+ERROR in /home/ymf/work/chromicle/src/RegexField.tsx
+./src/RegexField.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/RegexField.tsx(38,36)
+ TS2339: Property 'value' does not exist on type 'Readonly<{ children?: ReactNode; }> & Readonly<{}>'.
+
+ERROR in /home/ymf/work/chromicle/src/RegexField.tsx
+./src/RegexField.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/RegexField.tsx(42,24)
+ TS2339: Property 'onChange' does not exist on type 'Readonly<{ children?: ReactNode; }> & Readonly<{}>'.
+
+ERROR in /home/ymf/work/chromicle/src/RegexField.tsx
+./src/RegexField.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/RegexField.tsx(45,35)
+ TS7006: Parameter 'event' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/RegexField.tsx
+./src/RegexField.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/RegexField.tsx(45,55)
+ TS2339: Property 'onChange' does not exist on type 'Readonly<{ children?: ReactNode; }> & Readonly<{}>'.
+
+ERROR in /home/ymf/work/chromicle/src/RegexField.tsx
+./src/RegexField.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/RegexField.tsx(48,38)
+ TS2339: Property 'value' does not exist on type 'Readonly<{ children?: ReactNode; }> & Readonly<{}>'.
+
+ERROR in /home/ymf/work/chromicle/src/RegexField.tsx
+./src/RegexField.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/RegexField.tsx(53,43)
+ TS2339: Property 'value' does not exist on type 'Readonly<{ children?: ReactNode; }> & Readonly<{}>'.
+
+ERROR in /home/ymf/work/chromicle/src/RegexField.tsx
+./src/RegexField.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/RegexField.tsx(57,33)
+ TS2339: Property 'value' does not exist on type 'Readonly<{ children?: ReactNode; }> & Readonly<{}>'.
+
+ERROR in /home/ymf/work/chromicle/src/RegexField.tsx
+./src/RegexField.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/RegexField.tsx(59,47)
+ TS2339: Property 'value' does not exist on type 'Readonly<{ children?: ReactNode; }> & Readonly<{}>'.
+
+ERROR in /home/ymf/work/chromicle/src/RegexField.tsx
+./src/RegexField.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/RegexField.tsx(67,12)
+ TS2339: Property 'propTypes' does not exist on type 'typeof RegexField'.
+
+ERROR in /home/ymf/work/chromicle/src/RegexField.tsx
+./src/RegexField.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/RegexField.tsx(73,31)
+ TS7006: Parameter 'props' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/RegexField.tsx
+./src/RegexField.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/RegexField.tsx(76,9)
+ TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
+
+ERROR in /home/ymf/work/chromicle/src/RegexField.tsx
+./src/RegexField.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/RegexField.tsx(81,10)
+ TS2322: Type '{ value: any; options: {}; onChange: (value: any) => any; theme: any; }' is not assignable to type 'IntrinsicAttributes & Pick<{}, never> & StyledComponentProps<"fieldNoRegex" | "fieldRegex"> & { children?: ReactNode; }'.
+ Property 'value' does not exist on type 'IntrinsicAttributes & Pick<{}, never> & StyledComponentProps<"fieldNoRegex" | "fieldRegex"> & { children?: ReactNode; }'.
+
+ERROR in /home/ymf/work/chromicle/src/RegexField.tsx
+./src/RegexField.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/RegexField.tsx(84,23)
+ TS7006: Parameter 'value' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/RegexField.tsx
+./src/RegexField.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/RegexField.tsx(88,28)
+ TS7006: Parameter 'props' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/RegexField.tsx
+./src/RegexField.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/RegexField.tsx(91,5)
+ TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
+
+ERROR in /home/ymf/work/chromicle/src/RegexField.tsx
+./src/RegexField.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/RegexField.tsx(93,10)
+ TS2322: Type '{ value: any; options: {}; onChange: (value: any) => any; theme: any; }' is not assignable to type 'IntrinsicAttributes & Pick<{}, never> & StyledComponentProps<"fieldNoRegex" | "fieldRegex"> & { children?: ReactNode; }'.
+ Property 'value' does not exist on type 'IntrinsicAttributes & Pick<{}, never> & StyledComponentProps<"fieldNoRegex" | "fieldRegex"> & { children?: ReactNode; }'.
+
+ERROR in /home/ymf/work/chromicle/src/RegexField.tsx
+./src/RegexField.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/RegexField.tsx(96,23)
+ TS7006: Parameter 'value' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(33,16)
+ TS7006: Parameter 'theme' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(63,22)
+ TS7006: Parameter 'old' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(63,27)
+ TS7006: Parameter 'onChange' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(63,40)
+ TS7006: Parameter 'event' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(67,21)
+ TS7006: Parameter 'old' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(67,26)
+ TS7006: Parameter 'onChange' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(67,39)
+ TS7006: Parameter 'event' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(81,20)
+ TS7006: Parameter 'value' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(89,15)
+ TS2339: Property 'classes' does not exist on type 'Readonly<{ children?: ReactNode; }> & Readonly<{}>'.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(89,24)
+ TS2339: Property 'fromDuration' does not exist on type 'Readonly<{ children?: ReactNode; }> & Readonly<{}>'.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(89,38)
+ TS2339: Property 'toDuration' does not exist on type 'Readonly<{ children?: ReactNode; }> & Readonly<{}>'.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(89,50)
+ TS2339: Property 'nameOnChange' does not exist on type 'Readonly<{ children?: ReactNode; }> & Readonly<{}>'.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(89,64)
+ TS2339: Property 'fromOnChange' does not exist on type 'Readonly<{ children?: ReactNode; }> & Readonly<{}>'.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(89,78)
+ TS2339: Property 'toOnChange' does not exist on type 'Readonly<{ children?: ReactNode; }> & Readonly<{}>'.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(89,90)
+ TS2339: Property 'name' does not exist on type 'Readonly<{ children?: ReactNode; }> & Readonly<{}>'.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(98,35)
+ TS2322: Type '{ textAlign: string; }' is not assignable to type 'CSSProperties'.
+ Types of property 'textAlign' are incompatible.
+ Type 'string' is not assignable to type 'TextAlignProperty'.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(103,34)
+ TS2322: Type '{ width: number; textAlign: string; }' is not assignable to type 'CSSProperties'.
+ Types of property 'textAlign' are incompatible.
+ Type 'string' is not assignable to type 'TextAlignProperty'.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(110,34)
+ TS2322: Type '{ width: number; textAlign: string; }' is not assignable to type 'CSSProperties'.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(123,9)
+ TS7018: Object literal's property 'patterns' implicitly has an 'any[]' type.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(133,17)
+ TS7006: Parameter 'props' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(137,14)
+ TS2339: Property 'msgClient' does not exist on type 'Settings'.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(139,14)
+ TS2339: Property 'msgClient' does not exist on type 'Settings'.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(142,17)
+ TS7006: Parameter 'msg' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(143,52)
+ TS7006: Parameter 'p' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(146,14)
+ TS2339: Property 'msgClient' does not exist on type 'Settings'.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(149,17)
+ TS7006: Parameter 'msg' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(153,14)
+ TS2339: Property 'msgClient' does not exist on type 'Settings'.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(156,17)
+ TS7006: Parameter 'msg' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(158,61)
+ TS7006: Parameter 'p' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(170,14)
+ TS2339: Property 'dialogPromiseResolver' does not exist on type 'Settings'.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(190,28)
+ TS7006: Parameter 'id' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(192,9)
+ TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(192,34)
+ TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(193,14)
+ TS2339: Property 'msgClient' does not exist on type 'Settings'.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(208,27)
+ TS7006: Parameter 'item' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(209,17)
+ TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(226,23)
+ TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(237,21)
+ TS7006: Parameter 'calendars' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(240,41)
+ TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(242,14)
+ TS2339: Property 'msgClient' does not exist on type 'Settings'.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(248,21)
+ TS7006: Parameter 'patterns' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(248,31)
+ TS7006: Parameter 'id' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(249,14)
+ TS2339: Property 'msgClient' does not exist on type 'Settings'.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(251,48)
+ TS7006: Parameter 'p' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(255,22)
+ TS7006: Parameter 'field' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(255,29)
+ TS7006: Parameter 'idx' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(255,34)
+ TS7006: Parameter 'value' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(258,9)
+ TS2554: Expected 2 arguments, but got 1.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(261,21)
+ TS7006: Parameter 'idx' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(266,9)
+ TS2554: Expected 2 arguments, but got 1.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(273,9)
+ TS2554: Expected 2 arguments, but got 1.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(276,28)
+ TS7006: Parameter 'event' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(276,35)
+ TS7006: Parameter 'reason' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(281,26)
+ TS7006: Parameter 'msg' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(285,25)
+ TS7006: Parameter 'title' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(285,32)
+ TS7006: Parameter 'message' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(287,18)
+ TS2339: Property 'dialogPromiseResolver' does not exist on type 'Settings'.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(293,25)
+ TS7006: Parameter 'result' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(294,14)
+ TS2339: Property 'dialogPromiseResolver' does not exist on type 'Settings'.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(298,28)
+ TS7006: Parameter 'trackedPeriods' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(299,14)
+ TS2339: Property 'msgClient' does not exist on type 'Settings'.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(301,56)
+ TS7006: Parameter 'p' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(309,30)
+ TS7006: Parameter 'idx' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(309,37)
+ TS7006: Parameter 'name' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(310,52)
+ TS2339: Property 'trackedPeriods' does not exist on type '{}'.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(315,30)
+ TS7006: Parameter 'idx' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(315,37)
+ TS7006: Parameter 'duration' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(316,52)
+ TS2339: Property 'trackedPeriods' does not exist on type '{}'.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(321,28)
+ TS7006: Parameter 'idx' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(321,35)
+ TS7006: Parameter 'duration' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(322,52)
+ TS2339: Property 'trackedPeriods' does not exist on type '{}'.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(328,17)
+ TS2339: Property 'classes' does not exist on type 'Readonly<{ children?: ReactNode; }> & Readonly<{}>'.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(376,53)
+ TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(378,63)
+ TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(413,51)
+ TS2339: Property 'trackedPeriods' does not exist on type '{}'.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(414,54)
+ TS2339: Property 'trackedPeriods' does not exist on type '{}'.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(414,74)
+ TS7006: Parameter 'p' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(414,77)
+ TS7006: Parameter 'idx' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(416,37)
+ TS2322: Type '{ name: any; fromDuration: any; toDuration: any; nameOnChange: (name: any) => void; fromOnChange: (duration: any) => void; toOnChange: (duration: any) => void; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<TrackedPeriod> & Readonly<{ children?: ReactNode; }> & Readonly<{}>'.
+ Property 'name' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<TrackedPeriod> & Readonly<{ children?: ReactNode; }> & Readonly<{}>'.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(433,10)
+ TS2339: Property 'propTypes' does not exist on type 'typeof Settings'.
+
+ERROR in /home/ymf/work/chromicle/src/Settings.tsx
+./src/Settings.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Settings.tsx(437,27)
+ TS2345: Argument of type '(theme: any) => { tableHead: { verticalAlign: string; textAlign: string; lineHeight: string; }; tableContent: { textAlign: string; maxWidth: number; }; calendarList: { maxHeight: number; overflowY: string; }; }' is not assignable to parameter of type 'StyleRulesCallback<"tableHead" | "tableContent" | "calendarList"> | Record<"tableHead" | "tableContent" | "calendarList", CSSProperties>'.
+ Type '(theme: any) => { tableHead: { verticalAlign: string; textAlign: string; lineHeight: string; }; tableContent: { textAlign: string; maxWidth: number; }; calendarList: { maxHeight: number; overflowY: string; }; }' is not assignable to type 'StyleRulesCallback<"tableHead" | "tableContent" | "calendarList">'.
+ Type '{ tableHead: { verticalAlign: string; textAlign: string; lineHeight: string; }; tableContent: { textAlign: string; maxWidth: number; }; calendarList: { maxHeight: number; overflowY: string; }; }' is not assignable to type 'Record<"tableHead" | "tableContent" | "calendarList", CSSProperties>'.
+ Types of property 'tableHead' are incompatible.
+ Type '{ verticalAlign: string; textAlign: string; lineHeight: string; }' is not assignable to type 'CSSProperties'.
+ Types of property 'textAlign' are incompatible.
+ Type 'string' is not assignable to type 'TextAlignProperty'.
+
+ERROR in /home/ymf/work/chromicle/src/Snackbar.tsx
+./src/Snackbar.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Snackbar.tsx(3,24)
+ TS7016: Could not find a declaration file for module 'classnames'. '/home/ymf/work/chromicle/node_modules/classnames/index.js' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Snackbar.tsx
+./src/Snackbar.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Snackbar.tsx(20,16)
+ TS7006: Parameter 'theme' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Snackbar.tsx
+./src/Snackbar.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Snackbar.tsx(40,25)
+ TS7006: Parameter 'props' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/Snackbar.tsx
+./src/Snackbar.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/Snackbar.tsx(42,18)
+ TS7017: Element implicitly has an 'any' type because type '{ error: ComponentType<SvgIconProps>; warning: ComponentType<SvgIconProps>; }' has no index signature.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(2,10)
+ TS2724: Module '"./msg"' has no exported member 'msgType'. Did you mean 'MsgType'?
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(9,5)
+ TS7034: Variable 'analyzePatterns' implicitly has type 'any[]' in some locations where its type cannot be determined.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(19,5)
+ TS7034: Variable 'mainGraphData' implicitly has type 'any[]' in some locations where its type cannot be determined.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(34,65)
+ TS7006: Parameter 'p' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(41,51)
+ TS7006: Parameter 'p' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(42,57)
+ TS7006: Parameter 'p' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(58,47)
+ TS2339: Property 'deflate' does not exist on type 'number'.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(59,26)
+ TS7005: Variable 'analyzePatterns' implicitly has an 'any[]' type.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(66,23)
+ TS7006: Parameter 'id' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(66,27)
+ TS7006: Parameter 'start' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(66,34)
+ TS7006: Parameter 'end' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(68,9)
+ TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(68,46)
+ TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(69,12)
+ TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(70,16)
+ TS7006: Parameter 'e' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(70,16)
+ TS7011: Function expression, which lacks return-type annotation, implicitly has an 'any[]' return type.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(72,13)
+ TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(79,17)
+ TS7005: Variable 'mainGraphData' implicitly has an 'any[]' type.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(104,14)
+ TS7006: Parameter 'id' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(104,18)
+ TS7006: Parameter 'start' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(104,24)
+ TS7006: Parameter 'end' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(104,66)
+ TS7006: Parameter 'd' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(104,77)
+ TS7006: Parameter 'e' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(135,21)
+ TS2339: Property 'type' does not exist on type 'Msg<{}>'.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(137,37)
+ TS2339: Property 'patterns' does not exist on type '{}'.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(137,50)
+ TS7006: Parameter 'p' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(138,26)
+ TS2339: Property 'id' does not exist on type '{}'.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(148,26)
+ TS2339: Property 'id' does not exist on type '{}'.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(149,28)
+ TS7005: Variable 'analyzePatterns' implicitly has an 'any[]' type.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(163,26)
+ TS2339: Property 'enabledOnly' does not exist on type '{}'.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(166,35)
+ TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(167,43)
+ TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(167,53)
+ TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(173,35)
+ TS2339: Property 'id' does not exist on type '{}'.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(173,48)
+ TS2339: Property 'start' does not exist on type '{}'.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(173,64)
+ TS2339: Property 'end' does not exist on type '{}'.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(173,74)
+ TS7006: Parameter 'data' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(175,49)
+ TS7006: Parameter 'e' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(188,46)
+ TS2339: Property 'trackedPeriods' does not exist on type '{}'.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(188,65)
+ TS7006: Parameter 'p' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(199,22)
+ TS2339: Property 'forEach' does not exist on type '{}'.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(199,30)
+ TS7006: Parameter 'prop' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(199,38)
+ TS7017: Element implicitly has an 'any' type because type '{}' has no index signature.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(199,50)
+ TS7017: Element implicitly has an 'any' type because type '{ trackedPeriods: { name: string; start: Duration; end: Duration; }[]; }' has no index signature.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(204,13)
+ TS2349: Cannot invoke an expression whose type lacks a call signature. Type '(<TResult1 = void, TResult2 = never>(onfulfilled?: (value: void) => TResult1 | PromiseLike<TResult1>, onrejected?: (reason: any) => TResult2 | PromiseLike<TResult2>) => Promise<TResult1 | TResult2>) | (<TResult1 = void[], TResult2 = never>(onfulfilled?: (value: void[]) => TResult1 | PromiseLike<...>, onrejected?: (r...' has no compatible call signatures.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(204,23)
+ TS2339: Property 'sync' does not exist on type '{}'.
+
+ERROR in /home/ymf/work/chromicle/src/background.ts
+./src/background.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/background.ts(205,46)
+ TS7005: Variable 'mainGraphData' implicitly has an 'any[]' type.
+
+ERROR in /home/ymf/work/chromicle/src/gapi.ts
+./src/gapi.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/gapi.ts(146,12)
+ TS2709: Cannot use namespace 'LRU' as a type.
+
+ERROR in /home/ymf/work/chromicle/src/gapi.ts
+./src/gapi.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/gapi.ts(156,22)
+ TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature.
+
+ERROR in /home/ymf/work/chromicle/src/gapi.ts
+./src/gapi.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/gapi.ts(158,23)
+ TS7006: Parameter 'k' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/gapi.ts
+./src/gapi.ts
+[tsl] ERROR in /home/ymf/work/chromicle/src/gapi.ts(158,26)
+ TS7006: Parameter 'v' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/index.tsx
+./src/index.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/index.tsx(2,22)
+ TS7016: Could not find a declaration file for module 'react-dom'. '/home/ymf/work/chromicle/node_modules/react-dom/index.js' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/popup.tsx
+./src/popup.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/popup.tsx(2,22)
+ TS7016: Could not find a declaration file for module 'react-dom'. '/home/ymf/work/chromicle/node_modules/react-dom/index.js' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/popup.tsx
+./src/popup.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/popup.tsx(22,16)
+ TS7006: Parameter 'theme' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/popup.tsx
+./src/popup.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/popup.tsx(39,9)
+ TS7018: Object literal's property 'patternGraphData' implicitly has an 'any[]' type.
+
+ERROR in /home/ymf/work/chromicle/src/popup.tsx
+./src/popup.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/popup.tsx(42,17)
+ TS7006: Parameter 'props' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/popup.tsx
+./src/popup.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/popup.tsx(44,14)
+ TS2339: Property 'msgClient' does not exist on type 'Popup'.
+
+ERROR in /home/ymf/work/chromicle/src/popup.tsx
+./src/popup.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/popup.tsx(45,14)
+ TS2339: Property 'loading' does not exist on type 'Popup'.
+
+ERROR in /home/ymf/work/chromicle/src/popup.tsx
+./src/popup.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/popup.tsx(49,19)
+ TS7006: Parameter 'sync' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/popup.tsx
+./src/popup.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/popup.tsx(50,21)
+ TS2339: Property 'msgClient' does not exist on type 'Popup'.
+
+ERROR in /home/ymf/work/chromicle/src/popup.tsx
+./src/popup.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/popup.tsx(53,17)
+ TS7006: Parameter 'msg' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/popup.tsx
+./src/popup.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/popup.tsx(54,60)
+ TS7006: Parameter 'd' implicitly has an 'any' type.
+
+ERROR in /home/ymf/work/chromicle/src/popup.tsx
+./src/popup.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/popup.tsx(64,15)
+ TS2339: Property 'classes' does not exist on type 'Readonly<{ children?: ReactNode; }> & Readonly<{}>'.
+
+ERROR in /home/ymf/work/chromicle/src/popup.tsx
+./src/popup.tsx
+[tsl] ERROR in /home/ymf/work/chromicle/src/popup.tsx(95,35)
+ TS7006: Parameter 'dd' implicitly has an 'any' type.
+Child HtmlWebpackCompiler:
+ 1 asset
+ Entrypoint HtmlWebpackPlugin_0 = __child-HtmlWebpackPlugin_0
+ [./node_modules/html-webpack-plugin/lib/loader.js!./src/index.html] 687 bytes {HtmlWebpackPlugin_0} [built]
+ [./node_modules/webpack/buildin/global.js] (webpack)/buildin/global.js 472 bytes {HtmlWebpackPlugin_0} [built]
+ [./node_modules/webpack/buildin/module.js] (webpack)/buildin/module.js 497 bytes {HtmlWebpackPlugin_0} [built]
+ + 1 hidden module
diff --git a/webpack.config.js b/webpack.config.js
index 49261a0..da6d978 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -5,20 +5,29 @@ module.exports = (env, argv) => {
const prodMode = argv.mode == 'production';
return {
entry: {
- index: "./src/index.js",
- background: "./src/background.js",
- popup: "./src/popup.js"
+ index: "./src/index.tsx",
+ background: "./src/background.ts",
+ popup: "./src/popup.tsx"
},
output: {
path: path.join(__dirname, "/dist"),
filename: "[name].js"
},
+ resolve: {
+ extensions: [".ts", ".tsx", ".js", ".json"]
+ },
+ devtool: "source-map",
module: {
rules: [
{
- test: /\.js$/,
+ test: /\.tsx?$/,
exclude: /node_modules/,
- use: ['babel-loader', 'eslint-loader']
+ use: ['ts-loader']
+ },
+ {
+ test: /\.js$/,
+ use: ["source-map-loader"],
+ enforce: "pre"
},
{
test: /\.css$/,