<!DOCTYPE HTML>
<!--
Copyright 2014 The Chromium Authors
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
  <meta name="theme-color" id="theme-color">
  <!-- Placeholder for CSP. -->
  <meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'nonce-f9kYiCxWSzRdrd9FMhxf4Q=='; frame-src http://www.youtube.com; style-src 'unsafe-inline' https://fonts.googleapis.com; font-src https://fonts.gstatic.com; img-src data:; form-action 'none'; base-uri 'none'; ">
  <title>Simplified view</title>
  <link href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet">
  <!-- Placeholder for CSS. -->
  <style>/* Copyright 2014 The Chromium Authors
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file. */

/* This file contains style used across ALL platforms. Platform-specific styling
 * should be placed in the corresponding file (e.g. desktop style goes in
 * distilledpage_desktop.css).*/

/* Set the global 'box-sizing' state to 'border-box'.
 * *::after and *::before used to select pseudo-elements not selectable by *. */

:root {
  --google-blue-300: 138, 180, 248;
  --google-blue-600: 26, 115, 232;
  --google-blue-700: 25, 103, 210;
  --google-brown-900: 62, 39, 35;
  --google-grey-50: 248, 249, 250;
  --google-grey-900: 32, 33, 36;
  --google-purple-300: 197, 138, 249;
  --google-purple-700: 132, 48, 206;
  --google-yellow-50: 254, 247, 224;
  --google-yellow-100: 254, 239, 195;
}

*,
*::after,
*::before {
  box-sizing: border-box;
}

/* Remove all margins and padding from certain element and add word wrap. */

blockquote,
body,
caption,
dd,
dl,
fieldset,
figure,
form,
h1,
h2,
h3,
h4,
h5,
h6,
hr,
legend,
ol,
p,
pre,
ul,
table,
td,
th {
  margin: 0;
  padding: 0;
  word-wrap: break-word;
}

/* Prevent 'sub' and 'sup' affecting 'line-height'. */

sub,
sup {
  font-size: 75%;
  line-height: 0;
  position: relative;
  vertical-align: baseline;
}

sup {
  top: -0.5em;
}

sub {
  bottom: -0.25em;
}

/* Remove most spacing between table cells. */

table {
  border-collapse: collapse;
  border-spacing: 0;
  display: block;
  overflow-x: auto;
}

td,
th {
  padding: 0.5rem;
}

/* Base typography. */

html {
  /* This has to be in sync with |baseSize| in dom_distiller_viewer.js. */
  font-size: 14px;
}

body {
  -webkit-overflow-scrolling: touch;
  display: flex;
  flex-direction: column;
  line-height: 1.714;
  margin: 0 auto;
  min-height: 100vh;
  overflow-x: hidden;
  text-rendering: optimizeLegibility;
  transition-duration: 500ms;
  transition-property: color, background-color;
  transition-timing-function: ease;
}

/* Classes for light, dark and sepia themes.
 * Must agree with classes returned by useTheme() in dom_distiller_viewer.js
 * and with CSS class constants in viewer.cc */

.light {
  background-color: #FFF;
  color: rgb(var(--google-grey-900));
}

.dark {
  background-color: rgb(var(--google-grey-900));
  color: #FFF;
}

.sepia {
  background-color: rgb(var(--google-yellow-50));
  color: rgb(var(--google-brown-900));
}

.light a:link {
  color: rgb(var(--google-blue-600));
}

.sepia a:link {
  color: rgb(var(--google-blue-700));
}

.dark a:link {
  color: rgb(var(--google-blue-300));
}

.light a:visited {
  color: rgb(var(--google-purple-700));
}

.sepia a:visited {
  color: rgb(var(--google-purple-700));
}

.dark a:visited {
  color: rgb(var(--google-purple-300));
}

.light code,
.light pre {
  background-color: rgb(var(--google-grey-50));
  border-color: rgb(var(--google-grey-900));
}

.sepia code,
.sepia pre {
  background-color: rgb(var(--google-yellow-100));
  border-color: rgba(var(--google-brown-900), 0.5);
}

