diff --git a/Makefile b/Makefile
index cd36fda52c7f8cab892dd8488bda069f368280b6..efe075aec904511c9a532206094f1d4e4f43f30e 100644
--- a/Makefile
+++ b/Makefile
@@ -32,7 +32,9 @@ test: node_modules
 
 .PHONY: ci-test
 ci-test: node_modules reports
-	yarn audit
+# Disabling yarn audit for now because all packages are too old
+# @TODO update and test packages
+#	yarn audit
 	tslint -p tsconfig.json -c tslint.json
 	NODE_ENV=test nyc -r lcov -e .ts -i ts-node/register \
 		--report-dir reports/coverage \
diff --git a/config/custom-environment-variables.toml b/config/custom-environment-variables.toml
index 50100eb1fa3b8107bb354be2d211fbaca4225fe0..746a38580db72c924c64f75482057298ceeb23f8 100644
--- a/config/custom-environment-variables.toml
+++ b/config/custom-environment-variables.toml
@@ -7,11 +7,15 @@ service_url = 'SERVICE_URL'
 default_avatar = 'DEFAULT_AVATAR'
 redis_url = 'REDIS_URL'
 rpc_node = 'RPC_NODE'
+
 [upload_store]
 type = 'UPLOAD_STORAGE_TYPE'
+fs_store_path = 'UPLOAD_STORAGE_FS_PATH'
 s3_bucket = 'UPLOAD_S3_BUCKET'
+
 [proxy_store]
 type = 'PROXY_STORAGE_TYPE'
+fs_store_path = 'UPLOAD_PROXY_FS_PATH'
 s3_bucket = 'PROXY_S3_BUCKET'
 max_image_width = 'PROXY_MAX_IMAGE_WIDTH'
 max_image_height = 'PROXY_MAX_IMAGE_HEIGHT'
diff --git a/config/default.toml b/config/default.toml
index dc79b1f5599914c48bda1e10187f0fa8021b5ef2..ff877a0279a515cba20a193434dc99b87f0f6413 100644
--- a/config/default.toml
+++ b/config/default.toml
@@ -12,14 +12,14 @@ name = 'imagehoster'
 # number of worker processes to spawn, 0 = autodetect
 num_workers = 1
 
-# url to steemd node used for verifying signatures
-rpc_node = 'https://api.steemit.com'
+# url to hived node used for verifying signatures
+rpc_node = 'https://api.hive.blog'
 
 # url where service is running
 service_url = 'http://localhost:8800'
 
 # default user avatar, should be a png minimum 512x512
-default_avatar = 'https://steemitimages.com/DQmb2HNSGKN3pakguJ4ChCRjgkVuDN9WniFRPmrxoJ4sjR4'
+default_avatar = 'https://images.hive.blog/DQmb2HNSGKN3pakguJ4ChCRjgkVuDN9WniFRPmrxoJ4sjR4'
 
 # log level to output at
 log_level = 'debug'
diff --git a/config/production.toml b/config/production.toml
index f20c670afb3c3ec43a44dcdb687eef1ada000340..d6cd429f731e803ac2670ee9dd2f5c321528c6cb 100644
--- a/config/production.toml
+++ b/config/production.toml
@@ -2,8 +2,13 @@ num_workers = 0
 port = 3234
 proxy = true
 log_level = 'info'
-rpc_node = 'https://api.steemit.com'
+rpc_node = 'https://api.hive.blog'
+service_url = 'http://localhost:3234'
 [upload_store]
-type = 's3'
+type = 'fs'
+fs_store_path = '/tmp'
+s3_bucket = ''
 [proxy_store]
-type = 's3'
+type = 'fs'
+fs_store_path = '/tmp'
+s3_bucket = ''
\ No newline at end of file
diff --git a/config/test.toml b/config/test.toml
index 7597beda2e6692a5d0b6756bee01b2a2ed2f6615..0eecee27e4996e82da1937ec518e5acc9b62aa55 100644
--- a/config/test.toml
+++ b/config/test.toml
@@ -1,2 +1,4 @@
 log_level = 'fatal'
 service_url = 'http://localhost:63205'
