Repository: DefinitelyTyped/dt-mergebot
Pull request #435 (2022-02-12 13:30:49)

check merge trigger phrase at the start of every line
This checks every line in a comment for the phrase "ready to merge" in the beginning, rather than just looking at the start of the whole comment.


Patch:
diff --git a/src/basic.ts b/src/basic.ts
index 53ce1a6..c5ffa7a 100644
--- a/src/basic.ts
+++ b/src/basic.ts
@@ -44,6 +44,7 @@ export const LabelNames = [
     "Too Many Owners",
     "Untested Change",
     "Check Config",
+    "Too Many Files",
     "Huge Change",
     "Needs Actions Permission",
     ...StalenessKinds,
diff --git a/src/compute-pr-actions.ts b/src/compute-pr-actions.ts
index 4b38e57..7b191bc 100644
--- a/src/compute-pr-actions.ts
+++ b/src/compute-pr-actions.ts
@@ -252,6 +252,7 @@ export function process(prInfo: BotResult,
     label("Too Many Owners", info.tooManyOwners);
     label("Check Config", info.checkConfig);
     label("Untested Change", info.isUntested);
+    label("Too Many Files", info.tooManyFiles);
     label("Huge Change", info.hugeChange);
     if (info.staleness?.state === "nearly" || info.staleness?.state === "done") label(info.staleness.kind);
 
@@ -274,6 +275,10 @@ export function process(prInfo: BotResult,
     }
 
     // Some step should override actions.projectColumn, the default "Other" indicates a problem
+    if (info.author === "github-actions") {
+        actions.projectColumn = "Needs Maintainer Action";
+        return actions;
+    }
 
     // First-timers are blocked from CI runs until approved, this case is for infra edits (require a maintainer)
     if (info.ciResult === "action_required") {
@@ -379,9 +384,10 @@ function createWelcomeComment(info: ExtendedPrInfo, post: (c: Comments.Comment)
 
     const testsLink = info.hasNewPackages ? urls.testingNewPackages : urls.testingEditedPackages;
 
-    const specialWelcome = !info.isFirstContribution ? `` :
-        txt`| I see this is your first time submitting to DefinitelyTyped 👋
-             — I'm the local bot who will help you through the process of getting things through.`;
+    const specialWelcome = info.isFirstContribution
+        ? txt`| I see this is your first time submitting to DefinitelyTyped 👋
+             — I'm the local bot who will help you through the process of getting things through.`
+        : info.author === "github-actions" ? "From one bot to another, beep bloop boople bloop." : "";
     display(`@${info.author} Thank you for submitting this PR!${specialWelcome}`,
             ``,
             `***This is a live comment which I will keep updated.***`);
diff --git a/src/pr-info.ts b/src/pr-info.ts
index 9b6ef8e..bbda6c5 100644
--- a/src/pr-info.ts
+++ b/src/pr-info.ts
@@ -7,6 +7,7 @@ import { PR_repository_pullRequest,
 import { getMonthlyDownloadCount } from "./util/npm";
 import { fetchFile as defaultFetchFile } from "./util/fetchFile";
 import { noNullish, someLast, sameUser, authorNotBot, max, abbrOid } from "./util/util";
+import { TOO_MANY_FILES } from "./queries/pr-query";
 import * as comment from "./util/comment";
 import * as urls from "./urls";
 import * as HeaderParser from "@definitelytyped/header-parser";
@@ -136,7 +137,7 @@ export interface PrInfo {
      */
     readonly tooManyFiles: boolean;
     /*
-     * True for PRs with over 5k line chanbges (top ~3%)
+     * True for PRs with over 5k line changes (top ~3%)
      */
     readonly hugeChange: boolean;
 
@@ -209,13 +210,14 @@ export async function deriveStateForPR(
     // that case `files.totalCount` would be 3k so it'd fit the count but `changedFiles` would
     // be correct; so to be safe: check it, and warn if there are many files (or zero)
     const tooManyFiles = !fileCount // should never happen, make it look fishy if it does
-        || fileCount !== prInfo.files?.nodes?.length // didn't get all files somehow
-        || fileCount > 500; // suspiciously many files
+        || fileCount > TOO_MANY_FILES // suspiciously many files
+        || fileCount !== prInfo.files?.nodes?.length; // didn't get all files (probably too many)
     const hugeChange = prInfo.additions + prInfo.deletions > 5000;
 
+    const paths = noNullish(prInfo.files?.nodes).map(f => f.path).sort();
+    if (paths.length > TOO_MANY_FILES) paths.length = TOO_MANY_FILES; // redundant, but just in case
     const pkgInfoEtc = await getPackageInfosEtc(
-        noNullish(prInfo.files?.nodes).map(f => f.path).sort(),
-        prInfo.headRefOid, baseId,
+        paths, prInfo.headRefOid, baseId,
         fetchFile, async name => await getDownloads(name, lastPushDate));
     if (pkgInfoEtc instanceof Error) return botError(pkgInfoEtc.message);
     const { pkgInfo, popularityLevel } = pkgInfoEtc;
@@ -225,7 +227,7 @@ export async function deriveStateForPR(
     const comments = noNullish(prInfo.comments.nodes);
     const mergeOfferDate = getMergeOfferDate(comments, prInfo.headRefOid);
     const mergeRequest = getMergeRequest(comments,
-                                         pkgInfo.length === 1 ? [author, ...pkgInfo[0]!.owners] : [author],
+                                         pkgInfo.filter(p => p.name).length === 1 ? [author, ...pkgInfo.find(p => p.name)!.owners] : [author],
                                          max([createdDate, reopenedDate, lastPushDate]));
     const lastActivityDate = max([createdDate, lastPushDate, lastCommentDate, blessing?.date, reopenedDate, latestReview]);
     const mainBotCommentID = getMainCommentID(comments);
@@ -454,10 +456,10 @@ function getMergeOfferDate(comments: PR_repository_pullRequest_comments_nodes[],
 function getMergeRequest(comments: PR_repository_pullRequest_comments_nodes[], users: string[], sinceDate: Date) {
     const request = latestComment(comments.filter(comment =>
         users.some(u => comment.author && sameUser(u, comment.author.login))
-        && comment.body.trim().toLowerCase().startsWith("ready to merge")));
+        && comment.body.split("\n").some(line => line.trim().toLowerCase().startsWith("ready to merge"))));
     if (!request) return request;
     const date = new Date(request.createdAt);
-    return date > sinceDate ? { date, user: request.author!.login  } : undefined;
+    return date > sinceDate ? { date, user: request.author!.login } : undefined;
 }
 
 function getReviews(prInfo: PR_repository_pullRequest) {
diff --git a/src/queries/pr-query.ts b/src/queries/pr-query.ts
index 367239f..36e0eeb 100644
--- a/src/queries/pr-query.ts
+++ b/src/queries/pr-query.ts
@@ -4,6 +4,8 @@ import { PR, PRVariables, PR_repository_pullRequest_files_nodes } from "./schema
 import { PRFiles, PRFilesVariables } from "./schema/PRFiles";
 import { noNullish } from "../util/util";
 
+export const TOO_MANY_FILES = 500;
+
 // Note: If you want to work on this in local a copy of GraphiQL:
 // - Download the electron app: https://github.com/skevy/graphiql-app/releases
 // - Then set the headers:
@@ -185,7 +187,7 @@ export async function getPRInfo(prNumber: number) {
     return info;
 }
 
-export async function getPRInfoFirst(prNumber: number) {
+async function getPRInfoFirst(prNumber: number) {
     // The query can return a mergeable value of `UNKNOWN`, and then it takes a
     // while to get the actual value while GH refreshes the state (verified
     // with GH that this is expected).  So implement a simple retry thing to
@@ -240,7 +242,7 @@ async function getPRInfoRest(prNumber: number, endCursor: string | null,
         const newFiles = result.data.repository?.pullRequest?.files;
         if (!newFiles) return;
         files.push(...noNullish(newFiles.nodes));
-        if (!newFiles.pageInfo.hasNextPage) return;
+        if (files.length >= TOO_MANY_FILES || !newFiles.pageInfo.hasNextPage) return;
         endCursor = newFiles.pageInfo.endCursor;
     }
 }
diff --git a/src/run.ts b/src/run.ts
index 033c321..71b7e5e 100755
--- a/src/run.ts
+++ b/src/run.ts
@@ -63,7 +63,7 @@ const show = (name: string, value: unknown) => {
 
 const start = async function () {
     console.log(`Getting open PRs.`);
-    const { prs: prs, cardIDs } = await getAllOpenPRsAndCardIDs();
+    const { prs, cardIDs } = await getAllOpenPRsAndCardIDs();
     //
     for (const pr of prs) {
         if (!shouldRunOn(pr)) continue;


Test patch:
diff --git a/src/_tests/cachedQueries.json b/src/_tests/cachedQueries.json
index 554da2f..b8a613a 100644
--- a/src/_tests/cachedQueries.json
+++ b/src/_tests/cachedQueries.json
@@ -53,6 +53,11 @@
       "name": "Author is Owner",
       "__typename": "Label"
     },
+    {
+      "id": "LA_kwDOAFz6BM7QXorW",
+      "name": "Blocked upstream",
+      "__typename": "Label"
+    },
     {
       "id": "MDU6TGFiZWwyMTU0ODE2NTQ5",
       "name": "Check Config",
@@ -123,6 +128,11 @@
       "name": "Edits Owners",
       "__typename": "Label"
     },
+    {
+      "id": "LA_kwDOAFz6BM71Jg4R",
+      "name": "github_actions",
+      "__typename": "Label"
+    },
     {
       "id": "MDU6TGFiZWw1ODMyOTQ0NzQ=",
       "name": "Has Merge Conflict",
@@ -258,6 +268,11 @@
       "name": "The CI is blocked",
       "__typename": "Label"
     },
+    {
+      "id": "LA_kwDOAFz6BM8AAAABEGgY4Q",
+      "name": "Too Many Files",
+      "__typename": "Label"
+    },
     {
       "id": "MDU6TGFiZWwyMTU2MzIyMzcx",
       "name": "Too Many Owners",
diff --git a/src/_tests/fixtures/44424-1-travis-instantly-finished/mutations.json b/src/_tests/fixtures/44424-1-travis-instantly-finished/mutations.json
index 9b682b4..134c7ba 100644
--- a/src/_tests/fixtures/44424-1-travis-instantly-finished/mutations.json
+++ b/src/_tests/fixtures/44424-1-travis-instantly-finished/mutations.json
@@ -13,7 +13,8 @@
     "variables": {
       "input": {
         "labelIds": [
-          "MDU6TGFiZWwyOTUzOTk4NzE4"
+          "MDU6TGFiZWwyOTUzOTk4NzE4",
+          "LA_kwDOAFz6BM8AAAABEGgY4Q"
         ],
         "labelableId": "MDExOlB1bGxSZXF1ZXN0NDEyMjY1MDE2"
       }
diff --git a/src/_tests/fixtures/44424-1-travis-instantly-finished/result.json b/src/_tests/fixtures/44424-1-travis-instantly-finished/result.json
index 52638a5..d79f08a 100644
--- a/src/_tests/fixtures/44424-1-travis-instantly-finished/result.json
+++ b/src/_tests/fixtures/44424-1-travis-instantly-finished/result.json
@@ -2,7 +2,8 @@
   "projectColumn": "Needs Maintainer Action",
   "labels": [
     "Possibly Edits Infrastructure",
-    "Author is Owner"
+    "Author is Owner",
+    "Too Many Files"
   ],
   "responseComments": [
     {
diff --git a/src/_tests/fixtures/44424-2-after-travis-second/mutations.json b/src/_tests/fixtures/44424-2-after-travis-second/mutations.json
index 4a63d00..a290c41 100644
--- a/src/_tests/fixtures/44424-2-after-travis-second/mutations.json
+++ b/src/_tests/fixtures/44424-2-after-travis-second/mutations.json
@@ -13,7 +13,8 @@
     "variables": {
       "input": {
         "labelIds": [
-          "MDU6TGFiZWwyOTUzOTk4NzE4"
+          "MDU6TGFiZWwyOTUzOTk4NzE4",
+          "LA_kwDOAFz6BM8AAAABEGgY4Q"
         ],
         "labelableId": "MDExOlB1bGxSZXF1ZXN0NDEyMjY1MDE2"
       }
diff --git a/src/_tests/fixtures/44424-2-after-travis-second/result.json b/src/_tests/fixtures/44424-2-after-travis-second/result.json
index 5e5532a..df3a889 100644
--- a/src/_tests/fixtures/44424-2-after-travis-second/result.json
+++ b/src/_tests/fixtures/44424-2-after-travis-second/result.json
@@ -2,7 +2,8 @@
   "projectColumn": "Waiting for Code Reviews",
   "labels": [
     "Possibly Edits Infrastructure",
-    "Author is Owner"
+    "Author is Owner",
+    "Too Many Files"
   ],
   "responseComments": [
     {
diff --git a/src/_tests/fixtures/58632/_downloads.json b/src/_tests/fixtures/58632/_downloads.json
new file mode 100644
index 0000000..0967ef4
--- /dev/null
+++ b/src/_tests/fixtures/58632/_downloads.json
@@ -0,0 +1,1 @@
+{}
diff --git a/src/_tests/fixtures/58632/_files.json b/src/_tests/fixtures/58632/_files.json
new file mode 100644
index 0000000..0967ef4
--- /dev/null
+++ b/src/_tests/fixtures/58632/_files.json
@@ -0,0 +1,1 @@
+{}
diff --git a/src/_tests/fixtures/58632/_response.json b/src/_tests/fixtures/58632/_response.json
new file mode 100644
index 0000000..ba1b261
--- /dev/null
+++ b/src/_tests/fixtures/58632/_response.json
@@ -0,0 +1,325 @@
+{
+  "data": {
+    "repository": {
+      "id": "MDEwOlJlcG9zaXRvcnk2MDkzMzE2",
+      "pullRequest": {
+        "id": "PR_kwDOAFz6BM4yI35U",
+        "title": "Remove contributors with deleted accounts",
+        "createdAt": "2022-02-07T00:04:01Z",
+        "author": {
+          "login": "github-actions",
+          "__typename": "Bot"
+        },
+        "authorAssociation": "CONTRIBUTOR",
+        "baseRef": {
+          "name": "master",
+          "__typename": "Ref"
+        },
+        "labels": {
+          "nodes": [
+            {
+              "name": "Popular package",
+              "__typename": "Label"
+            },
+            {
+              "name": "Owner Approved",
+              "__typename": "Label"
+            },
+            {
+              "name": "Edits multiple packages",
+              "__typename": "Label"
+            },
+            {
+              "name": "Where is GH Actions?",
+              "__typename": "Label"
+            },
+            {
+              "name": "Untested Change",
+              "__typename": "Label"
+            },
+            {
+              "name": "Edits Owners",
+              "__typename": "Label"
+            }
+          ],
+          "__typename": "LabelConnection"
+        },
+        "isDraft": false,
+        "mergeable": "UNKNOWN",
+        "number": 58632,
+        "state": "MERGED",
+        "headRefOid": "d7304db2a17425c0b41451f5c2e056d063725ecf",
+        "changedFiles": 6,
+        "additions": 8,
+        "deletions": 12,
+        "commitIds": {
+          "nodes": [
+            {
+              "commit": {
+                "oid": "d7304db2a17425c0b41451f5c2e056d063725ecf",
+                "parents": {
+                  "nodes": [
+                    {
+                      "oid": "e33d3fe8b10acee209c6353529cf180b3cac25ac",
+                      "__typename": "Commit"
+                    }
+                  ],
+                  "__typename": "CommitConnection"
+                },
+                "__typename": "Commit"
+              },
+              "__typename": "PullRequestCommit"
+            }
+          ],
+          "__typename": "PullRequestCommitConnection"
+        },
+        "timelineItems": {
+          "nodes": [],
+          "__typename": "PullRequestTimelineItemsConnection"
+        },
+        "reviews": {
+          "nodes": [
+            {
+              "author": {
+                "login": "alitaheri",
+                "__typename": "User"
+              },
+              "commit": {
+                "oid": "d7304db2a17425c0b41451f5c2e056d063725ecf",
+                "__typename": "Commit"
+              },
+              "comments": {
+                "nodes": [],
+                "__typename": "PullRequestReviewCommentConnection"
+              },
+              "authorAssociation": "CONTRIBUTOR",
+              "state": "APPROVED",
+              "submittedAt": "2022-02-08T14:24:13Z",
+              "url": "https://github.com/DefinitelyTyped/DefinitelyTyped/pull/58632#pullrequestreview-876105577",
+              "__typename": "PullRequestReview"
+            },
+            {
+              "author": {
+                "login": "candyapplecorn",
+                "__typename": "User"
+              },
+              "commit": {
+                "oid": "d7304db2a17425c0b41451f5c2e056d063725ecf",
+                "__typename": "Commit"
+              },
+              "comments": {
+                "nodes": [],
+                "__typename": "PullRequestReviewCommentConnection"
+              },
+              "authorAssociation": "CONTRIBUTOR",
+              "state": "APPROVED",
+              "submittedAt": "2022-02-09T22:06:31Z",
+              "url": "https://github.com/DefinitelyTyped/DefinitelyTyped/pull/58632#pullrequestreview-878109819",
+              "__typename": "PullRequestReview"
+            },
+            {
+              "author": {
+                "login": "al-fyodorov",
+                "__typename": "User"
+              },
+              "commit": {
+                "oid": "d7304db2a17425c0b41451f5c2e056d063725ecf",
+                "__typename": "Commit"
+              },
+              "comments": {
+                "nodes": [],
+                "__typename": "PullRequestReviewCommentConnection"
+              },
+              "authorAssociation": "CONTRIBUTOR",
+              "state": "APPROVED",
+              "submittedAt": "2022-02-15T11:39:02Z",
+              "url": "https://github.com/DefinitelyTyped/DefinitelyTyped/pull/58632#pullrequestreview-882856991",
+              "__typename": "PullRequestReview"
+            }
+          ],
+          "__typename": "PullRequestReviewConnection"
+        },
+        "commits": {
+          "totalCount": 1,
+          "nodes": [
+            {
+              "commit": {
+                "checkSuites": {
+                  "nodes": [
+                    {
+                      "databaseId": 5197815169,
+                      "app": {
+                        "name": "Azure Pipelines",
+                        "__typename": "App"
+                      },
+                      "conclusion": "SUCCESS",
+                      "resourcePath": "/DefinitelyTyped/DefinitelyTyped/commit/d7304db2a17425c0b41451f5c2e056d063725ecf/checks?check_suite_id=5197815169",
+                      "status": "COMPLETED",
+                      "url": "https://github.com/DefinitelyTyped/DefinitelyTyped/commit/d7304db2a17425c0b41451f5c2e056d063725ecf/checks?check_suite_id=5197815169",
+                      "checkRuns": {
+                        "nodes": [
+                          {
+                            "title": "Build #20220207.1 succeeded",
+                            "__typename": "CheckRun"
+                          }
+                        ],
+                        "__typename": "CheckRunConnection"
+                      },
+                      "__typename": "CheckSuite"
+                    },
+                    {
+                      "databaseId": 5197815175,
+                      "app": {
+                        "name": "Dependabot",
+                        "__typename": "App"
+                      },
+                      "conclusion": null,
+                      "resourcePath": "/DefinitelyTyped/DefinitelyTyped/commit/d7304db2a17425c0b41451f5c2e056d063725ecf/checks?check_suite_id=5197815175",
+                      "status": "QUEUED",
+                      "url": "https://github.com/DefinitelyTyped/DefinitelyTyped/commit/d7304db2a17425c0b41451f5c2e056d063725ecf/checks?check_suite_id=5197815175",
+                      "checkRuns": {
+                        "nodes": [],
+                        "__typename": "CheckRunConnection"
+                      },
+                      "__typename": "CheckSuite"
+                    }
+                  ],
+                  "__typename": "CheckSuiteConnection"
+                },
+                "status": null,
+                "authoredDate": "2022-02-07T00:03:58Z",
+                "committedDate": "2022-02-07T00:03:58Z",
+                "pushedDate": "2022-02-07T00:04:05Z",
+                "oid": "d7304db2a17425c0b41451f5c2e056d063725ecf",
+                "__typename": "Commit"
+              },
+              "__typename": "PullRequestCommit"
+            }
+          ],
+          "__typename": "PullRequestCommitConnection"
+        },
+        "comments": {
+          "totalCount": 4,
+          "nodes": [
+            {
+              "id": "IC_kwDOAFz6BM49cv4g",
+              "author": {
+                "login": "typescript-bot",
+                "__typename": "User"
+              },
+              "databaseId": 1030946336,
+              "body": "@github-actions Thank you for submitting this PR!\n\n***This is a live comment which I will keep updated.***\n\n## 6 packages in this PR\n\n* `mithril-global` — [on npm](https://www.npmjs.com/package/mithril-global), [on unpkg](https://unpkg.com/browse/mithril-global@latest/)\n  - 1 removed owner: @isiahmeadows\n* `mithril` — [on npm](https://www.npmjs.com/package/mithril), [on unpkg](https://unpkg.com/browse/mithril@latest/)\n  - 1 removed owner: @isiahmeadows\n* `ospec` — [on npm](https://www.npmjs.com/package/ospec), [on unpkg](https://unpkg.com/browse/ospec@latest/)\n  - 1 removed owner: @isiahmeadows\n* `react-grid-layout` — [on npm](https://www.npmjs.com/package/react-grid-layout), [on unpkg](https://unpkg.com/browse/react-grid-layout@latest/)\n  - owner-approval: @al-fyodorov, @alitaheri\n  - 1 removed owner: @catusmagnus\n* `react-native-fbsdk` — [on npm](https://www.npmjs.com/package/react-native-fbsdk), [on unpkg](https://unpkg.com/browse/react-native-fbsdk@latest/)\n  - 1 removed owner: @UHKim\n* `ssh2-sftp-client` — [on npm](https://www.npmjs.com/package/ssh2-sftp-client), [on unpkg](https://unpkg.com/browse/ssh2-sftp-client@latest/)\n  - owner-approval: @candyapplecorn\n  - 1 removed owner: @sgalizia\n\n## Code Reviews\n\nBecause this PR edits multiple packages, it can be merged once it's reviewed by a DT maintainer.\n\nYou can test the changes of this PR [in the Playground](https://www.typescriptlang.org/play/?dtPR=58632&install-plugin=playground-dt-review).\n\n## Status\n\n * ✅ No merge conflicts\n * ❓ Continuous integration tests have gone missing\n * 🕐 A DT maintainer needs to approve changes which affect more than one package\n\nOnce every item on this list is checked, I'll ask you for permission to merge and publish the changes.\n\n## Inactive\n\nThis PR has been inactive for 10 days.\n\n----------------------\n... diagnostics scrubbed ...\n<!--typescript_bot_welcome-->",
+              "createdAt": "2022-02-07T00:04:41Z",
+              "reactions": {
+                "nodes": [],
+                "__typename": "ReactionConnection"
+              },
+              "__typename": "IssueComment"
+            },
+            {
+              "id": "IC_kwDOAFz6BM49cv4q",
+              "author": {
+                "login": "typescript-bot",
+                "__typename": "User"
+              },
+              "databaseId": 1030946346,
+              "body": "🔔 @spacejack @isiahmeadows @maranomynet @abirkholz @alitaheri @ZheyangSong @andrewhathaway @manav-m @al-fyodorov @catusmagnus @ifiokjr @titozzz @stuartforrest-infinity @UHKim @igrayson @ascariandrea @kartik2406 @viamuli @gbhmt @builtbylane @loru88 @sgalizia @hengkx @candyapplecorn @tsop14 — please [review this PR](https://github.com/DefinitelyTyped/DefinitelyTyped/pull/58632/files) in the next few days. Be sure to explicitly select **`Approve`** or **`Request Changes`** in the GitHub UI so I know what's going on.\n<!--typescript_bot_pinging-reviewers-->",
+              "createdAt": "2022-02-07T00:04:43Z",
+              "reactions": {
+                "nodes": [],
+                "__typename": "ReactionConnection"
+              },
+              "__typename": "IssueComment"
+            },
+            {
+              "id": "IC_kwDOAFz6BM49pTyu",
+              "author": {
+                "login": "candyapplecorn",
+                "__typename": "User"
+              },
+              "databaseId": 1034239150,
+              "body": "This doesn't seem morally right. I don't know how to remove my approval, but if I could I would.\r\nJust because their accounts were deleted, doesn't invalidate their past work.\r\nEdit - Unless the purpose of putting ones' name is to let other contributors have people to contact for info/help? But in my experience, it's always been just as much about getting one's name on a contributor list, as it is about recording a breadcrumb trail of past contributors for new contributors to access as a resource.",
+              "createdAt": "2022-02-09T22:08:45Z",
+              "reactions": {
+                "nodes": [],
+                "__typename": "ReactionConnection"
+              },
+              "__typename": "IssueComment"
+            },
+            {
+              "id": "IC_kwDOAFz6BM4-MZQM",
+              "author": {
+                "login": "andrewbranch",
+                "__typename": "User"
+              },
+              "databaseId": 1043436556,
+              "body": "@candyapplecorn the purpose of the header comment is not attribution; it’s ongoing maintenance. These accounts get automatically pinged for reviews on future PRs (like you were pinged here), and when they approve, the PRs get fast-tracked to merge. The reason we have to delete inactive ones is that GitHub releases the usernames of deleted accounts after a while, so new users could be signing up and be getting pinged for reviews of something they’ve never heard of. I’m sympathetic to the unintended consequence of erasing something that someone wanted attribution for, but the reality is that people intentionally remove themselves from these headers all the time when they want to stop getting pinged for reviews, and we have no way of continuing to list them as contributors either, other than in the historical record (both in the git history and in the published package.jsons)—that’s just not what the header was made for.",
+              "createdAt": "2022-02-17T21:00:53Z",
+              "reactions": {
+                "nodes": [],
+                "__typename": "ReactionConnection"
+              },
+              "__typename": "IssueComment"
+            }
+          ],
+          "__typename": "IssueCommentConnection"
+        },
+        "files": {
+          "totalCount": 6,
+          "nodes": [
+            {
+              "path": "types/mithril-global/index.d.ts",
+              "additions": 1,
+              "deletions": 1,
+              "__typename": "PullRequestChangedFile"
+            },
+            {
+              "path": "types/mithril/index.d.ts",
+              "additions": 1,
+              "deletions": 1,
+              "__typename": "PullRequestChangedFile"
+            },
+            {
+              "path": "types/ospec/index.d.ts",
+              "additions": 0,
+              "deletions": 1,
+              "__typename": "PullRequestChangedFile"
+            },
+            {
+              "path": "types/react-grid-layout/index.d.ts",
+              "additions": 6,
+              "deletions": 7,
+              "__typename": "PullRequestChangedFile"
+            },
+            {
+              "path": "types/react-native-fbsdk/index.d.ts",
+              "additions": 0,
+              "deletions": 1,
+              "__typename": "PullRequestChangedFile"
+            },
+            {
+              "path": "types/ssh2-sftp-client/index.d.ts",
+              "additions": 0,
+              "deletions": 1,
+              "__typename": "PullRequestChangedFile"
+            }
+          ],
+          "pageInfo": {
+            "hasNextPage": false,
+            "endCursor": "Ng",
+            "__typename": "PageInfo"
+          },
+          "__typename": "PullRequestChangedFileConnection"
+        },
+        "projectCards": {
+          "nodes": [],
+          "__typename": "ProjectCardConnection"
+        },
+        "__typename": "PullRequest"
+      },
+      "__typename": "Repository"
+    }
+  },
+  "loading": false,
+  "networkStatus": 7
+}
diff --git a/src/_tests/fixtures/58632/derived.json b/src/_tests/fixtures/58632/derived.json
new file mode 100644
index 0000000..3f65fbc
--- /dev/null
+++ b/src/_tests/fixtures/58632/derived.json
@@ -0,0 +1,6 @@
+{
+  "type": "remove",
+  "now": "2022-02-17T22:40:31.072Z",
+  "message": "PR is not active",
+  "isDraft": false
+}
diff --git a/src/_tests/fixtures/58632/mutations.json b/src/_tests/fixtures/58632/mutations.json
new file mode 100644
index 0000000..fe51488
--- /dev/null
+++ b/src/_tests/fixtures/58632/mutations.json
@@ -0,0 +1,1 @@
+[]
diff --git a/src/_tests/fixtures/58632/result.json b/src/_tests/fixtures/58632/result.json
new file mode 100644
index 0000000..25a0649
--- /dev/null
+++ b/src/_tests/fixtures/58632/result.json
@@ -0,0 +1,8 @@
+{
+  "labels": [],
+  "responseComments": [],
+  "shouldClose": false,
+  "shouldMerge": false,
+  "shouldUpdateLabels": false,
+  "projectColumn": "*REMOVE*"
+}
diff --git a/src/_tests/fixtures/58764/_downloads.json b/src/_tests/fixtures/58764/_downloads.json
new file mode 100644
index 0000000..c612b99
--- /dev/null
+++ b/src/_tests/fixtures/58764/_downloads.json
@@ -0,0 +1,11 @@
+{
+  "bootstrap.v3.datetimepicker": 2109,
+  "mithril-global": 23,
+  "mithril": 15949,
+  "ospec": 791,
+  "react-grid-layout": 520136,
+  "react-native-fbsdk": 78391,
+  "react-virtualized": 1521648,
+  "ssh2-sftp-client": 307276,
+  "styled-components": 8672781
+}
diff --git a/src/_tests/fixtures/58764/_files.json b/src/_tests/fixtures/58764/_files.json
new file mode 100644
index 0000000..733ae21
--- /dev/null
+++ b/src/_tests/fixtures/58764/_files.json
@@ -0,0 +1,19 @@
+{
+  "2cee47aedc9b4d321e378d7020984adf005fef64:types/bootstrap.v3.datetimepicker/index.d.ts": "// Type definitions for non-npm package Bootstrap 3 Datepicker 4.17\n// Project: http://eonasdan.github.io/bootstrap-datetimepicker\n// Definitions by: Katona Péter <https://github.com/katonap>\n// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped\n// TypeScript Version: 2.3\n// based on the previous version created by Jesica N. Fera <https://github.com/bayitajesi>\n\n/**\n * bootstrap-datetimepicker.js 4.17.45 Copyright (c) 2015 Jonathan Peterson\n * Available via the MIT license.\n * see: http://eonasdan.github.io/bootstrap-datetimepicker or https://github.com/Eonasdan/bootstrap-datetimepicker for details.\n */\n\n/// <reference types=\"jquery\"/>\n\nimport * as moment from \"moment\";\n\nexport as namespace BootstrapV3DatetimePicker;\n\nexport type InputParser = (input: string | Date | moment.Moment) => moment.Moment;\n\nexport interface Datetimepicker {\n    /** Clears the datepicker by setting the value to null */\n    clear(): void;\n    /** Returns the component's model current date, a moment object or null if not set. */\n    date(): moment.Moment;\n    /**\n     * Takes string, Date, moment, null parameter and sets the components model current moment to it.\n     * Passing a null value unsets the components model current moment.\n     * Parsing of the newDate parameter is made using moment library with the options.format and options.useStrict components configuration.\n     * Throws:\n     * - TypeError - in case the newDate cannot be parsed\n     *\n     * Emits:\n     * - dp.change - In case newDate is different from current moment\n     */\n    date(date: moment.Moment | Date | string | null): void;\n    /** Destroys the widget and removes all attached event listeners */\n    destroy(): void;\n    /**\n     * Disables the input element, the component is attached to, by adding a disabled=\"true\" attribute to it. If the widget was visible before that call it is hidden.\n     * Emits:\n     * - dp.hide - if the widget was visible before that call\n     */\n    disable(): void;\n    /** Enables the input element, the component is attached to, by removing disabled attribute from it. */\n    enable(): void;\n    /**\n     * Hides the widget\n     * Emits:\n     * - dp.hide - if the widget was visible before that call\n     */\n    hide(): void;\n    /**\n     * Returns the components current options object.\n     * Note that the changing the values of the returned object does not change the components actual configuration.\n     */\n    options(): DatetimepickerOptions;\n    /** Takes an object variable with option key:value properties and configures the component. Use this to update multiple options on the component. */\n    options(options: DatetimepickerOptions): void;\n    /**\n     * Shows the widget\n     * Emits:\n     * - dp.show - if the widget was hidden before that call\n     * - dp.change - if the widget is opened for the first time and the useCurrent is set to true or to a granularity value and the input element the component is attached to has an empty value\n     */\n    show(): void;\n    /**\n     * Shows or hides the widget\n     * Emits:\n     * - dp.hide - if the widget is hidden after the toggle call\n     * - dp.show - if the widget is show after the toggle call\n     * - dp.change - if the widget is opened for the first time and the input element is empty and options.useCurrent != false\n     */\n    toggle(): void;\n\n    ////////////////////////////////////////////////////////////////////////////////////////////////////\n    //// Below are the getters/setters for the properties of the 'options(): DatetimepickerOptions' ////\n    ////////////////////////////////////////////////////////////////////////////////////////////////////\n\n    /** Returns the options.allowInputToggle option. */\n    allowInputToggle(): boolean;\n    /** If true, the picker will show on textbox focus and icon click when used in a button group */\n    allowInputToggle(value: boolean): void;\n    /** Returns the current options.calendarWeeks option configuration */\n    calendarWeeks(): boolean;\n    /** Set if the week numbers will appear to the left on the days view */\n    calendarWeeks(value: boolean): void;\n    /** Returns the options.collapse option configuration */\n    collapse(): boolean;\n    /** If set to false the picker will display similar to sideBySide except vertical. */\n    collapse(value: boolean): void;\n    /**\n     * Returns the options.daysOfWeekDisabled configuration\n     * IMPORTANT! Throws exception if not set explicitly https://github.com/Eonasdan/bootstrap-datetimepicker/issues/1459\n     */\n    daysOfWeekDisabled(): number[];\n    /**\n     * Takes an [ Number:0 to 6 ] and disallow the user to select weekdays that exist in this array.\n     * This has lower priority over the options.minDate, options.maxDate, options.disabledDates and options.enabledDates configuration settings.\n     * Emits:\n     * - dp.change - if the currently selected moment falls in the values passed on the daysOfWeek parameter.\n     * - dp.error - if the currently selected moment falls in the values passed on the daysOfWeek parameter.\n     */\n    daysOfWeekDisabled(days: number[]): void;\n    /** Returns the options.dayViewHeaderFormat option. */\n    dayViewHeaderFormat(): string;\n    /** Used to customize the header of the day view. */\n    dayViewHeaderFormat(value: string): void;\n    /** Returns a moment with the options.defaultDate option configuration or false if not set */\n    defaultDate(): moment.Moment | boolean;\n    /**\n     * Will set the picker's inital date.\n     * If a boolean:false value is passed the options.defaultDate parameter is cleared.\n     * Throws:\n     * - TypeError - if the provided date doesn't pass validation, including disabledDates, enabledDates, minDate, maxDate, and daysOfWeekDisabled\n     * - TypeError - if the provided date cannot be parsed by momentjs\n     */\n    defaultDate(date: string | Date | moment.Moment | boolean): void;\n    /**\n     * Returns the options.disabledDates option.\n     * NOTES: probably should be: disabledDates(): boolean | Array<moment.Moment>; see: DatetimepickerOptions\n     */\n    disabledDates(): boolean | any;\n    /**\n     * Takes an array of values and disallows the user to select those days.\n     * Setting this takes precedence over options.minDate, options.maxDate configuration.\n     * Also calling this function removes the configuration of options.enabledDates if such exist.\n     * Note: These values are matched with Day granularity.\n     */\n    disabledDates(dates: boolean | Array<string | Date | moment.Moment>): void;\n    /**\n     * Returns the options.disabledHours option.\n     * NOTES: probably should be: disabledHours(): boolean | number[]; see: DatetimepickerOptions\n     */\n    disabledHours(): boolean | any;\n    /**\n     * Must be in 24 hour format. Will disallow hour selections (much like disabledTimeIntervals) but will affect all days.\n     * Like en/disabledDates, the en/disabledHours options are mutually exclusive and will reset one of the options back to false.\n     */\n    disabledHours(value: boolean | number[]): void;\n    /**\n     * Returns the options.disabledTimeIntervals option, or... not exactly\n     * IMPORTANT! Creates an object from the options.disabledTimeIntervals with the keys being numbers, the values being the moment arrays.\n     * eg { \"0\": [<moment.Moment1>, <moment.Moment2>], \"1\": [...] }\n     * https://github.com/Eonasdan/bootstrap-datetimepicker/issues/1498\n     */\n    disabledTimeIntervals(): boolean | moment.Moment[][];\n    /**\n     * Disables time selection between the given moments\n     * eg: [[moment({ h: 0 }), moment({ h: 8 })], [moment({ h: 18 }), moment({ h: 24 })]]\n     */\n    disabledTimeIntervals(value: boolean | moment.Moment[][]): void;\n    /**\n     * Returns the options.enabledDates option\n     * NOTES: probably should be: enabledDates(): boolean | Array<moment.Moment>; see: DatetimepickerOptions\n     */\n    enabledDates(): boolean | any;\n    /**\n     * Takes an array of values and allows the user to select only from those days.\n     * Setting this takes precedence over options.minDate, options.maxDate configuration.\n     * Also calling this function removes the configuration of options.disabledDates if such exist.\n     * Note: These values are matched with Day granularity.\n     */\n    enabledDates(dates: boolean | Array<string | Date | moment.Moment>): void;\n    /**\n     * Returns the options.enabledHours option.\n     * NOTES: probably should be: enabledHours(): boolean | number[]; see: DatetimepickerOptions\n     */\n    enabledHours(): boolean | any;\n    /**\n     * Must be in 24 hour format. Will allow hour selections (much like enabledTimeIntervals) but will affect all days.\n     * Like en/disabledDates, the en/disabledHours options are mutually exclusive and will reset one of the options back to false.\n     */\n    enabledHours(value: boolean | number[]): void;\n    /** Returns a boolean or array with the options.extraFormats option configuration */\n    extraFormats(): boolean | Array<string | moment.MomentBuiltinFormat>;\n    /** Takes an array of valid input moment format options, or boolean:false */\n    extraFormats(formats: boolean | Array<string  | moment.MomentBuiltinFormat>): void;\n    /** Returns the options.focusOnShow option. */\n    focusOnShow(): boolean;\n    /** If false, the textbox will not be given focus when the picker is shown */\n    focusOnShow(value: boolean): void;\n    /** Returns the component's options.format string */\n    format(): boolean | string | moment.MomentBuiltinFormat;\n    /**\n     * Takes a moment.js format string and sets the components options.format.\n     * This is used for displaying and also for parsing input strings either from the input element the component is attached to or the date() function.\n     * The parameter can also be a boolean:false in which case the format is set to the locale's L LT.\n     * Note: this is also used to determine if the TimePicker sub component will display the hours in 12 or 24 format. (if \"a\" or \"h\" exists in the passed string then a 12 hour mode is set)\n     * Throws:\n     * - TypeError - if format is boolean:true\n     */\n    format(format: boolean | string | moment.MomentBuiltinFormat): void;\n    /** Returns options.icons */\n    icons(): Icons;\n    /*",
+  "2cee47aedc9b4d321e378d7020984adf005fef64:types/mithril-global/index.d.ts": "// Type definitions for non-npm package Mithril 2.0\n// Project: https://mithril.js.org/\n// Definitions by: Mike Linkovich <https://github.com/spacejack>, Isiah Meadows <https://github.com/isiahmeadows>\n// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped\n// TypeScript Version: 3.2\n\n// Global Mithril types\n\n/// <reference types=\"mithril\" />\n\nimport * as mithril from 'mithril';\nimport * as stream from 'mithril/stream';\n\ndeclare namespace MithrilGlobal {\n    export type CommonAttributes<A, S> = mithril.CommonAttributes<A, S>;\n    export type Hyperscript = mithril.Hyperscript;\n    export type RouteResolver<A = {}, S = {}> = mithril.RouteResolver<A, S>;\n    export type RouteDefs = mithril.RouteDefs;\n    export type RouteOptions = mithril.RouteOptions;\n    export type Route = mithril.Route;\n    export type RequestOptions<T> = mithril.RequestOptions<T>;\n    export type JsonpOptions = mithril.JsonpOptions;\n    export type Child = mithril.Child;\n    export type ChildArray = mithril.ChildArray;\n    export type Children = mithril.Children;\n    export type ChildArrayOrPrimitive = mithril.ChildArrayOrPrimitive;\n    export type Vnode<A = {}, S = {}> = mithril.Vnode<A, S>;\n    export type VnodeDOM<A = {}, S = {}> = mithril.VnodeDOM<A, S>;\n    export type CVnode<A = {}> = mithril.CVnode<A>;\n    export type CVnodeDOM<A = {}> = mithril.CVnodeDOM<A>;\n    export type Component<A = {}, S = {}> = mithril.Component<A, S>;\n    export type Comp<A = {}, S extends Partial<mithril.Component<A, S>> = {}> = mithril.Comp<A, S>;\n    export type ClassComponent<A = {}> = mithril.ClassComponent<A>;\n    export type FactoryComponent<A = {}> = mithril.FactoryComponent<A>;\n    export type ComponentTypes<A = {}, S extends Partial<mithril.Component<A, S>> = {}> = mithril.ComponentTypes<A, S>;\n    export type Attributes = mithril.Attributes;\n    export type Static = mithril.Static & { stream: typeof stream };\n    export type Stream<T> = stream<T>;\n}\n\ndeclare const MithrilGlobal: MithrilGlobal.Static;\nexport = MithrilGlobal;\nexport as namespace m;\n",
+  "9ba7dfc289e4ce1023a9d398b9e04a91ae3a9070:types/mithril-global/index.d.ts": "// Type definitions for non-npm package Mithril 2.0\n// Project: https://mithril.js.org/\n// Definitions by: Mike Linkovich <https://github.com/spacejack>\n// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped\n// TypeScript Version: 3.2\n\n// Global Mithril types\n\n/// <reference types=\"mithril\" />\n\nimport * as mithril from 'mithril';\nimport * as stream from 'mithril/stream';\n\ndeclare namespace MithrilGlobal {\n    export type CommonAttributes<A, S> = mithril.CommonAttributes<A, S>;\n    export type Hyperscript = mithril.Hyperscript;\n    export type RouteResolver<A = {}, S = {}> = mithril.RouteResolver<A, S>;\n    export type RouteDefs = mithril.RouteDefs;\n    export type RouteOptions = mithril.RouteOptions;\n    export type Route = mithril.Route;\n    export type RequestOptions<T> = mithril.RequestOptions<T>;\n    export type JsonpOptions = mithril.JsonpOptions;\n    export type Child = mithril.Child;\n    export type ChildArray = mithril.ChildArray;\n    export type Children = mithril.Children;\n    export type ChildArrayOrPrimitive = mithril.ChildArrayOrPrimitive;\n    export type Vnode<A = {}, S = {}> = mithril.Vnode<A, S>;\n    export type VnodeDOM<A = {}, S = {}> = mithril.VnodeDOM<A, S>;\n    export type CVnode<A = {}> = mithril.CVnode<A>;\n    export type CVnodeDOM<A = {}> = mithril.CVnodeDOM<A>;\n    export type Component<A = {}, S = {}> = mithril.Component<A, S>;\n    export type Comp<A = {}, S extends Partial<mithril.Component<A, S>> = {}> = mithril.Comp<A, S>;\n    export type ClassComponent<A = {}> = mithril.ClassComponent<A>;\n    export type FactoryComponent<A = {}> = mithril.FactoryComponent<A>;\n    export type ComponentTypes<A = {}, S extends Partial<mithril.Component<A, S>> = {}> = mithril.ComponentTypes<A, S>;\n    export type Attributes = mithril.Attributes;\n    export type Static = mithril.Static & { stream: typeof stream };\n    export type Stream<T> = stream<T>;\n}\n\ndeclare const MithrilGlobal: MithrilGlobal.Static;\nexport = MithrilGlobal;\nexport as namespace m;\n",
+  "2cee47aedc9b4d321e378d7020984adf005fef64:types/mithril/index.d.ts": "// Type definitions for Mithril 2.0\n// Project: https://mithril.js.org/, https://github.com/mithriljs/mithril.js\n// Definitions by: Mike Linkovich <https://github.com/spacejack>, Isiah Meadows <https://github.com/isiahmeadows>\n// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped\n// TypeScript Version: 3.2\n\n/** Renders a vnode structure into a DOM element. */\ndeclare function render(el: Element, vnodes: Mithril.Children): void;\n\n/** Mounts a component to a DOM element, enabling it to autoredraw on user events. */\ndeclare function mount(element: Element, component: Mithril.ComponentTypes<any, any>): void;\n/** Unmounts a component from a DOM element. */\ndeclare function mount(element: Element, component: null): void; // tslint:disable-line unified-signatures\n\n/** Makes an XHR request and returns a promise. */\ndeclare function request<T>(options: Mithril.RequestOptions<T> & { url: string }): Promise<T>;\n/** Makes an XHR request and returns a promise. */\ndeclare function request<T>(url: string, options?: Mithril.RequestOptions<T>): Promise<T>;\n\n/** Makes a JSON-P request and returns a promise. */\ndeclare function jsonp<T>(options: Mithril.JsonpOptions & { url: string }): Promise<T>; // tslint:disable-line:no-unnecessary-generics\n/** Makes a JSON-P request and returns a promise. */\ndeclare function jsonp<T>(url: string, options?: Mithril.JsonpOptions): Promise<T>; // tslint:disable-line:no-unnecessary-generics\n\ndeclare namespace Mithril {\n    interface CommonAttributes<Attrs, State> {\n        /** The oninit hook is called before a vnode is touched by the virtual DOM engine. */\n        oninit?(this: State, vnode: Vnode<Attrs, State>): any;\n        /** The oncreate hook is called after a DOM element is created and attached to the document. */\n        oncreate?(this: State, vnode: VnodeDOM<Attrs, State>): any;\n        /** The onbeforeremove hook is called before a DOM element is detached from the document. If a Promise is returned, Mithril only detaches the DOM element after the promise completes. */\n        onbeforeremove?(this: State, vnode: VnodeDOM<Attrs, State>): Promise<any> | void;\n        /** The onremove hook is called before a DOM element is removed from the document. */\n        onremove?(this: State, vnode: VnodeDOM<Attrs, State>): any;\n        /** The onbeforeupdate hook is called before a vnode is diffed in a update. */\n        onbeforeupdate?(this: State, vnode: Vnode<Attrs, State>, old: VnodeDOM<Attrs, State>): boolean | void;\n        /** The onupdate hook is called after a DOM element is updated, while attached to the document. */\n        onupdate?(this: State, vnode: VnodeDOM<Attrs, State>): any;\n        /** A key to optionally associate with this element. */\n        key?: string | number | undefined;\n    }\n\n    interface Hyperscript {\n        /** Creates a virtual element (Vnode). */\n        (selector: string, ...children: Children[]): Vnode<any, any>;\n        /** Creates a virtual element (Vnode). */\n        (selector: string, attributes: Attributes, ...children: Children[]): Vnode<any, any>;\n        /** Creates a virtual element (Vnode). */\n        <Attrs, State>(component: ComponentTypes<Attrs, State>, ...args: Children[]): Vnode<Attrs, State>;\n        /** Creates a virtual element (Vnode). */\n        <Attrs, State>(\n            component: ComponentTypes<Attrs, State>,\n            attributes: Attrs & CommonAttributes<Attrs, State>,\n            ...args: Children[]\n        ): Vnode<Attrs, State>;\n        /** Creates a fragment virtual element (Vnode). */\n        fragment(attrs: CommonAttributes<any, any> & { [key: string]: any }, children: ChildArrayOrPrimitive): Vnode<any, any>;\n        /** Turns an HTML string into a virtual element (Vnode). Do not use trust on unsanitized user input. */\n        trust(html: string): Vnode<any, any>;\n    }\n\n    interface RouteResolver<Attrs = {}, State = {}> {\n        /** The onmatch hook is called when the router needs to find a component to render. */\n        onmatch?(\n            this: this,\n            args: Attrs,\n            requestedPath: string,\n            route: string,\n        ): ComponentTypes<any, any> | Promise<any> | void;\n        /** The render method is called on every redraw for a matching route. */\n        render?(this: this, vnode: Vnode<Attrs, State>): Children;\n    }\n\n    /** This represents a key-value mapping linking routes to components. */\n    interface RouteDefs {\n        /** The key represents the route. The value represents the corresponding component. */\n        [url: string]: ComponentTypes<any, any> | RouteResolver<any, any>;\n    }\n\n    interface RouteOptions {\n        /** Routing parameters. If path has routing parameter slots, the properties of this object are interpolated into the path string. */\n        replace?: boolean | undefined;\n        /** The state object to pass to the underlying history.pushState / history.replaceState call. */\n        state?: any;\n        /** The title string to pass to the underlying history.pushState / history.replaceState call. */\n        title?: string | undefined;\n    }\n\n    interface RouteLinkAttrs extends Attributes {\n        href: string;\n        selector?: string | ComponentTypes<any> | undefined;\n        options?: RouteOptions | undefined;\n    }\n\n    interface Route {\n        /** Creates application routes and mounts Components and/or RouteResolvers to a DOM element. */\n        (element: Element, defaultRoute: string, routes: RouteDefs): void;\n        /** Returns the last fully resolved routing path, without the prefix. */\n        get(): string;\n        /** Redirects to a matching route or to the default route if no matching routes can be found. */\n        set(route: string, data?: any, options?: RouteOptions): void;\n        /** Defines a router prefix which is a fragment of the URL that dictates the underlying strategy used by the router. */\n        prefix: string;\n        /** This Component renders a link <a href> that will use the current routing strategy */\n        Link: Component<RouteLinkAttrs>;\n        /** Returns the named parameter value from the current route. */\n        param(name: string): string;\n        /** Gets all route parameters. */\n        param(): any;\n    }\n\n    interface RequestOptions<T> {\n        /** The HTTP method to use. */\n        method?: string | undefined;\n        /** The data to be interpolated into the URL and serialized into the querystring. */\n        params?: { [key: string]: any } | undefined;\n        /** The data to be serialized into the request body. */\n        body?: (XMLHttpRequest['send'] extends (x: infer R) => any ? R : never) | (object & { [id: string]: any }) | undefined;\n        /** Whether the request should be asynchronous. Defaults to true. */\n        async?: boolean | undefined;\n        /** A username for HTTP authorization. */\n        user?: string | undefined;\n        /** A password for HTTP authorization. */\n        password?: string | undefined;\n        /** Whether to send cookies to 3rd party domains. */\n        withCredentials?: boolean | undefined;\n        /** Exposes the underlying XMLHttpRequest object for low-level configuration. */\n        config?(xhr: XMLHttpRequest, options: this): XMLHttpRequest | void;\n        /** Headers to append to the request before sending it. */\n        headers?: { [key: string]: string } | undefined;\n        /** A constructor to be applied to each object in the response. */\n        type?: new (o: any) => any;\n        /** A serialization method to be applied to data. Defaults to JSON.stringify, or if options.data is an instance of FormData, defaults to the identity function. */\n        serialize?(data: any): any;\n        /** A deserialization method to be applied to the response. Defaults to a small wrapper around JSON.parse that returns null for empty responses. */\n        deserialize?(data: string): T;\n        /** A hook to specify how the XMLHttpRequest response should be read. Useful for reading response headers and cookies. Defaults to a function that returns xhr.responseText */\n        extract?(xhr: XMLHttpRequest, options: this): T;\n        /**\n         * Force the use of the HTTP body section for data in GET requests when set to true,\n         * or the use of querystring for other HTTP methods when set to false.\n         * Defaults to false for GET requests and true for other methods.\n         */\n        useBody?: boolean | undefined;\n        /** If false, redraws mounted components upon completion of the request. If true, it does not. */\n        background?: boolean | undefined;\n        /** Milliseconds a request can take before automatically being terminated. */\n        timeout?: number | undefined;\n        /** The expected type of the response, as a legal value of XMLHttpRequest.responseType. */\n        responseType?: '' | 'arraybuffer' | 'blob' | 'document' | 'json' | 'text' | undefined;\n    }\n\n    interface JsonpOptions {\n        /** The data to be interpolated into the URL and serialized into the querystring. */\n        params?: { [id: string]: any } | undefined;\n        /** The data to be serialized into the request body. */\n        body?: any;\n        /** A constructor to be applied to each object in the response. */\n        type?: new (o: any) => any;\n        /** The name of the function that will be called as the callback. */\n        callbackName?: string | undefined;\n        /** The name of the querystring parameter name that specifies the callback name. */\n        callbackKey?: string | undefined;\n        /** If false, redraws mounted components upon completion of the request. If true, it does not. */\n        background?: boolean | undefined;\n    }\n\n    interface Redraw {\n        /** Manually triggers an asynchronous redraw of mounted components. */\n        (): void;\n        /** Manually triggers a synchronous redraw of mounted components. */\n        sync(): void;\n    }\n\n    type Params = object & ParamsRec;\n\n    interface ParamsRec {\n        // Ideally, it'd be this:\n        // `[key: string | number]: Params | !symbol & !object`\n        [key: string]: string | number | boolean | null | undefined | Params;\n    }\n\n    interface Static extends Hyperscript {\n        route: Route;\n        mount: typeof mount;\n",
+  "9ba7dfc289e4ce1023a9d398b9e04a91ae3a9070:types/mithril/index.d.ts": "// Type definitions for Mithril 2.0\n// Project: https://mithril.js.org/, https://github.com/mithriljs/mithril.js\n// Definitions by: Mike Linkovich <https://github.com/spacejack>\n// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped\n// TypeScript Version: 3.2\n\n/** Renders a vnode structure into a DOM element. */\ndeclare function render(el: Element, vnodes: Mithril.Children): void;\n\n/** Mounts a component to a DOM element, enabling it to autoredraw on user events. */\ndeclare function mount(element: Element, component: Mithril.ComponentTypes<any, any>): void;\n/** Unmounts a component from a DOM element. */\ndeclare function mount(element: Element, component: null): void; // tslint:disable-line unified-signatures\n\n/** Makes an XHR request and returns a promise. */\ndeclare function request<T>(options: Mithril.RequestOptions<T> & { url: string }): Promise<T>;\n/** Makes an XHR request and returns a promise. */\ndeclare function request<T>(url: string, options?: Mithril.RequestOptions<T>): Promise<T>;\n\n/** Makes a JSON-P request and returns a promise. */\ndeclare function jsonp<T>(options: Mithril.JsonpOptions & { url: string }): Promise<T>; // tslint:disable-line:no-unnecessary-generics\n/** Makes a JSON-P request and returns a promise. */\ndeclare function jsonp<T>(url: string, options?: Mithril.JsonpOptions): Promise<T>; // tslint:disable-line:no-unnecessary-generics\n\ndeclare namespace Mithril {\n    interface CommonAttributes<Attrs, State> {\n        /** The oninit hook is called before a vnode is touched by the virtual DOM engine. */\n        oninit?(this: State, vnode: Vnode<Attrs, State>): any;\n        /** The oncreate hook is called after a DOM element is created and attached to the document. */\n        oncreate?(this: State, vnode: VnodeDOM<Attrs, State>): any;\n        /** The onbeforeremove hook is called before a DOM element is detached from the document. If a Promise is returned, Mithril only detaches the DOM element after the promise completes. */\n        onbeforeremove?(this: State, vnode: VnodeDOM<Attrs, State>): Promise<any> | void;\n        /** The onremove hook is called before a DOM element is removed from the document. */\n        onremove?(this: State, vnode: VnodeDOM<Attrs, State>): any;\n        /** The onbeforeupdate hook is called before a vnode is diffed in a update. */\n        onbeforeupdate?(this: State, vnode: Vnode<Attrs, State>, old: VnodeDOM<Attrs, State>): boolean | void;\n        /** The onupdate hook is called after a DOM element is updated, while attached to the document. */\n        onupdate?(this: State, vnode: VnodeDOM<Attrs, State>): any;\n        /** A key to optionally associate with this element. */\n        key?: string | number | undefined;\n    }\n\n    interface Hyperscript {\n        /** Creates a virtual element (Vnode). */\n        (selector: string, ...children: Children[]): Vnode<any, any>;\n        /** Creates a virtual element (Vnode). */\n        (selector: string, attributes: Attributes, ...children: Children[]): Vnode<any, any>;\n        /** Creates a virtual element (Vnode). */\n        <Attrs, State>(component: ComponentTypes<Attrs, State>, ...args: Children[]): Vnode<Attrs, State>;\n        /** Creates a virtual element (Vnode). */\n        <Attrs, State>(\n            component: ComponentTypes<Attrs, State>,\n            attributes: Attrs & CommonAttributes<Attrs, State>,\n            ...args: Children[]\n        ): Vnode<Attrs, State>;\n        /** Creates a fragment virtual element (Vnode). */\n        fragment(attrs: CommonAttributes<any, any> & { [key: string]: any }, children: ChildArrayOrPrimitive): Vnode<any, any>;\n        /** Turns an HTML string into a virtual element (Vnode). Do not use trust on unsanitized user input. */\n        trust(html: string): Vnode<any, any>;\n    }\n\n    interface RouteResolver<Attrs = {}, State = {}> {\n        /** The onmatch hook is called when the router needs to find a component to render. */\n        onmatch?(\n            this: this,\n            args: Attrs,\n            requestedPath: string,\n            route: string,\n        ): ComponentTypes<any, any> | Promise<any> | void;\n        /** The render method is called on every redraw for a matching route. */\n        render?(this: this, vnode: Vnode<Attrs, State>): Children;\n    }\n\n    /** This represents a key-value mapping linking routes to components. */\n    interface RouteDefs {\n        /** The key represents the route. The value represents the corresponding component. */\n        [url: string]: ComponentTypes<any, any> | RouteResolver<any, any>;\n    }\n\n    interface RouteOptions {\n        /** Routing parameters. If path has routing parameter slots, the properties of this object are interpolated into the path string. */\n        replace?: boolean | undefined;\n        /** The state object to pass to the underlying history.pushState / history.replaceState call. */\n        state?: any;\n        /** The title string to pass to the underlying history.pushState / history.replaceState call. */\n        title?: string | undefined;\n    }\n\n    interface RouteLinkAttrs extends Attributes {\n        href: string;\n        selector?: string | ComponentTypes<any> | undefined;\n        options?: RouteOptions | undefined;\n    }\n\n    interface Route {\n        /** Creates application routes and mounts Components and/or RouteResolvers to a DOM element. */\n        (element: Element, defaultRoute: string, routes: RouteDefs): void;\n        /** Returns the last fully resolved routing path, without the prefix. */\n        get(): string;\n        /** Redirects to a matching route or to the default route if no matching routes can be found. */\n        set(route: string, data?: any, options?: RouteOptions): void;\n        /** Defines a router prefix which is a fragment of the URL that dictates the underlying strategy used by the router. */\n        prefix: string;\n        /** This Component renders a link <a href> that will use the current routing strategy */\n        Link: Component<RouteLinkAttrs>;\n        /** Returns the named parameter value from the current route. */\n        param(name: string): string;\n        /** Gets all route parameters. */\n        param(): any;\n    }\n\n    interface RequestOptions<T> {\n        /** The HTTP method to use. */\n        method?: string | undefined;\n        /** The data to be interpolated into the URL and serialized into the querystring. */\n        params?: { [key: string]: any } | undefined;\n        /** The data to be serialized into the request body. */\n        body?: (XMLHttpRequest['send'] extends (x: infer R) => any ? R : never) | (object & { [id: string]: any }) | undefined;\n        /** Whether the request should be asynchronous. Defaults to true. */\n        async?: boolean | undefined;\n        /** A username for HTTP authorization. */\n        user?: string | undefined;\n        /** A password for HTTP authorization. */\n        password?: string | undefined;\n        /** Whether to send cookies to 3rd party domains. */\n        withCredentials?: boolean | undefined;\n        /** Exposes the underlying XMLHttpRequest object for low-level configuration. */\n        config?(xhr: XMLHttpRequest, options: this): XMLHttpRequest | void;\n        /** Headers to append to the request before sending it. */\n        headers?: { [key: string]: string } | undefined;\n        /** A constructor to be applied to each object in the response. */\n        type?: new (o: any) => any;\n        /** A serialization method to be applied to data. Defaults to JSON.stringify, or if options.data is an instance of FormData, defaults to the identity function. */\n        serialize?(data: any): any;\n        /** A deserialization method to be applied to the response. Defaults to a small wrapper around JSON.parse that returns null for empty responses. */\n        deserialize?(data: string): T;\n        /** A hook to specify how the XMLHttpRequest response should be read. Useful for reading response headers and cookies. Defaults to a function that returns xhr.responseText */\n        extract?(xhr: XMLHttpRequest, options: this): T;\n        /**\n         * Force the use of the HTTP body section for data in GET requests when set to true,\n         * or the use of querystring for other HTTP methods when set to false.\n         * Defaults to false for GET requests and true for other methods.\n         */\n        useBody?: boolean | undefined;\n        /** If false, redraws mounted components upon completion of the request. If true, it does not. */\n        background?: boolean | undefined;\n        /** Milliseconds a request can take before automatically being terminated. */\n        timeout?: number | undefined;\n        /** The expected type of the response, as a legal value of XMLHttpRequest.responseType. */\n        responseType?: '' | 'arraybuffer' | 'blob' | 'document' | 'json' | 'text' | undefined;\n    }\n\n    interface JsonpOptions {\n        /** The data to be interpolated into the URL and serialized into the querystring. */\n        params?: { [id: string]: any } | undefined;\n        /** The data to be serialized into the request body. */\n        body?: any;\n        /** A constructor to be applied to each object in the response. */\n        type?: new (o: any) => any;\n        /** The name of the function that will be called as the callback. */\n        callbackName?: string | undefined;\n        /** The name of the querystring parameter name that specifies the callback name. */\n        callbackKey?: string | undefined;\n        /** If false, redraws mounted components upon completion of the request. If true, it does not. */\n        background?: boolean | undefined;\n    }\n\n    interface Redraw {\n        /** Manually triggers an asynchronous redraw of mounted components. */\n        (): void;\n        /** Manually triggers a synchronous redraw of mounted components. */\n        sync(): void;\n    }\n\n    type Params = object & ParamsRec;\n\n    interface ParamsRec {\n        // Ideally, it'd be this:\n        // `[key: string | number]: Params | !symbol & !object`\n        [key: string]: string | number | boolean | null | undefined | Params;\n    }\n\n    interface Static extends Hyperscript {\n        route: Route;\n        mount: typeof mount;\n        render: typeof render;\n        redraw: Re",
+  "2cee47aedc9b4d321e378d7020984adf005fef64:types/ospec/index.d.ts": "// Type definitions for ospec 4.0\n// Project: https://github.com/MithrilJS/mithril.js/tree/next/ospec\n// Definitions by: Már Örlygsson <https://github.com/maranomynet>\n//                 Mike Linkovich <https://github.com/spacejack>\n//                 Isiah Meadows <https://github.com/isiahmeadows>\n// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped\n// TypeScript Version: 3.1\n\ntype ObjectConstructor = new (...args: any[]) => any;\n\ndeclare namespace o {\n    type AssertionDescriber = (description: string) => void;\n\n    interface Spy<Args extends any[], Returns> {\n        (...args: Args): Returns;\n        /** The number of times the function has been called */\n        readonly callCount: number;\n        /** The arguments that were passed to the function in the last time it was called */\n        readonly args: Args;\n        /** List of arguments that were passed to the function each tine it was called */\n        readonly calls: Args[];\n    }\n\n    interface Assertion<T> {\n        /** Asserts that two values are strictly equal */\n        equals(expected: T): AssertionDescriber;\n        /** Asserts that two values are **not** strictly equal */\n        notEquals(value: T): AssertionDescriber;\n\n        /** Asserts that two objects are recursively equal */\n        deepEquals(expected: T): AssertionDescriber;\n        /** Asserts that two objects are **not** recursively equal */\n        notDeepEquals(value: T): AssertionDescriber;\n\n        /** Asserts that the function throws an error of a given type */\n        throws(this: Assertion<() => any>, error: string | ObjectConstructor): AssertionDescriber;\n        /** Asserts that the function does **not** throw an error of given type */\n        notThrows(this: Assertion<() => any>, error: string | ObjectConstructor): AssertionDescriber; // See above\n    }\n\n    type Definer = (done: (error?: Error | null) => void, timeout: (delay: number) => void) => void | PromiseLike<any>;\n\n    interface Result {\n        pass: boolean | null;\n        context: string;\n        message: string;\n        error: Error | null;\n        testError: Error | null;\n    }\n\n    type Reporter = (results: Result[]) => number;\n\n    interface Ospec {\n        /** Starts an assertion */\n        <T>(actual: T): Assertion<T>;\n\n        /** Defines a test */\n        (name: string, assertions: Definer): void;\n\n        /** Defines a test */\n        only(name: string, assertions: Definer): void;\n\n        /** Defines a group of tests */\n        spec(name: string, tests: () => void): void;\n\n        /** Defines code to be run at the beginning of a test group */\n        before(setup: Definer): void;\n        /** Defines code to be run before each test in a group */\n        beforeEach(teardown: Definer): void;\n        /** Defines code to be run at the end of a test group */\n        after(setup: Definer): void;\n        /** Defines code to be run after each test in a group */\n        afterEach(teardown: Definer): void;\n\n        /** Returns a function that records the number of times it gets called, and its arguments */\n        spy<A extends any[]>(): Spy<A, undefined>; // tslint:disable-line:no-unnecessary-generics\n        spy<A extends any[], R>(fn: (...args: A) => R): Spy<A, R>;\n\n        /** Amount of time (in milliseconds) to wait until bailing out of a test */\n        timeout(delay: number): void;\n        /** Configure the default amount of time (in milliseconds) to wait until bailing out of a group of tests */\n        specTimeout(delay: number): void;\n\n        /** Runs the test suite */\n        run(reporter?: Reporter): void;\n        /** Default reporter used by `o.run()` */\n        report: Reporter;\n\n        'new'(): Ospec;\n    }\n}\n\ndeclare const o: o.Ospec;\nexport = o;\nexport as namespace o;\n",
+  "9ba7dfc289e4ce1023a9d398b9e04a91ae3a9070:types/ospec/index.d.ts": "// Type definitions for ospec 4.0\n// Project: https://github.com/MithrilJS/mithril.js/tree/next/ospec\n// Definitions by: Már Örlygsson <https://github.com/maranomynet>\n//                 Mike Linkovich <https://github.com/spacejack>\n// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped\n// TypeScript Version: 3.1\n\ntype ObjectConstructor = new (...args: any[]) => any;\n\ndeclare namespace o {\n    type AssertionDescriber = (description: string) => void;\n\n    interface Spy<Args extends any[], Returns> {\n        (...args: Args): Returns;\n        /** The number of times the function has been called */\n        readonly callCount: number;\n        /** The arguments that were passed to the function in the last time it was called */\n        readonly args: Args;\n        /** List of arguments that were passed to the function each tine it was called */\n        readonly calls: Args[];\n    }\n\n    interface Assertion<T> {\n        /** Asserts that two values are strictly equal */\n        equals(expected: T): AssertionDescriber;\n        /** Asserts that two values are **not** strictly equal */\n        notEquals(value: T): AssertionDescriber;\n\n        /** Asserts that two objects are recursively equal */\n        deepEquals(expected: T): AssertionDescriber;\n        /** Asserts that two objects are **not** recursively equal */\n        notDeepEquals(value: T): AssertionDescriber;\n\n        /** Asserts that the function throws an error of a given type */\n        throws(this: Assertion<() => any>, error: string | ObjectConstructor): AssertionDescriber;\n        /** Asserts that the function does **not** throw an error of given type */\n        notThrows(this: Assertion<() => any>, error: string | ObjectConstructor): AssertionDescriber; // See above\n    }\n\n    type Definer = (done: (error?: Error | null) => void, timeout: (delay: number) => void) => void | PromiseLike<any>;\n\n    interface Result {\n        pass: boolean | null;\n        context: string;\n        message: string;\n        error: Error | null;\n        testError: Error | null;\n    }\n\n    type Reporter = (results: Result[]) => number;\n\n    interface Ospec {\n        /** Starts an assertion */\n        <T>(actual: T): Assertion<T>;\n\n        /** Defines a test */\n        (name: string, assertions: Definer): void;\n\n        /** Defines a test */\n        only(name: string, assertions: Definer): void;\n\n        /** Defines a group of tests */\n        spec(name: string, tests: () => void): void;\n\n        /** Defines code to be run at the beginning of a test group */\n        before(setup: Definer): void;\n        /** Defines code to be run before each test in a group */\n        beforeEach(teardown: Definer): void;\n        /** Defines code to be run at the end of a test group */\n        after(setup: Definer): void;\n        /** Defines code to be run after each test in a group */\n        afterEach(teardown: Definer): void;\n\n        /** Returns a function that records the number of times it gets called, and its arguments */\n        spy<A extends any[]>(): Spy<A, undefined>; // tslint:disable-line:no-unnecessary-generics\n        spy<A extends any[], R>(fn: (...args: A) => R): Spy<A, R>;\n\n        /** Amount of time (in milliseconds) to wait until bailing out of a test */\n        timeout(delay: number): void;\n        /** Configure the default amount of time (in milliseconds) to wait until bailing out of a group of tests */\n        specTimeout(delay: number): void;\n\n        /** Runs the test suite */\n        run(reporter?: Reporter): void;\n        /** Default reporter used by `o.run()` */\n        report: Reporter;\n\n        'new'(): Ospec;\n    }\n}\n\ndeclare const o: o.Ospec;\nexport = o;\nexport as namespace o;\n",
+  "2cee47aedc9b4d321e378d7020984adf005fef64:types/react-grid-layout/index.d.ts": "// Type definitions for react-grid-layout 1.3\n// Project: https://github.com/STRML/react-grid-layout\n// Definitions by: Andrew Birkholz <https://github.com/abirkholz>,\n//                 Ali Taheri <https://github.com/alitaheri>,\n//                 Zheyang Song <https://github.com/ZheyangSong>,\n//                 Andrew Hathaway <https://github.com/andrewhathaway>,\n//                 Manav Mishra <https://github.com/manav-m>,\n//                 Alexey Fyodorov <https://github.com/al-fyodorov>,\n//                 Catus Magnus <https://github.com/catusmagnus>\n// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped\n// TypeScript Version: 2.8\n\nimport * as React from 'react';\n\nexport as namespace ReactGridLayout;\nexport = ReactGridLayout;\n\ndeclare class ReactGridLayout extends React.Component<ReactGridLayout.ReactGridLayoutProps> {}\n\ntype ResizeHandle = 's' | 'w' | 'e' | 'n' | 'sw' | 'nw' | 'se' | 'ne';\n\ndeclare namespace ReactGridLayout {\n    interface Layout {\n        /**\n         * A string corresponding to the component key.\n         * Uses the index of components instead if not provided.\n         */\n        i: string;\n\n        /**\n         * X position in grid units.\n         */\n        x: number;\n\n        /**\n         * Y position in grid units.\n         */\n        y: number;\n\n        /**\n         * Width in grid units.\n         */\n        w: number;\n\n        /**\n         * Height in grid units.\n         */\n        h: number;\n\n        /**\n         * Minimum width in grid units.\n         */\n        minW?: number | undefined;\n\n        /**\n         * Maximum width in grid units.\n         */\n        maxW?: number | undefined;\n\n        /**\n         * Minimum height in grid units.\n         */\n        minH?: number | undefined;\n\n        /**\n         * Maximum height in grid units.\n         */\n        maxH?: number | undefined;\n\n        /**\n         * set by DragEvents (onDragStart, onDrag, onDragStop) and ResizeEvents (onResizeStart, onResize, onResizeStop)\n         */\n        moved?: boolean | undefined;\n\n        /**\n         * If true, equal to `isDraggable: false` and `isResizable: false`.\n         */\n        static?: boolean | undefined;\n\n        /**\n         * If false, will not be draggable. Overrides `static`.\n         */\n        isDraggable?: boolean | undefined;\n\n        /**\n         * If false, will not be resizable. Overrides `static`.\n         */\n        isResizable?: boolean | undefined;\n\n        /**\n         * By default, a handle is only shown on the bottom-right (southeast) corner.\n         * Note that resizing from the top or left is generally not intuitive.\n         */\n        resizeHandles?: ResizeHandle[] | undefined;\n\n        /**\n         * If true and draggable, item will be moved only within grid.\n         */\n        isBounded?: boolean | undefined;\n    }\n\n    interface Layouts {\n        [P: string]: Layout[];\n    }\n\n    type ItemCallback = (\n        layout: Layout[],\n        oldItem: Layout,\n        newItem: Layout,\n        placeholder: Layout,\n        event: MouseEvent,\n        element: HTMLElement,\n    ) => void;\n\n    type DragOverEvent = MouseEvent & {\n        nativeEvent: {\n            layerX: number,\n            layerY: number,\n        } & Event\n    };\n\n    interface CoreProps {\n        /**\n         * The classname to add to the root element.\n         */\n        className?: string | undefined;\n\n        /**\n         * Inline-style object to pass to the root element.\n         */\n        style?: React.CSSProperties | undefined;\n\n        /**\n         * This allows setting the initial width on the server side.\n         * This is required unless using the HOC <WidthProvider> or similar.\n         */\n        width?: number | undefined;\n\n        /**\n         * If true, the container height swells and contracts to fit contents.\n         */\n        autoSize?: boolean | undefined;\n\n        /**\n         * A CSS selector for tags that will not be draggable.\n         * For example: `draggableCancel: '.MyNonDraggableAreaClassName'`\n         * If you forget the leading. it will not work.\n         * \"\".react-resizable-handle\" is always prepended to this value.\n         */\n        draggableCancel?: string | undefined;\n\n        /**\n         * A CSS selector for tags that will act as the draggable handle.\n         * For example: `draggableHandle: '.MyDragHandleClassName'`\n         * If you forget the leading . it will not work.\n         */\n        draggableHandle?: string | undefined;\n\n        /**\n         * Compaction type.\n         */\n        compactType?: 'vertical' | 'horizontal' | null | undefined;\n\n        /**\n         * Rows have a static height, but you can change this based on breakpoints if you like.\n         */\n        rowHeight?: number | undefined;\n\n        /**\n         * Configuration of a dropping element. Dropping element is a \"virtual\" element\n         * which appears when you drag over some element from outside.\n         */\n        droppingItem?: {\n            i: string;\n            w: number;\n            h: number;\n        } | undefined;\n\n        /**\n         * If true, the layout will compact vertically.\n         */\n        verticalCompact?: boolean | undefined;\n\n        /**\n         * Default Infinity, but you can specify a max here if you like.\n         * Note that this isn't fully fleshed out and won't error if you specify a layout that\n         * extends beyond the row capacity. It will, however, not allow users to drag/resize\n         * an item past the barrier. They can push items beyond the barrier, though.\n         * Intentionally not documented for this reason.\n         */\n        maxRows?: number | undefined;\n\n        // Flags:\n\n        /**\n         * If set to false it will disable dragging on all children.\n         */\n        isDraggable?: boolean | undefined;\n\n        /**\n         * If set to false it will disable resizing on all children.\n         */\n        isResizable?: boolean | undefined;\n\n        /**\n         * If true and draggable, all items will be moved only within grid.\n         */\n        isBounded?: boolean | undefined;\n\n        /**\n         * Uses CSS3 `translate()` instead of position top/left.\n         * This makes about 6x faster paint performance.\n         */\n        useCSSTransforms?: boolean | undefined;\n\n        /**\n         * If parent DOM node of ResponsiveReactGridLayout or ReactGridLayout has \"transform: scale(n)\" css property,\n         * we should set scale coefficient to avoid render artefacts while dragging.\n         */\n        transformScale?: number | undefined;\n\n        /**\n         * If true, grid can be placed one over the other.\n         */\n        allowOverlap?: boolean | undefined;\n\n        /**\n         * If true, grid items won't change position when being dragged over.\n         */\n        preventCollision?: boolean | undefined;\n\n        /**\n         * If true, droppable elements (with `draggable={true}` attribute)\n         * can be dropped on the grid. It triggers \"onDrop\" callback\n         * with position and event object as parameters.\n         * It can be useful for dropping an element in a specific position\n         * NOTE: In case of using Firefox you should add\n         * `onDragStart={e => e.dataTransfer.setData('text/plain', '')}` attribute\n         * along with `draggable={true}` otherwise this feature will work incorrect.\n         * onDragStart attribute is required for Firefox for a dragging initialization\n         * @see https://bugzilla.mozilla.org/show_bug.cgi?id=568313\n         */\n        isDroppable?: boolean | undefined;\n\n        /**\n         * Defines which resize handles should be rendered\n         * Allows for any combination of:\n         * 's' - South handle (bottom-center)\n         * 'w' - West handle (left-center)\n         * 'e' - East handle (right-center)\n         * 'n' - North handle (top-center)\n         * 'sw' - Southwest handle (bottom-left)\n         * 'nw' - Northwest handle (top-left)\n         * 'se' - Southeast handle (bottom-right)\n         * 'ne' - Northeast handle (top-right)\n         */\n        resizeHandles?: ResizeHandle[] | undefined;\n\n        /**\n         * Defines custom component for resize handle\n         */\n        resizeHandle?: React.ReactNode | ((resizeHandle: ResizeHandle) => React.ReactNode) | undefined;\n\n        /**\n         * Calls when drag starts.\n         */\n        onDragStart?: ItemCallback | undefined;\n\n        /**\n         * Calls on each drag movement.\n         */\n        onDrag?: ItemCallback | undefined;\n\n        /**\n         * Calls when drag is complete.\n         */\n        onDragStop?: ItemCallback | undefined;\n\n        /**\n         * Calls when resize starts.\n         */\n        onResizeStart?: ItemCallback | undefined;\n\n        /**\n         * Calls when resize movement happens.\n         */\n        onResize?: ItemCallback | undefined;\n\n        /**\n         * Calls when resize is complete.\n         */\n        onResizeStop?: ItemCallback | undefined;\n\n        /**\n         * Calls when some element has been dropped\n         */\n        onDrop?(layout: Layout[], item: Layout, e: Event): void;\n\n        /**\n         * Calls when an element is being dragged over the grid from outside as above.\n         * This callback should return an object to dynamically change the droppingItem size\n         * Return false to short-circuit the dragover\n         */\n        onDropDragOver?(e: DragOverEvent): { w?: number, h?: number } | false | undefined;\n\n        /**\n         * Ref for getting a reference for the grid's wrapping div.\n         * You can use this instead of a regular ref and the deprecated `ReactDOM.findDOMNode()`` function.\n         */\n        innerRef?: React.Ref<HTMLDivElement>;\n    }\n\n    interface ReactGridLayoutProps extends CoreProps {\n        children?: React.ReactNode;\n\n        /**\n         * Number of columns in this layout.\n         */\n        cols?: number | undefined;\n\n        /**\n         * Margin between items `[x, y]` in px.\n         */\n        margin?: [number, number] | undefined;\n\n        /**\n         * Padding inside the container `[x, y]` in px.\n         */\n        containerPadding?: [number, number] | undefined;\n\n        /**\n         * Layout is an array of object with the format:\n    ",
+  "9ba7dfc289e4ce1023a9d398b9e04a91ae3a9070:types/react-grid-layout/index.d.ts": "// Type definitions for react-grid-layout 1.3\n// Project: https://github.com/STRML/react-grid-layout\n// Definitions by: Andrew Birkholz <https://github.com/abirkholz>\n//                 Ali Taheri <https://github.com/alitaheri>\n//                 Zheyang Song <https://github.com/ZheyangSong>\n//                 Andrew Hathaway <https://github.com/andrewhathaway>\n//                 Manav Mishra <https://github.com/manav-m>\n//                 Alexey Fyodorov <https://github.com/al-fyodorov>\n// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped\n// TypeScript Version: 2.8\n\nimport * as React from 'react';\n\nexport as namespace ReactGridLayout;\nexport = ReactGridLayout;\n\ndeclare class ReactGridLayout extends React.Component<ReactGridLayout.ReactGridLayoutProps> {}\n\ntype ResizeHandle = 's' | 'w' | 'e' | 'n' | 'sw' | 'nw' | 'se' | 'ne';\n\ndeclare namespace ReactGridLayout {\n    interface Layout {\n        /**\n         * A string corresponding to the component key.\n         * Uses the index of components instead if not provided.\n         */\n        i: string;\n\n        /**\n         * X position in grid units.\n         */\n        x: number;\n\n        /**\n         * Y position in grid units.\n         */\n        y: number;\n\n        /**\n         * Width in grid units.\n         */\n        w: number;\n\n        /**\n         * Height in grid units.\n         */\n        h: number;\n\n        /**\n         * Minimum width in grid units.\n         */\n        minW?: number | undefined;\n\n        /**\n         * Maximum width in grid units.\n         */\n        maxW?: number | undefined;\n\n        /**\n         * Minimum height in grid units.\n         */\n        minH?: number | undefined;\n\n        /**\n         * Maximum height in grid units.\n         */\n        maxH?: number | undefined;\n\n        /**\n         * set by DragEvents (onDragStart, onDrag, onDragStop) and ResizeEvents (onResizeStart, onResize, onResizeStop)\n         */\n        moved?: boolean | undefined;\n\n        /**\n         * If true, equal to `isDraggable: false` and `isResizable: false`.\n         */\n        static?: boolean | undefined;\n\n        /**\n         * If false, will not be draggable. Overrides `static`.\n         */\n        isDraggable?: boolean | undefined;\n\n        /**\n         * If false, will not be resizable. Overrides `static`.\n         */\n        isResizable?: boolean | undefined;\n\n        /**\n         * By default, a handle is only shown on the bottom-right (southeast) corner.\n         * Note that resizing from the top or left is generally not intuitive.\n         */\n        resizeHandles?: ResizeHandle[] | undefined;\n\n        /**\n         * If true and draggable, item will be moved only within grid.\n         */\n        isBounded?: boolean | undefined;\n    }\n\n    interface Layouts {\n        [P: string]: Layout[];\n    }\n\n    type ItemCallback = (\n        layout: Layout[],\n        oldItem: Layout,\n        newItem: Layout,\n        placeholder: Layout,\n        event: MouseEvent,\n        element: HTMLElement,\n    ) => void;\n\n    type DragOverEvent = MouseEvent & {\n        nativeEvent: {\n            layerX: number,\n            layerY: number,\n        } & Event\n    };\n\n    interface CoreProps {\n        /**\n         * The classname to add to the root element.\n         */\n        className?: string | undefined;\n\n        /**\n         * Inline-style object to pass to the root element.\n         */\n        style?: React.CSSProperties | undefined;\n\n        /**\n         * This allows setting the initial width on the server side.\n         * This is required unless using the HOC <WidthProvider> or similar.\n         */\n        width?: number | undefined;\n\n        /**\n         * If true, the container height swells and contracts to fit contents.\n         */\n        autoSize?: boolean | undefined;\n\n        /**\n         * A CSS selector for tags that will not be draggable.\n         * For example: `draggableCancel: '.MyNonDraggableAreaClassName'`\n         * If you forget the leading. it will not work.\n         * \"\".react-resizable-handle\" is always prepended to this value.\n         */\n        draggableCancel?: string | undefined;\n\n        /**\n         * A CSS selector for tags that will act as the draggable handle.\n         * For example: `draggableHandle: '.MyDragHandleClassName'`\n         * If you forget the leading . it will not work.\n         */\n        draggableHandle?: string | undefined;\n\n        /**\n         * Compaction type.\n         */\n        compactType?: 'vertical' | 'horizontal' | null | undefined;\n\n        /**\n         * Rows have a static height, but you can change this based on breakpoints if you like.\n         */\n        rowHeight?: number | undefined;\n\n        /**\n         * Configuration of a dropping element. Dropping element is a \"virtual\" element\n         * which appears when you drag over some element from outside.\n         */\n        droppingItem?: {\n            i: string;\n            w: number;\n            h: number;\n        } | undefined;\n\n        /**\n         * If true, the layout will compact vertically.\n         */\n        verticalCompact?: boolean | undefined;\n\n        /**\n         * Default Infinity, but you can specify a max here if you like.\n         * Note that this isn't fully fleshed out and won't error if you specify a layout that\n         * extends beyond the row capacity. It will, however, not allow users to drag/resize\n         * an item past the barrier. They can push items beyond the barrier, though.\n         * Intentionally not documented for this reason.\n         */\n        maxRows?: number | undefined;\n\n        // Flags:\n\n        /**\n         * If set to false it will disable dragging on all children.\n         */\n        isDraggable?: boolean | undefined;\n\n        /**\n         * If set to false it will disable resizing on all children.\n         */\n        isResizable?: boolean | undefined;\n\n        /**\n         * If true and draggable, all items will be moved only within grid.\n         */\n        isBounded?: boolean | undefined;\n\n        /**\n         * Uses CSS3 `translate()` instead of position top/left.\n         * This makes about 6x faster paint performance.\n         */\n        useCSSTransforms?: boolean | undefined;\n\n        /**\n         * If parent DOM node of ResponsiveReactGridLayout or ReactGridLayout has \"transform: scale(n)\" css property,\n         * we should set scale coefficient to avoid render artefacts while dragging.\n         */\n        transformScale?: number | undefined;\n\n        /**\n         * If true, grid can be placed one over the other.\n         */\n        allowOverlap?: boolean | undefined;\n\n        /**\n         * If true, grid items won't change position when being dragged over.\n         */\n        preventCollision?: boolean | undefined;\n\n        /**\n         * If true, droppable elements (with `draggable={true}` attribute)\n         * can be dropped on the grid. It triggers \"onDrop\" callback\n         * with position and event object as parameters.\n         * It can be useful for dropping an element in a specific position\n         * NOTE: In case of using Firefox you should add\n         * `onDragStart={e => e.dataTransfer.setData('text/plain', '')}` attribute\n         * along with `draggable={true}` otherwise this feature will work incorrect.\n         * onDragStart attribute is required for Firefox for a dragging initialization\n         * @see https://bugzilla.mozilla.org/show_bug.cgi?id=568313\n         */\n        isDroppable?: boolean | undefined;\n\n        /**\n         * Defines which resize handles should be rendered\n         * Allows for any combination of:\n         * 's' - South handle (bottom-center)\n         * 'w' - West handle (left-center)\n         * 'e' - East handle (right-center)\n         * 'n' - North handle (top-center)\n         * 'sw' - Southwest handle (bottom-left)\n         * 'nw' - Northwest handle (top-left)\n         * 'se' - Southeast handle (bottom-right)\n         * 'ne' - Northeast handle (top-right)\n         */\n        resizeHandles?: ResizeHandle[] | undefined;\n\n        /**\n         * Defines custom component for resize handle\n         */\n        resizeHandle?: React.ReactNode | ((resizeHandle: ResizeHandle) => React.ReactNode) | undefined;\n\n        /**\n         * Calls when drag starts.\n         */\n        onDragStart?: ItemCallback | undefined;\n\n        /**\n         * Calls on each drag movement.\n         */\n        onDrag?: ItemCallback | undefined;\n\n        /**\n         * Calls when drag is complete.\n         */\n        onDragStop?: ItemCallback | undefined;\n\n        /**\n         * Calls when resize starts.\n         */\n        onResizeStart?: ItemCallback | undefined;\n\n        /**\n         * Calls when resize movement happens.\n         */\n        onResize?: ItemCallback | undefined;\n\n        /**\n         * Calls when resize is complete.\n         */\n        onResizeStop?: ItemCallback | undefined;\n\n        /**\n         * Calls when some element has been dropped\n         */\n        onDrop?(layout: Layout[], item: Layout, e: Event): void;\n\n        /**\n         * Calls when an element is being dragged over the grid from outside as above.\n         * This callback should return an object to dynamically change the droppingItem size\n         * Return false to short-circuit the dragover\n         */\n        onDropDragOver?(e: DragOverEvent): { w?: number, h?: number } | false | undefined;\n\n        /**\n         * Ref for getting a reference for the grid's wrapping div.\n         * You can use this instead of a regular ref and the deprecated `ReactDOM.findDOMNode()`` function.\n         */\n        innerRef?: React.Ref<HTMLDivElement>;\n    }\n\n    interface ReactGridLayoutProps extends CoreProps {\n        children?: React.ReactNode;\n\n        /**\n         * Number of columns in this layout.\n         */\n        cols?: number | undefined;\n\n        /**\n         * Margin between items `[x, y]` in px.\n         */\n        margin?: [number, number] | undefined;\n\n        /**\n         * Padding inside the container `[x, y]` in px.\n         */\n        containerPadding?: [number, number] | undefined;\n\n        /**\n         * Layout is an array of object with the format:\n         *\n         * `{x: number, y: number, w: number, h: number}`\n      ",
+  "2cee47aedc9b4d321e378d7020984adf005fef64:types/react-native-fbsdk/index.d.ts": "// Type definitions for react-native-fbsdk 3.0\n// Project: https://github.com/facebook/react-native-fbsdk\n// Definitions by: Ifiok Jr. <https://github.com/ifiokjr>\n//                 Thibault Malbranche <https://github.com/titozzz>\n//                 Stuart Forrest <https://github.com/stuartforrest-infinity>\n//                 Un Ha Kim <https://github.com/UHKim>\n// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped\n// TypeScript Version: 2.8\n\nimport { ComponentClass, Component } from 'react';\nimport { ViewStyle } from 'react-native';\n\n/**\n * Commonly used Facebook permissions\n */\nexport type Permissions =\n    | 'public_profile'\n    | 'user_friends'\n    | 'email'\n    | 'user_about_me'\n    | 'user_actions.books'\n    | 'user_actions.fitness'\n    | 'user_actions.music'\n    | 'user_actions.news'\n    | 'user_actions.video'\n    | 'user_birthday'\n    | 'user_education_history'\n    | 'user_events'\n    | 'user_games_activity'\n    | 'user_hometown'\n    | 'user_likes'\n    | 'user_location'\n    | 'user_managed_groups'\n    | 'user_photos'\n    | 'user_posts'\n    | 'user_relationships'\n    | 'user_relationship_details'\n    | 'user_religion_politics'\n    | 'user_tagged_places'\n    | 'user_videos'\n    | 'user_website'\n    | 'user_work_history'\n    | 'read_custom_friendlists'\n    | 'read_insights'\n    | 'read_audience_network_insights'\n    | 'read_page_mailboxes'\n    | 'manage_pages'\n    | 'publish_pages'\n    | 'publish_actions'\n    | 'rsvp_event'\n    | 'pages_show_list'\n    | 'pages_manage_cta'\n    | 'pages_manage_instant_articles'\n    | 'ads_read'\n    | 'ads_management'\n    | 'business_management'\n    | 'pages_messaging'\n    | 'pages_messaging_subscriptions'\n    | 'pages_messaging_payments'\n    | 'pages_messaging_phone_number'\n    | string;\n\n/**\n * Specifies the privacy of a group.\n */\nexport type AppGroupPrivacy =\n    // Anyone can see the group, who's in in and what members post.\n    | 'Open'\n    // Anyone can see the group and who's in it, but only members can see posts.\n    | 'Closed';\n\n/**\n * A model for app groups.\n */\nexport interface AppGroupCreationContent {\n    /**\n     * The description of the group.\n     */\n    description: string;\n\n    /**\n     * The name of the group.\n     */\n    name: string;\n\n    /**\n     * The privacy for the group.\n     */\n    privacy: AppGroupPrivacy;\n}\n\n/**\n * A model for app invites.\n */\nexport interface AppInviteContent {\n    /**\n     * A URL to a preview image that will be displayed with the app invite.\n     * This is optional. If you don't include it, a fallback image will be used.\n     */\n    previewImageUrl?: string | undefined;\n\n    /**\n     * An app link target that will be used as a target when the user accepts the invite.\n     */\n    applinkUrl: string;\n\n    /**\n     * Promotional code to be displayed while sending and receiving the invite.\n     * This is optional. This can be between 0 and 10 characters long and can contain\n     * alphanumeric characters only. To set a promo code, you need to set promo text.\n     */\n    promotionCode?: string | undefined;\n\n    /**\n     * Promotional text to be displayed while sending and receiving the invite.\n     * This is optional. This can be between 0 and 80 characters long and can contain\n     * alphanumeric and spaces only.\n     */\n    promotionText?: string | undefined;\n}\n\nexport type GameRequestActionType =\n    // The user is sending an object to their friends.\n    | 'send'\n    // The user is asking for an object from friends.\n    | 'askfor'\n    // It is the turn of the friends to play against the user in a match.\n    | 'turn';\n\nexport type GameRequestFilters =\n    // Friends using the app can be displayed.\n    | 'app_users'\n    // Friends not using the app can be displayed.\n    | 'app_non_users';\n\n/**\n * A model for a game request.\n */\nexport interface GameRequestContent {\n    /**\n     * A plain-text message to be sent as part of the request.  Required.\n     */\n    message: string;\n\n    /**\n     * Used when defining additional context about the nature of the request.\n     * The parameter 'objectID' is required if the action type is either 'send' or 'ask-for'.\n     */\n    actionType?: GameRequestActionType | undefined;\n\n    /**\n     * Additional freeform data you may pass for tracking. The maximum length is 255 characters.\n     */\n    data?: string | undefined;\n\n    /**\n     * Controls the set of friends someone sees if a multi-friend selector is shown.\n     */\n    filters?: GameRequestFilters | undefined;\n\n    /**\n     * The Open Graph object ID of the object being sent/asked for. This cannot be null for ActionType SEND and\n     * ASKFOR.\n     */\n    objectId?: string | undefined;\n\n    /**\n     * An array of user IDs, usernames or invite tokens of people to send requests to.\n     */\n    recipients?: string[] | undefined;\n\n    /**\n     * An array of user IDs that will be included in the dialog as the first suggested friends.\n     * Can't be used together with filters.\n     */\n    suggestions?: string[] | undefined;\n\n    /**\n     * The title for the dialog.\n     */\n    title?: string | undefined;\n}\n\nexport type ObjectIdActionType = 'unknown' | 'open_graph' | 'page';\n\n/**\n * A base interface for content to be shared.\n */\nexport interface ObjectIdAndType {\n    /**\n     * The object ID, this can be a URL or a Facebook ID.\n     */\n    objectId: string;\n\n    /**\n     * Encapsulates the valid values for the facebook:object_type\n     * attribute for a LikeView\n     */\n    objectType: ObjectIdActionType;\n}\n\nexport type ShareContent = ShareLinkContent | SharePhotoContent | ShareVideoContent | ShareOpenGraphContent;\n/**\n * A base interface for content to be shared.\n */\nexport interface ShareContentCommonParameters {\n    /**\n     * List of IDs for taggable people to tag with this content.\n     */\n    peopleIds?: string[] | undefined;\n\n    /**\n     * The ID for a place to tag with this content.\n     */\n    placeId?: string | undefined;\n\n    /**\n     * A value to be added to the referrer URL when a person follows a link from\n     * this shared content on feed.\n     */\n    ref?: string | undefined;\n\n    /**\n     * A hashtag to be added to the share interface. The hashtag must be 32 characters or less.\n     */\n    hashtag?: string | undefined;\n}\n\n/**\n * A model for status and link content to be shared.\n */\nexport interface ShareLinkContent {\n    /**\n     * The type of content to be shared is link.\n     */\n    contentType: 'link';\n\n    /**\n     * Common parameters for share content;\n     */\n    commonParameters?: ShareContentCommonParameters | undefined;\n\n    /**\n     * URL for the content being shared.\n     */\n    contentUrl: string;\n\n    /**\n     * The Description of the link.\n     * If not specified, this field is automatically populated by information scraped\n     * from the contentURL,  typically the title of the page.\n     * @deprecated `contentDescription` is deprecated from Graph API 2.9.\n     * For more information, see https://developers.facebook.com/docs/apps/changelog#v2_9_deprecations.\n     */\n    contentDescription?: string | undefined;\n\n    /**\n     * The title to display for this link.\n     * @deprecated `contentTitle` is deprecated from Graph API 2.9.\n     * For more information, see https://developers.facebook.com/docs/apps/changelog#v2_9_deprecations.\n     */\n    contentTitle?: string | undefined;\n\n    /**\n     * The URL of a picture to attach to this comment.\n     * @deprecated `imageUrl` is deprecated from Graph API 2.9.\n     * For more information, see https://developers.facebook.com/docs/apps/changelog#v2_9_deprecations.\n     */\n    imageUrl?: string | undefined;\n\n    /**\n     * The predefined quote to attach to this comment.\n     * If specified, the quote text will render with custom styling on top of the link.\n     */\n    quote?: string | undefined;\n}\n\nexport interface OpenGraphProperties {\n    [key: string]: OpenGraphValue;\n}\n\nexport interface OpenGraphValue {\n    type: OpenGraphValueType;\n\n    value: any;\n}\n\nexport type OpenGraphValueType = 'number' | 'open-graph-object' | 'photo' | 'string';\n\nexport interface ShareOpenGraphValueContainer {\n    /**\n     * Sets a number for the specified key.\n     */\n    putNumber(key: string, number: number): void;\n\n    /**\n     * Sets an open graph object for the specified key.\n     */\n    putObject(key: string, object: ShareOpenGraphValueContainer): void;\n\n    /**\n     * Sets a photo for the specified key.\n     */\n    putPhoto(key: string, photo: SharePhoto): void;\n\n    /**\n     * Sets a string for the specified key.\n     */\n    putString(key: string, string: string): void;\n\n    /**\n     * Gets an entry for the given key.\n     */\n    getEntry(key: string): OpenGraphValue;\n}\n\n/**\n * Represents an interface for adding and retrieving values to open graph objects and actions.\n */\nexport class ShareOpenGraphValueContainer {\n    private _properties: OpenGraphProperties;\n\n    constructor(properties: OpenGraphProperties);\n}\n\n/**\n * Represents an open graph action.\n */\nexport class ShareOpenGraphAction extends ShareOpenGraphValueContainer {\n    /**\n     * The action type.\n     */\n    actionType: string;\n\n    constructor(actionType: string);\n}\n\n/**\n * Represents a content object containing information about an Open Graph Action.\n */\nexport interface ShareOpenGraphContent {\n    /**\n     * The type of content to be shared is open graph content.\n     */\n    contentType: 'open-graph';\n\n    /**\n     * Common parameters for share content;\n     */\n    commonParameters?: ShareContentCommonParameters | undefined;\n\n    /**\n     * URL for the content being shared.\n     */\n    contentUrl?: string | undefined;\n\n    /**\n     * Open Graph Action to be shared.\n     */\n    action: ShareOpenGraphAction;\n\n    /**\n     * Property name that points to the primary Open Graph Object in the action.\n     */\n    previewPropertyName: string;\n}\n\n/**\n * Represents an open graph object.\n */\nexport class ShareOpenGraphObject extends ShareOpenGraphValueContainer {}\n\n/**\n * A photo for sharing.\n */\nexport interface SharePhoto {\n    /**\n     * The URL to the photo.\n     * Note that when sharing SharePhotoContent with Share Button, the imageUrl\n     * of a SharePhoto cannot be the Uri of an image on the web.\n     */\n    imageUrl: string;\n\n    /**\n     * Speci",
+  "9ba7dfc289e4ce1023a9d398b9e04a91ae3a9070:types/react-native-fbsdk/index.d.ts": "// Type definitions for react-native-fbsdk 3.0\n// Project: https://github.com/facebook/react-native-fbsdk\n// Definitions by: Ifiok Jr. <https://github.com/ifiokjr>\n//                 Thibault Malbranche <https://github.com/titozzz>\n//                 Stuart Forrest <https://github.com/stuartforrest-infinity>\n// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped\n// TypeScript Version: 2.8\n\nimport { ComponentClass, Component } from 'react';\nimport { ViewStyle } from 'react-native';\n\n/**\n * Commonly used Facebook permissions\n */\nexport type Permissions =\n    | 'public_profile'\n    | 'user_friends'\n    | 'email'\n    | 'user_about_me'\n    | 'user_actions.books'\n    | 'user_actions.fitness'\n    | 'user_actions.music'\n    | 'user_actions.news'\n    | 'user_actions.video'\n    | 'user_birthday'\n    | 'user_education_history'\n    | 'user_events'\n    | 'user_games_activity'\n    | 'user_hometown'\n    | 'user_likes'\n    | 'user_location'\n    | 'user_managed_groups'\n    | 'user_photos'\n    | 'user_posts'\n    | 'user_relationships'\n    | 'user_relationship_details'\n    | 'user_religion_politics'\n    | 'user_tagged_places'\n    | 'user_videos'\n    | 'user_website'\n    | 'user_work_history'\n    | 'read_custom_friendlists'\n    | 'read_insights'\n    | 'read_audience_network_insights'\n    | 'read_page_mailboxes'\n    | 'manage_pages'\n    | 'publish_pages'\n    | 'publish_actions'\n    | 'rsvp_event'\n    | 'pages_show_list'\n    | 'pages_manage_cta'\n    | 'pages_manage_instant_articles'\n    | 'ads_read'\n    | 'ads_management'\n    | 'business_management'\n    | 'pages_messaging'\n    | 'pages_messaging_subscriptions'\n    | 'pages_messaging_payments'\n    | 'pages_messaging_phone_number'\n    | string;\n\n/**\n * Specifies the privacy of a group.\n */\nexport type AppGroupPrivacy =\n    // Anyone can see the group, who's in in and what members post.\n    | 'Open'\n    // Anyone can see the group and who's in it, but only members can see posts.\n    | 'Closed';\n\n/**\n * A model for app groups.\n */\nexport interface AppGroupCreationContent {\n    /**\n     * The description of the group.\n     */\n    description: string;\n\n    /**\n     * The name of the group.\n     */\n    name: string;\n\n    /**\n     * The privacy for the group.\n     */\n    privacy: AppGroupPrivacy;\n}\n\n/**\n * A model for app invites.\n */\nexport interface AppInviteContent {\n    /**\n     * A URL to a preview image that will be displayed with the app invite.\n     * This is optional. If you don't include it, a fallback image will be used.\n     */\n    previewImageUrl?: string | undefined;\n\n    /**\n     * An app link target that will be used as a target when the user accepts the invite.\n     */\n    applinkUrl: string;\n\n    /**\n     * Promotional code to be displayed while sending and receiving the invite.\n     * This is optional. This can be between 0 and 10 characters long and can contain\n     * alphanumeric characters only. To set a promo code, you need to set promo text.\n     */\n    promotionCode?: string | undefined;\n\n    /**\n     * Promotional text to be displayed while sending and receiving the invite.\n     * This is optional. This can be between 0 and 80 characters long and can contain\n     * alphanumeric and spaces only.\n     */\n    promotionText?: string | undefined;\n}\n\nexport type GameRequestActionType =\n    // The user is sending an object to their friends.\n    | 'send'\n    // The user is asking for an object from friends.\n    | 'askfor'\n    // It is the turn of the friends to play against the user in a match.\n    | 'turn';\n\nexport type GameRequestFilters =\n    // Friends using the app can be displayed.\n    | 'app_users'\n    // Friends not using the app can be displayed.\n    | 'app_non_users';\n\n/**\n * A model for a game request.\n */\nexport interface GameRequestContent {\n    /**\n     * A plain-text message to be sent as part of the request.  Required.\n     */\n    message: string;\n\n    /**\n     * Used when defining additional context about the nature of the request.\n     * The parameter 'objectID' is required if the action type is either 'send' or 'ask-for'.\n     */\n    actionType?: GameRequestActionType | undefined;\n\n    /**\n     * Additional freeform data you may pass for tracking. The maximum length is 255 characters.\n     */\n    data?: string | undefined;\n\n    /**\n     * Controls the set of friends someone sees if a multi-friend selector is shown.\n     */\n    filters?: GameRequestFilters | undefined;\n\n    /**\n     * The Open Graph object ID of the object being sent/asked for. This cannot be null for ActionType SEND and\n     * ASKFOR.\n     */\n    objectId?: string | undefined;\n\n    /**\n     * An array of user IDs, usernames or invite tokens of people to send requests to.\n     */\n    recipients?: string[] | undefined;\n\n    /**\n     * An array of user IDs that will be included in the dialog as the first suggested friends.\n     * Can't be used together with filters.\n     */\n    suggestions?: string[] | undefined;\n\n    /**\n     * The title for the dialog.\n     */\n    title?: string | undefined;\n}\n\nexport type ObjectIdActionType = 'unknown' | 'open_graph' | 'page';\n\n/**\n * A base interface for content to be shared.\n */\nexport interface ObjectIdAndType {\n    /**\n     * The object ID, this can be a URL or a Facebook ID.\n     */\n    objectId: string;\n\n    /**\n     * Encapsulates the valid values for the facebook:object_type\n     * attribute for a LikeView\n     */\n    objectType: ObjectIdActionType;\n}\n\nexport type ShareContent = ShareLinkContent | SharePhotoContent | ShareVideoContent | ShareOpenGraphContent;\n/**\n * A base interface for content to be shared.\n */\nexport interface ShareContentCommonParameters {\n    /**\n     * List of IDs for taggable people to tag with this content.\n     */\n    peopleIds?: string[] | undefined;\n\n    /**\n     * The ID for a place to tag with this content.\n     */\n    placeId?: string | undefined;\n\n    /**\n     * A value to be added to the referrer URL when a person follows a link from\n     * this shared content on feed.\n     */\n    ref?: string | undefined;\n\n    /**\n     * A hashtag to be added to the share interface. The hashtag must be 32 characters or less.\n     */\n    hashtag?: string | undefined;\n}\n\n/**\n * A model for status and link content to be shared.\n */\nexport interface ShareLinkContent {\n    /**\n     * The type of content to be shared is link.\n     */\n    contentType: 'link';\n\n    /**\n     * Common parameters for share content;\n     */\n    commonParameters?: ShareContentCommonParameters | undefined;\n\n    /**\n     * URL for the content being shared.\n     */\n    contentUrl: string;\n\n    /**\n     * The Description of the link.\n     * If not specified, this field is automatically populated by information scraped\n     * from the contentURL,  typically the title of the page.\n     * @deprecated `contentDescription` is deprecated from Graph API 2.9.\n     * For more information, see https://developers.facebook.com/docs/apps/changelog#v2_9_deprecations.\n     */\n    contentDescription?: string | undefined;\n\n    /**\n     * The title to display for this link.\n     * @deprecated `contentTitle` is deprecated from Graph API 2.9.\n     * For more information, see https://developers.facebook.com/docs/apps/changelog#v2_9_deprecations.\n     */\n    contentTitle?: string | undefined;\n\n    /**\n     * The URL of a picture to attach to this comment.\n     * @deprecated `imageUrl` is deprecated from Graph API 2.9.\n     * For more information, see https://developers.facebook.com/docs/apps/changelog#v2_9_deprecations.\n     */\n    imageUrl?: string | undefined;\n\n    /**\n     * The predefined quote to attach to this comment.\n     * If specified, the quote text will render with custom styling on top of the link.\n     */\n    quote?: string | undefined;\n}\n\nexport interface OpenGraphProperties {\n    [key: string]: OpenGraphValue;\n}\n\nexport interface OpenGraphValue {\n    type: OpenGraphValueType;\n\n    value: any;\n}\n\nexport type OpenGraphValueType = 'number' | 'open-graph-object' | 'photo' | 'string';\n\nexport interface ShareOpenGraphValueContainer {\n    /**\n     * Sets a number for the specified key.\n     */\n    putNumber(key: string, number: number): void;\n\n    /**\n     * Sets an open graph object for the specified key.\n     */\n    putObject(key: string, object: ShareOpenGraphValueContainer): void;\n\n    /**\n     * Sets a photo for the specified key.\n     */\n    putPhoto(key: string, photo: SharePhoto): void;\n\n    /**\n     * Sets a string for the specified key.\n     */\n    putString(key: string, string: string): void;\n\n    /**\n     * Gets an entry for the given key.\n     */\n    getEntry(key: string): OpenGraphValue;\n}\n\n/**\n * Represents an interface for adding and retrieving values to open graph objects and actions.\n */\nexport class ShareOpenGraphValueContainer {\n    private _properties: OpenGraphProperties;\n\n    constructor(properties: OpenGraphProperties);\n}\n\n/**\n * Represents an open graph action.\n */\nexport class ShareOpenGraphAction extends ShareOpenGraphValueContainer {\n    /**\n     * The action type.\n     */\n    actionType: string;\n\n    constructor(actionType: string);\n}\n\n/**\n * Represents a content object containing information about an Open Graph Action.\n */\nexport interface ShareOpenGraphContent {\n    /**\n     * The type of content to be shared is open graph content.\n     */\n    contentType: 'open-graph';\n\n    /**\n     * Common parameters for share content;\n     */\n    commonParameters?: ShareContentCommonParameters | undefined;\n\n    /**\n     * URL for the content being shared.\n     */\n    contentUrl?: string | undefined;\n\n    /**\n     * Open Graph Action to be shared.\n     */\n    action: ShareOpenGraphAction;\n\n    /**\n     * Property name that points to the primary Open Graph Object in the action.\n     */\n    previewPropertyName: string;\n}\n\n/**\n * Represents an open graph object.\n */\nexport class ShareOpenGraphObject extends ShareOpenGraphValueContainer {}\n\n/**\n * A photo for sharing.\n */\nexport interface SharePhoto {\n    /**\n     * The URL to the photo.\n     * Note that when sharing SharePhotoContent with Share Button, the imageUrl\n     * of a SharePhoto cannot be the Uri of an image on the web.\n     */\n    imageUrl: string;\n\n    /**\n     * Specifies whether the photo was generated by the user or the ",
+  "2cee47aedc9b4d321e378d7020984adf005fef64:types/react-virtualized/index.d.ts": "// Type definitions for react-virtualized 9.21\n// Project: https://github.com/bvaughn/react-virtualized\n// Definitions by: Kalle Ott <https://github.com/kaoDev>\n//                 John Gunther <https://github.com/guntherjh>\n//                 Konstantin Nesterov <https://github.com/wasd171>\n//                 Steve Zhang <https://github.com/Stevearzh>\n//                 Maciej Goszczycki <https://github.com/mgoszcz2>\n//                 Brandon Hall <https://github.com/brandonhall>\n//                 Sebastian Busch <https://github.com/sbusch>\n//                 Adam Zmenak <https://github.com/azmenak>\n// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped\n// TypeScript Version: 2.8\n\nexport {\n    ArrowKeyStepper,\n    ArrowKeyStepperProps,\n    ChildProps as ArrowKeyStepperChildProps,\n    ScrollIndices,\n} from './dist/es/ArrowKeyStepper';\nexport { AutoSizer, AutoSizerProps, Dimensions, Size } from './dist/es/AutoSizer';\nexport {\n    CellMeasurer,\n    CellMeasurerCache,\n    CellMeasurerCacheParams,\n    CellMeasurerProps,\n    KeyMapper,\n} from './dist/es/CellMeasurer';\nexport {\n    Collection,\n    CollectionCellGroupRenderer,\n    CollectionCellGroupRendererParams,\n    CollectionCellRenderer,\n    CollectionCellRendererParams,\n    CollectionCellSizeAndPosition,\n    CollectionCellSizeAndPositionGetter,\n    CollectionProps,\n} from './dist/es/Collection';\nexport { ColumnSizer, ColumnSizerProps, SizedColumnProps } from './dist/es/ColumnSizer';\nexport {\n    accessibilityOverscanIndicesGetter,\n    defaultOverscanIndicesGetter,\n    defaultCellRangeRenderer,\n    Grid,\n    CellSizeAndPositionManager,\n    ConfigureParams,\n    ContainerSizeAndOffset,\n    GetVisibleCellRangeParams,\n    GridCellProps,\n    GridCellRangeProps,\n    GridCellRangeRenderer,\n    GridCellRenderer,\n    GridProps,\n    GridState,\n    OverscanIndices,\n    OverscanIndicesGetterParams,\n    ScrollDirection,\n    ScrollParams,\n    SectionRenderedParams,\n    SizeAndPositionData,\n    VisibleCellRange,\n    ScrollbarPresenceParams,\n} from './dist/es/Grid';\nexport { InfiniteLoader, InfiniteLoaderChildProps, InfiniteLoaderProps } from './dist/es/InfiniteLoader';\nexport { List, ListProps, ListRowProps, ListRowRenderer } from './dist/es/List';\nexport {\n    createCellPositioner as createMasonryCellPositioner,\n    Masonry,\n    CellRenderer,\n    MasonryCellProps,\n    MasonryProps,\n    MasonryState,\n    OnCellsRenderedCallback,\n    OnScrollCallback,\n    Position,\n    Positioner,\n} from './dist/es/Masonry';\nexport { MultiGrid, MultiGridProps, MultiGridState } from './dist/es/MultiGrid';\nexport {\n    ScrollSync,\n    OnScrollParams,\n    ScrollSyncChildProps,\n    ScrollSyncProps,\n    ScrollSyncState,\n} from './dist/es/ScrollSync';\nexport {\n    createMultiSort as createTableMultiSort,\n    defaultCellDataGetter as defaultTableCellDataGetter,\n    defaultCellRenderer as defaultTableCellRenderer,\n    defaultHeaderRenderer as defaultTableHeaderRenderer,\n    defaultHeaderRowRenderer as defaultTableHeaderRowRenderer,\n    defaultRowRenderer as defaultTableRowRenderer,\n    Table,\n    Column,\n    SortDirection,\n    SortIndicator,\n    ColumnProps,\n    HeaderMouseEventHandlerParams,\n    RowMouseEventHandlerParams,\n    SortDirectionType,\n    TableCellDataGetter,\n    TableCellDataGetterParams,\n    TableCellProps,\n    TableCellRenderer,\n    TableHeaderProps,\n    TableHeaderRenderer,\n    TableHeaderRowProps,\n    TableHeaderRowRenderer,\n    TableProps,\n    TableRowProps,\n    TableRowRenderer,\n    SortParams,\n} from './dist/es/Table';\nexport {\n    WindowScroller,\n    WindowScrollerChildProps,\n    WindowScrollerProps,\n    WindowScrollerState,\n    IS_SCROLLING_TIMEOUT,\n} from './dist/es/WindowScroller';\n\nexport type Index = {\n    index: number;\n};\n\nexport type PositionInfo = {\n    x: number;\n    y: number;\n};\n\nexport type ScrollPosition = {\n    scrollLeft: number;\n    scrollTop: number;\n};\n\nexport type SizeInfo = {\n    height: number;\n    width: number;\n};\n\nexport type SizeAndPositionInfo = SizeInfo & PositionInfo;\n\nexport type Map<T> = { [key: string]: T };\n\nexport type Alignment = 'auto' | 'end' | 'start' | 'center';\n\nexport type IndexRange = {\n    startIndex: number;\n    stopIndex: number;\n};\n\nexport type OverscanIndexRange = {\n    overscanStartIndex: number;\n    overscanStopIndex: number;\n};\n\nexport type ScrollEventData = {\n    clientHeight: number;\n    scrollHeight: number;\n    scrollTop: number;\n};\n",
+  "9ba7dfc289e4ce1023a9d398b9e04a91ae3a9070:types/react-virtualized/index.d.ts": "// Type definitions for react-virtualized 9.21\n// Project: https://github.com/bvaughn/react-virtualized\n// Definitions by: Kalle Ott <https://github.com/kaoDev>\n//                 John Gunther <https://github.com/guntherjh>\n//                 Konstantin Nesterov <https://github.com/wasd171>\n//                 Steve Zhang <https://github.com/Stevearzh>\n//                 Brandon Hall <https://github.com/brandonhall>\n//                 Sebastian Busch <https://github.com/sbusch>\n//                 Adam Zmenak <https://github.com/azmenak>\n// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped\n// TypeScript Version: 2.8\n\nexport {\n    ArrowKeyStepper,\n    ArrowKeyStepperProps,\n    ChildProps as ArrowKeyStepperChildProps,\n    ScrollIndices,\n} from './dist/es/ArrowKeyStepper';\nexport { AutoSizer, AutoSizerProps, Dimensions, Size } from './dist/es/AutoSizer';\nexport {\n    CellMeasurer,\n    CellMeasurerCache,\n    CellMeasurerCacheParams,\n    CellMeasurerProps,\n    KeyMapper,\n} from './dist/es/CellMeasurer';\nexport {\n    Collection,\n    CollectionCellGroupRenderer,\n    CollectionCellGroupRendererParams,\n    CollectionCellRenderer,\n    CollectionCellRendererParams,\n    CollectionCellSizeAndPosition,\n    CollectionCellSizeAndPositionGetter,\n    CollectionProps,\n} from './dist/es/Collection';\nexport { ColumnSizer, ColumnSizerProps, SizedColumnProps } from './dist/es/ColumnSizer';\nexport {\n    accessibilityOverscanIndicesGetter,\n    defaultOverscanIndicesGetter,\n    defaultCellRangeRenderer,\n    Grid,\n    CellSizeAndPositionManager,\n    ConfigureParams,\n    ContainerSizeAndOffset,\n    GetVisibleCellRangeParams,\n    GridCellProps,\n    GridCellRangeProps,\n    GridCellRangeRenderer,\n    GridCellRenderer,\n    GridProps,\n    GridState,\n    OverscanIndices,\n    OverscanIndicesGetterParams,\n    ScrollDirection,\n    ScrollParams,\n    SectionRenderedParams,\n    SizeAndPositionData,\n    VisibleCellRange,\n    ScrollbarPresenceParams,\n} from './dist/es/Grid';\nexport { InfiniteLoader, InfiniteLoaderChildProps, InfiniteLoaderProps } from './dist/es/InfiniteLoader';\nexport { List, ListProps, ListRowProps, ListRowRenderer } from './dist/es/List';\nexport {\n    createCellPositioner as createMasonryCellPositioner,\n    Masonry,\n    CellRenderer,\n    MasonryCellProps,\n    MasonryProps,\n    MasonryState,\n    OnCellsRenderedCallback,\n    OnScrollCallback,\n    Position,\n    Positioner,\n} from './dist/es/Masonry';\nexport { MultiGrid, MultiGridProps, MultiGridState } from './dist/es/MultiGrid';\nexport {\n    ScrollSync,\n    OnScrollParams,\n    ScrollSyncChildProps,\n    ScrollSyncProps,\n    ScrollSyncState,\n} from './dist/es/ScrollSync';\nexport {\n    createMultiSort as createTableMultiSort,\n    defaultCellDataGetter as defaultTableCellDataGetter,\n    defaultCellRenderer as defaultTableCellRenderer,\n    defaultHeaderRenderer as defaultTableHeaderRenderer,\n    defaultHeaderRowRenderer as defaultTableHeaderRowRenderer,\n    defaultRowRenderer as defaultTableRowRenderer,\n    Table,\n    Column,\n    SortDirection,\n    SortIndicator,\n    ColumnProps,\n    HeaderMouseEventHandlerParams,\n    RowMouseEventHandlerParams,\n    SortDirectionType,\n    TableCellDataGetter,\n    TableCellDataGetterParams,\n    TableCellProps,\n    TableCellRenderer,\n    TableHeaderProps,\n    TableHeaderRenderer,\n    TableHeaderRowProps,\n    TableHeaderRowRenderer,\n    TableProps,\n    TableRowProps,\n    TableRowRenderer,\n    SortParams,\n} from './dist/es/Table';\nexport {\n    WindowScroller,\n    WindowScrollerChildProps,\n    WindowScrollerProps,\n    WindowScrollerState,\n    IS_SCROLLING_TIMEOUT,\n} from './dist/es/WindowScroller';\n\nexport type Index = {\n    index: number;\n};\n\nexport type PositionInfo = {\n    x: number;\n    y: number;\n};\n\nexport type ScrollPosition = {\n    scrollLeft: number;\n    scrollTop: number;\n};\n\nexport type SizeInfo = {\n    height: number;\n    width: number;\n};\n\nexport type SizeAndPositionInfo = SizeInfo & PositionInfo;\n\nexport type Map<T> = { [key: string]: T };\n\nexport type Alignment = 'auto' | 'end' | 'start' | 'center';\n\nexport type IndexRange = {\n    startIndex: number;\n    stopIndex: number;\n};\n\nexport type OverscanIndexRange = {\n    overscanStartIndex: number;\n    overscanStopIndex: number;\n};\n\nexport type ScrollEventData = {\n    clientHeight: number;\n    scrollHeight: number;\n    scrollTop: number;\n};\n",
+  "2cee47aedc9b4d321e378d7020984adf005fef64:types/ssh2-sftp-client/index.d.ts": "// Type definitions for ssh2-sftp-client 7.0\n// Project: https://github.com/theophilusx/ssh2-sftp-client\n// Definitions by: igrayson <https://github.com/igrayson>\n//                 Ascari Andrea <https://github.com/ascariandrea>\n//                 Kartik Malik <https://github.com/kartik2406>\n//                 Michael Pertl <https://github.com/viamuli>\n//                 Taylor Herron <https://github.com/gbhmt>\n//                 Lane Goldberg <https://github.com/builtbylane>\n//                 Lorenzo Adinolfi <https://github.com/loru88>\n//                 Sam Galizia <https://github.com/sgalizia>\n//                 Tom Xu <https://github.com/hengkx>\n//                 Joseph Burger <https://github.com/candyapplecorn>\n//                 Emma Milner <https://github.com/tsop14>\n// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped\n\nimport * as ssh2 from 'ssh2';\n\nexport = sftp;\n\ntype FileInfoType = 'd' | '-' | 'l';\n\ndeclare class sftp {\n    constructor(name?: string);\n    connect(options: sftp.ConnectOptions): Promise<ssh2.SFTPWrapper>;\n\n    list(remoteFilePath: string, pattern?: string | RegExp): Promise<sftp.FileInfo[]>;\n\n    exists(remotePath: string): Promise<false | FileInfoType>;\n\n    stat(remotePath: string): Promise<sftp.FileStats>;\n\n    realPath(remotePath: string): Promise<string>;\n\n    get(\n        path: string,\n        dst?: string | NodeJS.WritableStream,\n        options?: sftp.TransferOptions,\n    ): Promise<string | NodeJS.WritableStream | Buffer>;\n\n    fastGet(remoteFilePath: string, localPath: string, options?: sftp.FastGetTransferOptions): Promise<string>;\n\n    put(\n        input: string | Buffer | NodeJS.ReadableStream,\n        remoteFilePath: string,\n        options?: sftp.TransferOptions,\n    ): Promise<string>;\n\n    fastPut(localPath: string, remoteFilePath: string, options?: sftp.FastPutTransferOptions): Promise<string>;\n\n    cwd(): Promise<string>;\n\n    mkdir(remoteFilePath: string, recursive?: boolean): Promise<string>;\n\n    rmdir(remoteFilePath: string, recursive?: boolean): Promise<string>;\n\n    delete(remoteFilePath: string, noErrorOK?: boolean): Promise<string>;\n\n    rename(remoteSourcePath: string, remoteDestPath: string): Promise<string>;\n\n    chmod(remotePath: string, mode: number | string): Promise<string>;\n\n    append(\n        input: Buffer | NodeJS.ReadableStream,\n        remotePath: string,\n        options?: sftp.WriteStreamOptions,\n    ): Promise<string>;\n\n    uploadDir(srcDir: string, destDir: string, filter?: string | RegExp): Promise<string>;\n\n    downloadDir(srcDir: string, destDir: string, filter?: string | RegExp): Promise<string>;\n\n    end(): Promise<void>;\n\n    on(event: string, callback: (...args: any[]) => void): void;\n\n    removeListener(event: string, callback: (...args: any[]) => void): void;\n\n    posixRename(fromPath: string, toPath: string): Promise<string>;\n}\n\ndeclare namespace sftp {\n    interface ConnectOptions extends ssh2.ConnectConfig {\n        retries?: number;\n        retry_factor?: number;\n        retry_minTimeout?: number;\n    }\n\n    interface ModeOption {\n        mode?: number | string;\n    }\n\n    interface PipeOptions {\n        end?: boolean;\n    }\n\n    interface ReadStreamOptions extends ModeOption {\n        flags?: 'r';\n        encoding?: null | string;\n        handle?: null | string;\n        autoClose?: boolean;\n    }\n\n    interface WriteStreamOptions extends ModeOption {\n        flags?: 'w' | 'a';\n        encoding?: null | string;\n        autoClose?: boolean;\n    }\n\n    interface TransferOptions {\n        pipeOptions?: PipeOptions;\n        writeStreamOptions?: WriteStreamOptions;\n        readStreamOptions?: ReadStreamOptions;\n    }\n\n    interface FastGetTransferOptions {\n        concurrency?: number;\n        chunkSize?: number;\n        step?: (totalTransferred: number, chunk: number, total: number) => void;\n    }\n\n    interface FastPutTransferOptions extends FastGetTransferOptions, ModeOption {}\n\n    interface FileInfo {\n        type: FileInfoType;\n        name: string;\n        size: number;\n        modifyTime: number;\n        accessTime: number;\n        rights: {\n            user: string;\n            group: string;\n            other: string;\n        };\n        owner: number;\n        group: number;\n    }\n\n    interface FileStats {\n        mode: number;\n        uid: number;\n        gid: number;\n        size: number;\n        accessTime: number;\n        modifyTime: number;\n        isDirectory: boolean;\n        isFile: boolean;\n        isBlockDevice: boolean;\n        isCharacterDevice: boolean;\n        isSymbolicLink: boolean;\n        isFIFO: boolean;\n        isSocket: boolean;\n    }\n}\n",
+  "9ba7dfc289e4ce1023a9d398b9e04a91ae3a9070:types/ssh2-sftp-client/index.d.ts": "// Type definitions for ssh2-sftp-client 7.0\n// Project: https://github.com/theophilusx/ssh2-sftp-client\n// Definitions by: igrayson <https://github.com/igrayson>\n//                 Ascari Andrea <https://github.com/ascariandrea>\n//                 Kartik Malik <https://github.com/kartik2406>\n//                 Michael Pertl <https://github.com/viamuli>\n//                 Taylor Herron <https://github.com/gbhmt>\n//                 Lane Goldberg <https://github.com/builtbylane>\n//                 Lorenzo Adinolfi <https://github.com/loru88>\n//                 Tom Xu <https://github.com/hengkx>\n//                 Joseph Burger <https://github.com/candyapplecorn>\n//                 Emma Milner <https://github.com/tsop14>\n// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped\n\nimport * as ssh2 from 'ssh2';\n\nexport = sftp;\n\ntype FileInfoType = 'd' | '-' | 'l';\n\ndeclare class sftp {\n    constructor(name?: string);\n    connect(options: sftp.ConnectOptions): Promise<ssh2.SFTPWrapper>;\n\n    list(remoteFilePath: string, pattern?: string | RegExp): Promise<sftp.FileInfo[]>;\n\n    exists(remotePath: string): Promise<false | FileInfoType>;\n\n    stat(remotePath: string): Promise<sftp.FileStats>;\n\n    realPath(remotePath: string): Promise<string>;\n\n    get(\n        path: string,\n        dst?: string | NodeJS.WritableStream,\n        options?: sftp.TransferOptions,\n    ): Promise<string | NodeJS.WritableStream | Buffer>;\n\n    fastGet(remoteFilePath: string, localPath: string, options?: sftp.FastGetTransferOptions): Promise<string>;\n\n    put(\n        input: string | Buffer | NodeJS.ReadableStream,\n        remoteFilePath: string,\n        options?: sftp.TransferOptions,\n    ): Promise<string>;\n\n    fastPut(localPath: string, remoteFilePath: string, options?: sftp.FastPutTransferOptions): Promise<string>;\n\n    cwd(): Promise<string>;\n\n    mkdir(remoteFilePath: string, recursive?: boolean): Promise<string>;\n\n    rmdir(remoteFilePath: string, recursive?: boolean): Promise<string>;\n\n    delete(remoteFilePath: string, noErrorOK?: boolean): Promise<string>;\n\n    rename(remoteSourcePath: string, remoteDestPath: string): Promise<string>;\n\n    chmod(remotePath: string, mode: number | string): Promise<string>;\n\n    append(\n        input: Buffer | NodeJS.ReadableStream,\n        remotePath: string,\n        options?: sftp.WriteStreamOptions,\n    ): Promise<string>;\n\n    uploadDir(srcDir: string, destDir: string, filter?: string | RegExp): Promise<string>;\n\n    downloadDir(srcDir: string, destDir: string, filter?: string | RegExp): Promise<string>;\n\n    end(): Promise<void>;\n\n    on(event: string, callback: (...args: any[]) => void): void;\n\n    removeListener(event: string, callback: (...args: any[]) => void): void;\n\n    posixRename(fromPath: string, toPath: string): Promise<string>;\n}\n\ndeclare namespace sftp {\n    interface ConnectOptions extends ssh2.ConnectConfig {\n        retries?: number;\n        retry_factor?: number;\n        retry_minTimeout?: number;\n    }\n\n    interface ModeOption {\n        mode?: number | string;\n    }\n\n    interface PipeOptions {\n        end?: boolean;\n    }\n\n    interface ReadStreamOptions extends ModeOption {\n        flags?: 'r';\n        encoding?: null | string;\n        handle?: null | string;\n        autoClose?: boolean;\n    }\n\n    interface WriteStreamOptions extends ModeOption {\n        flags?: 'w' | 'a';\n        encoding?: null | string;\n        autoClose?: boolean;\n    }\n\n    interface TransferOptions {\n        pipeOptions?: PipeOptions;\n        writeStreamOptions?: WriteStreamOptions;\n        readStreamOptions?: ReadStreamOptions;\n    }\n\n    interface FastGetTransferOptions {\n        concurrency?: number;\n        chunkSize?: number;\n        step?: (totalTransferred: number, chunk: number, total: number) => void;\n    }\n\n    interface FastPutTransferOptions extends FastGetTransferOptions, ModeOption {}\n\n    interface FileInfo {\n        type: FileInfoType;\n        name: string;\n        size: number;\n        modifyTime: number;\n        accessTime: number;\n        rights: {\n            user: string;\n            group: string;\n            other: string;\n        };\n        owner: number;\n        group: number;\n    }\n\n    interface FileStats {\n        mode: number;\n        uid: number;\n        gid: number;\n        size: number;\n        accessTime: number;\n        modifyTime: number;\n        isDirectory: boolean;\n        isFile: boolean;\n        isBlockDevice: boolean;\n        isCharacterDevice: boolean;\n        isSymbolicLink: boolean;\n        isFIFO: boolean;\n        isSocket: boolean;\n    }\n}\n",
+  "2cee47aedc9b4d321e378d7020984adf005fef64:types/styled-components/index.d.ts": "// Type definitions for styled-components 5.1\n// Project: https://github.com/styled-components/styled-components, https://styled-components.com\n// Definitions by: Igor Oleinikov <https://github.com/Igorbek>\n//                 Ihor Chulinda <https://github.com/Igmat>\n//                 Jessica Franco <https://github.com/Jessidhia>\n//                 Jason Killian <https://github.com/jkillian>\n//                 Sebastian Silbermann <https://github.com/eps1lon>\n//                 Matthew Wagerfield <https://github.com/wagerfield>\n//                 Yuki Ito <https://github.com/Lazyuki>\n//                 Maciej Goszczycki <https://github.com/mgoszcz2>\n//                 Aaron Reisman <https://github.com/lifeiscontent>\n// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped\n\n// forward declarations\ndeclare global {\n    namespace NodeJS {\n        // tslint:disable-next-line:no-empty-interface\n        interface ReadableStream {}\n    }\n}\n\nimport * as CSS from 'csstype';\nimport * as React from 'react';\nimport * as hoistNonReactStatics from 'hoist-non-react-statics';\n\nexport type CSSProperties = CSS.Properties<string | number>;\n\nexport type CSSPseudos = { [K in CSS.Pseudos]?: CSSObject };\n\nexport interface CSSObject extends CSSProperties, CSSPseudos {\n    [key: string]: CSSObject | string | number | undefined;\n}\n\nexport type CSSKeyframes = object & { [key: string]: CSSObject };\n\nexport interface ThemeProps<T> {\n    theme: T;\n}\n\nexport type ThemedStyledProps<P, T> = P & ThemeProps<T>;\nexport type StyledProps<P> = ThemedStyledProps<P, AnyIfEmpty<DefaultTheme>>;\nexport type IntrinsicElementsKeys = keyof JSX.IntrinsicElements;\n\n// Any prop that has a default prop becomes optional, but its type is unchanged\n// Undeclared default props are augmented into the resulting allowable attributes\n// If declared props have indexed properties, ignore default props entirely as keyof gets widened\n// Wrap in an outer-level conditional type to allow distribution over props that are unions\ntype Defaultize<P, D> = P extends any\n    ? string extends keyof P\n        ? P\n        : PickU<P, Exclude<keyof P, keyof D>> &\n              Partial<PickU<P, Extract<keyof P, keyof D>>> &\n              Partial<PickU<D, Exclude<keyof D, keyof P>>>\n    : never;\n\ntype ReactDefaultizedProps<C, P> = C extends { defaultProps: infer D } ? Defaultize<P, D> : P;\n\ntype MakeAttrsOptional<\n    C extends string | React.ComponentType<any>,\n    O extends object,\n    A extends keyof P,\n    P = React.ComponentPropsWithRef<C extends IntrinsicElementsKeys | React.ComponentType<any> ? C : never>,\n> =\n    // Distribute unions early to avoid quadratic expansion\n    P extends any ? OmitU<ReactDefaultizedProps<C, P> & O, A> & Partial<PickU<P & O, A>> : never;\n\nexport type StyledComponentProps<\n    // The Component from whose props are derived\n    C extends string | React.ComponentType<any>,\n    // The Theme from the current context\n    T extends object,\n    // The other props added by the template\n    O extends object,\n    // The props that are made optional by .attrs\n    A extends keyof any,\n    // The Component passed with \"forwardedAs\" prop\n    FAsC extends string | React.ComponentType<any> = C\n> =\n    // Distribute O if O is a union type\n    O extends object\n        ? WithOptionalTheme<\n              MakeAttrsOptional<C, O, A> & MakeAttrsOptional<FAsC, O, A>,\n              T\n          > &\n              WithChildrenIfReactComponentClass<C>\n        : never;\n\n// Because of React typing quirks, when getting props from a React.ComponentClass,\n// we need to manually add a `children` field.\n// See https://github.com/DefinitelyTyped/DefinitelyTyped/pull/31945\n// and https://github.com/DefinitelyTyped/DefinitelyTyped/pull/32843\ntype WithChildrenIfReactComponentClass<C extends string | React.ComponentType<any>> = C extends React.ComponentClass<\n    any\n>\n    ? { children?: React.ReactNode | undefined }\n    : {};\n\ntype StyledComponentPropsWithAs<\n    C extends string | React.ComponentType<any>,\n    T extends object,\n    O extends object,\n    A extends keyof any,\n    AsC extends string | React.ComponentType<any> = C,\n    FAsC extends string | React.ComponentType<any> = C\n> = StyledComponentProps<C, T, O, A, FAsC> & { as?: AsC | undefined; forwardedAs?: FAsC | undefined };\n\nexport type FalseyValue = undefined | null | false;\nexport type Interpolation<P> = InterpolationValue | InterpolationFunction<P> | FlattenInterpolation<P>;\n// cannot be made a self-referential interface, breaks WithPropNested\n// see https://github.com/microsoft/TypeScript/issues/34796\nexport type FlattenInterpolation<P> = ReadonlyArray<Interpolation<P>>;\nexport type InterpolationValue = string | number | FalseyValue | Keyframes | StyledComponentInterpolation | CSSObject;\nexport type SimpleInterpolation = InterpolationValue | FlattenSimpleInterpolation;\nexport type FlattenSimpleInterpolation = ReadonlyArray<SimpleInterpolation>;\n\nexport type InterpolationFunction<P> = (props: P) => Interpolation<P>;\n\ntype Attrs<P, A extends Partial<P>, T> = ((props: ThemedStyledProps<P, T>) => A) | A;\n\nexport type ThemedGlobalStyledClassProps<P, T> = WithOptionalTheme<P, T> & {\n    suppressMultiMountWarning?: boolean | undefined;\n};\n\nexport interface GlobalStyleComponent<P, T> extends React.ComponentClass<ThemedGlobalStyledClassProps<P, T>> {}\n\n// remove the call signature from StyledComponent so Interpolation can still infer InterpolationFunction\ntype StyledComponentInterpolation =\n    | PickU<StyledComponentBase<any, any, any, any>, keyof StyledComponentBase<any, any>>\n    | PickU<StyledComponentBase<any, any, any>, keyof StyledComponentBase<any, any>>;\n\n// abuse Pick to strip the call signature from ForwardRefExoticComponent\ntype ForwardRefExoticBase<P> = PickU<React.ForwardRefExoticComponent<P>, keyof React.ForwardRefExoticComponent<any>>;\n\n// Config to be used with withConfig\nexport interface StyledConfig<O extends object = {}> {\n    // TODO: Add all types from the original StyledComponentWrapperProperties\n    componentId?: string;\n    displayName?: string;\n    shouldForwardProp?: ((prop: keyof O, defaultValidatorFn: (prop: keyof O) => boolean) => boolean) | undefined;\n}\n\n// extracts React defaultProps\ntype ReactDefaultProps<C> = C extends { defaultProps: infer D } ? D : never;\n\n// any doesn't count as assignable to never in the extends clause, and we default A to never\nexport type AnyStyledComponent = StyledComponent<any, any, any, any> | StyledComponent<any, any, any>;\n\nexport type StyledComponent<\n    C extends keyof JSX.IntrinsicElements | React.ComponentType<any>,\n    T extends object,\n    O extends object = {},\n    A extends keyof any = never\n> = // the \"string\" allows this to be used as an object key\n    // I really want to avoid this if possible but it's the only way to use nesting with object styles...\n    string &\n        StyledComponentBase<C, T, O, A> &\n        hoistNonReactStatics.NonReactStatics<C extends React.ComponentType<any> ? C : never>;\n\nexport interface StyledComponentBase<\n    C extends string | React.ComponentType<any>,\n    T extends object,\n    O extends object = {},\n    A extends keyof any = never\n> extends ForwardRefExoticBase<StyledComponentProps<C, T, O, A>> {\n    // add our own fake call signature to implement the polymorphic 'as' prop\n    (props: StyledComponentProps<C, T, O, A> & { as?: never | undefined; forwardedAs?: never | undefined }): React.ReactElement<\n        StyledComponentProps<C, T, O, A>\n    >;\n    <AsC extends string | React.ComponentType<any> = C, FAsC extends string | React.ComponentType<any> = AsC>(\n        props: StyledComponentPropsWithAs<AsC, T, O, A, AsC, FAsC>,\n    ): React.ReactElement<StyledComponentPropsWithAs<AsC, T, O, A, AsC, FAsC>>;\n\n    withComponent<WithC extends AnyStyledComponent>(\n        component: WithC,\n    ): StyledComponent<\n        StyledComponentInnerComponent<WithC>,\n        T,\n        O & StyledComponentInnerOtherProps<WithC>,\n        A | StyledComponentInnerAttrs<WithC>\n    >;\n    withComponent<WithC extends keyof JSX.IntrinsicElements | React.ComponentType<any>>(\n        component: WithC,\n    ): StyledComponent<WithC, T, O, A>;\n}\n\nexport interface ThemedStyledFunctionBase<\n    C extends keyof JSX.IntrinsicElements | React.ComponentType<any>,\n    T extends object,\n    O extends object = {},\n    A extends keyof any = never\n> {\n    (first: TemplateStringsArray): StyledComponent<C, T, O, A>;\n    (\n        first:\n            | TemplateStringsArray\n            | CSSObject\n            | InterpolationFunction<ThemedStyledProps<StyledComponentPropsWithRef<C> & O, T>>,\n        ...rest: Array<Interpolation<ThemedStyledProps<StyledComponentPropsWithRef<C> & O, T>>>\n    ): StyledComponent<C, T, O, A>;\n    <U extends object>(\n        first:\n            | TemplateStringsArray\n            | CSSObject\n            | InterpolationFunction<ThemedStyledProps<StyledComponentPropsWithRef<C> & O & U, T>>,\n        ...rest: Array<Interpolation<ThemedStyledProps<StyledComponentPropsWithRef<C> & O & U, T>>>\n    ): StyledComponent<C, T, O & U, A>;\n}\n\nexport interface ThemedStyledFunction<\n    C extends keyof JSX.IntrinsicElements | React.ComponentType<any>,\n    T extends object,\n    O extends object = {},\n    A extends keyof any = never\n> extends ThemedStyledFunctionBase<C, T, O, A> {\n    // Fun thing: 'attrs' can also provide a polymorphic 'as' prop\n    // My head already hurts enough so maybe later...\n    attrs<\n        U,\n        NewA extends Partial<StyledComponentPropsWithRef<C> & U> & {\n            [others: string]: any;\n        } = {}\n    >(\n        attrs: Attrs<StyledComponentPropsWithRef<C> & U, NewA, T>,\n    ): ThemedStyledFunction<C, T, O & NewA, A | keyof NewA>;\n\n    withConfig: <Props extends O = O>(\n        config: StyledConfig<StyledComponentPropsWithRef<C> & Props>,\n    ) => ThemedStyledFunction<C, T, Props, A>;\n}\n\nexport type StyledFunction<C extends keyof JSX.IntrinsicElements | React.ComponentType<any>> = ThemedStyledFunction<\n    C,\n    any\n>;\n\ntype ThemedStyledComponentFactories<T extends object> = {\n    [TTag in keyof JSX.IntrinsicElements]: ThemedStyledFunction<TTag, T>;\n};\n\nexport type StyledComponentInnerComponent<C extends React.ComponentType<any>> = C extends StyledComponent<\n  ",
+  "9ba7dfc289e4ce1023a9d398b9e04a91ae3a9070:types/styled-components/index.d.ts": "// Type definitions for styled-components 5.1\n// Project: https://github.com/styled-components/styled-components, https://styled-components.com\n// Definitions by: Igor Oleinikov <https://github.com/Igorbek>\n//                 Ihor Chulinda <https://github.com/Igmat>\n//                 Jessica Franco <https://github.com/Jessidhia>\n//                 Jason Killian <https://github.com/jkillian>\n//                 Sebastian Silbermann <https://github.com/eps1lon>\n//                 Matthew Wagerfield <https://github.com/wagerfield>\n//                 Yuki Ito <https://github.com/Lazyuki>\n//                 Aaron Reisman <https://github.com/lifeiscontent>\n// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped\n\n// forward declarations\ndeclare global {\n    namespace NodeJS {\n        // tslint:disable-next-line:no-empty-interface\n        interface ReadableStream {}\n    }\n}\n\nimport * as CSS from 'csstype';\nimport * as React from 'react';\nimport * as hoistNonReactStatics from 'hoist-non-react-statics';\n\nexport type CSSProperties = CSS.Properties<string | number>;\n\nexport type CSSPseudos = { [K in CSS.Pseudos]?: CSSObject };\n\nexport interface CSSObject extends CSSProperties, CSSPseudos {\n    [key: string]: CSSObject | string | number | undefined;\n}\n\nexport type CSSKeyframes = object & { [key: string]: CSSObject };\n\nexport interface ThemeProps<T> {\n    theme: T;\n}\n\nexport type ThemedStyledProps<P, T> = P & ThemeProps<T>;\nexport type StyledProps<P> = ThemedStyledProps<P, AnyIfEmpty<DefaultTheme>>;\nexport type IntrinsicElementsKeys = keyof JSX.IntrinsicElements;\n\n// Any prop that has a default prop becomes optional, but its type is unchanged\n// Undeclared default props are augmented into the resulting allowable attributes\n// If declared props have indexed properties, ignore default props entirely as keyof gets widened\n// Wrap in an outer-level conditional type to allow distribution over props that are unions\ntype Defaultize<P, D> = P extends any\n    ? string extends keyof P\n        ? P\n        : PickU<P, Exclude<keyof P, keyof D>> &\n              Partial<PickU<P, Extract<keyof P, keyof D>>> &\n              Partial<PickU<D, Exclude<keyof D, keyof P>>>\n    : never;\n\ntype ReactDefaultizedProps<C, P> = C extends { defaultProps: infer D } ? Defaultize<P, D> : P;\n\ntype MakeAttrsOptional<\n    C extends string | React.ComponentType<any>,\n    O extends object,\n    A extends keyof P,\n    P = React.ComponentPropsWithRef<C extends IntrinsicElementsKeys | React.ComponentType<any> ? C : never>,\n> =\n    // Distribute unions early to avoid quadratic expansion\n    P extends any ? OmitU<ReactDefaultizedProps<C, P> & O, A> & Partial<PickU<P & O, A>> : never;\n\nexport type StyledComponentProps<\n    // The Component from whose props are derived\n    C extends string | React.ComponentType<any>,\n    // The Theme from the current context\n    T extends object,\n    // The other props added by the template\n    O extends object,\n    // The props that are made optional by .attrs\n    A extends keyof any,\n    // The Component passed with \"forwardedAs\" prop\n    FAsC extends string | React.ComponentType<any> = C\n> =\n    // Distribute O if O is a union type\n    O extends object\n        ? WithOptionalTheme<\n              MakeAttrsOptional<C, O, A> & MakeAttrsOptional<FAsC, O, A>,\n              T\n          > &\n              WithChildrenIfReactComponentClass<C>\n        : never;\n\n// Because of React typing quirks, when getting props from a React.ComponentClass,\n// we need to manually add a `children` field.\n// See https://github.com/DefinitelyTyped/DefinitelyTyped/pull/31945\n// and https://github.com/DefinitelyTyped/DefinitelyTyped/pull/32843\ntype WithChildrenIfReactComponentClass<C extends string | React.ComponentType<any>> = C extends React.ComponentClass<\n    any\n>\n    ? { children?: React.ReactNode | undefined }\n    : {};\n\ntype StyledComponentPropsWithAs<\n    C extends string | React.ComponentType<any>,\n    T extends object,\n    O extends object,\n    A extends keyof any,\n    AsC extends string | React.ComponentType<any> = C,\n    FAsC extends string | React.ComponentType<any> = C\n> = StyledComponentProps<C, T, O, A, FAsC> & { as?: AsC | undefined; forwardedAs?: FAsC | undefined };\n\nexport type FalseyValue = undefined | null | false;\nexport type Interpolation<P> = InterpolationValue | InterpolationFunction<P> | FlattenInterpolation<P>;\n// cannot be made a self-referential interface, breaks WithPropNested\n// see https://github.com/microsoft/TypeScript/issues/34796\nexport type FlattenInterpolation<P> = ReadonlyArray<Interpolation<P>>;\nexport type InterpolationValue = string | number | FalseyValue | Keyframes | StyledComponentInterpolation | CSSObject;\nexport type SimpleInterpolation = InterpolationValue | FlattenSimpleInterpolation;\nexport type FlattenSimpleInterpolation = ReadonlyArray<SimpleInterpolation>;\n\nexport type InterpolationFunction<P> = (props: P) => Interpolation<P>;\n\ntype Attrs<P, A extends Partial<P>, T> = ((props: ThemedStyledProps<P, T>) => A) | A;\n\nexport type ThemedGlobalStyledClassProps<P, T> = WithOptionalTheme<P, T> & {\n    suppressMultiMountWarning?: boolean | undefined;\n};\n\nexport interface GlobalStyleComponent<P, T> extends React.ComponentClass<ThemedGlobalStyledClassProps<P, T>> {}\n\n// remove the call signature from StyledComponent so Interpolation can still infer InterpolationFunction\ntype StyledComponentInterpolation =\n    | PickU<StyledComponentBase<any, any, any, any>, keyof StyledComponentBase<any, any>>\n    | PickU<StyledComponentBase<any, any, any>, keyof StyledComponentBase<any, any>>;\n\n// abuse Pick to strip the call signature from ForwardRefExoticComponent\ntype ForwardRefExoticBase<P> = PickU<React.ForwardRefExoticComponent<P>, keyof React.ForwardRefExoticComponent<any>>;\n\n// Config to be used with withConfig\nexport interface StyledConfig<O extends object = {}> {\n    // TODO: Add all types from the original StyledComponentWrapperProperties\n    componentId?: string;\n    displayName?: string;\n    shouldForwardProp?: ((prop: keyof O, defaultValidatorFn: (prop: keyof O) => boolean) => boolean) | undefined;\n}\n\n// extracts React defaultProps\ntype ReactDefaultProps<C> = C extends { defaultProps: infer D } ? D : never;\n\n// any doesn't count as assignable to never in the extends clause, and we default A to never\nexport type AnyStyledComponent = StyledComponent<any, any, any, any> | StyledComponent<any, any, any>;\n\nexport type StyledComponent<\n    C extends keyof JSX.IntrinsicElements | React.ComponentType<any>,\n    T extends object,\n    O extends object = {},\n    A extends keyof any = never\n> = // the \"string\" allows this to be used as an object key\n    // I really want to avoid this if possible but it's the only way to use nesting with object styles...\n    string &\n        StyledComponentBase<C, T, O, A> &\n        hoistNonReactStatics.NonReactStatics<C extends React.ComponentType<any> ? C : never>;\n\nexport interface StyledComponentBase<\n    C extends string | React.ComponentType<any>,\n    T extends object,\n    O extends object = {},\n    A extends keyof any = never\n> extends ForwardRefExoticBase<StyledComponentProps<C, T, O, A>> {\n    // add our own fake call signature to implement the polymorphic 'as' prop\n    (props: StyledComponentProps<C, T, O, A> & { as?: never | undefined; forwardedAs?: never | undefined }): React.ReactElement<\n        StyledComponentProps<C, T, O, A>\n    >;\n    <AsC extends string | React.ComponentType<any> = C, FAsC extends string | React.ComponentType<any> = AsC>(\n        props: StyledComponentPropsWithAs<AsC, T, O, A, AsC, FAsC>,\n    ): React.ReactElement<StyledComponentPropsWithAs<AsC, T, O, A, AsC, FAsC>>;\n\n    withComponent<WithC extends AnyStyledComponent>(\n        component: WithC,\n    ): StyledComponent<\n        StyledComponentInnerComponent<WithC>,\n        T,\n        O & StyledComponentInnerOtherProps<WithC>,\n        A | StyledComponentInnerAttrs<WithC>\n    >;\n    withComponent<WithC extends keyof JSX.IntrinsicElements | React.ComponentType<any>>(\n        component: WithC,\n    ): StyledComponent<WithC, T, O, A>;\n}\n\nexport interface ThemedStyledFunctionBase<\n    C extends keyof JSX.IntrinsicElements | React.ComponentType<any>,\n    T extends object,\n    O extends object = {},\n    A extends keyof any = never\n> {\n    (first: TemplateStringsArray): StyledComponent<C, T, O, A>;\n    (\n        first:\n            | TemplateStringsArray\n            | CSSObject\n            | InterpolationFunction<ThemedStyledProps<StyledComponentPropsWithRef<C> & O, T>>,\n        ...rest: Array<Interpolation<ThemedStyledProps<StyledComponentPropsWithRef<C> & O, T>>>\n    ): StyledComponent<C, T, O, A>;\n    <U extends object>(\n        first:\n            | TemplateStringsArray\n            | CSSObject\n            | InterpolationFunction<ThemedStyledProps<StyledComponentPropsWithRef<C> & O & U, T>>,\n        ...rest: Array<Interpolation<ThemedStyledProps<StyledComponentPropsWithRef<C> & O & U, T>>>\n    ): StyledComponent<C, T, O & U, A>;\n}\n\nexport interface ThemedStyledFunction<\n    C extends keyof JSX.IntrinsicElements | React.ComponentType<any>,\n    T extends object,\n    O extends object = {},\n    A extends keyof any = never\n> extends ThemedStyledFunctionBase<C, T, O, A> {\n    // Fun thing: 'attrs' can also provide a polymorphic 'as' prop\n    // My head already hurts enough so maybe later...\n    attrs<\n        U,\n        NewA extends Partial<StyledComponentPropsWithRef<C> & U> & {\n            [others: string]: any;\n        } = {}\n    >(\n        attrs: Attrs<StyledComponentPropsWithRef<C> & U, NewA, T>,\n    ): ThemedStyledFunction<C, T, O & NewA, A | keyof NewA>;\n\n    withConfig: <Props extends O = O>(\n        config: StyledConfig<StyledComponentPropsWithRef<C> & Props>,\n    ) => ThemedStyledFunction<C, T, Props, A>;\n}\n\nexport type StyledFunction<C extends keyof JSX.IntrinsicElements | React.ComponentType<any>> = ThemedStyledFunction<\n    C,\n    any\n>;\n\ntype ThemedStyledComponentFactories<T extends object> = {\n    [TTag in keyof JSX.IntrinsicElements]: ThemedStyledFunction<TTag, T>;\n};\n\nexport type StyledComponentInnerComponent<C extends React.ComponentType<any>> = C extends StyledComponent<\n    infer I,\n    any,\n    any,\n    any\n>\n    ? I\n    : C extends Styl"
+}
diff --git a/src/_tests/fixtures/58764/_response.json b/src/_tests/fixtures/58764/_response.json
new file mode 100644
index 0000000..177e412
--- /dev/null
+++ b/src/_tests/fixtures/58764/_response.json
@@ -0,0 +1,302 @@
+{
+  "data": {
+    "repository": {
+      "id": "MDEwOlJlcG9zaXRvcnk2MDkzMzE2",
+      "pullRequest": {
+        "id": "PR_kwDOAFz6BM4yvxmj",
+        "title": "Remove contributors with deleted accounts",
+        "createdAt": "2022-02-14T00:04:08Z",
+        "author": {
+          "login": "github-actions",
+          "__typename": "Bot"
+        },
+        "authorAssociation": "CONTRIBUTOR",
+        "baseRef": {
+          "name": "master",
+          "__typename": "Ref"
+        },
+        "labels": {
+          "nodes": [
+            {
+              "name": "Edits multiple packages",
+              "__typename": "Label"
+            },
+            {
+              "name": "Critical package",
+              "__typename": "Label"
+            },
+            {
+              "name": "Where is GH Actions?",
+              "__typename": "Label"
+            },
+            {
+              "name": "Untested Change",
+              "__typename": "Label"
+            },
+            {
+              "name": "Edits Owners",
+              "__typename": "Label"
+            }
+          ],
+          "__typename": "LabelConnection"
+        },
+        "isDraft": false,
+        "mergeable": "MERGEABLE",
+        "number": 58764,
+        "state": "OPEN",
+        "headRefOid": "9ba7dfc289e4ce1023a9d398b9e04a91ae3a9070",
+        "changedFiles": 9,
+        "additions": 9,
+        "deletions": 15,
+        "commitIds": {
+          "nodes": [
+            {
+              "commit": {
+                "oid": "9ba7dfc289e4ce1023a9d398b9e04a91ae3a9070",
+                "parents": {
+                  "nodes": [
+                    {
+                      "oid": "2cee47aedc9b4d321e378d7020984adf005fef64",
+                      "__typename": "Commit"
+                    }
+                  ],
+                  "__typename": "CommitConnection"
+                },
+                "__typename": "Commit"
+              },
+              "__typename": "PullRequestCommit"
+            }
+          ],
+          "__typename": "PullRequestCommitConnection"
+        },
+        "timelineItems": {
+          "nodes": [],
+          "__typename": "PullRequestTimelineItemsConnection"
+        },
+        "reviews": {
+          "nodes": [
+            {
+              "author": {
+                "login": "kaoDev",
+                "__typename": "User"
+              },
+              "commit": {
+                "oid": "9ba7dfc289e4ce1023a9d398b9e04a91ae3a9070",
+                "__typename": "Commit"
+              },
+              "comments": {
+                "nodes": [],
+                "__typename": "PullRequestReviewCommentConnection"
+              },
+              "authorAssociation": "CONTRIBUTOR",
+              "state": "APPROVED",
+              "submittedAt": "2022-02-14T18:07:29Z",
+              "url": "https://github.com/DefinitelyTyped/DefinitelyTyped/pull/58764#pullrequestreview-882009864",
+              "__typename": "PullRequestReview"
+            }
+          ],
+          "__typename": "PullRequestReviewConnection"
+        },
+        "commits": {
+          "totalCount": 1,
+          "nodes": [
+            {
+              "commit": {
+                "checkSuites": {
+                  "nodes": [
+                    {
+                      "databaseId": 5290726535,
+                      "app": {
+                        "name": "Azure Pipelines",
+                        "__typename": "App"
+                      },
+                      "conclusion": "FAILURE",
+                      "resourcePath": "/DefinitelyTyped/DefinitelyTyped/commit/9ba7dfc289e4ce1023a9d398b9e04a91ae3a9070/checks?check_suite_id=5290726535",
+                      "status": "COMPLETED",
+                      "url": "https://github.com/DefinitelyTyped/DefinitelyTyped/commit/9ba7dfc289e4ce1023a9d398b9e04a91ae3a9070/checks?check_suite_id=5290726535",
+                      "checkRuns": {
+                        "nodes": [
+                          {
+                            "title": "Build #20220214.1 failed",
+                            "__typename": "CheckRun"
+                          }
+                        ],
+                        "__typename": "CheckRunConnection"
+                      },
+                      "__typename": "CheckSuite"
+                    },
+                    {
+                      "databaseId": 5290726540,
+                      "app": {
+                        "name": "Dependabot",
+                        "__typename": "App"
+                      },
+                      "conclusion": null,
+                      "resourcePath": "/DefinitelyTyped/DefinitelyTyped/commit/9ba7dfc289e4ce1023a9d398b9e04a91ae3a9070/checks?check_suite_id=5290726540",
+                      "status": "QUEUED",
+                      "url": "https://github.com/DefinitelyTyped/DefinitelyTyped/commit/9ba7dfc289e4ce1023a9d398b9e04a91ae3a9070/checks?check_suite_id=5290726540",
+                      "checkRuns": {
+                        "nodes": [],
+                        "__typename": "CheckRunConnection"
+                      },
+                      "__typename": "CheckSuite"
+                    }
+                  ],
+                  "__typename": "CheckSuiteConnection"
+                },
+                "status": null,
+                "authoredDate": "2022-02-14T00:04:05Z",
+                "committedDate": "2022-02-14T00:04:05Z",
+                "pushedDate": "2022-02-14T00:04:13Z",
+                "oid": "9ba7dfc289e4ce1023a9d398b9e04a91ae3a9070",
+                "__typename": "Commit"
+              },
+              "__typename": "PullRequestCommit"
+            }
+          ],
+          "__typename": "PullRequestCommitConnection"
+        },
+        "comments": {
+          "totalCount": 3,
+          "nodes": [
+            {
+              "id": "IC_kwDOAFz6BM495gup",
+              "author": {
+                "login": "typescript-bot",
+                "__typename": "User"
+              },
+              "databaseId": 1038486441,
+              "body": "@github-actions Thank you for submitting this PR!\n\n***This is a live comment which I will keep updated.***\n\n## 9 packages in this PR\n\n* `bootstrap.v3.datetimepicker` — [on npm](https://www.npmjs.com/package/bootstrap.v3.datetimepicker), [on unpkg](https://unpkg.com/browse/bootstrap.v3.datetimepicker@latest/)\n* `mithril-global` — [on npm](https://www.npmjs.com/package/mithril-global), [on unpkg](https://unpkg.com/browse/mithril-global@latest/)\n  - 1 removed owner: @isiahmeadows\n* `mithril` — [on npm](https://www.npmjs.com/package/mithril), [on unpkg](https://unpkg.com/browse/mithril@latest/)\n  - 1 removed owner: @isiahmeadows\n* `ospec` — [on npm](https://www.npmjs.com/package/ospec), [on unpkg](https://unpkg.com/browse/ospec@latest/)\n  - 1 removed owner: @isiahmeadows\n* `react-grid-layout` — [on npm](https://www.npmjs.com/package/react-grid-layout), [on unpkg](https://unpkg.com/browse/react-grid-layout@latest/)\n  - 1 removed owner: @catusmagnus\n* `react-native-fbsdk` — [on npm](https://www.npmjs.com/package/react-native-fbsdk), [on unpkg](https://unpkg.com/browse/react-native-fbsdk@latest/)\n  - 1 removed owner: @UHKim\n* `react-virtualized` — [on npm](https://www.npmjs.com/package/react-virtualized), [on unpkg](https://unpkg.com/browse/react-virtualized@latest/)\n  - owner-approval: @kaoDev\n  - 1 removed owner: @mgoszcz2\n* `ssh2-sftp-client` — [on npm](https://www.npmjs.com/package/ssh2-sftp-client), [on unpkg](https://unpkg.com/browse/ssh2-sftp-client@latest/)\n  - 1 removed owner: @sgalizia\n* `styled-components` — [on npm](https://www.npmjs.com/package/styled-components), [on unpkg](https://unpkg.com/browse/styled-components@latest/)\n  - 1 removed owner: @mgoszcz2\n\n## Code Reviews\n\nBecause this is a widely-used package, a DT maintainer will need to review it before it can be merged.\n\nYou can test the changes of this PR [in the Playground](https://www.typescriptlang.org/play/?dtPR=58764&install-plugin=playground-dt-review).\n\n## Status\n\n * ✅ No merge conflicts\n * ❓ Continuous integration tests have gone missing\n * 🕐 A DT maintainer needs to approve changes which affect more than one package\n\nOnce every item on this list is checked, I'll ask you for permission to merge and publish the changes.\n\n----------------------\n... diagnostics scrubbed ...\n<!--typescript_bot_welcome-->",
+              "createdAt": "2022-02-14T00:04:52Z",
+              "reactions": {
+                "nodes": [],
+                "__typename": "ReactionConnection"
+              },
+              "__typename": "IssueComment"
+            },
+            {
+              "id": "IC_kwDOAFz6BM495gu5",
+              "author": {
+                "login": "typescript-bot",
+                "__typename": "User"
+              },
+              "databaseId": 1038486457,
+              "body": "Hey @github-actions,\n\n:unamused: Your PR doesn't modify any tests, so it's hard to know what's being fixed, and your changes might regress in the future. Please consider [adding tests](https://github.com/DefinitelyTyped/DefinitelyTyped#user-content-test-editing-an-existing-package) to cover the change you're making. Including tests allows this PR to be merged by yourself and the owners of this module.\n\n***This can potentially save days of time for you!***\n<!--typescript_bot_suggest-testing-->",
+              "createdAt": "2022-02-14T00:04:53Z",
+              "reactions": {
+                "nodes": [],
+                "__typename": "ReactionConnection"
+              },
+              "__typename": "IssueComment"
+            },
+            {
+              "id": "IC_kwDOAFz6BM495gu_",
+              "author": {
+                "login": "typescript-bot",
+                "__typename": "User"
+              },
+              "databaseId": 1038486463,
+              "body": "🔔 @katonap @spacejack @isiahmeadows @maranomynet @abirkholz @alitaheri @ZheyangSong @andrewhathaway @manav-m @al-fyodorov @catusmagnus @ifiokjr @titozzz @stuartforrest-infinity @UHKim @kaoDev @guntherjh @wasd171 @Stevearzh @mgoszcz2 @brandonhall @sbusch @azmenak @igrayson @ascariandrea @kartik2406 @viamuli @gbhmt @builtbylane @loru88 @sgalizia @hengkx @candyapplecorn @tsop14 @Igorbek @Igmat @Jessidhia @jkillian @eps1lon @wagerfield @Lazyuki @lifeiscontent — please [review this PR](https://github.com/DefinitelyTyped/DefinitelyTyped/pull/58764/files) in the next few days. Be sure to explicitly select **`Approve`** or **`Request Changes`** in the GitHub UI so I know what's going on.\n<!--typescript_bot_pinging-reviewers-->",
+              "createdAt": "2022-02-14T00:04:54Z",
+              "reactions": {
+                "nodes": [],
+                "__typename": "ReactionConnection"
+              },
+              "__typename": "IssueComment"
+            }
+          ],
+          "__typename": "IssueCommentConnection"
+        },
+        "files": {
+          "totalCount": 9,
+          "nodes": [
+            {
+              "path": "types/bootstrap.v3.datetimepicker/v3/index.d.ts",
+              "additions": 1,
+              "deletions": 1,
+              "__typename": "PullRequestChangedFile"
+            },
+            {
+              "path": "types/mithril-global/index.d.ts",
+              "additions": 1,
+              "deletions": 1,
+              "__typename": "PullRequestChangedFile"
+            },
+            {
+              "path": "types/mithril/index.d.ts",
+              "additions": 1,
+              "deletions": 1,
+              "__typename": "PullRequestChangedFile"
+            },
+            {
+              "path": "types/ospec/index.d.ts",
+              "additions": 0,
+              "deletions": 1,
+              "__typename": "PullRequestChangedFile"
+            },
+            {
+              "path": "types/react-grid-layout/index.d.ts",
+              "additions": 6,
+              "deletions": 7,
+              "__typename": "PullRequestChangedFile"
+            },
+            {
+              "path": "types/react-native-fbsdk/index.d.ts",
+              "additions": 0,
+              "deletions": 1,
+              "__typename": "PullRequestChangedFile"
+            },
+            {
+              "path": "types/react-virtualized/index.d.ts",
+              "additions": 0,
+              "deletions": 1,
+              "__typename": "PullRequestChangedFile"
+            },
+            {
+              "path": "types/ssh2-sftp-client/index.d.ts",
+              "additions": 0,
+              "deletions": 1,
+              "__typename": "PullRequestChangedFile"
+            },
+            {
+              "path": "types/styled-components/index.d.ts",
+              "additions": 0,
+              "deletions": 1,
+              "__typename": "PullRequestChangedFile"
+            }
+          ],
+          "pageInfo": {
+            "hasNextPage": false,
+            "endCursor": "OQ",
+            "__typename": "PageInfo"
+          },
+          "__typename": "PullRequestChangedFileConnection"
+        },
+        "projectCards": {
+          "nodes": [
+            {
+              "id": "PRC_lALOAFz6BM4AORWwzgSgr8E",
+              "project": {
+                "id": "MDc6UHJvamVjdDM3NDExMDQ=",
+                "number": 5,
+                "name": "New Pull Request Status Board",
+                "__typename": "Project"
+              },
+              "column": {
+                "id": "MDEzOlByb2plY3RDb2x1bW43NTUyOTI2",
+                "name": "Other",
+                "__typename": "ProjectColumn"
+              },
+              "__typename": "ProjectCard"
+            }
+          ],
+          "__typename": "ProjectCardConnection"
+        },
+        "__typename": "PullRequest"
+      },
+      "__typename": "Repository"
+    }
+  },
+  "loading": false,
+  "networkStatus": 7
+}
diff --git a/src/_tests/fixtures/58764/derived.json b/src/_tests/fixtures/58764/derived.json
new file mode 100644
index 0000000..7bd8e35
--- /dev/null
+++ b/src/_tests/fixtures/58764/derived.json
@@ -0,0 +1,225 @@
+{
+  "type": "info",
+  "now": "2022-02-17T22:11:42.329Z",
+  "pr_number": 58764,
+  "author": "github-actions",
+  "headCommitOid": "9ba7dfc289e4ce1023a9d398b9e04a91ae3a9070",
+  "mergeBaseOid": "2cee47aedc9b4d321e378d7020984adf005fef64",
+  "lastPushDate": "2022-02-14T00:04:13.000Z",
+  "lastActivityDate": "2022-02-14T18:07:29.000Z",
+  "hasMergeConflict": false,
+  "isFirstContribution": false,
+  "tooManyFiles": false,
+  "hugeChange": false,
+  "popularityLevel": "Critical",
+  "pkgInfo": [
+    {
+      "name": "bootstrap.v3.datetimepicker",
+      "kind": "edit",
+      "files": [
+        {
+          "path": "types/bootstrap.v3.datetimepicker/v3/index.d.ts",
+          "kind": "definition"
+        }
+      ],
+      "owners": [
+        "katonap"
+      ],
+      "addedOwners": [],
+      "deletedOwners": [],
+      "popularityLevel": "Well-liked by everyone"
+    },
+    {
+      "name": "mithril-global",
+      "kind": "edit",
+      "files": [
+        {
+          "path": "types/mithril-global/index.d.ts",
+          "kind": "definition"
+        }
+      ],
+      "owners": [
+        "spacejack",
+        "isiahmeadows"
+      ],
+      "addedOwners": [],
+      "deletedOwners": [
+        "isiahmeadows"
+      ],
+      "popularityLevel": "Well-liked by everyone"
+    },
+    {
+      "name": "mithril",
+      "kind": "edit",
+      "files": [
+        {
+          "path": "types/mithril/index.d.ts",
+          "kind": "definition"
+        }
+      ],
+      "owners": [
+        "spacejack",
+        "isiahmeadows"
+      ],
+      "addedOwners": [],
+      "deletedOwners": [
+        "isiahmeadows"
+      ],
+      "popularityLevel": "Well-liked by everyone"
+    },
+    {
+      "name": "ospec",
+      "kind": "edit",
+      "files": [
+        {
+          "path": "types/ospec/index.d.ts",
+          "kind": "definition"
+        }
+      ],
+      "owners": [
+        "maranomynet",
+        "spacejack",
+        "isiahmeadows"
+      ],
+      "addedOwners": [],
+      "deletedOwners": [
+        "isiahmeadows"
+      ],
+      "popularityLevel": "Well-liked by everyone"
+    },
+    {
+      "name": "react-grid-layout",
+      "kind": "edit",
+      "files": [
+        {
+          "path": "types/react-grid-layout/index.d.ts",
+          "kind": "definition"
+        }
+      ],
+      "owners": [
+        "abirkholz",
+        "alitaheri",
+        "ZheyangSong",
+        "andrewhathaway",
+        "manav-m",
+        "al-fyodorov",
+        "catusmagnus"
+      ],
+      "addedOwners": [],
+      "deletedOwners": [
+        "catusmagnus"
+      ],
+      "popularityLevel": "Popular"
+    },
+    {
+      "name": "react-native-fbsdk",
+      "kind": "edit",
+      "files": [
+        {
+          "path": "types/react-native-fbsdk/index.d.ts",
+          "kind": "definition"
+        }
+      ],
+      "owners": [
+        "ifiokjr",
+        "titozzz",
+        "stuartforrest-infinity",
+        "UHKim"
+      ],
+      "addedOwners": [],
+      "deletedOwners": [
+        "UHKim"
+      ],
+      "popularityLevel": "Well-liked by everyone"
+    },
+    {
+      "name": "react-virtualized",
+      "kind": "edit",
+      "files": [
+        {
+          "path": "types/react-virtualized/index.d.ts",
+          "kind": "definition"
+        }
+      ],
+      "owners": [
+        "kaoDev",
+        "guntherjh",
+        "wasd171",
+        "Stevearzh",
+        "mgoszcz2",
+        "brandonhall",
+        "sbusch",
+        "azmenak"
+      ],
+      "addedOwners": [],
+      "deletedOwners": [
+        "mgoszcz2"
+      ],
+      "popularityLevel": "Popular"
+    },
+    {
+      "name": "ssh2-sftp-client",
+      "kind": "edit",
+      "files": [
+        {
+          "path": "types/ssh2-sftp-client/index.d.ts",
+          "kind": "definition"
+        }
+      ],
+      "owners": [
+        "igrayson",
+        "ascariandrea",
+        "kartik2406",
+        "viamuli",
+        "gbhmt",
+        "builtbylane",
+        "loru88",
+        "sgalizia",
+        "hengkx",
+        "candyapplecorn",
+        "tsop14"
+      ],
+      "addedOwners": [],
+      "deletedOwners": [
+        "sgalizia"
+      ],
+      "popularityLevel": "Popular"
+    },
+    {
+      "name": "styled-components",
+      "kind": "edit",
+      "files": [
+        {
+          "path": "types/styled-components/index.d.ts",
+          "kind": "definition"
+        }
+      ],
+      "owners": [
+        "Igorbek",
+        "Igmat",
+        "Jessidhia",
+        "jkillian",
+        "eps1lon",
+        "wagerfield",
+        "Lazyuki",
+        "mgoszcz2",
+        "lifeiscontent"
+      ],
+      "addedOwners": [],
+      "deletedOwners": [
+        "mgoszcz2"
+      ],
+      "popularityLevel": "Critical"
+    }
+  ],
+  "reviews": [
+    {
+      "type": "approved",
+      "reviewer": "kaoDev",
+      "date": "2022-02-14T18:07:29.000Z",
+      "isMaintainer": false
+    }
+  ],
+  "mainBotCommentID": 1038486441,
+  "ciResult": "missing"
+}
diff --git a/src/_tests/fixtures/58764/mutations.json b/src/_tests/fixtures/58764/mutations.json
new file mode 100644
index 0000000..1b3716f
--- /dev/null
+++ b/src/_tests/fixtures/58764/mutations.json
@@ -0,0 +1,31 @@
+[
+  {
+    "mutation": "mutation ($input: UpdateIssueCommentInput!) {\n  updateIssueComment(input: $input) {\n    __typename\n  }\n}\n",
+    "variables": {
+      "input": {
+        "id": "IC_kwDOAFz6BM495gup",
+        "body": "@github-actions Thank you for submitting this PR!From one bot to another, beep bloop boople bloop.\n\n***This is a live comment which I will keep updated.***\n\n## 9 packages in this PR\n\n* `bootstrap.v3.datetimepicker` — [on npm](https://www.npmjs.com/package/bootstrap.v3.datetimepicker), [on unpkg](https://unpkg.com/browse/bootstrap.v3.datetimepicker@latest/)\n* `mithril-global` — [on npm](https://www.npmjs.com/package/mithril-global), [on unpkg](https://unpkg.com/browse/mithril-global@latest/)\n  - 1 removed owner: @isiahmeadows\n* `mithril` — [on npm](https://www.npmjs.com/package/mithril), [on unpkg](https://unpkg.com/browse/mithril@latest/)\n  - 1 removed owner: @isiahmeadows\n* `ospec` — [on npm](https://www.npmjs.com/package/ospec), [on unpkg](https://unpkg.com/browse/ospec@latest/)\n  - 1 removed owner: @isiahmeadows\n* `react-grid-layout` — [on npm](https://www.npmjs.com/package/react-grid-layout), [on unpkg](https://unpkg.com/browse/react-grid-layout@latest/)\n  - 1 removed owner: @catusmagnus\n* `react-native-fbsdk` — [on npm](https://www.npmjs.com/package/react-native-fbsdk), [on unpkg](https://unpkg.com/browse/react-native-fbsdk@latest/)\n  - 1 removed owner: @UHKim\n* `react-virtualized` — [on npm](https://www.npmjs.com/package/react-virtualized), [on unpkg](https://unpkg.com/browse/react-virtualized@latest/)\n  - owner-approval: @kaoDev\n  - 1 removed owner: @mgoszcz2\n* `ssh2-sftp-client` — [on npm](https://www.npmjs.com/package/ssh2-sftp-client), [on unpkg](https://unpkg.com/browse/ssh2-sftp-client@latest/)\n  - 1 removed owner: @sgalizia\n* `styled-components` — [on npm](https://www.npmjs.com/package/styled-components), [on unpkg](https://unpkg.com/browse/styled-components@latest/)\n  - 1 removed owner: @mgoszcz2\n\n## Code Reviews\n\nBecause this is a widely-used package, a DT maintainer will need to review it before it can be merged.\n\nYou can test the changes of this PR [in the Playground](https://www.typescriptlang.org/play/?dtPR=58764&install-plugin=playground-dt-review).\n\n## Status\n\n * ✅ No merge conflicts\n * ❓ Continuous integration tests have gone missing\n * 🕐 A DT maintainer needs to approve changes which affect more than one package\n\nOnce every item on this list is checked, I'll ask you for permission to merge and publish the changes.\n\n----------------------\n... diagnostics scrubbed ...\n<!--typescript_bot_welcome-->"
+      }
+    }
+  },
+  {
+    "mutation": "mutation ($input: RemoveLabelsFromLabelableInput!) {\n  removeLabelsFromLabelable(input: $input) {\n    __typename\n  }\n}\n",
+    "variables": {
+      "input": {
+        "labelIds": [
+          "MDU6TGFiZWwyMDk2NzQ1NzQx"
+        ],
+        "labelableId": "PR_kwDOAFz6BM4yvxmj"
+      }
+    }
+  },
+  {
+    "mutation": "mutation ($input: MoveProjectCardInput!) {\n  moveProjectCard(input: $input) {\n    __typename\n  }\n}\n",
+    "variables": {
+      "input": {
+        "cardId": "PRC_lALOAFz6BM4AORWwzgSgr8E",
+        "columnId": "MDEzOlByb2plY3RDb2x1bW45ODY3MDA2"
+      }
+    }
+  }
+]
diff --git a/src/_tests/fixtures/58764/result.json b/src/_tests/fixtures/58764/result.json
new file mode 100644
index 0000000..a133df9
--- /dev/null
+++ b/src/_tests/fixtures/58764/result.json
@@ -0,0 +1,22 @@
+{
+  "projectColumn": "Needs Maintainer Action",
+  "labels": [
+    "Critical package",
+    "Edits Owners",
+    "Edits multiple packages",
+    "Untested Change"
+  ],
+  "responseComments": [
+    {
+      "tag": "suggest-testing",
+      "status": "Hey @github-actions,\n\n:unamused: Your PR doesn't modify any tests, so it's hard to know what's being fixed, and your changes might regress in the future. Please consider [adding tests](https://github.com/DefinitelyTyped/DefinitelyTyped#user-content-test-editing-an-existing-package) to cover the change you're making. Including tests allows this PR to be merged by yourself and the owners of this module.\n\n***This can potentially save days of time for you!***"
+    },
+    {
+      "tag": "welcome",
+      "status": "@github-actions Thank you for submitting this PR!From one bot to another, beep bloop boople bloop.\n\n***This is a live comment which I will keep updated.***\n\n## 9 packages in this PR\n\n* `bootstrap.v3.datetimepicker` — [on npm](https://www.npmjs.com/package/bootstrap.v3.datetimepicker), [on unpkg](https://unpkg.com/browse/bootstrap.v3.datetimepicker@latest/)\n* `mithril-global` — [on npm](https://www.npmjs.com/package/mithril-global), [on unpkg](https://unpkg.com/browse/mithril-global@latest/)\n  - 1 removed owner: @isiahmeadows\n* `mithril` — [on npm](https://www.npmjs.com/package/mithril), [on unpkg](https://unpkg.com/browse/mithril@latest/)\n  - 1 removed owner: @isiahmeadows\n* `ospec` — [on npm](https://www.npmjs.com/package/ospec), [on unpkg](https://unpkg.com/browse/ospec@latest/)\n  - 1 removed owner: @isiahmeadows\n* `react-grid-layout` — [on npm](https://www.npmjs.com/package/react-grid-layout), [on unpkg](https://unpkg.com/browse/react-grid-layout@latest/)\n  - 1 removed owner: @catusmagnus\n* `react-native-fbsdk` — [on npm](https://www.npmjs.com/package/react-native-fbsdk), [on unpkg](https://unpkg.com/browse/react-native-fbsdk@latest/)\n  - 1 removed owner: @UHKim\n* `react-virtualized` — [on npm](https://www.npmjs.com/package/react-virtualized), [on unpkg](https://unpkg.com/browse/react-virtualized@latest/)\n  - owner-approval: @kaoDev\n  - 1 removed owner: @mgoszcz2\n* `ssh2-sftp-client` — [on npm](https://www.npmjs.com/package/ssh2-sftp-client), [on unpkg](https://unpkg.com/browse/ssh2-sftp-client@latest/)\n  - 1 removed owner: @sgalizia\n* `styled-components` — [on npm](https://www.npmjs.com/package/styled-components), [on unpkg](https://unpkg.com/browse/styled-components@latest/)\n  - 1 removed owner: @mgoszcz2\n\n## Code Reviews\n\nBecause this is a widely-used package, a DT maintainer will need to review it before it can be merged.\n\nYou can test the changes of this PR [in the Playground](https://www.typescriptlang.org/play/?dtPR=58764&install-plugin=playground-dt-review).\n\n## Status\n\n * ✅ No merge conflicts\n * ❓ Continuous integration tests have gone missing\n * 🕐 A DT maintainer needs to approve changes which affect more than one package\n\nOnce every item on this list is checked, I'll ask you for permission to merge and publish the changes.\n\n----------------------\n... diagnostics scrubbed ..."
+    }
+  ],
+  "shouldClose": false,
+  "shouldMerge": false,
+  "shouldUpdateLabels": true
+}
diff --git a/src/_tests/fixtures/59628/_downloads.json b/src/_tests/fixtures/59628/_downloads.json
new file mode 100644
index 0000000..25a2871
--- /dev/null
+++ b/src/_tests/fixtures/59628/_downloads.json
@@ -0,0 +1,3 @@
+{
+  "twemoji": 242870
+}
diff --git a/src/_tests/fixtures/59628/_files.json b/src/_tests/fixtures/59628/_files.json
new file mode 100644
index 0000000..a598a5d
--- /dev/null
+++ b/src/_tests/fixtures/59628/_files.json
@@ -0,0 +1,3 @@
+{
+  "e11ae5d76bb7c11e606ed5aa0e47c1f1e81fd88d:types/twemoji/index.d.ts": "// Type definitions for twemoji 12.1\n// Project: https://github.com/twitter/twemoji\n// Definitions by: Markus Tacker <https://github.com/coderbyheart>\n//                 Piotr Błażejewicz <https://github.com/peterblazejewicz>\n//                 David Wheatley <https://github.com/davwheat>\n// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped\n// TypeScript Version: 2.2\n\n/**\n * A simple library that provides standard Unicode emoji support across all platforms.\n * Twemoji v12.0 adheres to the Unicode 12.0 spec and supports the Emoji 12.0 spec\n * The Twemoji library offers support for 3,075 emojis.\n */\nexport as namespace twemoji;\n\n/**\n * default assets url, by default will be Twitter Inc. CDN\n */\nexport const base: string;\n\n/**\n * default assets file extensions, by default '.png'\n */\nexport const ext: string;\n\n/**\n * default assets/folder size, by default \"72x72\"\n * available via Twitter CDN: 72\n */\nexport const size: string;\n\n/**\n * default class name, by default 'emoji'\n */\nexport const className: string;\n\n/**\n * basic utilities / helpers to convert code points\n * to JavaScript surrogates and vice versa\n */\nexport const convert: {\n    /**\n     * Given an HEX codepoint, returns UTF16 surrogate pairs.\n     *\n     * @param   codepoint string  generic codepoint, i.e. '1F4A9'\n     * @return  string  codepoint transformed into utf16 surrogates pair,\n     *          i.e. \\uD83D\\uDCA9\n     *\n     * @example\n     *  twemoji.convert.fromCodePoint('1f1e8');\n     *  // \"\\ud83c\\udde8\"\n     *\n     *  '1f1e8-1f1f3'.split('-').map(twemoji.convert.fromCodePoint).join('')\n     *  // \"\\ud83c\\udde8\\ud83c\\uddf3\"\n     */\n    fromCodePoint: (codepoint: string) => string;\n\n    /**\n     * Given UTF16 surrogate pairs, returns the equivalent HEX codepoint.\n     *\n     * @param   unicodeSurrogates   string  generic utf16 surrogates pair, i.e. \\uD83D\\uDCA9\n     * @param   sep                 string  optional separator for double code points, default='-'\n     * @return  string  utf16 transformed into codepoint, i.e. '1F4A9'\n     *\n     * @example\n     *  twemoji.convert.toCodePoint('\\ud83c\\udde8\\ud83c\\uddf3');\n     *  // \"1f1e8-1f1f3\"\n     *\n     *  twemoji.convert.toCodePoint('\\ud83c\\udde8\\ud83c\\uddf3', '~');\n     *  // \"1f1e8~1f1f3\"\n     */\n    toCodePoint: (unicodeSurrogates: string, sep?: string) => string;\n};\n\n/**\n * User first: used to remove missing images\n * preserving the original text intent when\n * a fallback for network problems is desired.\n * Automatically added to Image nodes via DOM\n * It could be recycled for string operations via:\n *  $('img.emoji').on('error', twemoji.onerror)\n */\nexport function onerror(): void;\n\n/**\n * Given a string, invokes the callback argument\n * per each emoji found in such string.\n * This is the most raw version used by\n * the .parse(string) method itself.\n *\n * @param   text      string    generic string to parse\n * @param   callback  Function  a generic callback that will be\n *                              invoked to replace the content.\n *                              This calback wil receive standard\n *                              String.prototype.replace(str, callback)\n *                              arguments such:\n *  callback(\n *    rawText,  // the emoji match\n *  );\n *\n *                    and others commonly received via replace.\n */\nexport function replace(text: string, callback: () => void): string;\n\n/**\n * Simplify string tests against emoji.\n *\n * @param   text string  some text that might contain emoji\n * @return  boolean true if any emoji was found, false otherwise.\n *\n * @example\n *\n *  if (twemoji.test(someContent)) {\n *    console.log(\"emoji All The Things!\");\n *  }\n */\nexport function test(text: string): boolean;\n\n/**\n * If given to parse, this callback will be invoked per each found emoji.\n *\n * If this callback returns a falsy value instead of a valid `src` to use for the image, nothing will actually change for that specific emoji.\n *\n * @param icon the lower case HEX code point i.e. \"1f4a9\"\n * @param options all info for this parsing operation\n * @param variant the optional \\uFE0F (\"as image\") variant, in case this info is anyhow meaningful. By default this is ignored.\n */\nexport type ParseCallback = (icon: string, options: object, variant: string) => string | false;\n\n/**\n * If given to parse, this object with all properties will be used per each found emoji.\n *\n *            callback   Function  the callback to invoke per each found emoji.\n *            base       string    the base url, by default twemoji.base\n *            ext        string    the image extension, by default twemoji.ext\n *            size       string    the assets size, by default twemoji.size\n */\nexport interface ParseObject {\n    /**\n     * the callback to invoke per each found emoji.\n     *\n     * default: the common replacer\n     */\n    callback: ParseCallback;\n    /**\n     * The function to invoke in order to generate additional, custom attributes for the image tag.\n     *\n     * @param the lower case HEX code point i.e. \"1f4a9\"\n     * @param variant the optional \\uFE0F (\"as image\") variant, in case this info is anyhow meaningful. By default this is ignored.\n     */\n    attributes: (icon: string, variant: string) => object;\n    /**\n     * default: MaxCDN\n     */\n    base: string;\n    /**\n     * default: \".png\"\n     */\n    ext: string;\n    /**\n     * default: \"emoji\"\n     */\n    className: string;\n    /**\n     * default: \"72x72\"\n     */\n    size: string | number;\n    /**\n     * in case it's specified it replaces .size info, if any\n     */\n    folder: string;\n}\n\n/**\n * Main method/logic to generate either <img> tags or HTMLImage nodes.\n *  \"emojify\" a generic text or DOM Element.\n *\n * @overloads\n *\n * String replacement for `innerHTML` or server side operations\n *  twemoji.parse(string);\n *  twemoji.parse(string, Function);\n *  twemoji.parse(string, Object);\n *\n * HTMLElement tree parsing for safer operations over existing DOM\n *  twemoji.parse(HTMLElement);\n *  twemoji.parse(HTMLElement, Function);\n *  twemoji.parse(HTMLElement, Object);\n *\n * @param   what string|HTMLElement  the source to parse and enrich with emoji.\n *\n *          string              replace emoji matches with <img> tags.\n *                              Mainly used to inject emoji via `innerHTML`\n *                              It does **not** parse the string or validate it,\n *                              it simply replaces found emoji with a tag.\n *                              NOTE: be sure this won't affect security.\n *\n *          HTMLElement         walk through the DOM tree and find emoji\n *                              that are inside **text node only** (nodeType === 3)\n *                              Mainly used to put emoji in already generated DOM\n *                              without compromising surrounding nodes and\n *                              **avoiding** the usage of `innerHTML`.\n *                              NOTE: Using DOM elements instead of strings should\n *                              improve security without compromising too much\n *                              performance compared with a less safe `innerHTML`.\n *\n * @param   how object|Function\n *\n * @example\n *\n *  twemoji.parse(\"I \\u2764\\uFE0F emoji!\");\n *  // I <img class=\"emoji\" draggable=\"false\" alt=\"❤️\" src=\"/assets/2764.gif\"/> emoji!\n *\n *\n *  twemoji.parse(\"I \\u2764\\uFE0F emoji!\", function(iconId, options) {\n *    return '/assets/' + iconId + '.gif';\n *  });\n *  // I <img class=\"emoji\" draggable=\"false\" alt=\"❤️\" src=\"/assets/2764.gif\"/> emoji!\n *\n *\n * twemoji.parse(\"I \\u2764\\uFE0F emoji!\", {\n *   size: 72,\n *   callback: function(iconId, options) {\n *     return '/assets/' + options.size + '/' + iconId + options.ext;\n *   }\n * });\n *  // I <img class=\"emoji\" draggable=\"false\" alt=\"❤️\" src=\"/assets/72x72/2764.png\"/> emoji!\n */\nexport function parse<T extends string | HTMLElement>(what: T, how?: Partial<ParseObject> | ParseCallback): T;\n"
+}
diff --git a/src/_tests/fixtures/59628/_response.json b/src/_tests/fixtures/59628/_response.json
new file mode 100644
index 0000000..8afc7fa
--- /dev/null
+++ b/src/_tests/fixtures/59628/_response.json
@@ -0,0 +1,357 @@
+{
+  "data": {
+    "repository": {
+      "id": "MDEwOlJlcG9zaXRvcnk2MDkzMzE2",
+      "pullRequest": {
+        "id": "PR_kwDOAFz6BM41bNTc",
+        "title": ":tada: 'twemoji' no longer required",
+        "createdAt": "2022-03-31T19:26:36Z",
+        "author": {
+          "login": "peterblazejewicz",
+          "__typename": "User"
+        },
+        "authorAssociation": "MEMBER",
+        "baseRef": {
+          "name": "master",
+          "__typename": "Ref"
+        },
+        "labels": {
+          "nodes": [
+            {
+              "name": "Popular package",
+              "__typename": "Label"
+            },
+            {
+              "name": "Self Merge",
+              "__typename": "Label"
+            },
+            {
+              "name": "Owner Approved",
+              "__typename": "Label"
+            },
+            {
+              "name": "Edits Infrastructure",
+              "__typename": "Label"
+            },
+            {
+              "name": "Maintainer Approved",
+              "__typename": "Label"
+            }
+          ],
+          "__typename": "LabelConnection"
+        },
+        "isDraft": false,
+        "mergeable": "MERGEABLE",
+        "number": 59628,
+        "state": "OPEN",
+        "headRefOid": "15c10d80e670b01133ffe2d37c4ffe3d3c3f3941",
+        "changedFiles": 6,
+        "additions": 4,
+        "deletions": 313,
+        "commitIds": {
+          "nodes": [
+            {
+              "commit": {
+                "oid": "15c10d80e670b01133ffe2d37c4ffe3d3c3f3941",
+                "parents": {
+                  "nodes": [
+                    {
+                      "oid": "e11ae5d76bb7c11e606ed5aa0e47c1f1e81fd88d",
+                      "__typename": "Commit"
+                    }
+                  ],
+                  "__typename": "CommitConnection"
+                },
+                "__typename": "Commit"
+              },
+              "__typename": "PullRequestCommit"
+            }
+          ],
+          "__typename": "PullRequestCommitConnection"
+        },
+        "timelineItems": {
+          "nodes": [
+            {
+              "actor": {
+                "login": "typescript-bot",
+                "__typename": "User"
+              },
+              "createdAt": "2022-03-31T19:32:10Z",
+              "projectColumnName": "Needs Maintainer Action",
+              "__typename": "MovedColumnsInProjectEvent"
+            },
+            {
+              "actor": {
+                "login": "typescript-bot",
+                "__typename": "User"
+              },
+              "createdAt": "2022-03-31T22:12:55Z",
+              "projectColumnName": "Waiting for Author to Merge",
+              "__typename": "MovedColumnsInProjectEvent"
+            }
+          ],
+          "__typename": "PullRequestTimelineItemsConnection"
+        },
+        "reviews": {
+          "nodes": [
+            {
+              "author": {
+                "login": "davwheat",
+                "__typename": "User"
+              },
+              "commit": {
+                "oid": "15c10d80e670b01133ffe2d37c4ffe3d3c3f3941",
+                "__typename": "Commit"
+              },
+              "comments": {
+                "nodes": [],
+                "__typename": "PullRequestReviewCommentConnection"
+              },
+              "authorAssociation": "CONTRIBUTOR",
+              "state": "APPROVED",
+              "submittedAt": "2022-03-31T19:33:37Z",
+              "url": "https://github.com/DefinitelyTyped/DefinitelyTyped/pull/59628#pullrequestreview-928083763",
+              "__typename": "PullRequestReview"
+            },
+            {
+              "author": {
+                "login": "andrewbranch",
+                "__typename": "User"
+              },
+              "commit": {
+                "oid": "15c10d80e670b01133ffe2d37c4ffe3d3c3f3941",
+                "__typename": "Commit"
+              },
+              "comments": {
+                "nodes": [],
+                "__typename": "PullRequestReviewCommentConnection"
+              },
+              "authorAssociation": "MEMBER",
+              "state": "APPROVED",
+              "submittedAt": "2022-03-31T22:12:17Z",
+              "url": "https://github.com/DefinitelyTyped/DefinitelyTyped/pull/59628#pullrequestreview-928237599",
+              "__typename": "PullRequestReview"
+            }
+          ],
+          "__typename": "PullRequestReviewConnection"
+        },
+        "commits": {
+          "totalCount": 1,
+          "nodes": [
+            {
+              "commit": {
+                "checkSuites": {
+                  "nodes": [
+                    {
+                      "databaseId": 5883803312,
+                      "app": {
+                        "name": "GitHub Actions",
+                        "__typename": "App"
+                      },
+                      "conclusion": "SUCCESS",
+                      "resourcePath": "/DefinitelyTyped/DefinitelyTyped/commit/15c10d80e670b01133ffe2d37c4ffe3d3c3f3941/checks?check_suite_id=5883803312",
+                      "status": "COMPLETED",
+                      "url": "https://github.com/DefinitelyTyped/DefinitelyTyped/commit/15c10d80e670b01133ffe2d37c4ffe3d3c3f3941/checks?check_suite_id=5883803312",
+                      "checkRuns": {
+                        "nodes": [
+                          {
+                            "title": null,
+                            "__typename": "CheckRun"
+                          }
+                        ],
+                        "__typename": "CheckRunConnection"
+                      },
+                      "__typename": "CheckSuite"
+                    },
+                    {
+                      "databaseId": 5883805587,
+                      "app": {
+                        "name": "Azure Pipelines",
+                        "__typename": "App"
+                      },
+                      "conclusion": "SUCCESS",
+                      "resourcePath": "/DefinitelyTyped/DefinitelyTyped/commit/15c10d80e670b01133ffe2d37c4ffe3d3c3f3941/checks?check_suite_id=5883805587",
+                      "status": "COMPLETED",
+                      "url": "https://github.com/DefinitelyTyped/DefinitelyTyped/commit/15c10d80e670b01133ffe2d37c4ffe3d3c3f3941/checks?check_suite_id=5883805587",
+                      "checkRuns": {
+                        "nodes": [
+                          {
+                            "title": "Build #20220331.39 succeeded",
+                            "__typename": "CheckRun"
+                          }
+                        ],
+                        "__typename": "CheckRunConnection"
+                      },
+                      "__typename": "CheckSuite"
+                    }
+                  ],
+                  "__typename": "CheckSuiteConnection"
+                },
+                "status": null,
+                "authoredDate": "2022-03-31T19:23:51Z",
+                "committedDate": "2022-03-31T19:23:51Z",
+                "pushedDate": "2022-03-31T19:26:15Z",
+                "oid": "15c10d80e670b01133ffe2d37c4ffe3d3c3f3941",
+                "__typename": "Commit"
+              },
+              "__typename": "PullRequestCommit"
+            }
+          ],
+          "__typename": "PullRequestCommitConnection"
+        },
+        "comments": {
+          "totalCount": 5,
+          "nodes": [
+            {
+              "id": "IC_kwDOAFz6BM5ArAD6",
+              "author": {
+                "login": "typescript-bot",
+                "__typename": "User"
+              },
+              "databaseId": 1085014266,
+              "body": "@peterblazejewicz Thank you for submitting this PR!\n\n***This is a live comment which I will keep updated.***\n\nThis PR touches some part of DefinitelyTyped infrastructure, so a DT maintainer will need to review it. This is rare — did you mean to do this?\n\n## 1 package in this PR (and infra files)\n\n* `twemoji` (*probably deleted!*) — [on npm](https://www.npmjs.com/package/twemoji), [on unpkg](https://unpkg.com/browse/twemoji@latest/) (author is owner)\n  - owner-approval: @davwheat\n* Infra files\n  - [`notNeededPackages.json`](https://github.com/DefinitelyTyped/DefinitelyTyped/pull/59628/files/15c10d80e670b01133ffe2d37c4ffe3d3c3f3941#diff-a275c2eae7b8f788a52327e76809026ee1bc5ea614393806c8f3cbab07202621)\n\n## Code Reviews\n\nThis PR can be merged once it's reviewed by a DT maintainer.\n\nYou can test the changes of this PR [in the Playground](https://www.typescriptlang.org/play/?dtPR=59628&install-plugin=playground-dt-review).\n\n## Status\n\n * ✅ No merge conflicts\n * ✅ Continuous integration tests have passed\n * ✅ A DT maintainer needs to approve changes which affect DT infrastructure ([`notNeededPackages.json`](https://github.com/DefinitelyTyped/DefinitelyTyped/pull/59628/files/15c10d80e670b01133ffe2d37c4ffe3d3c3f3941#diff-a275c2eae7b8f788a52327e76809026ee1bc5ea614393806c8f3cbab07202621))\n\nAll of the items on the list are green. **To merge, you need to post a comment including the string \"Ready to merge\"** to bring in your changes.\n\n----------------------\n... diagnostics scrubbed ...\n<!--typescript_bot_welcome-->",
+              "createdAt": "2022-03-31T19:27:13Z",
+              "reactions": {
+                "nodes": [],
+                "__typename": "ReactionConnection"
+              },
+              "__typename": "IssueComment"
+            },
+            {
+              "id": "IC_kwDOAFz6BM5ArAEU",
+              "author": {
+                "login": "typescript-bot",
+                "__typename": "User"
+              },
+              "databaseId": 1085014292,
+              "body": "🔔 @coderbyheart @davwheat — please [review this PR](https://github.com/DefinitelyTyped/DefinitelyTyped/pull/59628/files) in the next few days. Be sure to explicitly select **`Approve`** or **`Request Changes`** in the GitHub UI so I know what's going on.\n<!--typescript_bot_pinging-reviewers-->",
+              "createdAt": "2022-03-31T19:27:16Z",
+              "reactions": {
+                "nodes": [],
+                "__typename": "ReactionConnection"
+              },
+              "__typename": "IssueComment"
+            },
+            {
+              "id": "IC_kwDOAFz6BM5AroSK",
+              "author": {
+                "login": "typescript-bot",
+                "__typename": "User"
+              },
+              "databaseId": 1085179018,
+              "body": "@peterblazejewicz: Everything looks good here. I am ready to merge this PR (at 15c10d8) on your behalf whenever you think it's ready.\n\nIf you'd like that to happen, please post a comment saying:\n\n> Ready to merge\n\nand I'll merge this PR almost instantly. Thanks for helping out! :heart:\n\n(@coderbyheart, @davwheat: you can do this too.)\n<!--typescript_bot_merge-offer-->",
+              "createdAt": "2022-03-31T22:12:56Z",
+              "reactions": {
+                "nodes": [],
+                "__typename": "ReactionConnection"
+              },
+              "__typename": "IssueComment"
+            },
+            {
+              "id": "IC_kwDOAFz6BM5ArpCN",
+              "author": {
+                "login": "davwheat",
+                "__typename": "User"
+              },
+              "databaseId": 1085182093,
+              "body": "Ready to merge",
+              "createdAt": "2022-03-31T22:17:03Z",
+              "reactions": {
+                "nodes": [],
+                "__typename": "ReactionConnection"
+              },
+              "__typename": "IssueComment"
+            },
+            {
+              "id": "IC_kwDOAFz6BM5ArxKw",
+              "author": {
+                "login": "andrewbranch",
+                "__typename": "User"
+              },
+              "databaseId": 1085215408,
+              "body": "@typescript-bot 🤨",
+              "createdAt": "2022-03-31T23:05:00Z",
+              "reactions": {
+                "nodes": [],
+                "__typename": "ReactionConnection"
+              },
+              "__typename": "IssueComment"
+            }
+          ],
+          "__typename": "IssueCommentConnection"
+        },
+        "files": {
+          "totalCount": 6,
+          "nodes": [
+            {
+              "path": "notNeededPackages.json",
+              "additions": 4,
+              "deletions": 0,
+              "__typename": "PullRequestChangedFile"
+            },
+            {
+              "path": "types/twemoji/index.d.ts",
+              "additions": 0,
+              "deletions": 229,
+              "__typename": "PullRequestChangedFile"
+            },
+            {
+              "path": "types/twemoji/test/twemoji-tests.common-js.ts",
+              "additions": 0,
+              "deletions": 30,
+              "__typename": "PullRequestChangedFile"
+            },
+            {
+              "path": "types/twemoji/test/twemoji-tests.global.ts",
+              "additions": 0,
+              "deletions": 28,
+              "__typename": "PullRequestChangedFile"
+            },
+            {
+              "path": "types/twemoji/tsconfig.json",
+              "additions": 0,
+              "deletions": 25,
+              "__typename": "PullRequestChangedFile"
+            },
+            {
+              "path": "types/twemoji/tslint.json",
+              "additions": 0,
+              "deletions": 1,
+              "__typename": "PullRequestChangedFile"
+            }
+          ],
+          "pageInfo": {
+            "hasNextPage": false,
+            "endCursor": "Ng",
+            "__typename": "PageInfo"
+          },
+          "__typename": "PullRequestChangedFileConnection"
+        },
+        "projectCards": {
+          "nodes": [
+            {
+              "id": "PRC_lALOAFz6BM4AORWwzgTEe7s",
+              "project": {
+                "id": "MDc6UHJvamVjdDM3NDExMDQ=",
+                "number": 5,
+                "name": "New Pull Request Status Board",
+                "__typename": "Project"
+              },
+              "column": {
+                "id": "MDEzOlByb2plY3RDb2x1bW43NTUyOTIz",
+                "name": "Waiting for Author to Merge",
+                "__typename": "ProjectColumn"
+              },
+              "__typename": "ProjectCard"
+            }
+          ],
+          "__typename": "ProjectCardConnection"
+        },
+        "__typename": "PullRequest"
+      },
+      "__typename": "Repository"
+    }
+  },
+  "loading": false,
+  "networkStatus": 7
+}
diff --git a/src/_tests/fixtures/59628/derived.json b/src/_tests/fixtures/59628/derived.json
new file mode 100644
index 0000000..ecca257
--- /dev/null
+++ b/src/_tests/fixtures/59628/derived.json
@@ -0,0 +1,84 @@
+{
+  "type": "info",
+  "now": "2022-03-31T23:12:03.301Z",
+  "pr_number": 59628,
+  "author": "peterblazejewicz",
+  "headCommitOid": "15c10d80e670b01133ffe2d37c4ffe3d3c3f3941",
+  "mergeBaseOid": "e11ae5d76bb7c11e606ed5aa0e47c1f1e81fd88d",
+  "lastPushDate": "2022-03-31T19:26:15.000Z",
+  "lastActivityDate": "2022-03-31T23:05:00.000Z",
+  "mergeOfferDate": "2022-03-31T22:12:56.000Z",
+  "mergeRequestDate": "2022-03-31T22:17:03.000Z",
+  "mergeRequestUser": "davwheat",
+  "hasMergeConflict": false,
+  "isFirstContribution": false,
+  "tooManyFiles": false,
+  "hugeChange": false,
+  "popularityLevel": "Popular",
+  "pkgInfo": [
+    {
+      "name": null,
+      "kind": "edit",
+      "files": [
+        {
+          "path": "notNeededPackages.json",
+          "kind": "infrastructure"
+        }
+      ],
+      "owners": [],
+      "addedOwners": [],
+      "deletedOwners": [],
+      "popularityLevel": "Critical"
+    },
+    {
+      "name": "twemoji",
+      "kind": "delete",
+      "files": [
+        {
+          "path": "types/twemoji/index.d.ts",
+          "kind": "definition"
+        },
+        {
+          "path": "types/twemoji/test/twemoji-tests.common-js.ts",
+          "kind": "test"
+        },
+        {
+          "path": "types/twemoji/test/twemoji-tests.global.ts",
+          "kind": "test"
+        },
+        {
+          "path": "types/twemoji/tsconfig.json",
+          "kind": "package-meta-ok"
+        },
+        {
+          "path": "types/twemoji/tslint.json",
+          "kind": "package-meta-ok"
+        }
+      ],
+      "owners": [
+        "coderbyheart",
+        "peterblazejewicz",
+        "davwheat"
+      ],
+      "addedOwners": [],
+      "deletedOwners": [],
+      "popularityLevel": "Popular"
+    }
+  ],
+  "reviews": [
+    {
+      "type": "approved",
+      "reviewer": "andrewbranch",
+      "date": "2022-03-31T22:12:17.000Z",
+      "isMaintainer": true
+    },
+    {
+      "type": "approved",
+      "reviewer": "davwheat",
+      "date": "2022-03-31T19:33:37.000Z",
+      "isMaintainer": false
+    }
+  ],
+  "mainBotCommentID": 1085014266,
+  "ciResult": "pass"
+}
diff --git a/src/_tests/fixtures/59628/mutations.json b/src/_tests/fixtures/59628/mutations.json
new file mode 100644
index 0000000..7ac50c9
--- /dev/null
+++ b/src/_tests/fixtures/59628/mutations.json
@@ -0,0 +1,31 @@
+[
+  {
+    "mutation": "mutation ($input: UpdateIssueCommentInput!) {\n  updateIssueComment(input: $input) {\n    __typename\n  }\n}\n",
+    "variables": {
+      "input": {
+        "id": "IC_kwDOAFz6BM5ArAD6",
+        "body": "@peterblazejewicz Thank you for submitting this PR!\n\n***This is a live comment which I will keep updated.***\n\nThis PR touches some part of DefinitelyTyped infrastructure, so a DT maintainer will need to review it. This is rare — did you mean to do this?\n\n## 1 package in this PR (and infra files)\n\n* `twemoji` (*probably deleted!*) — [on npm](https://www.npmjs.com/package/twemoji), [on unpkg](https://unpkg.com/browse/twemoji@latest/) (author is owner)\n  - owner-approval: @davwheat\n* Infra files\n  - [`notNeededPackages.json`](https://github.com/DefinitelyTyped/DefinitelyTyped/pull/59628/files/15c10d80e670b01133ffe2d37c4ffe3d3c3f3941#diff-a275c2eae7b8f788a52327e76809026ee1bc5ea614393806c8f3cbab07202621)\n\n## Code Reviews\n\nThis PR can be merged once it's reviewed by a DT maintainer.\n\nYou can test the changes of this PR [in the Playground](https://www.typescriptlang.org/play/?dtPR=59628&install-plugin=playground-dt-review).\n\n## Status\n\n * ✅ No merge conflicts\n * ✅ Continuous integration tests have passed\n * ✅ A DT maintainer needs to approve changes which affect DT infrastructure ([`notNeededPackages.json`](https://github.com/DefinitelyTyped/DefinitelyTyped/pull/59628/files/15c10d80e670b01133ffe2d37c4ffe3d3c3f3941#diff-a275c2eae7b8f788a52327e76809026ee1bc5ea614393806c8f3cbab07202621))\n\nAll of the items on the list are green. **To merge, you need to post a comment including the string \"Ready to merge\"** to bring in your changes.\n\n----------------------\n... diagnostics scrubbed ...\n<!--typescript_bot_welcome-->"
+      }
+    }
+  },
+  {
+    "mutation": "mutation ($input: MoveProjectCardInput!) {\n  moveProjectCard(input: $input) {\n    __typename\n  }\n}\n",
+    "variables": {
+      "input": {
+        "cardId": "PRC_lALOAFz6BM4AORWwzgTEe7s",
+        "columnId": "MDEzOlByb2plY3RDb2x1bW43NTUyOTI1"
+      }
+    }
+  },
+  {
+    "mutation": "mutation ($input: MergePullRequestInput!) {\n  mergePullRequest(input: $input) {\n    __typename\n  }\n}\n",
+    "variables": {
+      "input": {
+        "commitHeadline": "🤖 Merge PR #59628 :tada: 'twemoji' no longer required by @peterblazejewicz",
+        "expectedHeadOid": "15c10d80e670b01133ffe2d37c4ffe3d3c3f3941",
+        "mergeMethod": "SQUASH",
+        "pullRequestId": "PR_kwDOAFz6BM41bNTc"
+      }
+    }
+  }
+]
diff --git a/src/_tests/fixtures/59628/result.json b/src/_tests/fixtures/59628/result.json
new file mode 100644
index 0000000..0afd218
--- /dev/null
+++ b/src/_tests/fixtures/59628/result.json
@@ -0,0 +1,23 @@
+{
+  "projectColumn": "Recently Merged",
+  "labels": [
+    "Popular package",
+    "Owner Approved",
+    "Maintainer Approved",
+    "Edits Infrastructure",
+    "Self Merge"
+  ],
+  "responseComments": [
+    {
+      "tag": "welcome",
+      "status": "@peterblazejewicz Thank you for submitting this PR!\n\n***This is a live comment which I will keep updated.***\n\nThis PR touches some part of DefinitelyTyped infrastructure, so a DT maintainer will need to review it. This is rare — did you mean to do this?\n\n## 1 package in this PR (and infra files)\n\n* `twemoji` (*probably deleted!*) — [on npm](https://www.npmjs.com/package/twemoji), [on unpkg](https://unpkg.com/browse/twemoji@latest/) (author is owner)\n  - owner-approval: @davwheat\n* Infra files\n  - [`notNeededPackages.json`](https://github.com/DefinitelyTyped/DefinitelyTyped/pull/59628/files/15c10d80e670b01133ffe2d37c4ffe3d3c3f3941#diff-a275c2eae7b8f788a52327e76809026ee1bc5ea614393806c8f3cbab07202621)\n\n## Code Reviews\n\nThis PR can be merged once it's reviewed by a DT maintainer.\n\nYou can test the changes of this PR [in the Playground](https://www.typescriptlang.org/play/?dtPR=59628&install-plugin=playground-dt-review).\n\n## Status\n\n * ✅ No merge conflicts\n * ✅ Continuous integration tests have passed\n * ✅ A DT maintainer needs to approve changes which affect DT infrastructure ([`notNeededPackages.json`](https://github.com/DefinitelyTyped/DefinitelyTyped/pull/59628/files/15c10d80e670b01133ffe2d37c4ffe3d3c3f3941#diff-a275c2eae7b8f788a52327e76809026ee1bc5ea614393806c8f3cbab07202621))\n\nAll of the items on the list are green. **To merge, you need to post a comment including the string \"Ready to merge\"** to bring in your changes.\n\n----------------------\n... diagnostics scrubbed ..."
+    },
+    {
+      "tag": "merge-offer",
+      "status": "@peterblazejewicz: Everything looks good here. I am ready to merge this PR (at 15c10d8) on your behalf whenever you think it's ready.\n\nIf you'd like that to happen, please post a comment saying:\n\n> Ready to merge\n\nand I'll merge this PR almost instantly. Thanks for helping out! :heart:\n\n(@coderbyheart, @davwheat: you can do this too.)"
+    }
+  ],
+  "shouldClose": false,
+  "shouldMerge": true,
+  "shouldUpdateLabels": true
+}