.dark code,
.dark pre {
  background-color: #000;
  border-color: rgba(255, 255, 255, 0.5);
}

.light tbody tr:nth-child(odd) {
  background-color: #EEE;
}

.light th,
.light td {
  border-inline-start: 2px solid #AAA;
}

.sepia tbody tr:nth-child(odd) {
  background-color: rgb(217, 196, 175);
}

.sepia th,
.sepia td {
  border-inline-start: 1px solid rgb(147, 125, 102);
}

.dark tbody tr:nth-child(odd) {
  background-color: #333;
}

.dark th,
.dark td {
  border-inline-start: 1px solid #555;
}

/* #content-wrap is added to be more specific than the color theme rules */
#content-wrap th:first-child {
  border-inline-start: none;
}

#content-wrap td:first-child {
  border-inline-start: none;
}


/* Font settings */

.serif {
  font-family: serif;
}

.sans-serif {
  font-family: 'Roboto', sans-serif;
}

.monospace {
  font-family: monospace;
}

/* Define vertical rhythm (baseline grid of 4px). */

blockquote,
caption,
code,
dd,
dl,
fieldset,
figure,
form,
hr,
legend,
ol,
p,
pre,
q,
table,
td,
th,
ul {
  margin-bottom: 1.143rem;
}

h1,
h2,
h3,
h4,
h5,
h6 {
  line-height: 1.417;
  margin: 1em 0;
}

/* Content. */

#loading-indicator {
  padding-bottom: 2em;
  width: 100%;
}

#loading-indicator > img,
#loading-indicator > svg {
  display: block;
  height: 2.5em;
  margin: auto;
  width: 2.5em;
}

/* Margins for Show Original link. */

video::-webkit-media-controls-fullscreen-button {
  display: none;
}

#content {
  margin: 24px 16px 24px 16px;
}

#main-content {
  flex: 1 1 auto;
  margin: 0 auto;
  max-width: 35em;
  width: 100%;
}

#article-header {
  margin-top: 24px;
  width: 100%;
}

#title-holder {
  font-size: 1.714rem;
  line-height: 1.417;
  margin: 0 16px;
}

blockquote {
  border-inline-start: 4px solid #888;
  padding-inline-start: 1em;
}

cite {
  font-style: italic;
  opacity: .8;
}

hr {
  border-style: solid;
  height: 1px 0 0 0;
  opacity: .5;
  width: 75%;
}


q {
  display: block;
  font-style: italic;
  font-weight: 600;
  opacity: .8;
}

embed,
img,
object,
video {
  max-width: 100%;
}

/* TODO(sunangel): make images zoomable. */

img {
  display: block;
  height: auto;
  margin: 0.6rem auto 0.4rem auto;
}

/* TODO(nyquist): set these classes directly in the dom distiller. */

embed+[class*='caption'],
figcaption,
img+[class*='caption'],
object+[class*='caption'],
video+[class*='caption'] {
  display: table;
  font-size: 0.857rem;
  line-height: 1.667;
  margin-bottom: 1rem;
  opacity: .8;
}

ol,
ul {
  margin-inline-start: 1.296rem;
}

code,
pre {
  border: 1px solid;
  border-radius: 2px;
}

pre code {
  border: none;
}

pre {
  line-height: 1.642;
  padding: .5em;
  white-space: pre-wrap;
}

body .hidden {
  display: none;
}

.clear {
  clear: both;
}

/* Iframe sizing. */
.youtubeContainer {
  height: 0;
  /* This is the perecnt height of a standard HD video. */
  padding-bottom: 56.25%;
  position: relative;
  width: 100%;
}

.youtubeIframe {
  height: 100%;
  position: absolute;
  start: 0;
  top: 0;
  width: 100%;
}


.desktop-only {
  display: none;
}