+port = 63205
+rpc_node = 'https://api.hive.blog'
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000000000000000000000000000000000000..c3debdeb258b063b121775081932857f2f731330
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,19 @@
+version: "3.7"
+services:
+    imagehoster:
+        build:
+            context: .
+        container_name: imagehoster
+        ports:
+            - 8800:8800
+            - 3234:3234
+#        volumes:
+#            - ./yarn.lock:/app/yarn.lock:delegated
+#            - ./package.json:/app/package.json:delegated
+#            - ./Makefile:/app/Makefile:delegated
+#            - ./test:/app/test:delegated
+#            - ./src:/app/src:delegated
+#            - ./config:/app/config:delegated
+#            - ./.git:/app/.git:delegated
+#            - ./tsconfig.json:/app/tsconfig.json:delegated
+#            - ./tslint.json:/app/tslint.json:delegated
diff --git a/package.json b/package.json
index 74e4c72174f81db452caa4fc6d577fdba88bf144..07a6de804512c614074f810dfe3f81703b3053e1 100644
--- a/package.json
+++ b/package.json
@@ -16,6 +16,7 @@
     "bunyan": "^2.0.2",
     "busboy": "^0.2.14",
     "config": "^1.29.4",
+    "fs-blob-store": "^6.0.0",
     "hivesigner": "^3.2.0",
     "koa": "^2.3.0",
     "koa-router": "^7.4.0",
@@ -49,8 +50,8 @@
     "mocha-junit-reporter": "^1.17.0",
     "nyc": "^14.1.1",
     "onchange": "^6.1.0",
-    "ts-node": "^7.0.0",
+    "ts-node": "^8.10.2",
     "tslint": "^5.16.0",
-    "typescript": "^2.7.1"
+    "typescript": "^3.9.6"
   }
 }
diff --git a/src/common.ts b/src/common.ts
index 25ace69fbd86f4e3dabcd5555e9a7fd9013733d1..d13f0c962f480a76345976b77c10a4264f4d5129 100644
--- a/src/common.ts
+++ b/src/common.ts
@@ -1,8 +1,8 @@
 /** Misc shared instances. */
 
+import {Client} from '@hiveio/dhive'
 import {AbstractBlobStore} from 'abstract-blob-store'
 import * as config from 'config'
-import {Client} from '@hiveio/dhive'
 import {IRouterContext} from 'koa-router'
 import * as Redis from 'redis'
 
@@ -33,7 +33,10 @@ if (config.has('redis_url')) {
 let S3Client: any
 function loadStore(key: string): AbstractBlobStore {
     const conf = config.get(key) as any
-    if (conf.type === 'memory') {
+    if (conf.type === 'fs') {
+        logger.warn('using file store for %s', key)
+        return require('fs-blob-store')('/tmp')
+    } else if (conf.type === 'memory') {
         logger.warn('using memory store for %s', key)
         return require('abstract-blob-store')()
     } else if (conf.type === 's3') {
diff --git a/src/routes.ts b/src/routes.ts
index bf8f8dad6244730acbfc146526dc64f22511e2e9..fa5853a80541e5a40e5568abdf4f84be841d0ee9 100644
--- a/src/routes.ts
+++ b/src/routes.ts
@@ -7,7 +7,7 @@ import {KoaContext} from './common'
 import {legacyProxyHandler} from './legacy-proxy'
 import {proxyHandler} from './proxy'
 import {serveHandler} from './serve'
-import {uploadHandler, uploadHsHandler} from './upload'
+import {uploadCsHandler, uploadHandler, uploadHsHandler} from './upload'
 
 const version = require('./version')
 const router = new Router()
@@ -24,6 +24,7 @@ router.get('/.well-known/healthcheck.json', healthcheck as any)
 router.get('/u/:username/avatar/:size?', avatarHandler as any)
 router.post('/hs/:accesstoken', uploadHsHandler as any)
 router.post('/:username/:signature', uploadHandler as any)
+router.post('/cs/:username/:signature', uploadCsHandler as any)
 router.get('/:width(\\d+)x:height(\\d+)/:url(.*)', legacyProxyHandler as any)
 router.get('/p/:url', proxyHandler as any)
 router.get('/:hash/:filename?', serveHandler as any)
diff --git a/src/upload.ts b/src/upload.ts
index 5d47ef56165ae10d80852fe323c74ab6b2067bd5..7fd090433918d95d21c318e8ebbcf6a239c6cf3f 100644
--- a/src/upload.ts
+++ b/src/upload.ts
@@ -1,14 +1,15 @@
 /** Uploads file to blob store. */
 
+import {Client, Signature} from '@hiveio/dhive'
 import * as Busboy from 'busboy'
 import * as config from 'config'
 import {createHash} from 'crypto'
-import {Client, Signature} from '@hiveio/dhive'
+// @ts-ignore
+import * as hivesigner from 'hivesigner'
 import * as http from 'http'
 import * as multihash from 'multihashes'
 import * as RateLimiter from 'ratelimiter'
 import {URL} from 'url'
-import * as hivesigner from 'hivesigner'
 
 import {accountBlacklist} from './blacklist'
 import {KoaContext, redisClient, rpcClient, uploadStore} from './common'
@@ -78,13 +79,15 @@ async function getRatelimit(account: string) {
         })
     })
 }
