Add GrLibLoader library config for Resemble.js

This will be used by the new image diff UI for highlighting changes
between the base and revision image when requested.

Change-Id: I6487039ee4af0a1ed6d02f97d940a146a2914dea
diff --git a/Documentation/js_licenses.txt b/Documentation/js_licenses.txt
index 9ac438a..40fd4cf 100644
--- a/Documentation/js_licenses.txt
+++ b/Documentation/js_licenses.txt
@@ -250,6 +250,7 @@
 [[DefinitelyTyped]]
 DefinitelyTyped
 
+* @types/resemblejs
 * @types/resize-observer-browser
 
 [[DefinitelyTyped_license]]
diff --git a/Documentation/licenses.txt b/Documentation/licenses.txt
index 1bff25c..0c06dae 100644
--- a/Documentation/licenses.txt
+++ b/Documentation/licenses.txt
@@ -3209,6 +3209,7 @@
 [[DefinitelyTyped]]
 DefinitelyTyped
 
+* @types/resemblejs
 * @types/resize-observer-browser
 
 [[DefinitelyTyped_license]]
diff --git a/polygerrit-ui/app/elements/shared/gr-lib-loader/resemble-types.d.ts b/polygerrit-ui/app/elements/shared/gr-lib-loader/resemble-types.d.ts
new file mode 100644
index 0000000..79ce81c
--- /dev/null
+++ b/polygerrit-ui/app/elements/shared/gr-lib-loader/resemble-types.d.ts
@@ -0,0 +1,28 @@
+/**
+ * @license
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Resemble from 'resemblejs';
+
+// @types/resemblejs does not expose a global variable resemble and instead
+// exposes the namespace Resemble. Because Resemble.js should remain an
+// optional dependency, we define a global variable in a separate .d.ts file;
+// otherwise, the TS compiler tries to import the JS library too and fails.
+declare global {
+  interface Window {
+    resemble?: typeof Resemble;
+  }
+}
diff --git a/polygerrit-ui/app/elements/shared/gr-lib-loader/resemblejs_config.ts b/polygerrit-ui/app/elements/shared/gr-lib-loader/resemblejs_config.ts
new file mode 100644
index 0000000..872d01c
--- /dev/null
+++ b/polygerrit-ui/app/elements/shared/gr-lib-loader/resemblejs_config.ts
@@ -0,0 +1,33 @@
+/**
+ * @license
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import {LibraryConfig} from './gr-lib-loader';
+
+export const RESEMBLEJS_LIBRARY_CONFIG: LibraryConfig = {
+  src: 'bower_components/resemblejs/resemble.js',
+  checkPresent: () => window.resemble !== undefined,
+  configureCallback: () => {
+    window.resemble!.outputSettings({
+      errorColor: {red: 255, green: 0, blue: 255},
+      errorType: 'flat',
+      transparency: 0,
+      // Disable large image threshold; by default this otherwise skips pixels
+      // if width or height exceed 1200 pixels.
+      largeImageThreshold: 0,
+    });
+    return window.resemble;
+  },
+};
diff --git a/polygerrit-ui/app/node_modules_licenses/licenses.ts b/polygerrit-ui/app/node_modules_licenses/licenses.ts
index ac49388..17f83a0 100644
--- a/polygerrit-ui/app/node_modules_licenses/licenses.ts
+++ b/polygerrit-ui/app/node_modules_licenses/licenses.ts
@@ -288,6 +288,14 @@
     license: SharedLicenses.Polymer2017
   },
   {
+    name: "@types/resemblejs",
+    license: {
+      name: 'DefinitelyTyped',
+      type: LicenseTypes.Mit,
+      packageLicenseFile: "LICENSE"
+    }
+  },
+  {
     name: "@types/resize-observer-browser",
     license: {
       name: 'DefinitelyTyped',
diff --git a/polygerrit-ui/app/package.json b/polygerrit-ui/app/package.json
index 4f5acf5..ac6aaf6 100644
--- a/polygerrit-ui/app/package.json
+++ b/polygerrit-ui/app/package.json
@@ -31,6 +31,7 @@
     "@polymer/paper-toggle-button": "^3.0.1",
     "@polymer/paper-tooltip": "^3.0.1",
     "@polymer/polymer": "^3.4.1",
+    "@types/resemblejs": "^3.2.0",
     "@types/resize-observer-browser": "^0.1.5",
     "@webcomponents/shadycss": "^1.10.2",
     "@webcomponents/webcomponentsjs": "^1.3.3",
diff --git a/polygerrit-ui/app/yarn.lock b/polygerrit-ui/app/yarn.lock
index fed42a4..a89d6dc 100644
--- a/polygerrit-ui/app/yarn.lock
+++ b/polygerrit-ui/app/yarn.lock
@@ -395,6 +395,11 @@
   dependencies:
     "@webcomponents/shadycss" "^1.9.1"
 
+"@types/resemblejs@^3.2.0":
+  version "3.2.0"
+  resolved "https://registry.yarnpkg.com/@types/resemblejs/-/resemblejs-3.2.0.tgz#a2093fd6ae027d39b56ae279f362a4d83e00788f"
+  integrity sha512-YUBCCipw3DG0/FUswHAiamZcs+JBZlRr1aNs1T19AkfLZNtzV4VphmRLy6wJ3m1i9QxIfiBe3RnzVjHbjRqLaA==
+
 "@types/resize-observer-browser@^0.1.5":
   version "0.1.5"
   resolved "https://registry.yarnpkg.com/@types/resize-observer-browser/-/resize-observer-browser-0.1.5.tgz#36d897708172ac2380cd486da7a3daf1161c1e23"