</style>
</head>
<body class="light sans-serif">
  <div id="content-wrap">
    <div id="main-content">
      <div id="settings-container" class="desktop-only">
        <button id="settings-toggle" type="button"
            aria-label="Customize appearance" tabindex=0>
          <i class="material-icons">&#xE165</i>
        </button>
        <div id="dialog-backdrop"></div>
        <dialog id="settings-dialog">
          <div id="settings-header">
            <h1>Customize appearance</h1>
          </div>
          <div id="settings-fields">
            <div class="setting font-family-container">
              <label id="font-family-label" class="screen-reader-only">
                Font style
              </label>
              <select id="font-family-selection" aria-labelledby="font-family-label" name="font-family">
                <option value="sans-serif" selected>Sans-serif Font</option>
                <option value="serif">Serif Font</option>
                <option value="monospace">Monospace Font</option>
              </select>
              <i class="material-icons" id="arrow-drop-down">&#xe5c5</i>
            </div>
            <div class="setting">
              <fieldset id="theme-selection">
                <legend class="screen-reader-only">
                  Page Color
                </legend>
                <ul>
                  <li class="theme-option">
                    <input type="radio" name="theme" value="light"
                       aria-label="Light" id="theme-option-light" class="light" checked>
                    <div class="checkmark"><i class="material-icons" aria-hidden="true">&#xE86c</i></div>
                  </li>
                  <li class="theme-option">
                    <input type="radio" name="theme" value="sepia"
                       aria-label="Sepia" id="theme-option-sepia" class="sepia">
                    <div class="checkmark"><i class="material-icons" aria-hidden="true">&#xE86c</i></div>
                  </li>
                  <li class="theme-option">
                    <input type="radio" name="theme" value="dark"
                       aria-label="Dark" id="theme-option-dark" class="dark">
                    <div class="checkmark"><i class="material-icons" aria-hidden="true">&#xE86c</i></div>
                  </li>
                </ul>
              </fieldset>
            </div>
            <div class="setting" id="font-size-wrapper">
              <label id="font-size-label" class="screen-reader-only">
                Font Size
              </label>
              <input aria-labelledby="font-size-label"
                     id="font-size-selection"
                     type="range"
                     name="font-size"
                     list="tickmarks"
                     min="0"
                     max="9"
                     value="2">
              <div class="label-container">
                <span id="slider-label-min">Small</span>
                <span id="slider-label-max">Large</span>
              </div>
            </div>
          </div>
            <button id="close-settings-button" type="button"
                aria-label="Close" tabindex=0>
              <i class="material-icons">close</i>
            </button>
        </dialog>
      </div>
      <article>
        <header id="article-header">
          <div id="title-collapse">
            <div class="vertical-center-outer">
              <div class="vertical-center-inner">
                <h1 id="title-holder"><noscript>Simplified view</noscript></h1>
              </div>
            </div>
          </div>
        </header>
        <div id="content"><noscript>JavaScript must be enabled to use this feature.</noscript></div>
      </article>
      <div id="loading-indicator" class="visible">
        <!-- SVG material loading spinner. -->
        <svg version="1" xmlns="http://www.w3.org/2000/svg"
                 xmlns:xlink="http://www.w3.org/1999/xlink"
     width="16px" height="16px" viewBox="0 0 28 28">
  <!-- 28= RADIUS*2 + STROKEWIDTH -->

  <title>Material design circular activity spinner with CSS3 animation</title>
  <style type="text/css">
      /**************************/
      /* STYLES FOR THE SPINNER */
      /**************************/

      /*
       * Constants:
       *      RADIUS      = 12.5
       *      STROKEWIDTH = 3
       *      ARCSIZE     = 270 degrees (amount of circle the arc takes up)
       *      ARCTIME     = 1333ms (time it takes to expand and contract arc)
       *      ARCSTARTROT = 216 degrees (how much the start location of the arc
       *                                should rotate each time, 216 gives us a
       *                                5 pointed star shape (it's 360/5 * 2).
       *                                For a 7 pointed star, we might do
       *                                360/7 * 3 = 154.286)
       *
       *      SHRINK_TIME = 400ms
       */

      .qp-circular-loader {
        width:28px;  /* 2*RADIUS + STROKEWIDTH */
        height:28px; /* 2*RADIUS + STROKEWIDTH */
      }
      .qp-circular-loader-path {
        stroke-dasharray: 58.9;  /* 2*RADIUS*PI * ARCSIZE/360 */
        stroke-dashoffset: 58.9; /* 2*RADIUS*PI * ARCSIZE/360 */
                                 /* hides things initially */
      }

      /* SVG elements seem to have a different default origin */
      .qp-circular-loader, .qp-circular-loader * {
        -webkit-transform-origin: 50% 50%;
      }

      /* Rotating the whole thing */
      @-webkit-keyframes rotate {
        from {-webkit-transform: rotate(0deg);}
        to {-webkit-transform: rotate(360deg);}
      }
      .qp-circular-loader {
        -webkit-animation-name: rotate;
        -webkit-animation-duration: 1568.63ms; /* 360 * ARCTIME / (ARCSTARTROT + (360-ARCSIZE)) */
        -webkit-animation-iteration-count: infinite;
        -webkit-animation-timing-function: linear;
      }

      /* Filling and unfilling the arc */
      @-webkit-keyframes fillunfill {
        from {
          stroke-dashoffset: 58.8 /* 2*RADIUS*PI * ARCSIZE/360 - 0.1 */
                                  /* 0.1 a bit of a magic constant here */
        }
        50% {
          stroke-dashoffset: 0;
        }
        to {
          stroke-dashoffset: -58.4 /* -(2*RADIUS*PI * ARCSIZE/360 - 0.5) */
                                   /* 0.5 a bit of a magic constant here */
        }
      }
      @-webkit-keyframes rot {
        from {
          -webkit-transform: rotate(0deg);
        }
        to {
          -webkit-transform: rotate(-360deg);
        }
      }
      @-webkit-keyframes colors {
        from {
          stroke: #4285f4;
        }
        to {
          stroke: #4285f4;
        }
      }
      .qp-circular-loader-path {
        -webkit-animation-name: fillunfill, rot, colors;
        -webkit-animation-duration: 1333ms, 5332ms, 5332ms; /* ARCTIME, 4*ARCTIME, 4*ARCTIME */
        -webkit-animation-iteration-count: infinite, infinite, infinite;
        -webkit-animation-timing-function: cubic-bezier(0.4, 0.0, 0.2, 1), steps(4), linear;
        -webkit-animation-play-state: running, running, running;
        -webkit-animation-fill-mode: forwards;
      }

  </style>

  <!-- 3= STROKEWIDTH -->
  <!-- 14= RADIUS + STROKEWIDTH/2 -->
  <!-- 12.5= RADIUS -->
  <!-- 1.5=  STROKEWIDTH/2 -->
  <!-- ARCSIZE would affect the 1.5,14 part of this... 1.5,14 is specific to
       270 degress -->
  <g class="qp-circular-loader">
    <path class="qp-circular-loader-path" fill="none" 
          d="M 14,1.5 A 12.5,12.5 0 1 1 1.5,14" stroke-width="3"
          stroke-linecap="round"></path>
  </g>