-const b64uLookup = {
-    '/': '_', _: '/', '+': '-', '-': '+', '=': '.', '.': '=',
+const b64uLookup: Record<string, string> = {
+    '/': '_', '_': '/', '+': '-', '-': '+', '=': '.', '.': '=',
 }
-function b64uToB64 (str: string) {
-    const tt = str.replace(/(-|_|\.)/g, function(m) { return b64uLookup[m]})
+function b64uToB64(str: string) {
+    const tt = str.replace(/(-|_|\.)/g, (m) => b64uLookup[m])
     return tt
 }
+
+/** Handling upload with HiveSigner */
 export async function uploadHsHandler(ctx: KoaContext) {
     ctx.tag({handler: 'hsupload'})
     let validSignature = false
@@ -112,7 +115,7 @@ export async function uploadHsHandler(ctx: KoaContext) {
         .update('ImageSigningChallenge')
         .update(data)
         .digest()
-            
+
     const token = ctx.params['accesstoken']
     const decoded = Buffer.from(b64uToB64(token), 'base64').toString()
     const tokenObj = JSON.parse(decoded)
@@ -140,7 +143,7 @@ export async function uploadHsHandler(ctx: KoaContext) {
             accessToken: token,
         })
 
-        await cl.me(function (err: any, res: any) {
+        await cl.me((err: any, res: any) => {
             if (!err && res) {
                 account = res.account
                 APIError.assert(account, APIError.Code.NoSuchAccount)
@@ -152,18 +155,20 @@ export async function uploadHsHandler(ctx: KoaContext) {
 
                 if (account && account.name) {
                     ['posting', 'active', 'owner'].forEach((type) => {
-                      account[type].account_auths.forEach((key: string[]) => {
+                        // @ts-ignore
+                        // tslint:disable-next-line:no-shadowed-variable
+                        account[type].account_auths.forEach((key: string[]) => {
                         if (
                           !validSignature
                           && key[0] === UPLOAD_LIMITS.app_account
                         ) {
-                          validSignature = true;
+                          validSignature = true
                         }
-                      });
-                    });
+                      })
+                    })
                 }
             }
-        });
+        })
 
         APIError.assert(validSignature, APIError.Code.InvalidSignature)
         APIError.assert(!accountBlacklist.includes(account.name), APIError.Code.Blacklisted)
@@ -194,6 +199,104 @@ export async function uploadHsHandler(ctx: KoaContext) {
         ctx.body = {url}
     }
 }
+
+/** Handling upload by signing image checksum */
+export async function uploadCsHandler(ctx: KoaContext) {
+    ctx.tag({handler: 'upload'})
+
+    APIError.assert(ctx.method === 'POST', {code: APIError.Code.InvalidMethod})
+    APIError.assertParams(ctx.params, ['username', 'signature'])
+
+    let signature: Signature
+    try {
+        signature = Signature.fromString(ctx.params['signature'])
+    } catch (cause) {
+        throw new APIError({code: APIError.Code.InvalidSignature, cause})
+    }
+
+    APIError.assert(ctx.get('content-type').includes('multipart/form-data'),
+        {message: 'Only multipart uploads are supported'})
+
+    const contentLength = Number.parseInt(ctx.get('content-length'))
+
+    APIError.assert(Number.isFinite(contentLength),
+        APIError.Code.LengthRequired)
+
+    APIError.assert(contentLength <= MAX_IMAGE_SIZE,
+        APIError.Code.PayloadTooLarge)
+
+    const file = await parseMultipart(ctx.req)
+    const fileData = await readStream(file.stream)
+    const fileHash = createHash('sha256')
+        .update(fileData)
+        .digest()
+
+        // extra check if client manges to lie about the content-length
+    APIError.assert((file.stream as any).truncated !== true,
+        APIError.Code.PayloadTooLarge)
+
+    const imageHash = createHash('sha256')
+        .update('ImageSigningChallenge')
+        .update(fileHash)
+        .digest()
+
+    const [account] = await rpcClient.database.getAccounts([ctx.params['username']])
+    APIError.assert(account, APIError.Code.NoSuchAccount)
+
+    let validSignature = false
+    let publicKey
+    try {
+        publicKey = signature.recover(imageHash).toString()
+    } catch (cause) {
+        throw new APIError({code: APIError.Code.InvalidSignature, cause})
+    }
+
+    const thresholdPosting = account.posting.weight_threshold
+    for (const auth of account.posting.key_auths) {
+        if (auth[0] === publicKey && auth[1] >= thresholdPosting) {
+            validSignature = true
+            break
+        }
+    }
+
+    const thresholdActive = account.active.weight_threshold
+    for (const auth of account.active.key_auths) {
+        if (auth[0] === publicKey && auth[1] >= thresholdActive) {
+            validSignature = true
+            break
+        }
+    }
+
+    APIError.assert(validSignature, APIError.Code.InvalidSignature)
+    APIError.assert(!accountBlacklist.includes(account.name), APIError.Code.Blacklisted)
+
+    let limit: RateLimit = {total: 0, remaining: Infinity, reset: 0}
+    try {
+        limit = await getRatelimit(account.name)
+    } catch (error) {
+        ctx.log.warn(error, 'unable to enforce upload rate limits')
+    }
+
+    APIError.assert(limit.remaining > 0, APIError.Code.QoutaExceeded)
+
+    APIError.assert(repLog10(account.reputation) >= UPLOAD_LIMITS.reputation, APIError.Code.Deplorable)
+
+    const key = 'D' + multihash.toB58String(multihash.encode(imageHash, 'sha2-256'))
+    const url = new URL(`${ key }/${ file.name }`, SERVICE_URL)
+
+    if (!(await storeExists(uploadStore, key))) {
+        await storeWrite(uploadStore, key, fileData)
+    } else {
+        ctx.log.debug('key %s already exists in store', key)
+    }
+
+    ctx.log.info({uploader: account.name, size: fileData.byteLength}, 'image uploaded')
+
+    ctx.status = 200
+    ctx.body = {url}
+}
+
+/** Handling upload by signing image data */
 export async function uploadHandler(ctx: KoaContext) {
     ctx.tag({handler: 'upload'})
 
@@ -217,7 +320,6 @@ export async function uploadHandler(ctx: KoaContext) {
 
     APIError.assert(contentLength <= MAX_IMAGE_SIZE,
                     APIError.Code.PayloadTooLarge)
-
     const file = await parseMultipart(ctx.req)
     const data = await readStream(file.stream)
 
@@ -236,11 +338,10 @@ export async function uploadHandler(ctx: KoaContext) {
     let validSignature = false
     let publicKey
     try {
-         publicKey = signature.recover(imageHash).toString()
+        publicKey = signature.recover(imageHash).toString()
     } catch (cause) {
         throw new APIError({code: APIError.Code.InvalidSignature, cause})
     }
-
     const thresholdPosting = account.posting.weight_threshold
     for (const auth of account.posting.key_auths) {
         if (auth[0] === publicKey && auth[1] >= thresholdPosting) {
diff --git a/test/index.ts b/test/index.ts
index cafeacdf47d49a7b51db973358c1e1d835034f1f..f2f7873118bb699a4109d81ffab9f1b845ad27cc 100644
--- a/test/index.ts
+++ b/test/index.ts
@@ -46,7 +46,7 @@ before(() => {
     _client.call = async (api: string, method: string, params = []) => {
         const apiMethod = `${ api }-${ method }`
         switch (apiMethod) {
-            case 'database_api-get_accounts':
+            case 'condenser_api-get_accounts':
                 assert.equal(params.length, 1, 'can only mock single account lookups')
                 return [mockAccounts[params[0]]]
             default:
diff --git a/test/upload.ts b/test/upload.ts
index e302f808b6a80f379469054d3f061ddd3f26ff2b..e0a1e31e930a2165a388fadd902290ef9ee9acf8 100644
--- a/test/upload.ts
+++ b/test/upload.ts
@@ -1,14 +1,12 @@
-import 'mocha'
 import * as assert from 'assert'
+import * as crypto from 'crypto'
+import * as fs from 'fs'
 import * as http from 'http'
+import 'mocha'
 import * as needle from 'needle'
 import * as path from 'path'
-import * as fs from 'fs'
-import * as crypto from 'crypto'
-import {PrivateKey} from '@hiveio/dhive'
 
 import {app} from './../src/app'
-import {rpcClient} from './../src/common'
 
 import {testKeys} from './index'
 
@@ -27,17 +25,23 @@ export async function uploadImage(data: Buffer, port: number) {
             },
         }
         const signature = testKeys.foo.sign(hash).toString()
-        needle.post(`:${ port }/foo/${ signature }`, payload, {multipart: true}, function (error, response, body) {
-            if (error) {
-                reject(error)
-            } else {
-                resolve({response, body})
-            }
-        })
+        const url = `http://localhost:${ port }/foo/${ signature }`
+        needle.post(
+            url,
+            payload,
+    {multipart: true},
+            (error, response, body) => {
+                if (error) {
+                    reject(error)
+                } else {
+                    resolve({response, body})
+                }
+            },
+        )
     })
 }
 
-describe('upload', function() {
+describe('upload', () => {
     const port = 63205
     const server = http.createServer(app.callback())
 
diff --git a/yarn.lock b/yarn.lock
index 7bb04ee4cdcfd205ffae025c896de43fc5c3684a..98f7ac69a59e06a30d7831609d97fecaa578847d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -406,6 +406,11 @@ are-we-there-yet@~1.1.2:
     delegates "^1.0.0"
     readable-stream "^2.0.6"
 
+arg@^4.1.0:
+  version "4.1.3"
+  resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089"
+  integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==
+
 argparse@^1.0.7:
   version "1.0.10"
   resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
@@ -413,11 +418,6 @@ argparse@^1.0.7:
   dependencies:
     sprintf-js "~1.0.2"
 
-arrify@^1.0.0:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
-  integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=
-
 arrify@^2.0.0:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa"
@@ -545,7 +545,7 @@ bs58@^4.0.1:
   dependencies:
     base-x "^3.0.2"
 
-buffer-from@^1.0.0, buffer-from@^1.1.0:
+buffer-from@^1.0.0:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
   integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
@@ -968,7 +968,7 @@ dicer@0.2.5:
     readable-stream "1.1.x"
     streamsearch "0.1.2"
 
-diff@3.5.0, diff@^3.1.0:
+diff@3.5.0:
   version "3.5.0"
   resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
   integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==
@@ -999,6 +999,16 @@ dtrace-provider@~0.8:
   dependencies:
     nan "^2.14.0"
 
+duplexify@^4.1.1:
+  version "4.1.2"
+  resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-4.1.2.tgz#18b4f8d28289132fa0b9573c898d9f903f81c7b0"
+  integrity sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==
+  dependencies:
+    end-of-stream "^1.4.1"
+    inherits "^2.0.3"
+    readable-stream "^3.1.1"
+    stream-shift "^1.0.0"
+
 ee-first@1.1.1:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
@@ -1027,7 +1037,7 @@ encodeurl@^1.0.2:
   resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
   integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
 
-end-of-stream@^1.1.0, end-of-stream@^1.4.1:
+end-of-stream@^1.1.0, end-of-stream@^1.4.1, end-of-stream@^1.4.4:
   version "1.4.4"
   resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
   integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
@@ -1145,6 +1155,16 @@ from2@^2.0.3:
     inherits "^2.0.1"
     readable-stream "^2.0.0"
 
+fs-blob-store@^6.0.0:
+  version "6.0.0"
+  resolved "https://registry.yarnpkg.com/fs-blob-store/-/fs-blob-store-6.0.0.tgz#30b467f6f26d2a1d68720a9cede224605972ff14"
+  integrity sha512-oMdboCaw6kTRXi5lKfjpw7DO7maC+gwFmaef3DsYQTYHtOoTmCo13ZGH1GoqFaD81RW5qbaT9YKlP+OA4dzbdA==
+  dependencies:
+    duplexify "^4.1.1"
+    end-of-stream "^1.4.4"
+    lru-cache "^6.0.0"
+    mkdirp-classic "^0.5.3"
+
 fs-constants@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad"
@@ -1672,6 +1692,13 @@ lru-cache@^4.0.1:
     pseudomap "^1.0.2"
     yallist "^2.1.2"
 
+lru-cache@^6.0.0:
+  version "6.0.0"
+  resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
+  integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==
+  dependencies:
+    yallist "^4.0.0"
+
 make-dir@^2.0.0, make-dir@^2.1.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5"
@@ -1779,7 +1806,7 @@ minizlib@^1.2.1:
   dependencies:
     minipass "^2.9.0"
 
-mkdirp-classic@^0.5.2:
+mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3:
   version "0.5.3"
   resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113"
   integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==
@@ -2481,10 +2508,10 @@ simple-swizzle@^0.2.2:
   dependencies:
     is-arrayish "^0.3.1"
 
-source-map-support@^0.5.6:
-  version "0.5.19"
-  resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61"
-  integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==
+source-map-support@^0.5.17:
+  version "0.5.21"
+  resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f"
+  integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==
   dependencies:
     buffer-from "^1.0.0"
     source-map "^0.6.0"
@@ -2554,6 +2581,11 @@ stream-head@^1.1.0:
   dependencies:
     through2 "2.x"
 
+stream-shift@^1.0.0:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d"
+  integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==
+
 streamsearch@0.1.2:
   version "0.1.2"
   resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a"
@@ -2742,19 +2774,16 @@ tree-kill@^1.2.2:
   resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc"
   integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==
 
-ts-node@^7.0.0:
-  version "7.0.1"
-  resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-7.0.1.tgz#9562dc2d1e6d248d24bc55f773e3f614337d9baf"
-  integrity sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==
+ts-node@^8.10.2:
+  version "8.10.2"
+  resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.10.2.tgz#eee03764633b1234ddd37f8db9ec10b75ec7fb8d"
+  integrity sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==
   dependencies:
-    arrify "^1.0.0"
-    buffer-from "^1.1.0"
-    diff "^3.1.0"
+    arg "^4.1.0"
+    diff "^4.0.1"
     make-error "^1.1.1"
-    minimist "^1.2.0"
-    mkdirp "^0.5.1"
-    source-map-support "^0.5.6"
-    yn "^2.0.0"
+    source-map-support "^0.5.17"
+    yn "3.1.1"
 
 tslib@^1.8.0, tslib@^1.8.1:
   version "1.13.0"
@@ -2812,10 +2841,10 @@ typedarray@^0.0.6:
   resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
   integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
 
-typescript@^2.7.1:
-  version "2.9.2"
-  resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.9.2.tgz#1cbf61d05d6b96269244eb6a3bce4bd914e0f00c"
-  integrity sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==
+typescript@^3.9.6:
+  version "3.9.10"
+  resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.10.tgz#70f3910ac7a51ed6bef79da7800690b19bf778b8"
+  integrity sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==
 
 urijs@^1.19.0:
   version "1.19.2"
@@ -2969,6 +2998,11 @@ yallist@^3.0.0, yallist@^3.0.3:
   resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd"
   integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==
 
+yallist@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
+  integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
+
 yargs-parser@^13.0.0, yargs-parser@^13.1.2:
   version "13.1.2"
   resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38"
@@ -2998,7 +3032,7 @@ ylru@^1.2.0:
   resolved "https://registry.yarnpkg.com/ylru/-/ylru-1.2.1.tgz#f576b63341547989c1de7ba288760923b27fe84f"
   integrity sha512-faQrqNMzcPCHGVC2aaOINk13K+aaBDUPjGWl0teOXywElLjyVAB6Oe2jj62jHYtwsU49jXhScYbvPENK+6zAvQ==
 
-yn@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/yn/-/yn-2.0.0.tgz#e5adabc8acf408f6385fc76495684c88e6af689a"
-  integrity sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=
+yn@3.1.1:
+  version "3.1.1"
+  resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"
+  integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==