/**
 * @license
 * Copyright 2021 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */

module.exports = {
  env: { browser: true, es2020: true },
  extends: [
    "eslint:recommended",
    "plugin:jsdoc/recommended",
    "google",
    "plugin:@typescript-eslint/recommended",
    "plugin:@typescript-eslint/recommended-requiring-type-checking",
    "prettier",
  ],
  ignorePatterns: [
    "dist/",
    ".eslintrc.js",
    "fake_server.js",
    "karma.conf.js",
    "webpack.config.js",
  ],
  parser: "@typescript-eslint/parser",
  parserOptions: {
    sourceType: "module",
    tsconfigRootDir: __dirname,
    project: ["./tsconfig.json"],
  },
  plugins: ["@typescript-eslint", "jsdoc"],
  rules: {
    "max-len": [
      "warn",
      {
        code: Infinity,
        comments: 80,
        ignorePattern: String.raw`^\s*// eslint-disable-next-line.*`,
        ignoreUrls: true,
      },
    ],
    "no-inner-declarations": "off",
    "require-jsdoc": "off",
    "valid-jsdoc": "off",
    "jsdoc/check-indentation": "warn",
    "jsdoc/check-param-names": "off",
    "jsdoc/check-values": [
      "error",
      {
        allowedLicenses: true,
        licensePattern:
          "^\nCopyright 2021 Google LLC\nSPDX-License-Identifier: Apache-2\\.0$",
      },
    ],
    "jsdoc/require-file-overview": [
      "error",
      {
        tags: {
          file: {
            mustExist: true,
            preventDuplicates: true,
            initialCommentsOnly: true,
          },
          license: {
            mustExist: true,
            preventDuplicates: true,
            initialCommentsOnly: true,
          },
        },
      },
    ],
    "jsdoc/require-jsdoc": ["warn", { publicOnly: true }],
    "jsdoc/require-param": "off",
    "jsdoc/require-param-type": "off",
    "jsdoc/require-returns": "off",
    "jsdoc/require-returns-type": "off",
  },
  overrides: [
    {
      files: ["*_test.ts"],
      rules: {
        "jsdoc/require-file-overview": [
          "error",
          {
            tags: {
              license: {
                mustExist: true,
                preventDuplicates: true,
                initialCommentsOnly: true,
              },
            },
          },
        ],
      },
    },
  ],
  settings: {
    jsdoc: {
      tagNamePreference: { file: "fileoverview", returns: "return" },
    },
  },
};

@@ -394,16 +394,129 @@
 dist/%22,%0A
+    // This configuration is designed for TypeScript and much of it doesn't%0A    // work properly with .js files.%0A
     %22.es
@@ -861,221 +861,568 @@
     
-code: Infinity,%0A        comments: 80,%0A        ignorePattern: String.raw%60%5E%5Cs*// eslint-disable-next-line.*%60,%0A        ignoreUrls: true,%0A      %7D,%0A    %5D,%0A    %22no-inner-declarations%22: %22off%22,%0A    %22require-jsdoc%22: %22off%22,
+// Whatever Prettier wraps lines to is acceptable.%0A        code: Infinity,%0A        // However, Prettier doesn't wrap comments.%0A        comments: 80,%0A        ignorePattern: String.raw%60%5E%5Cs*// eslint-disable-next-line.*%60,%0A        ignoreUrls: true,%0A      %7D,%0A    %5D,%0A    // Per https://eslint.org/docs/rules/no-inner-declarations, this is obsolete%0A    // since ES2015.%0A    %22no-inner-declarations%22: %22off%22,%0A    // Superseded by jsdoc/require-jsdoc.%0A    %22require-jsdoc%22: %22off%22,%0A    // Many JSDoc-related rules are superseded by TypeScript type annotation%0A    // syntax.
 %0A   
@@ -1717,32 +1717,97 @@
       %7D,%0A    %5D,%0A
+    // Non-test files require both @license and a @fileoverview.%0A
     %22jsdoc/requi
@@ -2442,24 +2442,87 @@
    rules: %7B%0A
+        // Test files require @license, but not @fileoverview.%0A
         %22jsd
@@ -2843,24 +2843,68 @@
    jsdoc: %7B%0A
+      // Google Style uses these tag names.%0A
       tagNam

Add explanatory comments to .eslintrc.js (#54)