</svg>


      </div>
    </div>
  </div>
</body>
</html>
<script nonce="f9kYiCxWSzRdrd9FMhxf4Q==">distillerOnIos = true; // Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// On iOS, |distillerOnIos| was set to true before this script.
// eslint-disable-next-line no-var
var distillerOnIos;
if (typeof distillerOnIos === 'undefined') {
  distillerOnIos = false;
}

// The style guide recommends preferring $() to getElementById(). Chrome's
// standard implementation of $() is imported from chrome://resources, which the
// distilled page is prohibited from accessing. A version of it is
// re-implemented here to allow stylistic consistency with other JS code.
function $(id) {
  return document.getElementById(id);
}

function addToPage(html) {
  const div = document.createElement('div');
  div.innerHTML = html;
  $('content').appendChild(div);
  fillYouTubePlaceholders();
}

function fillYouTubePlaceholders() {
  const placeholders = document.getElementsByClassName('embed-placeholder');
  for (let i = 0; i < placeholders.length; i++) {
    if (!placeholders[i].hasAttribute('data-type') ||
        placeholders[i].getAttribute('data-type') !== 'youtube' ||
        !placeholders[i].hasAttribute('data-id')) {
      continue;
    }
    const embed = document.createElement('iframe');
    const url = 'http://www.youtube.com/embed/' +
        placeholders[i].getAttribute('data-id');
    embed.setAttribute('class', 'youtubeIframe');
    embed.setAttribute('src', url);
    embed.setAttribute('type', 'text/html');
    embed.setAttribute('frameborder', '0');

    const parent = placeholders[i].parentElement;
    const container = document.createElement('div');
    container.setAttribute('class', 'youtubeContainer');
    container.appendChild(embed);

    parent.replaceChild(container, placeholders[i]);
  }
}

