UNPKG

okova

Version:

Advanced DRM inspection toolkit

9,327 lines 334 kB
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// src/lib/main.ts
var main_exports = {};
__export(main_exports, {
  BinaryReader: () => BinaryReader,
  CLIENT_TYPE: () => CLIENT_TYPE,
  MessageEvent: () => MessageEvent,
  PlayReadyCdm: () => PlayReadyCdm,
  PlayReadyClient: () => PlayReadyClient,
  RemoteCdm: () => RemoteCdm,
  Session: () => Session,
  WidevineCdm: () => WidevineCdm,
  WidevineClient: () => WidevineClient,
  base64ToBytes: () => base64ToBytes,
  bytesToBase64: () => bytesToBase64,
  bytesToString: () => bytesToString,
  compareArrays: () => compareArrays,
  fetchDecryptionKeys: () => fetchDecryptionKeys,
  fromBase64: () => fromBase64,
  fromBinary: () => fromBinary,
  fromBuffer: () => fromBuffer,
  fromHex: () => fromHex,
  fromText: () => fromText,
  getRandomBytes: () => getRandomBytes,
  parseBufferSource: () => parseBufferSource,
  requestMediaKeySystemAccess: () => requestMediaKeySystemAccess,
  stringToBytes: () => stringToBytes,
  xorArrays: () => xorArrays
});
module.exports = __toCommonJS(main_exports);

// src/lib/utils.ts
var encode = (input) => new TextEncoder().encode(input);
var decode = (input) => new TextDecoder().decode(input);
var fromText = (data) => ({
  toBase64: () => {
    return btoa(
      encode(data).reduce((s, byte) => s + String.fromCharCode(byte), "")
    );
  },
  toHex: () => {
    return Array.from(encode(data)).map((byte) => byte.toString(16).padStart(2, "0")).join("");
  },
  toBuffer: () => encode(data)
});
var fromBinary = (data) => ({
  toBuffer: () => {
    const len = data.length;
    const buffer = new Uint8Array(len);
    for (let i = 0; i < len; i++) buffer[i] = data.charCodeAt(i);
    return buffer;
  }
});
var parseBase64 = (data) => Uint8Array.from(atob(data), (c) => c.charCodeAt(0));
var fromBase64 = (data) => ({
  toBuffer: () => parseBase64(data),
  toText: () => decode(parseBase64(data)),
  toHex: () => fromBuffer(fromBase64(data).toBuffer()).toHex()
});
var fromBuffer = (data) => ({
  toBase64: () => {
    const binString = Array.from(
      data,
      (byte) => String.fromCodePoint(byte)
    ).join("");
    return btoa(binString);
  },
  toHex: () => {
    return Array.from(data).map((byte) => byte.toString(16).padStart(2, "0")).join("");
  },
  toText: () => decode(data),
  toBinary: () => {
    let binary = "";
    const len = data.length;
    for (let i = 0; i < len; i++) binary += String.fromCharCode(data[i]);
    return binary;
  }
});
var parseHex = (hex) => hex.match(/.{1,2}/g).map((byte) => parseInt(byte, 16));
var fromHex = (data) => ({
  toBase64: () => {
    return btoa(String.fromCharCode(...parseHex(data)));
  },
  toBuffer: () => {
    return new Uint8Array(parseHex(data));
  },
  toText: () => {
    return decode(new Uint8Array(parseHex(data)));
  }
});
var parseBufferSource = (data) => {
  if (data instanceof Uint8Array) return data;
  return data instanceof ArrayBuffer ? new Uint8Array(data) : new Uint8Array(data.buffer);
};
var BinaryReader = class {
  offset;
  length;
  rawBytes;
  dataView;
  constructor(data) {
    this.offset = 0;
    this.length = data.length;
    this.rawBytes = new Uint8Array(data);
    this.dataView = new DataView(data.buffer, data.byteOffset, data.byteLength);
  }
  readUint8() {
    return this.dataView.getUint8(this.offset++);
  }
  readUint16(little) {
    const result = this.dataView.getUint16(this.offset, little);
    this.offset += 2;
    return result;
  }
  readUint32(little) {
    const result = this.dataView.getUint32(this.offset, little);
    this.offset += 4;
    return result;
  }
  readBytes(size) {
    const result = this.rawBytes.subarray(this.offset, this.offset + size);
    this.offset += size;
    return result;
  }
  reset() {
    this.dataView = new DataView(this.rawBytes.buffer);
    this.offset = 0;
  }
};
var compareArrays = (arr1, arr2) => {
  if (arr1.length !== arr2.length) return false;
  return Array.from(arr1).every((value, index) => value === arr2[index]);
};
var bytesToString = (bytes) => {
  return String.fromCharCode.apply(null, Array.from(bytes));
};
var bytesToBase64 = (uint8array) => {
  return btoa(String.fromCharCode.apply(null, Array.from(uint8array)));
};
var stringToBytes = (string) => {
  return Uint8Array.from(string.split("").map((x) => x.charCodeAt(0)));
};
var base64ToBytes = (base64_string) => {
  return Uint8Array.from(atob(base64_string), (c) => c.charCodeAt(0));
};
var xorArrays = (arr1, arr2) => {
  return new Uint8Array(arr1.map((byte, i) => byte ^ arr2[i]));
};
var getRandomBytes = (size) => {
  const randomBytes = new Uint8Array(size);
  crypto.getRandomValues(randomBytes);
  return randomBytes;
};

// src/lib/api.ts
var MessageEvent = class extends Event {
  messageType;
  message;
  constructor(messageType, message) {
    super("message");
    this.messageType = messageType;
    this.message = message;
  }
};
var Session = class extends EventTarget {
  sessionId;
  keyStatuses;
  expiration;
  closed;
  onmessage;
  onkeyschange;
  onkeystatuseschange;
  sessionType;
  keySystem;
  keys;
  #closed;
  constructor(sessionType = "temporary", keySystem) {
    super();
    this.sessionId = "";
    this.keyStatuses = /* @__PURE__ */ new Map();
    this.expiration = NaN;
    this.closed = new Promise((resolve) => {
      this.addEventListener("closed", () => resolve("closed-by-application"));
    });
    this.onmessage = null;
    this.onkeyschange = null;
    this.onkeystatuseschange = null;
    this.sessionType = sessionType;
    this.keySystem = keySystem;
    this.keys = [];
    const sessionId = this.keySystem.createSession(this.sessionType);
    if (typeof sessionId === "string") this.sessionId = sessionId;
    this.#closed = false;
  }
  async #validate() {
    if (this.#closed) throw new Error("Session closed");
    if (!this.sessionId) {
      this.sessionId = await this.keySystem.createSession(this.sessionType);
    }
  }
  async load(sessionId) {
    this.sessionId = sessionId;
    this.#closed = false;
    return true;
  }
  async generateRequest(initDataType, initData) {
    await this.#validate();
    const request = await this.keySystem.generateRequest(
      this.sessionId,
      parseBufferSource(initData),
      initDataType
    );
    this.dispatchEvent(
      new MessageEvent("license-request", request)
    );
  }
  async update(response) {
    await this.#validate();
    await this.keySystem.updateSession(
      this.sessionId,
      parseBufferSource(response)
    );
    const keys = await this.keySystem.getKeys?.(this.sessionId);
    if (keys) {
      this.keys = keys;
      for (const key of keys) {
        const id = fromHex(key.keyId).toBuffer();
        this.keyStatuses.set(id, "usable");
      }
      this.dispatchEvent(new Event("keystatuseschange"));
    }
  }
  async close() {
    this.#closed = true;
    this.dispatchEvent(new Event("closed"));
  }
  async remove() {
    this.dispatchEvent(new Event("removed"));
  }
  async waitForLicenseRequest() {
    return new Promise((resolve) => {
      this.addEventListener(
        "message",
        (e) => {
          const event = e;
          if (event.messageType === "license-request") {
            resolve(new Uint8Array(event.message));
          }
        },
        false
      );
    });
  }
  async waitForKeyStatusesChange() {
    if (this.keys.length) return this.keys;
    return new Promise((resolve) => {
      this.addEventListener(
        "keystatuseschange",
        () => resolve(this.keys),
        false
      );
    });
  }
};
var requestMediaKeySystemAccess = (keySystem, supportedConfigurations) => {
  const supportedKeySystems = /* @__PURE__ */ new Set([
    "com.widevine.alpha",
    "com.microsoft.playready.recommendation",
    "remote"
  ]);
  if (!supportedKeySystems.has(keySystem))
    throw new Error("Unsupported media key system");
  return {
    keySystem,
    createMediaKeys: async ({ cdm }) => {
      const state = { serverCertificate: null };
      return {
        createSession: (sessionType) => {
          const session = new Session(sessionType, cdm);
          return session;
        },
        setServerCertificate: async (serverCertificate) => {
          state.serverCertificate = serverCertificate;
          return true;
        },
        getStatusForPolicy: async () => "usable"
      };
    },
    getConfiguration: () => supportedConfigurations[0]
  };
};

// src/lib/crypto/common.ts
var import_jsrsasign = require("jsrsasign");
var import_nist3 = require("@noble/curves/nist");
var utils2 = __toESM(require("@noble/curves/utils"), 1);

// src/lib/crypto/elgamal.ts
var import_nist2 = require("@noble/curves/nist");

// src/lib/crypto/ecc-key.ts
var import_nist = require("@noble/curves/nist");
var utils = __toESM(require("@noble/curves/utils"), 1);
var EccKey = class _EccKey {
  privateKey;
  publicKey;
  constructor(privateKey, publicKey) {
    this.privateKey = privateKey;
    this.publicKey = publicKey;
  }
  static randomScalar() {
    const randomBytes = getRandomBytes(32);
    return utils.bytesToNumberBE(randomBytes) % import_nist.p256.CURVE.n;
  }
  static generate() {
    const privateKey = _EccKey.randomScalar();
    const publicKey = import_nist.p256.Point.BASE.multiply(privateKey).toAffine();
    return new _EccKey(privateKey, publicKey);
  }
  static construct(privateKey) {
    const publicKey = import_nist.p256.Point.BASE.multiply(privateKey).toAffine();
    return new _EccKey(privateKey, publicKey);
  }
  static from(data) {
    const privateBytes = data.subarray(0, 32);
    return _EccKey.construct(utils.bytesToNumberBE(privateBytes));
  }
  dumps(privateOnly = false) {
    return privateOnly ? new Uint8Array([...this.privateBytes()]) : new Uint8Array([...this.privateBytes(), ...this.publicBytes()]);
  }
  privateBytes() {
    return utils.numberToBytesBE(this.privateKey, 32);
  }
  publicBytes() {
    return new Uint8Array([
      ...utils.numberToBytesBE(this.publicKey.x, 32),
      ...utils.numberToBytesBE(this.publicKey.y, 32)
    ]);
  }
  privateSha256Digest() {
    return createSha256(this.publicBytes());
  }
  publicSha256Digest() {
    return createSha256(this.publicBytes());
  }
};

// src/lib/crypto/elgamal.ts
var ElGamal = class {
  static encrypt(affineMessagePoint, affinePublicKey) {
    const messagePoint = new import_nist2.p256.Point(
      affineMessagePoint.x,
      affineMessagePoint.y,
      1n
    );
    const publicKey = new import_nist2.p256.Point(affinePublicKey.x, affinePublicKey.y, 1n);
    const ephemeralKey = EccKey.randomScalar();
    const point1 = import_nist2.p256.Point.BASE.multiply(ephemeralKey);
    const sharedSecret = publicKey.multiply(ephemeralKey);
    const point2 = messagePoint.add(sharedSecret);
    return {
      point1: point1.toAffine(),
      point2: point2.toAffine()
    };
  }
  static decrypt({
    point1,
    point2
  }, privateKey) {
    const projectivePoint1 = new import_nist2.p256.Point(point1.x, point1.y, 1n);
    const projectivePoint2 = new import_nist2.p256.Point(point2.x, point2.y, 1n);
    const sharedSecret = projectivePoint1.multiply(privateKey);
    return projectivePoint2.subtract(sharedSecret).toAffine();
  }
};

// src/lib/crypto/common.ts
var toPKCS8 = (pkcs1pem) => {
  const keyobj = import_jsrsasign.KEYUTIL.getKey(pkcs1pem);
  const pkcs8pem = import_jsrsasign.KEYUTIL.getPEM(keyobj, "PKCS8PRV");
  return pkcs8pem;
};
var toPKCS1 = (pkcs8pem) => {
  const keyobj = import_jsrsasign.KEYUTIL.getKey(pkcs8pem);
  const pkcs1pem = import_jsrsasign.KEYUTIL.getPEM(keyobj, "PKCS1PRV");
  return pkcs1pem;
};
var parseSpkiFromCertificateKey = (publicKey) => {
  const publicKeyDerHex = fromBuffer(publicKey).toHex();
  const keyResult = import_jsrsasign.KEYUTIL.parsePublicRawRSAKeyHex(publicKeyDerHex);
  const key = import_jsrsasign.KEYUTIL.getKey(keyResult);
  const pem = import_jsrsasign.KEYUTIL.getPEM(key);
  const header = "-----BEGIN PUBLIC KEY-----";
  const footer = "-----END PUBLIC KEY-----";
  const body = pem.substring(header.length, pem.length - footer.length - 2);
  return fromBase64(body).toBuffer();
};
var importSpkiKeyForEncrypt = async (keyData) => {
  return crypto.subtle.importKey(
    "spki",
    keyData,
    {
      name: "RSA-OAEP",
      hash: "SHA-1"
    },
    true,
    ["encrypt"]
  );
};
var importSpkiKeyForVerify = async (keyData) => {
  return crypto.subtle.importKey(
    "spki",
    keyData,
    {
      name: "RSA-PSS",
      hash: "SHA-1"
    },
    true,
    ["verify"]
  );
};
var getRandomHex = (size = 16) => {
  const result = [];
  const hexRef = [
    "0",
    "1",
    "2",
    "3",
    "4",
    "5",
    "6",
    "7",
    "8",
    "9",
    "a",
    "b",
    "c",
    "d",
    "e",
    "f"
  ];
  for (let n = 0; n < size; n++)
    result.push(hexRef[Math.floor(Math.random() * 16)]);
  return result.join("").toUpperCase();
};
var getRandomBytes2 = (size = 16) => {
  return new Uint8Array(crypto.getRandomValues(new Uint8Array(size)));
};
var generateAesCbcKey = async (length = 128) => crypto.subtle.generateKey({ name: "AES-CBC", length }, true, ["encrypt"]);
var importAesCbcKeyForEncrypt = async (keyData) => {
  return crypto.subtle.importKey("raw", keyData, "AES-CBC", false, ["encrypt"]);
};
var importAesCbcKeyForDecrypt = async (keyData) => crypto.subtle.importKey("raw", keyData, { name: "AES-CBC" }, false, [
  "decrypt"
]);
var encryptWithAesCbc = async (data, key, iv) => {
  const result = await crypto.subtle.encrypt(
    { name: "AES-CBC", iv },
    key,
    data
  );
  return new Uint8Array(result);
};
var decryptWithAesCbc = async (data, key, iv) => {
  const result = await crypto.subtle.decrypt(
    { name: "AES-CBC", iv },
    key,
    data
  );
  return new Uint8Array(result);
};
var encryptWithRsaOaep = async (data, key) => {
  const result = await crypto.subtle.encrypt({ name: "RSA-OAEP" }, key, data);
  return new Uint8Array(result);
};
var exportKey = (key) => crypto.subtle.exportKey("raw", key).then((value) => new Uint8Array(value));
var createHmacSha256 = async (key, data) => {
  const hmacKey = await crypto.subtle.importKey(
    "raw",
    key,
    {
      name: "HMAC",
      hash: "SHA-256"
    },
    true,
    ["sign", "verify"]
  );
  const signature = await crypto.subtle.sign("HMAC", hmacKey, data);
  return new Uint8Array(signature);
};
var createSha256 = async (data) => {
  const hashBuffer = await crypto.subtle.digest("SHA-256", data);
  const hashArray = new Uint8Array(hashBuffer);
  return hashArray;
};
var ecc256Verify = async (publicKey, data, signature) => {
  return import_nist3.p256.verify(signature, await createSha256(data), publicKey);
};
var ecc256Sign = async (private_key, data) => {
  return import_nist3.p256.sign(await createSha256(data), private_key);
};
var ecc256decrypt = (private_key, ciphertext) => {
  const decrypted = ElGamal.decrypt(
    {
      point1: {
        x: utils2.bytesToNumberBE(ciphertext.subarray(0, 32)),
        y: utils2.bytesToNumberBE(ciphertext.subarray(32, 64))
      },
      point2: {
        x: utils2.bytesToNumberBE(ciphertext.subarray(64, 96)),
        y: utils2.bytesToNumberBE(ciphertext.subarray(96, 128))
      }
    },
    private_key
  );
  return utils2.numberToBytesBE(decrypted.x, 32);
};
var aesEcbEncrypt = async (key, data) => {
  const cryptoKey = await crypto.subtle.importKey("raw", key, "AES-ECB", true, [
    "encrypt",
    "decrypt"
  ]);
  const encryptedBuffer = await crypto.subtle.encrypt(
    { name: "AES-ECB" },
    cryptoKey,
    data
  );
  return new Uint8Array(encryptedBuffer);
};

// src/lib/widevine/proto/license_protocol.pb.js
var protobufjs = __toESM(require("protobufjs/minimal.js"), 1);
var $protobuf = protobufjs.default || protobufjs;
var $Reader = $protobuf.Reader;
var $Writer = $protobuf.Writer;
var $util = $protobuf.util;
var $root = $protobuf.roots["default"] || ($protobuf.roots["default"] = {});
var LicenseType = $root.LicenseType = (() => {
  const valuesById = {}, values = Object.create(valuesById);
  values[valuesById[1] = "STREAMING"] = 1;
  values[valuesById[2] = "OFFLINE"] = 2;
  values[valuesById[3] = "AUTOMATIC"] = 3;
  return values;
})();
var PlatformVerificationStatus = $root.PlatformVerificationStatus = (() => {
  const valuesById = {}, values = Object.create(valuesById);
  values[valuesById[0] = "PLATFORM_UNVERIFIED"] = 0;
  values[valuesById[1] = "PLATFORM_TAMPERED"] = 1;
  values[valuesById[2] = "PLATFORM_SOFTWARE_VERIFIED"] = 2;
  values[valuesById[3] = "PLATFORM_HARDWARE_VERIFIED"] = 3;
  values[valuesById[4] = "PLATFORM_NO_VERIFICATION"] = 4;
  values[valuesById[5] = "PLATFORM_SECURE_STORAGE_SOFTWARE_VERIFIED"] = 5;
  return values;
})();
var LicenseIdentification = $root.LicenseIdentification = (() => {
  function LicenseIdentification2(p) {
    if (p) {
      for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
        if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
    }
  }
  LicenseIdentification2.prototype.requestId = $util.newBuffer([]);
  LicenseIdentification2.prototype.sessionId = $util.newBuffer([]);
  LicenseIdentification2.prototype.purchaseId = $util.newBuffer([]);
  LicenseIdentification2.prototype.type = 1;
  LicenseIdentification2.prototype.version = 0;
  LicenseIdentification2.prototype.providerSessionToken = $util.newBuffer([]);
  LicenseIdentification2.create = function create(properties) {
    return new LicenseIdentification2(properties);
  };
  LicenseIdentification2.encode = function encode2(m, w) {
    if (!w) w = $Writer.create();
    if (m.requestId != null && Object.hasOwnProperty.call(m, "requestId"))
      w.uint32(10).bytes(m.requestId);
    if (m.sessionId != null && Object.hasOwnProperty.call(m, "sessionId"))
      w.uint32(18).bytes(m.sessionId);
    if (m.purchaseId != null && Object.hasOwnProperty.call(m, "purchaseId"))
      w.uint32(26).bytes(m.purchaseId);
    if (m.type != null && Object.hasOwnProperty.call(m, "type"))
      w.uint32(32).int32(m.type);
    if (m.version != null && Object.hasOwnProperty.call(m, "version"))
      w.uint32(40).int32(m.version);
    if (m.providerSessionToken != null && Object.hasOwnProperty.call(m, "providerSessionToken"))
      w.uint32(50).bytes(m.providerSessionToken);
    return w;
  };
  LicenseIdentification2.encodeDelimited = function encodeDelimited(message, writer) {
    return this.encode(message, writer).ldelim();
  };
  LicenseIdentification2.decode = function decode2(r, l) {
    if (!(r instanceof $Reader)) r = $Reader.create(r);
    var c = l === void 0 ? r.len : r.pos + l, m = new $root.LicenseIdentification();
    while (r.pos < c) {
      var t = r.uint32();
      switch (t >>> 3) {
        case 1: {
          m.requestId = r.bytes();
          break;
        }
        case 2: {
          m.sessionId = r.bytes();
          break;
        }
        case 3: {
          m.purchaseId = r.bytes();
          break;
        }
        case 4: {
          m.type = r.int32();
          break;
        }
        case 5: {
          m.version = r.int32();
          break;
        }
        case 6: {
          m.providerSessionToken = r.bytes();
          break;
        }
        default:
          r.skipType(t & 7);
          break;
      }
    }
    return m;
  };
  LicenseIdentification2.decodeDelimited = function decodeDelimited(reader) {
    if (!(reader instanceof $Reader)) reader = new $Reader(reader);
    return this.decode(reader, reader.uint32());
  };
  LicenseIdentification2.fromObject = function fromObject(d) {
    if (d instanceof $root.LicenseIdentification) return d;
    var m = new $root.LicenseIdentification();
    if (d.requestId != null) {
      if (typeof d.requestId === "string")
        $util.base64.decode(
          d.requestId,
          m.requestId = $util.newBuffer($util.base64.length(d.requestId)),
          0
        );
      else if (d.requestId.length >= 0) m.requestId = d.requestId;
    }
    if (d.sessionId != null) {
      if (typeof d.sessionId === "string")
        $util.base64.decode(
          d.sessionId,
          m.sessionId = $util.newBuffer($util.base64.length(d.sessionId)),
          0
        );
      else if (d.sessionId.length >= 0) m.sessionId = d.sessionId;
    }
    if (d.purchaseId != null) {
      if (typeof d.purchaseId === "string")
        $util.base64.decode(
          d.purchaseId,
          m.purchaseId = $util.newBuffer($util.base64.length(d.purchaseId)),
          0
        );
      else if (d.purchaseId.length >= 0) m.purchaseId = d.purchaseId;
    }
    switch (d.type) {
      default:
        if (typeof d.type === "number") {
          m.type = d.type;
          break;
        }
        break;
      case "STREAMING":
      case 1:
        m.type = 1;
        break;
      case "OFFLINE":
      case 2:
        m.type = 2;
        break;
      case "AUTOMATIC":
      case 3:
        m.type = 3;
        break;
    }
    if (d.version != null) {
      m.version = d.version | 0;
    }
    if (d.providerSessionToken != null) {
      if (typeof d.providerSessionToken === "string")
        $util.base64.decode(
          d.providerSessionToken,
          m.providerSessionToken = $util.newBuffer(
            $util.base64.length(d.providerSessionToken)
          ),
          0
        );
      else if (d.providerSessionToken.length >= 0)
        m.providerSessionToken = d.providerSessionToken;
    }
    return m;
  };
  LicenseIdentification2.toObject = function toObject(m, o) {
    if (!o) o = {};
    var d = {};
    if (o.defaults) {
      if (o.bytes === String) d.requestId = "";
      else {
        d.requestId = [];
        if (o.bytes !== Array) d.requestId = $util.newBuffer(d.requestId);
      }
      if (o.bytes === String) d.sessionId = "";
      else {
        d.sessionId = [];
        if (o.bytes !== Array) d.sessionId = $util.newBuffer(d.sessionId);
      }
      if (o.bytes === String) d.purchaseId = "";
      else {
        d.purchaseId = [];
        if (o.bytes !== Array) d.purchaseId = $util.newBuffer(d.purchaseId);
      }
      d.type = o.enums === String ? "STREAMING" : 1;
      d.version = 0;
      if (o.bytes === String) d.providerSessionToken = "";
      else {
        d.providerSessionToken = [];
        if (o.bytes !== Array)
          d.providerSessionToken = $util.newBuffer(d.providerSessionToken);
      }
    }
    if (m.requestId != null && m.hasOwnProperty("requestId")) {
      d.requestId = o.bytes === String ? $util.base64.encode(m.requestId, 0, m.requestId.length) : o.bytes === Array ? Array.prototype.slice.call(m.requestId) : m.requestId;
    }
    if (m.sessionId != null && m.hasOwnProperty("sessionId")) {
      d.sessionId = o.bytes === String ? $util.base64.encode(m.sessionId, 0, m.sessionId.length) : o.bytes === Array ? Array.prototype.slice.call(m.sessionId) : m.sessionId;
    }
    if (m.purchaseId != null && m.hasOwnProperty("purchaseId")) {
      d.purchaseId = o.bytes === String ? $util.base64.encode(m.purchaseId, 0, m.purchaseId.length) : o.bytes === Array ? Array.prototype.slice.call(m.purchaseId) : m.purchaseId;
    }
    if (m.type != null && m.hasOwnProperty("type")) {
      d.type = o.enums === String ? $root.LicenseType[m.type] === void 0 ? m.type : $root.LicenseType[m.type] : m.type;
    }
    if (m.version != null && m.hasOwnProperty("version")) {
      d.version = m.version;
    }
    if (m.providerSessionToken != null && m.hasOwnProperty("providerSessionToken")) {
      d.providerSessionToken = o.bytes === String ? $util.base64.encode(
        m.providerSessionToken,
        0,
        m.providerSessionToken.length
      ) : o.bytes === Array ? Array.prototype.slice.call(m.providerSessionToken) : m.providerSessionToken;
    }
    return d;
  };
  LicenseIdentification2.prototype.toJSON = function toJSON() {
    return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
  };
  LicenseIdentification2.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
    if (typeUrlPrefix === void 0) {
      typeUrlPrefix = "type.googleapis.com";
    }
    return typeUrlPrefix + "/LicenseIdentification";
  };
  return LicenseIdentification2;
})();
var License = $root.License = (() => {
  function License2(p) {
    this.key = [];
    this.groupIds = [];
    if (p) {
      for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
        if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
    }
  }
  License2.prototype.id = null;
  License2.prototype.policy = null;
  License2.prototype.key = $util.emptyArray;
  License2.prototype.licenseStartTime = $util.Long ? $util.Long.fromBits(0, 0, false) : 0;
  License2.prototype.remoteAttestationVerified = false;
  License2.prototype.providerClientToken = $util.newBuffer([]);
  License2.prototype.protectionScheme = 0;
  License2.prototype.srmRequirement = $util.newBuffer([]);
  License2.prototype.srmUpdate = $util.newBuffer([]);
  License2.prototype.platformVerificationStatus = 4;
  License2.prototype.groupIds = $util.emptyArray;
  License2.create = function create(properties) {
    return new License2(properties);
  };
  License2.encode = function encode2(m, w) {
    if (!w) w = $Writer.create();
    if (m.id != null && Object.hasOwnProperty.call(m, "id"))
      $root.LicenseIdentification.encode(m.id, w.uint32(10).fork()).ldelim();
    if (m.policy != null && Object.hasOwnProperty.call(m, "policy"))
      $root.License.Policy.encode(m.policy, w.uint32(18).fork()).ldelim();
    if (m.key != null && m.key.length) {
      for (var i = 0; i < m.key.length; ++i)
        $root.License.KeyContainer.encode(
          m.key[i],
          w.uint32(26).fork()
        ).ldelim();
    }
    if (m.licenseStartTime != null && Object.hasOwnProperty.call(m, "licenseStartTime"))
      w.uint32(32).int64(m.licenseStartTime);
    if (m.remoteAttestationVerified != null && Object.hasOwnProperty.call(m, "remoteAttestationVerified"))
      w.uint32(40).bool(m.remoteAttestationVerified);
    if (m.providerClientToken != null && Object.hasOwnProperty.call(m, "providerClientToken"))
      w.uint32(50).bytes(m.providerClientToken);
    if (m.protectionScheme != null && Object.hasOwnProperty.call(m, "protectionScheme"))
      w.uint32(56).uint32(m.protectionScheme);
    if (m.srmRequirement != null && Object.hasOwnProperty.call(m, "srmRequirement"))
      w.uint32(66).bytes(m.srmRequirement);
    if (m.srmUpdate != null && Object.hasOwnProperty.call(m, "srmUpdate"))
      w.uint32(74).bytes(m.srmUpdate);
    if (m.platformVerificationStatus != null && Object.hasOwnProperty.call(m, "platformVerificationStatus"))
      w.uint32(80).int32(m.platformVerificationStatus);
    if (m.groupIds != null && m.groupIds.length) {
      for (var i = 0; i < m.groupIds.length; ++i)
        w.uint32(90).bytes(m.groupIds[i]);
    }
    return w;
  };
  License2.encodeDelimited = function encodeDelimited(message, writer) {
    return this.encode(message, writer).ldelim();
  };
  License2.decode = function decode2(r, l) {
    if (!(r instanceof $Reader)) r = $Reader.create(r);
    var c = l === void 0 ? r.len : r.pos + l, m = new $root.License();
    while (r.pos < c) {
      var t = r.uint32();
      switch (t >>> 3) {
        case 1: {
          m.id = $root.LicenseIdentification.decode(r, r.uint32());
          break;
        }
        case 2: {
          m.policy = $root.License.Policy.decode(r, r.uint32());
          break;
        }
        case 3: {
          if (!(m.key && m.key.length)) m.key = [];
          m.key.push($root.License.KeyContainer.decode(r, r.uint32()));
          break;
        }
        case 4: {
          m.licenseStartTime = r.int64();
          break;
        }
        case 5: {
          m.remoteAttestationVerified = r.bool();
          break;
        }
        case 6: {
          m.providerClientToken = r.bytes();
          break;
        }
        case 7: {
          m.protectionScheme = r.uint32();
          break;
        }
        case 8: {
          m.srmRequirement = r.bytes();
          break;
        }
        case 9: {
          m.srmUpdate = r.bytes();
          break;
        }
        case 10: {
          m.platformVerificationStatus = r.int32();
          break;
        }
        case 11: {
          if (!(m.groupIds && m.groupIds.length)) m.groupIds = [];
          m.groupIds.push(r.bytes());
          break;
        }
        default:
          r.skipType(t & 7);
          break;
      }
    }
    return m;
  };
  License2.decodeDelimited = function decodeDelimited(reader) {
    if (!(reader instanceof $Reader)) reader = new $Reader(reader);
    return this.decode(reader, reader.uint32());
  };
  License2.fromObject = function fromObject(d) {
    if (d instanceof $root.License) return d;
    var m = new $root.License();
    if (d.id != null) {
      if (typeof d.id !== "object")
        throw TypeError(".License.id: object expected");
      m.id = $root.LicenseIdentification.fromObject(d.id);
    }
    if (d.policy != null) {
      if (typeof d.policy !== "object")
        throw TypeError(".License.policy: object expected");
      m.policy = $root.License.Policy.fromObject(d.policy);
    }
    if (d.key) {
      if (!Array.isArray(d.key))
        throw TypeError(".License.key: array expected");
      m.key = [];
      for (var i = 0; i < d.key.length; ++i) {
        if (typeof d.key[i] !== "object")
          throw TypeError(".License.key: object expected");
        m.key[i] = $root.License.KeyContainer.fromObject(d.key[i]);
      }
    }
    if (d.licenseStartTime != null) {
      if ($util.Long)
        (m.licenseStartTime = $util.Long.fromValue(
          d.licenseStartTime
        )).unsigned = false;
      else if (typeof d.licenseStartTime === "string")
        m.licenseStartTime = parseInt(d.licenseStartTime, 10);
      else if (typeof d.licenseStartTime === "number")
        m.licenseStartTime = d.licenseStartTime;
      else if (typeof d.licenseStartTime === "object")
        m.licenseStartTime = new $util.LongBits(
          d.licenseStartTime.low >>> 0,
          d.licenseStartTime.high >>> 0
        ).toNumber();
    }
    if (d.remoteAttestationVerified != null) {
      m.remoteAttestationVerified = Boolean(d.remoteAttestationVerified);
    }
    if (d.providerClientToken != null) {
      if (typeof d.providerClientToken === "string")
        $util.base64.decode(
          d.providerClientToken,
          m.providerClientToken = $util.newBuffer(
            $util.base64.length(d.providerClientToken)
          ),
          0
        );
      else if (d.providerClientToken.length >= 0)
        m.providerClientToken = d.providerClientToken;
    }
    if (d.protectionScheme != null) {
      m.protectionScheme = d.protectionScheme >>> 0;
    }
    if (d.srmRequirement != null) {
      if (typeof d.srmRequirement === "string")
        $util.base64.decode(
          d.srmRequirement,
          m.srmRequirement = $util.newBuffer(
            $util.base64.length(d.srmRequirement)
          ),
          0
        );
      else if (d.srmRequirement.length >= 0)
        m.srmRequirement = d.srmRequirement;
    }
    if (d.srmUpdate != null) {
      if (typeof d.srmUpdate === "string")
        $util.base64.decode(
          d.srmUpdate,
          m.srmUpdate = $util.newBuffer($util.base64.length(d.srmUpdate)),
          0
        );
      else if (d.srmUpdate.length >= 0) m.srmUpdate = d.srmUpdate;
    }
    switch (d.platformVerificationStatus) {
      case "PLATFORM_UNVERIFIED":
      case 0:
        m.platformVerificationStatus = 0;
        break;
      case "PLATFORM_TAMPERED":
      case 1:
        m.platformVerificationStatus = 1;
        break;
      case "PLATFORM_SOFTWARE_VERIFIED":
      case 2:
        m.platformVerificationStatus = 2;
        break;
      case "PLATFORM_HARDWARE_VERIFIED":
      case 3:
        m.platformVerificationStatus = 3;
        break;
      default:
        if (typeof d.platformVerificationStatus === "number") {
          m.platformVerificationStatus = d.platformVerificationStatus;
          break;
        }
        break;
      case "PLATFORM_NO_VERIFICATION":
      case 4:
        m.platformVerificationStatus = 4;
        break;
      case "PLATFORM_SECURE_STORAGE_SOFTWARE_VERIFIED":
      case 5:
        m.platformVerificationStatus = 5;
        break;
    }
    if (d.groupIds) {
      if (!Array.isArray(d.groupIds))
        throw TypeError(".License.groupIds: array expected");
      m.groupIds = [];
      for (var i = 0; i < d.groupIds.length; ++i) {
        if (typeof d.groupIds[i] === "string")
          $util.base64.decode(
            d.groupIds[i],
            m.groupIds[i] = $util.newBuffer(
              $util.base64.length(d.groupIds[i])
            ),
            0
          );
        else if (d.groupIds[i].length >= 0) m.groupIds[i] = d.groupIds[i];
      }
    }
    return m;
  };
  License2.toObject = function toObject(m, o) {
    if (!o) o = {};
    var d = {};
    if (o.arrays || o.defaults) {
      d.key = [];
      d.groupIds = [];
    }
    if (o.defaults) {
      d.id = null;
      d.policy = null;
      if ($util.Long) {
        var n = new $util.Long(0, 0, false);
        d.licenseStartTime = o.longs === String ? n.toString() : o.longs === Number ? n.toNumber() : n;
      } else d.licenseStartTime = o.longs === String ? "0" : 0;
      d.remoteAttestationVerified = false;
      if (o.bytes === String) d.providerClientToken = "";
      else {
        d.providerClientToken = [];
        if (o.bytes !== Array)
          d.providerClientToken = $util.newBuffer(d.providerClientToken);
      }
      d.protectionScheme = 0;
      if (o.bytes === String) d.srmRequirement = "";
      else {
        d.srmRequirement = [];
        if (o.bytes !== Array)
          d.srmRequirement = $util.newBuffer(d.srmRequirement);
      }
      if (o.bytes === String) d.srmUpdate = "";
      else {
        d.srmUpdate = [];
        if (o.bytes !== Array) d.srmUpdate = $util.newBuffer(d.srmUpdate);
      }
      d.platformVerificationStatus = o.enums === String ? "PLATFORM_NO_VERIFICATION" : 4;
    }
    if (m.id != null && m.hasOwnProperty("id")) {
      d.id = $root.LicenseIdentification.toObject(m.id, o);
    }
    if (m.policy != null && m.hasOwnProperty("policy")) {
      d.policy = $root.License.Policy.toObject(m.policy, o);
    }
    if (m.key && m.key.length) {
      d.key = [];
      for (var j = 0; j < m.key.length; ++j) {
        d.key[j] = $root.License.KeyContainer.toObject(m.key[j], o);
      }
    }
    if (m.licenseStartTime != null && m.hasOwnProperty("licenseStartTime")) {
      if (typeof m.licenseStartTime === "number")
        d.licenseStartTime = o.longs === String ? String(m.licenseStartTime) : m.licenseStartTime;
      else
        d.licenseStartTime = o.longs === String ? $util.Long.prototype.toString.call(m.licenseStartTime) : o.longs === Number ? new $util.LongBits(
          m.licenseStartTime.low >>> 0,
          m.licenseStartTime.high >>> 0
        ).toNumber() : m.licenseStartTime;
    }
    if (m.remoteAttestationVerified != null && m.hasOwnProperty("remoteAttestationVerified")) {
      d.remoteAttestationVerified = m.remoteAttestationVerified;
    }
    if (m.providerClientToken != null && m.hasOwnProperty("providerClientToken")) {
      d.providerClientToken = o.bytes === String ? $util.base64.encode(
        m.providerClientToken,
        0,
        m.providerClientToken.length
      ) : o.bytes === Array ? Array.prototype.slice.call(m.providerClientToken) : m.providerClientToken;
    }
    if (m.protectionScheme != null && m.hasOwnProperty("protectionScheme")) {
      d.protectionScheme = m.protectionScheme;
    }
    if (m.srmRequirement != null && m.hasOwnProperty("srmRequirement")) {
      d.srmRequirement = o.bytes === String ? $util.base64.encode(m.srmRequirement, 0, m.srmRequirement.length) : o.bytes === Array ? Array.prototype.slice.call(m.srmRequirement) : m.srmRequirement;
    }
    if (m.srmUpdate != null && m.hasOwnProperty("srmUpdate")) {
      d.srmUpdate = o.bytes === String ? $util.base64.encode(m.srmUpdate, 0, m.srmUpdate.length) : o.bytes === Array ? Array.prototype.slice.call(m.srmUpdate) : m.srmUpdate;
    }
    if (m.platformVerificationStatus != null && m.hasOwnProperty("platformVerificationStatus")) {
      d.platformVerificationStatus = o.enums === String ? $root.PlatformVerificationStatus[m.platformVerificationStatus] === void 0 ? m.platformVerificationStatus : $root.PlatformVerificationStatus[m.platformVerificationStatus] : m.platformVerificationStatus;
    }
    if (m.groupIds && m.groupIds.length) {
      d.groupIds = [];
      for (var j = 0; j < m.groupIds.length; ++j) {
        d.groupIds[j] = o.bytes === String ? $util.base64.encode(m.groupIds[j], 0, m.groupIds[j].length) : o.bytes === Array ? Array.prototype.slice.call(m.groupIds[j]) : m.groupIds[j];
      }
    }
    return d;
  };
  License2.prototype.toJSON = function toJSON() {
    return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
  };
  License2.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
    if (typeUrlPrefix === void 0) {
      typeUrlPrefix = "type.googleapis.com";
    }
    return typeUrlPrefix + "/License";
  };
  License2.Policy = function() {
    function Policy(p) {
      if (p) {
        for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
          if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
      }
    }
    Policy.prototype.canPlay = false;
    Policy.prototype.canPersist = false;
    Policy.prototype.canRenew = false;
    Policy.prototype.rentalDurationSeconds = $util.Long ? $util.Long.fromBits(0, 0, false) : 0;
    Policy.prototype.playbackDurationSeconds = $util.Long ? $util.Long.fromBits(0, 0, false) : 0;
    Policy.prototype.licenseDurationSeconds = $util.Long ? $util.Long.fromBits(0, 0, false) : 0;
    Policy.prototype.renewalRecoveryDurationSeconds = $util.Long ? $util.Long.fromBits(0, 0, false) : 0;
    Policy.prototype.renewalServerUrl = "";
    Policy.prototype.renewalDelaySeconds = $util.Long ? $util.Long.fromBits(0, 0, false) : 0;
    Policy.prototype.renewalRetryIntervalSeconds = $util.Long ? $util.Long.fromBits(0, 0, false) : 0;
    Policy.prototype.renewWithUsage = false;
    Policy.prototype.alwaysIncludeClientId = false;
    Policy.prototype.playStartGracePeriodSeconds = $util.Long ? $util.Long.fromBits(0, 0, false) : 0;
    Policy.prototype.softEnforcePlaybackDuration = false;
    Policy.prototype.softEnforceRentalDuration = true;
    Policy.create = function create(properties) {
      return new Policy(properties);
    };
    Policy.encode = function encode2(m, w) {
      if (!w) w = $Writer.create();
      if (m.canPlay != null && Object.hasOwnProperty.call(m, "canPlay"))
        w.uint32(8).bool(m.canPlay);
      if (m.canPersist != null && Object.hasOwnProperty.call(m, "canPersist"))
        w.uint32(16).bool(m.canPersist);
      if (m.canRenew != null && Object.hasOwnProperty.call(m, "canRenew"))
        w.uint32(24).bool(m.canRenew);
      if (m.rentalDurationSeconds != null && Object.hasOwnProperty.call(m, "rentalDurationSeconds"))
        w.uint32(32).int64(m.rentalDurationSeconds);
      if (m.playbackDurationSeconds != null && Object.hasOwnProperty.call(m, "playbackDurationSeconds"))
        w.uint32(40).int64(m.playbackDurationSeconds);
      if (m.licenseDurationSeconds != null && Object.hasOwnProperty.call(m, "licenseDurationSeconds"))
        w.uint32(48).int64(m.licenseDurationSeconds);
      if (m.renewalRecoveryDurationSeconds != null && Object.hasOwnProperty.call(m, "renewalRecoveryDurationSeconds"))
        w.uint32(56).int64(m.renewalRecoveryDurationSeconds);
      if (m.renewalServerUrl != null && Object.hasOwnProperty.call(m, "renewalServerUrl"))
        w.uint32(66).string(m.renewalServerUrl);
      if (m.renewalDelaySeconds != null && Object.hasOwnProperty.call(m, "renewalDelaySeconds"))
        w.uint32(72).int64(m.renewalDelaySeconds);
      if (m.renewalRetryIntervalSeconds != null && Object.hasOwnProperty.call(m, "renewalRetryIntervalSeconds"))
        w.uint32(80).int64(m.renewalRetryIntervalSeconds);
      if (m.renewWithUsage != null && Object.hasOwnProperty.call(m, "renewWithUsage"))
        w.uint32(88).bool(m.renewWithUsage);
      if (m.alwaysIncludeClientId != null && Object.hasOwnProperty.call(m, "alwaysIncludeClientId"))
        w.uint32(96).bool(m.alwaysIncludeClientId);
      if (m.playStartGracePeriodSeconds != null && Object.hasOwnProperty.call(m, "playStartGracePeriodSeconds"))
        w.uint32(104).int64(m.playStartGracePeriodSeconds);
      if (m.softEnforcePlaybackDuration != null && Object.hasOwnProperty.call(m, "softEnforcePlaybackDuration"))
        w.uint32(112).bool(m.softEnforcePlaybackDuration);
      if (m.softEnforceRentalDuration != null && Object.hasOwnProperty.call(m, "softEnforceRentalDuration"))
        w.uint32(120).bool(m.softEnforceRentalDuration);
      return w;
    };
    Policy.encodeDelimited = function encodeDelimited(message, writer) {
      return this.encode(message, writer).ldelim();
    };
    Policy.decode = function decode2(r, l) {
      if (!(r instanceof $Reader)) r = $Reader.create(r);
      var c = l === void 0 ? r.len : r.pos + l, m = new $root.License.Policy();
      while (r.pos < c) {
        var t = r.uint32();
        switch (t >>> 3) {
          case 1: {
            m.canPlay = r.bool();
            break;
          }
          case 2: {
            m.canPersist = r.bool();
            break;
          }
          case 3: {
            m.canRenew = r.bool();
            break;
          }
          case 4: {
            m.rentalDurationSeconds = r.int64();
            break;
          }
          case 5: {
            m.playbackDurationSeconds = r.int64();
            break;
          }
          case 6: {
            m.licenseDurationSeconds = r.int64();
            break;
          }
          case 7: {
            m.renewalRecoveryDurationSeconds = r.int64();
            break;
          }
          case 8: {
            m.renewalServerUrl = r.string();
            break;
          }
          case 9: {
            m.renewalDelaySeconds = r.int64();
            break;
          }
          case 10: {
            m.renewalRetryIntervalSeconds = r.int64();
            break;
          }
          case 11: {
            m.renewWithUsage = r.bool();
            break;
          }
          case 12: {
            m.alwaysIncludeClientId = r.bool();
            break;
          }
          case 13: {
            m.playStartGracePeriodSeconds = r.int64();
            break;
          }
          case 14: {
            m.softEnforcePlaybackDuration = r.bool();
            break;
          }
          case 15: {
            m.softEnforceRentalDuration = r.bool();
            break;
          }
          default:
            r.skipType(t & 7);
            break;
        }
      }
      return m;
    };
    Policy.decodeDelimited = function decodeDelimited(reader) {
      if (!(reader instanceof $Reader)) reader = new $Reader(reader);
      return this.decode(reader, reader.uint32());
    };
    Policy.fromObject = function fromObject(d) {
      if (d instanceof $root.License.Policy) return d;
      var m = new $root.License.Policy();
      if (d.canPlay != null) {
        m.canPlay = Boolean(d.canPlay);
      }
      if (d.canPersist != null) {
        m.canPersist = Boolean(d.canPersist);
      }
      if (d.canRenew != null) {
        m.canRenew = Boolean(d.canRenew);
      }
      if (d.rentalDurationSeconds != null) {
        if ($util.Long)
          (m.rentalDurationSeconds = $util.Long.fromValue(
            d.rentalDurationSeconds
          )).unsigned = false;
        else if (typeof d.rentalDurationSeconds === "string")
          m.rentalDurationSeconds = parseInt(d.rentalDurationSeconds, 10);
        else if (typeof d.rentalDurationSeconds === "number")
          m.rentalDurationSeconds = d.rentalDurationSeconds;
        else if (typeof d.rentalDurationSeconds === "object")
          m.rentalDurationSeconds = new $util.LongBits(
            d.rentalDurationSeconds.low >>> 0,
            d.rentalDurationSeconds.high >>> 0
          ).toNumber();
      }
      if (d.playbackDurationSeconds != null) {
        if ($util.Long)
          (m.playbackDurationSeconds = $util.Long.fromValue(
            d.playbackDurationSeconds
          )).unsigned = false;
        else if (typeof d.playbackDurationSeconds === "string")
          m.playbackDurationSeconds = parseInt(d.playbackDurationSeconds, 10);
        else if (typeof d.playbackDurationSeconds === "number")
          m.playbackDurationSeconds = d.playbackDurationSeconds;
        else if (typeof d.playbackDurationSeconds === "object")
          m.playbackDurationSeconds = new $util.LongBits(
            d.playbackDurationSeconds.low >>> 0,
            d.playbackDurationSeconds.high >>> 0
          ).toNumber();
      }
      if (d.licenseDurationSeconds != null) {
        if ($util.Long)
          (m.licenseDurationSeconds = $util.Long.fromValue(
            d.licenseDurationSeconds
          )).unsigned = false;
        else if (typeof d.licenseDurationSeconds === "string")
          m.licenseDurationSeconds = parseInt(d.licenseDurationSeconds, 10);
        else if (typeof d.licenseDurationSeconds === "number")
          m.licenseDurationSeconds = d.licenseDurationSeconds;
        else if (typeof d.licenseDurationSeconds === "object")
          m.licenseDurationSeconds = new $util.LongBits(
            d.licenseDurationSeconds.low >>> 0,
            d.licenseDurationSeconds.high >>> 0
          ).toNumber();
      }
      if (d.renewalRecoveryDurationSeconds != null) {
        if ($util.Long)
          (m.renewalRecoveryDurationSeconds = $util.Long.fromValue(
            d.renewalRecoveryDurationSeconds
          )).unsigned = false;
        else if (typeof d.renewalRecoveryDurationSeconds === "string")
          m.renewalRecoveryDurationSeconds = parseInt(
            d.renewalRecoveryDurationSeconds,
            10
          );
        else if (typeof d.renewalRecoveryDurationSeconds === "number")
          m.renewalRecoveryDurationSeconds = d.renewalRecoveryDurationSeconds;
        else if (typeof d.renewalRecoveryDurationSeconds === "object")
          m.renewalRecoveryDurationSeconds = new $util.LongBits(
            d.renewalRecoveryDurationSeconds.low >>> 0,
            d.renewalRecoveryDurationSeconds.high >>> 0
          ).toNumber();
      }
      if (d.renewalServerUrl != null) {
        m.renewalServerUrl = String(d.renewalServerUrl);
      }
      if (d.renewalDelaySeconds != null) {
        if ($util.Long)
          (m.renewalDelaySeconds = $util.Long.fromValue(
            d.renewalDelaySeconds
          )).unsigned = false;
        else if (typeof d.renewalDelaySeconds === "string")
          m.renewalDelaySeconds = parseInt(d.renewalDelaySeconds, 10);
        else if (typeof d.renewalDelaySeconds === "number")
          m.renewalDelaySeconds = d.renewalDelaySeconds;
        else if (typeof d.renewalDelaySeconds === "object")
          m.renewalDelaySeconds = new $util.LongBits(
            d.renewalDelaySeconds.low >>> 0,
            d.renewalDelaySeconds.high >>> 0
          ).toNumber();
      }
      if (d.renewalRetryIntervalSeconds != null) {
        if ($util.Long)
          (m.renewalRetryIntervalSeconds = $util.Long.fromValue(
            d.renewalRetryIntervalSeconds
          )).unsigned = false;
        else if (typeof d.renewalRetryIntervalSeconds === "string")
          m.renewalRetryIntervalSeconds = parseInt(
            d.renewalRetryIntervalSeconds,
            10
          );
        else if (typeof d.renewalRetryIntervalSeconds === "number")
          m.renewalRetryIntervalSeconds = d.renewalRetryIntervalSeconds;
        else if (typeof d.renewalRetryIntervalSeconds === "object")
          m.renewalRetryIntervalSeconds = new $util.LongBits(
            d.renewalRetryIntervalSeconds.low >>> 0,
            d.renewalRetryIntervalSeconds.high >>> 0
          ).toNumber();
      }
      if (d.renewWithUsage != null) {
        m.renewWithUsage = Boolean(d.renewWithUsage);
      }
      if (d.alwaysIncludeClientId != null) {
        m.alwaysIncludeClientId = Boolean(d.alwaysIncludeClientId);
      }
      if (d.playStartGracePeriodSeconds != null) {
        if ($util.Long)
          (m.playStartGracePeriodSeconds = $util.Long.fromValue(
            d.playStartGracePeriodSeconds
          )).unsigned = false;
        else if (typeof d.playStartGracePeriodSeconds === "string")
          m.playStartGracePeriodSeconds = parseInt(
            d.playStartGracePeriodSeconds,
            10
          );
        else if (typeof d.playStartGracePeriodSeconds === "number")
          m.playStartGracePeriodSeconds = d.playStartGracePeriodSeconds;
        else if (typeof d.playStartGracePeriodSeconds === "object")
          m.playStartGracePeriodSeconds = new $util.LongBits(
            d.playStartGracePeriodSeconds.low >>> 0,
            d.playStartGracePeriodSeconds.high >>> 0
          ).toNumber();
      }
      if (d.softEnforcePlaybackDuration != null) {
        m.softEnforcePlaybackDuration = Boolean(d.softEnforcePlaybackDuration);
      }
      if (d.softEnforceRentalDuration != null) {
        m.softEnforceRentalDuration = Boolean(d.softEnforceRentalDuration);
      }
      return m;
    };
    Policy.toObject = function toObject(m, o) {
      if (!o) o = {};
      var d = {};
      if (o.defaults) {
        d.canPlay = false;
        d.canPersist = false;
        d.canRenew = false;
        if ($util.Long) {
          var n = new $util.Long(0, 0, false);
          d.rentalDurationSeconds = o.longs === String ? n.toString() : o.longs === Number ? n.toNumber() : n;
        } else d.rentalDurationSeconds = o.longs === String ? "0" : 0;
        if ($util.Long) {
          var n = new $util.Long(0, 0, false);
          d.playbackDurationSeconds = o.longs === String ? n.toString() : o.longs === Number ? n.toNumber() : n;
        } else d.playbackDurationSeconds = o.longs === String ? "0" : 0;
        if ($util.Long) {
          var n = new $util.Long(0, 0, false);
          d.licenseDurationSeconds = o.longs === String ? n.toString() : o.longs === Number ? n.toNumber() : n;
        } else d.licenseDurationSeconds = o.longs === String ? "0" : 0;
        if ($util.Long) {
          var n = new $util.Long(0, 0, false);
          d.renewalRecoveryDurationSeconds = o.longs === String ? n.toString() : o.longs === Number ? n.toNumber() : n;
        } else d.renewalRecoveryDurationSeconds = o.longs === String ? "0" : 0;
        d.renewalServerUrl = "";
        if ($util.Long) {
          var n = new $util.Long(0, 0, false);
          d.renewalDelaySeconds = o.longs === String ? n.toString() : o.longs === Number ? n.toNumber() : n;
        } else d.renewalDelaySeconds = o.longs === String ? "0" : 0;
        if ($util.Long) {
          var n = new $util.Long(0, 0, false);
          d.renewalRetryIntervalSeconds = o.longs === String ? n.toString() : o.longs === Number ? n.toNumber() : n;
        } else d.renewalRetryIntervalSeconds = o.longs === String ? "0" : 0;
        d.renewWithUsage = false;
        d.alwaysIncludeClientId = false;
        if ($util.Long) {
          var n = new $util.Long(0, 0, false);
          d.playStartGracePeriodSeconds = o.longs === String ? n.toString() : o.longs === Number ? n.toNumber() : n;
        } else d.playStartGracePeriodSeconds = o.longs === String ? "0" : 0;
        d.softEnforcePlaybackDuration = false;
        d.softEnforceRentalDuration = true;
      }
      if (m.canPlay != null && m.hasOwnProperty("canPlay")) {
        d.canPlay = m.canPlay;
      }
      if (m.canPersist != null && m.hasOwnProperty("canPersist")) {
        d.canPersist = m.canPersist;
      }
      if (m.canRenew != null && m.hasOwnProperty("canRenew")) {
        d.canRenew = m.canRenew;
      }
      if (m.rentalDurationSeconds != null && m.hasOwnProperty("rentalDurationSeconds")) {
        if (typeof m.rentalDurationSeconds === "number")
          d.rentalDurationSeconds = o.longs === String ? String(m.rentalDurationSeconds) : m.rentalDurationSeconds;
        else
          d.rentalDurationSeconds = o.longs === String ? $util.Long.prototype.toString.call(m.rentalDurationSeconds) : o.longs === Number ? new $util.LongBits(
            m.rentalDurationSeconds.low >>> 0,
            m.rentalDurationSeconds.high >>> 0
          ).toNumber() : m.rentalDurationSeconds;
      }
      if (m.playbackDurationSeconds != null && m.hasOwnProperty("playbackDurationSeconds")) {
        if (typeof m.playbackDurationSeconds === "number")
          d.playbackDurationSeconds = o.longs === String ? String(m.playbackDurationSeconds) : m.playbackDurationSeconds;
        else
          d.playbackDurationSeconds = o.longs === String ? $util.Long.prototype.toString.call(m.playbackDurationSeconds) : o.longs === Number ? new $util.LongBits(
            m.playbackDurationSeconds.low >>> 0,
            m.playbackDurationSeconds.high >>> 0
          ).toNumber() : m.playbackDurationSeconds;
      }
      if (m.licenseDurationSeconds != null && m.hasOwnProperty("licenseDurationSeconds")) {
        if (typeof m.licenseDurationSeconds === "number")
          d.licenseDurationSeconds = o.longs === String ? String(m.licenseDurationSeconds) : m.licenseDurationSeconds;
        else
          d.licenseDurationSeconds = o.longs === String ? $util.Long.prototype.toString.call(m.licenseDurationSeconds) : o.longs === Number ? new $util.LongBits(
            m.licenseDurationSeconds.low >>> 0,
            m.licenseDurationSeconds.high >>> 0
          ).toNumber() : m.licenseDurationSeconds;
      }
      if (m.renewalRecoveryDurationSeconds != null && m.hasOwnProperty("renewalRecoveryDurationSeconds")) {
        if (typeof m.renewalRecoveryDurationSeconds === "number")
          d.renewalRecoveryDurationSeconds = o.longs === String ? String(m.renewalRecoveryDurationSeconds) : m.renewalRecoveryDurationSeconds;
        else
          d.renewalRecoveryDurationSeconds = o.longs === String ? $util.Long.prototype.toString.call(
            m.renewalRecoveryDurationSeconds
          ) : o.longs === Number ? new $util.LongBits(
            m.renewalRecoveryDurationSeconds.low >>> 0,
            m.renewalRecoveryDurationSeconds.high >>> 0
          ).toNumber() : m.renewalRecoveryDurationSeconds;
      }
      if (m.renewalServerUrl != null && m.hasOwnProperty("renewalServerUrl")) {
        d.renewalServerUrl = m.renewalServerUrl;
      }
      if (m.renewalDelaySeconds != null && m.hasOwnProperty("renewalDelaySeconds")) {
        if (typeof m.renewalDelaySeconds === "number")
          d.renewalDelaySeconds = o.longs === String ? String(m.renewalDelaySeconds) : m.renewalDelaySeconds;
        else
          d.renewalDelaySeconds = o.longs === String ? $util.Long.prototype.toString.call(m.renewalDelaySeconds) : o.longs === Number ? new $util.LongBits(
            m.renewalDelaySeconds.low >>> 0,
            m.renewalDelaySeconds.high >>> 0
          ).toNumber() : m.renewalDelaySeconds;
      }
      if (m.renewalRetryIntervalSeconds != null && m.hasOwnProperty("renewalRetryIntervalSeconds")) {
        if (typeof m.renewalRetryIntervalSeconds === "number")
          d.renewalRetryIntervalSeconds = o.longs === String ? String(m.renewalRetryIntervalSeconds) : m.renewalRetryIntervalSeconds;
        else
          d.renewalRetryIntervalSeconds = o.longs === String ? $util.Long.prototype.toString.call(
            m.renewalRetryIntervalSeconds
          ) : o.longs === Number ? new $util.LongBits(
            m.renewalRetryIntervalSeconds.low >>> 0,
            m.renewalRetryIntervalSeconds.high >>> 0
          ).toNumber() : m.renewalRetryIntervalSeconds;
      }
      if (m.renewWithUsage != null && m.hasOwnProperty("renewWithUsage")) {
        d.renewWithUsage = m.renewWithUsage;
      }
      if (m.alwaysIncludeClientId != null && m.hasOwnProperty("alwaysIncludeClientId")) {
        d.alwaysIncludeClientId = m.alwaysIncludeClientId;
      }
      if (m.playStartGracePeriodSeconds != null && m.hasOwnProperty("playStartGracePeriodSeconds")) {
        if (typeof m.playStartGracePeriodSeconds === "number")
          d.playStartGracePeriodSeconds = o.longs === String ? String(m.playStartGracePeriodSeconds) : m.playStartGracePeriodSeconds;
        else
          d.playStartGracePeriodSeconds = o.longs === String ? $util.Long.prototype.toString.call(
            m.playStartGracePeriodSeconds
          ) : o.longs === Number ? new $util.LongBits(
            m.playStartGracePeriodSeconds.low >>> 0,
            m.playStartGracePeriodSeconds.high >>> 0
          ).toNumber() : m.playStartGracePeriodSeconds;
      }
      if (m.softEnforcePlaybackDuration != null && m.hasOwnProperty("softEnforcePlaybackDuration")) {
        d.softEnforcePlaybackDuration = m.softEnforcePlaybackDuration;
      }
      if (m.softEnforceRentalDuration != null && m.hasOwnProperty("softEnforceRentalDuration")) {
        d.softEnforceRentalDuration = m.softEnforceRentalDuration;
      }
      return d;
    };
    Policy.prototype.toJSON = function toJSON() {
      return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
    };
    Policy.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
      if (typeUrlPrefix === void 0) {
        typeUrlPrefix = "type.googleapis.com";
      }
      return typeUrlPrefix + "/License.Policy";
    };
    return Policy;
  }();
  License2.KeyContainer = function() {
    function KeyContainer(p) {
      this.videoResolutionConstraints = [];
      if (p) {
        for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
          if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
      }
    }
    KeyContainer.prototype.id = $util.newBuffer([]);
    KeyContainer.prototype.iv = $util.newBuffer([]);
    KeyContainer.prototype.key = $util.newBuffer([]);
    KeyContainer.prototype.type = 1;
    KeyContainer.prototype.level = 1;
    KeyContainer.prototype.requiredProtection = null;
    KeyContainer.prototype.requestedProtection = null;
    KeyContainer.prototype.keyControl = null;
    KeyContainer.prototype.operatorSessionKeyPermissions = null;
    KeyContainer.prototype.videoResolutionConstraints = $util.emptyArray;
    KeyContainer.prototype.antiRollbackUsageTable = false;
    KeyContainer.prototype.trackLabel = "";
    KeyContainer.create = function create(properties) {
      return new KeyContainer(properties);
    };
    KeyContainer.encode = function encode2(m, w) {
      if (!w) w = $Writer.create();
      if (m.id != null && Object.hasOwnProperty.call(m, "id"))
        w.uint32(10).bytes(m.id);
      if (m.iv != null && Object.hasOwnProperty.call(m, "iv"))
        w.uint32(18).bytes(m.iv);
      if (m.key != null && Object.hasOwnProperty.call(m, "key"))
        w.uint32(26).bytes(m.key);
      if (m.type != null && Object.hasOwnProperty.call(m, "type"))
        w.uint32(32).int32(m.type);
      if (m.level != null && Object.hasOwnProperty.call(m, "level"))
        w.uint32(40).int32(m.level);
      if (m.requiredProtection != null && Object.hasOwnProperty.call(m, "requiredProtection"))
        $root.License.KeyContainer.OutputProtection.encode(
          m.requiredProtection,
          w.uint32(50).fork()
        ).ldelim();
      if (m.requestedProtection != null && Object.hasOwnProperty.call(m, "requestedProtection"))
        $root.License.KeyContainer.OutputProtection.encode(
          m.requestedProtection,
          w.uint32(58).fork()
        ).ldelim();
      if (m.keyControl != null && Object.hasOwnProperty.call(m, "keyControl"))
        $root.License.KeyContainer.KeyControl.encode(
          m.keyControl,
          w.uint32(66).fork()
        ).ldelim();
      if (m.operatorSessionKeyPermissions != null && Object.hasOwnProperty.call(m, "operatorSessionKeyPermissions"))
        $root.License.KeyContainer.OperatorSessionKeyPermissions.encode(
          m.operatorSessionKeyPermissions,
          w.uint32(74).fork()
        ).ldelim();
      if (m.videoResolutionConstraints != null && m.videoResolutionConstraints.length) {
        for (var i = 0; i < m.videoResolutionConstraints.length; ++i)
          $root.License.KeyContainer.VideoResolutionConstraint.encode(
            m.videoResolutionConstraints[i],
            w.uint32(82).fork()
          ).ldelim();
      }
      if (m.antiRollbackUsageTable != null && Object.hasOwnProperty.call(m, "antiRollbackUsageTable"))
        w.uint32(88).bool(m.antiRollbackUsageTable);
      if (m.trackLabel != null && Object.hasOwnProperty.call(m, "trackLabel"))
        w.uint32(98).string(m.trackLabel);
      return w;
    };
    KeyContainer.encodeDelimited = function encodeDelimited(message, writer) {
      return this.encode(message, writer).ldelim();
    };
    KeyContainer.decode = function decode2(r, l) {
      if (!(r instanceof $Reader)) r = $Reader.create(r);
      var c = l === void 0 ? r.len : r.pos + l, m = new $root.License.KeyContainer();
      while (r.pos < c) {
        var t = r.uint32();
        switch (t >>> 3) {
          case 1: {
            m.id = r.bytes();
            break;
          }
          case 2: {
            m.iv = r.bytes();
            break;
          }
          case 3: {
            m.key = r.bytes();
            break;
          }
          case 4: {
            m.type = r.int32();
            break;
          }
          case 5: {
            m.level = r.int32();
            break;
          }
          case 6: {
            m.requiredProtection = $root.License.KeyContainer.OutputProtection.decode(r, r.uint32());
            break;
          }
          case 7: {
            m.requestedProtection = $root.License.KeyContainer.OutputProtection.decode(r, r.uint32());
            break;
          }
          case 8: {
            m.keyControl = $root.License.KeyContainer.KeyControl.decode(
              r,
              r.uint32()
            );
            break;
          }
          case 9: {
            m.operatorSessionKeyPermissions = $root.License.KeyContainer.OperatorSessionKeyPermissions.decode(
              r,
              r.uint32()
            );
            break;
          }
          case 10: {
            if (!(m.videoResolutionConstraints && m.videoResolutionConstraints.length))
              m.videoResolutionConstraints = [];
            m.videoResolutionConstraints.push(
              $root.License.KeyContainer.VideoResolutionConstraint.decode(
                r,
                r.uint32()
              )
            );
            break;
          }
          case 11: {
            m.antiRollbackUsageTable = r.bool();
            break;
          }
          case 12: {
            m.trackLabel = r.string();
            break;
          }
          default:
            r.skipType(t & 7);
            break;
        }
      }
      return m;
    };
    KeyContainer.decodeDelimited = function decodeDelimited(reader) {
      if (!(reader instanceof $Reader)) reader = new $Reader(reader);
      return this.decode(reader, reader.uint32());
    };
    KeyContainer.fromObject = function fromObject(d) {
      if (d instanceof $root.License.KeyContainer) return d;
      var m = new $root.License.KeyContainer();
      if (d.id != null) {
        if (typeof d.id === "string")
          $util.base64.decode(
            d.id,
            m.id = $util.newBuffer($util.base64.length(d.id)),
            0
          );
        else if (d.id.length >= 0) m.id = d.id;
      }
      if (d.iv != null) {
        if (typeof d.iv === "string")
          $util.base64.decode(
            d.iv,
            m.iv = $util.newBuffer($util.base64.length(d.iv)),
            0
          );
        else if (d.iv.length >= 0) m.iv = d.iv;
      }
      if (d.key != null) {
        if (typeof d.key === "string")
          $util.base64.decode(
            d.key,
            m.key = $util.newBuffer($util.base64.length(d.key)),
            0
          );
        else if (d.key.length >= 0) m.key = d.key;
      }
      switch (d.type) {
        default:
          if (typeof d.type === "number") {
            m.type = d.type;
            break;
          }
          break;
        case "SIGNING":
        case 1:
          m.type = 1;
          break;
        case "CONTENT":
        case 2:
          m.type = 2;
          break;
        case "KEY_CONTROL":
        case 3:
          m.type = 3;
          break;
        case "OPERATOR_SESSION":
        case 4:
          m.type = 4;
          break;
        case "ENTITLEMENT":
        case 5:
          m.type = 5;
          break;
        case "OEM_CONTENT":
        case 6:
          m.type = 6;
          break;
      }
      switch (d.level) {
        default:
          if (typeof d.level === "number") {
            m.level = d.level;
            break;
          }
          break;
        case "SW_SECURE_CRYPTO":
        case 1:
          m.level = 1;
          break;
        case "SW_SECURE_DECODE":
        case 2:
          m.level = 2;
          break;
        case "HW_SECURE_CRYPTO":
        case 3:
          m.level = 3;
          break;
        case "HW_SECURE_DECODE":
        case 4:
          m.level = 4;
          break;
        case "HW_SECURE_ALL":
        case 5:
          m.level = 5;
          break;
      }
      if (d.requiredProtection != null) {
        if (typeof d.requiredProtection !== "object")
          throw TypeError(
            ".License.KeyContainer.requiredProtection: object expected"
          );
        m.requiredProtection = $root.License.KeyContainer.OutputProtection.fromObject(
          d.requiredProtection
        );
      }
      if (d.requestedProtection != null) {
        if (typeof d.requestedProtection !== "object")
          throw TypeError(
            ".License.KeyContainer.requestedProtection: object expected"
          );
        m.requestedProtection = $root.License.KeyContainer.OutputProtection.fromObject(
          d.requestedProtection
        );
      }
      if (d.keyControl != null) {
        if (typeof d.keyControl !== "object")
          throw TypeError(".License.KeyContainer.keyControl: object expected");
        m.keyControl = $root.License.KeyContainer.KeyControl.fromObject(
          d.keyControl
        );
      }
      if (d.operatorSessionKeyPermissions != null) {
        if (typeof d.operatorSessionKeyPermissions !== "object")
          throw TypeError(
            ".License.KeyContainer.operatorSessionKeyPermissions: object expected"
          );
        m.operatorSessionKeyPermissions = $root.License.KeyContainer.OperatorSessionKeyPermissions.fromObject(
          d.operatorSessionKeyPermissions
        );
      }
      if (d.videoResolutionConstraints) {
        if (!Array.isArray(d.videoResolutionConstraints))
          throw TypeError(
            ".License.KeyContainer.videoResolutionConstraints: array expected"
          );
        m.videoResolutionConstraints = [];
        for (var i = 0; i < d.videoResolutionConstraints.length; ++i) {
          if (typeof d.videoResolutionConstraints[i] !== "object")
            throw TypeError(
              ".License.KeyContainer.videoResolutionConstraints: object expected"
            );
          m.videoResolutionConstraints[i] = $root.License.KeyContainer.VideoResolutionConstraint.fromObject(
            d.videoResolutionConstraints[i]
          );
        }
      }
      if (d.antiRollbackUsageTable != null) {
        m.antiRollbackUsageTable = Boolean(d.antiRollbackUsageTable);
      }
      if (d.trackLabel != null) {
        m.trackLabel = String(d.trackLabel);
      }
      return m;
    };
    KeyContainer.toObject = function toObject(m, o) {
      if (!o) o = {};
      var d = {};
      if (o.arrays || o.defaults) {
        d.videoResolutionConstraints = [];
      }
      if (o.defaults) {
        if (o.bytes === String) d.id = "";
        else {
          d.id = [];
          if (o.bytes !== Array) d.id = $util.newBuffer(d.id);
        }
        if (o.bytes === String) d.iv = "";
        else {
          d.iv = [];
          if (o.bytes !== Array) d.iv = $util.newBuffer(d.iv);
        }
        if (o.bytes === String) d.key = "";
        else {
          d.key = [];
          if (o.bytes !== Array) d.key = $util.newBuffer(d.key);
        }
        d.type = o.enums === String ? "SIGNING" : 1;
        d.level = o.enums === String ? "SW_SECURE_CRYPTO" : 1;
        d.requiredProtection = null;
        d.requestedProtection = null;
        d.keyControl = null;
        d.operatorSessionKeyPermissions = null;
        d.antiRollbackUsageTable = false;
        d.trackLabel = "";
      }
      if (m.id != null && m.hasOwnProperty("id")) {
        d.id = o.bytes === String ? $util.base64.encode(m.id, 0, m.id.length) : o.bytes === Array ? Array.prototype.slice.call(m.id) : m.id;
      }
      if (m.iv != null && m.hasOwnProperty("iv")) {
        d.iv = o.bytes === String ? $util.base64.encode(m.iv, 0, m.iv.length) : o.bytes === Array ? Array.prototype.slice.call(m.iv) : m.iv;
      }
      if (m.key != null && m.hasOwnProperty("key")) {
        d.key = o.bytes === String ? $util.base64.encode(m.key, 0, m.key.length) : o.bytes === Array ? Array.prototype.slice.call(m.key) : m.key;
      }
      if (m.type != null && m.hasOwnProperty("type")) {
        d.type = o.enums === String ? $root.License.KeyContainer.KeyType[m.type] === void 0 ? m.type : $root.License.KeyContainer.KeyType[m.type] : m.type;
      }
      if (m.level != null && m.hasOwnProperty("level")) {
        d.level = o.enums === String ? $root.License.KeyContainer.SecurityLevel[m.level] === void 0 ? m.level : $root.License.KeyContainer.SecurityLevel[m.level] : m.level;
      }
      if (m.requiredProtection != null && m.hasOwnProperty("requiredProtection")) {
        d.requiredProtection = $root.License.KeyContainer.OutputProtection.toObject(
          m.requiredProtection,
          o
        );
      }
      if (m.requestedProtection != null && m.hasOwnProperty("requestedProtection")) {
        d.requestedProtection = $root.License.KeyContainer.OutputProtection.toObject(
          m.requestedProtection,
          o
        );
      }
      if (m.keyControl != null && m.hasOwnProperty("keyControl")) {
        d.keyControl = $root.License.KeyContainer.KeyControl.toObject(
          m.keyControl,
          o
        );
      }
      if (m.operatorSessionKeyPermissions != null && m.hasOwnProperty("operatorSessionKeyPermissions")) {
        d.operatorSessionKeyPermissions = $root.License.KeyContainer.OperatorSessionKeyPermissions.toObject(
          m.operatorSessionKeyPermissions,
          o
        );
      }
      if (m.videoResolutionConstraints && m.videoResolutionConstraints.length) {
        d.videoResolutionConstraints = [];
        for (var j = 0; j < m.videoResolutionConstraints.length; ++j) {
          d.videoResolutionConstraints[j] = $root.License.KeyContainer.VideoResolutionConstraint.toObject(
            m.videoResolutionConstraints[j],
            o
          );
        }
      }
      if (m.antiRollbackUsageTable != null && m.hasOwnProperty("antiRollbackUsageTable")) {
        d.antiRollbackUsageTable = m.antiRollbackUsageTable;
      }
      if (m.trackLabel != null && m.hasOwnProperty("trackLabel")) {
        d.trackLabel = m.trackLabel;
      }
      return d;
    };
    KeyContainer.prototype.toJSON = function toJSON() {
      return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
    };
    KeyContainer.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
      if (typeUrlPrefix === void 0) {
        typeUrlPrefix = "type.googleapis.com";
      }
      return typeUrlPrefix + "/License.KeyContainer";
    };
    KeyContainer.KeyType = function() {
      const valuesById = {}, values = Object.create(valuesById);
      values[valuesById[1] = "SIGNING"] = 1;
      values[valuesById[2] = "CONTENT"] = 2;
      values[valuesById[3] = "KEY_CONTROL"] = 3;
      values[valuesById[4] = "OPERATOR_SESSION"] = 4;
      values[valuesById[5] = "ENTITLEMENT"] = 5;
      values[valuesById[6] = "OEM_CONTENT"] = 6;
      return values;
    }();
    KeyContainer.SecurityLevel = function() {
      const valuesById = {}, values = Object.create(valuesById);
      values[valuesById[1] = "SW_SECURE_CRYPTO"] = 1;
      values[valuesById[2] = "SW_SECURE_DECODE"] = 2;
      values[valuesById[3] = "HW_SECURE_CRYPTO"] = 3;
      values[valuesById[4] = "HW_SECURE_DECODE"] = 4;
      values[valuesById[5] = "HW_SECURE_ALL"] = 5;
      return values;
    }();
    KeyContainer.KeyControl = function() {
      function KeyControl(p) {
        if (p) {
          for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
            if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
        }
      }
      KeyControl.prototype.keyControlBlock = $util.newBuffer([]);
      KeyControl.prototype.iv = $util.newBuffer([]);
      KeyControl.create = function create(properties) {
        return new KeyControl(properties);
      };
      KeyControl.encode = function encode2(m, w) {
        if (!w) w = $Writer.create();
        if (m.keyControlBlock != null && Object.hasOwnProperty.call(m, "keyControlBlock"))
          w.uint32(10).bytes(m.keyControlBlock);
        if (m.iv != null && Object.hasOwnProperty.call(m, "iv"))
          w.uint32(18).bytes(m.iv);
        return w;
      };
      KeyControl.encodeDelimited = function encodeDelimited(message, writer) {
        return this.encode(message, writer).ldelim();
      };
      KeyControl.decode = function decode2(r, l) {
        if (!(r instanceof $Reader)) r = $Reader.create(r);
        var c = l === void 0 ? r.len : r.pos + l, m = new $root.License.KeyContainer.KeyControl();
        while (r.pos < c) {
          var t = r.uint32();
          switch (t >>> 3) {
            case 1: {
              m.keyControlBlock = r.bytes();
              break;
            }
            case 2: {
              m.iv = r.bytes();
              break;
            }
            default:
              r.skipType(t & 7);
              break;
          }
        }
        return m;
      };
      KeyControl.decodeDelimited = function decodeDelimited(reader) {
        if (!(reader instanceof $Reader)) reader = new $Reader(reader);
        return this.decode(reader, reader.uint32());
      };
      KeyControl.fromObject = function fromObject(d) {
        if (d instanceof $root.License.KeyContainer.KeyControl) return d;
        var m = new $root.License.KeyContainer.KeyControl();
        if (d.keyControlBlock != null) {
          if (typeof d.keyControlBlock === "string")
            $util.base64.decode(
              d.keyControlBlock,
              m.keyControlBlock = $util.newBuffer(
                $util.base64.length(d.keyControlBlock)
              ),
              0
            );
          else if (d.keyControlBlock.length >= 0)
            m.keyControlBlock = d.keyControlBlock;
        }
        if (d.iv != null) {
          if (typeof d.iv === "string")
            $util.base64.decode(
              d.iv,
              m.iv = $util.newBuffer($util.base64.length(d.iv)),
              0
            );
          else if (d.iv.length >= 0) m.iv = d.iv;
        }
        return m;
      };
      KeyControl.toObject = function toObject(m, o) {
        if (!o) o = {};
        var d = {};
        if (o.defaults) {
          if (o.bytes === String) d.keyControlBlock = "";
          else {
            d.keyControlBlock = [];
            if (o.bytes !== Array)
              d.keyControlBlock = $util.newBuffer(d.keyControlBlock);
          }
          if (o.bytes === String) d.iv = "";
          else {
            d.iv = [];
            if (o.bytes !== Array) d.iv = $util.newBuffer(d.iv);
          }
        }
        if (m.keyControlBlock != null && m.hasOwnProperty("keyControlBlock")) {
          d.keyControlBlock = o.bytes === String ? $util.base64.encode(
            m.keyControlBlock,
            0,
            m.keyControlBlock.length
          ) : o.bytes === Array ? Array.prototype.slice.call(m.keyControlBlock) : m.keyControlBlock;
        }
        if (m.iv != null && m.hasOwnProperty("iv")) {
          d.iv = o.bytes === String ? $util.base64.encode(m.iv, 0, m.iv.length) : o.bytes === Array ? Array.prototype.slice.call(m.iv) : m.iv;
        }
        return d;
      };
      KeyControl.prototype.toJSON = function toJSON() {
        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
      };
      KeyControl.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
        if (typeUrlPrefix === void 0) {
          typeUrlPrefix = "type.googleapis.com";
        }
        return typeUrlPrefix + "/License.KeyContainer.KeyControl";
      };
      return KeyControl;
    }();
    KeyContainer.OutputProtection = function() {
      function OutputProtection(p) {
        if (p) {
          for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
            if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
        }
      }
      OutputProtection.prototype.hdcp = 0;
      OutputProtection.prototype.cgmsFlags = 42;
      OutputProtection.prototype.hdcpSrmRule = 0;
      OutputProtection.prototype.disableAnalogOutput = false;
      OutputProtection.prototype.disableDigitalOutput = false;
      OutputProtection.create = function create(properties) {
        return new OutputProtection(properties);
      };
      OutputProtection.encode = function encode2(m, w) {
        if (!w) w = $Writer.create();
        if (m.hdcp != null && Object.hasOwnProperty.call(m, "hdcp"))
          w.uint32(8).int32(m.hdcp);
        if (m.cgmsFlags != null && Object.hasOwnProperty.call(m, "cgmsFlags"))
          w.uint32(16).int32(m.cgmsFlags);
        if (m.hdcpSrmRule != null && Object.hasOwnProperty.call(m, "hdcpSrmRule"))
          w.uint32(24).int32(m.hdcpSrmRule);
        if (m.disableAnalogOutput != null && Object.hasOwnProperty.call(m, "disableAnalogOutput"))
          w.uint32(32).bool(m.disableAnalogOutput);
        if (m.disableDigitalOutput != null && Object.hasOwnProperty.call(m, "disableDigitalOutput"))
          w.uint32(40).bool(m.disableDigitalOutput);
        return w;
      };
      OutputProtection.encodeDelimited = function encodeDelimited(message, writer) {
        return this.encode(message, writer).ldelim();
      };
      OutputProtection.decode = function decode2(r, l) {
        if (!(r instanceof $Reader)) r = $Reader.create(r);
        var c = l === void 0 ? r.len : r.pos + l, m = new $root.License.KeyContainer.OutputProtection();
        while (r.pos < c) {
          var t = r.uint32();
          switch (t >>> 3) {
            case 1: {
              m.hdcp = r.int32();
              break;
            }
            case 2: {
              m.cgmsFlags = r.int32();
              break;
            }
            case 3: {
              m.hdcpSrmRule = r.int32();
              break;
            }
            case 4: {
              m.disableAnalogOutput = r.bool();
              break;
            }
            case 5: {
              m.disableDigitalOutput = r.bool();
              break;
            }
            default:
              r.skipType(t & 7);
              break;
          }
        }
        return m;
      };
      OutputProtection.decodeDelimited = function decodeDelimited(reader) {
        if (!(reader instanceof $Reader)) reader = new $Reader(reader);
        return this.decode(reader, reader.uint32());
      };
      OutputProtection.fromObject = function fromObject(d) {
        if (d instanceof $root.License.KeyContainer.OutputProtection) return d;
        var m = new $root.License.KeyContainer.OutputProtection();
        switch (d.hdcp) {
          default:
            if (typeof d.hdcp === "number") {
              m.hdcp = d.hdcp;
              break;
            }
            break;
          case "HDCP_NONE":
          case 0:
            m.hdcp = 0;
            break;
          case "HDCP_V1":
          case 1:
            m.hdcp = 1;
            break;
          case "HDCP_V2":
          case 2:
            m.hdcp = 2;
            break;
          case "HDCP_V2_1":
          case 3:
            m.hdcp = 3;
            break;
          case "HDCP_V2_2":
          case 4:
            m.hdcp = 4;
            break;
          case "HDCP_V2_3":
          case 5:
            m.hdcp = 5;
            break;
          case "HDCP_NO_DIGITAL_OUTPUT":
          case 255:
            m.hdcp = 255;
            break;
        }
        switch (d.cgmsFlags) {
          default:
            if (typeof d.cgmsFlags === "number") {
              m.cgmsFlags = d.cgmsFlags;
              break;
            }
            break;
          case "CGMS_NONE":
          case 42:
            m.cgmsFlags = 42;
            break;
          case "COPY_FREE":
          case 0:
            m.cgmsFlags = 0;
            break;
          case "COPY_ONCE":
          case 2:
            m.cgmsFlags = 2;
            break;
          case "COPY_NEVER":
          case 3:
            m.cgmsFlags = 3;
            break;
        }
        switch (d.hdcpSrmRule) {
          default:
            if (typeof d.hdcpSrmRule === "number") {
              m.hdcpSrmRule = d.hdcpSrmRule;
              break;
            }
            break;
          case "HDCP_SRM_RULE_NONE":
          case 0:
            m.hdcpSrmRule = 0;
            break;
          case "CURRENT_SRM":
          case 1:
            m.hdcpSrmRule = 1;
            break;
        }
        if (d.disableAnalogOutput != null) {
          m.disableAnalogOutput = Boolean(d.disableAnalogOutput);
        }
        if (d.disableDigitalOutput != null) {
          m.disableDigitalOutput = Boolean(d.disableDigitalOutput);
        }
        return m;
      };
      OutputProtection.toObject = function toObject(m, o) {
        if (!o) o = {};
        var d = {};
        if (o.defaults) {
          d.hdcp = o.enums === String ? "HDCP_NONE" : 0;
          d.cgmsFlags = o.enums === String ? "CGMS_NONE" : 42;
          d.hdcpSrmRule = o.enums === String ? "HDCP_SRM_RULE_NONE" : 0;
          d.disableAnalogOutput = false;
          d.disableDigitalOutput = false;
        }
        if (m.hdcp != null && m.hasOwnProperty("hdcp")) {
          d.hdcp = o.enums === String ? $root.License.KeyContainer.OutputProtection.HDCP[m.hdcp] === void 0 ? m.hdcp : $root.License.KeyContainer.OutputProtection.HDCP[m.hdcp] : m.hdcp;
        }
        if (m.cgmsFlags != null && m.hasOwnProperty("cgmsFlags")) {
          d.cgmsFlags = o.enums === String ? $root.License.KeyContainer.OutputProtection.CGMS[m.cgmsFlags] === void 0 ? m.cgmsFlags : $root.License.KeyContainer.OutputProtection.CGMS[m.cgmsFlags] : m.cgmsFlags;
        }
        if (m.hdcpSrmRule != null && m.hasOwnProperty("hdcpSrmRule")) {
          d.hdcpSrmRule = o.enums === String ? $root.License.KeyContainer.OutputProtection.HdcpSrmRule[m.hdcpSrmRule] === void 0 ? m.hdcpSrmRule : $root.License.KeyContainer.OutputProtection.HdcpSrmRule[m.hdcpSrmRule] : m.hdcpSrmRule;
        }
        if (m.disableAnalogOutput != null && m.hasOwnProperty("disableAnalogOutput")) {
          d.disableAnalogOutput = m.disableAnalogOutput;
        }
        if (m.disableDigitalOutput != null && m.hasOwnProperty("disableDigitalOutput")) {
          d.disableDigitalOutput = m.disableDigitalOutput;
        }
        return d;
      };
      OutputProtection.prototype.toJSON = function toJSON() {
        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
      };
      OutputProtection.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
        if (typeUrlPrefix === void 0) {
          typeUrlPrefix = "type.googleapis.com";
        }
        return typeUrlPrefix + "/License.KeyContainer.OutputProtection";
      };
      OutputProtection.HDCP = function() {
        const valuesById = {}, values = Object.create(valuesById);
        values[valuesById[0] = "HDCP_NONE"] = 0;
        values[valuesById[1] = "HDCP_V1"] = 1;
        values[valuesById[2] = "HDCP_V2"] = 2;
        values[valuesById[3] = "HDCP_V2_1"] = 3;
        values[valuesById[4] = "HDCP_V2_2"] = 4;
        values[valuesById[5] = "HDCP_V2_3"] = 5;
        values[valuesById[255] = "HDCP_NO_DIGITAL_OUTPUT"] = 255;
        return values;
      }();
      OutputProtection.CGMS = function() {
        const valuesById = {}, values = Object.create(valuesById);
        values[valuesById[42] = "CGMS_NONE"] = 42;
        values[valuesById[0] = "COPY_FREE"] = 0;
        values[valuesById[2] = "COPY_ONCE"] = 2;
        values[valuesById[3] = "COPY_NEVER"] = 3;
        return values;
      }();
      OutputProtection.HdcpSrmRule = function() {
        const valuesById = {}, values = Object.create(valuesById);
        values[valuesById[0] = "HDCP_SRM_RULE_NONE"] = 0;
        values[valuesById[1] = "CURRENT_SRM"] = 1;
        return values;
      }();
      return OutputProtection;
    }();
    KeyContainer.VideoResolutionConstraint = function() {
      function VideoResolutionConstraint(p) {
        if (p) {
          for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
            if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
        }
      }
      VideoResolutionConstraint.prototype.minResolutionPixels = 0;
      VideoResolutionConstraint.prototype.maxResolutionPixels = 0;
      VideoResolutionConstraint.prototype.requiredProtection = null;
      VideoResolutionConstraint.create = function create(properties) {
        return new VideoResolutionConstraint(properties);
      };
      VideoResolutionConstraint.encode = function encode2(m, w) {
        if (!w) w = $Writer.create();
        if (m.minResolutionPixels != null && Object.hasOwnProperty.call(m, "minResolutionPixels"))
          w.uint32(8).uint32(m.minResolutionPixels);
        if (m.maxResolutionPixels != null && Object.hasOwnProperty.call(m, "maxResolutionPixels"))
          w.uint32(16).uint32(m.maxResolutionPixels);
        if (m.requiredProtection != null && Object.hasOwnProperty.call(m, "requiredProtection"))
          $root.License.KeyContainer.OutputProtection.encode(
            m.requiredProtection,
            w.uint32(26).fork()
          ).ldelim();
        return w;
      };
      VideoResolutionConstraint.encodeDelimited = function encodeDelimited(message, writer) {
        return this.encode(message, writer).ldelim();
      };
      VideoResolutionConstraint.decode = function decode2(r, l) {
        if (!(r instanceof $Reader)) r = $Reader.create(r);
        var c = l === void 0 ? r.len : r.pos + l, m = new $root.License.KeyContainer.VideoResolutionConstraint();
        while (r.pos < c) {
          var t = r.uint32();
          switch (t >>> 3) {
            case 1: {
              m.minResolutionPixels = r.uint32();
              break;
            }
            case 2: {
              m.maxResolutionPixels = r.uint32();
              break;
            }
            case 3: {
              m.requiredProtection = $root.License.KeyContainer.OutputProtection.decode(
                r,
                r.uint32()
              );
              break;
            }
            default:
              r.skipType(t & 7);
              break;
          }
        }
        return m;
      };
      VideoResolutionConstraint.decodeDelimited = function decodeDelimited(reader) {
        if (!(reader instanceof $Reader)) reader = new $Reader(reader);
        return this.decode(reader, reader.uint32());
      };
      VideoResolutionConstraint.fromObject = function fromObject(d) {
        if (d instanceof $root.License.KeyContainer.VideoResolutionConstraint)
          return d;
        var m = new $root.License.KeyContainer.VideoResolutionConstraint();
        if (d.minResolutionPixels != null) {
          m.minResolutionPixels = d.minResolutionPixels >>> 0;
        }
        if (d.maxResolutionPixels != null) {
          m.maxResolutionPixels = d.maxResolutionPixels >>> 0;
        }
        if (d.requiredProtection != null) {
          if (typeof d.requiredProtection !== "object")
            throw TypeError(
              ".License.KeyContainer.VideoResolutionConstraint.requiredProtection: object expected"
            );
          m.requiredProtection = $root.License.KeyContainer.OutputProtection.fromObject(
            d.requiredProtection
          );
        }
        return m;
      };
      VideoResolutionConstraint.toObject = function toObject(m, o) {
        if (!o) o = {};
        var d = {};
        if (o.defaults) {
          d.minResolutionPixels = 0;
          d.maxResolutionPixels = 0;
          d.requiredProtection = null;
        }
        if (m.minResolutionPixels != null && m.hasOwnProperty("minResolutionPixels")) {
          d.minResolutionPixels = m.minResolutionPixels;
        }
        if (m.maxResolutionPixels != null && m.hasOwnProperty("maxResolutionPixels")) {
          d.maxResolutionPixels = m.maxResolutionPixels;
        }
        if (m.requiredProtection != null && m.hasOwnProperty("requiredProtection")) {
          d.requiredProtection = $root.License.KeyContainer.OutputProtection.toObject(
            m.requiredProtection,
            o
          );
        }
        return d;
      };
      VideoResolutionConstraint.prototype.toJSON = function toJSON() {
        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
      };
      VideoResolutionConstraint.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
        if (typeUrlPrefix === void 0) {
          typeUrlPrefix = "type.googleapis.com";
        }
        return typeUrlPrefix + "/License.KeyContainer.VideoResolutionConstraint";
      };
      return VideoResolutionConstraint;
    }();
    KeyContainer.OperatorSessionKeyPermissions = function() {
      function OperatorSessionKeyPermissions(p) {
        if (p) {
          for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
            if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
        }
      }
      OperatorSessionKeyPermissions.prototype.allowEncrypt = false;
      OperatorSessionKeyPermissions.prototype.allowDecrypt = false;
      OperatorSessionKeyPermissions.prototype.allowSign = false;
      OperatorSessionKeyPermissions.prototype.allowSignatureVerify = false;
      OperatorSessionKeyPermissions.create = function create(properties) {
        return new OperatorSessionKeyPermissions(properties);
      };
      OperatorSessionKeyPermissions.encode = function encode2(m, w) {
        if (!w) w = $Writer.create();
        if (m.allowEncrypt != null && Object.hasOwnProperty.call(m, "allowEncrypt"))
          w.uint32(8).bool(m.allowEncrypt);
        if (m.allowDecrypt != null && Object.hasOwnProperty.call(m, "allowDecrypt"))
          w.uint32(16).bool(m.allowDecrypt);
        if (m.allowSign != null && Object.hasOwnProperty.call(m, "allowSign"))
          w.uint32(24).bool(m.allowSign);
        if (m.allowSignatureVerify != null && Object.hasOwnProperty.call(m, "allowSignatureVerify"))
          w.uint32(32).bool(m.allowSignatureVerify);
        return w;
      };
      OperatorSessionKeyPermissions.encodeDelimited = function encodeDelimited(message, writer) {
        return this.encode(message, writer).ldelim();
      };
      OperatorSessionKeyPermissions.decode = function decode2(r, l) {
        if (!(r instanceof $Reader)) r = $Reader.create(r);
        var c = l === void 0 ? r.len : r.pos + l, m = new $root.License.KeyContainer.OperatorSessionKeyPermissions();
        while (r.pos < c) {
          var t = r.uint32();
          switch (t >>> 3) {
            case 1: {
              m.allowEncrypt = r.bool();
              break;
            }
            case 2: {
              m.allowDecrypt = r.bool();
              break;
            }
            case 3: {
              m.allowSign = r.bool();
              break;
            }
            case 4: {
              m.allowSignatureVerify = r.bool();
              break;
            }
            default:
              r.skipType(t & 7);
              break;
          }
        }
        return m;
      };
      OperatorSessionKeyPermissions.decodeDelimited = function decodeDelimited(reader) {
        if (!(reader instanceof $Reader)) reader = new $Reader(reader);
        return this.decode(reader, reader.uint32());
      };
      OperatorSessionKeyPermissions.fromObject = function fromObject(d) {
        if (d instanceof $root.License.KeyContainer.OperatorSessionKeyPermissions)
          return d;
        var m = new $root.License.KeyContainer.OperatorSessionKeyPermissions();
        if (d.allowEncrypt != null) {
          m.allowEncrypt = Boolean(d.allowEncrypt);
        }
        if (d.allowDecrypt != null) {
          m.allowDecrypt = Boolean(d.allowDecrypt);
        }
        if (d.allowSign != null) {
          m.allowSign = Boolean(d.allowSign);
        }
        if (d.allowSignatureVerify != null) {
          m.allowSignatureVerify = Boolean(d.allowSignatureVerify);
        }
        return m;
      };
      OperatorSessionKeyPermissions.toObject = function toObject(m, o) {
        if (!o) o = {};
        var d = {};
        if (o.defaults) {
          d.allowEncrypt = false;
          d.allowDecrypt = false;
          d.allowSign = false;
          d.allowSignatureVerify = false;
        }
        if (m.allowEncrypt != null && m.hasOwnProperty("allowEncrypt")) {
          d.allowEncrypt = m.allowEncrypt;
        }
        if (m.allowDecrypt != null && m.hasOwnProperty("allowDecrypt")) {
          d.allowDecrypt = m.allowDecrypt;
        }
        if (m.allowSign != null && m.hasOwnProperty("allowSign")) {
          d.allowSign = m.allowSign;
        }
        if (m.allowSignatureVerify != null && m.hasOwnProperty("allowSignatureVerify")) {
          d.allowSignatureVerify = m.allowSignatureVerify;
        }
        return d;
      };
      OperatorSessionKeyPermissions.prototype.toJSON = function toJSON() {
        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
      };
      OperatorSessionKeyPermissions.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
        if (typeUrlPrefix === void 0) {
          typeUrlPrefix = "type.googleapis.com";
        }
        return typeUrlPrefix + "/License.KeyContainer.OperatorSessionKeyPermissions";
      };
      return OperatorSessionKeyPermissions;
    }();
    return KeyContainer;
  }();
  return License2;
})();
var ProtocolVersion = $root.ProtocolVersion = (() => {
  const valuesById = {}, values = Object.create(valuesById);
  values[valuesById[20] = "VERSION_2_0"] = 20;
  values[valuesById[21] = "VERSION_2_1"] = 21;
  values[valuesById[22] = "VERSION_2_2"] = 22;
  return values;
})();
var LicenseRequest = $root.LicenseRequest = (() => {
  function LicenseRequest2(p) {
    if (p) {
      for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
        if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
    }
  }
  LicenseRequest2.prototype.clientId = null;
  LicenseRequest2.prototype.contentId = null;
  LicenseRequest2.prototype.type = 1;
  LicenseRequest2.prototype.requestTime = $util.Long ? $util.Long.fromBits(0, 0, false) : 0;
  LicenseRequest2.prototype.keyControlNonceDeprecated = $util.newBuffer([]);
  LicenseRequest2.prototype.protocolVersion = 20;
  LicenseRequest2.prototype.keyControlNonce = 0;
  LicenseRequest2.prototype.encryptedClientId = null;
  LicenseRequest2.create = function create(properties) {
    return new LicenseRequest2(properties);
  };
  LicenseRequest2.encode = function encode2(m, w) {
    if (!w) w = $Writer.create();
    if (m.clientId != null && Object.hasOwnProperty.call(m, "clientId"))
      $root.ClientIdentification.encode(
        m.clientId,
        w.uint32(10).fork()
      ).ldelim();
    if (m.contentId != null && Object.hasOwnProperty.call(m, "contentId"))
      $root.LicenseRequest.ContentIdentification.encode(
        m.contentId,
        w.uint32(18).fork()
      ).ldelim();
    if (m.type != null && Object.hasOwnProperty.call(m, "type"))
      w.uint32(24).int32(m.type);
    if (m.requestTime != null && Object.hasOwnProperty.call(m, "requestTime"))
      w.uint32(32).int64(m.requestTime);
    if (m.keyControlNonceDeprecated != null && Object.hasOwnProperty.call(m, "keyControlNonceDeprecated"))
      w.uint32(42).bytes(m.keyControlNonceDeprecated);
    if (m.protocolVersion != null && Object.hasOwnProperty.call(m, "protocolVersion"))
      w.uint32(48).int32(m.protocolVersion);
    if (m.keyControlNonce != null && Object.hasOwnProperty.call(m, "keyControlNonce"))
      w.uint32(56).uint32(m.keyControlNonce);
    if (m.encryptedClientId != null && Object.hasOwnProperty.call(m, "encryptedClientId"))
      $root.EncryptedClientIdentification.encode(
        m.encryptedClientId,
        w.uint32(66).fork()
      ).ldelim();
    return w;
  };
  LicenseRequest2.encodeDelimited = function encodeDelimited(message, writer) {
    return this.encode(message, writer).ldelim();
  };
  LicenseRequest2.decode = function decode2(r, l) {
    if (!(r instanceof $Reader)) r = $Reader.create(r);
    var c = l === void 0 ? r.len : r.pos + l, m = new $root.LicenseRequest();
    while (r.pos < c) {
      var t = r.uint32();
      switch (t >>> 3) {
        case 1: {
          m.clientId = $root.ClientIdentification.decode(r, r.uint32());
          break;
        }
        case 2: {
          m.contentId = $root.LicenseRequest.ContentIdentification.decode(
            r,
            r.uint32()
          );
          break;
        }
        case 3: {
          m.type = r.int32();
          break;
        }
        case 4: {
          m.requestTime = r.int64();
          break;
        }
        case 5: {
          m.keyControlNonceDeprecated = r.bytes();
          break;
        }
        case 6: {
          m.protocolVersion = r.int32();
          break;
        }
        case 7: {
          m.keyControlNonce = r.uint32();
          break;
        }
        case 8: {
          m.encryptedClientId = $root.EncryptedClientIdentification.decode(
            r,
            r.uint32()
          );
          break;
        }
        default:
          r.skipType(t & 7);
          break;
      }
    }
    return m;
  };
  LicenseRequest2.decodeDelimited = function decodeDelimited(reader) {
    if (!(reader instanceof $Reader)) reader = new $Reader(reader);
    return this.decode(reader, reader.uint32());
  };
  LicenseRequest2.fromObject = function fromObject(d) {
    if (d instanceof $root.LicenseRequest) return d;
    var m = new $root.LicenseRequest();
    if (d.clientId != null) {
      if (typeof d.clientId !== "object")
        throw TypeError(".LicenseRequest.clientId: object expected");
      m.clientId = $root.ClientIdentification.fromObject(d.clientId);
    }
    if (d.contentId != null) {
      if (typeof d.contentId !== "object")
        throw TypeError(".LicenseRequest.contentId: object expected");
      m.contentId = $root.LicenseRequest.ContentIdentification.fromObject(
        d.contentId
      );
    }
    switch (d.type) {
      default:
        if (typeof d.type === "number") {
          m.type = d.type;
          break;
        }
        break;
      case "NEW":
      case 1:
        m.type = 1;
        break;
      case "RENEWAL":
      case 2:
        m.type = 2;
        break;
      case "RELEASE":
      case 3:
        m.type = 3;
        break;
    }
    if (d.requestTime != null) {
      if ($util.Long)
        (m.requestTime = $util.Long.fromValue(d.requestTime)).unsigned = false;
      else if (typeof d.requestTime === "string")
        m.requestTime = parseInt(d.requestTime, 10);
      else if (typeof d.requestTime === "number") m.requestTime = d.requestTime;
      else if (typeof d.requestTime === "object")
        m.requestTime = new $util.LongBits(
          d.requestTime.low >>> 0,
          d.requestTime.high >>> 0
        ).toNumber();
    }
    if (d.keyControlNonceDeprecated != null) {
      if (typeof d.keyControlNonceDeprecated === "string")
        $util.base64.decode(
          d.keyControlNonceDeprecated,
          m.keyControlNonceDeprecated = $util.newBuffer(
            $util.base64.length(d.keyControlNonceDeprecated)
          ),
          0
        );
      else if (d.keyControlNonceDeprecated.length >= 0)
        m.keyControlNonceDeprecated = d.keyControlNonceDeprecated;
    }
    switch (d.protocolVersion) {
      default:
        if (typeof d.protocolVersion === "number") {
          m.protocolVersion = d.protocolVersion;
          break;
        }
        break;
      case "VERSION_2_0":
      case 20:
        m.protocolVersion = 20;
        break;
      case "VERSION_2_1":
      case 21:
        m.protocolVersion = 21;
        break;
      case "VERSION_2_2":
      case 22:
        m.protocolVersion = 22;
        break;
    }
    if (d.keyControlNonce != null) {
      m.keyControlNonce = d.keyControlNonce >>> 0;
    }
    if (d.encryptedClientId != null) {
      if (typeof d.encryptedClientId !== "object")
        throw TypeError(".LicenseRequest.encryptedClientId: object expected");
      m.encryptedClientId = $root.EncryptedClientIdentification.fromObject(
        d.encryptedClientId
      );
    }
    return m;
  };
  LicenseRequest2.toObject = function toObject(m, o) {
    if (!o) o = {};
    var d = {};
    if (o.defaults) {
      d.clientId = null;
      d.contentId = null;
      d.type = o.enums === String ? "NEW" : 1;
      if ($util.Long) {
        var n = new $util.Long(0, 0, false);
        d.requestTime = o.longs === String ? n.toString() : o.longs === Number ? n.toNumber() : n;
      } else d.requestTime = o.longs === String ? "0" : 0;
      if (o.bytes === String) d.keyControlNonceDeprecated = "";
      else {
        d.keyControlNonceDeprecated = [];
        if (o.bytes !== Array)
          d.keyControlNonceDeprecated = $util.newBuffer(
            d.keyControlNonceDeprecated
          );
      }
      d.protocolVersion = o.enums === String ? "VERSION_2_0" : 20;
      d.keyControlNonce = 0;
      d.encryptedClientId = null;
    }
    if (m.clientId != null && m.hasOwnProperty("clientId")) {
      d.clientId = $root.ClientIdentification.toObject(m.clientId, o);
    }
    if (m.contentId != null && m.hasOwnProperty("contentId")) {
      d.contentId = $root.LicenseRequest.ContentIdentification.toObject(
        m.contentId,
        o
      );
    }
    if (m.type != null && m.hasOwnProperty("type")) {
      d.type = o.enums === String ? $root.LicenseRequest.RequestType[m.type] === void 0 ? m.type : $root.LicenseRequest.RequestType[m.type] : m.type;
    }
    if (m.requestTime != null && m.hasOwnProperty("requestTime")) {
      if (typeof m.requestTime === "number")
        d.requestTime = o.longs === String ? String(m.requestTime) : m.requestTime;
      else
        d.requestTime = o.longs === String ? $util.Long.prototype.toString.call(m.requestTime) : o.longs === Number ? new $util.LongBits(
          m.requestTime.low >>> 0,
          m.requestTime.high >>> 0
        ).toNumber() : m.requestTime;
    }
    if (m.keyControlNonceDeprecated != null && m.hasOwnProperty("keyControlNonceDeprecated")) {
      d.keyControlNonceDeprecated = o.bytes === String ? $util.base64.encode(
        m.keyControlNonceDeprecated,
        0,
        m.keyControlNonceDeprecated.length
      ) : o.bytes === Array ? Array.prototype.slice.call(m.keyControlNonceDeprecated) : m.keyControlNonceDeprecated;
    }
    if (m.protocolVersion != null && m.hasOwnProperty("protocolVersion")) {
      d.protocolVersion = o.enums === String ? $root.ProtocolVersion[m.protocolVersion] === void 0 ? m.protocolVersion : $root.ProtocolVersion[m.protocolVersion] : m.protocolVersion;
    }
    if (m.keyControlNonce != null && m.hasOwnProperty("keyControlNonce")) {
      d.keyControlNonce = m.keyControlNonce;
    }
    if (m.encryptedClientId != null && m.hasOwnProperty("encryptedClientId")) {
      d.encryptedClientId = $root.EncryptedClientIdentification.toObject(
        m.encryptedClientId,
        o
      );
    }
    return d;
  };
  LicenseRequest2.prototype.toJSON = function toJSON() {
    return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
  };
  LicenseRequest2.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
    if (typeUrlPrefix === void 0) {
      typeUrlPrefix = "type.googleapis.com";
    }
    return typeUrlPrefix + "/LicenseRequest";
  };
  LicenseRequest2.ContentIdentification = function() {
    function ContentIdentification(p) {
      if (p) {
        for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
          if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
      }
    }
    ContentIdentification.prototype.widevinePsshData = null;
    ContentIdentification.prototype.webmKeyId = null;
    ContentIdentification.prototype.existingLicense = null;
    ContentIdentification.prototype.initData = null;
    let $oneOfFields;
    Object.defineProperty(ContentIdentification.prototype, "contentIdVariant", {
      get: $util.oneOfGetter(
        $oneOfFields = [
          "widevinePsshData",
          "webmKeyId",
          "existingLicense",
          "initData"
        ]
      ),
      set: $util.oneOfSetter($oneOfFields)
    });
    ContentIdentification.create = function create(properties) {
      return new ContentIdentification(properties);
    };
    ContentIdentification.encode = function encode2(m, w) {
      if (!w) w = $Writer.create();
      if (m.widevinePsshData != null && Object.hasOwnProperty.call(m, "widevinePsshData"))
        $root.LicenseRequest.ContentIdentification.WidevinePsshData.encode(
          m.widevinePsshData,
          w.uint32(10).fork()
        ).ldelim();
      if (m.webmKeyId != null && Object.hasOwnProperty.call(m, "webmKeyId"))
        $root.LicenseRequest.ContentIdentification.WebmKeyId.encode(
          m.webmKeyId,
          w.uint32(18).fork()
        ).ldelim();
      if (m.existingLicense != null && Object.hasOwnProperty.call(m, "existingLicense"))
        $root.LicenseRequest.ContentIdentification.ExistingLicense.encode(
          m.existingLicense,
          w.uint32(26).fork()
        ).ldelim();
      if (m.initData != null && Object.hasOwnProperty.call(m, "initData"))
        $root.LicenseRequest.ContentIdentification.InitData.encode(
          m.initData,
          w.uint32(34).fork()
        ).ldelim();
      return w;
    };
    ContentIdentification.encodeDelimited = function encodeDelimited(message, writer) {
      return this.encode(message, writer).ldelim();
    };
    ContentIdentification.decode = function decode2(r, l) {
      if (!(r instanceof $Reader)) r = $Reader.create(r);
      var c = l === void 0 ? r.len : r.pos + l, m = new $root.LicenseRequest.ContentIdentification();
      while (r.pos < c) {
        var t = r.uint32();
        switch (t >>> 3) {
          case 1: {
            m.widevinePsshData = $root.LicenseRequest.ContentIdentification.WidevinePsshData.decode(
              r,
              r.uint32()
            );
            break;
          }
          case 2: {
            m.webmKeyId = $root.LicenseRequest.ContentIdentification.WebmKeyId.decode(
              r,
              r.uint32()
            );
            break;
          }
          case 3: {
            m.existingLicense = $root.LicenseRequest.ContentIdentification.ExistingLicense.decode(
              r,
              r.uint32()
            );
            break;
          }
          case 4: {
            m.initData = $root.LicenseRequest.ContentIdentification.InitData.decode(
              r,
              r.uint32()
            );
            break;
          }
          default:
            r.skipType(t & 7);
            break;
        }
      }
      return m;
    };
    ContentIdentification.decodeDelimited = function decodeDelimited(reader) {
      if (!(reader instanceof $Reader)) reader = new $Reader(reader);
      return this.decode(reader, reader.uint32());
    };
    ContentIdentification.fromObject = function fromObject(d) {
      if (d instanceof $root.LicenseRequest.ContentIdentification) return d;
      var m = new $root.LicenseRequest.ContentIdentification();
      if (d.widevinePsshData != null) {
        if (typeof d.widevinePsshData !== "object")
          throw TypeError(
            ".LicenseRequest.ContentIdentification.widevinePsshData: object expected"
          );
        m.widevinePsshData = $root.LicenseRequest.ContentIdentification.WidevinePsshData.fromObject(
          d.widevinePsshData
        );
      }
      if (d.webmKeyId != null) {
        if (typeof d.webmKeyId !== "object")
          throw TypeError(
            ".LicenseRequest.ContentIdentification.webmKeyId: object expected"
          );
        m.webmKeyId = $root.LicenseRequest.ContentIdentification.WebmKeyId.fromObject(
          d.webmKeyId
        );
      }
      if (d.existingLicense != null) {
        if (typeof d.existingLicense !== "object")
          throw TypeError(
            ".LicenseRequest.ContentIdentification.existingLicense: object expected"
          );
        m.existingLicense = $root.LicenseRequest.ContentIdentification.ExistingLicense.fromObject(
          d.existingLicense
        );
      }
      if (d.initData != null) {
        if (typeof d.initData !== "object")
          throw TypeError(
            ".LicenseRequest.ContentIdentification.initData: object expected"
          );
        m.initData = $root.LicenseRequest.ContentIdentification.InitData.fromObject(
          d.initData
        );
      }
      return m;
    };
    ContentIdentification.toObject = function toObject(m, o) {
      if (!o) o = {};
      var d = {};
      if (m.widevinePsshData != null && m.hasOwnProperty("widevinePsshData")) {
        d.widevinePsshData = $root.LicenseRequest.ContentIdentification.WidevinePsshData.toObject(
          m.widevinePsshData,
          o
        );
        if (o.oneofs) d.contentIdVariant = "widevinePsshData";
      }
      if (m.webmKeyId != null && m.hasOwnProperty("webmKeyId")) {
        d.webmKeyId = $root.LicenseRequest.ContentIdentification.WebmKeyId.toObject(
          m.webmKeyId,
          o
        );
        if (o.oneofs) d.contentIdVariant = "webmKeyId";
      }
      if (m.existingLicense != null && m.hasOwnProperty("existingLicense")) {
        d.existingLicense = $root.LicenseRequest.ContentIdentification.ExistingLicense.toObject(
          m.existingLicense,
          o
        );
        if (o.oneofs) d.contentIdVariant = "existingLicense";
      }
      if (m.initData != null && m.hasOwnProperty("initData")) {
        d.initData = $root.LicenseRequest.ContentIdentification.InitData.toObject(
          m.initData,
          o
        );
        if (o.oneofs) d.contentIdVariant = "initData";
      }
      return d;
    };
    ContentIdentification.prototype.toJSON = function toJSON() {
      return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
    };
    ContentIdentification.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
      if (typeUrlPrefix === void 0) {
        typeUrlPrefix = "type.googleapis.com";
      }
      return typeUrlPrefix + "/LicenseRequest.ContentIdentification";
    };
    ContentIdentification.WidevinePsshData = function() {
      function WidevinePsshData2(p) {
        this.psshData = [];
        if (p) {
          for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
            if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
        }
      }
      WidevinePsshData2.prototype.psshData = $util.emptyArray;
      WidevinePsshData2.prototype.licenseType = 1;
      WidevinePsshData2.prototype.requestId = $util.newBuffer([]);
      WidevinePsshData2.create = function create(properties) {
        return new WidevinePsshData2(properties);
      };
      WidevinePsshData2.encode = function encode2(m, w) {
        if (!w) w = $Writer.create();
        if (m.psshData != null && m.psshData.length) {
          for (var i = 0; i < m.psshData.length; ++i)
            w.uint32(10).bytes(m.psshData[i]);
        }
        if (m.licenseType != null && Object.hasOwnProperty.call(m, "licenseType"))
          w.uint32(16).int32(m.licenseType);
        if (m.requestId != null && Object.hasOwnProperty.call(m, "requestId"))
          w.uint32(26).bytes(m.requestId);
        return w;
      };
      WidevinePsshData2.encodeDelimited = function encodeDelimited(message, writer) {
        return this.encode(message, writer).ldelim();
      };
      WidevinePsshData2.decode = function decode2(r, l) {
        if (!(r instanceof $Reader)) r = $Reader.create(r);
        var c = l === void 0 ? r.len : r.pos + l, m = new $root.LicenseRequest.ContentIdentification.WidevinePsshData();
        while (r.pos < c) {
          var t = r.uint32();
          switch (t >>> 3) {
            case 1: {
              if (!(m.psshData && m.psshData.length)) m.psshData = [];
              m.psshData.push(r.bytes());
              break;
            }
            case 2: {
              m.licenseType = r.int32();
              break;
            }
            case 3: {
              m.requestId = r.bytes();
              break;
            }
            default:
              r.skipType(t & 7);
              break;
          }
        }
        return m;
      };
      WidevinePsshData2.decodeDelimited = function decodeDelimited(reader) {
        if (!(reader instanceof $Reader)) reader = new $Reader(reader);
        return this.decode(reader, reader.uint32());
      };
      WidevinePsshData2.fromObject = function fromObject(d) {
        if (d instanceof $root.LicenseRequest.ContentIdentification.WidevinePsshData)
          return d;
        var m = new $root.LicenseRequest.ContentIdentification.WidevinePsshData();
        if (d.psshData) {
          if (!Array.isArray(d.psshData))
            throw TypeError(
              ".LicenseRequest.ContentIdentification.WidevinePsshData.psshData: array expected"
            );
          m.psshData = [];
          for (var i = 0; i < d.psshData.length; ++i) {
            if (typeof d.psshData[i] === "string")
              $util.base64.decode(
                d.psshData[i],
                m.psshData[i] = $util.newBuffer(
                  $util.base64.length(d.psshData[i])
                ),
                0
              );
            else if (d.psshData[i].length >= 0) m.psshData[i] = d.psshData[i];
          }
        }
        switch (d.licenseType) {
          default:
            if (typeof d.licenseType === "number") {
              m.licenseType = d.licenseType;
              break;
            }
            break;
          case "STREAMING":
          case 1:
            m.licenseType = 1;
            break;
          case "OFFLINE":
          case 2:
            m.licenseType = 2;
            break;
          case "AUTOMATIC":
          case 3:
            m.licenseType = 3;
            break;
        }
        if (d.requestId != null) {
          if (typeof d.requestId === "string")
            $util.base64.decode(
              d.requestId,
              m.requestId = $util.newBuffer($util.base64.length(d.requestId)),
              0
            );
          else if (d.requestId.length >= 0) m.requestId = d.requestId;
        }
        return m;
      };
      WidevinePsshData2.toObject = function toObject(m, o) {
        if (!o) o = {};
        var d = {};
        if (o.arrays || o.defaults) {
          d.psshData = [];
        }
        if (o.defaults) {
          d.licenseType = o.enums === String ? "STREAMING" : 1;
          if (o.bytes === String) d.requestId = "";
          else {
            d.requestId = [];
            if (o.bytes !== Array) d.requestId = $util.newBuffer(d.requestId);
          }
        }
        if (m.psshData && m.psshData.length) {
          d.psshData = [];
          for (var j = 0; j < m.psshData.length; ++j) {
            d.psshData[j] = o.bytes === String ? $util.base64.encode(m.psshData[j], 0, m.psshData[j].length) : o.bytes === Array ? Array.prototype.slice.call(m.psshData[j]) : m.psshData[j];
          }
        }
        if (m.licenseType != null && m.hasOwnProperty("licenseType")) {
          d.licenseType = o.enums === String ? $root.LicenseType[m.licenseType] === void 0 ? m.licenseType : $root.LicenseType[m.licenseType] : m.licenseType;
        }
        if (m.requestId != null && m.hasOwnProperty("requestId")) {
          d.requestId = o.bytes === String ? $util.base64.encode(m.requestId, 0, m.requestId.length) : o.bytes === Array ? Array.prototype.slice.call(m.requestId) : m.requestId;
        }
        return d;
      };
      WidevinePsshData2.prototype.toJSON = function toJSON() {
        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
      };
      WidevinePsshData2.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
        if (typeUrlPrefix === void 0) {
          typeUrlPrefix = "type.googleapis.com";
        }
        return typeUrlPrefix + "/LicenseRequest.ContentIdentification.WidevinePsshData";
      };
      return WidevinePsshData2;
    }();
    ContentIdentification.WebmKeyId = function() {
      function WebmKeyId(p) {
        if (p) {
          for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
            if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
        }
      }
      WebmKeyId.prototype.header = $util.newBuffer([]);
      WebmKeyId.prototype.licenseType = 1;
      WebmKeyId.prototype.requestId = $util.newBuffer([]);
      WebmKeyId.create = function create(properties) {
        return new WebmKeyId(properties);
      };
      WebmKeyId.encode = function encode2(m, w) {
        if (!w) w = $Writer.create();
        if (m.header != null && Object.hasOwnProperty.call(m, "header"))
          w.uint32(10).bytes(m.header);
        if (m.licenseType != null && Object.hasOwnProperty.call(m, "licenseType"))
          w.uint32(16).int32(m.licenseType);
        if (m.requestId != null && Object.hasOwnProperty.call(m, "requestId"))
          w.uint32(26).bytes(m.requestId);
        return w;
      };
      WebmKeyId.encodeDelimited = function encodeDelimited(message, writer) {
        return this.encode(message, writer).ldelim();
      };
      WebmKeyId.decode = function decode2(r, l) {
        if (!(r instanceof $Reader)) r = $Reader.create(r);
        var c = l === void 0 ? r.len : r.pos + l, m = new $root.LicenseRequest.ContentIdentification.WebmKeyId();
        while (r.pos < c) {
          var t = r.uint32();
          switch (t >>> 3) {
            case 1: {
              m.header = r.bytes();
              break;
            }
            case 2: {
              m.licenseType = r.int32();
              break;
            }
            case 3: {
              m.requestId = r.bytes();
              break;
            }
            default:
              r.skipType(t & 7);
              break;
          }
        }
        return m;
      };
      WebmKeyId.decodeDelimited = function decodeDelimited(reader) {
        if (!(reader instanceof $Reader)) reader = new $Reader(reader);
        return this.decode(reader, reader.uint32());
      };
      WebmKeyId.fromObject = function fromObject(d) {
        if (d instanceof $root.LicenseRequest.ContentIdentification.WebmKeyId)
          return d;
        var m = new $root.LicenseRequest.ContentIdentification.WebmKeyId();
        if (d.header != null) {
          if (typeof d.header === "string")
            $util.base64.decode(
              d.header,
              m.header = $util.newBuffer($util.base64.length(d.header)),
              0
            );
          else if (d.header.length >= 0) m.header = d.header;
        }
        switch (d.licenseType) {
          default:
            if (typeof d.licenseType === "number") {
              m.licenseType = d.licenseType;
              break;
            }
            break;
          case "STREAMING":
          case 1:
            m.licenseType = 1;
            break;
          case "OFFLINE":
          case 2:
            m.licenseType = 2;
            break;
          case "AUTOMATIC":
          case 3:
            m.licenseType = 3;
            break;
        }
        if (d.requestId != null) {
          if (typeof d.requestId === "string")
            $util.base64.decode(
              d.requestId,
              m.requestId = $util.newBuffer($util.base64.length(d.requestId)),
              0
            );
          else if (d.requestId.length >= 0) m.requestId = d.requestId;
        }
        return m;
      };
      WebmKeyId.toObject = function toObject(m, o) {
        if (!o) o = {};
        var d = {};
        if (o.defaults) {
          if (o.bytes === String) d.header = "";
          else {
            d.header = [];
            if (o.bytes !== Array) d.header = $util.newBuffer(d.header);
          }
          d.licenseType = o.enums === String ? "STREAMING" : 1;
          if (o.bytes === String) d.requestId = "";
          else {
            d.requestId = [];
            if (o.bytes !== Array) d.requestId = $util.newBuffer(d.requestId);
          }
        }
        if (m.header != null && m.hasOwnProperty("header")) {
          d.header = o.bytes === String ? $util.base64.encode(m.header, 0, m.header.length) : o.bytes === Array ? Array.prototype.slice.call(m.header) : m.header;
        }
        if (m.licenseType != null && m.hasOwnProperty("licenseType")) {
          d.licenseType = o.enums === String ? $root.LicenseType[m.licenseType] === void 0 ? m.licenseType : $root.LicenseType[m.licenseType] : m.licenseType;
        }
        if (m.requestId != null && m.hasOwnProperty("requestId")) {
          d.requestId = o.bytes === String ? $util.base64.encode(m.requestId, 0, m.requestId.length) : o.bytes === Array ? Array.prototype.slice.call(m.requestId) : m.requestId;
        }
        return d;
      };
      WebmKeyId.prototype.toJSON = function toJSON() {
        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
      };
      WebmKeyId.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
        if (typeUrlPrefix === void 0) {
          typeUrlPrefix = "type.googleapis.com";
        }
        return typeUrlPrefix + "/LicenseRequest.ContentIdentification.WebmKeyId";
      };
      return WebmKeyId;
    }();
    ContentIdentification.ExistingLicense = function() {
      function ExistingLicense(p) {
        if (p) {
          for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
            if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
        }
      }
      ExistingLicense.prototype.licenseId = null;
      ExistingLicense.prototype.secondsSinceStarted = $util.Long ? $util.Long.fromBits(0, 0, false) : 0;
      ExistingLicense.prototype.secondsSinceLastPlayed = $util.Long ? $util.Long.fromBits(0, 0, false) : 0;
      ExistingLicense.prototype.sessionUsageTableEntry = $util.newBuffer([]);
      ExistingLicense.create = function create(properties) {
        return new ExistingLicense(properties);
      };
      ExistingLicense.encode = function encode2(m, w) {
        if (!w) w = $Writer.create();
        if (m.licenseId != null && Object.hasOwnProperty.call(m, "licenseId"))
          $root.LicenseIdentification.encode(
            m.licenseId,
            w.uint32(10).fork()
          ).ldelim();
        if (m.secondsSinceStarted != null && Object.hasOwnProperty.call(m, "secondsSinceStarted"))
          w.uint32(16).int64(m.secondsSinceStarted);
        if (m.secondsSinceLastPlayed != null && Object.hasOwnProperty.call(m, "secondsSinceLastPlayed"))
          w.uint32(24).int64(m.secondsSinceLastPlayed);
        if (m.sessionUsageTableEntry != null && Object.hasOwnProperty.call(m, "sessionUsageTableEntry"))
          w.uint32(34).bytes(m.sessionUsageTableEntry);
        return w;
      };
      ExistingLicense.encodeDelimited = function encodeDelimited(message, writer) {
        return this.encode(message, writer).ldelim();
      };
      ExistingLicense.decode = function decode2(r, l) {
        if (!(r instanceof $Reader)) r = $Reader.create(r);
        var c = l === void 0 ? r.len : r.pos + l, m = new $root.LicenseRequest.ContentIdentification.ExistingLicense();
        while (r.pos < c) {
          var t = r.uint32();
          switch (t >>> 3) {
            case 1: {
              m.licenseId = $root.LicenseIdentification.decode(r, r.uint32());
              break;
            }
            case 2: {
              m.secondsSinceStarted = r.int64();
              break;
            }
            case 3: {
              m.secondsSinceLastPlayed = r.int64();
              break;
            }
            case 4: {
              m.sessionUsageTableEntry = r.bytes();
              break;
            }
            default:
              r.skipType(t & 7);
              break;
          }
        }
        return m;
      };
      ExistingLicense.decodeDelimited = function decodeDelimited(reader) {
        if (!(reader instanceof $Reader)) reader = new $Reader(reader);
        return this.decode(reader, reader.uint32());
      };
      ExistingLicense.fromObject = function fromObject(d) {
        if (d instanceof $root.LicenseRequest.ContentIdentification.ExistingLicense)
          return d;
        var m = new $root.LicenseRequest.ContentIdentification.ExistingLicense();
        if (d.licenseId != null) {
          if (typeof d.licenseId !== "object")
            throw TypeError(
              ".LicenseRequest.ContentIdentification.ExistingLicense.licenseId: object expected"
            );
          m.licenseId = $root.LicenseIdentification.fromObject(d.licenseId);
        }
        if (d.secondsSinceStarted != null) {
          if ($util.Long)
            (m.secondsSinceStarted = $util.Long.fromValue(
              d.secondsSinceStarted
            )).unsigned = false;
          else if (typeof d.secondsSinceStarted === "string")
            m.secondsSinceStarted = parseInt(d.secondsSinceStarted, 10);
          else if (typeof d.secondsSinceStarted === "number")
            m.secondsSinceStarted = d.secondsSinceStarted;
          else if (typeof d.secondsSinceStarted === "object")
            m.secondsSinceStarted = new $util.LongBits(
              d.secondsSinceStarted.low >>> 0,
              d.secondsSinceStarted.high >>> 0
            ).toNumber();
        }
        if (d.secondsSinceLastPlayed != null) {
          if ($util.Long)
            (m.secondsSinceLastPlayed = $util.Long.fromValue(
              d.secondsSinceLastPlayed
            )).unsigned = false;
          else if (typeof d.secondsSinceLastPlayed === "string")
            m.secondsSinceLastPlayed = parseInt(d.secondsSinceLastPlayed, 10);
          else if (typeof d.secondsSinceLastPlayed === "number")
            m.secondsSinceLastPlayed = d.secondsSinceLastPlayed;
          else if (typeof d.secondsSinceLastPlayed === "object")
            m.secondsSinceLastPlayed = new $util.LongBits(
              d.secondsSinceLastPlayed.low >>> 0,
              d.secondsSinceLastPlayed.high >>> 0
            ).toNumber();
        }
        if (d.sessionUsageTableEntry != null) {
          if (typeof d.sessionUsageTableEntry === "string")
            $util.base64.decode(
              d.sessionUsageTableEntry,
              m.sessionUsageTableEntry = $util.newBuffer(
                $util.base64.length(d.sessionUsageTableEntry)
              ),
              0
            );
          else if (d.sessionUsageTableEntry.length >= 0)
            m.sessionUsageTableEntry = d.sessionUsageTableEntry;
        }
        return m;
      };
      ExistingLicense.toObject = function toObject(m, o) {
        if (!o) o = {};
        var d = {};
        if (o.defaults) {
          d.licenseId = null;
          if ($util.Long) {
            var n = new $util.Long(0, 0, false);
            d.secondsSinceStarted = o.longs === String ? n.toString() : o.longs === Number ? n.toNumber() : n;
          } else d.secondsSinceStarted = o.longs === String ? "0" : 0;
          if ($util.Long) {
            var n = new $util.Long(0, 0, false);
            d.secondsSinceLastPlayed = o.longs === String ? n.toString() : o.longs === Number ? n.toNumber() : n;
          } else d.secondsSinceLastPlayed = o.longs === String ? "0" : 0;
          if (o.bytes === String) d.sessionUsageTableEntry = "";
          else {
            d.sessionUsageTableEntry = [];
            if (o.bytes !== Array)
              d.sessionUsageTableEntry = $util.newBuffer(
                d.sessionUsageTableEntry
              );
          }
        }
        if (m.licenseId != null && m.hasOwnProperty("licenseId")) {
          d.licenseId = $root.LicenseIdentification.toObject(m.licenseId, o);
        }
        if (m.secondsSinceStarted != null && m.hasOwnProperty("secondsSinceStarted")) {
          if (typeof m.secondsSinceStarted === "number")
            d.secondsSinceStarted = o.longs === String ? String(m.secondsSinceStarted) : m.secondsSinceStarted;
          else
            d.secondsSinceStarted = o.longs === String ? $util.Long.prototype.toString.call(m.secondsSinceStarted) : o.longs === Number ? new $util.LongBits(
              m.secondsSinceStarted.low >>> 0,
              m.secondsSinceStarted.high >>> 0
            ).toNumber() : m.secondsSinceStarted;
        }
        if (m.secondsSinceLastPlayed != null && m.hasOwnProperty("secondsSinceLastPlayed")) {
          if (typeof m.secondsSinceLastPlayed === "number")
            d.secondsSinceLastPlayed = o.longs === String ? String(m.secondsSinceLastPlayed) : m.secondsSinceLastPlayed;
          else
            d.secondsSinceLastPlayed = o.longs === String ? $util.Long.prototype.toString.call(m.secondsSinceLastPlayed) : o.longs === Number ? new $util.LongBits(
              m.secondsSinceLastPlayed.low >>> 0,
              m.secondsSinceLastPlayed.high >>> 0
            ).toNumber() : m.secondsSinceLastPlayed;
        }
        if (m.sessionUsageTableEntry != null && m.hasOwnProperty("sessionUsageTableEntry")) {
          d.sessionUsageTableEntry = o.bytes === String ? $util.base64.encode(
            m.sessionUsageTableEntry,
            0,
            m.sessionUsageTableEntry.length
          ) : o.bytes === Array ? Array.prototype.slice.call(m.sessionUsageTableEntry) : m.sessionUsageTableEntry;
        }
        return d;
      };
      ExistingLicense.prototype.toJSON = function toJSON() {
        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
      };
      ExistingLicense.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
        if (typeUrlPrefix === void 0) {
          typeUrlPrefix = "type.googleapis.com";
        }
        return typeUrlPrefix + "/LicenseRequest.ContentIdentification.ExistingLicense";
      };
      return ExistingLicense;
    }();
    ContentIdentification.InitData = function() {
      function InitData(p) {
        if (p) {
          for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
            if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
        }
      }
      InitData.prototype.initDataType = 1;
      InitData.prototype.initData = $util.newBuffer([]);
      InitData.prototype.licenseType = 1;
      InitData.prototype.requestId = $util.newBuffer([]);
      InitData.create = function create(properties) {
        return new InitData(properties);
      };
      InitData.encode = function encode2(m, w) {
        if (!w) w = $Writer.create();
        if (m.initDataType != null && Object.hasOwnProperty.call(m, "initDataType"))
          w.uint32(8).int32(m.initDataType);
        if (m.initData != null && Object.hasOwnProperty.call(m, "initData"))
          w.uint32(18).bytes(m.initData);
        if (m.licenseType != null && Object.hasOwnProperty.call(m, "licenseType"))
          w.uint32(24).int32(m.licenseType);
        if (m.requestId != null && Object.hasOwnProperty.call(m, "requestId"))
          w.uint32(34).bytes(m.requestId);
        return w;
      };
      InitData.encodeDelimited = function encodeDelimited(message, writer) {
        return this.encode(message, writer).ldelim();
      };
      InitData.decode = function decode2(r, l) {
        if (!(r instanceof $Reader)) r = $Reader.create(r);
        var c = l === void 0 ? r.len : r.pos + l, m = new $root.LicenseRequest.ContentIdentification.InitData();
        while (r.pos < c) {
          var t = r.uint32();
          switch (t >>> 3) {
            case 1: {
              m.initDataType = r.int32();
              break;
            }
            case 2: {
              m.initData = r.bytes();
              break;
            }
            case 3: {
              m.licenseType = r.int32();
              break;
            }
            case 4: {
              m.requestId = r.bytes();
              break;
            }
            default:
              r.skipType(t & 7);
              break;
          }
        }
        return m;
      };
      InitData.decodeDelimited = function decodeDelimited(reader) {
        if (!(reader instanceof $Reader)) reader = new $Reader(reader);
        return this.decode(reader, reader.uint32());
      };
      InitData.fromObject = function fromObject(d) {
        if (d instanceof $root.LicenseRequest.ContentIdentification.InitData)
          return d;
        var m = new $root.LicenseRequest.ContentIdentification.InitData();
        switch (d.initDataType) {
          default:
            if (typeof d.initDataType === "number") {
              m.initDataType = d.initDataType;
              break;
            }
            break;
          case "CENC":
          case 1:
            m.initDataType = 1;
            break;
          case "WEBM":
          case 2:
            m.initDataType = 2;
            break;
        }
        if (d.initData != null) {
          if (typeof d.initData === "string")
            $util.base64.decode(
              d.initData,
              m.initData = $util.newBuffer($util.base64.length(d.initData)),
              0
            );
          else if (d.initData.length >= 0) m.initData = d.initData;
        }
        switch (d.licenseType) {
          default:
            if (typeof d.licenseType === "number") {
              m.licenseType = d.licenseType;
              break;
            }
            break;
          case "STREAMING":
          case 1:
            m.licenseType = 1;
            break;
          case "OFFLINE":
          case 2:
            m.licenseType = 2;
            break;
          case "AUTOMATIC":
          case 3:
            m.licenseType = 3;
            break;
        }
        if (d.requestId != null) {
          if (typeof d.requestId === "string")
            $util.base64.decode(
              d.requestId,
              m.requestId = $util.newBuffer($util.base64.length(d.requestId)),
              0
            );
          else if (d.requestId.length >= 0) m.requestId = d.requestId;
        }
        return m;
      };
      InitData.toObject = function toObject(m, o) {
        if (!o) o = {};
        var d = {};
        if (o.defaults) {
          d.initDataType = o.enums === String ? "CENC" : 1;
          if (o.bytes === String) d.initData = "";
          else {
            d.initData = [];
            if (o.bytes !== Array) d.initData = $util.newBuffer(d.initData);
          }
          d.licenseType = o.enums === String ? "STREAMING" : 1;
          if (o.bytes === String) d.requestId = "";
          else {
            d.requestId = [];
            if (o.bytes !== Array) d.requestId = $util.newBuffer(d.requestId);
          }
        }
        if (m.initDataType != null && m.hasOwnProperty("initDataType")) {
          d.initDataType = o.enums === String ? $root.LicenseRequest.ContentIdentification.InitData.InitDataType[m.initDataType] === void 0 ? m.initDataType : $root.LicenseRequest.ContentIdentification.InitData.InitDataType[m.initDataType] : m.initDataType;
        }
        if (m.initData != null && m.hasOwnProperty("initData")) {
          d.initData = o.bytes === String ? $util.base64.encode(m.initData, 0, m.initData.length) : o.bytes === Array ? Array.prototype.slice.call(m.initData) : m.initData;
        }
        if (m.licenseType != null && m.hasOwnProperty("licenseType")) {
          d.licenseType = o.enums === String ? $root.LicenseType[m.licenseType] === void 0 ? m.licenseType : $root.LicenseType[m.licenseType] : m.licenseType;
        }
        if (m.requestId != null && m.hasOwnProperty("requestId")) {
          d.requestId = o.bytes === String ? $util.base64.encode(m.requestId, 0, m.requestId.length) : o.bytes === Array ? Array.prototype.slice.call(m.requestId) : m.requestId;
        }
        return d;
      };
      InitData.prototype.toJSON = function toJSON() {
        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
      };
      InitData.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
        if (typeUrlPrefix === void 0) {
          typeUrlPrefix = "type.googleapis.com";
        }
        return typeUrlPrefix + "/LicenseRequest.ContentIdentification.InitData";
      };
      InitData.InitDataType = function() {
        const valuesById = {}, values = Object.create(valuesById);
        values[valuesById[1] = "CENC"] = 1;
        values[valuesById[2] = "WEBM"] = 2;
        return values;
      }();
      return InitData;
    }();
    return ContentIdentification;
  }();
  LicenseRequest2.RequestType = function() {
    const valuesById = {}, values = Object.create(valuesById);
    values[valuesById[1] = "NEW"] = 1;
    values[valuesById[2] = "RENEWAL"] = 2;
    values[valuesById[3] = "RELEASE"] = 3;
    return values;
  }();
  return LicenseRequest2;
})();
var MetricData = $root.MetricData = (() => {
  function MetricData2(p) {
    this.metricData = [];
    if (p) {
      for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
        if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
    }
  }
  MetricData2.prototype.stageName = "";
  MetricData2.prototype.metricData = $util.emptyArray;
  MetricData2.create = function create(properties) {
    return new MetricData2(properties);
  };
  MetricData2.encode = function encode2(m, w) {
    if (!w) w = $Writer.create();
    if (m.stageName != null && Object.hasOwnProperty.call(m, "stageName"))
      w.uint32(10).string(m.stageName);
    if (m.metricData != null && m.metricData.length) {
      for (var i = 0; i < m.metricData.length; ++i)
        $root.MetricData.TypeValue.encode(
          m.metricData[i],
          w.uint32(18).fork()
        ).ldelim();
    }
    return w;
  };
  MetricData2.encodeDelimited = function encodeDelimited(message, writer) {
    return this.encode(message, writer).ldelim();
  };
  MetricData2.decode = function decode2(r, l) {
    if (!(r instanceof $Reader)) r = $Reader.create(r);
    var c = l === void 0 ? r.len : r.pos + l, m = new $root.MetricData();
    while (r.pos < c) {
      var t = r.uint32();
      switch (t >>> 3) {
        case 1: {
          m.stageName = r.string();
          break;
        }
        case 2: {
          if (!(m.metricData && m.metricData.length)) m.metricData = [];
          m.metricData.push($root.MetricData.TypeValue.decode(r, r.uint32()));
          break;
        }
        default:
          r.skipType(t & 7);
          break;
      }
    }
    return m;
  };
  MetricData2.decodeDelimited = function decodeDelimited(reader) {
    if (!(reader instanceof $Reader)) reader = new $Reader(reader);
    return this.decode(reader, reader.uint32());
  };
  MetricData2.fromObject = function fromObject(d) {
    if (d instanceof $root.MetricData) return d;
    var m = new $root.MetricData();
    if (d.stageName != null) {
      m.stageName = String(d.stageName);
    }
    if (d.metricData) {
      if (!Array.isArray(d.metricData))
        throw TypeError(".MetricData.metricData: array expected");
      m.metricData = [];
      for (var i = 0; i < d.metricData.length; ++i) {
        if (typeof d.metricData[i] !== "object")
          throw TypeError(".MetricData.metricData: object expected");
        m.metricData[i] = $root.MetricData.TypeValue.fromObject(
          d.metricData[i]
        );
      }
    }
    return m;
  };
  MetricData2.toObject = function toObject(m, o) {
    if (!o) o = {};
    var d = {};
    if (o.arrays || o.defaults) {
      d.metricData = [];
    }
    if (o.defaults) {
      d.stageName = "";
    }
    if (m.stageName != null && m.hasOwnProperty("stageName")) {
      d.stageName = m.stageName;
    }
    if (m.metricData && m.metricData.length) {
      d.metricData = [];
      for (var j = 0; j < m.metricData.length; ++j) {
        d.metricData[j] = $root.MetricData.TypeValue.toObject(
          m.metricData[j],
          o
        );
      }
    }
    return d;
  };
  MetricData2.prototype.toJSON = function toJSON() {
    return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
  };
  MetricData2.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
    if (typeUrlPrefix === void 0) {
      typeUrlPrefix = "type.googleapis.com";
    }
    return typeUrlPrefix + "/MetricData";
  };
  MetricData2.MetricType = function() {
    const valuesById = {}, values = Object.create(valuesById);
    values[valuesById[1] = "LATENCY"] = 1;
    values[valuesById[2] = "TIMESTAMP"] = 2;
    return values;
  }();
  MetricData2.TypeValue = function() {
    function TypeValue(p) {
      if (p) {
        for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
          if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
      }
    }
    TypeValue.prototype.type = 1;
    TypeValue.prototype.value = $util.Long ? $util.Long.fromBits(0, 0, false) : 0;
    TypeValue.create = function create(properties) {
      return new TypeValue(properties);
    };
    TypeValue.encode = function encode2(m, w) {
      if (!w) w = $Writer.create();
      if (m.type != null && Object.hasOwnProperty.call(m, "type"))
        w.uint32(8).int32(m.type);
      if (m.value != null && Object.hasOwnProperty.call(m, "value"))
        w.uint32(16).int64(m.value);
      return w;
    };
    TypeValue.encodeDelimited = function encodeDelimited(message, writer) {
      return this.encode(message, writer).ldelim();
    };
    TypeValue.decode = function decode2(r, l) {
      if (!(r instanceof $Reader)) r = $Reader.create(r);
      var c = l === void 0 ? r.len : r.pos + l, m = new $root.MetricData.TypeValue();
      while (r.pos < c) {
        var t = r.uint32();
        switch (t >>> 3) {
          case 1: {
            m.type = r.int32();
            break;
          }
          case 2: {
            m.value = r.int64();
            break;
          }
          default:
            r.skipType(t & 7);
            break;
        }
      }
      return m;
    };
    TypeValue.decodeDelimited = function decodeDelimited(reader) {
      if (!(reader instanceof $Reader)) reader = new $Reader(reader);
      return this.decode(reader, reader.uint32());
    };
    TypeValue.fromObject = function fromObject(d) {
      if (d instanceof $root.MetricData.TypeValue) return d;
      var m = new $root.MetricData.TypeValue();
      switch (d.type) {
        default:
          if (typeof d.type === "number") {
            m.type = d.type;
            break;
          }
          break;
        case "LATENCY":
        case 1:
          m.type = 1;
          break;
        case "TIMESTAMP":
        case 2:
          m.type = 2;
          break;
      }
      if (d.value != null) {
        if ($util.Long)
          (m.value = $util.Long.fromValue(d.value)).unsigned = false;
        else if (typeof d.value === "string") m.value = parseInt(d.value, 10);
        else if (typeof d.value === "number") m.value = d.value;
        else if (typeof d.value === "object")
          m.value = new $util.LongBits(
            d.value.low >>> 0,
            d.value.high >>> 0
          ).toNumber();
      }
      return m;
    };
    TypeValue.toObject = function toObject(m, o) {
      if (!o) o = {};
      var d = {};
      if (o.defaults) {
        d.type = o.enums === String ? "LATENCY" : 1;
        if ($util.Long) {
          var n = new $util.Long(0, 0, false);
          d.value = o.longs === String ? n.toString() : o.longs === Number ? n.toNumber() : n;
        } else d.value = o.longs === String ? "0" : 0;
      }
      if (m.type != null && m.hasOwnProperty("type")) {
        d.type = o.enums === String ? $root.MetricData.MetricType[m.type] === void 0 ? m.type : $root.MetricData.MetricType[m.type] : m.type;
      }
      if (m.value != null && m.hasOwnProperty("value")) {
        if (typeof m.value === "number")
          d.value = o.longs === String ? String(m.value) : m.value;
        else
          d.value = o.longs === String ? $util.Long.prototype.toString.call(m.value) : o.longs === Number ? new $util.LongBits(
            m.value.low >>> 0,
            m.value.high >>> 0
          ).toNumber() : m.value;
      }
      return d;
    };
    TypeValue.prototype.toJSON = function toJSON() {
      return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
    };
    TypeValue.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
      if (typeUrlPrefix === void 0) {
        typeUrlPrefix = "type.googleapis.com";
      }
      return typeUrlPrefix + "/MetricData.TypeValue";
    };
    return TypeValue;
  }();
  return MetricData2;
})();
var VersionInfo = $root.VersionInfo = (() => {
  function VersionInfo2(p) {
    if (p) {
      for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
        if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
    }
  }
  VersionInfo2.prototype.licenseSdkVersion = "";
  VersionInfo2.prototype.licenseServiceVersion = "";
  VersionInfo2.create = function create(properties) {
    return new VersionInfo2(properties);
  };
  VersionInfo2.encode = function encode2(m, w) {
    if (!w) w = $Writer.create();
    if (m.licenseSdkVersion != null && Object.hasOwnProperty.call(m, "licenseSdkVersion"))
      w.uint32(10).string(m.licenseSdkVersion);
    if (m.licenseServiceVersion != null && Object.hasOwnProperty.call(m, "licenseServiceVersion"))
      w.uint32(18).string(m.licenseServiceVersion);
    return w;
  };
  VersionInfo2.encodeDelimited = function encodeDelimited(message, writer) {
    return this.encode(message, writer).ldelim();
  };
  VersionInfo2.decode = function decode2(r, l) {
    if (!(r instanceof $Reader)) r = $Reader.create(r);
    var c = l === void 0 ? r.len : r.pos + l, m = new $root.VersionInfo();
    while (r.pos < c) {
      var t = r.uint32();
      switch (t >>> 3) {
        case 1: {
          m.licenseSdkVersion = r.string();
          break;
        }
        case 2: {
          m.licenseServiceVersion = r.string();
          break;
        }
        default:
          r.skipType(t & 7);
          break;
      }
    }
    return m;
  };
  VersionInfo2.decodeDelimited = function decodeDelimited(reader) {
    if (!(reader instanceof $Reader)) reader = new $Reader(reader);
    return this.decode(reader, reader.uint32());
  };
  VersionInfo2.fromObject = function fromObject(d) {
    if (d instanceof $root.VersionInfo) return d;
    var m = new $root.VersionInfo();
    if (d.licenseSdkVersion != null) {
      m.licenseSdkVersion = String(d.licenseSdkVersion);
    }
    if (d.licenseServiceVersion != null) {
      m.licenseServiceVersion = String(d.licenseServiceVersion);
    }
    return m;
  };
  VersionInfo2.toObject = function toObject(m, o) {
    if (!o) o = {};
    var d = {};
    if (o.defaults) {
      d.licenseSdkVersion = "";
      d.licenseServiceVersion = "";
    }
    if (m.licenseSdkVersion != null && m.hasOwnProperty("licenseSdkVersion")) {
      d.licenseSdkVersion = m.licenseSdkVersion;
    }
    if (m.licenseServiceVersion != null && m.hasOwnProperty("licenseServiceVersion")) {
      d.licenseServiceVersion = m.licenseServiceVersion;
    }
    return d;
  };
  VersionInfo2.prototype.toJSON = function toJSON() {
    return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
  };
  VersionInfo2.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
    if (typeUrlPrefix === void 0) {
      typeUrlPrefix = "type.googleapis.com";
    }
    return typeUrlPrefix + "/VersionInfo";
  };
  return VersionInfo2;
})();
var SignedMessage = $root.SignedMessage = (() => {
  function SignedMessage2(p) {
    this.metricData = [];
    if (p) {
      for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
        if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
    }
  }
  SignedMessage2.prototype.type = 1;
  SignedMessage2.prototype.msg = $util.newBuffer([]);
  SignedMessage2.prototype.signature = $util.newBuffer([]);
  SignedMessage2.prototype.sessionKey = $util.newBuffer([]);
  SignedMessage2.prototype.remoteAttestation = $util.newBuffer([]);
  SignedMessage2.prototype.metricData = $util.emptyArray;
  SignedMessage2.prototype.serviceVersionInfo = null;
  SignedMessage2.prototype.sessionKeyType = 1;
  SignedMessage2.prototype.oemcryptoCoreMessage = $util.newBuffer([]);
  SignedMessage2.create = function create(properties) {
    return new SignedMessage2(properties);
  };
  SignedMessage2.encode = function encode2(m, w) {
    if (!w) w = $Writer.create();
    if (m.type != null && Object.hasOwnProperty.call(m, "type"))
      w.uint32(8).int32(m.type);
    if (m.msg != null && Object.hasOwnProperty.call(m, "msg"))
      w.uint32(18).bytes(m.msg);
    if (m.signature != null && Object.hasOwnProperty.call(m, "signature"))
      w.uint32(26).bytes(m.signature);
    if (m.sessionKey != null && Object.hasOwnProperty.call(m, "sessionKey"))
      w.uint32(34).bytes(m.sessionKey);
    if (m.remoteAttestation != null && Object.hasOwnProperty.call(m, "remoteAttestation"))
      w.uint32(42).bytes(m.remoteAttestation);
    if (m.metricData != null && m.metricData.length) {
      for (var i = 0; i < m.metricData.length; ++i)
        $root.MetricData.encode(m.metricData[i], w.uint32(50).fork()).ldelim();
    }
    if (m.serviceVersionInfo != null && Object.hasOwnProperty.call(m, "serviceVersionInfo"))
      $root.VersionInfo.encode(
        m.serviceVersionInfo,
        w.uint32(58).fork()
      ).ldelim();
    if (m.sessionKeyType != null && Object.hasOwnProperty.call(m, "sessionKeyType"))
      w.uint32(64).int32(m.sessionKeyType);
    if (m.oemcryptoCoreMessage != null && Object.hasOwnProperty.call(m, "oemcryptoCoreMessage"))
      w.uint32(74).bytes(m.oemcryptoCoreMessage);
    return w;
  };
  SignedMessage2.encodeDelimited = function encodeDelimited(message, writer) {
    return this.encode(message, writer).ldelim();
  };
  SignedMessage2.decode = function decode2(r, l) {
    if (!(r instanceof $Reader)) r = $Reader.create(r);
    var c = l === void 0 ? r.len : r.pos + l, m = new $root.SignedMessage();
    while (r.pos < c) {
      var t = r.uint32();
      switch (t >>> 3) {
        case 1: {
          m.type = r.int32();
          break;
        }
        case 2: {
          m.msg = r.bytes();
          break;
        }
        case 3: {
          m.signature = r.bytes();
          break;
        }
        case 4: {
          m.sessionKey = r.bytes();
          break;
        }
        case 5: {
          m.remoteAttestation = r.bytes();
          break;
        }
        case 6: {
          if (!(m.metricData && m.metricData.length)) m.metricData = [];
          m.metricData.push($root.MetricData.decode(r, r.uint32()));
          break;
        }
        case 7: {
          m.serviceVersionInfo = $root.VersionInfo.decode(r, r.uint32());
          break;
        }
        case 8: {
          m.sessionKeyType = r.int32();
          break;
        }
        case 9: {
          m.oemcryptoCoreMessage = r.bytes();
          break;
        }
        default:
          r.skipType(t & 7);
          break;
      }
    }
    return m;
  };
  SignedMessage2.decodeDelimited = function decodeDelimited(reader) {
    if (!(reader instanceof $Reader)) reader = new $Reader(reader);
    return this.decode(reader, reader.uint32());
  };
  SignedMessage2.fromObject = function fromObject(d) {
    if (d instanceof $root.SignedMessage) return d;
    var m = new $root.SignedMessage();
    switch (d.type) {
      default:
        if (typeof d.type === "number") {
          m.type = d.type;
          break;
        }
        break;
      case "LICENSE_REQUEST":
      case 1:
        m.type = 1;
        break;
      case "LICENSE":
      case 2:
        m.type = 2;
        break;
      case "ERROR_RESPONSE":
      case 3:
        m.type = 3;
        break;
      case "SERVICE_CERTIFICATE_REQUEST":
      case 4:
        m.type = 4;
        break;
      case "SERVICE_CERTIFICATE":
      case 5:
        m.type = 5;
        break;
      case "SUB_LICENSE":
      case 6:
        m.type = 6;
        break;
      case "CAS_LICENSE_REQUEST":
      case 7:
        m.type = 7;
        break;
      case "CAS_LICENSE":
      case 8:
        m.type = 8;
        break;
      case "EXTERNAL_LICENSE_REQUEST":
      case 9:
        m.type = 9;
        break;
      case "EXTERNAL_LICENSE":
      case 10:
        m.type = 10;
        break;
    }
    if (d.msg != null) {
      if (typeof d.msg === "string")
        $util.base64.decode(
          d.msg,
          m.msg = $util.newBuffer($util.base64.length(d.msg)),
          0
        );
      else if (d.msg.length >= 0) m.msg = d.msg;
    }
    if (d.signature != null) {
      if (typeof d.signature === "string")
        $util.base64.decode(
          d.signature,
          m.signature = $util.newBuffer($util.base64.length(d.signature)),
          0
        );
      else if (d.signature.length >= 0) m.signature = d.signature;
    }
    if (d.sessionKey != null) {
      if (typeof d.sessionKey === "string")
        $util.base64.decode(
          d.sessionKey,
          m.sessionKey = $util.newBuffer($util.base64.length(d.sessionKey)),
          0
        );
      else if (d.sessionKey.length >= 0) m.sessionKey = d.sessionKey;
    }
    if (d.remoteAttestation != null) {
      if (typeof d.remoteAttestation === "string")
        $util.base64.decode(
          d.remoteAttestation,
          m.remoteAttestation = $util.newBuffer(
            $util.base64.length(d.remoteAttestation)
          ),
          0
        );
      else if (d.remoteAttestation.length >= 0)
        m.remoteAttestation = d.remoteAttestation;
    }
    if (d.metricData) {
      if (!Array.isArray(d.metricData))
        throw TypeError(".SignedMessage.metricData: array expected");
      m.metricData = [];
      for (var i = 0; i < d.metricData.length; ++i) {
        if (typeof d.metricData[i] !== "object")
          throw TypeError(".SignedMessage.metricData: object expected");
        m.metricData[i] = $root.MetricData.fromObject(d.metricData[i]);
      }
    }
    if (d.serviceVersionInfo != null) {
      if (typeof d.serviceVersionInfo !== "object")
        throw TypeError(".SignedMessage.serviceVersionInfo: object expected");
      m.serviceVersionInfo = $root.VersionInfo.fromObject(d.serviceVersionInfo);
    }
    switch (d.sessionKeyType) {
      case "UNDEFINED":
      case 0:
        m.sessionKeyType = 0;
        break;
      default:
        if (typeof d.sessionKeyType === "number") {
          m.sessionKeyType = d.sessionKeyType;
          break;
        }
        break;
      case "WRAPPED_AES_KEY":
      case 1:
        m.sessionKeyType = 1;
        break;
      case "EPHERMERAL_ECC_PUBLIC_KEY":
      case 2:
        m.sessionKeyType = 2;
        break;
    }
    if (d.oemcryptoCoreMessage != null) {
      if (typeof d.oemcryptoCoreMessage === "string")
        $util.base64.decode(
          d.oemcryptoCoreMessage,
          m.oemcryptoCoreMessage = $util.newBuffer(
            $util.base64.length(d.oemcryptoCoreMessage)
          ),
          0
        );
      else if (d.oemcryptoCoreMessage.length >= 0)
        m.oemcryptoCoreMessage = d.oemcryptoCoreMessage;
    }
    return m;
  };
  SignedMessage2.toObject = function toObject(m, o) {
    if (!o) o = {};
    var d = {};
    if (o.arrays || o.defaults) {
      d.metricData = [];
    }
    if (o.defaults) {
      d.type = o.enums === String ? "LICENSE_REQUEST" : 1;
      if (o.bytes === String) d.msg = "";
      else {
        d.msg = [];
        if (o.bytes !== Array) d.msg = $util.newBuffer(d.msg);
      }
      if (o.bytes === String) d.signature = "";
      else {
        d.signature = [];
        if (o.bytes !== Array) d.signature = $util.newBuffer(d.signature);
      }
      if (o.bytes === String) d.sessionKey = "";
      else {
        d.sessionKey = [];
        if (o.bytes !== Array) d.sessionKey = $util.newBuffer(d.sessionKey);
      }
      if (o.bytes === String) d.remoteAttestation = "";
      else {
        d.remoteAttestation = [];
        if (o.bytes !== Array)
          d.remoteAttestation = $util.newBuffer(d.remoteAttestation);
      }
      d.serviceVersionInfo = null;
      d.sessionKeyType = o.enums === String ? "WRAPPED_AES_KEY" : 1;
      if (o.bytes === String) d.oemcryptoCoreMessage = "";
      else {
        d.oemcryptoCoreMessage = [];
        if (o.bytes !== Array)
          d.oemcryptoCoreMessage = $util.newBuffer(d.oemcryptoCoreMessage);
      }
    }
    if (m.type != null && m.hasOwnProperty("type")) {
      d.type = o.enums === String ? $root.SignedMessage.MessageType[m.type] === void 0 ? m.type : $root.SignedMessage.MessageType[m.type] : m.type;
    }
    if (m.msg != null && m.hasOwnProperty("msg")) {
      d.msg = o.bytes === String ? $util.base64.encode(m.msg, 0, m.msg.length) : o.bytes === Array ? Array.prototype.slice.call(m.msg) : m.msg;
    }
    if (m.signature != null && m.hasOwnProperty("signature")) {
      d.signature = o.bytes === String ? $util.base64.encode(m.signature, 0, m.signature.length) : o.bytes === Array ? Array.prototype.slice.call(m.signature) : m.signature;
    }
    if (m.sessionKey != null && m.hasOwnProperty("sessionKey")) {
      d.sessionKey = o.bytes === String ? $util.base64.encode(m.sessionKey, 0, m.sessionKey.length) : o.bytes === Array ? Array.prototype.slice.call(m.sessionKey) : m.sessionKey;
    }
    if (m.remoteAttestation != null && m.hasOwnProperty("remoteAttestation")) {
      d.remoteAttestation = o.bytes === String ? $util.base64.encode(
        m.remoteAttestation,
        0,
        m.remoteAttestation.length
      ) : o.bytes === Array ? Array.prototype.slice.call(m.remoteAttestation) : m.remoteAttestation;
    }
    if (m.metricData && m.metricData.length) {
      d.metricData = [];
      for (var j = 0; j < m.metricData.length; ++j) {
        d.metricData[j] = $root.MetricData.toObject(m.metricData[j], o);
      }
    }
    if (m.serviceVersionInfo != null && m.hasOwnProperty("serviceVersionInfo")) {
      d.serviceVersionInfo = $root.VersionInfo.toObject(
        m.serviceVersionInfo,
        o
      );
    }
    if (m.sessionKeyType != null && m.hasOwnProperty("sessionKeyType")) {
      d.sessionKeyType = o.enums === String ? $root.SignedMessage.SessionKeyType[m.sessionKeyType] === void 0 ? m.sessionKeyType : $root.SignedMessage.SessionKeyType[m.sessionKeyType] : m.sessionKeyType;
    }
    if (m.oemcryptoCoreMessage != null && m.hasOwnProperty("oemcryptoCoreMessage")) {
      d.oemcryptoCoreMessage = o.bytes === String ? $util.base64.encode(
        m.oemcryptoCoreMessage,
        0,
        m.oemcryptoCoreMessage.length
      ) : o.bytes === Array ? Array.prototype.slice.call(m.oemcryptoCoreMessage) : m.oemcryptoCoreMessage;
    }
    return d;
  };
  SignedMessage2.prototype.toJSON = function toJSON() {
    return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
  };
  SignedMessage2.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
    if (typeUrlPrefix === void 0) {
      typeUrlPrefix = "type.googleapis.com";
    }
    return typeUrlPrefix + "/SignedMessage";
  };
  SignedMessage2.MessageType = function() {
    const valuesById = {}, values = Object.create(valuesById);
    values[valuesById[1] = "LICENSE_REQUEST"] = 1;
    values[valuesById[2] = "LICENSE"] = 2;
    values[valuesById[3] = "ERROR_RESPONSE"] = 3;
    values[valuesById[4] = "SERVICE_CERTIFICATE_REQUEST"] = 4;
    values[valuesById[5] = "SERVICE_CERTIFICATE"] = 5;
    values[valuesById[6] = "SUB_LICENSE"] = 6;
    values[valuesById[7] = "CAS_LICENSE_REQUEST"] = 7;
    values[valuesById[8] = "CAS_LICENSE"] = 8;
    values[valuesById[9] = "EXTERNAL_LICENSE_REQUEST"] = 9;
    values[valuesById[10] = "EXTERNAL_LICENSE"] = 10;
    return values;
  }();
  SignedMessage2.SessionKeyType = function() {
    const valuesById = {}, values = Object.create(valuesById);
    values[valuesById[0] = "UNDEFINED"] = 0;
    values[valuesById[1] = "WRAPPED_AES_KEY"] = 1;
    values[valuesById[2] = "EPHERMERAL_ECC_PUBLIC_KEY"] = 2;
    return values;
  }();
  return SignedMessage2;
})();
var HashAlgorithmProto = $root.HashAlgorithmProto = (() => {
  const valuesById = {}, values = Object.create(valuesById);
  values[valuesById[0] = "HASH_ALGORITHM_UNSPECIFIED"] = 0;
  values[valuesById[1] = "HASH_ALGORITHM_SHA_1"] = 1;
  values[valuesById[2] = "HASH_ALGORITHM_SHA_256"] = 2;
  values[valuesById[3] = "HASH_ALGORITHM_SHA_384"] = 3;
  return values;
})();
var ClientIdentification = $root.ClientIdentification = (() => {
  function ClientIdentification2(p) {
    this.clientInfo = [];
    this.deviceCredentials = [];
    if (p) {
      for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
        if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
    }
  }
  ClientIdentification2.prototype.type = 0;
  ClientIdentification2.prototype.token = $util.newBuffer([]);
  ClientIdentification2.prototype.clientInfo = $util.emptyArray;
  ClientIdentification2.prototype.providerClientToken = $util.newBuffer([]);
  ClientIdentification2.prototype.licenseCounter = 0;
  ClientIdentification2.prototype.clientCapabilities = null;
  ClientIdentification2.prototype.vmpData = $util.newBuffer([]);
  ClientIdentification2.prototype.deviceCredentials = $util.emptyArray;
  ClientIdentification2.create = function create(properties) {
    return new ClientIdentification2(properties);
  };
  ClientIdentification2.encode = function encode2(m, w) {
    if (!w) w = $Writer.create();
    if (m.type != null && Object.hasOwnProperty.call(m, "type"))
      w.uint32(8).int32(m.type);
    if (m.token != null && Object.hasOwnProperty.call(m, "token"))
      w.uint32(18).bytes(m.token);
    if (m.clientInfo != null && m.clientInfo.length) {
      for (var i = 0; i < m.clientInfo.length; ++i)
        $root.ClientIdentification.NameValue.encode(
          m.clientInfo[i],
          w.uint32(26).fork()
        ).ldelim();
    }
    if (m.providerClientToken != null && Object.hasOwnProperty.call(m, "providerClientToken"))
      w.uint32(34).bytes(m.providerClientToken);
    if (m.licenseCounter != null && Object.hasOwnProperty.call(m, "licenseCounter"))
      w.uint32(40).uint32(m.licenseCounter);
    if (m.clientCapabilities != null && Object.hasOwnProperty.call(m, "clientCapabilities"))
      $root.ClientIdentification.ClientCapabilities.encode(
        m.clientCapabilities,
        w.uint32(50).fork()
      ).ldelim();
    if (m.vmpData != null && Object.hasOwnProperty.call(m, "vmpData"))
      w.uint32(58).bytes(m.vmpData);
    if (m.deviceCredentials != null && m.deviceCredentials.length) {
      for (var i = 0; i < m.deviceCredentials.length; ++i)
        $root.ClientIdentification.ClientCredentials.encode(
          m.deviceCredentials[i],
          w.uint32(66).fork()
        ).ldelim();
    }
    return w;
  };
  ClientIdentification2.encodeDelimited = function encodeDelimited(message, writer) {
    return this.encode(message, writer).ldelim();
  };
  ClientIdentification2.decode = function decode2(r, l) {
    if (!(r instanceof $Reader)) r = $Reader.create(r);
    var c = l === void 0 ? r.len : r.pos + l, m = new $root.ClientIdentification();
    while (r.pos < c) {
      var t = r.uint32();
      switch (t >>> 3) {
        case 1: {
          m.type = r.int32();
          break;
        }
        case 2: {
          m.token = r.bytes();
          break;
        }
        case 3: {
          if (!(m.clientInfo && m.clientInfo.length)) m.clientInfo = [];
          m.clientInfo.push(
            $root.ClientIdentification.NameValue.decode(r, r.uint32())
          );
          break;
        }
        case 4: {
          m.providerClientToken = r.bytes();
          break;
        }
        case 5: {
          m.licenseCounter = r.uint32();
          break;
        }
        case 6: {
          m.clientCapabilities = $root.ClientIdentification.ClientCapabilities.decode(r, r.uint32());
          break;
        }
        case 7: {
          m.vmpData = r.bytes();
          break;
        }
        case 8: {
          if (!(m.deviceCredentials && m.deviceCredentials.length))
            m.deviceCredentials = [];
          m.deviceCredentials.push(
            $root.ClientIdentification.ClientCredentials.decode(r, r.uint32())
          );
          break;
        }
        default:
          r.skipType(t & 7);
          break;
      }
    }
    return m;
  };
  ClientIdentification2.decodeDelimited = function decodeDelimited(reader) {
    if (!(reader instanceof $Reader)) reader = new $Reader(reader);
    return this.decode(reader, reader.uint32());
  };
  ClientIdentification2.fromObject = function fromObject(d) {
    if (d instanceof $root.ClientIdentification) return d;
    var m = new $root.ClientIdentification();
    switch (d.type) {
      default:
        if (typeof d.type === "number") {
          m.type = d.type;
          break;
        }
        break;
      case "KEYBOX":
      case 0:
        m.type = 0;
        break;
      case "DRM_DEVICE_CERTIFICATE":
      case 1:
        m.type = 1;
        break;
      case "REMOTE_ATTESTATION_CERTIFICATE":
      case 2:
        m.type = 2;
        break;
      case "OEM_DEVICE_CERTIFICATE":
      case 3:
        m.type = 3;
        break;
    }
    if (d.token != null) {
      if (typeof d.token === "string")
        $util.base64.decode(
          d.token,
          m.token = $util.newBuffer($util.base64.length(d.token)),
          0
        );
      else if (d.token.length >= 0) m.token = d.token;
    }
    if (d.clientInfo) {
      if (!Array.isArray(d.clientInfo))
        throw TypeError(".ClientIdentification.clientInfo: array expected");
      m.clientInfo = [];
      for (var i = 0; i < d.clientInfo.length; ++i) {
        if (typeof d.clientInfo[i] !== "object")
          throw TypeError(".ClientIdentification.clientInfo: object expected");
        m.clientInfo[i] = $root.ClientIdentification.NameValue.fromObject(
          d.clientInfo[i]
        );
      }
    }
    if (d.providerClientToken != null) {
      if (typeof d.providerClientToken === "string")
        $util.base64.decode(
          d.providerClientToken,
          m.providerClientToken = $util.newBuffer(
            $util.base64.length(d.providerClientToken)
          ),
          0
        );
      else if (d.providerClientToken.length >= 0)
        m.providerClientToken = d.providerClientToken;
    }
    if (d.licenseCounter != null) {
      m.licenseCounter = d.licenseCounter >>> 0;
    }
    if (d.clientCapabilities != null) {
      if (typeof d.clientCapabilities !== "object")
        throw TypeError(
          ".ClientIdentification.clientCapabilities: object expected"
        );
      m.clientCapabilities = $root.ClientIdentification.ClientCapabilities.fromObject(
        d.clientCapabilities
      );
    }
    if (d.vmpData != null) {
      if (typeof d.vmpData === "string")
        $util.base64.decode(
          d.vmpData,
          m.vmpData = $util.newBuffer($util.base64.length(d.vmpData)),
          0
        );
      else if (d.vmpData.length >= 0) m.vmpData = d.vmpData;
    }
    if (d.deviceCredentials) {
      if (!Array.isArray(d.deviceCredentials))
        throw TypeError(
          ".ClientIdentification.deviceCredentials: array expected"
        );
      m.deviceCredentials = [];
      for (var i = 0; i < d.deviceCredentials.length; ++i) {
        if (typeof d.deviceCredentials[i] !== "object")
          throw TypeError(
            ".ClientIdentification.deviceCredentials: object expected"
          );
        m.deviceCredentials[i] = $root.ClientIdentification.ClientCredentials.fromObject(
          d.deviceCredentials[i]
        );
      }
    }
    return m;
  };
  ClientIdentification2.toObject = function toObject(m, o) {
    if (!o) o = {};
    var d = {};
    if (o.arrays || o.defaults) {
      d.clientInfo = [];
      d.deviceCredentials = [];
    }
    if (o.defaults) {
      d.type = o.enums === String ? "KEYBOX" : 0;
      if (o.bytes === String) d.token = "";
      else {
        d.token = [];
        if (o.bytes !== Array) d.token = $util.newBuffer(d.token);
      }
      if (o.bytes === String) d.providerClientToken = "";
      else {
        d.providerClientToken = [];
        if (o.bytes !== Array)
          d.providerClientToken = $util.newBuffer(d.providerClientToken);
      }
      d.licenseCounter = 0;
      d.clientCapabilities = null;
      if (o.bytes === String) d.vmpData = "";
      else {
        d.vmpData = [];
        if (o.bytes !== Array) d.vmpData = $util.newBuffer(d.vmpData);
      }
    }
    if (m.type != null && m.hasOwnProperty("type")) {
      d.type = o.enums === String ? $root.ClientIdentification.TokenType[m.type] === void 0 ? m.type : $root.ClientIdentification.TokenType[m.type] : m.type;
    }
    if (m.token != null && m.hasOwnProperty("token")) {
      d.token = o.bytes === String ? $util.base64.encode(m.token, 0, m.token.length) : o.bytes === Array ? Array.prototype.slice.call(m.token) : m.token;
    }
    if (m.clientInfo && m.clientInfo.length) {
      d.clientInfo = [];
      for (var j = 0; j < m.clientInfo.length; ++j) {
        d.clientInfo[j] = $root.ClientIdentification.NameValue.toObject(
          m.clientInfo[j],
          o
        );
      }
    }
    if (m.providerClientToken != null && m.hasOwnProperty("providerClientToken")) {
      d.providerClientToken = o.bytes === String ? $util.base64.encode(
        m.providerClientToken,
        0,
        m.providerClientToken.length
      ) : o.bytes === Array ? Array.prototype.slice.call(m.providerClientToken) : m.providerClientToken;
    }
    if (m.licenseCounter != null && m.hasOwnProperty("licenseCounter")) {
      d.licenseCounter = m.licenseCounter;
    }
    if (m.clientCapabilities != null && m.hasOwnProperty("clientCapabilities")) {
      d.clientCapabilities = $root.ClientIdentification.ClientCapabilities.toObject(
        m.clientCapabilities,
        o
      );
    }
    if (m.vmpData != null && m.hasOwnProperty("vmpData")) {
      d.vmpData = o.bytes === String ? $util.base64.encode(m.vmpData, 0, m.vmpData.length) : o.bytes === Array ? Array.prototype.slice.call(m.vmpData) : m.vmpData;
    }
    if (m.deviceCredentials && m.deviceCredentials.length) {
      d.deviceCredentials = [];
      for (var j = 0; j < m.deviceCredentials.length; ++j) {
        d.deviceCredentials[j] = $root.ClientIdentification.ClientCredentials.toObject(
          m.deviceCredentials[j],
          o
        );
      }
    }
    return d;
  };
  ClientIdentification2.prototype.toJSON = function toJSON() {
    return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
  };
  ClientIdentification2.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
    if (typeUrlPrefix === void 0) {
      typeUrlPrefix = "type.googleapis.com";
    }
    return typeUrlPrefix + "/ClientIdentification";
  };
  ClientIdentification2.TokenType = function() {
    const valuesById = {}, values = Object.create(valuesById);
    values[valuesById[0] = "KEYBOX"] = 0;
    values[valuesById[1] = "DRM_DEVICE_CERTIFICATE"] = 1;
    values[valuesById[2] = "REMOTE_ATTESTATION_CERTIFICATE"] = 2;
    values[valuesById[3] = "OEM_DEVICE_CERTIFICATE"] = 3;
    return values;
  }();
  ClientIdentification2.NameValue = function() {
    function NameValue(p) {
      if (p) {
        for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
          if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
      }
    }
    NameValue.prototype.name = "";
    NameValue.prototype.value = "";
    NameValue.create = function create(properties) {
      return new NameValue(properties);
    };
    NameValue.encode = function encode2(m, w) {
      if (!w) w = $Writer.create();
      if (m.name != null && Object.hasOwnProperty.call(m, "name"))
        w.uint32(10).string(m.name);
      if (m.value != null && Object.hasOwnProperty.call(m, "value"))
        w.uint32(18).string(m.value);
      return w;
    };
    NameValue.encodeDelimited = function encodeDelimited(message, writer) {
      return this.encode(message, writer).ldelim();
    };
    NameValue.decode = function decode2(r, l) {
      if (!(r instanceof $Reader)) r = $Reader.create(r);
      var c = l === void 0 ? r.len : r.pos + l, m = new $root.ClientIdentification.NameValue();
      while (r.pos < c) {
        var t = r.uint32();
        switch (t >>> 3) {
          case 1: {
            m.name = r.string();
            break;
          }
          case 2: {
            m.value = r.string();
            break;
          }
          default:
            r.skipType(t & 7);
            break;
        }
      }
      return m;
    };
    NameValue.decodeDelimited = function decodeDelimited(reader) {
      if (!(reader instanceof $Reader)) reader = new $Reader(reader);
      return this.decode(reader, reader.uint32());
    };
    NameValue.fromObject = function fromObject(d) {
      if (d instanceof $root.ClientIdentification.NameValue) return d;
      var m = new $root.ClientIdentification.NameValue();
      if (d.name != null) {
        m.name = String(d.name);
      }
      if (d.value != null) {
        m.value = String(d.value);
      }
      return m;
    };
    NameValue.toObject = function toObject(m, o) {
      if (!o) o = {};
      var d = {};
      if (o.defaults) {
        d.name = "";
        d.value = "";
      }
      if (m.name != null && m.hasOwnProperty("name")) {
        d.name = m.name;
      }
      if (m.value != null && m.hasOwnProperty("value")) {
        d.value = m.value;
      }
      return d;
    };
    NameValue.prototype.toJSON = function toJSON() {
      return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
    };
    NameValue.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
      if (typeUrlPrefix === void 0) {
        typeUrlPrefix = "type.googleapis.com";
      }
      return typeUrlPrefix + "/ClientIdentification.NameValue";
    };
    return NameValue;
  }();
  ClientIdentification2.ClientCapabilities = function() {
    function ClientCapabilities(p) {
      this.supportedCertificateKeyType = [];
      if (p) {
        for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
          if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
      }
    }
    ClientCapabilities.prototype.clientToken = false;
    ClientCapabilities.prototype.sessionToken = false;
    ClientCapabilities.prototype.videoResolutionConstraints = false;
    ClientCapabilities.prototype.maxHdcpVersion = 0;
    ClientCapabilities.prototype.oemCryptoApiVersion = 0;
    ClientCapabilities.prototype.antiRollbackUsageTable = false;
    ClientCapabilities.prototype.srmVersion = 0;
    ClientCapabilities.prototype.canUpdateSrm = false;
    ClientCapabilities.prototype.supportedCertificateKeyType = $util.emptyArray;
    ClientCapabilities.prototype.analogOutputCapabilities = 0;
    ClientCapabilities.prototype.canDisableAnalogOutput = false;
    ClientCapabilities.prototype.resourceRatingTier = 0;
    ClientCapabilities.create = function create(properties) {
      return new ClientCapabilities(properties);
    };
    ClientCapabilities.encode = function encode2(m, w) {
      if (!w) w = $Writer.create();
      if (m.clientToken != null && Object.hasOwnProperty.call(m, "clientToken"))
        w.uint32(8).bool(m.clientToken);
      if (m.sessionToken != null && Object.hasOwnProperty.call(m, "sessionToken"))
        w.uint32(16).bool(m.sessionToken);
      if (m.videoResolutionConstraints != null && Object.hasOwnProperty.call(m, "videoResolutionConstraints"))
        w.uint32(24).bool(m.videoResolutionConstraints);
      if (m.maxHdcpVersion != null && Object.hasOwnProperty.call(m, "maxHdcpVersion"))
        w.uint32(32).int32(m.maxHdcpVersion);
      if (m.oemCryptoApiVersion != null && Object.hasOwnProperty.call(m, "oemCryptoApiVersion"))
        w.uint32(40).uint32(m.oemCryptoApiVersion);
      if (m.antiRollbackUsageTable != null && Object.hasOwnProperty.call(m, "antiRollbackUsageTable"))
        w.uint32(48).bool(m.antiRollbackUsageTable);
      if (m.srmVersion != null && Object.hasOwnProperty.call(m, "srmVersion"))
        w.uint32(56).uint32(m.srmVersion);
      if (m.canUpdateSrm != null && Object.hasOwnProperty.call(m, "canUpdateSrm"))
        w.uint32(64).bool(m.canUpdateSrm);
      if (m.supportedCertificateKeyType != null && m.supportedCertificateKeyType.length) {
        for (var i = 0; i < m.supportedCertificateKeyType.length; ++i)
          w.uint32(72).int32(m.supportedCertificateKeyType[i]);
      }
      if (m.analogOutputCapabilities != null && Object.hasOwnProperty.call(m, "analogOutputCapabilities"))
        w.uint32(80).int32(m.analogOutputCapabilities);
      if (m.canDisableAnalogOutput != null && Object.hasOwnProperty.call(m, "canDisableAnalogOutput"))
        w.uint32(88).bool(m.canDisableAnalogOutput);
      if (m.resourceRatingTier != null && Object.hasOwnProperty.call(m, "resourceRatingTier"))
        w.uint32(96).uint32(m.resourceRatingTier);
      return w;
    };
    ClientCapabilities.encodeDelimited = function encodeDelimited(message, writer) {
      return this.encode(message, writer).ldelim();
    };
    ClientCapabilities.decode = function decode2(r, l) {
      if (!(r instanceof $Reader)) r = $Reader.create(r);
      var c = l === void 0 ? r.len : r.pos + l, m = new $root.ClientIdentification.ClientCapabilities();
      while (r.pos < c) {
        var t = r.uint32();
        switch (t >>> 3) {
          case 1: {
            m.clientToken = r.bool();
            break;
          }
          case 2: {
            m.sessionToken = r.bool();
            break;
          }
          case 3: {
            m.videoResolutionConstraints = r.bool();
            break;
          }
          case 4: {
            m.maxHdcpVersion = r.int32();
            break;
          }
          case 5: {
            m.oemCryptoApiVersion = r.uint32();
            break;
          }
          case 6: {
            m.antiRollbackUsageTable = r.bool();
            break;
          }
          case 7: {
            m.srmVersion = r.uint32();
            break;
          }
          case 8: {
            m.canUpdateSrm = r.bool();
            break;
          }
          case 9: {
            if (!(m.supportedCertificateKeyType && m.supportedCertificateKeyType.length))
              m.supportedCertificateKeyType = [];
            if ((t & 7) === 2) {
              var c2 = r.uint32() + r.pos;
              while (r.pos < c2) m.supportedCertificateKeyType.push(r.int32());
            } else m.supportedCertificateKeyType.push(r.int32());
            break;
          }
          case 10: {
            m.analogOutputCapabilities = r.int32();
            break;
          }
          case 11: {
            m.canDisableAnalogOutput = r.bool();
            break;
          }
          case 12: {
            m.resourceRatingTier = r.uint32();
            break;
          }
          default:
            r.skipType(t & 7);
            break;
        }
      }
      return m;
    };
    ClientCapabilities.decodeDelimited = function decodeDelimited(reader) {
      if (!(reader instanceof $Reader)) reader = new $Reader(reader);
      return this.decode(reader, reader.uint32());
    };
    ClientCapabilities.fromObject = function fromObject(d) {
      if (d instanceof $root.ClientIdentification.ClientCapabilities) return d;
      var m = new $root.ClientIdentification.ClientCapabilities();
      if (d.clientToken != null) {
        m.clientToken = Boolean(d.clientToken);
      }
      if (d.sessionToken != null) {
        m.sessionToken = Boolean(d.sessionToken);
      }
      if (d.videoResolutionConstraints != null) {
        m.videoResolutionConstraints = Boolean(d.videoResolutionConstraints);
      }
      switch (d.maxHdcpVersion) {
        default:
          if (typeof d.maxHdcpVersion === "number") {
            m.maxHdcpVersion = d.maxHdcpVersion;
            break;
          }
          break;
        case "HDCP_NONE":
        case 0:
          m.maxHdcpVersion = 0;
          break;
        case "HDCP_V1":
        case 1:
          m.maxHdcpVersion = 1;
          break;
        case "HDCP_V2":
        case 2:
          m.maxHdcpVersion = 2;
          break;
        case "HDCP_V2_1":
        case 3:
          m.maxHdcpVersion = 3;
          break;
        case "HDCP_V2_2":
        case 4:
          m.maxHdcpVersion = 4;
          break;
        case "HDCP_V2_3":
        case 5:
          m.maxHdcpVersion = 5;
          break;
        case "HDCP_NO_DIGITAL_OUTPUT":
        case 255:
          m.maxHdcpVersion = 255;
          break;
      }
      if (d.oemCryptoApiVersion != null) {
        m.oemCryptoApiVersion = d.oemCryptoApiVersion >>> 0;
      }
      if (d.antiRollbackUsageTable != null) {
        m.antiRollbackUsageTable = Boolean(d.antiRollbackUsageTable);
      }
      if (d.srmVersion != null) {
        m.srmVersion = d.srmVersion >>> 0;
      }
      if (d.canUpdateSrm != null) {
        m.canUpdateSrm = Boolean(d.canUpdateSrm);
      }
      if (d.supportedCertificateKeyType) {
        if (!Array.isArray(d.supportedCertificateKeyType))
          throw TypeError(
            ".ClientIdentification.ClientCapabilities.supportedCertificateKeyType: array expected"
          );
        m.supportedCertificateKeyType = [];
        for (var i = 0; i < d.supportedCertificateKeyType.length; ++i) {
          switch (d.supportedCertificateKeyType[i]) {
            default:
              if (typeof d.supportedCertificateKeyType[i] === "number") {
                m.supportedCertificateKeyType[i] = d.supportedCertificateKeyType[i];
                break;
              }
            case "RSA_2048":
            case 0:
              m.supportedCertificateKeyType[i] = 0;
              break;
            case "RSA_3072":
            case 1:
              m.supportedCertificateKeyType[i] = 1;
              break;
            case "ECC_SECP256R1":
            case 2:
              m.supportedCertificateKeyType[i] = 2;
              break;
            case "ECC_SECP384R1":
            case 3:
              m.supportedCertificateKeyType[i] = 3;
              break;
            case "ECC_SECP521R1":
            case 4:
              m.supportedCertificateKeyType[i] = 4;
              break;
          }
        }
      }
      switch (d.analogOutputCapabilities) {
        default:
          if (typeof d.analogOutputCapabilities === "number") {
            m.analogOutputCapabilities = d.analogOutputCapabilities;
            break;
          }
          break;
        case "ANALOG_OUTPUT_UNKNOWN":
        case 0:
          m.analogOutputCapabilities = 0;
          break;
        case "ANALOG_OUTPUT_NONE":
        case 1:
          m.analogOutputCapabilities = 1;
          break;
        case "ANALOG_OUTPUT_SUPPORTED":
        case 2:
          m.analogOutputCapabilities = 2;
          break;
        case "ANALOG_OUTPUT_SUPPORTS_CGMS_A":
        case 3:
          m.analogOutputCapabilities = 3;
          break;
      }
      if (d.canDisableAnalogOutput != null) {
        m.canDisableAnalogOutput = Boolean(d.canDisableAnalogOutput);
      }
      if (d.resourceRatingTier != null) {
        m.resourceRatingTier = d.resourceRatingTier >>> 0;
      }
      return m;
    };
    ClientCapabilities.toObject = function toObject(m, o) {
      if (!o) o = {};
      var d = {};
      if (o.arrays || o.defaults) {
        d.supportedCertificateKeyType = [];
      }
      if (o.defaults) {
        d.clientToken = false;
        d.sessionToken = false;
        d.videoResolutionConstraints = false;
        d.maxHdcpVersion = o.enums === String ? "HDCP_NONE" : 0;
        d.oemCryptoApiVersion = 0;
        d.antiRollbackUsageTable = false;
        d.srmVersion = 0;
        d.canUpdateSrm = false;
        d.analogOutputCapabilities = o.enums === String ? "ANALOG_OUTPUT_UNKNOWN" : 0;
        d.canDisableAnalogOutput = false;
        d.resourceRatingTier = 0;
      }
      if (m.clientToken != null && m.hasOwnProperty("clientToken")) {
        d.clientToken = m.clientToken;
      }
      if (m.sessionToken != null && m.hasOwnProperty("sessionToken")) {
        d.sessionToken = m.sessionToken;
      }
      if (m.videoResolutionConstraints != null && m.hasOwnProperty("videoResolutionConstraints")) {
        d.videoResolutionConstraints = m.videoResolutionConstraints;
      }
      if (m.maxHdcpVersion != null && m.hasOwnProperty("maxHdcpVersion")) {
        d.maxHdcpVersion = o.enums === String ? $root.ClientIdentification.ClientCapabilities.HdcpVersion[m.maxHdcpVersion] === void 0 ? m.maxHdcpVersion : $root.ClientIdentification.ClientCapabilities.HdcpVersion[m.maxHdcpVersion] : m.maxHdcpVersion;
      }
      if (m.oemCryptoApiVersion != null && m.hasOwnProperty("oemCryptoApiVersion")) {
        d.oemCryptoApiVersion = m.oemCryptoApiVersion;
      }
      if (m.antiRollbackUsageTable != null && m.hasOwnProperty("antiRollbackUsageTable")) {
        d.antiRollbackUsageTable = m.antiRollbackUsageTable;
      }
      if (m.srmVersion != null && m.hasOwnProperty("srmVersion")) {
        d.srmVersion = m.srmVersion;
      }
      if (m.canUpdateSrm != null && m.hasOwnProperty("canUpdateSrm")) {
        d.canUpdateSrm = m.canUpdateSrm;
      }
      if (m.supportedCertificateKeyType && m.supportedCertificateKeyType.length) {
        d.supportedCertificateKeyType = [];
        for (var j = 0; j < m.supportedCertificateKeyType.length; ++j) {
          d.supportedCertificateKeyType[j] = o.enums === String ? $root.ClientIdentification.ClientCapabilities.CertificateKeyType[m.supportedCertificateKeyType[j]] === void 0 ? m.supportedCertificateKeyType[j] : $root.ClientIdentification.ClientCapabilities.CertificateKeyType[m.supportedCertificateKeyType[j]] : m.supportedCertificateKeyType[j];
        }
      }
      if (m.analogOutputCapabilities != null && m.hasOwnProperty("analogOutputCapabilities")) {
        d.analogOutputCapabilities = o.enums === String ? $root.ClientIdentification.ClientCapabilities.AnalogOutputCapabilities[m.analogOutputCapabilities] === void 0 ? m.analogOutputCapabilities : $root.ClientIdentification.ClientCapabilities.AnalogOutputCapabilities[m.analogOutputCapabilities] : m.analogOutputCapabilities;
      }
      if (m.canDisableAnalogOutput != null && m.hasOwnProperty("canDisableAnalogOutput")) {
        d.canDisableAnalogOutput = m.canDisableAnalogOutput;
      }
      if (m.resourceRatingTier != null && m.hasOwnProperty("resourceRatingTier")) {
        d.resourceRatingTier = m.resourceRatingTier;
      }
      return d;
    };
    ClientCapabilities.prototype.toJSON = function toJSON() {
      return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
    };
    ClientCapabilities.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
      if (typeUrlPrefix === void 0) {
        typeUrlPrefix = "type.googleapis.com";
      }
      return typeUrlPrefix + "/ClientIdentification.ClientCapabilities";
    };
    ClientCapabilities.HdcpVersion = function() {
      const valuesById = {}, values = Object.create(valuesById);
      values[valuesById[0] = "HDCP_NONE"] = 0;
      values[valuesById[1] = "HDCP_V1"] = 1;
      values[valuesById[2] = "HDCP_V2"] = 2;
      values[valuesById[3] = "HDCP_V2_1"] = 3;
      values[valuesById[4] = "HDCP_V2_2"] = 4;
      values[valuesById[5] = "HDCP_V2_3"] = 5;
      values[valuesById[255] = "HDCP_NO_DIGITAL_OUTPUT"] = 255;
      return values;
    }();
    ClientCapabilities.CertificateKeyType = function() {
      const valuesById = {}, values = Object.create(valuesById);
      values[valuesById[0] = "RSA_2048"] = 0;
      values[valuesById[1] = "RSA_3072"] = 1;
      values[valuesById[2] = "ECC_SECP256R1"] = 2;
      values[valuesById[3] = "ECC_SECP384R1"] = 3;
      values[valuesById[4] = "ECC_SECP521R1"] = 4;
      return values;
    }();
    ClientCapabilities.AnalogOutputCapabilities = function() {
      const valuesById = {}, values = Object.create(valuesById);
      values[valuesById[0] = "ANALOG_OUTPUT_UNKNOWN"] = 0;
      values[valuesById[1] = "ANALOG_OUTPUT_NONE"] = 1;
      values[valuesById[2] = "ANALOG_OUTPUT_SUPPORTED"] = 2;
      values[valuesById[3] = "ANALOG_OUTPUT_SUPPORTS_CGMS_A"] = 3;
      return values;
    }();
    return ClientCapabilities;
  }();
  ClientIdentification2.ClientCredentials = function() {
    function ClientCredentials(p) {
      if (p) {
        for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
          if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
      }
    }
    ClientCredentials.prototype.type = 0;
    ClientCredentials.prototype.token = $util.newBuffer([]);
    ClientCredentials.create = function create(properties) {
      return new ClientCredentials(properties);
    };
    ClientCredentials.encode = function encode2(m, w) {
      if (!w) w = $Writer.create();
      if (m.type != null && Object.hasOwnProperty.call(m, "type"))
        w.uint32(8).int32(m.type);
      if (m.token != null && Object.hasOwnProperty.call(m, "token"))
        w.uint32(18).bytes(m.token);
      return w;
    };
    ClientCredentials.encodeDelimited = function encodeDelimited(message, writer) {
      return this.encode(message, writer).ldelim();
    };
    ClientCredentials.decode = function decode2(r, l) {
      if (!(r instanceof $Reader)) r = $Reader.create(r);
      var c = l === void 0 ? r.len : r.pos + l, m = new $root.ClientIdentification.ClientCredentials();
      while (r.pos < c) {
        var t = r.uint32();
        switch (t >>> 3) {
          case 1: {
            m.type = r.int32();
            break;
          }
          case 2: {
            m.token = r.bytes();
            break;
          }
          default:
            r.skipType(t & 7);
            break;
        }
      }
      return m;
    };
    ClientCredentials.decodeDelimited = function decodeDelimited(reader) {
      if (!(reader instanceof $Reader)) reader = new $Reader(reader);
      return this.decode(reader, reader.uint32());
    };
    ClientCredentials.fromObject = function fromObject(d) {
      if (d instanceof $root.ClientIdentification.ClientCredentials) return d;
      var m = new $root.ClientIdentification.ClientCredentials();
      switch (d.type) {
        default:
          if (typeof d.type === "number") {
            m.type = d.type;
            break;
          }
          break;
        case "KEYBOX":
        case 0:
          m.type = 0;
          break;
        case "DRM_DEVICE_CERTIFICATE":
        case 1:
          m.type = 1;
          break;
        case "REMOTE_ATTESTATION_CERTIFICATE":
        case 2:
          m.type = 2;
          break;
        case "OEM_DEVICE_CERTIFICATE":
        case 3:
          m.type = 3;
          break;
      }
      if (d.token != null) {
        if (typeof d.token === "string")
          $util.base64.decode(
            d.token,
            m.token = $util.newBuffer($util.base64.length(d.token)),
            0
          );
        else if (d.token.length >= 0) m.token = d.token;
      }
      return m;
    };
    ClientCredentials.toObject = function toObject(m, o) {
      if (!o) o = {};
      var d = {};
      if (o.defaults) {
        d.type = o.enums === String ? "KEYBOX" : 0;
        if (o.bytes === String) d.token = "";
        else {
          d.token = [];
          if (o.bytes !== Array) d.token = $util.newBuffer(d.token);
        }
      }
      if (m.type != null && m.hasOwnProperty("type")) {
        d.type = o.enums === String ? $root.ClientIdentification.TokenType[m.type] === void 0 ? m.type : $root.ClientIdentification.TokenType[m.type] : m.type;
      }
      if (m.token != null && m.hasOwnProperty("token")) {
        d.token = o.bytes === String ? $util.base64.encode(m.token, 0, m.token.length) : o.bytes === Array ? Array.prototype.slice.call(m.token) : m.token;
      }
      return d;
    };
    ClientCredentials.prototype.toJSON = function toJSON() {
      return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
    };
    ClientCredentials.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
      if (typeUrlPrefix === void 0) {
        typeUrlPrefix = "type.googleapis.com";
      }
      return typeUrlPrefix + "/ClientIdentification.ClientCredentials";
    };
    return ClientCredentials;
  }();
  return ClientIdentification2;
})();
var EncryptedClientIdentification = $root.EncryptedClientIdentification = (() => {
  function EncryptedClientIdentification2(p) {
    if (p) {
      for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
        if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
    }
  }
  EncryptedClientIdentification2.prototype.providerId = "";
  EncryptedClientIdentification2.prototype.serviceCertificateSerialNumber = $util.newBuffer([]);
  EncryptedClientIdentification2.prototype.encryptedClientId = $util.newBuffer(
    []
  );
  EncryptedClientIdentification2.prototype.encryptedClientIdIv = $util.newBuffer([]);
  EncryptedClientIdentification2.prototype.encryptedPrivacyKey = $util.newBuffer([]);
  EncryptedClientIdentification2.create = function create(properties) {
    return new EncryptedClientIdentification2(properties);
  };
  EncryptedClientIdentification2.encode = function encode2(m, w) {
    if (!w) w = $Writer.create();
    if (m.providerId != null && Object.hasOwnProperty.call(m, "providerId"))
      w.uint32(10).string(m.providerId);
    if (m.serviceCertificateSerialNumber != null && Object.hasOwnProperty.call(m, "serviceCertificateSerialNumber"))
      w.uint32(18).bytes(m.serviceCertificateSerialNumber);
    if (m.encryptedClientId != null && Object.hasOwnProperty.call(m, "encryptedClientId"))
      w.uint32(26).bytes(m.encryptedClientId);
    if (m.encryptedClientIdIv != null && Object.hasOwnProperty.call(m, "encryptedClientIdIv"))
      w.uint32(34).bytes(m.encryptedClientIdIv);
    if (m.encryptedPrivacyKey != null && Object.hasOwnProperty.call(m, "encryptedPrivacyKey"))
      w.uint32(42).bytes(m.encryptedPrivacyKey);
    return w;
  };
  EncryptedClientIdentification2.encodeDelimited = function encodeDelimited(message, writer) {
    return this.encode(message, writer).ldelim();
  };
  EncryptedClientIdentification2.decode = function decode2(r, l) {
    if (!(r instanceof $Reader)) r = $Reader.create(r);
    var c = l === void 0 ? r.len : r.pos + l, m = new $root.EncryptedClientIdentification();
    while (r.pos < c) {
      var t = r.uint32();
      switch (t >>> 3) {
        case 1: {
          m.providerId = r.string();
          break;
        }
        case 2: {
          m.serviceCertificateSerialNumber = r.bytes();
          break;
        }
        case 3: {
          m.encryptedClientId = r.bytes();
          break;
        }
        case 4: {
          m.encryptedClientIdIv = r.bytes();
          break;
        }
        case 5: {
          m.encryptedPrivacyKey = r.bytes();
          break;
        }
        default:
          r.skipType(t & 7);
          break;
      }
    }
    return m;
  };
  EncryptedClientIdentification2.decodeDelimited = function decodeDelimited(reader) {
    if (!(reader instanceof $Reader)) reader = new $Reader(reader);
    return this.decode(reader, reader.uint32());
  };
  EncryptedClientIdentification2.fromObject = function fromObject(d) {
    if (d instanceof $root.EncryptedClientIdentification) return d;
    var m = new $root.EncryptedClientIdentification();
    if (d.providerId != null) {
      m.providerId = String(d.providerId);
    }
    if (d.serviceCertificateSerialNumber != null) {
      if (typeof d.serviceCertificateSerialNumber === "string")
        $util.base64.decode(
          d.serviceCertificateSerialNumber,
          m.serviceCertificateSerialNumber = $util.newBuffer(
            $util.base64.length(d.serviceCertificateSerialNumber)
          ),
          0
        );
      else if (d.serviceCertificateSerialNumber.length >= 0)
        m.serviceCertificateSerialNumber = d.serviceCertificateSerialNumber;
    }
    if (d.encryptedClientId != null) {
      if (typeof d.encryptedClientId === "string")
        $util.base64.decode(
          d.encryptedClientId,
          m.encryptedClientId = $util.newBuffer(
            $util.base64.length(d.encryptedClientId)
          ),
          0
        );
      else if (d.encryptedClientId.length >= 0)
        m.encryptedClientId = d.encryptedClientId;
    }
    if (d.encryptedClientIdIv != null) {
      if (typeof d.encryptedClientIdIv === "string")
        $util.base64.decode(
          d.encryptedClientIdIv,
          m.encryptedClientIdIv = $util.newBuffer(
            $util.base64.length(d.encryptedClientIdIv)
          ),
          0
        );
      else if (d.encryptedClientIdIv.length >= 0)
        m.encryptedClientIdIv = d.encryptedClientIdIv;
    }
    if (d.encryptedPrivacyKey != null) {
      if (typeof d.encryptedPrivacyKey === "string")
        $util.base64.decode(
          d.encryptedPrivacyKey,
          m.encryptedPrivacyKey = $util.newBuffer(
            $util.base64.length(d.encryptedPrivacyKey)
          ),
          0
        );
      else if (d.encryptedPrivacyKey.length >= 0)
        m.encryptedPrivacyKey = d.encryptedPrivacyKey;
    }
    return m;
  };
  EncryptedClientIdentification2.toObject = function toObject(m, o) {
    if (!o) o = {};
    var d = {};
    if (o.defaults) {
      d.providerId = "";
      if (o.bytes === String) d.serviceCertificateSerialNumber = "";
      else {
        d.serviceCertificateSerialNumber = [];
        if (o.bytes !== Array)
          d.serviceCertificateSerialNumber = $util.newBuffer(
            d.serviceCertificateSerialNumber
          );
      }
      if (o.bytes === String) d.encryptedClientId = "";
      else {
        d.encryptedClientId = [];
        if (o.bytes !== Array)
          d.encryptedClientId = $util.newBuffer(d.encryptedClientId);
      }
      if (o.bytes === String) d.encryptedClientIdIv = "";
      else {
        d.encryptedClientIdIv = [];
        if (o.bytes !== Array)
          d.encryptedClientIdIv = $util.newBuffer(d.encryptedClientIdIv);
      }
      if (o.bytes === String) d.encryptedPrivacyKey = "";
      else {
        d.encryptedPrivacyKey = [];
        if (o.bytes !== Array)
          d.encryptedPrivacyKey = $util.newBuffer(d.encryptedPrivacyKey);
      }
    }
    if (m.providerId != null && m.hasOwnProperty("providerId")) {
      d.providerId = m.providerId;
    }
    if (m.serviceCertificateSerialNumber != null && m.hasOwnProperty("serviceCertificateSerialNumber")) {
      d.serviceCertificateSerialNumber = o.bytes === String ? $util.base64.encode(
        m.serviceCertificateSerialNumber,
        0,
        m.serviceCertificateSerialNumber.length
      ) : o.bytes === Array ? Array.prototype.slice.call(m.serviceCertificateSerialNumber) : m.serviceCertificateSerialNumber;
    }
    if (m.encryptedClientId != null && m.hasOwnProperty("encryptedClientId")) {
      d.encryptedClientId = o.bytes === String ? $util.base64.encode(
        m.encryptedClientId,
        0,
        m.encryptedClientId.length
      ) : o.bytes === Array ? Array.prototype.slice.call(m.encryptedClientId) : m.encryptedClientId;
    }
    if (m.encryptedClientIdIv != null && m.hasOwnProperty("encryptedClientIdIv")) {
      d.encryptedClientIdIv = o.bytes === String ? $util.base64.encode(
        m.encryptedClientIdIv,
        0,
        m.encryptedClientIdIv.length
      ) : o.bytes === Array ? Array.prototype.slice.call(m.encryptedClientIdIv) : m.encryptedClientIdIv;
    }
    if (m.encryptedPrivacyKey != null && m.hasOwnProperty("encryptedPrivacyKey")) {
      d.encryptedPrivacyKey = o.bytes === String ? $util.base64.encode(
        m.encryptedPrivacyKey,
        0,
        m.encryptedPrivacyKey.length
      ) : o.bytes === Array ? Array.prototype.slice.call(m.encryptedPrivacyKey) : m.encryptedPrivacyKey;
    }
    return d;
  };
  EncryptedClientIdentification2.prototype.toJSON = function toJSON() {
    return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
  };
  EncryptedClientIdentification2.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
    if (typeUrlPrefix === void 0) {
      typeUrlPrefix = "type.googleapis.com";
    }
    return typeUrlPrefix + "/EncryptedClientIdentification";
  };
  return EncryptedClientIdentification2;
})();
var LicenseError = $root.LicenseError = (() => {
  function LicenseError2(p) {
    if (p) {
      for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
        if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
    }
  }
  LicenseError2.prototype.errorCode = 1;
  LicenseError2.create = function create(properties) {
    return new LicenseError2(properties);
  };
  LicenseError2.encode = function encode2(m, w) {
    if (!w) w = $Writer.create();
    if (m.errorCode != null && Object.hasOwnProperty.call(m, "errorCode"))
      w.uint32(8).int32(m.errorCode);
    return w;
  };
  LicenseError2.encodeDelimited = function encodeDelimited(message, writer) {
    return this.encode(message, writer).ldelim();
  };
  LicenseError2.decode = function decode2(r, l) {
    if (!(r instanceof $Reader)) r = $Reader.create(r);
    var c = l === void 0 ? r.len : r.pos + l, m = new $root.LicenseError();
    while (r.pos < c) {
      var t = r.uint32();
      switch (t >>> 3) {
        case 1: {
          m.errorCode = r.int32();
          break;
        }
        default:
          r.skipType(t & 7);
          break;
      }
    }
    return m;
  };
  LicenseError2.decodeDelimited = function decodeDelimited(reader) {
    if (!(reader instanceof $Reader)) reader = new $Reader(reader);
    return this.decode(reader, reader.uint32());
  };
  LicenseError2.fromObject = function fromObject(d) {
    if (d instanceof $root.LicenseError) return d;
    var m = new $root.LicenseError();
    switch (d.errorCode) {
      default:
        if (typeof d.errorCode === "number") {
          m.errorCode = d.errorCode;
          break;
        }
        break;
      case "INVALID_DEVICE_CERTIFICATE":
      case 1:
        m.errorCode = 1;
        break;
      case "REVOKED_DEVICE_CERTIFICATE":
      case 2:
        m.errorCode = 2;
        break;
      case "SERVICE_UNAVAILABLE":
      case 3:
        m.errorCode = 3;
        break;
    }
    return m;
  };
  LicenseError2.toObject = function toObject(m, o) {
    if (!o) o = {};
    var d = {};
    if (o.defaults) {
      d.errorCode = o.enums === String ? "INVALID_DEVICE_CERTIFICATE" : 1;
    }
    if (m.errorCode != null && m.hasOwnProperty("errorCode")) {
      d.errorCode = o.enums === String ? $root.LicenseError.Error[m.errorCode] === void 0 ? m.errorCode : $root.LicenseError.Error[m.errorCode] : m.errorCode;
    }
    return d;
  };
  LicenseError2.prototype.toJSON = function toJSON() {
    return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
  };
  LicenseError2.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
    if (typeUrlPrefix === void 0) {
      typeUrlPrefix = "type.googleapis.com";
    }
    return typeUrlPrefix + "/LicenseError";
  };
  LicenseError2.Error = function() {
    const valuesById = {}, values = Object.create(valuesById);
    values[valuesById[1] = "INVALID_DEVICE_CERTIFICATE"] = 1;
    values[valuesById[2] = "REVOKED_DEVICE_CERTIFICATE"] = 2;
    values[valuesById[3] = "SERVICE_UNAVAILABLE"] = 3;
    return values;
  }();
  return LicenseError2;
})();
var DrmCertificate = $root.DrmCertificate = (() => {
  function DrmCertificate2(p) {
    this.serviceTypes = [];
    if (p) {
      for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
        if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
    }
  }
  DrmCertificate2.prototype.type = 0;
  DrmCertificate2.prototype.serialNumber = $util.newBuffer([]);
  DrmCertificate2.prototype.creationTimeSeconds = 0;
  DrmCertificate2.prototype.expirationTimeSeconds = 0;
  DrmCertificate2.prototype.publicKey = $util.newBuffer([]);
  DrmCertificate2.prototype.systemId = 0;
  DrmCertificate2.prototype.testDeviceDeprecated = false;
  DrmCertificate2.prototype.providerId = "";
  DrmCertificate2.prototype.serviceTypes = $util.emptyArray;
  DrmCertificate2.prototype.algorithm = 1;
  DrmCertificate2.prototype.rotId = $util.newBuffer([]);
  DrmCertificate2.prototype.encryptionKey = null;
  DrmCertificate2.create = function create(properties) {
    return new DrmCertificate2(properties);
  };
  DrmCertificate2.encode = function encode2(m, w) {
    if (!w) w = $Writer.create();
    if (m.type != null && Object.hasOwnProperty.call(m, "type"))
      w.uint32(8).int32(m.type);
    if (m.serialNumber != null && Object.hasOwnProperty.call(m, "serialNumber"))
      w.uint32(18).bytes(m.serialNumber);
    if (m.creationTimeSeconds != null && Object.hasOwnProperty.call(m, "creationTimeSeconds"))
      w.uint32(24).uint32(m.creationTimeSeconds);
    if (m.publicKey != null && Object.hasOwnProperty.call(m, "publicKey"))
      w.uint32(34).bytes(m.publicKey);
    if (m.systemId != null && Object.hasOwnProperty.call(m, "systemId"))
      w.uint32(40).uint32(m.systemId);
    if (m.testDeviceDeprecated != null && Object.hasOwnProperty.call(m, "testDeviceDeprecated"))
      w.uint32(48).bool(m.testDeviceDeprecated);
    if (m.providerId != null && Object.hasOwnProperty.call(m, "providerId"))
      w.uint32(58).string(m.providerId);
    if (m.serviceTypes != null && m.serviceTypes.length) {
      for (var i = 0; i < m.serviceTypes.length; ++i)
        w.uint32(64).int32(m.serviceTypes[i]);
    }
    if (m.algorithm != null && Object.hasOwnProperty.call(m, "algorithm"))
      w.uint32(72).int32(m.algorithm);
    if (m.rotId != null && Object.hasOwnProperty.call(m, "rotId"))
      w.uint32(82).bytes(m.rotId);
    if (m.encryptionKey != null && Object.hasOwnProperty.call(m, "encryptionKey"))
      $root.DrmCertificate.EncryptionKey.encode(
        m.encryptionKey,
        w.uint32(90).fork()
      ).ldelim();
    if (m.expirationTimeSeconds != null && Object.hasOwnProperty.call(m, "expirationTimeSeconds"))
      w.uint32(96).uint32(m.expirationTimeSeconds);
    return w;
  };
  DrmCertificate2.encodeDelimited = function encodeDelimited(message, writer) {
    return this.encode(message, writer).ldelim();
  };
  DrmCertificate2.decode = function decode2(r, l) {
    if (!(r instanceof $Reader)) r = $Reader.create(r);
    var c = l === void 0 ? r.len : r.pos + l, m = new $root.DrmCertificate();
    while (r.pos < c) {
      var t = r.uint32();
      switch (t >>> 3) {
        case 1: {
          m.type = r.int32();
          break;
        }
        case 2: {
          m.serialNumber = r.bytes();
          break;
        }
        case 3: {
          m.creationTimeSeconds = r.uint32();
          break;
        }
        case 12: {
          m.expirationTimeSeconds = r.uint32();
          break;
        }
        case 4: {
          m.publicKey = r.bytes();
          break;
        }
        case 5: {
          m.systemId = r.uint32();
          break;
        }
        case 6: {
          m.testDeviceDeprecated = r.bool();
          break;
        }
        case 7: {
          m.providerId = r.string();
          break;
        }
        case 8: {
          if (!(m.serviceTypes && m.serviceTypes.length)) m.serviceTypes = [];
          if ((t & 7) === 2) {
            var c2 = r.uint32() + r.pos;
            while (r.pos < c2) m.serviceTypes.push(r.int32());
          } else m.serviceTypes.push(r.int32());
          break;
        }
        case 9: {
          m.algorithm = r.int32();
          break;
        }
        case 10: {
          m.rotId = r.bytes();
          break;
        }
        case 11: {
          m.encryptionKey = $root.DrmCertificate.EncryptionKey.decode(
            r,
            r.uint32()
          );
          break;
        }
        default:
          r.skipType(t & 7);
          break;
      }
    }
    return m;
  };
  DrmCertificate2.decodeDelimited = function decodeDelimited(reader) {
    if (!(reader instanceof $Reader)) reader = new $Reader(reader);
    return this.decode(reader, reader.uint32());
  };
  DrmCertificate2.fromObject = function fromObject(d) {
    if (d instanceof $root.DrmCertificate) return d;
    var m = new $root.DrmCertificate();
    switch (d.type) {
      default:
        if (typeof d.type === "number") {
          m.type = d.type;
          break;
        }
        break;
      case "ROOT":
      case 0:
        m.type = 0;
        break;
      case "DEVICE_MODEL":
      case 1:
        m.type = 1;
        break;
      case "DEVICE":
      case 2:
        m.type = 2;
        break;
      case "SERVICE":
      case 3:
        m.type = 3;
        break;
      case "PROVISIONER":
      case 4:
        m.type = 4;
        break;
    }
    if (d.serialNumber != null) {
      if (typeof d.serialNumber === "string")
        $util.base64.decode(
          d.serialNumber,
          m.serialNumber = $util.newBuffer(
            $util.base64.length(d.serialNumber)
          ),
          0
        );
      else if (d.serialNumber.length >= 0) m.serialNumber = d.serialNumber;
    }
    if (d.creationTimeSeconds != null) {
      m.creationTimeSeconds = d.creationTimeSeconds >>> 0;
    }
    if (d.expirationTimeSeconds != null) {
      m.expirationTimeSeconds = d.expirationTimeSeconds >>> 0;
    }
    if (d.publicKey != null) {
      if (typeof d.publicKey === "string")
        $util.base64.decode(
          d.publicKey,
          m.publicKey = $util.newBuffer($util.base64.length(d.publicKey)),
          0
        );
      else if (d.publicKey.length >= 0) m.publicKey = d.publicKey;
    }
    if (d.systemId != null) {
      m.systemId = d.systemId >>> 0;
    }
    if (d.testDeviceDeprecated != null) {
      m.testDeviceDeprecated = Boolean(d.testDeviceDeprecated);
    }
    if (d.providerId != null) {
      m.providerId = String(d.providerId);
    }
    if (d.serviceTypes) {
      if (!Array.isArray(d.serviceTypes))
        throw TypeError(".DrmCertificate.serviceTypes: array expected");
      m.serviceTypes = [];
      for (var i = 0; i < d.serviceTypes.length; ++i) {
        switch (d.serviceTypes[i]) {
          default:
            if (typeof d.serviceTypes[i] === "number") {
              m.serviceTypes[i] = d.serviceTypes[i];
              break;
            }
          case "UNKNOWN_SERVICE_TYPE":
          case 0:
            m.serviceTypes[i] = 0;
            break;
          case "LICENSE_SERVER_SDK":
          case 1:
            m.serviceTypes[i] = 1;
            break;
          case "LICENSE_SERVER_PROXY_SDK":
          case 2:
            m.serviceTypes[i] = 2;
            break;
          case "PROVISIONING_SDK":
          case 3:
            m.serviceTypes[i] = 3;
            break;
          case "CAS_PROXY_SDK":
          case 4:
            m.serviceTypes[i] = 4;
            break;
        }
      }
    }
    switch (d.algorithm) {
      case "UNKNOWN_ALGORITHM":
      case 0:
        m.algorithm = 0;
        break;
      default:
        if (typeof d.algorithm === "number") {
          m.algorithm = d.algorithm;
          break;
        }
        break;
      case "RSA":
      case 1:
        m.algorithm = 1;
        break;
      case "ECC_SECP256R1":
      case 2:
        m.algorithm = 2;
        break;
      case "ECC_SECP384R1":
      case 3:
        m.algorithm = 3;
        break;
      case "ECC_SECP521R1":
      case 4:
        m.algorithm = 4;
        break;
    }
    if (d.rotId != null) {
      if (typeof d.rotId === "string")
        $util.base64.decode(
          d.rotId,
          m.rotId = $util.newBuffer($util.base64.length(d.rotId)),
          0
        );
      else if (d.rotId.length >= 0) m.rotId = d.rotId;
    }
    if (d.encryptionKey != null) {
      if (typeof d.encryptionKey !== "object")
        throw TypeError(".DrmCertificate.encryptionKey: object expected");
      m.encryptionKey = $root.DrmCertificate.EncryptionKey.fromObject(
        d.encryptionKey
      );
    }
    return m;
  };
  DrmCertificate2.toObject = function toObject(m, o) {
    if (!o) o = {};
    var d = {};
    if (o.arrays || o.defaults) {
      d.serviceTypes = [];
    }
    if (o.defaults) {
      d.type = o.enums === String ? "ROOT" : 0;
      if (o.bytes === String) d.serialNumber = "";
      else {
        d.serialNumber = [];
        if (o.bytes !== Array) d.serialNumber = $util.newBuffer(d.serialNumber);
      }
      d.creationTimeSeconds = 0;
      if (o.bytes === String) d.publicKey = "";
      else {
        d.publicKey = [];
        if (o.bytes !== Array) d.publicKey = $util.newBuffer(d.publicKey);
      }
      d.systemId = 0;
      d.testDeviceDeprecated = false;
      d.providerId = "";
      d.algorithm = o.enums === String ? "RSA" : 1;
      if (o.bytes === String) d.rotId = "";
      else {
        d.rotId = [];
        if (o.bytes !== Array) d.rotId = $util.newBuffer(d.rotId);
      }
      d.encryptionKey = null;
      d.expirationTimeSeconds = 0;
    }
    if (m.type != null && m.hasOwnProperty("type")) {
      d.type = o.enums === String ? $root.DrmCertificate.Type[m.type] === void 0 ? m.type : $root.DrmCertificate.Type[m.type] : m.type;
    }
    if (m.serialNumber != null && m.hasOwnProperty("serialNumber")) {
      d.serialNumber = o.bytes === String ? $util.base64.encode(m.serialNumber, 0, m.serialNumber.length) : o.bytes === Array ? Array.prototype.slice.call(m.serialNumber) : m.serialNumber;
    }
    if (m.creationTimeSeconds != null && m.hasOwnProperty("creationTimeSeconds")) {
      d.creationTimeSeconds = m.creationTimeSeconds;
    }
    if (m.publicKey != null && m.hasOwnProperty("publicKey")) {
      d.publicKey = o.bytes === String ? $util.base64.encode(m.publicKey, 0, m.publicKey.length) : o.bytes === Array ? Array.prototype.slice.call(m.publicKey) : m.publicKey;
    }
    if (m.systemId != null && m.hasOwnProperty("systemId")) {
      d.systemId = m.systemId;
    }
    if (m.testDeviceDeprecated != null && m.hasOwnProperty("testDeviceDeprecated")) {
      d.testDeviceDeprecated = m.testDeviceDeprecated;
    }
    if (m.providerId != null && m.hasOwnProperty("providerId")) {
      d.providerId = m.providerId;
    }
    if (m.serviceTypes && m.serviceTypes.length) {
      d.serviceTypes = [];
      for (var j = 0; j < m.serviceTypes.length; ++j) {
        d.serviceTypes[j] = o.enums === String ? $root.DrmCertificate.ServiceType[m.serviceTypes[j]] === void 0 ? m.serviceTypes[j] : $root.DrmCertificate.ServiceType[m.serviceTypes[j]] : m.serviceTypes[j];
      }
    }
    if (m.algorithm != null && m.hasOwnProperty("algorithm")) {
      d.algorithm = o.enums === String ? $root.DrmCertificate.Algorithm[m.algorithm] === void 0 ? m.algorithm : $root.DrmCertificate.Algorithm[m.algorithm] : m.algorithm;
    }
    if (m.rotId != null && m.hasOwnProperty("rotId")) {
      d.rotId = o.bytes === String ? $util.base64.encode(m.rotId, 0, m.rotId.length) : o.bytes === Array ? Array.prototype.slice.call(m.rotId) : m.rotId;
    }
    if (m.encryptionKey != null && m.hasOwnProperty("encryptionKey")) {
      d.encryptionKey = $root.DrmCertificate.EncryptionKey.toObject(
        m.encryptionKey,
        o
      );
    }
    if (m.expirationTimeSeconds != null && m.hasOwnProperty("expirationTimeSeconds")) {
      d.expirationTimeSeconds = m.expirationTimeSeconds;
    }
    return d;
  };
  DrmCertificate2.prototype.toJSON = function toJSON() {
    return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
  };
  DrmCertificate2.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
    if (typeUrlPrefix === void 0) {
      typeUrlPrefix = "type.googleapis.com";
    }
    return typeUrlPrefix + "/DrmCertificate";
  };
  DrmCertificate2.Type = function() {
    const valuesById = {}, values = Object.create(valuesById);
    values[valuesById[0] = "ROOT"] = 0;
    values[valuesById[1] = "DEVICE_MODEL"] = 1;
    values[valuesById[2] = "DEVICE"] = 2;
    values[valuesById[3] = "SERVICE"] = 3;
    values[valuesById[4] = "PROVISIONER"] = 4;
    return values;
  }();
  DrmCertificate2.ServiceType = function() {
    const valuesById = {}, values = Object.create(valuesById);
    values[valuesById[0] = "UNKNOWN_SERVICE_TYPE"] = 0;
    values[valuesById[1] = "LICENSE_SERVER_SDK"] = 1;
    values[valuesById[2] = "LICENSE_SERVER_PROXY_SDK"] = 2;
    values[valuesById[3] = "PROVISIONING_SDK"] = 3;
    values[valuesById[4] = "CAS_PROXY_SDK"] = 4;
    return values;
  }();
  DrmCertificate2.Algorithm = function() {
    const valuesById = {}, values = Object.create(valuesById);
    values[valuesById[0] = "UNKNOWN_ALGORITHM"] = 0;
    values[valuesById[1] = "RSA"] = 1;
    values[valuesById[2] = "ECC_SECP256R1"] = 2;
    values[valuesById[3] = "ECC_SECP384R1"] = 3;
    values[valuesById[4] = "ECC_SECP521R1"] = 4;
    return values;
  }();
  DrmCertificate2.EncryptionKey = function() {
    function EncryptionKey(p) {
      if (p) {
        for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
          if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
      }
    }
    EncryptionKey.prototype.publicKey = $util.newBuffer([]);
    EncryptionKey.prototype.algorithm = 1;
    EncryptionKey.create = function create(properties) {
      return new EncryptionKey(properties);
    };
    EncryptionKey.encode = function encode2(m, w) {
      if (!w) w = $Writer.create();
      if (m.publicKey != null && Object.hasOwnProperty.call(m, "publicKey"))
        w.uint32(10).bytes(m.publicKey);
      if (m.algorithm != null && Object.hasOwnProperty.call(m, "algorithm"))
        w.uint32(16).int32(m.algorithm);
      return w;
    };
    EncryptionKey.encodeDelimited = function encodeDelimited(message, writer) {
      return this.encode(message, writer).ldelim();
    };
    EncryptionKey.decode = function decode2(r, l) {
      if (!(r instanceof $Reader)) r = $Reader.create(r);
      var c = l === void 0 ? r.len : r.pos + l, m = new $root.DrmCertificate.EncryptionKey();
      while (r.pos < c) {
        var t = r.uint32();
        switch (t >>> 3) {
          case 1: {
            m.publicKey = r.bytes();
            break;
          }
          case 2: {
            m.algorithm = r.int32();
            break;
          }
          default:
            r.skipType(t & 7);
            break;
        }
      }
      return m;
    };
    EncryptionKey.decodeDelimited = function decodeDelimited(reader) {
      if (!(reader instanceof $Reader)) reader = new $Reader(reader);
      return this.decode(reader, reader.uint32());
    };
    EncryptionKey.fromObject = function fromObject(d) {
      if (d instanceof $root.DrmCertificate.EncryptionKey) return d;
      var m = new $root.DrmCertificate.EncryptionKey();
      if (d.publicKey != null) {
        if (typeof d.publicKey === "string")
          $util.base64.decode(
            d.publicKey,
            m.publicKey = $util.newBuffer($util.base64.length(d.publicKey)),
            0
          );
        else if (d.publicKey.length >= 0) m.publicKey = d.publicKey;
      }
      switch (d.algorithm) {
        case "UNKNOWN_ALGORITHM":
        case 0:
          m.algorithm = 0;
          break;
        default:
          if (typeof d.algorithm === "number") {
            m.algorithm = d.algorithm;
            break;
          }
          break;
        case "RSA":
        case 1:
          m.algorithm = 1;
          break;
        case "ECC_SECP256R1":
        case 2:
          m.algorithm = 2;
          break;
        case "ECC_SECP384R1":
        case 3:
          m.algorithm = 3;
          break;
        case "ECC_SECP521R1":
        case 4:
          m.algorithm = 4;
          break;
      }
      return m;
    };
    EncryptionKey.toObject = function toObject(m, o) {
      if (!o) o = {};
      var d = {};
      if (o.defaults) {
        if (o.bytes === String) d.publicKey = "";
        else {
          d.publicKey = [];
          if (o.bytes !== Array) d.publicKey = $util.newBuffer(d.publicKey);
        }
        d.algorithm = o.enums === String ? "RSA" : 1;
      }
      if (m.publicKey != null && m.hasOwnProperty("publicKey")) {
        d.publicKey = o.bytes === String ? $util.base64.encode(m.publicKey, 0, m.publicKey.length) : o.bytes === Array ? Array.prototype.slice.call(m.publicKey) : m.publicKey;
      }
      if (m.algorithm != null && m.hasOwnProperty("algorithm")) {
        d.algorithm = o.enums === String ? $root.DrmCertificate.Algorithm[m.algorithm] === void 0 ? m.algorithm : $root.DrmCertificate.Algorithm[m.algorithm] : m.algorithm;
      }
      return d;
    };
    EncryptionKey.prototype.toJSON = function toJSON() {
      return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
    };
    EncryptionKey.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
      if (typeUrlPrefix === void 0) {
        typeUrlPrefix = "type.googleapis.com";
      }
      return typeUrlPrefix + "/DrmCertificate.EncryptionKey";
    };
    return EncryptionKey;
  }();
  return DrmCertificate2;
})();
var SignedDrmCertificate = $root.SignedDrmCertificate = (() => {
  function SignedDrmCertificate3(p) {
    if (p) {
      for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
        if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
    }
  }
  SignedDrmCertificate3.prototype.drmCertificate = $util.newBuffer([]);
  SignedDrmCertificate3.prototype.signature = $util.newBuffer([]);
  SignedDrmCertificate3.prototype.signer = null;
  SignedDrmCertificate3.prototype.hashAlgorithm = 0;
  SignedDrmCertificate3.create = function create(properties) {
    return new SignedDrmCertificate3(properties);
  };
  SignedDrmCertificate3.encode = function encode2(m, w) {
    if (!w) w = $Writer.create();
    if (m.drmCertificate != null && Object.hasOwnProperty.call(m, "drmCertificate"))
      w.uint32(10).bytes(m.drmCertificate);
    if (m.signature != null && Object.hasOwnProperty.call(m, "signature"))
      w.uint32(18).bytes(m.signature);
    if (m.signer != null && Object.hasOwnProperty.call(m, "signer"))
      $root.SignedDrmCertificate.encode(m.signer, w.uint32(26).fork()).ldelim();
    if (m.hashAlgorithm != null && Object.hasOwnProperty.call(m, "hashAlgorithm"))
      w.uint32(32).int32(m.hashAlgorithm);
    return w;
  };
  SignedDrmCertificate3.encodeDelimited = function encodeDelimited(message, writer) {
    return this.encode(message, writer).ldelim();
  };
  SignedDrmCertificate3.decode = function decode2(r, l) {
    if (!(r instanceof $Reader)) r = $Reader.create(r);
    var c = l === void 0 ? r.len : r.pos + l, m = new $root.SignedDrmCertificate();
    while (r.pos < c) {
      var t = r.uint32();
      switch (t >>> 3) {
        case 1: {
          m.drmCertificate = r.bytes();
          break;
        }
        case 2: {
          m.signature = r.bytes();
          break;
        }
        case 3: {
          m.signer = $root.SignedDrmCertificate.decode(r, r.uint32());
          break;
        }
        case 4: {
          m.hashAlgorithm = r.int32();
          break;
        }
        default:
          r.skipType(t & 7);
          break;
      }
    }
    return m;
  };
  SignedDrmCertificate3.decodeDelimited = function decodeDelimited(reader) {
    if (!(reader instanceof $Reader)) reader = new $Reader(reader);
    return this.decode(reader, reader.uint32());
  };
  SignedDrmCertificate3.fromObject = function fromObject(d) {
    if (d instanceof $root.SignedDrmCertificate) return d;
    var m = new $root.SignedDrmCertificate();
    if (d.drmCertificate != null) {
      if (typeof d.drmCertificate === "string")
        $util.base64.decode(
          d.drmCertificate,
          m.drmCertificate = $util.newBuffer(
            $util.base64.length(d.drmCertificate)
          ),
          0
        );
      else if (d.drmCertificate.length >= 0)
        m.drmCertificate = d.drmCertificate;
    }
    if (d.signature != null) {
      if (typeof d.signature === "string")
        $util.base64.decode(
          d.signature,
          m.signature = $util.newBuffer($util.base64.length(d.signature)),
          0
        );
      else if (d.signature.length >= 0) m.signature = d.signature;
    }
    if (d.signer != null) {
      if (typeof d.signer !== "object")
        throw TypeError(".SignedDrmCertificate.signer: object expected");
      m.signer = $root.SignedDrmCertificate.fromObject(d.signer);
    }
    switch (d.hashAlgorithm) {
      default:
        if (typeof d.hashAlgorithm === "number") {
          m.hashAlgorithm = d.hashAlgorithm;
          break;
        }
        break;
      case "HASH_ALGORITHM_UNSPECIFIED":
      case 0:
        m.hashAlgorithm = 0;
        break;
      case "HASH_ALGORITHM_SHA_1":
      case 1:
        m.hashAlgorithm = 1;
        break;
      case "HASH_ALGORITHM_SHA_256":
      case 2:
        m.hashAlgorithm = 2;
        break;
      case "HASH_ALGORITHM_SHA_384":
      case 3:
        m.hashAlgorithm = 3;
        break;
    }
    return m;
  };
  SignedDrmCertificate3.toObject = function toObject(m, o) {
    if (!o) o = {};
    var d = {};
    if (o.defaults) {
      if (o.bytes === String) d.drmCertificate = "";
      else {
        d.drmCertificate = [];
        if (o.bytes !== Array)
          d.drmCertificate = $util.newBuffer(d.drmCertificate);
      }
      if (o.bytes === String) d.signature = "";
      else {
        d.signature = [];
        if (o.bytes !== Array) d.signature = $util.newBuffer(d.signature);
      }
      d.signer = null;
      d.hashAlgorithm = o.enums === String ? "HASH_ALGORITHM_UNSPECIFIED" : 0;
    }
    if (m.drmCertificate != null && m.hasOwnProperty("drmCertificate")) {
      d.drmCertificate = o.bytes === String ? $util.base64.encode(m.drmCertificate, 0, m.drmCertificate.length) : o.bytes === Array ? Array.prototype.slice.call(m.drmCertificate) : m.drmCertificate;
    }
    if (m.signature != null && m.hasOwnProperty("signature")) {
      d.signature = o.bytes === String ? $util.base64.encode(m.signature, 0, m.signature.length) : o.bytes === Array ? Array.prototype.slice.call(m.signature) : m.signature;
    }
    if (m.signer != null && m.hasOwnProperty("signer")) {
      d.signer = $root.SignedDrmCertificate.toObject(m.signer, o);
    }
    if (m.hashAlgorithm != null && m.hasOwnProperty("hashAlgorithm")) {
      d.hashAlgorithm = o.enums === String ? $root.HashAlgorithmProto[m.hashAlgorithm] === void 0 ? m.hashAlgorithm : $root.HashAlgorithmProto[m.hashAlgorithm] : m.hashAlgorithm;
    }
    return d;
  };
  SignedDrmCertificate3.prototype.toJSON = function toJSON() {
    return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
  };
  SignedDrmCertificate3.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
    if (typeUrlPrefix === void 0) {
      typeUrlPrefix = "type.googleapis.com";
    }
    return typeUrlPrefix + "/SignedDrmCertificate";
  };
  return SignedDrmCertificate3;
})();
var WidevinePsshData = $root.WidevinePsshData = (() => {
  function WidevinePsshData2(p) {
    this.keyIds = [];
    this.groupIds = [];
    this.entitledKeys = [];
    if (p) {
      for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
        if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
    }
  }
  WidevinePsshData2.prototype.keyIds = $util.emptyArray;
  WidevinePsshData2.prototype.contentId = $util.newBuffer([]);
  WidevinePsshData2.prototype.cryptoPeriodIndex = 0;
  WidevinePsshData2.prototype.protectionScheme = 0;
  WidevinePsshData2.prototype.cryptoPeriodSeconds = 0;
  WidevinePsshData2.prototype.type = 0;
  WidevinePsshData2.prototype.keySequence = 0;
  WidevinePsshData2.prototype.groupIds = $util.emptyArray;
  WidevinePsshData2.prototype.entitledKeys = $util.emptyArray;
  WidevinePsshData2.prototype.videoFeature = "";
  WidevinePsshData2.prototype.algorithm = 0;
  WidevinePsshData2.prototype.provider = "";
  WidevinePsshData2.prototype.trackType = "";
  WidevinePsshData2.prototype.policy = "";
  WidevinePsshData2.prototype.groupedLicense = $util.newBuffer([]);
  WidevinePsshData2.create = function create(properties) {
    return new WidevinePsshData2(properties);
  };
  WidevinePsshData2.encode = function encode2(m, w) {
    if (!w) w = $Writer.create();
    if (m.algorithm != null && Object.hasOwnProperty.call(m, "algorithm"))
      w.uint32(8).int32(m.algorithm);
    if (m.keyIds != null && m.keyIds.length) {
      for (var i = 0; i < m.keyIds.length; ++i) w.uint32(18).bytes(m.keyIds[i]);
    }
    if (m.provider != null && Object.hasOwnProperty.call(m, "provider"))
      w.uint32(26).string(m.provider);
    if (m.contentId != null && Object.hasOwnProperty.call(m, "contentId"))
      w.uint32(34).bytes(m.contentId);
    if (m.trackType != null && Object.hasOwnProperty.call(m, "trackType"))
      w.uint32(42).string(m.trackType);
    if (m.policy != null && Object.hasOwnProperty.call(m, "policy"))
      w.uint32(50).string(m.policy);
    if (m.cryptoPeriodIndex != null && Object.hasOwnProperty.call(m, "cryptoPeriodIndex"))
      w.uint32(56).uint32(m.cryptoPeriodIndex);
    if (m.groupedLicense != null && Object.hasOwnProperty.call(m, "groupedLicense"))
      w.uint32(66).bytes(m.groupedLicense);
    if (m.protectionScheme != null && Object.hasOwnProperty.call(m, "protectionScheme"))
      w.uint32(72).uint32(m.protectionScheme);
    if (m.cryptoPeriodSeconds != null && Object.hasOwnProperty.call(m, "cryptoPeriodSeconds"))
      w.uint32(80).uint32(m.cryptoPeriodSeconds);
    if (m.type != null && Object.hasOwnProperty.call(m, "type"))
      w.uint32(88).int32(m.type);
    if (m.keySequence != null && Object.hasOwnProperty.call(m, "keySequence"))
      w.uint32(96).uint32(m.keySequence);
    if (m.groupIds != null && m.groupIds.length) {
      for (var i = 0; i < m.groupIds.length; ++i)
        w.uint32(106).bytes(m.groupIds[i]);
    }
    if (m.entitledKeys != null && m.entitledKeys.length) {
      for (var i = 0; i < m.entitledKeys.length; ++i)
        $root.WidevinePsshData.EntitledKey.encode(
          m.entitledKeys[i],
          w.uint32(114).fork()
        ).ldelim();
    }
    if (m.videoFeature != null && Object.hasOwnProperty.call(m, "videoFeature"))
      w.uint32(122).string(m.videoFeature);
    return w;
  };
  WidevinePsshData2.encodeDelimited = function encodeDelimited(message, writer) {
    return this.encode(message, writer).ldelim();
  };
  WidevinePsshData2.decode = function decode2(r, l) {
    if (!(r instanceof $Reader)) r = $Reader.create(r);
    var c = l === void 0 ? r.len : r.pos + l, m = new $root.WidevinePsshData();
    while (r.pos < c) {
      var t = r.uint32();
      switch (t >>> 3) {
        case 2: {
          if (!(m.keyIds && m.keyIds.length)) m.keyIds = [];
          m.keyIds.push(r.bytes());
          break;
        }
        case 4: {
          m.contentId = r.bytes();
          break;
        }
        case 7: {
          m.cryptoPeriodIndex = r.uint32();
          break;
        }
        case 9: {
          m.protectionScheme = r.uint32();
          break;
        }
        case 10: {
          m.cryptoPeriodSeconds = r.uint32();
          break;
        }
        case 11: {
          m.type = r.int32();
          break;
        }
        case 12: {
          m.keySequence = r.uint32();
          break;
        }
        case 13: {
          if (!(m.groupIds && m.groupIds.length)) m.groupIds = [];
          m.groupIds.push(r.bytes());
          break;
        }
        case 14: {
          if (!(m.entitledKeys && m.entitledKeys.length)) m.entitledKeys = [];
          m.entitledKeys.push(
            $root.WidevinePsshData.EntitledKey.decode(r, r.uint32())
          );
          break;
        }
        case 15: {
          m.videoFeature = r.string();
          break;
        }
        case 1: {
          m.algorithm = r.int32();
          break;
        }
        case 3: {
          m.provider = r.string();
          break;
        }
        case 5: {
          m.trackType = r.string();
          break;
        }
        case 6: {
          m.policy = r.string();
          break;
        }
        case 8: {
          m.groupedLicense = r.bytes();
          break;
        }
        default:
          r.skipType(t & 7);
          break;
      }
    }
    return m;
  };
  WidevinePsshData2.decodeDelimited = function decodeDelimited(reader) {
    if (!(reader instanceof $Reader)) reader = new $Reader(reader);
    return this.decode(reader, reader.uint32());
  };
  WidevinePsshData2.fromObject = function fromObject(d) {
    if (d instanceof $root.WidevinePsshData) return d;
    var m = new $root.WidevinePsshData();
    if (d.keyIds) {
      if (!Array.isArray(d.keyIds))
        throw TypeError(".WidevinePsshData.keyIds: array expected");
      m.keyIds = [];
      for (var i = 0; i < d.keyIds.length; ++i) {
        if (typeof d.keyIds[i] === "string")
          $util.base64.decode(
            d.keyIds[i],
            m.keyIds[i] = $util.newBuffer($util.base64.length(d.keyIds[i])),
            0
          );
        else if (d.keyIds[i].length >= 0) m.keyIds[i] = d.keyIds[i];
      }
    }
    if (d.contentId != null) {
      if (typeof d.contentId === "string")
        $util.base64.decode(
          d.contentId,
          m.contentId = $util.newBuffer($util.base64.length(d.contentId)),
          0
        );
      else if (d.contentId.length >= 0) m.contentId = d.contentId;
    }
    if (d.cryptoPeriodIndex != null) {
      m.cryptoPeriodIndex = d.cryptoPeriodIndex >>> 0;
    }
    if (d.protectionScheme != null) {
      m.protectionScheme = d.protectionScheme >>> 0;
    }
    if (d.cryptoPeriodSeconds != null) {
      m.cryptoPeriodSeconds = d.cryptoPeriodSeconds >>> 0;
    }
    switch (d.type) {
      default:
        if (typeof d.type === "number") {
          m.type = d.type;
          break;
        }
        break;
      case "SINGLE":
      case 0:
        m.type = 0;
        break;
      case "ENTITLEMENT":
      case 1:
        m.type = 1;
        break;
      case "ENTITLED_KEY":
      case 2:
        m.type = 2;
        break;
    }
    if (d.keySequence != null) {
      m.keySequence = d.keySequence >>> 0;
    }
    if (d.groupIds) {
      if (!Array.isArray(d.groupIds))
        throw TypeError(".WidevinePsshData.groupIds: array expected");
      m.groupIds = [];
      for (var i = 0; i < d.groupIds.length; ++i) {
        if (typeof d.groupIds[i] === "string")
          $util.base64.decode(
            d.groupIds[i],
            m.groupIds[i] = $util.newBuffer(
              $util.base64.length(d.groupIds[i])
            ),
            0
          );
        else if (d.groupIds[i].length >= 0) m.groupIds[i] = d.groupIds[i];
      }
    }
    if (d.entitledKeys) {
      if (!Array.isArray(d.entitledKeys))
        throw TypeError(".WidevinePsshData.entitledKeys: array expected");
      m.entitledKeys = [];
      for (var i = 0; i < d.entitledKeys.length; ++i) {
        if (typeof d.entitledKeys[i] !== "object")
          throw TypeError(".WidevinePsshData.entitledKeys: object expected");
        m.entitledKeys[i] = $root.WidevinePsshData.EntitledKey.fromObject(
          d.entitledKeys[i]
        );
      }
    }
    if (d.videoFeature != null) {
      m.videoFeature = String(d.videoFeature);
    }
    switch (d.algorithm) {
      default:
        if (typeof d.algorithm === "number") {
          m.algorithm = d.algorithm;
          break;
        }
        break;
      case "UNENCRYPTED":
      case 0:
        m.algorithm = 0;
        break;
      case "AESCTR":
      case 1:
        m.algorithm = 1;
        break;
    }
    if (d.provider != null) {
      m.provider = String(d.provider);
    }
    if (d.trackType != null) {
      m.trackType = String(d.trackType);
    }
    if (d.policy != null) {
      m.policy = String(d.policy);
    }
    if (d.groupedLicense != null) {
      if (typeof d.groupedLicense === "string")
        $util.base64.decode(
          d.groupedLicense,
          m.groupedLicense = $util.newBuffer(
            $util.base64.length(d.groupedLicense)
          ),
          0
        );
      else if (d.groupedLicense.length >= 0)
        m.groupedLicense = d.groupedLicense;
    }
    return m;
  };
  WidevinePsshData2.toObject = function toObject(m, o) {
    if (!o) o = {};
    var d = {};
    if (o.arrays || o.defaults) {
      d.keyIds = [];
      d.groupIds = [];
      d.entitledKeys = [];
    }
    if (o.defaults) {
      d.algorithm = o.enums === String ? "UNENCRYPTED" : 0;
      d.provider = "";
      if (o.bytes === String) d.contentId = "";
      else {
        d.contentId = [];
        if (o.bytes !== Array) d.contentId = $util.newBuffer(d.contentId);
      }
      d.trackType = "";
      d.policy = "";
      d.cryptoPeriodIndex = 0;
      if (o.bytes === String) d.groupedLicense = "";
      else {
        d.groupedLicense = [];
        if (o.bytes !== Array)
          d.groupedLicense = $util.newBuffer(d.groupedLicense);
      }
      d.protectionScheme = 0;
      d.cryptoPeriodSeconds = 0;
      d.type = o.enums === String ? "SINGLE" : 0;
      d.keySequence = 0;
      d.videoFeature = "";
    }
    if (m.algorithm != null && m.hasOwnProperty("algorithm")) {
      d.algorithm = o.enums === String ? $root.WidevinePsshData.Algorithm[m.algorithm] === void 0 ? m.algorithm : $root.WidevinePsshData.Algorithm[m.algorithm] : m.algorithm;
    }
    if (m.keyIds && m.keyIds.length) {
      d.keyIds = [];
      for (var j = 0; j < m.keyIds.length; ++j) {
        d.keyIds[j] = o.bytes === String ? $util.base64.encode(m.keyIds[j], 0, m.keyIds[j].length) : o.bytes === Array ? Array.prototype.slice.call(m.keyIds[j]) : m.keyIds[j];
      }
    }
    if (m.provider != null && m.hasOwnProperty("provider")) {
      d.provider = m.provider;
    }
    if (m.contentId != null && m.hasOwnProperty("contentId")) {
      d.contentId = o.bytes === String ? $util.base64.encode(m.contentId, 0, m.contentId.length) : o.bytes === Array ? Array.prototype.slice.call(m.contentId) : m.contentId;
    }
    if (m.trackType != null && m.hasOwnProperty("trackType")) {
      d.trackType = m.trackType;
    }
    if (m.policy != null && m.hasOwnProperty("policy")) {
      d.policy = m.policy;
    }
    if (m.cryptoPeriodIndex != null && m.hasOwnProperty("cryptoPeriodIndex")) {
      d.cryptoPeriodIndex = m.cryptoPeriodIndex;
    }
    if (m.groupedLicense != null && m.hasOwnProperty("groupedLicense")) {
      d.groupedLicense = o.bytes === String ? $util.base64.encode(m.groupedLicense, 0, m.groupedLicense.length) : o.bytes === Array ? Array.prototype.slice.call(m.groupedLicense) : m.groupedLicense;
    }
    if (m.protectionScheme != null && m.hasOwnProperty("protectionScheme")) {
      d.protectionScheme = m.protectionScheme;
    }
    if (m.cryptoPeriodSeconds != null && m.hasOwnProperty("cryptoPeriodSeconds")) {
      d.cryptoPeriodSeconds = m.cryptoPeriodSeconds;
    }
    if (m.type != null && m.hasOwnProperty("type")) {
      d.type = o.enums === String ? $root.WidevinePsshData.Type[m.type] === void 0 ? m.type : $root.WidevinePsshData.Type[m.type] : m.type;
    }
    if (m.keySequence != null && m.hasOwnProperty("keySequence")) {
      d.keySequence = m.keySequence;
    }
    if (m.groupIds && m.groupIds.length) {
      d.groupIds = [];
      for (var j = 0; j < m.groupIds.length; ++j) {
        d.groupIds[j] = o.bytes === String ? $util.base64.encode(m.groupIds[j], 0, m.groupIds[j].length) : o.bytes === Array ? Array.prototype.slice.call(m.groupIds[j]) : m.groupIds[j];
      }
    }
    if (m.entitledKeys && m.entitledKeys.length) {
      d.entitledKeys = [];
      for (var j = 0; j < m.entitledKeys.length; ++j) {
        d.entitledKeys[j] = $root.WidevinePsshData.EntitledKey.toObject(
          m.entitledKeys[j],
          o
        );
      }
    }
    if (m.videoFeature != null && m.hasOwnProperty("videoFeature")) {
      d.videoFeature = m.videoFeature;
    }
    return d;
  };
  WidevinePsshData2.prototype.toJSON = function toJSON() {
    return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
  };
  WidevinePsshData2.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
    if (typeUrlPrefix === void 0) {
      typeUrlPrefix = "type.googleapis.com";
    }
    return typeUrlPrefix + "/WidevinePsshData";
  };
  WidevinePsshData2.Type = function() {
    const valuesById = {}, values = Object.create(valuesById);
    values[valuesById[0] = "SINGLE"] = 0;
    values[valuesById[1] = "ENTITLEMENT"] = 1;
    values[valuesById[2] = "ENTITLED_KEY"] = 2;
    return values;
  }();
  WidevinePsshData2.EntitledKey = function() {
    function EntitledKey(p) {
      if (p) {
        for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
          if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
      }
    }
    EntitledKey.prototype.entitlementKeyId = $util.newBuffer([]);
    EntitledKey.prototype.keyId = $util.newBuffer([]);
    EntitledKey.prototype.key = $util.newBuffer([]);
    EntitledKey.prototype.iv = $util.newBuffer([]);
    EntitledKey.prototype.entitlementKeySizeBytes = 32;
    EntitledKey.create = function create(properties) {
      return new EntitledKey(properties);
    };
    EntitledKey.encode = function encode2(m, w) {
      if (!w) w = $Writer.create();
      if (m.entitlementKeyId != null && Object.hasOwnProperty.call(m, "entitlementKeyId"))
        w.uint32(10).bytes(m.entitlementKeyId);
      if (m.keyId != null && Object.hasOwnProperty.call(m, "keyId"))
        w.uint32(18).bytes(m.keyId);
      if (m.key != null && Object.hasOwnProperty.call(m, "key"))
        w.uint32(26).bytes(m.key);
      if (m.iv != null && Object.hasOwnProperty.call(m, "iv"))
        w.uint32(34).bytes(m.iv);
      if (m.entitlementKeySizeBytes != null && Object.hasOwnProperty.call(m, "entitlementKeySizeBytes"))
        w.uint32(40).uint32(m.entitlementKeySizeBytes);
      return w;
    };
    EntitledKey.encodeDelimited = function encodeDelimited(message, writer) {
      return this.encode(message, writer).ldelim();
    };
    EntitledKey.decode = function decode2(r, l) {
      if (!(r instanceof $Reader)) r = $Reader.create(r);
      var c = l === void 0 ? r.len : r.pos + l, m = new $root.WidevinePsshData.EntitledKey();
      while (r.pos < c) {
        var t = r.uint32();
        switch (t >>> 3) {
          case 1: {
            m.entitlementKeyId = r.bytes();
            break;
          }
          case 2: {
            m.keyId = r.bytes();
            break;
          }
          case 3: {
            m.key = r.bytes();
            break;
          }
          case 4: {
            m.iv = r.bytes();
            break;
          }
          case 5: {
            m.entitlementKeySizeBytes = r.uint32();
            break;
          }
          default:
            r.skipType(t & 7);
            break;
        }
      }
      return m;
    };
    EntitledKey.decodeDelimited = function decodeDelimited(reader) {
      if (!(reader instanceof $Reader)) reader = new $Reader(reader);
      return this.decode(reader, reader.uint32());
    };
    EntitledKey.fromObject = function fromObject(d) {
      if (d instanceof $root.WidevinePsshData.EntitledKey) return d;
      var m = new $root.WidevinePsshData.EntitledKey();
      if (d.entitlementKeyId != null) {
        if (typeof d.entitlementKeyId === "string")
          $util.base64.decode(
            d.entitlementKeyId,
            m.entitlementKeyId = $util.newBuffer(
              $util.base64.length(d.entitlementKeyId)
            ),
            0
          );
        else if (d.entitlementKeyId.length >= 0)
          m.entitlementKeyId = d.entitlementKeyId;
      }
      if (d.keyId != null) {
        if (typeof d.keyId === "string")
          $util.base64.decode(
            d.keyId,
            m.keyId = $util.newBuffer($util.base64.length(d.keyId)),
            0
          );
        else if (d.keyId.length >= 0) m.keyId = d.keyId;
      }
      if (d.key != null) {
        if (typeof d.key === "string")
          $util.base64.decode(
            d.key,
            m.key = $util.newBuffer($util.base64.length(d.key)),
            0
          );
        else if (d.key.length >= 0) m.key = d.key;
      }
      if (d.iv != null) {
        if (typeof d.iv === "string")
          $util.base64.decode(
            d.iv,
            m.iv = $util.newBuffer($util.base64.length(d.iv)),
            0
          );
        else if (d.iv.length >= 0) m.iv = d.iv;
      }
      if (d.entitlementKeySizeBytes != null) {
        m.entitlementKeySizeBytes = d.entitlementKeySizeBytes >>> 0;
      }
      return m;
    };
    EntitledKey.toObject = function toObject(m, o) {
      if (!o) o = {};
      var d = {};
      if (o.defaults) {
        if (o.bytes === String) d.entitlementKeyId = "";
        else {
          d.entitlementKeyId = [];
          if (o.bytes !== Array)
            d.entitlementKeyId = $util.newBuffer(d.entitlementKeyId);
        }
        if (o.bytes === String) d.keyId = "";
        else {
          d.keyId = [];
          if (o.bytes !== Array) d.keyId = $util.newBuffer(d.keyId);
        }
        if (o.bytes === String) d.key = "";
        else {
          d.key = [];
          if (o.bytes !== Array) d.key = $util.newBuffer(d.key);
        }
        if (o.bytes === String) d.iv = "";
        else {
          d.iv = [];
          if (o.bytes !== Array) d.iv = $util.newBuffer(d.iv);
        }
        d.entitlementKeySizeBytes = 32;
      }
      if (m.entitlementKeyId != null && m.hasOwnProperty("entitlementKeyId")) {
        d.entitlementKeyId = o.bytes === String ? $util.base64.encode(
          m.entitlementKeyId,
          0,
          m.entitlementKeyId.length
        ) : o.bytes === Array ? Array.prototype.slice.call(m.entitlementKeyId) : m.entitlementKeyId;
      }
      if (m.keyId != null && m.hasOwnProperty("keyId")) {
        d.keyId = o.bytes === String ? $util.base64.encode(m.keyId, 0, m.keyId.length) : o.bytes === Array ? Array.prototype.slice.call(m.keyId) : m.keyId;
      }
      if (m.key != null && m.hasOwnProperty("key")) {
        d.key = o.bytes === String ? $util.base64.encode(m.key, 0, m.key.length) : o.bytes === Array ? Array.prototype.slice.call(m.key) : m.key;
      }
      if (m.iv != null && m.hasOwnProperty("iv")) {
        d.iv = o.bytes === String ? $util.base64.encode(m.iv, 0, m.iv.length) : o.bytes === Array ? Array.prototype.slice.call(m.iv) : m.iv;
      }
      if (m.entitlementKeySizeBytes != null && m.hasOwnProperty("entitlementKeySizeBytes")) {
        d.entitlementKeySizeBytes = m.entitlementKeySizeBytes;
      }
      return d;
    };
    EntitledKey.prototype.toJSON = function toJSON() {
      return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
    };
    EntitledKey.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
      if (typeUrlPrefix === void 0) {
        typeUrlPrefix = "type.googleapis.com";
      }
      return typeUrlPrefix + "/WidevinePsshData.EntitledKey";
    };
    return EntitledKey;
  }();
  WidevinePsshData2.Algorithm = function() {
    const valuesById = {}, values = Object.create(valuesById);
    values[valuesById[0] = "UNENCRYPTED"] = 0;
    values[valuesById[1] = "AESCTR"] = 1;
    return values;
  }();
  return WidevinePsshData2;
})();
var FileHashes = $root.FileHashes = (() => {
  function FileHashes2(p) {
    this.signatures = [];
    if (p) {
      for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
        if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
    }
  }
  FileHashes2.prototype.signer = $util.newBuffer([]);
  FileHashes2.prototype.signatures = $util.emptyArray;
  FileHashes2.create = function create(properties) {
    return new FileHashes2(properties);
  };
  FileHashes2.encode = function encode2(m, w) {
    if (!w) w = $Writer.create();
    if (m.signer != null && Object.hasOwnProperty.call(m, "signer"))
      w.uint32(10).bytes(m.signer);
    if (m.signatures != null && m.signatures.length) {
      for (var i = 0; i < m.signatures.length; ++i)
        $root.FileHashes.Signature.encode(
          m.signatures[i],
          w.uint32(18).fork()
        ).ldelim();
    }
    return w;
  };
  FileHashes2.encodeDelimited = function encodeDelimited(message, writer) {
    return this.encode(message, writer).ldelim();
  };
  FileHashes2.decode = function decode2(r, l) {
    if (!(r instanceof $Reader)) r = $Reader.create(r);
    var c = l === void 0 ? r.len : r.pos + l, m = new $root.FileHashes();
    while (r.pos < c) {
      var t = r.uint32();
      switch (t >>> 3) {
        case 1: {
          m.signer = r.bytes();
          break;
        }
        case 2: {
          if (!(m.signatures && m.signatures.length)) m.signatures = [];
          m.signatures.push($root.FileHashes.Signature.decode(r, r.uint32()));
          break;
        }
        default:
          r.skipType(t & 7);
          break;
      }
    }
    return m;
  };
  FileHashes2.decodeDelimited = function decodeDelimited(reader) {
    if (!(reader instanceof $Reader)) reader = new $Reader(reader);
    return this.decode(reader, reader.uint32());
  };
  FileHashes2.fromObject = function fromObject(d) {
    if (d instanceof $root.FileHashes) return d;
    var m = new $root.FileHashes();
    if (d.signer != null) {
      if (typeof d.signer === "string")
        $util.base64.decode(
          d.signer,
          m.signer = $util.newBuffer($util.base64.length(d.signer)),
          0
        );
      else if (d.signer.length >= 0) m.signer = d.signer;
    }
    if (d.signatures) {
      if (!Array.isArray(d.signatures))
        throw TypeError(".FileHashes.signatures: array expected");
      m.signatures = [];
      for (var i = 0; i < d.signatures.length; ++i) {
        if (typeof d.signatures[i] !== "object")
          throw TypeError(".FileHashes.signatures: object expected");
        m.signatures[i] = $root.FileHashes.Signature.fromObject(
          d.signatures[i]
        );
      }
    }
    return m;
  };
  FileHashes2.toObject = function toObject(m, o) {
    if (!o) o = {};
    var d = {};
    if (o.arrays || o.defaults) {
      d.signatures = [];
    }
    if (o.defaults) {
      if (o.bytes === String) d.signer = "";
      else {
        d.signer = [];
        if (o.bytes !== Array) d.signer = $util.newBuffer(d.signer);
      }
    }
    if (m.signer != null && m.hasOwnProperty("signer")) {
      d.signer = o.bytes === String ? $util.base64.encode(m.signer, 0, m.signer.length) : o.bytes === Array ? Array.prototype.slice.call(m.signer) : m.signer;
    }
    if (m.signatures && m.signatures.length) {
      d.signatures = [];
      for (var j = 0; j < m.signatures.length; ++j) {
        d.signatures[j] = $root.FileHashes.Signature.toObject(
          m.signatures[j],
          o
        );
      }
    }
    return d;
  };
  FileHashes2.prototype.toJSON = function toJSON() {
    return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
  };
  FileHashes2.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
    if (typeUrlPrefix === void 0) {
      typeUrlPrefix = "type.googleapis.com";
    }
    return typeUrlPrefix + "/FileHashes";
  };
  FileHashes2.Signature = function() {
    function Signature(p) {
      if (p) {
        for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
          if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
      }
    }
    Signature.prototype.filename = "";
    Signature.prototype.testSigning = false;
    Signature.prototype.SHA512Hash = $util.newBuffer([]);
    Signature.prototype.mainExe = false;
    Signature.prototype.signature = $util.newBuffer([]);
    Signature.create = function create(properties) {
      return new Signature(properties);
    };
    Signature.encode = function encode2(m, w) {
      if (!w) w = $Writer.create();
      if (m.filename != null && Object.hasOwnProperty.call(m, "filename"))
        w.uint32(10).string(m.filename);
      if (m.testSigning != null && Object.hasOwnProperty.call(m, "testSigning"))
        w.uint32(16).bool(m.testSigning);
      if (m.SHA512Hash != null && Object.hasOwnProperty.call(m, "SHA512Hash"))
        w.uint32(26).bytes(m.SHA512Hash);
      if (m.mainExe != null && Object.hasOwnProperty.call(m, "mainExe"))
        w.uint32(32).bool(m.mainExe);
      if (m.signature != null && Object.hasOwnProperty.call(m, "signature"))
        w.uint32(42).bytes(m.signature);
      return w;
    };
    Signature.encodeDelimited = function encodeDelimited(message, writer) {
      return this.encode(message, writer).ldelim();
    };
    Signature.decode = function decode2(r, l) {
      if (!(r instanceof $Reader)) r = $Reader.create(r);
      var c = l === void 0 ? r.len : r.pos + l, m = new $root.FileHashes.Signature();
      while (r.pos < c) {
        var t = r.uint32();
        switch (t >>> 3) {
          case 1: {
            m.filename = r.string();
            break;
          }
          case 2: {
            m.testSigning = r.bool();
            break;
          }
          case 3: {
            m.SHA512Hash = r.bytes();
            break;
          }
          case 4: {
            m.mainExe = r.bool();
            break;
          }
          case 5: {
            m.signature = r.bytes();
            break;
          }
          default:
            r.skipType(t & 7);
            break;
        }
      }
      return m;
    };
    Signature.decodeDelimited = function decodeDelimited(reader) {
      if (!(reader instanceof $Reader)) reader = new $Reader(reader);
      return this.decode(reader, reader.uint32());
    };
    Signature.fromObject = function fromObject(d) {
      if (d instanceof $root.FileHashes.Signature) return d;
      var m = new $root.FileHashes.Signature();
      if (d.filename != null) {
        m.filename = String(d.filename);
      }
      if (d.testSigning != null) {
        m.testSigning = Boolean(d.testSigning);
      }
      if (d.SHA512Hash != null) {
        if (typeof d.SHA512Hash === "string")
          $util.base64.decode(
            d.SHA512Hash,
            m.SHA512Hash = $util.newBuffer($util.base64.length(d.SHA512Hash)),
            0
          );
        else if (d.SHA512Hash.length >= 0) m.SHA512Hash = d.SHA512Hash;
      }
      if (d.mainExe != null) {
        m.mainExe = Boolean(d.mainExe);
      }
      if (d.signature != null) {
        if (typeof d.signature === "string")
          $util.base64.decode(
            d.signature,
            m.signature = $util.newBuffer($util.base64.length(d.signature)),
            0
          );
        else if (d.signature.length >= 0) m.signature = d.signature;
      }
      return m;
    };
    Signature.toObject = function toObject(m, o) {
      if (!o) o = {};
      var d = {};
      if (o.defaults) {
        d.filename = "";
        d.testSigning = false;
        if (o.bytes === String) d.SHA512Hash = "";
        else {
          d.SHA512Hash = [];
          if (o.bytes !== Array) d.SHA512Hash = $util.newBuffer(d.SHA512Hash);
        }
        d.mainExe = false;
        if (o.bytes === String) d.signature = "";
        else {
          d.signature = [];
          if (o.bytes !== Array) d.signature = $util.newBuffer(d.signature);
        }
      }
      if (m.filename != null && m.hasOwnProperty("filename")) {
        d.filename = m.filename;
      }
      if (m.testSigning != null && m.hasOwnProperty("testSigning")) {
        d.testSigning = m.testSigning;
      }
      if (m.SHA512Hash != null && m.hasOwnProperty("SHA512Hash")) {
        d.SHA512Hash = o.bytes === String ? $util.base64.encode(m.SHA512Hash, 0, m.SHA512Hash.length) : o.bytes === Array ? Array.prototype.slice.call(m.SHA512Hash) : m.SHA512Hash;
      }
      if (m.mainExe != null && m.hasOwnProperty("mainExe")) {
        d.mainExe = m.mainExe;
      }
      if (m.signature != null && m.hasOwnProperty("signature")) {
        d.signature = o.bytes === String ? $util.base64.encode(m.signature, 0, m.signature.length) : o.bytes === Array ? Array.prototype.slice.call(m.signature) : m.signature;
      }
      return d;
    };
    Signature.prototype.toJSON = function toJSON() {
      return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
    };
    Signature.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
      if (typeUrlPrefix === void 0) {
        typeUrlPrefix = "type.googleapis.com";
      }
      return typeUrlPrefix + "/FileHashes.Signature";
    };
    return Signature;
  }();
  return FileHashes2;
})();
var RemoteAttestation = $root.RemoteAttestation = (() => {
  function RemoteAttestation2(p) {
    if (p) {
      for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
        if (p[ks[i]] != null) this[ks[i]] = p[ks[i]];
    }
  }
  RemoteAttestation2.prototype.certificate = null;
  RemoteAttestation2.prototype.salt = $util.newBuffer([]);
  RemoteAttestation2.prototype.signature = $util.newBuffer([]);
  RemoteAttestation2.create = function create(properties) {
    return new RemoteAttestation2(properties);
  };
  RemoteAttestation2.encode = function encode2(m, w) {
    if (!w) w = $Writer.create();
    if (m.certificate != null && Object.hasOwnProperty.call(m, "certificate"))
      $root.EncryptedClientIdentification.encode(
        m.certificate,
        w.uint32(10).fork()
      ).ldelim();
    if (m.salt != null && Object.hasOwnProperty.call(m, "salt"))
      w.uint32(18).bytes(m.salt);
    if (m.signature != null && Object.hasOwnProperty.call(m, "signature"))
      w.uint32(26).bytes(m.signature);
    return w;
  };
  RemoteAttestation2.encodeDelimited = function encodeDelimited(message, writer) {
    return this.encode(message, writer).ldelim();
  };
  RemoteAttestation2.decode = function decode2(r, l) {
    if (!(r instanceof $Reader)) r = $Reader.create(r);
    var c = l === void 0 ? r.len : r.pos + l, m = new $root.RemoteAttestation();
    while (r.pos < c) {
      var t = r.uint32();
      switch (t >>> 3) {
        case 1: {
          m.certificate = $root.EncryptedClientIdentification.decode(
            r,
            r.uint32()
          );
          break;
        }
        case 2: {
          m.salt = r.bytes();
          break;
        }
        case 3: {
          m.signature = r.bytes();
          break;
        }
        default:
          r.skipType(t & 7);
          break;
      }
    }
    return m;
  };
  RemoteAttestation2.decodeDelimited = function decodeDelimited(reader) {
    if (!(reader instanceof $Reader)) reader = new $Reader(reader);
    return this.decode(reader, reader.uint32());
  };
  RemoteAttestation2.fromObject = function fromObject(d) {
    if (d instanceof $root.RemoteAttestation) return d;
    var m = new $root.RemoteAttestation();
    if (d.certificate != null) {
      if (typeof d.certificate !== "object")
        throw TypeError(".RemoteAttestation.certificate: object expected");
      m.certificate = $root.EncryptedClientIdentification.fromObject(
        d.certificate
      );
    }
    if (d.salt != null) {
      if (typeof d.salt === "string")
        $util.base64.decode(
          d.salt,
          m.salt = $util.newBuffer($util.base64.length(d.salt)),
          0
        );
      else if (d.salt.length >= 0) m.salt = d.salt;
    }
    if (d.signature != null) {
      if (typeof d.signature === "string")
        $util.base64.decode(
          d.signature,
          m.signature = $util.newBuffer($util.base64.length(d.signature)),
          0
        );
      else if (d.signature.length >= 0) m.signature = d.signature;
    }
    return m;
  };
  RemoteAttestation2.toObject = function toObject(m, o) {
    if (!o) o = {};
    var d = {};
    if (o.defaults) {
      d.certificate = null;
      if (o.bytes === String) d.salt = "";
      else {
        d.salt = [];
        if (o.bytes !== Array) d.salt = $util.newBuffer(d.salt);
      }
      if (o.bytes === String) d.signature = "";
      else {
        d.signature = [];
        if (o.bytes !== Array) d.signature = $util.newBuffer(d.signature);
      }
    }
    if (m.certificate != null && m.hasOwnProperty("certificate")) {
      d.certificate = $root.EncryptedClientIdentification.toObject(
        m.certificate,
        o
      );
    }
    if (m.salt != null && m.hasOwnProperty("salt")) {
      d.salt = o.bytes === String ? $util.base64.encode(m.salt, 0, m.salt.length) : o.bytes === Array ? Array.prototype.slice.call(m.salt) : m.salt;
    }
    if (m.signature != null && m.hasOwnProperty("signature")) {
      d.signature = o.bytes === String ? $util.base64.encode(m.signature, 0, m.signature.length) : o.bytes === Array ? Array.prototype.slice.call(m.signature) : m.signature;
    }
    return d;
  };
  RemoteAttestation2.prototype.toJSON = function toJSON() {
    return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
  };
  RemoteAttestation2.getTypeUrl = function getTypeUrl(typeUrlPrefix) {
    if (typeUrlPrefix === void 0) {
      typeUrlPrefix = "type.googleapis.com";
    }
    return typeUrlPrefix + "/RemoteAttestation";
  };
  return RemoteAttestation2;
})();

// src/lib/widevine/wvd.ts
var VERSION = 2;
var MAGIC = fromText("WVD").toBuffer();
var WVD_DEVICE_TYPES = { chrome: 1, android: 2 };
var areUint8ArraysEqual = (a, b3) => {
  return a.length === b3.length && a.every((val, index) => val === b3[index]);
};
var readUint8 = (data, offset) => {
  return data[offset];
};
var readUint16BE = (data, offset) => {
  return data[offset] << 8 | data[offset + 1];
};
var writeUint8 = (value) => {
  const buffer = new Uint8Array(1);
  buffer[0] = value;
  return buffer;
};
var writeUint16BE = (value) => {
  const buffer = new Uint8Array(2);
  buffer[0] = value >> 8 & 255;
  buffer[1] = value & 255;
  return buffer;
};
var parseWvd = (data) => {
  let offset = 0;
  const magic = data.subarray(offset, offset + 3);
  offset += 3;
  if (!areUint8ArraysEqual(magic, MAGIC)) {
    throw new Error("Invalid WVD file: Wrong magic number");
  }
  const version = readUint8(data, offset);
  offset += 1;
  if (version !== VERSION) {
    throw new Error(`Unsupported WVD version: ${version}`);
  }
  const deviceType = readUint8(data, offset);
  offset += 1;
  const securityLevel = readUint8(data, offset);
  offset += 1;
  offset += 1;
  const privateKeyLen = readUint16BE(data, offset);
  offset += 2;
  const privateKey = data.subarray(offset, offset + privateKeyLen);
  offset += privateKeyLen;
  const clientIdLen = readUint16BE(data, offset);
  offset += 2;
  const clientId = data.subarray(offset, offset + clientIdLen);
  return {
    version,
    deviceType,
    securityLevel,
    privateKey,
    clientId
  };
};
var buildWvd = (wvdData) => {
  const { deviceType, securityLevel, privateKey, clientId } = wvdData;
  const privateKeyLen = privateKey.length;
  const clientIdLen = clientId.length;
  const wvdArray = new Uint8Array(
    MAGIC.length + // Magic number (3 bytes)
    1 + // Version (1 byte)
    1 + // Device type (1 byte)
    1 + // Security level (1 byte)
    1 + // Flags (1 byte, padded as in the Python script)
    2 + // Private key length (2 bytes)
    privateKeyLen + // Private key
    2 + // Client ID length (2 bytes)
    clientIdLen
    // Client ID
  );
  let offset = 0;
  wvdArray.set(MAGIC, offset);
  offset += MAGIC.length;
  wvdArray.set(writeUint8(VERSION), offset);
  offset += 1;
  wvdArray.set(writeUint8(deviceType), offset);
  offset += 1;
  wvdArray.set(writeUint8(securityLevel), offset);
  offset += 1;
  wvdArray.set(writeUint8(0), offset);
  offset += 1;
  wvdArray.set(writeUint16BE(privateKeyLen), offset);
  offset += 2;
  wvdArray.set(privateKey, offset);
  offset += privateKeyLen;
  wvdArray.set(writeUint16BE(clientIdLen), offset);
  offset += 2;
  wvdArray.set(clientId, offset);
  return wvdArray;
};

// src/lib/widevine/certificate.ts
var getRootCertificate = () => {
  const signedDrmCertificateBase64 = `
        CpwDCAASAQAY3ZSIiwUijgMwggGKAoIBgQC0/jnDZZAD2zwRlwnoaM3yw16b8udNI7EQ24dl39z7nzWgVwNTTPZtNX2meNuzNtI/nECplSZy
        f7i+Zt/FIZh4FRZoXS9GDkPLioQ5q/uwNYAivjQji6tTW3LsS7VIaVM+R1/9Cf2ndhOPD5LWTN+udqm62SIQqZ1xRdbX4RklhZxTmpfrhNfM
        qIiCIHAmIP1+QFAn4iWTb7w+cqD6wb0ptE2CXMG0y5xyfrDpihc+GWP8/YJIK7eyM7l97Eu6iR8nuJuISISqGJIOZfXIbBH/azbkdDTKjDOx
        +biOtOYS4AKYeVJeRTP/Edzrw1O6fGAaET0A+9K3qjD6T15Id1sX3HXvb9IZbdy+f7B4j9yCYEy/5CkGXmmMOROtFCXtGbLynwGCDVZEiMg1
        7B8RsyTgWQ035Ec86kt/lzEcgXyUikx9aBWE/6UI/Rjn5yvkRycSEbgj7FiTPKwS0ohtQT3F/hzcufjUUT4H5QNvpxLoEve1zqaWVT94tGSC
        UNIzX5ECAwEAARKAA1jx1k0ECXvf1+9dOwI5F/oUNnVKOGeFVxKnFO41FtU9v0KG9mkAds2T9Hyy355EzUzUrgkYU0Qy7OBhG+XaE9NVxd0a
        y5AeflvG6Q8in76FAv6QMcxrA4S9IsRV+vXyCM1lQVjofSnaBFiC9TdpvPNaV4QXezKHcLKwdpyywxXRESYqI3WZPrl3IjINvBoZwdVlkHZV
        dA8OaU1fTY8Zr9/WFjGUqJJfT7x6Mfiujq0zt+kw0IwKimyDNfiKgbL+HIisKmbF/73mF9BiC9yKRfewPlrIHkokL2yl4xyIFIPVxe9enz2F
        RXPia1BSV0z7kmxmdYrWDRuu8+yvUSIDXQouY5OcCwEgqKmELhfKrnPsIht5rvagcizfB0fbiIYwFHghESKIrNdUdPnzJsKlVshWTwApHQh7
        evuVicPumFSePGuUBRMS9nG5qxPDDJtGCHs9Mmpoyh6ckGLF7RC5HxclzpC5bc3ERvWjYhN0AqdipPpV2d7PouaAdFUGSdUCDA==`.split("\n").map((s) => s.trim()).join("\n");
  const signedDrmCertificate = SignedDrmCertificate.decode(
    fromBase64(signedDrmCertificateBase64).toBuffer()
  );
  const drmCertificate = DrmCertificate.decode(
    signedDrmCertificate.drmCertificate
  );
  return {
    signedDrmCertificateBase64,
    signedDrmCertificate,
    drmCertificate
  };
};
var importCertificateKey = async (publicKey, usage) => {
  const keyData = parseSpkiFromCertificateKey(publicKey);
  if (usage === "verify") {
    return importSpkiKeyForVerify(keyData);
  } else {
    return importSpkiKeyForEncrypt(keyData);
  }
};
var verifyCertificate = async (signedDrmCertificate) => {
  const publicKey = getRootCertificate().drmCertificate.publicKey;
  const signature = signedDrmCertificate.signature;
  const data = signedDrmCertificate.drmCertificate;
  const key = await importCertificateKey(publicKey, "verify");
  const isValid = await crypto.subtle.verify(
    { name: "RSA-PSS", saltLength: 20 },
    key,
    signature,
    data
  );
  return isValid;
};
var parseCertificate = async (data) => {
  const certificate = ArrayBuffer.isView(data) ? data : fromBase64(data).toBuffer();
  let signedDrmCertificate;
  let signedMessage;
  try {
    signedMessage = SignedMessage.decode(certificate);
  } finally {
  }
  if (signedMessage?.type) {
    try {
      signedDrmCertificate = SignedDrmCertificate.decode(signedMessage.msg);
    } catch (e) {
      throw new Error("Failed to parse service certificate");
    }
  } else {
    try {
      signedDrmCertificate = SignedDrmCertificate.decode(certificate);
    } catch (e) {
      throw new Error("Failed to parse service certificate");
    }
  }
  const drmCertificate = DrmCertificate.decode(
    signedDrmCertificate.drmCertificate
  );
  return { signedDrmCertificate, drmCertificate };
};

// src/lib/widevine/key.ts
var Key = class _Key {
  id;
  value;
  type;
  level;
  trackLabel;
  permissions;
  constructor(id, value, type = "CONTENT", level, trackLabel, permissions = []) {
    this.id = id;
    this.value = value;
    this.type = type;
    this.level = level;
    this.trackLabel = trackLabel;
    this.permissions = permissions;
  }
  toString() {
    let message = "Key: ";
    if (this.id) message += `${this.id}`;
    if (this.value) message += `:${this.value}`;
    if (this.type) message += ` \u2219 Type: ${this.type}`;
    if (this.level) message += ` \u2219 Level: ${this.level}`;
    if (this.trackLabel) message += ` \u2219 Label: ${this.trackLabel}`;
    return message;
  }
  static async fromContainer(container, encKey) {
    if (!container.key || !container.iv) throw new Error("Key not found");
    const decryptionKey = await importAesCbcKeyForDecrypt(encKey);
    const keyValue = await decryptWithAesCbc(
      container.key,
      decryptionKey,
      container.iv
    );
    const id = container.id ? fromBuffer(container.id).toHex() : "UNKNOWN";
    const value = fromBuffer(keyValue).toHex();
    const type = License.KeyContainer.KeyType[container.type];
    return new _Key(
      id,
      value,
      type,
      String(container.level),
      container.trackLabel,
      container.operatorSessionKeyPermissions
    );
  }
};

// src/lib/widevine/pssh.ts
var WV_SYSTEM_ID = new Uint8Array([
  237,
  239,
  139,
  169,
  121,
  214,
  74,
  206,
  163,
  200,
  39,
  220,
  213,
  29,
  33,
  237
]);
function areUint8ArraysEqual2(a, b3) {
  return a.length === b3.length && a.every((val, index) => val === b3[index]);
}
function concatUint8Arrays(...arrays) {
  const totalLength = arrays.reduce((acc, arr) => acc + arr.length, 0);
  const result = new Uint8Array(totalLength);
  let offset = 0;
  for (const arr of arrays) {
    result.set(arr, offset);
    offset += arr.length;
  }
  return result;
}
var prepare = (data) => {
  const dataBuffer = typeof data === "string" ? fromBase64(data).toBuffer() : data;
  const dataFragment = dataBuffer.subarray(12, 28);
  const isWidevineSystemIdDetected = areUint8ArraysEqual2(
    dataFragment,
    WV_SYSTEM_ID
  );
  if (isWidevineSystemIdDetected) {
    return typeof data === "string" ? data : fromBuffer(data).toBase64();
  }
  const header = new Uint8Array([0, 0, 0, 32 + dataBuffer.length]);
  const pssh = new TextEncoder().encode("pssh");
  const version = new Uint8Array([0, 0, 0, 0]);
  const dataLength = new Uint8Array([0, 0, 0, dataBuffer.length]);
  const newData = concatUint8Arrays(
    header,
    pssh,
    version,
    WV_SYSTEM_ID,
    dataLength,
    dataBuffer
  );
  return fromBuffer(newData).toBase64();
};
var parse = (initData) => {
  try {
    const initDataBuffer = typeof initData === "string" ? fromBase64(initData).toBuffer().subarray(32) : initData.subarray(32);
    return WidevinePsshData.decode(initDataBuffer);
  } catch (e) {
    throw new Error("Unable to parse, unsupported init data format");
  }
};
var createPssh = (initData) => {
  const preparedInitData = prepare(initData);
  const parsedInitData = parse(preparedInitData);
  return {
    data: parsedInitData,
    toBuffer: () => WidevinePsshData.encode(parsedInitData).finish()
  };
};

// src/lib/buffer.ts
var concatUint8Arrays2 = (...arrays) => {
  const totalLength = arrays.reduce((acc, arr) => acc + arr.length, 0);
  const result = new Uint8Array(totalLength);
  let offset = 0;
  for (const arr of arrays) {
    result.set(arr, offset);
    offset += arr.length;
  }
  return result;
};
var bitShiftLeftBuffer = (buffer) => {
  const shifted = new Uint8Array(buffer.length);
  const last = buffer.length - 1;
  for (let index = 0; index < last; index++) {
    shifted[index] = buffer[index] << 1;
    if (buffer[index + 1] & 128) {
      shifted[index] |= 1;
    }
  }
  shifted[last] = buffer[last] << 1;
  return shifted;
};
var tryGetUtf16Le = (bytes) => {
  if (bytes.length % 2 !== 0) {
    return null;
  }
  for (let i = 1; i < bytes.length; i += 2) {
    if (bytes[i] !== 0) {
      return null;
    }
  }
  try {
    const decoder = new TextDecoder("utf-16le", { fatal: true });
    return decoder.decode(bytes);
  } catch (e) {
    return null;
  }
};

// src/lib/crypto/cmac.ts
var xorBuffer = (a, b3) => {
  const result = new Uint8Array(a.length);
  for (let i = 0; i < a.length; i++) {
    result[i] = a[i] ^ b3[i];
  }
  return result;
};
var hexToBytes = (hex) => {
  const bytes = new Uint8Array(hex.length / 2);
  for (let i = 0; i < hex.length; i += 2) {
    bytes[i / 2] = parseInt(hex.substr(i, 2), 16);
  }
  return bytes;
};
var const_Zero = new Uint8Array(16);
var const_Rb = new Uint8Array(hexToBytes("00000000000000000000000000000087"));
var const_blockSize = 16;
var generateSubkeys = async (key) => {
  const l = await aes(key, const_Zero);
  let subkey1 = bitShiftLeftBuffer(l);
  if (l[0] & 128) {
    subkey1 = xorBuffer(subkey1, const_Rb);
  }
  let subkey2 = bitShiftLeftBuffer(subkey1);
  if (subkey1[0] & 128) {
    subkey2 = xorBuffer(subkey2, const_Rb);
  }
  return { subkey1, subkey2 };
};
var getMessageBlock = (message, blockIndex) => {
  const start = blockIndex * const_blockSize;
  const end = start + const_blockSize;
  return message.slice(start, end);
};
var getPaddedMessageBlock = (message, blockIndex) => {
  const block = new Uint8Array(const_blockSize);
  const start = blockIndex * const_blockSize;
  const end = message.length;
  block.set(message.slice(start, end), 0);
  block[end - start] = 128;
  return block;
};
var aes = async (key, message) => {
  const aesCipher = await encryptWithAesCbc(message, key, const_Zero);
  return aesCipher.slice(0, 16);
};
var aesCmac = async (keyData, message) => {
  const keyLengthToCipher = {
    16: "aes-128-cbc",
    24: "aes-192-cbc",
    32: "aes-256-cbc"
  };
  if (!keyLengthToCipher[keyData.length]) {
    throw new Error("Keys must be 128, 192, or 256 bits in length.");
  }
  const key = await importAesCbcKeyForEncrypt(keyData);
  const subkeys = await generateSubkeys(key);
  let blockCount = Math.ceil(message.length / const_blockSize);
  let lastBlockCompleteFlag;
  let lastBlock;
  if (blockCount === 0) {
    blockCount = 1;
    lastBlockCompleteFlag = false;
  } else {
    lastBlockCompleteFlag = message.length % const_blockSize === 0;
  }
  const lastBlockIndex = blockCount - 1;
  if (lastBlockCompleteFlag) {
    lastBlock = xorBuffer(
      getMessageBlock(message, lastBlockIndex),
      subkeys.subkey1
    );
  } else {
    lastBlock = xorBuffer(
      getPaddedMessageBlock(message, lastBlockIndex),
      subkeys.subkey2
    );
  }
  let x = new Uint8Array(16);
  let y;
  for (let index = 0; index < lastBlockIndex; index++) {
    y = xorBuffer(x, getMessageBlock(message, index));
    x = await aes(key, y);
  }
  y = xorBuffer(lastBlock, x);
  return aes(key, y);
};

// src/lib/widevine/context.ts
var deriveContext = (message) => {
  const textEncoder = new TextEncoder();
  const toBytes = (n, length = 4) => {
    const bytes = new Uint8Array(length);
    bytes[length - 2] = n >> 8 & 255;
    bytes[length - 1] = n & 255;
    return bytes;
  };
  const getContext = (label, msg, keySize) => concatUint8Arrays2(
    textEncoder.encode(label + "\0"),
    msg,
    toBytes(keySize)
  );
  return {
    enc: getContext(
      "ENCRYPTION",
      message,
      16 * 8
      /* 128-bit */
    ),
    auth: getContext(
      "AUTHENTICATION",
      message,
      32 * 8 * 2
      /* 512-bit */
    )
  };
};
var deriveKeys = async (encContext, macContext, key) => {
  const derive = async (sessionKey, context, counter) => {
    const message = concatUint8Arrays2(new Uint8Array([counter]), context);
    return await aesCmac(sessionKey, message);
  };
  const encKey = await derive(key, encContext, 1);
  const macKeyServer = concatUint8Arrays2(
    await derive(key, macContext, 1),
    await derive(key, macContext, 2)
  );
  const macKeyClient = concatUint8Arrays2(
    await derive(key, macContext, 3),
    await derive(key, macContext, 4)
  );
  return { encKey, macKeyServer, macKeyClient };
};

// src/lib/widevine/message.ts
var getMessageType = (messageBuffer) => {
  try {
    const message = SignedMessage.decode(messageBuffer);
    return message.type;
  } catch (e) {
    console.error("Failed to parse message as SignedMessage", e);
  }
};

// src/lib/widevine/session.ts
var generateSessionId = (deviceType) => {
  switch (deviceType) {
    case "chrome":
      return fromBuffer(getRandomBytes2()).toBase64();
    case "android":
    default: {
      const randAscii = getRandomHex();
      const counter = "01";
      const rest = "00000000000000";
      const hex = randAscii + counter + rest;
      return hex;
    }
  }
};
var INDIVIDUALIZATION_MESSAGE = new Uint8Array([8, 4]);
var Session2 = class extends EventTarget {
  sessionId;
  keyStatuses;
  keys;
  expiration;
  closed;
  onmessage;
  onkeyschange;
  onkeystatuseschange;
  sessionType;
  privacyMode = false;
  #client;
  #log;
  #initData;
  #initDataType;
  #individualizationSent = false;
  #serviceCertificate;
  #contexts;
  constructor(sessionType = "temporary", client) {
    super();
    this.sessionId = generateSessionId("android");
    this.keyStatuses = /* @__PURE__ */ new Map();
    this.keys = /* @__PURE__ */ new Map();
    this.expiration = NaN;
    this.closed = new Promise((resolve) => {
      this.addEventListener("closed", () => resolve("closed-by-application"));
    });
    this.onmessage = null;
    this.onkeyschange = null;
    this.onkeystatuseschange = null;
    this.sessionType = sessionType;
    this.#client = client;
    this.#contexts = /* @__PURE__ */ new Map();
    this.#log = console;
  }
  setLogger(logger) {
    this.#log = logger;
  }
  async generateRequest(initDataType, initData) {
    if (this.privacyMode && !this.#individualizationSent) {
      this.dispatchEvent(
        new MessageEvent(
          "individualization-request",
          INDIVIDUALIZATION_MESSAGE
        )
      );
      this.#individualizationSent = true;
      this.#initData = initData;
      this.#initDataType = initDataType;
      return;
    }
    const pssh = createPssh(initData);
    const licenseRequest = await this.#createLicenseRequest(pssh);
    const message = await this.#signMessage(
      licenseRequest.bytes,
      SignedMessage.MessageType.LICENSE_REQUEST
    );
    this.#contexts.set(
      fromBuffer(licenseRequest.requestId).toText(),
      deriveContext(licenseRequest.bytes)
    );
    this.dispatchEvent(
      new MessageEvent(
        "license-request",
        message.bytes
      )
    );
    return message.bytes;
  }
  async waitForLicenseRequest() {
    return new Promise((resolve) => {
      this.addEventListener(
        "message",
        (e) => {
          const event = e;
          if (event.messageType === "license-request")
            resolve(new Uint8Array(event.message));
        },
        false
      );
    });
  }
  async #createLicenseRequest(pssh) {
    const requestId = ArrayBuffer.isView(this.sessionId) ? this.sessionId : fromText(this.sessionId).toBuffer();
    const entity = LicenseRequest.create({
      clientId: this.#serviceCertificate ? void 0 : this.#client.id,
      encryptedClientId: this.#serviceCertificate ? await this.#client.encryptId(this.#serviceCertificate) : void 0,
      contentId: {
        widevinePsshData: {
          psshData: [pssh.toBuffer()],
          licenseType: this.sessionType === "persistent-license" ? LicenseType.OFFLINE : LicenseType.STREAMING,
          requestId
        }
      },
      type: LicenseRequest.RequestType.NEW,
      requestTime: Math.round(Date.now() / 1e3),
      protocolVersion: ProtocolVersion.VERSION_2_1
    });
    const bytes = LicenseRequest.encode(entity).finish();
    return { requestId, entity, bytes };
  }
  async #signMessage(message, type) {
    const entity = SignedMessage.create({
      type,
      msg: message,
      signature: await this.#client.signWithKey(message)
    });
    const bytes = SignedMessage.encode(entity).finish();
    return { entity, bytes };
  }
  load() {
    return Promise.resolve(true);
  }
  async update(response) {
    const type = getMessageType(response);
    const typeText = type ? SignedMessage.MessageType[type] : "?";
    if (type === SignedMessage.MessageType.SERVICE_CERTIFICATE) {
      await this.#setServiceCertificate(response);
      if (!this.#initData || !this.#initDataType) return;
      this.generateRequest(this.#initDataType, this.#initData);
      return;
    }
    let signedLicense = null;
    try {
      signedLicense = SignedMessage.decode(response);
    } catch (e) {
      this.#log.error("Unable to parse license - check protobufs");
      this.#log.debug(fromBuffer(response).toText());
      return;
    }
    const license = License.decode(signedLicense.msg);
    const requestId = fromBuffer(license.id.requestId).toText();
    const context = this.#contexts.get(requestId);
    if (!context)
      throw new Error(
        `Failed to find context to decrypt keys, requestId: ${requestId}`
      );
    const sessionKey = await this.#client.decryptWithKey(
      signedLicense.sessionKey
    );
    const derivedKeys = await deriveKeys(context.enc, context.auth, sessionKey);
    const { success, signature } = await this.#verifyMessage(
      signedLicense,
      derivedKeys.macKeyServer
    );
    if (!success) {
      this.#log.debug(`Calculated signature: ${signature.calculated}`);
      this.#log.debug(`Actual signature: ${signature.actual}`);
      throw new Error(
        "Signature mismatch on license message, rejecting license"
      );
    }
    for (const keyContainer of license.key) {
      if (!keyContainer.key || !keyContainer.iv) continue;
      const key = await Key.fromContainer(keyContainer, derivedKeys.encKey);
      if (!key.id) continue;
      this.#addKey(key);
    }
    this.dispatchEvent(new Event("keyschange"));
    this.dispatchEvent(new Event("keystatuseschange"));
    this.#contexts.delete(requestId);
    if (this.keys.size) await this.close();
  }
  async #setServiceCertificate(certificate) {
    const { signedDrmCertificate, drmCertificate } = await parseCertificate(certificate);
    const isValid = verifyCertificate(signedDrmCertificate);
    if (!isValid) throw new Error("Certificate invalid: signature mismatch");
    this.#serviceCertificate = signedDrmCertificate;
    return drmCertificate.providerId;
  }
  async #verifyMessage(message, key) {
    const actualSignatureHex = fromBuffer(message.signature).toHex();
    const data = [message.msg];
    if (message.oemcryptoCoreMessage?.length)
      data.unshift(message.oemcryptoCoreMessage);
    const calculatedSignature = await createHmacSha256(
      key,
      concatUint8Arrays2(...data)
    );
    const calculatedSignatureHex = fromBuffer(calculatedSignature).toHex();
    const success = actualSignatureHex === calculatedSignatureHex;
    const signature = {
      actual: actualSignatureHex,
      calculated: calculatedSignatureHex
    };
    return { success, signature };
  }
  #addKey(key) {
    this.keys.set(key.id, key);
    this.keyStatuses.set(
      fromText(`${key.id}:${key.value}`).toBuffer(),
      "usable"
    );
  }
  async getKeys() {
    return Array.from(this.keys.values());
  }
  close() {
    this.dispatchEvent(new Event("closed"));
    return Promise.resolve();
  }
  remove() {
    return Promise.resolve();
  }
};

// src/lib/widevine/client.ts
var CLIENT_TYPE = { android: "android", chrome: "chrome" };
var types = /* @__PURE__ */ new Map([
  [WVD_DEVICE_TYPES.android, CLIENT_TYPE.android],
  [WVD_DEVICE_TYPES.chrome, CLIENT_TYPE.chrome]
]);
var WidevineClient = class _WidevineClient {
  id;
  type;
  securityLevel;
  signedDrmCertificate;
  drmCertificate;
  systemId;
  vmp;
  info;
  #key;
  static async from(payload) {
    if ("wvd" in payload) {
      return await _WidevineClient.fromPacked(payload.wvd);
    } else {
      return await _WidevineClient.fromUnpacked(payload.id, payload.key);
    }
  }
  static async fromPacked(data, format = "wvd") {
    const isWvd = fromBuffer(data.slice(0, 3)).toText() == "WVD";
    if (format === "wvd" || isWvd) {
      const parsed = parseWvd(data);
      const pcks1 = `-----BEGIN RSA PRIVATE KEY-----
${fromBuffer(parsed.privateKey).toBase64()}
-----END RSA PRIVATE KEY-----`;
      const key = fromText(pcks1).toBuffer();
      const type = types.get(parsed.deviceType);
      const securityLevel = parsed.securityLevel;
      const client = new _WidevineClient(parsed.clientId, type, securityLevel);
      await client.importKey(key);
      return client;
    } else {
      throw new Error("Unsupported format");
    }
  }
  static async fromUnpacked(id, key, vmp) {
    const client = new _WidevineClient(id);
    if (vmp) {
      client.vmp = FileHashes.decode(vmp);
      client.id.vmpData = vmp;
    }
    await client.importKey(key);
    return client;
  }
  get key() {
    if (!this.#key) throw new Error("Import key before using it");
    return this.#key;
  }
  constructor(id, type = CLIENT_TYPE.android, securityLevel = 3) {
    this.id = ArrayBuffer.isView(id) ? ClientIdentification.decode(id) : id;
    this.signedDrmCertificate = SignedDrmCertificate.decode(this.id.token);
    this.drmCertificate = DrmCertificate.decode(
      this.signedDrmCertificate.drmCertificate
    );
    this.systemId = this.drmCertificate.systemId;
    this.vmp = this.id.vmpData ? FileHashes.decode(this.id.vmpData) : null;
    this.type = type;
    this.securityLevel = securityLevel;
    const clientInfo = this.id.clientInfo;
    this.info = new Map(clientInfo.map((item) => [item.name, item.value]));
  }
  getName() {
    return `${this.info.get("company_name")}_${this.info.get("model_name")}`;
  }
  get filename() {
    return this.getName();
  }
  get label() {
    return `${this.info.get("company_name")} ${this.info.get("model_name")}`;
  }
  async unpack() {
    const id = ClientIdentification.encode(this.id).finish();
    const key = await this.exportKey();
    return {
      device_client_id_blob: id,
      device_private_key: key
    };
  }
  async pack(format = "wvd") {
    if (format === "wvd") {
      const id = ClientIdentification.encode(this.id).finish();
      const key = await this.exportKey();
      const keyDer = fromBuffer(key).toText().split("\n").map((s) => s.trim()).slice(1, -1).join("\n");
      const keyDerBinary = fromBase64(keyDer).toBuffer();
      const [type] = types.entries().find(([, type2]) => type2 === this.type);
      const wvd = buildWvd({
        clientId: id,
        deviceType: type,
        securityLevel: this.securityLevel,
        privateKey: keyDerBinary
      });
      return wvd;
    } else {
      throw new Error("Unsupported format");
    }
  }
  async importKey(pkcs1) {
    const pkcs1pem = typeof pkcs1 === "string" ? pkcs1 : fromBuffer(pkcs1).toText();
    const pkcs8pem = toPKCS8(pkcs1pem);
    const pemContents = pkcs8pem.split("\n").slice(1, -2).join("\n");
    const data = fromBase64(pemContents).toBuffer();
    const keyForDecrypt = await crypto.subtle.importKey(
      "pkcs8",
      data,
      { name: "RSA-OAEP", hash: "SHA-1" },
      true,
      ["decrypt"]
    );
    const keyForSign = await crypto.subtle.importKey(
      "pkcs8",
      data,
      { name: "RSA-PSS", hash: "SHA-1" },
      true,
      ["sign"]
    );
    this.#key = { forDecrypt: keyForDecrypt, forSign: keyForSign };
    return this.#key;
  }
  async exportKey() {
    const key = this.key.forSign;
    const der = await crypto.subtle.exportKey("pkcs8", key);
    const derAsBinary = new Uint8Array(der);
    const derAsBase64 = fromBuffer(derAsBinary).toBase64();
    const pemHeader = "-----BEGIN PRIVATE KEY-----";
    const pemFooter = "-----END PRIVATE KEY-----";
    const pem = `${pemHeader}
${derAsBase64}
-----${pemFooter}-----`;
    const pkcs1 = toPKCS1(pem).trim();
    return fromText(pkcs1).toBuffer();
  }
  async decryptWithKey(data) {
    const result = await crypto.subtle.decrypt(
      { name: "RSA-OAEP" },
      this.key.forDecrypt,
      data
    );
    return new Uint8Array(result);
  }
  async signWithKey(data) {
    const result = await crypto.subtle.sign(
      { name: "RSA-PSS", saltLength: 20 },
      this.key.forSign,
      data
    );
    return new Uint8Array(result);
  }
  async encryptId(certificate) {
    if (!certificate.drmCertificate)
      throw Error("Service certificate not found");
    const serviceCertificate = DrmCertificate.decode(
      certificate.drmCertificate
    );
    const id = ClientIdentification.encode(this.id).finish();
    const privacyKey = await generateAesCbcKey();
    const encryptedClientIdIv = getRandomBytes2(16);
    const encryptedClientId = await encryptWithAesCbc(
      id,
      privacyKey,
      encryptedClientIdIv
    );
    const publicKey = await importCertificateKey(
      serviceCertificate.publicKey,
      "encrypt"
    );
    const privacyKeyData = await exportKey(privacyKey);
    const encryptedPrivacyKey = await encryptWithRsaOaep(
      privacyKeyData,
      publicKey
    );
    return EncryptedClientIdentification.create({
      providerId: serviceCertificate.providerId,
      serviceCertificateSerialNumber: serviceCertificate.serialNumber,
      encryptedClientIdIv,
      encryptedPrivacyKey,
      encryptedClientId
    });
  }
  toString() {
    return `${this.systemId} L${this.securityLevel}`;
  }
  /**
   * https://www.w3.org/TR/encrypted-media-2/#navigator-extension-requestmediakeysystemaccess
   */
  requestMediaKeySystemAccess(keySystem, supportedConfigurations) {
    if (keySystem !== "com.widevine.alpha")
      throw new Error("Unsupported media key system");
    return {
      keySystem,
      createMediaKeys: async () => {
        const state = { serverCertificate: null };
        return {
          createSession: (sessionType) => {
            return new Session2(sessionType, this);
          },
          setServerCertificate: async (serverCertificate) => {
            state.serverCertificate = serverCertificate;
            return true;
          },
          getStatusForPolicy: async () => "usable"
        };
      },
      getConfiguration: () => supportedConfigurations[0]
    };
  }
};

// src/lib/widevine/cdm.ts
var WidevineCdm = class {
  keySystem = "com.widevine.alpha";
  sessions;
  client;
  static Client = WidevineClient;
  constructor({ client }) {
    this.sessions = /* @__PURE__ */ new Map();
    this.client = client;
  }
  createSession(sessionType) {
    const session = new Session2(sessionType, this.client);
    this.sessions.set(session.sessionId, session);
    return session.sessionId;
  }
  async generateRequest(sessionId, initData, initDataType) {
    const session = this.sessions.get(sessionId);
    if (!session) throw new Error("Session not found");
    if (!initData.length) throw new Error("Init data is empty");
    const licenseRequest = await session.generateRequest(
      initDataType ?? "cenc",
      initData
    );
    return licenseRequest;
  }
  async updateSession(sessionId, response) {
    const session = this.sessions.get(sessionId);
    if (!session) throw new Error("Session not found");
    await session.update(response);
  }
  async closeSession(sessionId) {
    const session = this.sessions.get(sessionId);
    if (!session) throw new Error("Session not found");
    await session.close();
    this.sessions.delete(sessionId);
  }
  async removeSession(sessionId) {
    const session = this.sessions.get(sessionId);
    if (!session) throw new Error("Session not found");
    await session.remove();
    this.sessions.delete(sessionId);
  }
  async getKeys(sessionId) {
    const session = this.sessions.get(sessionId);
    if (!session) throw new Error("Session not found");
    const keys = Array.from(session.keys.values());
    return keys.map((key) => ({ key: key.value, keyId: key.id }));
  }
};

// src/lib/playready/client.ts
var import_utils12 = require("@noble/curves/utils");

// src/lib/playready/bcert.ts
var import_barsic = require("barsic");

// src/lib/playready/exceptions.ts
var PlayreadyException = class extends Error {
  constructor(message) {
    super(message);
    this.name = this.constructor.name;
  }
};
var InvalidCertificate = class extends PlayreadyException {
  constructor(message = "The BCert is not correctly formatted.") {
    super(message);
  }
};
var InvalidCertificateChain = class extends PlayreadyException {
  constructor(message = "The BCertChain is not correctly formatted.") {
    super(message);
  }
};

// src/lib/playready/bcert.ts
var BCertCertType = {
  UNKNOWN: 0,
  PC: 1,
  DEVICE: 2,
  DOMAIN: 3,
  ISSUER: 4,
  CRL_SIGNER: 5,
  SERVICE: 6,
  SILVERLIGHT: 7,
  APPLICATION: 8,
  METERING: 9,
  KEYFILESIGNER: 10,
  SERVER: 11,
  LICENSESIGNER: 12,
  SECURETIMESERVER: 13,
  RPROVMODELAUTH: 14
};
var BCertObjType = {
  BASIC: 1,
  DOMAIN: 2,
  PC: 3,
  DEVICE: 4,
  FEATURE: 5,
  KEY: 6,
  MANUFACTURER: 7,
  SIGNATURE: 8,
  SILVERLIGHT: 9,
  METERING: 10,
  EXTDATASIGNKEY: 11,
  EXTDATACONTAINER: 12,
  EXTDATASIGNATURE: 13,
  EXTDATA_HWID: 14,
  SERVER: 15,
  SECURITY_VERSION: 16,
  SECURITY_VERSION_2: 17,
  UNKNOWN_OBJECT_ID: 65533
};
var BCertFlag = {
  EMPTY: 0,
  EXTDATA_PRESENT: 1
};
var BCertObjFlag = {
  EMPTY: 0,
  MUST_UNDERSTAND: 1,
  CONTAINER_OBJ: 2
};
var BCertSignatureType = { P256: 1 };
var BCertKeyType = { ECC256: 1 };
var BCertKeyUsage = {
  SIGN: 1,
  ENCRYPT_KEY: 2,
  ISSUER_DEVICE: 6
};
var BCertFeatures = {
  SECURE_CLOCK: 4,
  SUPPORTS_CRLS: 9,
  SUPPORTS_PR3_FEATURES: 13
};
var BasicInfo = import_barsic.b.object({
  cert_id: import_barsic.b.bytes(16),
  security_level: import_barsic.b.uint32(),
  flags: import_barsic.b.uint32(),
  cert_type: import_barsic.b.uint32(),
  public_key_digest: import_barsic.b.bytes(32),
  expiration_date: import_barsic.b.uint32(),
  client_id: import_barsic.b.bytes(16)
});
var DomainInfo = import_barsic.b.object({
  service_id: import_barsic.b.bytes(16),
  account_id: import_barsic.b.bytes(16),
  revision_timestamp: import_barsic.b.uint32(),
  domain_url_length: import_barsic.b.uint32(),
  domain_url: import_barsic.b.bytes((ctx) => ctx.domain_url_length + 3 & 4294967292)
});
var PCInfo = import_barsic.b.object({
  security_version: import_barsic.b.uint32()
});
var DeviceInfo = import_barsic.b.object({
  max_license: import_barsic.b.uint32(),
  max_header: import_barsic.b.uint32(),
  max_chain_depth: import_barsic.b.uint32()
});
var FeatureInfo = import_barsic.b.object({
  feature_count: import_barsic.b.uint32(),
  features: import_barsic.b.array(import_barsic.b.uint32(), (ctx) => ctx.feature_count)
});
var CertKey = import_barsic.b.object({
  type: import_barsic.b.uint16(),
  length: import_barsic.b.uint16(),
  flags: import_barsic.b.uint32(),
  key: import_barsic.b.bytes((ctx) => ctx.length / 8),
  usages_count: import_barsic.b.uint32(),
  usages: import_barsic.b.array(import_barsic.b.uint32(), (ctx) => ctx.usages_count)
});
var KeyInfo = import_barsic.b.object({
  key_count: import_barsic.b.uint32(),
  cert_keys: import_barsic.b.array(CertKey, (ctx) => ctx.key_count)
});
var ManufacturerInfo = import_barsic.b.object({
  flags: import_barsic.b.uint32(),
  manufacturer_name_length: import_barsic.b.uint32(),
  manufacturer_name: import_barsic.b.bytes(
    (ctx) => ctx.manufacturer_name_length + 3 & 4294967292
  ),
  model_name_length: import_barsic.b.uint32(),
  model_name: import_barsic.b.bytes((ctx) => ctx.model_name_length + 3 & 4294967292),
  model_number_length: import_barsic.b.uint32(),
  model_number: import_barsic.b.bytes((ctx) => ctx.model_number_length + 3 & 4294967292)
});
var SignatureInfo = import_barsic.b.object({
  signature_type: import_barsic.b.uint16(),
  signature_size: import_barsic.b.uint16(),
  signature: import_barsic.b.bytes((ctx) => ctx.signature_size),
  signature_key_size: import_barsic.b.uint32(),
  signature_key: import_barsic.b.bytes((ctx) => ctx.signature_key_size / 8)
});
var SilverlightInfo = import_barsic.b.object({
  security_version: import_barsic.b.uint32(),
  platform_identifier: import_barsic.b.uint32()
});
var MeteringInfo = import_barsic.b.object({
  metering_id: import_barsic.b.bytes(16),
  metering_url_length: import_barsic.b.uint32(),
  metering_url: import_barsic.b.bytes((ctx) => ctx.metering_url_length + 3 & 4294967292)
});
var ExtDataSignKeyInfo = import_barsic.b.object({
  key_type: import_barsic.b.uint16(),
  key_length: import_barsic.b.uint16(),
  flags: import_barsic.b.uint32(),
  key: import_barsic.b.bytes((ctx) => ctx.key_length / 8)
});
var DataRecord = import_barsic.b.object({
  data_size: import_barsic.b.uint32(),
  data: import_barsic.b.bytes((ctx) => ctx.data_size)
});
var ExtDataSignature = import_barsic.b.object({
  signature_type: import_barsic.b.uint16(),
  signature_size: import_barsic.b.uint16(),
  signature: import_barsic.b.bytes((ctx) => ctx.signature_size)
});
var ExtDataContainer = import_barsic.b.object({
  record_count: import_barsic.b.uint32(),
  records: import_barsic.b.array(DataRecord, (ctx) => ctx.record_count),
  signature: ExtDataSignature
});
var ServerInfo = import_barsic.b.object({
  warning_days: import_barsic.b.uint32()
});
var SecurityVersion = import_barsic.b.object({
  security_version: import_barsic.b.uint32(),
  platform_identifier: import_barsic.b.uint32()
});
var Attribute = import_barsic.b.sized(
  import_barsic.b.object({
    flags: import_barsic.b.uint16(),
    tag: import_barsic.b.uint16(),
    length: import_barsic.b.uint32(),
    attribute: import_barsic.b.prefixed(
      (ctx) => ctx.length - 8,
      import_barsic.b.discriminatedUnion(
        (ctx) => ctx.tag,
        {
          [BCertObjType.BASIC]: BasicInfo,
          [BCertObjType.DOMAIN]: DomainInfo,
          [BCertObjType.PC]: PCInfo,
          [BCertObjType.DEVICE]: DeviceInfo,
          [BCertObjType.FEATURE]: FeatureInfo,
          [BCertObjType.KEY]: KeyInfo,
          [BCertObjType.MANUFACTURER]: ManufacturerInfo,
          [BCertObjType.SIGNATURE]: SignatureInfo,
          [BCertObjType.SILVERLIGHT]: SilverlightInfo,
          [BCertObjType.METERING]: MeteringInfo,
          [BCertObjType.EXTDATASIGNKEY]: ExtDataSignKeyInfo,
          [BCertObjType.EXTDATACONTAINER]: ExtDataContainer,
          [BCertObjType.EXTDATASIGNATURE]: ExtDataSignature,
          [BCertObjType.EXTDATA_HWID]: import_barsic.b.bytes((ctx) => ctx.length - 8),
          [BCertObjType.SERVER]: ServerInfo,
          [BCertObjType.SECURITY_VERSION]: SecurityVersion,
          [BCertObjType.SECURITY_VERSION_2]: SecurityVersion
        },
        import_barsic.b.bytes((ctx) => ctx.length - 8)
      )
    )
  }),
  (item) => item.length
);
var BCertBody = import_barsic.b.object({
  signature: import_barsic.b.literal("CERT"),
  version: import_barsic.b.uint32(),
  total_length: import_barsic.b.uint32(),
  certificate_length: import_barsic.b.uint32(),
  attributes: import_barsic.b.greedyRange(Attribute)
});
var BCert = import_barsic.b.sized(BCertBody, (ctx) => ctx.total_length);
var BCertChain = import_barsic.b.object({
  signature: import_barsic.b.literal("CHAI"),
  version: import_barsic.b.uint32(),
  total_length: import_barsic.b.uint32(),
  flags: import_barsic.b.uint32(),
  certificate_count: import_barsic.b.uint32(),
  // The header is 20 bytes (4*5). The certificates fill the rest of the 'total_length'.
  certificates: import_barsic.b.prefixed(
    (ctx) => ctx.total_length - 20,
    import_barsic.b.greedyRange(BCert)
  )
});
var Certificate = class _Certificate {
  parsed;
  _BCERT;
  constructor(parsedBCert, bcertObj = BCert) {
    this.parsed = parsedBCert;
    this._BCERT = bcertObj;
  }
  static async newLeafCert(params) {
    const basicInfo = {
      cert_id: params.certId,
      security_level: params.securityLevel,
      flags: BCertFlag.EMPTY,
      cert_type: BCertCertType.DEVICE,
      public_key_digest: await params.signingKey.publicSha256Digest(),
      expiration_date: params.expiry ?? 4294967295,
      client_id: params.clientId
    };
    const basicInfoAttribute = {
      flags: BCertObjFlag.MUST_UNDERSTAND,
      tag: BCertObjType.BASIC,
      length: BasicInfo.build(basicInfo).length + 8,
      attribute: basicInfo
    };
    const deviceInfo = {
      max_license: 10240,
      max_header: 15360,
      max_chain_depth: 2
    };
    const deviceInfoAttribute = {
      flags: BCertObjFlag.MUST_UNDERSTAND,
      tag: BCertObjType.DEVICE,
      length: DeviceInfo.build(deviceInfo).length + 8,
      attribute: deviceInfo
    };
    const feature = {
      feature_count: 3,
      features: [
        BCertFeatures.SECURE_CLOCK,
        BCertFeatures.SUPPORTS_CRLS,
        BCertFeatures.SUPPORTS_PR3_FEATURES
      ]
    };
    const featureAttribute = {
      flags: BCertObjFlag.MUST_UNDERSTAND,
      tag: BCertObjType.FEATURE,
      length: FeatureInfo.build(feature).length + 8,
      attribute: feature
    };
    const signingKeyPublicBytes = params.signingKey.publicBytes();
    const certKeySign = {
      type: BCertKeyType.ECC256,
      length: signingKeyPublicBytes.length * 8,
      flags: BCertFlag.EMPTY,
      key: signingKeyPublicBytes,
      usages_count: 1,
      usages: [BCertKeyUsage.SIGN]
    };
    const encryptionKeyPublicBytes = params.encryptionKey.publicBytes();
    const certKeyEncrypt = {
      type: BCertKeyType.ECC256,
      length: encryptionKeyPublicBytes.length * 8,
      flags: BCertFlag.EMPTY,
      key: encryptionKeyPublicBytes,
      usages_count: 1,
      usages: [BCertKeyUsage.ENCRYPT_KEY]
    };
    const keyInfo = {
      key_count: 2,
      cert_keys: [certKeySign, certKeyEncrypt]
    };
    const keyInfoAttribute = {
      flags: BCertObjFlag.MUST_UNDERSTAND,
      tag: BCertObjType.KEY,
      length: KeyInfo.build(keyInfo).length + 8,
      attribute: keyInfo
    };
    const manufacturerInfo = params.parent.get(0).getAttribute(BCertObjType.MANUFACTURER);
    if (!manufacturerInfo) throw new Error("Manufacturer info not found");
    const newBCertContainer = {
      signature: fromText("CERT").toBuffer(),
      version: 1,
      // total_length: 0, // filled at a later time
      // certificate_length: 0, // filled at a later time
      attributes: [
        basicInfoAttribute,
        deviceInfoAttribute,
        featureAttribute,
        keyInfoAttribute,
        manufacturerInfo
      ]
    };
    const payload = BCertBody.build(newBCertContainer);
    const payloadLength = payload.length;
    newBCertContainer.certificate_length = payloadLength;
    newBCertContainer.total_length = payloadLength + 144;
    const signPayload = BCert.build(newBCertContainer).subarray(
      0,
      payloadLength
    );
    const signature = await ecc256Sign(params.groupKey.privateKey, signPayload);
    const groupKeyPublicBytes = params.groupKey.publicBytes();
    const signatureInfo = {
      signature_type: BCertSignatureType.P256,
      signature_size: signature.toCompactRawBytes().length,
      signature: signature.toCompactRawBytes(),
      signature_key_size: groupKeyPublicBytes.length * 8,
      signature_key: groupKeyPublicBytes
    };
    const signatureInfoAttribute = {
      flags: BCertObjFlag.MUST_UNDERSTAND,
      tag: BCertObjType.SIGNATURE,
      length: SignatureInfo.build(signatureInfo).length + 8,
      attribute: signatureInfo
    };
    newBCertContainer.attributes.push(signatureInfoAttribute);
    return new _Certificate(newBCertContainer);
  }
  static loads(data) {
    const parsed = BCert.parse(data);
    const cert = BCert;
    return new _Certificate(parsed, cert);
  }
  getAttribute(type) {
    return this.parsed.attributes.find((attr) => attr.tag === type);
  }
  getSecurityLevel() {
    const basicInfo = this.getAttribute(BCertObjType.BASIC);
    if (basicInfo && "security_level" in basicInfo.attribute)
      return basicInfo.attribute.security_level;
  }
  static _unpad(name) {
    return fromBuffer(name).toText().replace(/\x00+$/, "");
  }
  getName() {
    const info = this.getAttribute(BCertObjType.MANUFACTURER)?.attribute;
    if (!info || !("manufacturer_name" in info)) return;
    return info ? `${_Certificate._unpad(info.manufacturer_name)} ${_Certificate._unpad(info.model_name)} ${_Certificate._unpad(info.model_number)}`.trim() : void 0;
  }
  getIssuerKey() {
    const keyInfo = this.getAttribute(BCertObjType.KEY)?.attribute;
    if (!keyInfo || !("cert_keys" in keyInfo)) return;
    return keyInfo?.cert_keys.find(
      (key) => key.usages.includes(BCertKeyUsage.ISSUER_DEVICE)
    )?.key;
  }
  dumps = () => BCert.build(this.parsed);
  async verify(publicKey, index) {
    const signatureObject = this.getAttribute(BCertObjType.SIGNATURE);
    if (!signatureObject || !("signature_key" in signatureObject.attribute) || !("signature" in signatureObject.attribute))
      throw new InvalidCertificate(
        `No signature object in certificate ${index}`
      );
    const signatureKey = signatureObject.attribute.signature_key;
    const signature = signatureObject.attribute.signature;
    if (!publicKey.every((byte, i) => byte === signatureKey[i]))
      throw new InvalidCertificate(
        `Signature keys of certificate ${index} do not match`
      );
    const fullCertData = this.dumps();
    const signPayload = fullCertData.slice(
      0,
      fullCertData.length - signatureObject.length
    );
    const uncompressedPublicKey = new Uint8Array(65);
    uncompressedPublicKey[0] = 4;
    uncompressedPublicKey.set(signatureKey, 1);
    const isValid = await ecc256Verify(
      uncompressedPublicKey,
      signPayload,
      signature
    );
    if (!isValid) {
      throw new InvalidCertificate(
        `Signature of certificate ${index} is not authentic`
      );
    }
    const issuerKey = this.getIssuerKey();
    return issuerKey;
  }
};
var CertificateChain = class _CertificateChain {
  ECC256MSBCertRootIssuerPubKey = fromHex(
    "864d61cff2256e422c568b3c28001cfb3e1527658584ba0521b79b1828d936de1d826a8fc3e6e7fa7a90d5ca2946f1f64a2efb9f5dcffe7e434eb44293fac5ab"
  ).toBuffer();
  parsed;
  _BCERT_CHAIN;
  constructor(parsedBCertChain, bcertChainObj = BCertChain) {
    this.parsed = parsedBCertChain;
    this._BCERT_CHAIN = bcertChainObj;
  }
  static from(data) {
    const certChain = BCertChain;
    const parsed = BCertChain.parse(data, false);
    return new _CertificateChain(parsed, certChain);
  }
  dumps() {
    return this._BCERT_CHAIN.build(this.parsed);
  }
  getSecurityLevel() {
    return this.get(0).getSecurityLevel();
  }
  getName() {
    return this.get(0).getName();
  }
  async verify() {
    let issuerKey = this.ECC256MSBCertRootIssuerPubKey;
    try {
      for (let i = this.count() - 1; i >= 0; i--) {
        const certificate = this.get(i);
        issuerKey = await certificate.verify(issuerKey, i);
        if (!issuerKey && i !== 0) {
          throw new InvalidCertificate(`Certificate ${i} is not valid`);
        }
      }
    } catch (e) {
      if (e instanceof InvalidCertificate) {
        throw new InvalidCertificateChain(e.message);
      }
      throw e;
    }
    return true;
  }
  append(bcert) {
    this.parsed.certificate_count++;
    this.parsed.certificates.push(bcert.parsed);
    this.parsed.total_length += bcert.dumps().length;
  }
  prepend(bcert) {
    this.parsed.certificate_count++;
    this.parsed.certificates.unshift(bcert.parsed);
    this.parsed.total_length += bcert.dumps().length;
  }
  remove(index) {
    if (this.count() <= 0) {
      throw new InvalidCertificateChain(
        `CertificateChain does not contain any Certificates`
      );
    }
    if (index >= this.count()) {
      throw new RangeError(
        `No Certificate at index ${index}, ${this.count()} total`
      );
    }
    this.parsed.total_length -= this.get(index).dumps().length;
    this.parsed.certificates.splice(index, 1);
    this.parsed.certificate_count--;
  }
  get(index) {
    if (this.count() <= 0) {
      throw new InvalidCertificateChain(
        "CertificateChain does not contain any Certificates"
      );
    }
    if (index >= this.count()) {
      throw new RangeError(
        `No Certificate at index ${index}, ${this.count()} total`
      );
    }
    return new Certificate(this.parsed.certificates[index]);
  }
  count() {
    return this.parsed.certificate_count;
  }
};

// src/lib/playready/prd.ts
var import_barsic2 = require("barsic");
var PRD_MAGIC = fromText("PRD").toBuffer();
var PRD2 = import_barsic2.b.object({
  signature: import_barsic2.b.literal("PRD"),
  version: import_barsic2.b.uint8(),
  group_certificate_length: import_barsic2.b.uint32(),
  group_certificate: import_barsic2.b.bytes((ctx) => ctx.group_certificate_length),
  encryption_key: import_barsic2.b.bytes(96),
  signing_key: import_barsic2.b.bytes(96)
});
var PRD3 = import_barsic2.b.object({
  signature: import_barsic2.b.literal("PRD"),
  version: import_barsic2.b.uint8(),
  group_key: import_barsic2.b.bytes(96),
  encryption_key: import_barsic2.b.bytes(96),
  signing_key: import_barsic2.b.bytes(96),
  group_certificate_length: import_barsic2.b.uint32(),
  group_certificate: import_barsic2.b.bytes((ctx) => ctx.group_certificate_length)
});
var PRD = import_barsic2.b.object({
  signature: import_barsic2.b.literal("PRD"),
  version: import_barsic2.b.uint8(),
  data: import_barsic2.b.discriminatedUnion((ctx) => ctx.version, {
    2: PRD2,
    3: PRD3
  })
});

// src/lib/playready/client.ts
var PlayReadyClient = class _PlayReadyClient {
  groupKey;
  encryptionKey;
  signingKey;
  groupCertificate;
  securityLevel;
  constructor(data) {
    this.groupKey = EccKey.from(data.groupKey);
    this.encryptionKey = EccKey.from(data.encryptionKey);
    this.signingKey = EccKey.from(data.signingKey);
    this.groupCertificate = CertificateChain.from(data.groupCertificate);
    this.securityLevel = this.groupCertificate.getSecurityLevel();
  }
  static async from(payload) {
    if ("prd" in payload) {
      const parsed = PRD3.parse(payload.prd);
      const groupKey = parsed.group_key;
      const encryptionKey = parsed.encryption_key;
      const signingKey = parsed.signing_key;
      const groupCertificate = parsed.group_certificate;
      return new _PlayReadyClient({
        groupKey,
        encryptionKey,
        signingKey,
        groupCertificate
      });
    } else {
      const groupKey = EccKey.from(payload.groupKey);
      const encryptionKey = payload.encryptionKey ? EccKey.from(payload.encryptionKey) : EccKey.generate();
      const signingKey = payload.signingKey ? EccKey.from(payload.signingKey) : EccKey.generate();
      const certificateChain = CertificateChain.from(payload.groupCertificate);
      const issuerKey = certificateChain.get(0).getIssuerKey();
      const groupKeyBytes = groupKey.publicBytes();
      if (issuerKey && !(0, import_utils12.equalBytes)(issuerKey, groupKeyBytes)) {
        throw new InvalidCertificateChain(
          "Group key does not match this certificate"
        );
      }
      const newCertificate = await Certificate.newLeafCert({
        certId: getRandomBytes(16),
        securityLevel: certificateChain.getSecurityLevel(),
        clientId: getRandomBytes(16),
        signingKey,
        encryptionKey,
        groupKey,
        parent: certificateChain
      });
      certificateChain.prepend(newCertificate);
      await certificateChain.verify();
      return new _PlayReadyClient({
        groupKey: groupKey.dumps(),
        encryptionKey: encryptionKey.dumps(),
        signingKey: signingKey.dumps(),
        groupCertificate: certificateChain.dumps()
      });
    }
  }
  getName() {
    const name = `${this.groupCertificate.getName()}_sl${this.securityLevel}`;
    return name.split("").filter((char) => char.match(/[a-z0-9_-]/)).join("").trim().toLowerCase().replaceAll(" ", "_");
  }
  get filename() {
    return this.getName();
  }
  get label() {
    return `${this.groupCertificate.getName()}`;
  }
  pack() {
    return PRD3.build({
      signature: PRD_MAGIC,
      version: 3,
      group_key: this.groupKey.dumps(),
      encryption_key: this.encryptionKey.dumps(),
      signing_key: this.signingKey.dumps(),
      group_certificate_length: this.groupCertificate.dumps().length,
      group_certificate: this.groupCertificate.dumps()
    });
  }
  unpack() {
    this.groupCertificate.remove(0);
    return {
      "zgpriv.dat": this.groupKey.dumps(true),
      "bgroupcert.dat": this.groupCertificate.dumps()
    };
  }
};

// src/lib/playready/pssh.ts
var PlayreadyObject = class {
  type;
  length;
  wrmHeader;
  constructor(reader) {
    this.type = reader.readUint16(true);
    this.length = reader.readUint16(true);
    this.wrmHeader = null;
    if (this.type === 1) {
      this.wrmHeader = tryGetUtf16Le(reader.readBytes(this.length));
    }
  }
};
var PlayreadyHeader = class {
  length;
  recordCount;
  records;
  constructor(reader) {
    this.length = reader.readUint32(true);
    this.recordCount = reader.readUint16(true);
    this.records = [];
    for (let i = 0; i < this.recordCount; i++) {
      this.records.push(new PlayreadyObject(reader));
    }
  }
};
var Pssh = class {
  PLAYREADY_SYSTEM_ID = new Uint8Array([
    154,
    4,
    240,
    121,
    152,
    64,
    66,
    134,
    171,
    146,
    230,
    91,
    224,
    136,
    95,
    149
  ]);
  wrmHeaders;
  constructor(data) {
    const bytes = typeof data === "string" ? fromBase64(data).toBuffer() : data;
    this.wrmHeaders = this.#readWrmHeaders(bytes).filter(Boolean);
  }
  #readWrmHeaders(bytes) {
    const string = tryGetUtf16Le(bytes);
    if (string !== null) {
      console.log(1);
      return [string];
    }
    if (this.#isPsshBox(bytes)) {
      const boxData = bytes.subarray(32);
      const wrmHeader = tryGetUtf16Le(boxData);
      if (wrmHeader) {
        return [wrmHeader];
      } else {
        const reader = new BinaryReader(boxData);
        return new PlayreadyHeader(reader).records.map(
          (record) => record.wrmHeader
        );
      }
    } else {
      const reader = new BinaryReader(bytes);
      const isPlayreadyHeader = reader.readUint16(true) > 3;
      reader.reset();
      if (isPlayreadyHeader) {
        return new PlayreadyHeader(reader).records.map(
          (record) => record.wrmHeader
        );
      } else {
        return [new PlayreadyObject(reader).wrmHeader];
      }
    }
  }
  #isPsshBox(bytes) {
    return bytes[0] === 0 && bytes[1] === 0 && bytes.length >= 32 && compareArrays(bytes.subarray(12, 28), this.PLAYREADY_SYSTEM_ID);
  }
};

// src/lib/playready/session.ts
var import_xmldom = require("@xmldom/xmldom");
var utils4 = __toESM(require("@noble/curves/utils"), 1);

// src/lib/playready/xmr-license.ts
var _SignatureObject = class {
  signatureType;
  signatureDataLength;
  signatureData;
  constructor(reader) {
    this.signatureType = reader.readUint16();
    this.signatureDataLength = reader.readUint16();
    this.signatureData = reader.readBytes(this.signatureDataLength);
  }
};
var _AuxiliaryKey = class {
  location;
  key;
  constructor(reader) {
    this.location = reader.readUint32();
    this.key = reader.readBytes(16);
  }
};
var _AuxiliaryKeysObject = class {
  count;
  auxiliaryKeys;
  constructor(reader) {
    this.count = reader.readUint16();
    this.auxiliaryKeys = [];
    for (let i = 0; i < this.count; i++) {
      this.auxiliaryKeys.push(new _AuxiliaryKey(reader));
    }
  }
};
var _ContentKeyObject = class {
  keyId;
  keyType;
  cipherType;
  keyLength;
  encryptedKey;
  constructor(reader) {
    this.keyId = reader.readBytes(16);
    this.keyType = reader.readUint16();
    this.cipherType = reader.readUint16();
    this.keyLength = reader.readUint16();
    this.encryptedKey = reader.readBytes(this.keyLength);
  }
};
var _XmrObject = class {
  flags;
  type;
  length;
  data;
  constructor(reader) {
    this.flags = reader.readUint16();
    this.type = reader.readUint16();
    this.length = reader.readUint32();
    this.data = null;
    if (this.flags === 0 || this.flags === 1) {
      switch (this.type) {
        case 10:
          this.data = new _ContentKeyObject(reader);
          break;
        case 11:
          this.data = new _SignatureObject(reader);
          break;
        case 81:
          this.data = new _AuxiliaryKeysObject(reader);
          break;
        default:
          this.data = reader.readBytes(this.length - 8);
      }
    }
  }
};
var _XmrLicense = class {
  signature;
  xmrVersion;
  rightsId;
  containers;
  constructor(reader) {
    this.signature = reader.readBytes(4);
    this.xmrVersion = reader.readUint32();
    this.rightsId = reader.readBytes(16);
    this.containers = [];
    while (reader.length > reader.offset) {
      this.containers.push(new _XmrObject(reader));
    }
  }
};
var XmrLicense = class _XmrLicense2 {
  #reader;
  #licenseObj;
  constructor(reader, license_obj) {
    this.#reader = reader;
    this.#licenseObj = license_obj;
  }
  static loads(bytes) {
    const reader = new BinaryReader(bytes);
    return new _XmrLicense2(reader, new _XmrLicense(reader));
  }
  getObjects(type) {
    return this.#licenseObj.containers.filter((obj) => obj.type === type);
  }
  async checkSignature(integrity_key) {
    const signatureObject = this.getObjects(11)[0].data;
    const raw_data = this.#reader.rawBytes;
    if (!(signatureObject instanceof _SignatureObject)) return false;
    const signatureData = raw_data.subarray(
      0,
      raw_data.length - (signatureObject.signatureDataLength + 12)
    );
    const signature = await aesCmac(integrity_key, signatureData);
    return compareArrays(signature, signatureObject.signatureData);
  }
};

// src/lib/playready/xml-key.ts
var utils3 = __toESM(require("@noble/curves/utils"), 1);
var XmlKey = class {
  #sharedPoint;
  sharedXKey;
  sharedYKey;
  aesIv;
  aesKey;
  constructor() {
    this.#sharedPoint = EccKey.generate();
    this.sharedXKey = this.#sharedPoint.publicKey.x;
    this.sharedYKey = this.#sharedPoint.publicKey.y;
    const sharedKeyXBytes = utils3.numberToBytesBE(this.sharedXKey, 32);
    this.aesIv = sharedKeyXBytes.subarray(0, 16);
    this.aesKey = sharedKeyXBytes.subarray(16, 32);
  }
  get point() {
    return this.#sharedPoint.publicKey;
  }
};

// src/lib/playready/key.ts
var Key2 = class {
  keyId;
  keyType;
  cipherType;
  key;
  constructor(keyId, keyType, cipherType, key) {
    this.keyId = this._swapEndianess(keyId);
    this.keyType = keyType;
    this.cipherType = cipherType;
    this.key = key;
  }
  _swapEndianess(uuidBytes) {
    return new Uint8Array([
      uuidBytes[3],
      uuidBytes[2],
      uuidBytes[1],
      uuidBytes[0],
      uuidBytes[5],
      uuidBytes[4],
      uuidBytes[7],
      uuidBytes[6],
      uuidBytes[8],
      uuidBytes[9],
      ...uuidBytes.slice(10, 16)
    ]);
  }
};

// src/lib/playready/session.ts
var DEFAULT_CLIENT_VERSION = "10.0.16384.10011";
var Session3 = class {
  sessionId;
  type;
  certificateChain;
  encryptionKey;
  signingKey;
  clientVersion;
  rgbMagicConstantZero;
  #wmrmServerKey;
  parser;
  keys;
  static Client = PlayReadyClient;
  constructor(sessionType = "temporary", client) {
    this.sessionId = fromBuffer(getRandomBytes2()).toBase64();
    this.type = sessionType;
    if (client instanceof PlayReadyClient) {
      this.certificateChain = client.groupCertificate.dumps();
      this.encryptionKey = client.encryptionKey;
      this.signingKey = client.signingKey;
      this.clientVersion = DEFAULT_CLIENT_VERSION;
    } else {
      this.certificateChain = client.certificateChain;
      this.encryptionKey = EccKey.from(client.encryptionKey);
      this.signingKey = EccKey.from(client.signingKey);
      this.clientVersion = client.clientVersion ?? DEFAULT_CLIENT_VERSION;
    }
    this.rgbMagicConstantZero = new Uint8Array([
      126,
      233,
      237,
      74,
      247,
      115,
      34,
      79,
      0,
      184,
      234,
      126,
      251,
      2,
      124,
      187
    ]);
    this.#wmrmServerKey = {
      x: 90785344306297710604867503975059265028223978614363440949957868233137570135451n,
      y: 68827801477692731286297993103001909218341737652466656881935707825713852622178n
    };
    this.parser = new import_xmldom.DOMParser();
    this.keys = [];
  }
  #getKeyCipher(xmlKey) {
    const encrypted = ElGamal.encrypt(xmlKey.point, this.#wmrmServerKey);
    return new Uint8Array([
      ...utils4.numberToBytesBE(encrypted.point1.x, 32),
      ...utils4.numberToBytesBE(encrypted.point1.y, 32),
      ...utils4.numberToBytesBE(encrypted.point2.x, 32),
      ...utils4.numberToBytesBE(encrypted.point2.y, 32)
    ]);
  }
  async #getDataCipher(xmlKey) {
    const b64CertificateChain = bytesToBase64(this.certificateChain);
    const body = `<Data><CertificateChains><CertificateChain>${b64CertificateChain}</CertificateChain></CertificateChains><Features><Feature Name="AESCBC">""</Feature><REE><AESCBCS></AESCBCS></REE></Features></Data>`;
    const key = await importAesCbcKeyForEncrypt(xmlKey.aesKey);
    const cipherText = await encryptWithAesCbc(
      stringToBytes(body),
      key,
      xmlKey.aesIv
    );
    return new Uint8Array([...xmlKey.aesIv, ...cipherText]);
  }
  #buildDigestInfo(digestValue) {
    return `<SignedInfo xmlns="http://www.w3.org/2000/09/xmldsig#"><CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"></CanonicalizationMethod><SignatureMethod Algorithm="http://schemas.microsoft.com/DRM/2007/03/protocols#ecdsa-sha256"></SignatureMethod><Reference URI="#SignedData"><DigestMethod Algorithm="http://schemas.microsoft.com/DRM/2007/03/protocols#sha256"></DigestMethod><DigestValue>${digestValue}</DigestValue></Reference></SignedInfo>`;
  }
  #buildDigestContent(contentHeader, nonce, keyCipher, dataCipher, protocolVersion, revLists) {
    const clientTime = Math.floor(Date.now() / 1e3);
    return `<LA xmlns="http://schemas.microsoft.com/DRM/2007/03/protocols" Id="SignedData" xml:space="preserve"><Version>${protocolVersion}</Version><ContentHeader>${contentHeader}</ContentHeader><CLIENTINFO><CLIENTVERSION>${this.clientVersion}</CLIENTVERSION></CLIENTINFO>` + revLists + `<LicenseNonce>${nonce}</LicenseNonce><ClientTime>${clientTime}</ClientTime><EncryptedData xmlns="http://www.w3.org/2001/04/xmlenc#" Type="http://www.w3.org/2001/04/xmlenc#Element"><EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"></EncryptionMethod><KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"><EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#"><EncryptionMethod Algorithm="http://schemas.microsoft.com/DRM/2007/03/protocols#ecc256"></EncryptionMethod><KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"><KeyName>WMRMServer</KeyName></KeyInfo><CipherData><CipherValue>${keyCipher}</CipherValue></CipherData></EncryptedKey></KeyInfo><CipherData><CipherValue>${dataCipher}</CipherValue></CipherData></EncryptedData></LA>`;
  }
  #buildMainBody(laContent, signedInfo, signatureValue, publicKey) {
    return '<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><AcquireLicense xmlns="http://schemas.microsoft.com/DRM/2007/03/protocols"><challenge><Challenge xmlns="http://schemas.microsoft.com/DRM/2007/03/protocols/messages">' + laContent + '<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">' + signedInfo + `<SignatureValue>${signatureValue}</SignatureValue><KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"><KeyValue><ECCKeyValue><PublicKey>${publicKey}</PublicKey></ECCKeyValue></KeyValue></KeyInfo></Signature></Challenge></challenge></AcquireLicense></soap:Body></soap:Envelope>`;
  }
  async generateRequest(sessionId, initData, initDataType) {
    const pssh = new Pssh(initData);
    const wrmHeader = pssh.wrmHeaders[0];
    const challenge = await this.getLicenseChallenge(wrmHeader);
    return fromText(challenge).toBuffer();
  }
  async update(response) {
    const keys = await this.parseLicense(fromBuffer(response).toText());
    if (keys) this.keys = keys;
  }
  async getLicenseChallenge(wrm_header, rev_lists) {
    const xml_key = new XmlKey();
    const wrmHeaderDoc = this.parser.parseFromString(
      wrm_header,
      "application/xml"
    ).documentElement;
    const wrmHeaderVersion = wrmHeaderDoc?.getAttribute("version");
    let protocol_version = 1;
    switch (wrmHeaderVersion) {
      case "4.3.0.0":
        protocol_version = 5;
        break;
      case "4.2.0.0":
        protocol_version = 4;
        break;
    }
    const laContent = this.#buildDigestContent(
      wrm_header,
      bytesToBase64(getRandomBytes2(16)),
      bytesToBase64(this.#getKeyCipher(xml_key)),
      bytesToBase64(await this.#getDataCipher(xml_key)),
      protocol_version,
      rev_lists
    );
    const contentHash = await createSha256(fromText(laContent).toBuffer());
    const signedInfo = this.#buildDigestInfo(bytesToBase64(contentHash));
    const signature = await ecc256Sign(
      this.signingKey.privateKey,
      fromText(signedInfo).toBuffer()
    );
    const rawSignature = new Uint8Array([
      ...utils4.numberToBytesBE(signature.r, 32),
      ...utils4.numberToBytesBE(signature.s, 32)
    ]);
    const singing_key = this.signingKey.publicBytes();
    return this.#buildMainBody(
      laContent,
      signedInfo,
      bytesToBase64(rawSignature),
      bytesToBase64(singing_key)
    );
  }
  async parseLicense(rawLicense) {
    const xmlDoc = this.parser.parseFromString(rawLicense, "application/xml");
    const licenseElements = xmlDoc.getElementsByTagName("License");
    const keys = [];
    for (const licenseElement of Array.from(licenseElements)) {
      const license = XmrLicense.loads(
        base64ToBytes(licenseElement.textContent ?? "")
      );
      const isScalable = license.getObjects(81).length > 0;
      for (const obj of license.getObjects(10)) {
        const contentKeyObject = obj.data;
        if (![3, 4, 6].includes(contentKeyObject.cipherType)) {
          return;
        }
        const viaSymmetric = contentKeyObject.cipherType === 6;
        const encryptedKey = contentKeyObject.encryptedKey;
        const decrypted = ecc256decrypt(
          this.encryptionKey.privateKey,
          encryptedKey
        );
        let ci = decrypted.subarray(0, 16);
        let ck = decrypted.subarray(16, 32);
        if (isScalable) {
          ci = decrypted.filter((_, index) => index % 2 === 0).slice(0, 16);
          ck = decrypted.filter((_, index) => index % 2 === 1).slice(0, 16);
          if (viaSymmetric) {
            const embeddedRootLicense = encryptedKey.subarray(0, 144);
            let embeddedLeafLicense = encryptedKey.subarray(144);
            const rgbKey = xorArrays(ck, this.rgbMagicConstantZero);
            const contentKeyPrime = await aesEcbEncrypt(ck, rgbKey);
            const auxKey = license.getObjects(81)[0].data.auxiliaryKeys[0].key;
            const uplinkXKey = await aesEcbEncrypt(contentKeyPrime, auxKey);
            const secondaryKey = await aesEcbEncrypt(
              ck,
              embeddedRootLicense.subarray(128)
            );
            embeddedLeafLicense = await aesEcbEncrypt(
              uplinkXKey,
              embeddedLeafLicense
            );
            embeddedLeafLicense = await aesEcbEncrypt(
              secondaryKey,
              embeddedLeafLicense
            );
            ci = embeddedLeafLicense.subarray(0, 16);
            ck = embeddedLeafLicense.subarray(16, 32);
          }
        }
        if (!license.checkSignature(ci)) {
          throw new Error("License integrity signature does not match");
        }
        keys.push(
          new Key2(
            contentKeyObject.keyId,
            contentKeyObject.keyType,
            contentKeyObject.cipherType,
            ck
          )
        );
      }
    }
    this.keys = keys;
    return keys;
  }
};

// src/lib/playready/cdm.ts
var PlayReadyCdm = class {
  keySystem = "com.microsoft.playready.recommendation";
  sessions;
  client;
  static Client = PlayReadyClient;
  constructor(options) {
    this.sessions = /* @__PURE__ */ new Map();
    this.client = options.client;
  }
  createSession(sessionType) {
    const session = new Session3(sessionType, this.client);
    this.sessions.set(session.sessionId, session);
    return session.sessionId;
  }
  async generateRequest(sessionId, initData, initDataType) {
    const session = this.sessions.get(sessionId);
    if (!session) throw new Error("Session not found");
    const pssh = new Pssh(initData);
    const wrmHeader = pssh.wrmHeaders[0];
    const challenge = await session.getLicenseChallenge(wrmHeader);
    return fromText(challenge).toBuffer();
  }
  async updateSession(sessionId, response) {
    const session = this.sessions.get(sessionId);
    if (!session) throw new Error("Session not found");
    await session.parseLicense(fromBuffer(response).toText());
  }
  async closeSession(sessionId) {
    const session = this.sessions.get(sessionId);
    if (!session) throw new Error("Session not found");
    this.sessions.delete(sessionId);
  }
  async getKeys(sessionId) {
    const session = this.sessions.get(sessionId);
    if (!session) throw new Error("Session not found");
    return session.keys.map((key) => ({
      key: fromBuffer(key.key).toHex(),
      keyId: fromBuffer(key.keyId).toHex()
    }));
  }
};

// src/lib/remote/cdm.ts
var createHttpClient = ({ baseUrl, secret, ...params }) => {
  const headers = {
    "content-type": "application/json",
    ...params.headers || {}
  };
  if (secret) headers["x-secret-key"] = secret;
  const json = (data) => JSON.stringify(data);
  const handleError = (data, response) => {
    if (data.error) {
      const error = typeof data.error === "string" ? data.error : JSON.stringify(data.error);
      throw new Error(error, { cause: response });
    }
  };
  const http = {
    post: async (route, body) => {
      const response = await fetch(`${baseUrl}${route}`, {
        method: "POST",
        headers,
        ...body ? { body: json(body) } : {}
      });
      const contentLength = response.headers.get("content-length");
      if (contentLength === "0") return;
      const data = await response.json();
      handleError(data, response);
      return data;
    },
    get: async (route) => {
      const response = await fetch(`${baseUrl}${route}`, {
        method: "GET",
        headers
      });
      const data = await response.json();
      handleError(data, response);
      return data;
    },
    delete: async (route) => {
      const response = await fetch(`${baseUrl}${route}`, {
        method: "DELETE",
        headers
      });
      const data = await response.json();
      handleError(data, response);
      return data;
    }
  };
  return http;
};
var RemoteCdm = class {
  keySystem = "remote";
  #http;
  #client;
  constructor(params) {
    this.keySystem = params.keySystem;
    this.#http = createHttpClient(params);
    this.#client = params.client;
  }
  async createSession(sessionType) {
    const data = await this.#http.post(`/sessions`, {
      keySystem: this.keySystem,
      sessionType,
      client: this.#client
    });
    return data.id;
  }
  async generateRequest(sessionId, initData, initDataType) {
    const data = await this.#http.post(
      `/sessions/${sessionId}/generate-request`,
      {
        initDataType,
        initData: fromBuffer(initData).toBase64()
      }
    );
    return fromBase64(data.licenseRequest).toBuffer();
  }
  async updateSession(sessionId, response) {
    await this.#http.post(`/sessions/${sessionId}/update`, {
      response: fromBuffer(response).toBase64()
    });
  }
  async closeSession(sessionId) {
    await this.#http.post(`/sessions/${sessionId}/close`);
  }
  async removeSession(sessionId) {
    await this.#http.delete(`/sessions/${sessionId}`);
  }
  async getKeys(sessionId) {
    const keys = await this.#http.get(`/sessions/${sessionId}/keys`);
    return keys;
  }
};

// src/lib/main.ts
var fetchDecryptionKeys = async (params) => {
  const { pssh, cdm, transformRequest, transformResponse } = params;
  const initDataType = "cenc";
  const initData = fromBase64(pssh).toBuffer();
  const keySystemAccess = requestMediaKeySystemAccess(cdm.keySystem, []);
  const mediaKeys = await keySystemAccess.createMediaKeys({ cdm });
  const session = mediaKeys.createSession();
  session.generateRequest(initDataType, initData);
  const licenseRequest = await session.waitForLicenseRequest();
  const request = new Request(params.server, {
    body: licenseRequest,
    method: "POST",
    headers: params.headers
  });
  const response = await fetch(await transformRequest?.(request) || request).then((r) => transformResponse?.(r) || r).then((r) => r.arrayBuffer()).then((buffer) => new Uint8Array(buffer));
  session.update(response);
  const keys = await session.waitForKeyStatusesChange();
  return keys;
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  BinaryReader,
  CLIENT_TYPE,
  MessageEvent,
  PlayReadyCdm,
  PlayReadyClient,
  RemoteCdm,
  Session,
  WidevineCdm,
  WidevineClient,
  base64ToBytes,
  bytesToBase64,
  bytesToString,
  compareArrays,
  fetchDecryptionKeys,
  fromBase64,
  fromBinary,
  fromBuffer,
  fromHex,
  fromText,
  getRandomBytes,
  parseBufferSource,
  requestMediaKeySystemAccess,
  stringToBytes,
  xorArrays
});