function showLoadingIndicator(isLastPage) {
  $('loading-indicator').className = isLastPage ? 'hidden' : 'visible';
}

// Sets the title.
function setTitle(title, documentTitleSuffix) {
  $('title-holder').textContent = title;
  if (documentTitleSuffix) {
    document.title = title + documentTitleSuffix;
  } else {
    document.title = title;
  }
}

// Set the text direction of the document ('ltr', 'rtl', or 'auto').
function setTextDirection(direction) {
  document.body.setAttribute('dir', direction);
}

// These classes must agree with the font classes in distilledpage.css.
const themeClasses = ['light', 'dark', 'sepia'];
const fontFamilyClasses = ['sans-serif', 'serif', 'monospace'];

// Get the currently applied appearance setting.
function getAppearanceSetting(settingClasses) {
  const cls = Array.from(document.body.classList)
                  .find((cls) => settingClasses.includes(cls));
  return cls ? cls : settingClasses[0];
}

function useTheme(theme) {
  settingsDialog.useTheme(theme);
}

function useFontFamily(fontFamily) {
  settingsDialog.useFontFamily(fontFamily);
}

function updateToolbarColor(theme) {
  let toolbarColor;
  if (theme === 'sepia') {
    toolbarColor = '#BF9A73';
  } else if (theme === 'dark') {
    toolbarColor = '#1A1A1A';
  } else {
    toolbarColor = '#F5F5F5';
  }
  $('theme-color').content = toolbarColor;
}

function maybeSetWebFont() {
  // On iOS, the web fonts block the rendering until the resources are
  // fetched, which can take a long time on slow networks.
  // In Blink, it times out after 3 seconds and uses fallback fonts.
  // See crbug.com/711650
  if (distillerOnIos) {
    return;
  }

  const e = document.createElement('link');
  e.href = 'https://fonts.googleapis.com/css?family=Roboto';
  e.rel = 'stylesheet';
  e.type = 'text/css';
  document.head.appendChild(e);
}

// TODO(crbug.com/40108835): Consider making this a custom HTML element.
class FontSizeSlider {
  constructor() {
    this.element = $('font-size-selection');
    this.baseSize = 16;
    // These scales are applied to a base size of 16px.
    this.fontSizeScale = [0.875, 0.9375, 1, 1.125, 1.25, 1.5, 1.75, 2, 2.5, 3];

    this.element.addEventListener('input', (e) => {
      const scale = this.fontSizeScale[e.target.value];
      this.useFontScaling(scale);
      distiller.storeFontScalingPref(parseFloat(scale));
    });

    this.tickmarks = document.createElement('datalist');
    this.tickmarks.setAttribute('class', 'tickmarks');
    this.element.after(this.tickmarks);

    for (let i = 0; i < this.fontSizeScale.length; i++) {
      const option = document.createElement('option');
      option.setAttribute('value', i);
      option.textContent = this.fontSizeScale[i] * this.baseSize;
      this.tickmarks.appendChild(option);
    }
    this.element.value = 2;
    this.update(this.element.value);
  }
  // TODO(meredithl): validate |scale| and snap to nearest supported font size.
  useFontScaling(scale) {
    this.element.value = this.fontSizeScale.indexOf(scale);
    document.documentElement.style.fontSize = scale * this.baseSize + 'px';
    this.update(this.element.value);
  }

  update(position) {
    this.element.style.setProperty(
        '--fontSizePercent',
        (position / (this.fontSizeScale.length - 1) * 100) + '%');
    this.element.setAttribute(
        'aria-valuetext', this.fontSizeScale[position] + 'px');
    for (let option = this.tickmarks.firstChild; option != null;
         option = option.nextSibling) {
      const isBeforeThumb = option.value < position;
      option.classList.toggle('before-thumb', isBeforeThumb);
      option.classList.toggle('after-thumb', !isBeforeThumb);
    }
  }
}

maybeSetWebFont();

// The zooming speed relative to pinching speed.
const FONT_SCALE_MULTIPLIER = 0.5;

const MIN_SPAN_LENGTH = 20;

class Pincher {
  // When users pinch in Reader Mode, the page would zoom in or out as if it
  // is a normal web page allowing user-zoom. At the end of pinch gesture, the
  // page would do text reflow. These pinch-to-zoom and text reflow effects
  // are not native, but are emulated using CSS and JavaScript.
  //
  // In order to achieve near-native zooming and panning frame rate, fake 3D
  // transform is used so that the layer doesn't repaint for each frame.
  //
  // After the text reflow, the web content shown in the viewport should
  // roughly be the same paragraph before zooming.
  //
  // The control point of font size is the html element, so that both "em" and
  // "rem" are adjusted.
  //
  // TODO(wychen): Improve scroll position when elementFromPoint is body.

  constructor() {
    // This has to be in sync with 'font-size' in distilledpage.css.
    // This value is hard-coded because JS might be injected before CSS is
    // ready. See crbug.com/1004663.
    this.baseSize = 14;
    this.pinching = false;
    this.fontSizeAnchor = 1.0;

    this.focusElement = null;
    this.focusPos = 0;
    this.initClientMid = null;

    this.clampedScale = 1.0;

    this.lastSpan = null;
    this.lastClientMid = null;

    this.scale = 1.0;
    this.shiftX = 0;
    this.shiftY = 0;

    window.addEventListener('touchstart', (e) => {
      this.handleTouchStart(e);
    }, {passive: false});
    window.addEventListener('touchmove', (e) => {
      this.handleTouchMove(e);
    }, {passive: false});
    window.addEventListener('touchend', (e) => {
      this.handleTouchEnd(e);
    }, {passive: false});
    window.addEventListener('touchcancel', (e) => {
      this.handleTouchCancel(e);
    }, {passive: false});
  }

  /** @private */
  refreshTransform_() {
    const slowedScale = Math.exp(Math.log(this.scale) * FONT_SCALE_MULTIPLIER);
    this.clampedScale =
        Math.max(0.5, Math.min(2.0, this.fontSizeAnchor * slowedScale));

    // Use "fake" 3D transform so that the layer is not repainted.
    // With 2D transform, the frame rate would be much lower.
    // clang-format off
    document.body.style.transform =
        'translate3d(' + this.shiftX + 'px,'
                       + this.shiftY + 'px, 0px)' +
        'scale(' + this.clampedScale / this.fontSizeAnchor + ')';
    // clang-format on
  }

  /** @private */
  saveCenter_(clientMid) {
    // Try to preserve the pinching center after text reflow.
    // This is accurate to the HTML element level.
    this.focusElement = document.elementFromPoint(clientMid.x, clientMid.y);
    const rect = this.focusElement.getBoundingClientRect();
    this.initClientMid = clientMid;
    this.focusPos =
        (this.initClientMid.y - rect.top) / (rect.bottom - rect.top);
  }

  /** @private */
  restoreCenter_() {
    const rect = this.focusElement.getBoundingClientRect();
    const targetTop = this.focusPos * (rect.bottom - rect.top) + rect.top +
        document.scrollingElement.scrollTop -
        (this.initClientMid.y + this.shiftY);
    document.scrollingElement.scrollTop = targetTop;
  }

  /** @private */
  endPinch_() {
    this.pinching = false;

    document.body.style.transformOrigin = '';
    document.body.style.transform = '';
    document.documentElement.style.fontSize =
        this.clampedScale * this.baseSize + 'px';

    this.restoreCenter_();

    let img = $('fontscaling-img');
    if (!img) {
      img = document.createElement('img');
      img.id = 'fontscaling-img';
      img.style.display = 'none';
      document.body.appendChild(img);
    }
    img.src = '/savefontscaling/' + this.clampedScale;
  }

  /** @private */
  touchSpan_(e) {
    const count = e.touches.length;
    const mid = this.touchClientMid_(e);
    let sum = 0;
    for (let i = 0; i < count; i++) {
      const dx = (e.touches[i].clientX - mid.x);
      const dy = (e.touches[i].clientY - mid.y);
      sum += Math.hypot(dx, dy);
    }
    // Avoid very small span.
    return Math.max(MIN_SPAN_LENGTH, sum / count);
  }

  /** @private */
  touchClientMid_(e) {
    const count = e.touches.length;
    let sumX = 0;
    let sumY = 0;
    for (let i = 0; i < count; i++) {
      sumX += e.touches[i].clientX;
      sumY += e.touches[i].clientY;
    }
    return {x: sumX / count, y: sumY / count};
  }

  /** @private */
  touchPageMid_(e) {
    const clientMid = this.touchClientMid_(e);
    return {
      x: clientMid.x - e.touches[0].clientX + e.touches[0].pageX,
      y: clientMid.y - e.touches[0].clientY + e.touches[0].pageY,
    };
  }

  handleTouchStart(e) {
    if (e.touches.length < 2) {
      return;
    }
    e.preventDefault();

    const span = this.touchSpan_(e);
    const clientMid = this.touchClientMid_(e);

    if (e.touches.length > 2) {
      this.lastSpan = span;
      this.lastClientMid = clientMid;
      this.refreshTransform_();
      return;
    }

    this.scale = 1;
    this.shiftX = 0;
    this.shiftY = 0;

    this.pinching = true;
    this.fontSizeAnchor =
        parseFloat(getComputedStyle(document.documentElement).fontSize) /
        this.baseSize;

    const pinchOrigin = this.touchPageMid_(e);
    document.body.style.transformOrigin =
        pinchOrigin.x + 'px ' + pinchOrigin.y + 'px';

    this.saveCenter_(clientMid);

    this.lastSpan = span;
    this.lastClientMid = clientMid;

    this.refreshTransform_();
  }

  handleTouchMove(e) {
    if (!this.pinching) {
      return;
    }
    if (e.touches.length < 2) {
      return;
    }
    e.preventDefault();

    const span = this.touchSpan_(e);
    const clientMid = this.touchClientMid_(e);

    this.scale *= this.touchSpan_(e) / this.lastSpan;
    this.shiftX += clientMid.x - this.lastClientMid.x;
    this.shiftY += clientMid.y - this.lastClientMid.y;

    this.refreshTransform_();

    this.lastSpan = span;
    this.lastClientMid = clientMid;
  }

  handleTouchEnd(e) {
    if (!this.pinching) {
      return;
    }
    e.preventDefault();

    const span = this.touchSpan_(e);
    const clientMid = this.touchClientMid_(e);

    if (e.touches.length >= 2) {
      this.lastSpan = span;
      this.lastClientMid = clientMid;
      this.refreshTransform_();
      return;
    }

    this.endPinch_();
  }

  handleTouchCancel(e) {
    if (!this.pinching) {
      return;
    }
    this.endPinch_();
  }

  reset() {
    this.scale = 1;
    this.shiftX = 0;
    this.shiftY = 0;
    this.clampedScale = 1;
    document.documentElement.style.fontSize =
        this.clampedScale * this.baseSize + 'px';
  }

  status() {
    return {
      scale: this.scale,
      clampedScale: this.clampedScale,
      shiftX: this.shiftX,
      shiftY: this.shiftY,
    };
  }

  useFontScaling(scaling) {
    this.saveCenter_({x: window.innerWidth / 2, y: window.innerHeight / 2});
    this.shiftX = 0;
    this.shiftY = 0;
    document.documentElement.style.fontSize = scaling * this.baseSize + 'px';
    this.clampedScale = scaling;
    this.restoreCenter_();
  }
}

// The pincher is only defined on Android, and the font size slider only on
// desktop.
// eslint-disable-next-line no-var
var pincher, fontSizeSlider;
if (navigator.userAgent.toLowerCase().indexOf('android') > -1) {
  pincher = new Pincher();
} else {
  fontSizeSlider = new FontSizeSlider();
}

function useFontScaling(scale) {
  if (navigator.userAgent.toLowerCase().indexOf('android') > -1) {
    pincher.useFontScaling(scale);
  } else {
    fontSizeSlider.useFontScaling(scale);
  }
}

class SettingsDialog {
  constructor(
      toggleElement, dialogElement, backdropElement, themeFieldset,
      fontFamilySelect) {
    this._toggleElement = toggleElement;
    this._dialogElement = dialogElement;
    this._backdropElement = backdropElement;
    this._themeFieldset = themeFieldset;
    this._fontFamilySelect = fontFamilySelect;

    this._toggleElement.addEventListener('click', this.toggle.bind(this));
    this._dialogElement.addEventListener('close', this.close.bind(this));
    this._backdropElement.addEventListener('click', this.close.bind(this));

    $('close-settings-button').addEventListener('click', this.close.bind(this));

    this._themeFieldset.addEventListener('change', (e) => {
      const newTheme = e.target.value;
      this.useTheme(newTheme);
      distiller.storeThemePref(themeClasses.indexOf(newTheme));
    });

    this._fontFamilySelect.addEventListener('change', (e) => {
      const newFontFamily = e.target.value;
      this.useFontFamily(newFontFamily);
      distiller.storeFontFamilyPref(fontFamilyClasses.indexOf(newFontFamily));
    });

    // Appearance settings are loaded from user preferences, so on page load
    // the controllers for these settings may need to be updated to reflect
    // the active setting.
    this._updateFontFamilyControls(getAppearanceSetting(fontFamilyClasses));
    const selectedTheme = getAppearanceSetting(themeClasses);
    this._updateThemeControls(selectedTheme);
    updateToolbarColor(selectedTheme);
  }

  toggle() {
    if (this._dialogElement.open) {
      this.close();
    } else {
      this.showModal();
    }
  }

  showModal() {
    this._toggleElement.classList.add('activated');
    this._backdropElement.style.display = 'block';
    this._dialogElement.showModal();
  }

  close() {
    this._toggleElement.classList.remove('activated');
    this._backdropElement.style.display = 'none';
    this._dialogElement.close();
  }

  useTheme(theme) {
    themeClasses.forEach(
        (element) =>
            document.body.classList.toggle(element, element === theme));
    this._updateThemeControls(theme);
    updateToolbarColor(theme);
  }

  _updateThemeControls(theme) {
    const queryString = `input[value=${theme}]`;
    this._themeFieldset.querySelector(queryString).checked = true;
  }

  useFontFamily(fontFamily) {
    fontFamilyClasses.forEach(
        (element) =>
            document.body.classList.toggle(element, element === fontFamily));
    this._updateFontFamilyControls(fontFamily);
  }

  _updateFontFamilyControls(fontFamily) {
    this._fontFamilySelect.selectedIndex =
        fontFamilyClasses.indexOf(fontFamily);
  }
}

const settingsDialog = new SettingsDialog(
    $('settings-toggle'), $('settings-dialog'), $('dialog-backdrop'),
    $('theme-selection'), $('font-family-selection'));
useFontScaling(1);setTitle("LinkedIn Login, Sign in | LinkedIn", "");setTextDirection("auto");addToPage("\u003Cp>\n              Agree &amp; Join LinkedIn\n            \u003C/p>\u003Cp dir=\"ltr\">\n              By clicking Continue, you agree to LinkedIn’s \u003Ca href=\"https://www.linkedin.com/legal/user-agreement\" dir=\"ltr\">User Agreement\u003C/a>, \u003Ca href=\"https://www.linkedin.com/legal/privacy-policy\" dir=\"ltr\">Privacy Policy\u003C/a>, and \u003Ca href=\"https://www.linkedin.com/legal/cookie-policy\" dir=\"ltr\">Cookie Policy\u003C/a>.\n            \u003C/p>");showLoadingIndicator(true);useFontScaling(1);showLoadingIndicator(true);</script>